diff --git a/vendor/code.gitea.io/actions-proto-go/LICENSE b/vendor/code.gitea.io/actions-proto-go/LICENSE
new file mode 100644
index 0000000..8286dc0
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2022 The Gitea Authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/code.gitea.io/actions-proto-go/ping/v1/messages.pb.go b/vendor/code.gitea.io/actions-proto-go/ping/v1/messages.pb.go
new file mode 100644
index 0000000..83ff2cb
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/ping/v1/messages.pb.go
@@ -0,0 +1,212 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.28.1
+// protoc (unknown)
+// source: ping/v1/messages.proto
+
+package pingv1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type PingRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+}
+
+func (x *PingRequest) Reset() {
+ *x = PingRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ping_v1_messages_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PingRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PingRequest) ProtoMessage() {}
+
+func (x *PingRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_ping_v1_messages_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead.
+func (*PingRequest) Descriptor() ([]byte, []int) {
+ return file_ping_v1_messages_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *PingRequest) GetData() string {
+ if x != nil {
+ return x.Data
+ }
+ return ""
+}
+
+type PingResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+}
+
+func (x *PingResponse) Reset() {
+ *x = PingResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ping_v1_messages_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PingResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PingResponse) ProtoMessage() {}
+
+func (x *PingResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_ping_v1_messages_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead.
+func (*PingResponse) Descriptor() ([]byte, []int) {
+ return file_ping_v1_messages_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *PingResponse) GetData() string {
+ if x != nil {
+ return x.Data
+ }
+ return ""
+}
+
+var File_ping_v1_messages_proto protoreflect.FileDescriptor
+
+var file_ping_v1_messages_proto_rawDesc = []byte{
+ 0x0a, 0x16, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+ 0x31, 0x22, 0x21, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x64, 0x61, 0x74, 0x61, 0x22, 0x22, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x88, 0x01, 0x0a, 0x0b, 0x63, 0x6f, 0x6d,
+ 0x2e, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x2e,
+ 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x76,
+ 0x31, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02,
+ 0x07, 0x50, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x50, 0x69, 0x6e, 0x67, 0x5c,
+ 0x56, 0x31, 0xe2, 0x02, 0x13, 0x50, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42,
+ 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x50, 0x69, 0x6e, 0x67, 0x3a,
+ 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_ping_v1_messages_proto_rawDescOnce sync.Once
+ file_ping_v1_messages_proto_rawDescData = file_ping_v1_messages_proto_rawDesc
+)
+
+func file_ping_v1_messages_proto_rawDescGZIP() []byte {
+ file_ping_v1_messages_proto_rawDescOnce.Do(func() {
+ file_ping_v1_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_ping_v1_messages_proto_rawDescData)
+ })
+ return file_ping_v1_messages_proto_rawDescData
+}
+
+var file_ping_v1_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_ping_v1_messages_proto_goTypes = []interface{}{
+ (*PingRequest)(nil), // 0: ping.v1.PingRequest
+ (*PingResponse)(nil), // 1: ping.v1.PingResponse
+}
+var file_ping_v1_messages_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_ping_v1_messages_proto_init() }
+func file_ping_v1_messages_proto_init() {
+ if File_ping_v1_messages_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_ping_v1_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PingRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ping_v1_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PingResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_ping_v1_messages_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_ping_v1_messages_proto_goTypes,
+ DependencyIndexes: file_ping_v1_messages_proto_depIdxs,
+ MessageInfos: file_ping_v1_messages_proto_msgTypes,
+ }.Build()
+ File_ping_v1_messages_proto = out.File
+ file_ping_v1_messages_proto_rawDesc = nil
+ file_ping_v1_messages_proto_goTypes = nil
+ file_ping_v1_messages_proto_depIdxs = nil
+}
diff --git a/vendor/code.gitea.io/actions-proto-go/ping/v1/pingv1connect/services.connect.go b/vendor/code.gitea.io/actions-proto-go/ping/v1/pingv1connect/services.connect.go
new file mode 100644
index 0000000..84816b8
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/ping/v1/pingv1connect/services.connect.go
@@ -0,0 +1,112 @@
+// Code generated by protoc-gen-connect-go. DO NOT EDIT.
+//
+// Source: ping/v1/services.proto
+
+package pingv1connect
+
+import (
+ v1 "code.gitea.io/actions-proto-go/ping/v1"
+ connect "connectrpc.com/connect"
+ context "context"
+ errors "errors"
+ http "net/http"
+ strings "strings"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the connect package are
+// compatible. If you get a compiler error that this constant is not defined, this code was
+// generated with a version of connect newer than the one compiled into your binary. You can fix the
+// problem by either regenerating this code with an older version of connect or updating the connect
+// version compiled into your binary.
+const _ = connect.IsAtLeastVersion1_13_0
+
+const (
+ // PingServiceName is the fully-qualified name of the PingService service.
+ PingServiceName = "ping.v1.PingService"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this package. They're
+// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
+// period.
+const (
+ // PingServicePingProcedure is the fully-qualified name of the PingService's Ping RPC.
+ PingServicePingProcedure = "/ping.v1.PingService/Ping"
+)
+
+// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
+var (
+ pingServiceServiceDescriptor = v1.File_ping_v1_services_proto.Services().ByName("PingService")
+ pingServicePingMethodDescriptor = pingServiceServiceDescriptor.Methods().ByName("Ping")
+)
+
+// PingServiceClient is a client for the ping.v1.PingService service.
+type PingServiceClient interface {
+ Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error)
+}
+
+// NewPingServiceClient constructs a client for the ping.v1.PingService service. By default, it uses
+// the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
+// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
+// connect.WithGRPCWeb() options.
+//
+// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
+// http://api.acme.com or https://acme.com/grpc).
+func NewPingServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) PingServiceClient {
+ baseURL = strings.TrimRight(baseURL, "/")
+ return &pingServiceClient{
+ ping: connect.NewClient[v1.PingRequest, v1.PingResponse](
+ httpClient,
+ baseURL+PingServicePingProcedure,
+ connect.WithSchema(pingServicePingMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ }
+}
+
+// pingServiceClient implements PingServiceClient.
+type pingServiceClient struct {
+ ping *connect.Client[v1.PingRequest, v1.PingResponse]
+}
+
+// Ping calls ping.v1.PingService.Ping.
+func (c *pingServiceClient) Ping(ctx context.Context, req *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) {
+ return c.ping.CallUnary(ctx, req)
+}
+
+// PingServiceHandler is an implementation of the ping.v1.PingService service.
+type PingServiceHandler interface {
+ Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error)
+}
+
+// NewPingServiceHandler builds an HTTP handler from the service implementation. It returns the path
+// on which to mount the handler and the handler itself.
+//
+// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
+// and JSON codecs. They also support gzip compression.
+func NewPingServiceHandler(svc PingServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
+ pingServicePingHandler := connect.NewUnaryHandler(
+ PingServicePingProcedure,
+ svc.Ping,
+ connect.WithSchema(pingServicePingMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ return "/ping.v1.PingService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.Path {
+ case PingServicePingProcedure:
+ pingServicePingHandler.ServeHTTP(w, r)
+ default:
+ http.NotFound(w, r)
+ }
+ })
+}
+
+// UnimplementedPingServiceHandler returns CodeUnimplemented from all methods.
+type UnimplementedPingServiceHandler struct{}
+
+func (UnimplementedPingServiceHandler) Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ping.v1.PingService.Ping is not implemented"))
+}
diff --git a/vendor/code.gitea.io/actions-proto-go/ping/v1/services.pb.go b/vendor/code.gitea.io/actions-proto-go/ping/v1/services.pb.go
new file mode 100644
index 0000000..770a3a6
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/ping/v1/services.pb.go
@@ -0,0 +1,81 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.28.1
+// protoc (unknown)
+// source: ping/v1/services.proto
+
+package pingv1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+var File_ping_v1_services_proto protoreflect.FileDescriptor
+
+var file_ping_v1_services_proto_rawDesc = []byte{
+ 0x0a, 0x16, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+ 0x31, 0x1a, 0x16, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x42, 0x0a, 0x0b, 0x50, 0x69, 0x6e,
+ 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67,
+ 0x12, 0x14, 0x2e, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31,
+ 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x88, 0x01,
+ 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d,
+ 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x67, 0x6f, 0x2f, 0x70,
+ 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03,
+ 0x50, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x50, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07,
+ 0x50, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x50, 0x69, 0x6e, 0x67, 0x5c, 0x56,
+ 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08,
+ 0x50, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var file_ping_v1_services_proto_goTypes = []interface{}{
+ (*PingRequest)(nil), // 0: ping.v1.PingRequest
+ (*PingResponse)(nil), // 1: ping.v1.PingResponse
+}
+var file_ping_v1_services_proto_depIdxs = []int32{
+ 0, // 0: ping.v1.PingService.Ping:input_type -> ping.v1.PingRequest
+ 1, // 1: ping.v1.PingService.Ping:output_type -> ping.v1.PingResponse
+ 1, // [1:2] is the sub-list for method output_type
+ 0, // [0:1] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_ping_v1_services_proto_init() }
+func file_ping_v1_services_proto_init() {
+ if File_ping_v1_services_proto != nil {
+ return
+ }
+ file_ping_v1_messages_proto_init()
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_ping_v1_services_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 0,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_ping_v1_services_proto_goTypes,
+ DependencyIndexes: file_ping_v1_services_proto_depIdxs,
+ }.Build()
+ File_ping_v1_services_proto = out.File
+ file_ping_v1_services_proto_rawDesc = nil
+ file_ping_v1_services_proto_goTypes = nil
+ file_ping_v1_services_proto_depIdxs = nil
+}
diff --git a/vendor/code.gitea.io/actions-proto-go/runner/v1/messages.pb.go b/vendor/code.gitea.io/actions-proto-go/runner/v1/messages.pb.go
new file mode 100644
index 0000000..1c4cc60
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/runner/v1/messages.pb.go
@@ -0,0 +1,1686 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.28.1
+// protoc (unknown)
+// source: runner/v1/messages.proto
+
+package runnerv1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ structpb "google.golang.org/protobuf/types/known/structpb"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// RunnerStatus runner all status
+type RunnerStatus int32
+
+const (
+ RunnerStatus_RUNNER_STATUS_UNSPECIFIED RunnerStatus = 0
+ RunnerStatus_RUNNER_STATUS_IDLE RunnerStatus = 1
+ RunnerStatus_RUNNER_STATUS_ACTIVE RunnerStatus = 2
+ RunnerStatus_RUNNER_STATUS_OFFLINE RunnerStatus = 3
+)
+
+// Enum value maps for RunnerStatus.
+var (
+ RunnerStatus_name = map[int32]string{
+ 0: "RUNNER_STATUS_UNSPECIFIED",
+ 1: "RUNNER_STATUS_IDLE",
+ 2: "RUNNER_STATUS_ACTIVE",
+ 3: "RUNNER_STATUS_OFFLINE",
+ }
+ RunnerStatus_value = map[string]int32{
+ "RUNNER_STATUS_UNSPECIFIED": 0,
+ "RUNNER_STATUS_IDLE": 1,
+ "RUNNER_STATUS_ACTIVE": 2,
+ "RUNNER_STATUS_OFFLINE": 3,
+ }
+)
+
+func (x RunnerStatus) Enum() *RunnerStatus {
+ p := new(RunnerStatus)
+ *p = x
+ return p
+}
+
+func (x RunnerStatus) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RunnerStatus) Descriptor() protoreflect.EnumDescriptor {
+ return file_runner_v1_messages_proto_enumTypes[0].Descriptor()
+}
+
+func (RunnerStatus) Type() protoreflect.EnumType {
+ return &file_runner_v1_messages_proto_enumTypes[0]
+}
+
+func (x RunnerStatus) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RunnerStatus.Descriptor instead.
+func (RunnerStatus) EnumDescriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{0}
+}
+
+// The result of a task or a step, see https://docs.github.com/en/actions/learn-github-actions/contexts#jobs-context .
+type Result int32
+
+const (
+ Result_RESULT_UNSPECIFIED Result = 0
+ Result_RESULT_SUCCESS Result = 1
+ Result_RESULT_FAILURE Result = 2
+ Result_RESULT_CANCELLED Result = 3
+ Result_RESULT_SKIPPED Result = 4
+)
+
+// Enum value maps for Result.
+var (
+ Result_name = map[int32]string{
+ 0: "RESULT_UNSPECIFIED",
+ 1: "RESULT_SUCCESS",
+ 2: "RESULT_FAILURE",
+ 3: "RESULT_CANCELLED",
+ 4: "RESULT_SKIPPED",
+ }
+ Result_value = map[string]int32{
+ "RESULT_UNSPECIFIED": 0,
+ "RESULT_SUCCESS": 1,
+ "RESULT_FAILURE": 2,
+ "RESULT_CANCELLED": 3,
+ "RESULT_SKIPPED": 4,
+ }
+)
+
+func (x Result) Enum() *Result {
+ p := new(Result)
+ *p = x
+ return p
+}
+
+func (x Result) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Result) Descriptor() protoreflect.EnumDescriptor {
+ return file_runner_v1_messages_proto_enumTypes[1].Descriptor()
+}
+
+func (Result) Type() protoreflect.EnumType {
+ return &file_runner_v1_messages_proto_enumTypes[1]
+}
+
+func (x Result) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Result.Descriptor instead.
+func (Result) EnumDescriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{1}
+}
+
+type RegisterRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
+ // Deprecated: Do not use.
+ AgentLabels []string `protobuf:"bytes,3,rep,name=agent_labels,json=agentLabels,proto3" json:"agent_labels,omitempty"`
+ // Deprecated: Do not use.
+ CustomLabels []string `protobuf:"bytes,4,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty"`
+ Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"`
+ Labels []string `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty"`
+}
+
+func (x *RegisterRequest) Reset() {
+ *x = RegisterRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RegisterRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RegisterRequest) ProtoMessage() {}
+
+func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead.
+func (*RegisterRequest) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *RegisterRequest) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetToken() string {
+ if x != nil {
+ return x.Token
+ }
+ return ""
+}
+
+// Deprecated: Do not use.
+func (x *RegisterRequest) GetAgentLabels() []string {
+ if x != nil {
+ return x.AgentLabels
+ }
+ return nil
+}
+
+// Deprecated: Do not use.
+func (x *RegisterRequest) GetCustomLabels() []string {
+ if x != nil {
+ return x.CustomLabels
+ }
+ return nil
+}
+
+func (x *RegisterRequest) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetLabels() []string {
+ if x != nil {
+ return x.Labels
+ }
+ return nil
+}
+
+type RegisterResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Runner *Runner `protobuf:"bytes,1,opt,name=runner,proto3" json:"runner,omitempty"`
+}
+
+func (x *RegisterResponse) Reset() {
+ *x = RegisterResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RegisterResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RegisterResponse) ProtoMessage() {}
+
+func (x *RegisterResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead.
+func (*RegisterResponse) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *RegisterResponse) GetRunner() *Runner {
+ if x != nil {
+ return x.Runner
+ }
+ return nil
+}
+
+type DeclareRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
+ Labels []string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
+}
+
+func (x *DeclareRequest) Reset() {
+ *x = DeclareRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DeclareRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeclareRequest) ProtoMessage() {}
+
+func (x *DeclareRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeclareRequest.ProtoReflect.Descriptor instead.
+func (*DeclareRequest) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *DeclareRequest) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *DeclareRequest) GetLabels() []string {
+ if x != nil {
+ return x.Labels
+ }
+ return nil
+}
+
+type DeclareResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Runner *Runner `protobuf:"bytes,1,opt,name=runner,proto3" json:"runner,omitempty"`
+}
+
+func (x *DeclareResponse) Reset() {
+ *x = DeclareResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DeclareResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeclareResponse) ProtoMessage() {}
+
+func (x *DeclareResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeclareResponse.ProtoReflect.Descriptor instead.
+func (*DeclareResponse) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *DeclareResponse) GetRunner() *Runner {
+ if x != nil {
+ return x.Runner
+ }
+ return nil
+}
+
+type FetchTaskRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ TasksVersion int64 `protobuf:"varint,1,opt,name=tasks_version,json=tasksVersion,proto3" json:"tasks_version,omitempty"` // Runner use `tasks_version` to compare with Gitea and detemine whether new tasks may exist.
+}
+
+func (x *FetchTaskRequest) Reset() {
+ *x = FetchTaskRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FetchTaskRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchTaskRequest) ProtoMessage() {}
+
+func (x *FetchTaskRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchTaskRequest.ProtoReflect.Descriptor instead.
+func (*FetchTaskRequest) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *FetchTaskRequest) GetTasksVersion() int64 {
+ if x != nil {
+ return x.TasksVersion
+ }
+ return 0
+}
+
+type FetchTaskResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Task *Task `protobuf:"bytes,1,opt,name=task,proto3" json:"task,omitempty"`
+ TasksVersion int64 `protobuf:"varint,2,opt,name=tasks_version,json=tasksVersion,proto3" json:"tasks_version,omitempty"` // Gitea informs the Runner of the latest version of tasks through `tasks_version`.
+}
+
+func (x *FetchTaskResponse) Reset() {
+ *x = FetchTaskResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FetchTaskResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchTaskResponse) ProtoMessage() {}
+
+func (x *FetchTaskResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchTaskResponse.ProtoReflect.Descriptor instead.
+func (*FetchTaskResponse) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *FetchTaskResponse) GetTask() *Task {
+ if x != nil {
+ return x.Task
+ }
+ return nil
+}
+
+func (x *FetchTaskResponse) GetTasksVersion() int64 {
+ if x != nil {
+ return x.TasksVersion
+ }
+ return 0
+}
+
+type UpdateTaskRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ State *TaskState `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
+ Outputs map[string]string `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // The outputs of the task. Since the outputs may be large, the client does not need to send all outputs every time, only the unsent outputs.
+}
+
+func (x *UpdateTaskRequest) Reset() {
+ *x = UpdateTaskRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateTaskRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateTaskRequest) ProtoMessage() {}
+
+func (x *UpdateTaskRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateTaskRequest.ProtoReflect.Descriptor instead.
+func (*UpdateTaskRequest) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *UpdateTaskRequest) GetState() *TaskState {
+ if x != nil {
+ return x.State
+ }
+ return nil
+}
+
+func (x *UpdateTaskRequest) GetOutputs() map[string]string {
+ if x != nil {
+ return x.Outputs
+ }
+ return nil
+}
+
+type UpdateTaskResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ State *TaskState `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
+ SentOutputs []string `protobuf:"bytes,2,rep,name=sent_outputs,json=sentOutputs,proto3" json:"sent_outputs,omitempty"` // The keys of the outputs that have been sent, not only the ones that have been sent this time, but also those that have been sent before.
+}
+
+func (x *UpdateTaskResponse) Reset() {
+ *x = UpdateTaskResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateTaskResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateTaskResponse) ProtoMessage() {}
+
+func (x *UpdateTaskResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateTaskResponse.ProtoReflect.Descriptor instead.
+func (*UpdateTaskResponse) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *UpdateTaskResponse) GetState() *TaskState {
+ if x != nil {
+ return x.State
+ }
+ return nil
+}
+
+func (x *UpdateTaskResponse) GetSentOutputs() []string {
+ if x != nil {
+ return x.SentOutputs
+ }
+ return nil
+}
+
+type UpdateLogRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ TaskId int64 `protobuf:"varint,1,opt,name=task_id,json=taskId,proto3" json:"task_id,omitempty"`
+ Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` // The actual index of the first line.
+ Rows []*LogRow `protobuf:"bytes,3,rep,name=rows,proto3" json:"rows,omitempty"`
+ NoMore bool `protobuf:"varint,4,opt,name=no_more,json=noMore,proto3" json:"no_more,omitempty"` // No more logs.
+}
+
+func (x *UpdateLogRequest) Reset() {
+ *x = UpdateLogRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateLogRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateLogRequest) ProtoMessage() {}
+
+func (x *UpdateLogRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateLogRequest.ProtoReflect.Descriptor instead.
+func (*UpdateLogRequest) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *UpdateLogRequest) GetTaskId() int64 {
+ if x != nil {
+ return x.TaskId
+ }
+ return 0
+}
+
+func (x *UpdateLogRequest) GetIndex() int64 {
+ if x != nil {
+ return x.Index
+ }
+ return 0
+}
+
+func (x *UpdateLogRequest) GetRows() []*LogRow {
+ if x != nil {
+ return x.Rows
+ }
+ return nil
+}
+
+func (x *UpdateLogRequest) GetNoMore() bool {
+ if x != nil {
+ return x.NoMore
+ }
+ return false
+}
+
+type UpdateLogResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ AckIndex int64 `protobuf:"varint,1,opt,name=ack_index,json=ackIndex,proto3" json:"ack_index,omitempty"` // If all lines are received, should be index + length(lines).
+}
+
+func (x *UpdateLogResponse) Reset() {
+ *x = UpdateLogResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateLogResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateLogResponse) ProtoMessage() {}
+
+func (x *UpdateLogResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateLogResponse.ProtoReflect.Descriptor instead.
+func (*UpdateLogResponse) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *UpdateLogResponse) GetAckIndex() int64 {
+ if x != nil {
+ return x.AckIndex
+ }
+ return 0
+}
+
+// Runner Payload
+type Runner struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3" json:"uuid,omitempty"`
+ Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"`
+ Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
+ Status RunnerStatus `protobuf:"varint,5,opt,name=status,proto3,enum=runner.v1.RunnerStatus" json:"status,omitempty"`
+ // Deprecated: Do not use.
+ AgentLabels []string `protobuf:"bytes,6,rep,name=agent_labels,json=agentLabels,proto3" json:"agent_labels,omitempty"`
+ // Deprecated: Do not use.
+ CustomLabels []string `protobuf:"bytes,7,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty"`
+ Version string `protobuf:"bytes,8,opt,name=version,proto3" json:"version,omitempty"`
+ Labels []string `protobuf:"bytes,9,rep,name=labels,proto3" json:"labels,omitempty"`
+}
+
+func (x *Runner) Reset() {
+ *x = Runner{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Runner) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Runner) ProtoMessage() {}
+
+func (x *Runner) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Runner.ProtoReflect.Descriptor instead.
+func (*Runner) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *Runner) GetId() int64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Runner) GetUuid() string {
+ if x != nil {
+ return x.Uuid
+ }
+ return ""
+}
+
+func (x *Runner) GetToken() string {
+ if x != nil {
+ return x.Token
+ }
+ return ""
+}
+
+func (x *Runner) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *Runner) GetStatus() RunnerStatus {
+ if x != nil {
+ return x.Status
+ }
+ return RunnerStatus_RUNNER_STATUS_UNSPECIFIED
+}
+
+// Deprecated: Do not use.
+func (x *Runner) GetAgentLabels() []string {
+ if x != nil {
+ return x.AgentLabels
+ }
+ return nil
+}
+
+// Deprecated: Do not use.
+func (x *Runner) GetCustomLabels() []string {
+ if x != nil {
+ return x.CustomLabels
+ }
+ return nil
+}
+
+func (x *Runner) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *Runner) GetLabels() []string {
+ if x != nil {
+ return x.Labels
+ }
+ return nil
+}
+
+// Task represents a task.
+type Task struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // A unique number for each workflow run, unlike run_id or job_id, task_id never be reused.
+ WorkflowPayload []byte `protobuf:"bytes,2,opt,name=workflow_payload,json=workflowPayload,proto3,oneof" json:"workflow_payload,omitempty"` // The content of the expanded workflow yaml file.
+ Context *structpb.Struct `protobuf:"bytes,3,opt,name=context,proto3,oneof" json:"context,omitempty"` // See https://docs.github.com/en/actions/learn-github-actions/contexts#github-context .
+ Secrets map[string]string `protobuf:"bytes,4,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // See https://docs.github.com/en/actions/learn-github-actions/contexts#secrets-context .
+ // Deprecated: Do not use.
+ Machine string `protobuf:"bytes,5,opt,name=machine,proto3" json:"machine,omitempty"` // Unused.
+ Needs map[string]*TaskNeed `protobuf:"bytes,6,rep,name=needs,proto3" json:"needs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // See https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context .
+ Vars map[string]string `protobuf:"bytes,7,rep,name=vars,proto3" json:"vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // See https://docs.github.com/en/actions/learn-github-actions/contexts#vars-context .
+}
+
+func (x *Task) Reset() {
+ *x = Task{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Task) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Task) ProtoMessage() {}
+
+func (x *Task) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Task.ProtoReflect.Descriptor instead.
+func (*Task) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *Task) GetId() int64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Task) GetWorkflowPayload() []byte {
+ if x != nil {
+ return x.WorkflowPayload
+ }
+ return nil
+}
+
+func (x *Task) GetContext() *structpb.Struct {
+ if x != nil {
+ return x.Context
+ }
+ return nil
+}
+
+func (x *Task) GetSecrets() map[string]string {
+ if x != nil {
+ return x.Secrets
+ }
+ return nil
+}
+
+// Deprecated: Do not use.
+func (x *Task) GetMachine() string {
+ if x != nil {
+ return x.Machine
+ }
+ return ""
+}
+
+func (x *Task) GetNeeds() map[string]*TaskNeed {
+ if x != nil {
+ return x.Needs
+ }
+ return nil
+}
+
+func (x *Task) GetVars() map[string]string {
+ if x != nil {
+ return x.Vars
+ }
+ return nil
+}
+
+// TaskNeed represents a task need.
+type TaskNeed struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Outputs map[string]string `protobuf:"bytes,1,rep,name=outputs,proto3" json:"outputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // The set of outputs of a job that the current job depends on.
+ Result Result `protobuf:"varint,2,opt,name=result,proto3,enum=runner.v1.Result" json:"result,omitempty"` // The result of a job that the current job depends on. Possible values are success, failure, cancelled, or skipped.
+}
+
+func (x *TaskNeed) Reset() {
+ *x = TaskNeed{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *TaskNeed) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TaskNeed) ProtoMessage() {}
+
+func (x *TaskNeed) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use TaskNeed.ProtoReflect.Descriptor instead.
+func (*TaskNeed) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *TaskNeed) GetOutputs() map[string]string {
+ if x != nil {
+ return x.Outputs
+ }
+ return nil
+}
+
+func (x *TaskNeed) GetResult() Result {
+ if x != nil {
+ return x.Result
+ }
+ return Result_RESULT_UNSPECIFIED
+}
+
+// TaskState represents the state of a task.
+type TaskState struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Result Result `protobuf:"varint,2,opt,name=result,proto3,enum=runner.v1.Result" json:"result,omitempty"`
+ StartedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
+ StoppedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=stopped_at,json=stoppedAt,proto3" json:"stopped_at,omitempty"`
+ Steps []*StepState `protobuf:"bytes,5,rep,name=steps,proto3" json:"steps,omitempty"`
+}
+
+func (x *TaskState) Reset() {
+ *x = TaskState{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *TaskState) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TaskState) ProtoMessage() {}
+
+func (x *TaskState) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use TaskState.ProtoReflect.Descriptor instead.
+func (*TaskState) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *TaskState) GetId() int64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *TaskState) GetResult() Result {
+ if x != nil {
+ return x.Result
+ }
+ return Result_RESULT_UNSPECIFIED
+}
+
+func (x *TaskState) GetStartedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.StartedAt
+ }
+ return nil
+}
+
+func (x *TaskState) GetStoppedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.StoppedAt
+ }
+ return nil
+}
+
+func (x *TaskState) GetSteps() []*StepState {
+ if x != nil {
+ return x.Steps
+ }
+ return nil
+}
+
+// TaskState represents the state of a step.
+type StepState struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Result Result `protobuf:"varint,2,opt,name=result,proto3,enum=runner.v1.Result" json:"result,omitempty"`
+ StartedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
+ StoppedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=stopped_at,json=stoppedAt,proto3" json:"stopped_at,omitempty"`
+ LogIndex int64 `protobuf:"varint,5,opt,name=log_index,json=logIndex,proto3" json:"log_index,omitempty"` // Where the first line log of the step.
+ LogLength int64 `protobuf:"varint,6,opt,name=log_length,json=logLength,proto3" json:"log_length,omitempty"` // How many logs the step has.
+}
+
+func (x *StepState) Reset() {
+ *x = StepState{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StepState) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StepState) ProtoMessage() {}
+
+func (x *StepState) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StepState.ProtoReflect.Descriptor instead.
+func (*StepState) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *StepState) GetId() int64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *StepState) GetResult() Result {
+ if x != nil {
+ return x.Result
+ }
+ return Result_RESULT_UNSPECIFIED
+}
+
+func (x *StepState) GetStartedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.StartedAt
+ }
+ return nil
+}
+
+func (x *StepState) GetStoppedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.StoppedAt
+ }
+ return nil
+}
+
+func (x *StepState) GetLogIndex() int64 {
+ if x != nil {
+ return x.LogIndex
+ }
+ return 0
+}
+
+func (x *StepState) GetLogLength() int64 {
+ if x != nil {
+ return x.LogLength
+ }
+ return 0
+}
+
+// LogRow represents a row of logs.
+type LogRow struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"`
+ Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
+}
+
+func (x *LogRow) Reset() {
+ *x = LogRow{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_runner_v1_messages_proto_msgTypes[15]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *LogRow) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LogRow) ProtoMessage() {}
+
+func (x *LogRow) ProtoReflect() protoreflect.Message {
+ mi := &file_runner_v1_messages_proto_msgTypes[15]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use LogRow.ProtoReflect.Descriptor instead.
+func (*LogRow) Descriptor() ([]byte, []int) {
+ return file_runner_v1_messages_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *LogRow) GetTime() *timestamppb.Timestamp {
+ if x != nil {
+ return x.Time
+ }
+ return nil
+}
+
+func (x *LogRow) GetContent() string {
+ if x != nil {
+ return x.Content
+ }
+ return ""
+}
+
+var File_runner_v1_messages_proto protoreflect.FileDescriptor
+
+var file_runner_v1_messages_proto_rawDesc = []byte{
+ 0x0a, 0x18, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbd, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
+ 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,
+ 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x61, 0x62, 0x65,
+ 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x61, 0x67,
+ 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x27, 0x0a, 0x0d, 0x63, 0x75, 0x73,
+ 0x74, 0x6f, 0x6d, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09,
+ 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c, 0x61, 0x62, 0x65,
+ 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06,
+ 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61,
+ 0x62, 0x65, 0x6c, 0x73, 0x22, 0x3d, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65,
+ 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x06, 0x72, 0x75, 0x6e,
+ 0x6e, 0x65, 0x72, 0x22, 0x42, 0x0a, 0x0e, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x3c, 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x6c, 0x61,
+ 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x72, 0x75,
+ 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e,
+ 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x06, 0x72,
+ 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x10, 0x46, 0x65, 0x74, 0x63, 0x68, 0x54, 0x61,
+ 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x73,
+ 0x6b, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5d,
+ 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61,
+ 0x73, 0x6b, 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b,
+ 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc0, 0x01,
+ 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54,
+ 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
+ 0x43, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f,
+ 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6f, 0x75, 0x74,
+ 0x70, 0x75, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x22, 0x63, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
+ 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75,
+ 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x6e, 0x74, 0x4f, 0x75,
+ 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x61,
+ 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73,
+ 0x6b, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x04, 0x72, 0x6f, 0x77,
+ 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72,
+ 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73,
+ 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x06, 0x6e, 0x6f, 0x4d, 0x6f, 0x72, 0x65, 0x22, 0x30, 0x0a, 0x11, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b,
+ 0x0a, 0x09, 0x61, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x08, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x89, 0x02, 0x0a, 0x06,
+ 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6c,
+ 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52,
+ 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x27, 0x0a, 0x0d,
+ 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20,
+ 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4c,
+ 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x9a, 0x04, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b,
+ 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64,
+ 0x12, 0x2e, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x79,
+ 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0f, 0x77, 0x6f,
+ 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x88, 0x01, 0x01,
+ 0x12, 0x36, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x01, 0x52, 0x07, 0x63, 0x6f,
+ 0x6e, 0x74, 0x65, 0x78, 0x74, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72,
+ 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65,
+ 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73,
+ 0x12, 0x1c, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x30,
+ 0x0a, 0x05, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x2e, 0x4e,
+ 0x65, 0x65, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x65, 0x65, 0x64, 0x73,
+ 0x12, 0x2d, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x2e,
+ 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x76, 0x61, 0x72, 0x73, 0x1a,
+ 0x3a, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d, 0x0a, 0x0a, 0x4e,
+ 0x65, 0x65, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e,
+ 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x65, 0x65, 0x64, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x37, 0x0a, 0x09, 0x56, 0x61,
+ 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
+ 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x22, 0xad, 0x01, 0x0a, 0x08, 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x65, 0x65,
+ 0x64, 0x12, 0x3a, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54,
+ 0x61, 0x73, 0x6b, 0x4e, 0x65, 0x65, 0x64, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x29, 0x0a,
+ 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e,
+ 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
+ 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x3a, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70,
+ 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe8, 0x01, 0x0a, 0x09, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
+ 0x69, 0x64, 0x12, 0x29, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52,
+ 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x39, 0x0a,
+ 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x70,
+ 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65,
+ 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53,
+ 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22,
+ 0xf8, 0x01, 0x0a, 0x09, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a,
+ 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a,
+ 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e,
+ 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
+ 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65,
+ 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61,
+ 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+ 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b,
+ 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x6c,
+ 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x09, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x52, 0x0a, 0x06, 0x4c, 0x6f,
+ 0x67, 0x52, 0x6f, 0x77, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04,
+ 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2a, 0x7a,
+ 0x0a, 0x0c, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d,
+ 0x0a, 0x19, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a,
+ 0x12, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49,
+ 0x44, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f,
+ 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12,
+ 0x19, 0x0a, 0x15, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
+ 0x5f, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x03, 0x2a, 0x72, 0x0a, 0x06, 0x52, 0x65,
+ 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55,
+ 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e,
+ 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01,
+ 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55,
+ 0x52, 0x45, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x43,
+ 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45,
+ 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x04, 0x42, 0x96,
+ 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x42, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
+ 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x69, 0x6f,
+ 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x67,
+ 0x6f, 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x52, 0x75, 0x6e,
+ 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5c,
+ 0x56, 0x31, 0xe2, 0x02, 0x15, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47,
+ 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x52, 0x75, 0x6e,
+ 0x6e, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_runner_v1_messages_proto_rawDescOnce sync.Once
+ file_runner_v1_messages_proto_rawDescData = file_runner_v1_messages_proto_rawDesc
+)
+
+func file_runner_v1_messages_proto_rawDescGZIP() []byte {
+ file_runner_v1_messages_proto_rawDescOnce.Do(func() {
+ file_runner_v1_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_runner_v1_messages_proto_rawDescData)
+ })
+ return file_runner_v1_messages_proto_rawDescData
+}
+
+var file_runner_v1_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_runner_v1_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
+var file_runner_v1_messages_proto_goTypes = []interface{}{
+ (RunnerStatus)(0), // 0: runner.v1.RunnerStatus
+ (Result)(0), // 1: runner.v1.Result
+ (*RegisterRequest)(nil), // 2: runner.v1.RegisterRequest
+ (*RegisterResponse)(nil), // 3: runner.v1.RegisterResponse
+ (*DeclareRequest)(nil), // 4: runner.v1.DeclareRequest
+ (*DeclareResponse)(nil), // 5: runner.v1.DeclareResponse
+ (*FetchTaskRequest)(nil), // 6: runner.v1.FetchTaskRequest
+ (*FetchTaskResponse)(nil), // 7: runner.v1.FetchTaskResponse
+ (*UpdateTaskRequest)(nil), // 8: runner.v1.UpdateTaskRequest
+ (*UpdateTaskResponse)(nil), // 9: runner.v1.UpdateTaskResponse
+ (*UpdateLogRequest)(nil), // 10: runner.v1.UpdateLogRequest
+ (*UpdateLogResponse)(nil), // 11: runner.v1.UpdateLogResponse
+ (*Runner)(nil), // 12: runner.v1.Runner
+ (*Task)(nil), // 13: runner.v1.Task
+ (*TaskNeed)(nil), // 14: runner.v1.TaskNeed
+ (*TaskState)(nil), // 15: runner.v1.TaskState
+ (*StepState)(nil), // 16: runner.v1.StepState
+ (*LogRow)(nil), // 17: runner.v1.LogRow
+ nil, // 18: runner.v1.UpdateTaskRequest.OutputsEntry
+ nil, // 19: runner.v1.Task.SecretsEntry
+ nil, // 20: runner.v1.Task.NeedsEntry
+ nil, // 21: runner.v1.Task.VarsEntry
+ nil, // 22: runner.v1.TaskNeed.OutputsEntry
+ (*structpb.Struct)(nil), // 23: google.protobuf.Struct
+ (*timestamppb.Timestamp)(nil), // 24: google.protobuf.Timestamp
+}
+var file_runner_v1_messages_proto_depIdxs = []int32{
+ 12, // 0: runner.v1.RegisterResponse.runner:type_name -> runner.v1.Runner
+ 12, // 1: runner.v1.DeclareResponse.runner:type_name -> runner.v1.Runner
+ 13, // 2: runner.v1.FetchTaskResponse.task:type_name -> runner.v1.Task
+ 15, // 3: runner.v1.UpdateTaskRequest.state:type_name -> runner.v1.TaskState
+ 18, // 4: runner.v1.UpdateTaskRequest.outputs:type_name -> runner.v1.UpdateTaskRequest.OutputsEntry
+ 15, // 5: runner.v1.UpdateTaskResponse.state:type_name -> runner.v1.TaskState
+ 17, // 6: runner.v1.UpdateLogRequest.rows:type_name -> runner.v1.LogRow
+ 0, // 7: runner.v1.Runner.status:type_name -> runner.v1.RunnerStatus
+ 23, // 8: runner.v1.Task.context:type_name -> google.protobuf.Struct
+ 19, // 9: runner.v1.Task.secrets:type_name -> runner.v1.Task.SecretsEntry
+ 20, // 10: runner.v1.Task.needs:type_name -> runner.v1.Task.NeedsEntry
+ 21, // 11: runner.v1.Task.vars:type_name -> runner.v1.Task.VarsEntry
+ 22, // 12: runner.v1.TaskNeed.outputs:type_name -> runner.v1.TaskNeed.OutputsEntry
+ 1, // 13: runner.v1.TaskNeed.result:type_name -> runner.v1.Result
+ 1, // 14: runner.v1.TaskState.result:type_name -> runner.v1.Result
+ 24, // 15: runner.v1.TaskState.started_at:type_name -> google.protobuf.Timestamp
+ 24, // 16: runner.v1.TaskState.stopped_at:type_name -> google.protobuf.Timestamp
+ 16, // 17: runner.v1.TaskState.steps:type_name -> runner.v1.StepState
+ 1, // 18: runner.v1.StepState.result:type_name -> runner.v1.Result
+ 24, // 19: runner.v1.StepState.started_at:type_name -> google.protobuf.Timestamp
+ 24, // 20: runner.v1.StepState.stopped_at:type_name -> google.protobuf.Timestamp
+ 24, // 21: runner.v1.LogRow.time:type_name -> google.protobuf.Timestamp
+ 14, // 22: runner.v1.Task.NeedsEntry.value:type_name -> runner.v1.TaskNeed
+ 23, // [23:23] is the sub-list for method output_type
+ 23, // [23:23] is the sub-list for method input_type
+ 23, // [23:23] is the sub-list for extension type_name
+ 23, // [23:23] is the sub-list for extension extendee
+ 0, // [0:23] is the sub-list for field type_name
+}
+
+func init() { file_runner_v1_messages_proto_init() }
+func file_runner_v1_messages_proto_init() {
+ if File_runner_v1_messages_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_runner_v1_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RegisterRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RegisterResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DeclareRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DeclareResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FetchTaskRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FetchTaskResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateTaskRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateTaskResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateLogRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateLogResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Runner); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Task); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TaskNeed); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TaskState); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*StepState); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LogRow); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_runner_v1_messages_proto_msgTypes[11].OneofWrappers = []interface{}{}
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_runner_v1_messages_proto_rawDesc,
+ NumEnums: 2,
+ NumMessages: 21,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_runner_v1_messages_proto_goTypes,
+ DependencyIndexes: file_runner_v1_messages_proto_depIdxs,
+ EnumInfos: file_runner_v1_messages_proto_enumTypes,
+ MessageInfos: file_runner_v1_messages_proto_msgTypes,
+ }.Build()
+ File_runner_v1_messages_proto = out.File
+ file_runner_v1_messages_proto_rawDesc = nil
+ file_runner_v1_messages_proto_goTypes = nil
+ file_runner_v1_messages_proto_depIdxs = nil
+}
diff --git a/vendor/code.gitea.io/actions-proto-go/runner/v1/runnerv1connect/services.connect.go b/vendor/code.gitea.io/actions-proto-go/runner/v1/runnerv1connect/services.connect.go
new file mode 100644
index 0000000..3c3e86c
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/runner/v1/runnerv1connect/services.connect.go
@@ -0,0 +1,239 @@
+// Code generated by protoc-gen-connect-go. DO NOT EDIT.
+//
+// Source: runner/v1/services.proto
+
+package runnerv1connect
+
+import (
+ v1 "code.gitea.io/actions-proto-go/runner/v1"
+ connect "connectrpc.com/connect"
+ context "context"
+ errors "errors"
+ http "net/http"
+ strings "strings"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the connect package are
+// compatible. If you get a compiler error that this constant is not defined, this code was
+// generated with a version of connect newer than the one compiled into your binary. You can fix the
+// problem by either regenerating this code with an older version of connect or updating the connect
+// version compiled into your binary.
+const _ = connect.IsAtLeastVersion1_13_0
+
+const (
+ // RunnerServiceName is the fully-qualified name of the RunnerService service.
+ RunnerServiceName = "runner.v1.RunnerService"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this package. They're
+// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
+// period.
+const (
+ // RunnerServiceRegisterProcedure is the fully-qualified name of the RunnerService's Register RPC.
+ RunnerServiceRegisterProcedure = "/runner.v1.RunnerService/Register"
+ // RunnerServiceDeclareProcedure is the fully-qualified name of the RunnerService's Declare RPC.
+ RunnerServiceDeclareProcedure = "/runner.v1.RunnerService/Declare"
+ // RunnerServiceFetchTaskProcedure is the fully-qualified name of the RunnerService's FetchTask RPC.
+ RunnerServiceFetchTaskProcedure = "/runner.v1.RunnerService/FetchTask"
+ // RunnerServiceUpdateTaskProcedure is the fully-qualified name of the RunnerService's UpdateTask
+ // RPC.
+ RunnerServiceUpdateTaskProcedure = "/runner.v1.RunnerService/UpdateTask"
+ // RunnerServiceUpdateLogProcedure is the fully-qualified name of the RunnerService's UpdateLog RPC.
+ RunnerServiceUpdateLogProcedure = "/runner.v1.RunnerService/UpdateLog"
+)
+
+// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
+var (
+ runnerServiceServiceDescriptor = v1.File_runner_v1_services_proto.Services().ByName("RunnerService")
+ runnerServiceRegisterMethodDescriptor = runnerServiceServiceDescriptor.Methods().ByName("Register")
+ runnerServiceDeclareMethodDescriptor = runnerServiceServiceDescriptor.Methods().ByName("Declare")
+ runnerServiceFetchTaskMethodDescriptor = runnerServiceServiceDescriptor.Methods().ByName("FetchTask")
+ runnerServiceUpdateTaskMethodDescriptor = runnerServiceServiceDescriptor.Methods().ByName("UpdateTask")
+ runnerServiceUpdateLogMethodDescriptor = runnerServiceServiceDescriptor.Methods().ByName("UpdateLog")
+)
+
+// RunnerServiceClient is a client for the runner.v1.RunnerService service.
+type RunnerServiceClient interface {
+ // Register register a new runner in server.
+ Register(context.Context, *connect.Request[v1.RegisterRequest]) (*connect.Response[v1.RegisterResponse], error)
+ // Declare declare runner's version and labels to Gitea before starting fetching task.
+ Declare(context.Context, *connect.Request[v1.DeclareRequest]) (*connect.Response[v1.DeclareResponse], error)
+ // FetchTask requests the next available task for execution.
+ FetchTask(context.Context, *connect.Request[v1.FetchTaskRequest]) (*connect.Response[v1.FetchTaskResponse], error)
+ // UpdateTask updates the task status.
+ UpdateTask(context.Context, *connect.Request[v1.UpdateTaskRequest]) (*connect.Response[v1.UpdateTaskResponse], error)
+ // UpdateLog uploads log of the task.
+ UpdateLog(context.Context, *connect.Request[v1.UpdateLogRequest]) (*connect.Response[v1.UpdateLogResponse], error)
+}
+
+// NewRunnerServiceClient constructs a client for the runner.v1.RunnerService service. By default,
+// it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and
+// sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC()
+// or connect.WithGRPCWeb() options.
+//
+// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
+// http://api.acme.com or https://acme.com/grpc).
+func NewRunnerServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) RunnerServiceClient {
+ baseURL = strings.TrimRight(baseURL, "/")
+ return &runnerServiceClient{
+ register: connect.NewClient[v1.RegisterRequest, v1.RegisterResponse](
+ httpClient,
+ baseURL+RunnerServiceRegisterProcedure,
+ connect.WithSchema(runnerServiceRegisterMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ declare: connect.NewClient[v1.DeclareRequest, v1.DeclareResponse](
+ httpClient,
+ baseURL+RunnerServiceDeclareProcedure,
+ connect.WithSchema(runnerServiceDeclareMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ fetchTask: connect.NewClient[v1.FetchTaskRequest, v1.FetchTaskResponse](
+ httpClient,
+ baseURL+RunnerServiceFetchTaskProcedure,
+ connect.WithSchema(runnerServiceFetchTaskMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ updateTask: connect.NewClient[v1.UpdateTaskRequest, v1.UpdateTaskResponse](
+ httpClient,
+ baseURL+RunnerServiceUpdateTaskProcedure,
+ connect.WithSchema(runnerServiceUpdateTaskMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ updateLog: connect.NewClient[v1.UpdateLogRequest, v1.UpdateLogResponse](
+ httpClient,
+ baseURL+RunnerServiceUpdateLogProcedure,
+ connect.WithSchema(runnerServiceUpdateLogMethodDescriptor),
+ connect.WithClientOptions(opts...),
+ ),
+ }
+}
+
+// runnerServiceClient implements RunnerServiceClient.
+type runnerServiceClient struct {
+ register *connect.Client[v1.RegisterRequest, v1.RegisterResponse]
+ declare *connect.Client[v1.DeclareRequest, v1.DeclareResponse]
+ fetchTask *connect.Client[v1.FetchTaskRequest, v1.FetchTaskResponse]
+ updateTask *connect.Client[v1.UpdateTaskRequest, v1.UpdateTaskResponse]
+ updateLog *connect.Client[v1.UpdateLogRequest, v1.UpdateLogResponse]
+}
+
+// Register calls runner.v1.RunnerService.Register.
+func (c *runnerServiceClient) Register(ctx context.Context, req *connect.Request[v1.RegisterRequest]) (*connect.Response[v1.RegisterResponse], error) {
+ return c.register.CallUnary(ctx, req)
+}
+
+// Declare calls runner.v1.RunnerService.Declare.
+func (c *runnerServiceClient) Declare(ctx context.Context, req *connect.Request[v1.DeclareRequest]) (*connect.Response[v1.DeclareResponse], error) {
+ return c.declare.CallUnary(ctx, req)
+}
+
+// FetchTask calls runner.v1.RunnerService.FetchTask.
+func (c *runnerServiceClient) FetchTask(ctx context.Context, req *connect.Request[v1.FetchTaskRequest]) (*connect.Response[v1.FetchTaskResponse], error) {
+ return c.fetchTask.CallUnary(ctx, req)
+}
+
+// UpdateTask calls runner.v1.RunnerService.UpdateTask.
+func (c *runnerServiceClient) UpdateTask(ctx context.Context, req *connect.Request[v1.UpdateTaskRequest]) (*connect.Response[v1.UpdateTaskResponse], error) {
+ return c.updateTask.CallUnary(ctx, req)
+}
+
+// UpdateLog calls runner.v1.RunnerService.UpdateLog.
+func (c *runnerServiceClient) UpdateLog(ctx context.Context, req *connect.Request[v1.UpdateLogRequest]) (*connect.Response[v1.UpdateLogResponse], error) {
+ return c.updateLog.CallUnary(ctx, req)
+}
+
+// RunnerServiceHandler is an implementation of the runner.v1.RunnerService service.
+type RunnerServiceHandler interface {
+ // Register register a new runner in server.
+ Register(context.Context, *connect.Request[v1.RegisterRequest]) (*connect.Response[v1.RegisterResponse], error)
+ // Declare declare runner's version and labels to Gitea before starting fetching task.
+ Declare(context.Context, *connect.Request[v1.DeclareRequest]) (*connect.Response[v1.DeclareResponse], error)
+ // FetchTask requests the next available task for execution.
+ FetchTask(context.Context, *connect.Request[v1.FetchTaskRequest]) (*connect.Response[v1.FetchTaskResponse], error)
+ // UpdateTask updates the task status.
+ UpdateTask(context.Context, *connect.Request[v1.UpdateTaskRequest]) (*connect.Response[v1.UpdateTaskResponse], error)
+ // UpdateLog uploads log of the task.
+ UpdateLog(context.Context, *connect.Request[v1.UpdateLogRequest]) (*connect.Response[v1.UpdateLogResponse], error)
+}
+
+// NewRunnerServiceHandler builds an HTTP handler from the service implementation. It returns the
+// path on which to mount the handler and the handler itself.
+//
+// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
+// and JSON codecs. They also support gzip compression.
+func NewRunnerServiceHandler(svc RunnerServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
+ runnerServiceRegisterHandler := connect.NewUnaryHandler(
+ RunnerServiceRegisterProcedure,
+ svc.Register,
+ connect.WithSchema(runnerServiceRegisterMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ runnerServiceDeclareHandler := connect.NewUnaryHandler(
+ RunnerServiceDeclareProcedure,
+ svc.Declare,
+ connect.WithSchema(runnerServiceDeclareMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ runnerServiceFetchTaskHandler := connect.NewUnaryHandler(
+ RunnerServiceFetchTaskProcedure,
+ svc.FetchTask,
+ connect.WithSchema(runnerServiceFetchTaskMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ runnerServiceUpdateTaskHandler := connect.NewUnaryHandler(
+ RunnerServiceUpdateTaskProcedure,
+ svc.UpdateTask,
+ connect.WithSchema(runnerServiceUpdateTaskMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ runnerServiceUpdateLogHandler := connect.NewUnaryHandler(
+ RunnerServiceUpdateLogProcedure,
+ svc.UpdateLog,
+ connect.WithSchema(runnerServiceUpdateLogMethodDescriptor),
+ connect.WithHandlerOptions(opts...),
+ )
+ return "/runner.v1.RunnerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.Path {
+ case RunnerServiceRegisterProcedure:
+ runnerServiceRegisterHandler.ServeHTTP(w, r)
+ case RunnerServiceDeclareProcedure:
+ runnerServiceDeclareHandler.ServeHTTP(w, r)
+ case RunnerServiceFetchTaskProcedure:
+ runnerServiceFetchTaskHandler.ServeHTTP(w, r)
+ case RunnerServiceUpdateTaskProcedure:
+ runnerServiceUpdateTaskHandler.ServeHTTP(w, r)
+ case RunnerServiceUpdateLogProcedure:
+ runnerServiceUpdateLogHandler.ServeHTTP(w, r)
+ default:
+ http.NotFound(w, r)
+ }
+ })
+}
+
+// UnimplementedRunnerServiceHandler returns CodeUnimplemented from all methods.
+type UnimplementedRunnerServiceHandler struct{}
+
+func (UnimplementedRunnerServiceHandler) Register(context.Context, *connect.Request[v1.RegisterRequest]) (*connect.Response[v1.RegisterResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("runner.v1.RunnerService.Register is not implemented"))
+}
+
+func (UnimplementedRunnerServiceHandler) Declare(context.Context, *connect.Request[v1.DeclareRequest]) (*connect.Response[v1.DeclareResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("runner.v1.RunnerService.Declare is not implemented"))
+}
+
+func (UnimplementedRunnerServiceHandler) FetchTask(context.Context, *connect.Request[v1.FetchTaskRequest]) (*connect.Response[v1.FetchTaskResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("runner.v1.RunnerService.FetchTask is not implemented"))
+}
+
+func (UnimplementedRunnerServiceHandler) UpdateTask(context.Context, *connect.Request[v1.UpdateTaskRequest]) (*connect.Response[v1.UpdateTaskResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("runner.v1.RunnerService.UpdateTask is not implemented"))
+}
+
+func (UnimplementedRunnerServiceHandler) UpdateLog(context.Context, *connect.Request[v1.UpdateLogRequest]) (*connect.Response[v1.UpdateLogResponse], error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("runner.v1.RunnerService.UpdateLog is not implemented"))
+}
diff --git a/vendor/code.gitea.io/actions-proto-go/runner/v1/services.pb.go b/vendor/code.gitea.io/actions-proto-go/runner/v1/services.pb.go
new file mode 100644
index 0000000..851bf85
--- /dev/null
+++ b/vendor/code.gitea.io/actions-proto-go/runner/v1/services.pb.go
@@ -0,0 +1,118 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.28.1
+// protoc (unknown)
+// source: runner/v1/services.proto
+
+package runnerv1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+var File_runner_v1_services_proto protoreflect.FileDescriptor
+
+var file_runner_v1_services_proto_rawDesc = []byte{
+ 0x0a, 0x18, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x18, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31,
+ 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32,
+ 0xfb, 0x02, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x12, 0x45, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1a, 0x2e,
+ 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
+ 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x07, 0x44, 0x65, 0x63, 0x6c,
+ 0x61, 0x72, 0x65, 0x12, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
+ 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
+ 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x61,
+ 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09,
+ 0x46, 0x65, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
+ 0x76, 0x31, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x54, 0x61, 0x73, 0x6b, 0x12, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67,
+ 0x12, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e,
+ 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x96, 0x01,
+ 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42,
+ 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
+ 0x5a, 0x31, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x69, 0x6f, 0x2f,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x67, 0x6f,
+ 0x2f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x6e, 0x65,
+ 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x52, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5c, 0x56,
+ 0x31, 0xe2, 0x02, 0x15, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50,
+ 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x52, 0x75, 0x6e, 0x6e,
+ 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var file_runner_v1_services_proto_goTypes = []interface{}{
+ (*RegisterRequest)(nil), // 0: runner.v1.RegisterRequest
+ (*DeclareRequest)(nil), // 1: runner.v1.DeclareRequest
+ (*FetchTaskRequest)(nil), // 2: runner.v1.FetchTaskRequest
+ (*UpdateTaskRequest)(nil), // 3: runner.v1.UpdateTaskRequest
+ (*UpdateLogRequest)(nil), // 4: runner.v1.UpdateLogRequest
+ (*RegisterResponse)(nil), // 5: runner.v1.RegisterResponse
+ (*DeclareResponse)(nil), // 6: runner.v1.DeclareResponse
+ (*FetchTaskResponse)(nil), // 7: runner.v1.FetchTaskResponse
+ (*UpdateTaskResponse)(nil), // 8: runner.v1.UpdateTaskResponse
+ (*UpdateLogResponse)(nil), // 9: runner.v1.UpdateLogResponse
+}
+var file_runner_v1_services_proto_depIdxs = []int32{
+ 0, // 0: runner.v1.RunnerService.Register:input_type -> runner.v1.RegisterRequest
+ 1, // 1: runner.v1.RunnerService.Declare:input_type -> runner.v1.DeclareRequest
+ 2, // 2: runner.v1.RunnerService.FetchTask:input_type -> runner.v1.FetchTaskRequest
+ 3, // 3: runner.v1.RunnerService.UpdateTask:input_type -> runner.v1.UpdateTaskRequest
+ 4, // 4: runner.v1.RunnerService.UpdateLog:input_type -> runner.v1.UpdateLogRequest
+ 5, // 5: runner.v1.RunnerService.Register:output_type -> runner.v1.RegisterResponse
+ 6, // 6: runner.v1.RunnerService.Declare:output_type -> runner.v1.DeclareResponse
+ 7, // 7: runner.v1.RunnerService.FetchTask:output_type -> runner.v1.FetchTaskResponse
+ 8, // 8: runner.v1.RunnerService.UpdateTask:output_type -> runner.v1.UpdateTaskResponse
+ 9, // 9: runner.v1.RunnerService.UpdateLog:output_type -> runner.v1.UpdateLogResponse
+ 5, // [5:10] is the sub-list for method output_type
+ 0, // [0:5] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_runner_v1_services_proto_init() }
+func file_runner_v1_services_proto_init() {
+ if File_runner_v1_services_proto != nil {
+ return
+ }
+ file_runner_v1_messages_proto_init()
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_runner_v1_services_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 0,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_runner_v1_services_proto_goTypes,
+ DependencyIndexes: file_runner_v1_services_proto_depIdxs,
+ }.Build()
+ File_runner_v1_services_proto = out.File
+ file_runner_v1_services_proto_rawDesc = nil
+ file_runner_v1_services_proto_goTypes = nil
+ file_runner_v1_services_proto_depIdxs = nil
+}
diff --git a/vendor/code.gitea.io/gitea-vet/.changelog.yml b/vendor/code.gitea.io/gitea-vet/.changelog.yml
new file mode 100644
index 0000000..b3e6446
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.changelog.yml
@@ -0,0 +1,30 @@
+# The full repository name
+repo: gitea/gitea-vet
+
+# Service type (gitea or github)
+service: gitea
+
+# Base URL for Gitea instance if using gitea service type (optional)
+base-url: https://gitea.com
+
+# Changelog groups and which labeled PRs to add to each group
+groups:
+ -
+ name: BREAKING
+ labels:
+ - breaking
+ -
+ name: FEATURES
+ labels:
+ - feature
+ -
+ name: BUGFIXES
+ labels:
+ - bug
+ -
+ name: ENHANCEMENTS
+ labels:
+ - enhancement
+
+# regex indicating which labels to skip for the changelog
+skip-labels: skip-changelog|backport\/.+
diff --git a/vendor/code.gitea.io/gitea-vet/.gitignore b/vendor/code.gitea.io/gitea-vet/.gitignore
new file mode 100644
index 0000000..b89cc42
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.gitignore
@@ -0,0 +1,5 @@
+# GoLand
+.idea/
+
+# Binaries
+/gitea-vet*
\ No newline at end of file
diff --git a/vendor/code.gitea.io/gitea-vet/.golangci.yml b/vendor/code.gitea.io/gitea-vet/.golangci.yml
new file mode 100644
index 0000000..0914b19
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.golangci.yml
@@ -0,0 +1,19 @@
+linters:
+ enable:
+ - dogsled
+ - dupl
+ - errcheck
+ - gocognit
+ - goconst
+ - gocritic
+ - gocyclo
+ - gofmt
+ - revive
+ - gosimple
+ - govet
+ - misspell
+ - prealloc
+ - staticcheck
+ - typecheck
+ - unparam
+ - unused
diff --git a/vendor/code.gitea.io/gitea-vet/CHANGELOG.md b/vendor/code.gitea.io/gitea-vet/CHANGELOG.md
new file mode 100644
index 0000000..fca500a
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/CHANGELOG.md
@@ -0,0 +1,21 @@
+## [v0.2.2](https://gitea.com/gitea/gitea-vet/releases/tag/v0.2.2) - 2022-12-02
+
+* FEATURES
+ * Check SPDX-License-Identifier (#21)
+ * Add gitea's go-crypto fork to deny list (#19)
+ * Add "encoding/json" to denylist (#18)
+ * Add denylist import (#17)
+ * If you open a session either return it or close it (#16)
+ * Don't import git on models (#12)
+
+## [v0.2.1](https://gitea.com/gitea/gitea-vet/releases/tag/v0.2.1) - 2020-08-15
+
+* BUGFIXES
+ * Split migration check to Deps and Imports (#9)
+
+## [0.2.0](https://gitea.com/gitea/gitea-vet/pulls?q=&type=all&state=closed&milestone=1272) - 2020-07-20
+
+* FEATURES
+ * Add migrations check (#5)
+* BUGFIXES
+ * Correct Import Paths (#6)
diff --git a/vendor/code.gitea.io/gitea-vet/LICENSE b/vendor/code.gitea.io/gitea-vet/LICENSE
new file mode 100644
index 0000000..a39c526
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 The Gitea Authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/code.gitea.io/gitea-vet/Makefile b/vendor/code.gitea.io/gitea-vet/Makefile
new file mode 100644
index 0000000..4bb377e
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/Makefile
@@ -0,0 +1,22 @@
+GO ?= go
+
+.PHONY: build
+build:
+ $(GO) build
+
+.PHONY: fmt
+fmt:
+ $(GO) fmt ./...
+
+.PHONY: vet
+vet: build
+ $(GO) vet ./...
+ $(GO) vet -vettool=gitea-vet ./...
+
+.PHONY: lint
+lint:
+ @hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+ export BINARY="golangci-lint"; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell $(GO) env GOPATH)/bin v1.52.2; \
+ fi
+ golangci-lint run --timeout 10m
diff --git a/vendor/code.gitea.io/gitea-vet/README.md b/vendor/code.gitea.io/gitea-vet/README.md
new file mode 100644
index 0000000..5d3d097
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/README.md
@@ -0,0 +1,11 @@
+# gitea-vet
+
+[](https://drone.gitea.com/gitea/gitea-vet)
+
+`go vet` tool for Gitea
+
+| Analyzer | Description |
+|------------|-----------------------------------------------------------------------------|
+| Imports | Checks for import sorting. stdlib->code.gitea.io->other |
+| License | Checks file headers for some form of `Copyright...YYYY...Gitea/Gogs` |
+| Migrations | Checks for black-listed packages in `code.gitea.io/gitea/models/migrations` |
diff --git a/vendor/code.gitea.io/gitea-vet/checks/imports.go b/vendor/code.gitea.io/gitea-vet/checks/imports.go
new file mode 100644
index 0000000..17190c5
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/checks/imports.go
@@ -0,0 +1,45 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package checks
+
+import (
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var Imports = &analysis.Analyzer{
+ Name: "imports",
+ Doc: "check for import order",
+ Run: runImports,
+}
+
+func runImports(pass *analysis.Pass) (interface{}, error) {
+ for _, file := range pass.Files {
+ level := 0
+ for _, im := range file.Imports {
+ var lvl int
+ val := im.Path.Value
+ switch {
+ case importHasPrefix(val, "code.gitea.io"):
+ lvl = 2
+ case strings.Contains(val, "."):
+ lvl = 3
+ default:
+ lvl = 1
+ }
+
+ if lvl < level {
+ pass.Reportf(file.Pos(), "Imports are sorted wrong")
+ break
+ }
+ level = lvl
+ }
+ }
+ return nil, nil
+}
+
+func importHasPrefix(s, p string) bool {
+ return strings.HasPrefix(s, "\""+p)
+}
diff --git a/vendor/code.gitea.io/gitea-vet/checks/license.go b/vendor/code.gitea.io/gitea-vet/checks/license.go
new file mode 100644
index 0000000..11679c2
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/checks/license.go
@@ -0,0 +1,80 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package checks
+
+import (
+ "regexp"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var (
+ copyrightRegx = regexp.MustCompile(`.*Copyright.*\d{4}.*(Gitea|Gogs)`)
+ identifierRegx = regexp.MustCompile(`SPDX-License-Identifier: [\w.-]+`)
+
+ goGenerate = "//go:generate"
+ buildTag = "// +build"
+)
+
+var License = &analysis.Analyzer{
+ Name: "license",
+ Doc: "check for a copyright header",
+ Run: runLicense,
+}
+
+func runLicense(pass *analysis.Pass) (interface{}, error) {
+ for _, file := range pass.Files {
+ if len(file.Comments) == 0 {
+ pass.Reportf(file.Pos(), "Copyright not found")
+ continue
+ }
+
+ if len(file.Comments[0].List) == 0 {
+ pass.Reportf(file.Pos(), "Copyright not found or wrong")
+ continue
+ }
+
+ commentGroup := 0
+ if strings.HasPrefix(file.Comments[0].List[0].Text, goGenerate) {
+ if len(file.Comments[0].List) > 1 {
+ pass.Reportf(file.Pos(), "Must be an empty line between the go:generate and the Copyright")
+ continue
+ }
+ commentGroup++
+ }
+
+ if strings.HasPrefix(file.Comments[0].List[0].Text, buildTag) {
+ commentGroup++
+ }
+
+ if len(file.Comments) < commentGroup+1 {
+ pass.Reportf(file.Pos(), "Copyright not found")
+ continue
+ }
+
+ if len(file.Comments[commentGroup].List) < 1 {
+ pass.Reportf(file.Pos(), "Copyright not found or wrong")
+ continue
+ }
+
+ var copyright, identifier bool
+ for _, comment := range file.Comments[commentGroup].List {
+ if copyrightRegx.MatchString(comment.Text) {
+ copyright = true
+ }
+ if identifierRegx.MatchString(comment.Text) {
+ identifier = true
+ }
+ }
+
+ if !copyright {
+ pass.Reportf(file.Pos(), "Copyright did not match check")
+ }
+ if !identifier {
+ pass.Reportf(file.Pos(), "SPDX-License-Identifier did not match check")
+ }
+ }
+ return nil, nil
+}
diff --git a/vendor/code.gitea.io/gitea-vet/checks/migrations.go b/vendor/code.gitea.io/gitea-vet/checks/migrations.go
new file mode 100644
index 0000000..d139f79
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/checks/migrations.go
@@ -0,0 +1,76 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package checks
+
+import (
+ "errors"
+ "os/exec"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var Migrations = &analysis.Analyzer{
+ Name: "migrations",
+ Doc: "check migrations for black-listed packages.",
+ Run: checkMigrations,
+}
+
+var (
+ migrationDepBlockList = []string{
+ "code.gitea.io/gitea/models",
+ }
+ migrationImpBlockList = []string{
+ "code.gitea.io/gitea/modules/structs",
+ }
+)
+
+func checkMigrations(pass *analysis.Pass) (interface{}, error) {
+ if !strings.EqualFold(pass.Pkg.Path(), "code.gitea.io/gitea/models/migrations") {
+ return nil, nil
+ }
+
+ if _, err := exec.LookPath("go"); err != nil {
+ return nil, errors.New("go was not found in the PATH")
+ }
+
+ depsCmd := exec.Command("go", "list", "-f", `{{join .Deps "\n"}}`, "code.gitea.io/gitea/models/migrations")
+ depsOut, err := depsCmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ deps := strings.Split(string(depsOut), "\n")
+ for _, dep := range deps {
+ if stringInSlice(dep, migrationDepBlockList) {
+ pass.Reportf(0, "code.gitea.io/gitea/models/migrations cannot depend on the following packages: %s", migrationDepBlockList)
+ return nil, nil
+ }
+ }
+
+ impsCmd := exec.Command("go", "list", "-f", `{{join .Imports "\n"}}`, "code.gitea.io/gitea/models/migrations")
+ impsOut, err := impsCmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ imps := strings.Split(string(impsOut), "\n")
+ for _, imp := range imps {
+ if stringInSlice(imp, migrationImpBlockList) {
+ pass.Reportf(0, "code.gitea.io/gitea/models/migrations cannot import the following packages: %s", migrationImpBlockList)
+ return nil, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func stringInSlice(needle string, haystack []string) bool {
+ for _, h := range haystack {
+ if strings.EqualFold(needle, h) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/code.gitea.io/gitea-vet/checks/models.go b/vendor/code.gitea.io/gitea-vet/checks/models.go
new file mode 100644
index 0000000..acb83b1
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/checks/models.go
@@ -0,0 +1,243 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package checks
+
+import (
+ "bytes"
+ "errors"
+ "go/ast"
+ "go/format"
+ "go/token"
+ "os/exec"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var Models = &analysis.Analyzer{
+ Name: "models",
+ Doc: "check models for black-listed packages.",
+ Run: checkModels,
+}
+
+var ModelsSession = &analysis.Analyzer{
+ Name: "modelssession",
+ Doc: "check models for misuse of session.",
+ Run: checkModelsSession,
+}
+
+var (
+ modelsImpBlockList = []string{
+ "code.gitea.io/gitea/modules/git",
+ }
+)
+
+func checkModels(pass *analysis.Pass) (interface{}, error) {
+ if !strings.EqualFold(pass.Pkg.Path(), "code.gitea.io/gitea/models") {
+ return nil, nil
+ }
+
+ if _, err := exec.LookPath("go"); err != nil {
+ return nil, errors.New("go was not found in the PATH")
+ }
+
+ impsCmd := exec.Command("go", "list", "-f", `{{join .Imports "\n"}}`, "code.gitea.io/gitea/models")
+ impsOut, err := impsCmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ imps := strings.Split(string(impsOut), "\n")
+ for _, imp := range imps {
+ if stringInSlice(imp, modelsImpBlockList) {
+ pass.Reportf(0, "code.gitea.io/gitea/models cannot import the following packages: %s", modelsImpBlockList)
+ return nil, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func checkModelsSession(pass *analysis.Pass) (interface{}, error) {
+ if !strings.EqualFold(pass.Pkg.Path(), "code.gitea.io/gitea/models") {
+ return nil, nil
+ }
+
+ for _, file := range pass.Files {
+ for _, decl := range file.Decls {
+ // We only care about function declarations
+ fnDecl, ok := decl.(*ast.FuncDecl)
+ if !ok {
+ continue
+ }
+
+ fnname := formatFunctionName(fnDecl)
+
+ // OK now we to step through each line in the function and ensure that if we open a session we close it or return the session
+ w := walker{
+ fname: file.Name.String(),
+ fnname: fnname,
+ pass: pass,
+ }
+ ast.Walk(&w, fnDecl.Body)
+
+ // Finally we may have a named return so we need to check if the session is returned as one of these
+ if w.HasUnclosedSession() && w.sessionName != "" {
+ w.closesSession = fnDeclHasNamedReturn(fnDecl, w.sessionName)
+ }
+
+ if w.HasUnclosedSession() {
+ pass.Reportf(fnDecl.Pos(), "%s opens session but does not close it", fnname)
+ }
+ }
+ }
+
+ return nil, nil
+}
+
+// fnDeclHasNamedReturn checks if the function declaration has a named return with the provided name
+func fnDeclHasNamedReturn(fnDecl *ast.FuncDecl, name string) bool {
+ if fnDecl.Type.Results == nil {
+ return false
+ }
+ for _, result := range fnDecl.Type.Results.List {
+ if len(result.Names) != 1 {
+ continue
+ }
+ if result.Names[0].Name == name {
+ return true
+ }
+ }
+ return false
+}
+
+// formatNode is a convenience function for printing a node
+func formatNode(node ast.Node) string {
+ buf := new(bytes.Buffer)
+ _ = format.Node(buf, token.NewFileSet(), node)
+ return buf.String()
+}
+
+// formatFunctionName returns the function name as called by the source
+func formatFunctionName(fnDecl *ast.FuncDecl) string {
+ fnname := fnDecl.Name.Name
+ if fnDecl.Recv != nil && fnDecl.Recv.List[fnDecl.Recv.NumFields()-1] != nil {
+ ns := formatNode(fnDecl.Recv.List[fnDecl.Recv.NumFields()-1].Type)
+ if ns[0] == '*' {
+ ns = ns[1:]
+ }
+ fnname = ns + "." + fnname
+ }
+ return fnname
+}
+
+// walker looks for unclosed sessions
+type walker struct {
+ fname string
+ fnname string
+ pass *analysis.Pass
+ createsSession bool
+ closesSession bool
+ sessionName string
+}
+
+func (w *walker) HasUnclosedSession() bool {
+ return w.createsSession && !w.closesSession
+}
+
+func (w *walker) Visit(node ast.Node) ast.Visitor {
+ if node == nil {
+ return nil
+ }
+
+ switch t := node.(type) {
+
+ case *ast.ExprStmt:
+ if isCloseSessionExpr(t.X, w.sessionName) {
+ w.closesSession = true
+ return nil
+ }
+ case *ast.AssignStmt:
+ if len(t.Lhs) != 1 && len(t.Rhs) != 1 {
+ break
+ }
+
+ name, ok := t.Lhs[0].(*ast.Ident)
+ if !ok {
+ break
+ }
+
+ if isNewSession(t.Rhs[0]) {
+ w.createsSession = true
+ w.sessionName = name.Name
+ return nil
+ }
+ if isCloseSessionExpr(t.Rhs[0], w.sessionName) {
+ w.closesSession = true
+ return nil
+ }
+ case *ast.DeferStmt:
+ if isCloseSessionExpr(t.Call, w.sessionName) {
+ w.closesSession = true
+ return nil
+ }
+ case *ast.ReturnStmt:
+ for _, expr := range t.Results {
+ id, ok := expr.(*ast.Ident)
+ if !ok {
+ continue
+ }
+ if w.sessionName != "" && id.Name == w.sessionName {
+ w.closesSession = true
+ }
+ }
+ }
+
+ return w
+}
+
+// isCloseSessionExpr checks whether a provided expression represents a call to sess.Close
+func isCloseSessionExpr(expr ast.Expr, name string) bool {
+ if name == "" {
+ return false
+ }
+ call, ok := expr.(*ast.CallExpr)
+ if ok {
+ expr = call.Fun
+ }
+ sel, ok := expr.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+ id, ok := sel.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ if id.Name != name || sel.Sel.Name != "Close" {
+ return false
+ }
+
+ return true
+}
+
+// isNewSession checks whether a provided expression represents a call to x.NewSession()
+func isNewSession(expr ast.Expr) bool {
+ value, ok := expr.(*ast.CallExpr)
+ if !ok {
+ return false
+ }
+ sel, ok := value.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+ id, ok := sel.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+ if id.Name != "x" || sel.Sel.Name != "NewSession" {
+ return false
+ }
+ return true
+}
diff --git a/vendor/code.gitea.io/gitea-vet/main.go b/vendor/code.gitea.io/gitea-vet/main.go
new file mode 100644
index 0000000..7baec19
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/main.go
@@ -0,0 +1,19 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package main
+
+import (
+ "code.gitea.io/gitea-vet/checks"
+
+ "golang.org/x/tools/go/analysis/unitchecker"
+)
+
+func main() {
+ unitchecker.Main(
+ checks.Imports,
+ checks.License,
+ checks.Migrations,
+ checks.ModelsSession,
+ )
+}
diff --git a/vendor/connectrpc.com/connect/.gitignore b/vendor/connectrpc.com/connect/.gitignore
new file mode 100644
index 0000000..3553143
--- /dev/null
+++ b/vendor/connectrpc.com/connect/.gitignore
@@ -0,0 +1,5 @@
+/.tmp/
+*.pprof
+*.svg
+cover.out
+connect.test
diff --git a/vendor/connectrpc.com/connect/.golangci.yml b/vendor/connectrpc.com/connect/.golangci.yml
new file mode 100644
index 0000000..fc62729
--- /dev/null
+++ b/vendor/connectrpc.com/connect/.golangci.yml
@@ -0,0 +1,134 @@
+run:
+ skip-dirs-use-default: false
+linters-settings:
+ errcheck:
+ check-type-assertions: true
+ exhaustruct:
+ include:
+ # No zero values for param structs.
+ - 'connectrpc\.com/connect\..*[pP]arams'
+ forbidigo:
+ forbid:
+ - '^fmt\.Print'
+ - '^log\.'
+ - '^print$'
+ - '^println$'
+ - '^panic$'
+ godox:
+ # TODO, OPT, etc. comments are fine to commit. Use FIXME comments for
+ # temporary hacks, and use godox to prevent committing them.
+ keywords: [FIXME]
+ importas:
+ no-unaliased: true
+ alias:
+ - pkg: connectrpc.com/connect
+ alias: connect
+ - pkg: connectrpc.com/connect/internal/gen/connect/ping/v1
+ alias: pingv1
+ varnamelen:
+ ignore-decls:
+ - T any
+ - i int
+ - wg sync.WaitGroup
+linters:
+ enable-all: true
+ disable:
+ - cyclop # covered by gocyclo
+ - deadcode # abandoned
+ - depguard # unnecessary for small libraries
+ - exhaustivestruct # replaced by exhaustruct
+ - funlen # rely on code review to limit function length
+ - gocognit # dubious "cognitive overhead" quantification
+ - gofumpt # prefer standard gofmt
+ - goimports # rely on gci instead
+ - golint # deprecated by Go team
+ - gomnd # some unnamed constants are okay
+ - ifshort # deprecated by author
+ - inamedparam # convention is not followed
+ - interfacer # deprecated by author
+ - ireturn # "accept interfaces, return structs" isn't ironclad
+ - lll # don't want hard limits for line length
+ - maintidx # covered by gocyclo
+ - maligned # readability trumps efficient struct packing
+ - nlreturn # generous whitespace violates house style
+ - nonamedreturns # named returns are fine; it's *bare* returns that are bad
+ - nosnakecase # deprecated in https://github.com/golangci/golangci-lint/pull/3065
+ - protogetter # too many false positives
+ - scopelint # deprecated by author
+ - structcheck # abandoned
+ - testpackage # internal tests are fine
+ - varcheck # abandoned
+ - wrapcheck # don't _always_ need to wrap errors
+ - wsl # generous whitespace violates house style
+issues:
+ exclude:
+ # Don't ban use of fmt.Errorf to create new errors, but the remaining
+ # checks from err113 are useful.
+ - "err113: do not define dynamic errors.*"
+
+ exclude-rules:
+ # If future reflect.Kinds are nil-able, we'll find out when a test fails.
+ - linters: [exhaustive]
+ path: internal/assert/assert.go
+ # We need our duplex HTTP call to have access to the context.
+ - linters: [containedctx]
+ path: duplex_http_call.go
+ # We need to init a global in-mem HTTP server for testable examples.
+ - linters: [gochecknoinits, gochecknoglobals]
+ path: example_init_test.go
+ # We need to initialize default grpc User-Agent
+ - linters: [gochecknoglobals]
+ path: protocol_grpc.go
+ # We need to initialize default connect User-Agent
+ - linters: [gochecknoglobals]
+ path: protocol_connect.go
+ # We purposefully do an ineffectual assignment for an example.
+ - linters: [ineffassign]
+ path: client_example_test.go
+ # The generated file is effectively a global receiver.
+ - linters: [varnamelen]
+ path: cmd/protoc-gen-connect-go
+ text: "parameter name 'g' is too short"
+ # Thorough error logging and timeout config make this example unreadably long.
+ - linters: [errcheck, gosec]
+ path: error_writer_example_test.go
+ # It should be crystal clear that Connect uses plain *http.Clients.
+ - linters: [revive, stylecheck]
+ path: client_example_test.go
+ # Don't complain about timeout management or lack of output assertions in examples.
+ - linters: [gosec, testableexamples]
+ path: handler_example_test.go
+ # No output assertions needed for these examples.
+ - linters: [testableexamples]
+ path: error_writer_example_test.go
+ - linters: [testableexamples]
+ path: error_not_modified_example_test.go
+ - linters: [testableexamples]
+ path: error_example_test.go
+ # In examples, it's okay to use http.ListenAndServe.
+ - linters: [gosec]
+ path: error_not_modified_example_test.go
+ # There are many instances where we want to keep unused parameters
+ # as a matter of style or convention, for example when a context.Context
+ # is the first parameter, we choose to just globally ignore this.
+ - linters: [revive]
+ text: "^unused-parameter: "
+ # We want to return explicit nils in protocol_grpc.go
+ - linters: [revive]
+ text: "^if-return: "
+ path: protocol_grpc.go
+ # We want to return explicit nils in protocol_connect.go
+ - linters: [revive]
+ text: "^if-return: "
+ path: protocol_connect.go
+ # We want to return explicit nils in error_writer.go
+ - linters: [revive]
+ text: "^if-return: "
+ path: error_writer.go
+ # We want to set http.Server's logger
+ - linters: [forbidigo]
+ path: internal/memhttp
+ text: "use of `log.(New|Logger|Lshortfile)` forbidden by pattern .*"
+ # We want to show examples with http.Get
+ - linters: [noctx]
+ path: internal/memhttp/memhttp_test.go
diff --git a/vendor/connectrpc.com/connect/LICENSE b/vendor/connectrpc.com/connect/LICENSE
new file mode 100644
index 0000000..8b55ffa
--- /dev/null
+++ b/vendor/connectrpc.com/connect/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2021-2024 The Connect Authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/connectrpc.com/connect/MAINTAINERS.md b/vendor/connectrpc.com/connect/MAINTAINERS.md
new file mode 100644
index 0000000..129a3c0
--- /dev/null
+++ b/vendor/connectrpc.com/connect/MAINTAINERS.md
@@ -0,0 +1,12 @@
+Maintainers
+===========
+
+## Current
+* [Peter Edge](https://github.com/bufdev), [Buf](https://buf.build)
+* [Akshay Shah](https://github.com/akshayjshah), [Buf](https://buf.build)
+* [Josh Humphries](https://github.com/jhump), [Buf](https://buf.build)
+* [Matt Robenolt](https://github.com/mattrobenolt), [PlanetScale](https://planetscale.com)
+* [Edward McFarlane](https://github.com/emcfarlane), [Buf](https://buf.build)
+
+## Former
+* [Alex McKinney](https://github.com/amckinney)
diff --git a/vendor/connectrpc.com/connect/Makefile b/vendor/connectrpc.com/connect/Makefile
new file mode 100644
index 0000000..cb07829
--- /dev/null
+++ b/vendor/connectrpc.com/connect/Makefile
@@ -0,0 +1,117 @@
+# See https://tech.davis-hansson.com/p/make/
+SHELL := bash
+.DELETE_ON_ERROR:
+.SHELLFLAGS := -eu -o pipefail -c
+.DEFAULT_GOAL := all
+MAKEFLAGS += --warn-undefined-variables
+MAKEFLAGS += --no-builtin-rules
+MAKEFLAGS += --no-print-directory
+BIN := .tmp/bin
+export PATH := $(BIN):$(PATH)
+export GOBIN := $(abspath $(BIN))
+COPYRIGHT_YEARS := 2021-2024
+LICENSE_IGNORE := --ignore /testdata/
+
+.PHONY: help
+help: ## Describe useful make targets
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-30s %s\n", $$1, $$2}'
+
+.PHONY: all
+all: ## Build, test, and lint (default)
+ $(MAKE) test
+ $(MAKE) lint
+
+.PHONY: clean
+clean: ## Delete intermediate build artifacts
+ @# -X only removes untracked files, -d recurses into directories, -f actually removes files/dirs
+ git clean -Xdf
+
+.PHONY: test
+test: shorttest slowtest
+
+.PHONY: shorttest
+shorttest: build ## Run unit tests
+ go test -vet=off -race -cover -short ./...
+
+.PHONY: slowtest
+# Runs all tests, including known long/slow ones. The
+# race detector is not used for a few reasons:
+# 1. Race coverage of the short tests should be
+# adequate to catch race conditions.
+# 2. It slows tests down, which is not good if we
+# know these are already slow tests.
+# 3. Some of the slow tests can't repro issues and
+# find regressions as reliably with the race
+# detector enabled.
+slowtest: build
+ go test ./...
+
+.PHONY: runconformance
+runconformance: build ## Run conformance test suite
+ cd internal/conformance && ./runconformance.sh
+
+.PHONY: bench
+bench: BENCH ?= .*
+bench: build ## Run benchmarks for root package
+ go test -vet=off -run '^$$' -bench '$(BENCH)' -benchmem -cpuprofile cpu.pprof -memprofile mem.pprof .
+
+.PHONY: build
+build: generate ## Build all packages
+ go build ./...
+
+.PHONY: install
+install: ## Install all binaries
+ go install ./...
+
+.PHONY: lint
+lint: $(BIN)/golangci-lint $(BIN)/buf ## Lint Go and protobuf
+ go vet ./...
+ golangci-lint run --modules-download-mode=readonly --timeout=3m0s
+ buf lint
+ buf format -d --exit-code
+
+.PHONY: lintfix
+lintfix: $(BIN)/golangci-lint $(BIN)/buf ## Automatically fix some lint errors
+ golangci-lint run --fix --modules-download-mode=readonly --timeout=3m0s
+ buf format -w
+
+.PHONY: generate
+generate: $(BIN)/buf $(BIN)/protoc-gen-go $(BIN)/protoc-gen-connect-go $(BIN)/license-header ## Regenerate code and licenses
+ rm -rf internal/gen
+ PATH="$(abspath $(BIN))" buf generate
+ license-header \
+ --license-type apache \
+ --copyright-holder "The Connect Authors" \
+ --year-range "$(COPYRIGHT_YEARS)" $(LICENSE_IGNORE)
+
+.PHONY: upgrade
+upgrade: ## Upgrade dependencies
+ go get -u -t ./... && go mod tidy -v
+
+.PHONY: checkgenerate
+checkgenerate:
+ @# Used in CI to verify that `make generate` doesn't produce a diff.
+ test -z "$$(git status --porcelain | tee /dev/stderr)"
+
+.PHONY: $(BIN)/protoc-gen-connect-go
+$(BIN)/protoc-gen-connect-go:
+ @mkdir -p $(@D)
+ go build -o $(@) ./cmd/protoc-gen-connect-go
+
+$(BIN)/buf: Makefile
+ @mkdir -p $(@D)
+ go install github.com/bufbuild/buf/cmd/buf@v1.27.2
+
+$(BIN)/license-header: Makefile
+ @mkdir -p $(@D)
+ go install github.com/bufbuild/buf/private/pkg/licenseheader/cmd/license-header@v1.27.2
+
+$(BIN)/golangci-lint: Makefile
+ @mkdir -p $(@D)
+ go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2
+
+$(BIN)/protoc-gen-go: Makefile go.mod
+ @mkdir -p $(@D)
+ @# The version of protoc-gen-go is determined by the version in go.mod
+ go install google.golang.org/protobuf/cmd/protoc-gen-go
+
diff --git a/vendor/connectrpc.com/connect/README.md b/vendor/connectrpc.com/connect/README.md
new file mode 100644
index 0000000..082e72a
--- /dev/null
+++ b/vendor/connectrpc.com/connect/README.md
@@ -0,0 +1,185 @@
+Connect
+=======
+
+[](https://github.com/connectrpc/connect-go/actions/workflows/ci.yaml)
+[](https://goreportcard.com/report/connectrpc.com/connect)
+[](https://pkg.go.dev/connectrpc.com/connect)
+[][slack]
+
+Connect is a slim library for building browser and gRPC-compatible HTTP APIs.
+You write a short [Protocol Buffer][protobuf] schema and implement your
+application logic, and Connect generates code to handle marshaling, routing,
+compression, and content type negotiation. It also generates an idiomatic,
+type-safe client. Handlers and clients support three protocols: gRPC, gRPC-Web,
+and Connect's own protocol.
+
+The [Connect protocol][protocol] is a simple protocol that works over HTTP/1.1
+or HTTP/2. It takes the best portions of gRPC and gRPC-Web, including
+streaming, and packages them into a protocol that works equally well in
+browsers, monoliths, and microservices. Calling a Connect API is as easy as
+using `curl`. Try it with our live demo:
+
+```
+curl \
+ --header "Content-Type: application/json" \
+ --data '{"sentence": "I feel happy."}' \
+ https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say
+```
+
+Handlers and clients also support the gRPC and gRPC-Web protocols, including
+streaming, headers, trailers, and error details. gRPC-compatible [server
+reflection][grpcreflect] and [health checks][grpchealth] are available as
+standalone packages. Instead of cURL, we could call our API with a gRPC client:
+
+```
+go install github.com/bufbuild/buf/cmd/buf@latest
+buf curl --protocol grpc \
+ --data '{"sentence": "I feel happy."}' \
+ https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say
+```
+
+Under the hood, Connect is just [Protocol Buffers][protobuf] and the standard
+library: no custom HTTP implementation, no new name resolution or load
+balancing APIs, and no surprises. Everything you already know about `net/http`
+still applies, and any package that works with an `http.Server`, `http.Client`,
+or `http.Handler` also works with Connect.
+
+For more on Connect, see the [announcement blog post][blog], the documentation
+on [connectrpc.com][docs] (especially the [Getting Started] guide for Go), the
+[demo service][examples-go], or the [protocol specification][protocol].
+
+## A small example
+
+Curious what all this looks like in practice? From a [Protobuf
+schema](internal/proto/connect/ping/v1/ping.proto), we generate [a small RPC
+package](internal/gen/connect/ping/v1/pingv1connect/ping.connect.go). Using that
+package, we can build a server:
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+
+ "connectrpc.com/connect"
+ pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1"
+ "connectrpc.com/connect/internal/gen/connect/ping/v1/pingv1connect"
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/h2c"
+)
+
+type PingServer struct {
+ pingv1connect.UnimplementedPingServiceHandler // returns errors from all methods
+}
+
+func (ps *PingServer) Ping(
+ ctx context.Context,
+ req *connect.Request[pingv1.PingRequest],
+) (*connect.Response[pingv1.PingResponse], error) {
+ // connect.Request and connect.Response give you direct access to headers and
+ // trailers. No context-based nonsense!
+ log.Println(req.Header().Get("Some-Header"))
+ res := connect.NewResponse(&pingv1.PingResponse{
+ // req.Msg is a strongly-typed *pingv1.PingRequest, so we can access its
+ // fields without type assertions.
+ Number: req.Msg.Number,
+ })
+ res.Header().Set("Some-Other-Header", "hello!")
+ return res, nil
+}
+
+func main() {
+ mux := http.NewServeMux()
+ // The generated constructors return a path and a plain net/http
+ // handler.
+ mux.Handle(pingv1connect.NewPingServiceHandler(&PingServer{}))
+ err := http.ListenAndServe(
+ "localhost:8080",
+ // For gRPC clients, it's convenient to support HTTP/2 without TLS. You can
+ // avoid x/net/http2 by using http.ListenAndServeTLS.
+ h2c.NewHandler(mux, &http2.Server{}),
+ )
+ log.Fatalf("listen failed: %v", err)
+}
+```
+
+With that server running, you can make requests with any gRPC or Connect
+client. To write a client using Connect,
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+
+ "connectrpc.com/connect"
+ pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1"
+ "connectrpc.com/connect/internal/gen/connect/ping/v1/pingv1connect"
+)
+
+func main() {
+ client := pingv1connect.NewPingServiceClient(
+ http.DefaultClient,
+ "http://localhost:8080/",
+ )
+ req := connect.NewRequest(&pingv1.PingRequest{
+ Number: 42,
+ })
+ req.Header().Set("Some-Header", "hello from connect")
+ res, err := client.Ping(context.Background(), req)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ log.Println(res.Msg)
+ log.Println(res.Header().Get("Some-Other-Header"))
+}
+```
+
+Of course, `http.ListenAndServe` and `http.DefaultClient` aren't fit for
+production use! See Connect's [deployment docs][docs-deployment] for a guide to
+configuring timeouts, connection pools, observability, and h2c.
+
+## Ecosystem
+
+* [grpchealth]: gRPC-compatible health checks
+* [grpcreflect]: gRPC-compatible server reflection
+* [examples-go]: service powering demo.connectrpc.com, including bidi streaming
+* [connect-es]: Type-safe APIs with Protobuf and TypeScript
+* [Buf Studio]: web UI for ad-hoc RPCs
+* [conformance]: Connect, gRPC, and gRPC-Web interoperability tests
+
+## Status: Stable
+
+This module is stable. It supports:
+
+* The three most recent major releases of Go. Keep in mind that [only the last
+ two releases receive security patches][go-support-policy].
+* [APIv2] of Protocol Buffers in Go (`google.golang.org/protobuf`).
+
+Within those parameters, `connect` follows semantic versioning. We will
+_not_ make breaking changes in the 1.x series of releases.
+
+## Legal
+
+Offered under the [Apache 2 license][license].
+
+[APIv2]: https://blog.golang.org/protobuf-apiv2
+[Buf Studio]: https://buf.build/studio
+[Getting Started]: https://connectrpc.com/docs/go/getting-started
+[blog]: https://buf.build/blog/connect-a-better-grpc
+[conformance]: https://github.com/connectrpc/conformance
+[grpchealth]: https://github.com/connectrpc/grpchealth-go
+[grpcreflect]: https://github.com/connectrpc/grpcreflect-go
+[connect-es]: https://github.com/connectrpc/connect-es
+[examples-go]: https://github.com/connectrpc/examples-go
+[docs-deployment]: https://connectrpc.com/docs/go/deployment
+[docs]: https://connectrpc.com
+[go-support-policy]: https://golang.org/doc/devel/release#policy
+[license]: https://github.com/connectrpc/connect-go/blob/main/LICENSE
+[protobuf]: https://developers.google.com/protocol-buffers
+[protocol]: https://connectrpc.com/docs/protocol
+[slack]: https://buf.build/links/slack
diff --git a/vendor/connectrpc.com/connect/RELEASE.md b/vendor/connectrpc.com/connect/RELEASE.md
new file mode 100644
index 0000000..22364cd
--- /dev/null
+++ b/vendor/connectrpc.com/connect/RELEASE.md
@@ -0,0 +1,44 @@
+# Releasing connect-go
+
+This document outlines how to create a release of connect-go.
+
+1. Clone the repo, ensuring you have the latest main.
+
+2. On a new branch, open [connect.go](connect.go) and change the `Version` constant to an appropriate [semantic version](https://semver.org/). To select the correct version, look at the version number of the [latest release] and the changes that are included in this new release.
+ * If there are only bug fixes and no new features, remove the `-dev` suffix, set MINOR number to be equal to the [latest release], and set the PATCH number to be 1 more than the PATCH number of the [latest release].
+ * If there are features being released, remove the `-dev` suffix, set the MINOR number to be 1 more than the MINOR number of the [latest release], and set the PATCH number to `0`. In the common case, the diff here will just be to remove the `-dev` suffix.
+
+ ```patch
+ -const Version = "1.14.0-dev"
+ +const Version = "1.14.0"
+ ```
+
+3. Check for any changes in [cmd/protoc-gen-connect-go/main.go](cmd/protoc-gen-connect-go/main.go) that require a version restriction. A constant `IsAtLeastVersionX_Y_Z` should be defined in [connect.go](connect.go) if generated code has begun to use a new API. Make sure the generated code references this constant. If a new constant has been added since the last release, ensure that the name of the constant matches the version being released ([Example PR #496](https://github.com/connectrpc/connect-go/pull/496)).
+
+4. Open a PR titled "Prepare for vX.Y.Z" ([Example PR #661](https://github.com/connectrpc/connect-go/pull/661)) and a description tagging all current maintainers. Once it's reviewed and CI passes, merge it.
+
+ *Make sure no new commits are merged until the release is complete.*
+
+5. Review all commits in the new release and for each PR check an appropriate label is used and edit the title to be meaninful to end users. This will help auto-generated release notes match the final notes as closely as possible.
+
+6. Using the Github UI, create a new release.
+ - Under “Choose a tag”, type in “vX.Y.Z” to create a new tag for the release upon publish.
+ - Target the main branch.
+ - Title the Release “vX.Y.Z”.
+ - Click “set as latest release”.
+ - Set the last version as the “Previous tag”.
+ - Click “Generate release notes” to autogenerate release notes.
+ - Edit the release notes. A summary and other sub categories may be added if required but should, in most cases, be left as ### Enhancements and ### Bugfixes. Feel free to collect multiple small changes to docs or Github config into one line, but try to tag every contributor. Make especially sure to credit new external contributors!
+
+7. Publish the release.
+
+8. On a new branch, open [connect.go](connect.go) and change the `Version` to increment the minor tag and append the `-dev` suffix. Use the next minor release - we never anticipate bugs and patch releases.
+
+ ```patch
+ -const Version = "1.14.0"
+ +const Version = "1.15.0-dev"
+ ```
+
+9. Open a PR titled "Back to development" ([Example PR #662](https://github.com/connectrpc/connect-go/pull/662)). Once it's reviewed and CI passes, merge it.
+
+[latest release]: https://github.com/connectrpc/connect-go/releases/latest
diff --git a/vendor/connectrpc.com/connect/SECURITY.md b/vendor/connectrpc.com/connect/SECURITY.md
new file mode 100644
index 0000000..04dcde5
--- /dev/null
+++ b/vendor/connectrpc.com/connect/SECURITY.md
@@ -0,0 +1,5 @@
+Security Policy
+===============
+
+This project follows the [Connect security policy and reporting
+process](https://connectrpc.com/docs/governance/security).
diff --git a/vendor/connectrpc.com/connect/buf.gen.yaml b/vendor/connectrpc.com/connect/buf.gen.yaml
new file mode 100644
index 0000000..0989475
--- /dev/null
+++ b/vendor/connectrpc.com/connect/buf.gen.yaml
@@ -0,0 +1,12 @@
+version: v1
+managed:
+ enabled: true
+ go_package_prefix:
+ default: connectrpc.com/connect/internal/gen
+plugins:
+ - name: go
+ out: internal/gen
+ opt: paths=source_relative
+ - name: connect-go
+ out: internal/gen
+ opt: paths=source_relative
diff --git a/vendor/connectrpc.com/connect/buf.work.yaml b/vendor/connectrpc.com/connect/buf.work.yaml
new file mode 100644
index 0000000..30f1e1f
--- /dev/null
+++ b/vendor/connectrpc.com/connect/buf.work.yaml
@@ -0,0 +1,3 @@
+version: v1
+directories:
+ - internal/proto
diff --git a/vendor/connectrpc.com/connect/buffer_pool.go b/vendor/connectrpc.com/connect/buffer_pool.go
new file mode 100644
index 0000000..8ac68db
--- /dev/null
+++ b/vendor/connectrpc.com/connect/buffer_pool.go
@@ -0,0 +1,54 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bytes"
+ "sync"
+)
+
+const (
+ initialBufferSize = 512
+ maxRecycleBufferSize = 8 * 1024 * 1024 // if >8MiB, don't hold onto a buffer
+)
+
+type bufferPool struct {
+ sync.Pool
+}
+
+func newBufferPool() *bufferPool {
+ return &bufferPool{
+ Pool: sync.Pool{
+ New: func() any {
+ return bytes.NewBuffer(make([]byte, 0, initialBufferSize))
+ },
+ },
+ }
+}
+
+func (b *bufferPool) Get() *bytes.Buffer {
+ if buf, ok := b.Pool.Get().(*bytes.Buffer); ok {
+ return buf
+ }
+ return bytes.NewBuffer(make([]byte, 0, initialBufferSize))
+}
+
+func (b *bufferPool) Put(buffer *bytes.Buffer) {
+ if buffer.Cap() > maxRecycleBufferSize {
+ return
+ }
+ buffer.Reset()
+ b.Pool.Put(buffer)
+}
diff --git a/vendor/connectrpc.com/connect/client.go b/vendor/connectrpc.com/connect/client.go
new file mode 100644
index 0000000..1a7b1d6
--- /dev/null
+++ b/vendor/connectrpc.com/connect/client.go
@@ -0,0 +1,285 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Client is a reusable, concurrency-safe client for a single procedure.
+// Depending on the procedure's type, use the CallUnary, CallClientStream,
+// CallServerStream, or CallBidiStream method.
+//
+// By default, clients use the Connect protocol with the binary Protobuf Codec,
+// ask for gzipped responses, and send uncompressed requests. To use the gRPC
+// or gRPC-Web protocols, use the [WithGRPC] or [WithGRPCWeb] options.
+type Client[Req, Res any] struct {
+ config *clientConfig
+ callUnary func(context.Context, *Request[Req]) (*Response[Res], error)
+ protocolClient protocolClient
+ err error
+}
+
+// NewClient constructs a new Client.
+func NewClient[Req, Res any](httpClient HTTPClient, url string, options ...ClientOption) *Client[Req, Res] {
+ client := &Client[Req, Res]{}
+ config, err := newClientConfig(url, options)
+ if err != nil {
+ client.err = err
+ return client
+ }
+ client.config = config
+ protocolClient, protocolErr := client.config.Protocol.NewClient(
+ &protocolClientParams{
+ CompressionName: config.RequestCompressionName,
+ CompressionPools: newReadOnlyCompressionPools(
+ config.CompressionPools,
+ config.CompressionNames,
+ ),
+ Codec: config.Codec,
+ Protobuf: config.protobuf(),
+ CompressMinBytes: config.CompressMinBytes,
+ HTTPClient: httpClient,
+ URL: config.URL,
+ BufferPool: config.BufferPool,
+ ReadMaxBytes: config.ReadMaxBytes,
+ SendMaxBytes: config.SendMaxBytes,
+ EnableGet: config.EnableGet,
+ GetURLMaxBytes: config.GetURLMaxBytes,
+ GetUseFallback: config.GetUseFallback,
+ },
+ )
+ if protocolErr != nil {
+ client.err = protocolErr
+ return client
+ }
+ client.protocolClient = protocolClient
+ // Rather than applying unary interceptors along the hot path, we can do it
+ // once at client creation.
+ unarySpec := config.newSpec(StreamTypeUnary)
+ unaryFunc := UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) {
+ conn := client.protocolClient.NewConn(ctx, unarySpec, request.Header())
+ conn.onRequestSend(func(r *http.Request) {
+ request.setRequestMethod(r.Method)
+ })
+ // Send always returns an io.EOF unless the error is from the client-side.
+ // We want the user to continue to call Receive in those cases to get the
+ // full error from the server-side.
+ if err := conn.Send(request.Any()); err != nil && !errors.Is(err, io.EOF) {
+ _ = conn.CloseRequest()
+ _ = conn.CloseResponse()
+ return nil, err
+ }
+ if err := conn.CloseRequest(); err != nil {
+ _ = conn.CloseResponse()
+ return nil, err
+ }
+ response, err := receiveUnaryResponse[Res](conn, config.Initializer)
+ if err != nil {
+ _ = conn.CloseResponse()
+ return nil, err
+ }
+ return response, conn.CloseResponse()
+ })
+ if interceptor := config.Interceptor; interceptor != nil {
+ unaryFunc = interceptor.WrapUnary(unaryFunc)
+ }
+ client.callUnary = func(ctx context.Context, request *Request[Req]) (*Response[Res], error) {
+ // To make the specification, peer, and RPC headers visible to the full
+ // interceptor chain (as though they were supplied by the caller), we'll
+ // add them here.
+ request.spec = unarySpec
+ request.peer = client.protocolClient.Peer()
+ protocolClient.WriteRequestHeader(StreamTypeUnary, request.Header())
+ response, err := unaryFunc(ctx, request)
+ if err != nil {
+ return nil, err
+ }
+ typed, ok := response.(*Response[Res])
+ if !ok {
+ return nil, errorf(CodeInternal, "unexpected client response type %T", response)
+ }
+ return typed, nil
+ }
+ return client
+}
+
+// CallUnary calls a request-response procedure.
+func (c *Client[Req, Res]) CallUnary(ctx context.Context, request *Request[Req]) (*Response[Res], error) {
+ if c.err != nil {
+ return nil, c.err
+ }
+ return c.callUnary(ctx, request)
+}
+
+// CallClientStream calls a client streaming procedure.
+func (c *Client[Req, Res]) CallClientStream(ctx context.Context) *ClientStreamForClient[Req, Res] {
+ if c.err != nil {
+ return &ClientStreamForClient[Req, Res]{err: c.err}
+ }
+ return &ClientStreamForClient[Req, Res]{
+ conn: c.newConn(ctx, StreamTypeClient, nil),
+ initializer: c.config.Initializer,
+ }
+}
+
+// CallServerStream calls a server streaming procedure.
+func (c *Client[Req, Res]) CallServerStream(ctx context.Context, request *Request[Req]) (*ServerStreamForClient[Res], error) {
+ if c.err != nil {
+ return nil, c.err
+ }
+ conn := c.newConn(ctx, StreamTypeServer, func(r *http.Request) {
+ request.method = r.Method
+ })
+ request.spec = conn.Spec()
+ request.peer = conn.Peer()
+ mergeHeaders(conn.RequestHeader(), request.header)
+ // Send always returns an io.EOF unless the error is from the client-side.
+ // We want the user to continue to call Receive in those cases to get the
+ // full error from the server-side.
+ if err := conn.Send(request.Msg); err != nil && !errors.Is(err, io.EOF) {
+ _ = conn.CloseRequest()
+ _ = conn.CloseResponse()
+ return nil, err
+ }
+ if err := conn.CloseRequest(); err != nil {
+ return nil, err
+ }
+ return &ServerStreamForClient[Res]{
+ conn: conn,
+ initializer: c.config.Initializer,
+ }, nil
+}
+
+// CallBidiStream calls a bidirectional streaming procedure.
+func (c *Client[Req, Res]) CallBidiStream(ctx context.Context) *BidiStreamForClient[Req, Res] {
+ if c.err != nil {
+ return &BidiStreamForClient[Req, Res]{err: c.err}
+ }
+ return &BidiStreamForClient[Req, Res]{
+ conn: c.newConn(ctx, StreamTypeBidi, nil),
+ initializer: c.config.Initializer,
+ }
+}
+
+func (c *Client[Req, Res]) newConn(ctx context.Context, streamType StreamType, onRequestSend func(r *http.Request)) StreamingClientConn {
+ newConn := func(ctx context.Context, spec Spec) StreamingClientConn {
+ header := make(http.Header, 8) // arbitrary power of two, prevent immediate resizing
+ c.protocolClient.WriteRequestHeader(streamType, header)
+ conn := c.protocolClient.NewConn(ctx, spec, header)
+ conn.onRequestSend(onRequestSend)
+ return conn
+ }
+ if interceptor := c.config.Interceptor; interceptor != nil {
+ newConn = interceptor.WrapStreamingClient(newConn)
+ }
+ return newConn(ctx, c.config.newSpec(streamType))
+}
+
+type clientConfig struct {
+ URL *url.URL
+ Protocol protocol
+ Procedure string
+ Schema any
+ Initializer maybeInitializer
+ CompressMinBytes int
+ Interceptor Interceptor
+ CompressionPools map[string]*compressionPool
+ CompressionNames []string
+ Codec Codec
+ RequestCompressionName string
+ BufferPool *bufferPool
+ ReadMaxBytes int
+ SendMaxBytes int
+ EnableGet bool
+ GetURLMaxBytes int
+ GetUseFallback bool
+ IdempotencyLevel IdempotencyLevel
+}
+
+func newClientConfig(rawURL string, options []ClientOption) (*clientConfig, *Error) {
+ url, err := parseRequestURL(rawURL)
+ if err != nil {
+ return nil, err
+ }
+ protoPath := extractProtoPath(url.Path)
+ config := clientConfig{
+ URL: url,
+ Protocol: &protocolConnect{},
+ Procedure: protoPath,
+ CompressionPools: make(map[string]*compressionPool),
+ BufferPool: newBufferPool(),
+ }
+ withProtoBinaryCodec().applyToClient(&config)
+ withGzip().applyToClient(&config)
+ for _, opt := range options {
+ opt.applyToClient(&config)
+ }
+ if err := config.validate(); err != nil {
+ return nil, err
+ }
+ return &config, nil
+}
+
+func (c *clientConfig) validate() *Error {
+ if c.Codec == nil || c.Codec.Name() == "" {
+ return errorf(CodeUnknown, "no codec configured")
+ }
+ if c.RequestCompressionName != "" && c.RequestCompressionName != compressionIdentity {
+ if _, ok := c.CompressionPools[c.RequestCompressionName]; !ok {
+ return errorf(CodeUnknown, "unknown compression %q", c.RequestCompressionName)
+ }
+ }
+ return nil
+}
+
+func (c *clientConfig) protobuf() Codec {
+ if c.Codec.Name() == codecNameProto {
+ return c.Codec
+ }
+ return &protoBinaryCodec{}
+}
+
+func (c *clientConfig) newSpec(t StreamType) Spec {
+ return Spec{
+ StreamType: t,
+ Procedure: c.Procedure,
+ Schema: c.Schema,
+ IsClient: true,
+ IdempotencyLevel: c.IdempotencyLevel,
+ }
+}
+
+func parseRequestURL(rawURL string) (*url.URL, *Error) {
+ url, err := url.ParseRequestURI(rawURL)
+ if err == nil {
+ return url, nil
+ }
+ if !strings.Contains(rawURL, "://") {
+ // URL doesn't have a scheme, so the user is likely accustomed to
+ // grpc-go's APIs.
+ err = fmt.Errorf(
+ "URL %q missing scheme: use http:// or https:// (unlike grpc-go)",
+ rawURL,
+ )
+ }
+ return nil, NewError(CodeUnavailable, err)
+}
diff --git a/vendor/connectrpc.com/connect/client_stream.go b/vendor/connectrpc.com/connect/client_stream.go
new file mode 100644
index 0000000..886fe7c
--- /dev/null
+++ b/vendor/connectrpc.com/connect/client_stream.go
@@ -0,0 +1,283 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "errors"
+ "io"
+ "net/http"
+)
+
+// ClientStreamForClient is the client's view of a client streaming RPC.
+//
+// It's returned from [Client].CallClientStream, but doesn't currently have an
+// exported constructor function.
+type ClientStreamForClient[Req, Res any] struct {
+ conn StreamingClientConn
+ initializer maybeInitializer
+ // Error from client construction. If non-nil, return for all calls.
+ err error
+}
+
+// Spec returns the specification for the RPC.
+func (c *ClientStreamForClient[_, _]) Spec() Spec {
+ return c.conn.Spec()
+}
+
+// Peer describes the server for the RPC.
+func (c *ClientStreamForClient[_, _]) Peer() Peer {
+ return c.conn.Peer()
+}
+
+// RequestHeader returns the request headers. Headers are sent to the server with the
+// first call to Send.
+//
+// Headers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (c *ClientStreamForClient[Req, Res]) RequestHeader() http.Header {
+ if c.err != nil {
+ return http.Header{}
+ }
+ return c.conn.RequestHeader()
+}
+
+// Send a message to the server. The first call to Send also sends the request
+// headers.
+//
+// If the server returns an error, Send returns an error that wraps [io.EOF].
+// Clients should check for case using the standard library's [errors.Is] and
+// unmarshal the error using CloseAndReceive.
+func (c *ClientStreamForClient[Req, Res]) Send(request *Req) error {
+ if c.err != nil {
+ return c.err
+ }
+ if request == nil {
+ return c.conn.Send(nil)
+ }
+ return c.conn.Send(request)
+}
+
+// CloseAndReceive closes the send side of the stream and waits for the
+// response.
+func (c *ClientStreamForClient[Req, Res]) CloseAndReceive() (*Response[Res], error) {
+ if c.err != nil {
+ return nil, c.err
+ }
+ if err := c.conn.CloseRequest(); err != nil {
+ _ = c.conn.CloseResponse()
+ return nil, err
+ }
+ response, err := receiveUnaryResponse[Res](c.conn, c.initializer)
+ if err != nil {
+ _ = c.conn.CloseResponse()
+ return nil, err
+ }
+ return response, c.conn.CloseResponse()
+}
+
+// Conn exposes the underlying StreamingClientConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (c *ClientStreamForClient[Req, Res]) Conn() (StreamingClientConn, error) {
+ return c.conn, c.err
+}
+
+// ServerStreamForClient is the client's view of a server streaming RPC.
+//
+// It's returned from [Client].CallServerStream, but doesn't currently have an
+// exported constructor function.
+type ServerStreamForClient[Res any] struct {
+ conn StreamingClientConn
+ initializer maybeInitializer
+ msg *Res
+ // Error from client construction. If non-nil, return for all calls.
+ constructErr error
+ // Error from conn.Receive().
+ receiveErr error
+}
+
+// Receive advances the stream to the next message, which will then be
+// available through the Msg method. It returns false when the stream stops,
+// either by reaching the end or by encountering an unexpected error. After
+// Receive returns false, the Err method will return any unexpected error
+// encountered.
+func (s *ServerStreamForClient[Res]) Receive() bool {
+ if s.constructErr != nil || s.receiveErr != nil {
+ return false
+ }
+ s.msg = new(Res)
+ if err := s.initializer.maybe(s.conn.Spec(), s.msg); err != nil {
+ s.receiveErr = err
+ return false
+ }
+ s.receiveErr = s.conn.Receive(s.msg)
+ return s.receiveErr == nil
+}
+
+// Msg returns the most recent message unmarshaled by a call to Receive.
+func (s *ServerStreamForClient[Res]) Msg() *Res {
+ if s.msg == nil {
+ s.msg = new(Res)
+ }
+ return s.msg
+}
+
+// Err returns the first non-EOF error that was encountered by Receive.
+func (s *ServerStreamForClient[Res]) Err() error {
+ if s.constructErr != nil {
+ return s.constructErr
+ }
+ if s.receiveErr != nil && !errors.Is(s.receiveErr, io.EOF) {
+ return s.receiveErr
+ }
+ return nil
+}
+
+// ResponseHeader returns the headers received from the server. It blocks until
+// the first call to Receive returns.
+func (s *ServerStreamForClient[Res]) ResponseHeader() http.Header {
+ if s.constructErr != nil {
+ return http.Header{}
+ }
+ return s.conn.ResponseHeader()
+}
+
+// ResponseTrailer returns the trailers received from the server. Trailers
+// aren't fully populated until Receive() returns an error wrapping io.EOF.
+func (s *ServerStreamForClient[Res]) ResponseTrailer() http.Header {
+ if s.constructErr != nil {
+ return http.Header{}
+ }
+ return s.conn.ResponseTrailer()
+}
+
+// Close the receive side of the stream.
+func (s *ServerStreamForClient[Res]) Close() error {
+ if s.constructErr != nil {
+ return s.constructErr
+ }
+ return s.conn.CloseResponse()
+}
+
+// Conn exposes the underlying StreamingClientConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (s *ServerStreamForClient[Res]) Conn() (StreamingClientConn, error) {
+ return s.conn, s.constructErr
+}
+
+// BidiStreamForClient is the client's view of a bidirectional streaming RPC.
+//
+// It's returned from [Client].CallBidiStream, but doesn't currently have an
+// exported constructor function.
+type BidiStreamForClient[Req, Res any] struct {
+ conn StreamingClientConn
+ initializer maybeInitializer
+ // Error from client construction. If non-nil, return for all calls.
+ err error
+}
+
+// Spec returns the specification for the RPC.
+func (b *BidiStreamForClient[_, _]) Spec() Spec {
+ return b.conn.Spec()
+}
+
+// Peer describes the server for the RPC.
+func (b *BidiStreamForClient[_, _]) Peer() Peer {
+ return b.conn.Peer()
+}
+
+// RequestHeader returns the request headers. Headers are sent with the first
+// call to Send.
+//
+// Headers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (b *BidiStreamForClient[Req, Res]) RequestHeader() http.Header {
+ if b.err != nil {
+ return http.Header{}
+ }
+ return b.conn.RequestHeader()
+}
+
+// Send a message to the server. The first call to Send also sends the request
+// headers. To send just the request headers, without a body, call Send with a
+// nil pointer.
+//
+// If the server returns an error, Send returns an error that wraps [io.EOF].
+// Clients should check for EOF using the standard library's [errors.Is] and
+// call Receive to retrieve the error.
+func (b *BidiStreamForClient[Req, Res]) Send(msg *Req) error {
+ if b.err != nil {
+ return b.err
+ }
+ if msg == nil {
+ return b.conn.Send(nil)
+ }
+ return b.conn.Send(msg)
+}
+
+// CloseRequest closes the send side of the stream.
+func (b *BidiStreamForClient[Req, Res]) CloseRequest() error {
+ if b.err != nil {
+ return b.err
+ }
+ return b.conn.CloseRequest()
+}
+
+// Receive a message. When the server is done sending messages and no other
+// errors have occurred, Receive will return an error that wraps [io.EOF].
+func (b *BidiStreamForClient[Req, Res]) Receive() (*Res, error) {
+ if b.err != nil {
+ return nil, b.err
+ }
+ var msg Res
+ if err := b.initializer.maybe(b.conn.Spec(), &msg); err != nil {
+ return nil, err
+ }
+ if err := b.conn.Receive(&msg); err != nil {
+ return nil, err
+ }
+ return &msg, nil
+}
+
+// CloseResponse closes the receive side of the stream.
+func (b *BidiStreamForClient[Req, Res]) CloseResponse() error {
+ if b.err != nil {
+ return b.err
+ }
+ return b.conn.CloseResponse()
+}
+
+// ResponseHeader returns the headers received from the server. It blocks until
+// the first call to Receive returns.
+func (b *BidiStreamForClient[Req, Res]) ResponseHeader() http.Header {
+ if b.err != nil {
+ return http.Header{}
+ }
+ return b.conn.ResponseHeader()
+}
+
+// ResponseTrailer returns the trailers received from the server. Trailers
+// aren't fully populated until Receive() returns an error wrapping [io.EOF].
+func (b *BidiStreamForClient[Req, Res]) ResponseTrailer() http.Header {
+ if b.err != nil {
+ return http.Header{}
+ }
+ return b.conn.ResponseTrailer()
+}
+
+// Conn exposes the underlying StreamingClientConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (b *BidiStreamForClient[Req, Res]) Conn() (StreamingClientConn, error) {
+ return b.conn, b.err
+}
diff --git a/vendor/connectrpc.com/connect/code.go b/vendor/connectrpc.com/connect/code.go
new file mode 100644
index 0000000..126fae4
--- /dev/null
+++ b/vendor/connectrpc.com/connect/code.go
@@ -0,0 +1,226 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// A Code is one of the Connect protocol's error codes. There are no user-defined
+// codes, so only the codes enumerated below are valid. In both name and
+// semantics, these codes match the gRPC status codes.
+//
+// The descriptions below are optimized for brevity rather than completeness.
+// See the [Connect protocol specification] for detailed descriptions of each
+// code and example usage.
+//
+// [Connect protocol specification]: https://connectrpc.com/docs/protocol
+type Code uint32
+
+const (
+ // The zero code in gRPC is OK, which indicates that the operation was a
+ // success. We don't define a constant for it because it overlaps awkwardly
+ // with Go's error semantics: what does it mean to have a non-nil error with
+ // an OK status? (Also, the Connect protocol doesn't use a code for
+ // successes.)
+
+ // CodeCanceled indicates that the operation was canceled, typically by the
+ // caller.
+ CodeCanceled Code = 1
+
+ // CodeUnknown indicates that the operation failed for an unknown reason.
+ CodeUnknown Code = 2
+
+ // CodeInvalidArgument indicates that client supplied an invalid argument.
+ CodeInvalidArgument Code = 3
+
+ // CodeDeadlineExceeded indicates that deadline expired before the operation
+ // could complete.
+ CodeDeadlineExceeded Code = 4
+
+ // CodeNotFound indicates that some requested entity (for example, a file or
+ // directory) was not found.
+ CodeNotFound Code = 5
+
+ // CodeAlreadyExists indicates that client attempted to create an entity (for
+ // example, a file or directory) that already exists.
+ CodeAlreadyExists Code = 6
+
+ // CodePermissionDenied indicates that the caller doesn't have permission to
+ // execute the specified operation.
+ CodePermissionDenied Code = 7
+
+ // CodeResourceExhausted indicates that some resource has been exhausted. For
+ // example, a per-user quota may be exhausted or the entire file system may
+ // be full.
+ CodeResourceExhausted Code = 8
+
+ // CodeFailedPrecondition indicates that the system is not in a state
+ // required for the operation's execution.
+ CodeFailedPrecondition Code = 9
+
+ // CodeAborted indicates that operation was aborted by the system, usually
+ // because of a concurrency issue such as a sequencer check failure or
+ // transaction abort.
+ CodeAborted Code = 10
+
+ // CodeOutOfRange indicates that the operation was attempted past the valid
+ // range (for example, seeking past end-of-file).
+ CodeOutOfRange Code = 11
+
+ // CodeUnimplemented indicates that the operation isn't implemented,
+ // supported, or enabled in this service.
+ CodeUnimplemented Code = 12
+
+ // CodeInternal indicates that some invariants expected by the underlying
+ // system have been broken. This code is reserved for serious errors.
+ CodeInternal Code = 13
+
+ // CodeUnavailable indicates that the service is currently unavailable. This
+ // is usually temporary, so clients can back off and retry idempotent
+ // operations.
+ CodeUnavailable Code = 14
+
+ // CodeDataLoss indicates that the operation has resulted in unrecoverable
+ // data loss or corruption.
+ CodeDataLoss Code = 15
+
+ // CodeUnauthenticated indicates that the request does not have valid
+ // authentication credentials for the operation.
+ CodeUnauthenticated Code = 16
+
+ minCode = CodeCanceled
+ maxCode = CodeUnauthenticated
+)
+
+func (c Code) String() string {
+ switch c {
+ case CodeCanceled:
+ return "canceled"
+ case CodeUnknown:
+ return "unknown"
+ case CodeInvalidArgument:
+ return "invalid_argument"
+ case CodeDeadlineExceeded:
+ return "deadline_exceeded"
+ case CodeNotFound:
+ return "not_found"
+ case CodeAlreadyExists:
+ return "already_exists"
+ case CodePermissionDenied:
+ return "permission_denied"
+ case CodeResourceExhausted:
+ return "resource_exhausted"
+ case CodeFailedPrecondition:
+ return "failed_precondition"
+ case CodeAborted:
+ return "aborted"
+ case CodeOutOfRange:
+ return "out_of_range"
+ case CodeUnimplemented:
+ return "unimplemented"
+ case CodeInternal:
+ return "internal"
+ case CodeUnavailable:
+ return "unavailable"
+ case CodeDataLoss:
+ return "data_loss"
+ case CodeUnauthenticated:
+ return "unauthenticated"
+ }
+ return fmt.Sprintf("code_%d", c)
+}
+
+// MarshalText implements [encoding.TextMarshaler].
+func (c Code) MarshalText() ([]byte, error) {
+ return []byte(c.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler].
+func (c *Code) UnmarshalText(data []byte) error {
+ dataStr := string(data)
+ switch dataStr {
+ case "canceled":
+ *c = CodeCanceled
+ return nil
+ case "unknown":
+ *c = CodeUnknown
+ return nil
+ case "invalid_argument":
+ *c = CodeInvalidArgument
+ return nil
+ case "deadline_exceeded":
+ *c = CodeDeadlineExceeded
+ return nil
+ case "not_found":
+ *c = CodeNotFound
+ return nil
+ case "already_exists":
+ *c = CodeAlreadyExists
+ return nil
+ case "permission_denied":
+ *c = CodePermissionDenied
+ return nil
+ case "resource_exhausted":
+ *c = CodeResourceExhausted
+ return nil
+ case "failed_precondition":
+ *c = CodeFailedPrecondition
+ return nil
+ case "aborted":
+ *c = CodeAborted
+ return nil
+ case "out_of_range":
+ *c = CodeOutOfRange
+ return nil
+ case "unimplemented":
+ *c = CodeUnimplemented
+ return nil
+ case "internal":
+ *c = CodeInternal
+ return nil
+ case "unavailable":
+ *c = CodeUnavailable
+ return nil
+ case "data_loss":
+ *c = CodeDataLoss
+ return nil
+ case "unauthenticated":
+ *c = CodeUnauthenticated
+ return nil
+ }
+ // Ensure that non-canonical codes round-trip through MarshalText and
+ // UnmarshalText.
+ if strings.HasPrefix(dataStr, "code_") {
+ dataStr = strings.TrimPrefix(dataStr, "code_")
+ code, err := strconv.ParseInt(dataStr, 10 /* base */, 64 /* bitsize */)
+ if err == nil && (code < int64(minCode) || code > int64(maxCode)) {
+ *c = Code(code)
+ return nil
+ }
+ }
+ return fmt.Errorf("invalid code %q", dataStr)
+}
+
+// CodeOf returns the error's status code if it is or wraps an [*Error] and
+// [CodeUnknown] otherwise.
+func CodeOf(err error) Code {
+ if connectErr, ok := asError(err); ok {
+ return connectErr.Code()
+ }
+ return CodeUnknown
+}
diff --git a/vendor/connectrpc.com/connect/codec.go b/vendor/connectrpc.com/connect/codec.go
new file mode 100644
index 0000000..4e7c3ba
--- /dev/null
+++ b/vendor/connectrpc.com/connect/codec.go
@@ -0,0 +1,259 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/runtime/protoiface"
+)
+
+const (
+ codecNameProto = "proto"
+ codecNameJSON = "json"
+ codecNameJSONCharsetUTF8 = codecNameJSON + "; charset=utf-8"
+)
+
+// Codec marshals structs (typically generated from a schema) to and from bytes.
+type Codec interface {
+ // Name returns the name of the Codec.
+ //
+ // This may be used as part of the Content-Type within HTTP. For example,
+ // with gRPC this is the content subtype, so "application/grpc+proto" will
+ // map to the Codec with name "proto".
+ //
+ // Names must not be empty.
+ Name() string
+ // Marshal marshals the given message.
+ //
+ // Marshal may expect a specific type of message, and will error if this type
+ // is not given.
+ Marshal(any) ([]byte, error)
+ // Unmarshal unmarshals the given message.
+ //
+ // Unmarshal may expect a specific type of message, and will error if this
+ // type is not given.
+ Unmarshal([]byte, any) error
+}
+
+// marshalAppender is an extension to Codec for appending to a byte slice.
+type marshalAppender interface {
+ Codec
+
+ // MarshalAppend marshals the given message and appends it to the given
+ // byte slice.
+ //
+ // MarshalAppend may expect a specific type of message, and will error if
+ // this type is not given.
+ MarshalAppend([]byte, any) ([]byte, error)
+}
+
+// stableCodec is an extension to Codec for serializing with stable output.
+type stableCodec interface {
+ Codec
+
+ // MarshalStable marshals the given message with stable field ordering.
+ //
+ // MarshalStable should return the same output for a given input. Although
+ // it is not guaranteed to be canonicalized, the marshalling routine for
+ // MarshalStable will opt for the most normalized output available for a
+ // given serialization.
+ //
+ // For practical reasons, it is possible for MarshalStable to return two
+ // different results for two inputs considered to be "equal" in their own
+ // domain, and it may change in the future with codec updates, but for
+ // any given concrete value and any given version, it should return the
+ // same output.
+ MarshalStable(any) ([]byte, error)
+
+ // IsBinary returns true if the marshalled data is binary for this codec.
+ //
+ // If this function returns false, the data returned from Marshal and
+ // MarshalStable are considered valid text and may be used in contexts
+ // where text is expected.
+ IsBinary() bool
+}
+
+type protoBinaryCodec struct{}
+
+var _ Codec = (*protoBinaryCodec)(nil)
+
+func (c *protoBinaryCodec) Name() string { return codecNameProto }
+
+func (c *protoBinaryCodec) Marshal(message any) ([]byte, error) {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return nil, errNotProto(message)
+ }
+ return proto.Marshal(protoMessage)
+}
+
+func (c *protoBinaryCodec) MarshalAppend(dst []byte, message any) ([]byte, error) {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return nil, errNotProto(message)
+ }
+ return proto.MarshalOptions{}.MarshalAppend(dst, protoMessage)
+}
+
+func (c *protoBinaryCodec) Unmarshal(data []byte, message any) error {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return errNotProto(message)
+ }
+ err := proto.Unmarshal(data, protoMessage)
+ if err != nil {
+ return fmt.Errorf("unmarshal into %T: %w", message, err)
+ }
+ return nil
+}
+
+func (c *protoBinaryCodec) MarshalStable(message any) ([]byte, error) {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return nil, errNotProto(message)
+ }
+ // protobuf does not offer a canonical output today, so this format is not
+ // guaranteed to match deterministic output from other protobuf libraries.
+ // In addition, unknown fields may cause inconsistent output for otherwise
+ // equal messages.
+ // https://github.com/golang/protobuf/issues/1121
+ options := proto.MarshalOptions{Deterministic: true}
+ return options.Marshal(protoMessage)
+}
+
+func (c *protoBinaryCodec) IsBinary() bool {
+ return true
+}
+
+type protoJSONCodec struct {
+ name string
+}
+
+var _ Codec = (*protoJSONCodec)(nil)
+
+func (c *protoJSONCodec) Name() string { return c.name }
+
+func (c *protoJSONCodec) Marshal(message any) ([]byte, error) {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return nil, errNotProto(message)
+ }
+ return protojson.MarshalOptions{}.Marshal(protoMessage)
+}
+
+func (c *protoJSONCodec) MarshalAppend(dst []byte, message any) ([]byte, error) {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return nil, errNotProto(message)
+ }
+ return protojson.MarshalOptions{}.MarshalAppend(dst, protoMessage)
+}
+
+func (c *protoJSONCodec) Unmarshal(binary []byte, message any) error {
+ protoMessage, ok := message.(proto.Message)
+ if !ok {
+ return errNotProto(message)
+ }
+ if len(binary) == 0 {
+ return errors.New("zero-length payload is not a valid JSON object")
+ }
+ // Discard unknown fields so clients and servers aren't forced to always use
+ // exactly the same version of the schema.
+ options := protojson.UnmarshalOptions{DiscardUnknown: true}
+ err := options.Unmarshal(binary, protoMessage)
+ if err != nil {
+ return fmt.Errorf("unmarshal into %T: %w", message, err)
+ }
+ return nil
+}
+
+func (c *protoJSONCodec) MarshalStable(message any) ([]byte, error) {
+ // protojson does not offer a "deterministic" field ordering, but fields
+ // are still ordered consistently by their index. However, protojson can
+ // output inconsistent whitespace for some reason, therefore it is
+ // suggested to use a formatter to ensure consistent formatting.
+ // https://github.com/golang/protobuf/issues/1373
+ messageJSON, err := c.Marshal(message)
+ if err != nil {
+ return nil, err
+ }
+ compactedJSON := bytes.NewBuffer(messageJSON[:0])
+ if err = json.Compact(compactedJSON, messageJSON); err != nil {
+ return nil, err
+ }
+ return compactedJSON.Bytes(), nil
+}
+
+func (c *protoJSONCodec) IsBinary() bool {
+ return false
+}
+
+// readOnlyCodecs is a read-only interface to a map of named codecs.
+type readOnlyCodecs interface {
+ // Get gets the Codec with the given name.
+ Get(string) Codec
+ // Protobuf gets the user-supplied protobuf codec, falling back to the default
+ // implementation if necessary.
+ //
+ // This is helpful in the gRPC protocol, where the wire protocol requires
+ // marshaling protobuf structs to binary even if the RPC procedures were
+ // generated from a different IDL.
+ Protobuf() Codec
+ // Names returns a copy of the registered codec names. The returned slice is
+ // safe for the caller to mutate.
+ Names() []string
+}
+
+func newReadOnlyCodecs(nameToCodec map[string]Codec) readOnlyCodecs {
+ return &codecMap{
+ nameToCodec: nameToCodec,
+ }
+}
+
+type codecMap struct {
+ nameToCodec map[string]Codec
+}
+
+func (m *codecMap) Get(name string) Codec {
+ return m.nameToCodec[name]
+}
+
+func (m *codecMap) Protobuf() Codec {
+ if pb, ok := m.nameToCodec[codecNameProto]; ok {
+ return pb
+ }
+ return &protoBinaryCodec{}
+}
+
+func (m *codecMap) Names() []string {
+ names := make([]string, 0, len(m.nameToCodec))
+ for name := range m.nameToCodec {
+ names = append(names, name)
+ }
+ return names
+}
+
+func errNotProto(message any) error {
+ if _, ok := message.(protoiface.MessageV1); ok {
+ return fmt.Errorf("%T uses github.com/golang/protobuf, but connect-go only supports google.golang.org/protobuf: see https://go.dev/blog/protobuf-apiv2", message)
+ }
+ return fmt.Errorf("%T doesn't implement proto.Message", message)
+}
diff --git a/vendor/connectrpc.com/connect/compression.go b/vendor/connectrpc.com/connect/compression.go
new file mode 100644
index 0000000..ee43412
--- /dev/null
+++ b/vendor/connectrpc.com/connect/compression.go
@@ -0,0 +1,223 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "math"
+ "strings"
+ "sync"
+)
+
+const (
+ compressionGzip = "gzip"
+ compressionIdentity = "identity"
+)
+
+// A Decompressor is a reusable wrapper that decompresses an underlying data
+// source. The standard library's [*gzip.Reader] implements Decompressor.
+type Decompressor interface {
+ io.Reader
+
+ // Close closes the Decompressor, but not the underlying data source. It may
+ // return an error if the Decompressor wasn't read to EOF.
+ Close() error
+
+ // Reset discards the Decompressor's internal state, if any, and prepares it
+ // to read from a new source of compressed data.
+ Reset(io.Reader) error
+}
+
+// A Compressor is a reusable wrapper that compresses data written to an
+// underlying sink. The standard library's [*gzip.Writer] implements Compressor.
+type Compressor interface {
+ io.Writer
+
+ // Close flushes any buffered data to the underlying sink, then closes the
+ // Compressor. It must not close the underlying sink.
+ Close() error
+
+ // Reset discards the Compressor's internal state, if any, and prepares it to
+ // write compressed data to a new sink.
+ Reset(io.Writer)
+}
+
+type compressionPool struct {
+ decompressors sync.Pool
+ compressors sync.Pool
+}
+
+func newCompressionPool(
+ newDecompressor func() Decompressor,
+ newCompressor func() Compressor,
+) *compressionPool {
+ if newDecompressor == nil && newCompressor == nil {
+ return nil
+ }
+ return &compressionPool{
+ decompressors: sync.Pool{
+ New: func() any { return newDecompressor() },
+ },
+ compressors: sync.Pool{
+ New: func() any { return newCompressor() },
+ },
+ }
+}
+
+func (c *compressionPool) Decompress(dst *bytes.Buffer, src *bytes.Buffer, readMaxBytes int64) *Error {
+ decompressor, err := c.getDecompressor(src)
+ if err != nil {
+ return errorf(CodeInvalidArgument, "get decompressor: %w", err)
+ }
+ reader := io.Reader(decompressor)
+ if readMaxBytes > 0 && readMaxBytes < math.MaxInt64 {
+ reader = io.LimitReader(decompressor, readMaxBytes+1)
+ }
+ bytesRead, err := dst.ReadFrom(reader)
+ if err != nil {
+ _ = c.putDecompressor(decompressor)
+ err = wrapIfContextError(err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeInvalidArgument, "decompress: %w", err)
+ }
+ if readMaxBytes > 0 && bytesRead > readMaxBytes {
+ discardedBytes, err := io.Copy(io.Discard, decompressor)
+ _ = c.putDecompressor(decompressor)
+ if err != nil {
+ return errorf(CodeResourceExhausted, "message is larger than configured max %d - unable to determine message size: %w", readMaxBytes, err)
+ }
+ return errorf(CodeResourceExhausted, "message size %d is larger than configured max %d", bytesRead+discardedBytes, readMaxBytes)
+ }
+ if err := c.putDecompressor(decompressor); err != nil {
+ return errorf(CodeUnknown, "recycle decompressor: %w", err)
+ }
+ return nil
+}
+
+func (c *compressionPool) Compress(dst *bytes.Buffer, src *bytes.Buffer) *Error {
+ compressor, err := c.getCompressor(dst)
+ if err != nil {
+ return errorf(CodeUnknown, "get compressor: %w", err)
+ }
+ if _, err := src.WriteTo(compressor); err != nil {
+ _ = c.putCompressor(compressor)
+ err = wrapIfContextError(err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeInternal, "compress: %w", err)
+ }
+ if err := c.putCompressor(compressor); err != nil {
+ return errorf(CodeInternal, "recycle compressor: %w", err)
+ }
+ return nil
+}
+
+func (c *compressionPool) getDecompressor(reader io.Reader) (Decompressor, error) {
+ decompressor, ok := c.decompressors.Get().(Decompressor)
+ if !ok {
+ return nil, errors.New("expected Decompressor, got incorrect type from pool")
+ }
+ return decompressor, decompressor.Reset(reader)
+}
+
+func (c *compressionPool) putDecompressor(decompressor Decompressor) error {
+ if err := decompressor.Close(); err != nil {
+ return err
+ }
+ // While it's in the pool, we don't want the decompressor to retain a
+ // reference to the underlying reader. However, most decompressors attempt to
+ // read some header data from the new data source when Reset; since we don't
+ // know the compression format, we can't provide a valid header. Since we
+ // also reset the decompressor when it's pulled out of the pool, we can
+ // ignore errors here.
+ _ = decompressor.Reset(strings.NewReader(""))
+ c.decompressors.Put(decompressor)
+ return nil
+}
+
+func (c *compressionPool) getCompressor(writer io.Writer) (Compressor, error) {
+ compressor, ok := c.compressors.Get().(Compressor)
+ if !ok {
+ return nil, errors.New("expected Compressor, got incorrect type from pool")
+ }
+ compressor.Reset(writer)
+ return compressor, nil
+}
+
+func (c *compressionPool) putCompressor(compressor Compressor) error {
+ if err := compressor.Close(); err != nil {
+ return err
+ }
+ compressor.Reset(io.Discard) // don't keep references
+ c.compressors.Put(compressor)
+ return nil
+}
+
+// readOnlyCompressionPools is a read-only interface to a map of named
+// compressionPools.
+type readOnlyCompressionPools interface {
+ Get(string) *compressionPool
+ Contains(string) bool
+ // Wordy, but clarifies how this is different from readOnlyCodecs.Names().
+ CommaSeparatedNames() string
+}
+
+func newReadOnlyCompressionPools(
+ nameToPool map[string]*compressionPool,
+ reversedNames []string,
+) readOnlyCompressionPools {
+ // Client and handler configs keep compression names in registration order,
+ // but we want the last registered to be the most preferred.
+ names := make([]string, 0, len(reversedNames))
+ seen := make(map[string]struct{}, len(reversedNames))
+ for i := len(reversedNames) - 1; i >= 0; i-- {
+ name := reversedNames[i]
+ if _, ok := seen[name]; ok {
+ continue
+ }
+ seen[name] = struct{}{}
+ names = append(names, name)
+ }
+ return &namedCompressionPools{
+ nameToPool: nameToPool,
+ commaSeparatedNames: strings.Join(names, ","),
+ }
+}
+
+type namedCompressionPools struct {
+ nameToPool map[string]*compressionPool
+ commaSeparatedNames string
+}
+
+func (m *namedCompressionPools) Get(name string) *compressionPool {
+ if name == "" || name == compressionIdentity {
+ return nil
+ }
+ return m.nameToPool[name]
+}
+
+func (m *namedCompressionPools) Contains(name string) bool {
+ _, ok := m.nameToPool[name]
+ return ok
+}
+
+func (m *namedCompressionPools) CommaSeparatedNames() string {
+ return m.commaSeparatedNames
+}
diff --git a/vendor/connectrpc.com/connect/connect.go b/vendor/connectrpc.com/connect/connect.go
new file mode 100644
index 0000000..ea3fef5
--- /dev/null
+++ b/vendor/connectrpc.com/connect/connect.go
@@ -0,0 +1,441 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package connect is a slim RPC framework built on Protocol Buffers and
+// [net/http]. In addition to supporting its own protocol, Connect handlers and
+// clients are wire-compatible with gRPC and gRPC-Web, including streaming.
+//
+// This documentation is intended to explain each type and function in
+// isolation. Walkthroughs, FAQs, and other narrative docs are available on the
+// [Connect website], and there's a working [demonstration service] on Github.
+//
+// [Connect website]: https://connectrpc.com
+// [demonstration service]: https://github.com/connectrpc/examples-go
+package connect
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+)
+
+// Version is the semantic version of the connect module.
+const Version = "1.16.2"
+
+// These constants are used in compile-time handshakes with connect's generated
+// code.
+const (
+ IsAtLeastVersion0_0_1 = true
+ IsAtLeastVersion0_1_0 = true
+ IsAtLeastVersion1_7_0 = true
+ IsAtLeastVersion1_13_0 = true
+)
+
+// StreamType describes whether the client, server, neither, or both is
+// streaming.
+type StreamType uint8
+
+const (
+ StreamTypeUnary StreamType = 0b00
+ StreamTypeClient StreamType = 0b01
+ StreamTypeServer StreamType = 0b10
+ StreamTypeBidi = StreamTypeClient | StreamTypeServer
+)
+
+func (s StreamType) String() string {
+ switch s {
+ case StreamTypeUnary:
+ return "unary"
+ case StreamTypeClient:
+ return "client"
+ case StreamTypeServer:
+ return "server"
+ case StreamTypeBidi:
+ return "bidi"
+ }
+ return fmt.Sprintf("stream_%d", s)
+}
+
+// StreamingHandlerConn is the server's view of a bidirectional message
+// exchange. Interceptors for streaming RPCs may wrap StreamingHandlerConns.
+//
+// Like the standard library's [http.ResponseWriter], StreamingHandlerConns write
+// response headers to the network with the first call to Send. Any subsequent
+// mutations are effectively no-ops. Handlers may mutate response trailers at
+// any time before returning. When the client has finished sending data,
+// Receive returns an error wrapping [io.EOF]. Handlers should check for this
+// using the standard library's [errors.Is].
+//
+// Headers and trailers beginning with "Connect-" and "Grpc-" are reserved for
+// use by the gRPC and Connect protocols: applications may read them but
+// shouldn't write them.
+//
+// StreamingHandlerConn implementations provided by this module guarantee that
+// all returned errors can be cast to [*Error] using the standard library's
+// [errors.As].
+//
+// StreamingHandlerConn implementations do not need to be safe for concurrent use.
+type StreamingHandlerConn interface {
+ Spec() Spec
+ Peer() Peer
+
+ Receive(any) error
+ RequestHeader() http.Header
+
+ Send(any) error
+ ResponseHeader() http.Header
+ ResponseTrailer() http.Header
+}
+
+// StreamingClientConn is the client's view of a bidirectional message exchange.
+// Interceptors for streaming RPCs may wrap StreamingClientConns.
+//
+// StreamingClientConns write request headers to the network with the first
+// call to Send. Any subsequent mutations are effectively no-ops. When the
+// server is done sending data, the StreamingClientConn's Receive method
+// returns an error wrapping [io.EOF]. Clients should check for this using the
+// standard library's [errors.Is]. If the server encounters an error during
+// processing, subsequent calls to the StreamingClientConn's Send method will
+// return an error wrapping [io.EOF]; clients may then call Receive to unmarshal
+// the error.
+//
+// Headers and trailers beginning with "Connect-" and "Grpc-" are reserved for
+// use by the gRPC and Connect protocols: applications may read them but
+// shouldn't write them.
+//
+// StreamingClientConn implementations provided by this module guarantee that
+// all returned errors can be cast to [*Error] using the standard library's
+// [errors.As].
+//
+// In order to support bidirectional streaming RPCs, all StreamingClientConn
+// implementations must support limited concurrent use. See the comments on
+// each group of methods for details.
+type StreamingClientConn interface {
+ // Spec and Peer must be safe to call concurrently with all other methods.
+ Spec() Spec
+ Peer() Peer
+
+ // Send, RequestHeader, and CloseRequest may race with each other, but must
+ // be safe to call concurrently with all other methods.
+ Send(any) error
+ RequestHeader() http.Header
+ CloseRequest() error
+
+ // Receive, ResponseHeader, ResponseTrailer, and CloseResponse may race with
+ // each other, but must be safe to call concurrently with all other methods.
+ Receive(any) error
+ ResponseHeader() http.Header
+ ResponseTrailer() http.Header
+ CloseResponse() error
+}
+
+// Request is a wrapper around a generated request message. It provides
+// access to metadata like headers and the RPC specification, as well as
+// strongly-typed access to the message itself.
+type Request[T any] struct {
+ Msg *T
+
+ spec Spec
+ peer Peer
+ header http.Header
+ method string
+}
+
+// NewRequest wraps a generated request message.
+func NewRequest[T any](message *T) *Request[T] {
+ return &Request[T]{
+ Msg: message,
+ // Initialized lazily so we don't allocate unnecessarily.
+ header: nil,
+ }
+}
+
+// Any returns the concrete request message as an empty interface, so that
+// *Request implements the [AnyRequest] interface.
+func (r *Request[_]) Any() any {
+ return r.Msg
+}
+
+// Spec returns a description of this RPC.
+func (r *Request[_]) Spec() Spec {
+ return r.spec
+}
+
+// Peer describes the other party for this RPC.
+func (r *Request[_]) Peer() Peer {
+ return r.peer
+}
+
+// Header returns the HTTP headers for this request. Headers beginning with
+// "Connect-" and "Grpc-" are reserved for use by the Connect and gRPC
+// protocols: applications may read them but shouldn't write them.
+func (r *Request[_]) Header() http.Header {
+ if r.header == nil {
+ r.header = make(http.Header)
+ }
+ return r.header
+}
+
+// HTTPMethod returns the HTTP method for this request. This is nearly always
+// POST, but side-effect-free unary RPCs could be made via a GET.
+//
+// On a newly created request, via NewRequest, this will return the empty
+// string until the actual request is actually sent and the HTTP method
+// determined. This means that client interceptor functions will see the
+// empty string until *after* they delegate to the handler they wrapped. It
+// is even possible for this to return the empty string after such delegation,
+// if the request was never actually sent to the server (and thus no
+// determination ever made about the HTTP method).
+func (r *Request[_]) HTTPMethod() string {
+ return r.method
+}
+
+// internalOnly implements AnyRequest.
+func (r *Request[_]) internalOnly() {}
+
+// setRequestMethod sets the request method to the given value.
+func (r *Request[_]) setRequestMethod(method string) {
+ r.method = method
+}
+
+// AnyRequest is the common method set of every [Request], regardless of type
+// parameter. It's used in unary interceptors.
+//
+// Headers and trailers beginning with "Connect-" and "Grpc-" are reserved for
+// use by the gRPC and Connect protocols: applications may read them but
+// shouldn't write them.
+//
+// To preserve our ability to add methods to this interface without breaking
+// backward compatibility, only types defined in this package can implement
+// AnyRequest.
+type AnyRequest interface {
+ Any() any
+ Spec() Spec
+ Peer() Peer
+ Header() http.Header
+ HTTPMethod() string
+
+ internalOnly()
+ setRequestMethod(string)
+}
+
+// Response is a wrapper around a generated response message. It provides
+// access to metadata like headers and trailers, as well as strongly-typed
+// access to the message itself.
+type Response[T any] struct {
+ Msg *T
+
+ header http.Header
+ trailer http.Header
+}
+
+// NewResponse wraps a generated response message.
+func NewResponse[T any](message *T) *Response[T] {
+ return &Response[T]{
+ Msg: message,
+ // Initialized lazily so we don't allocate unnecessarily.
+ header: nil,
+ trailer: nil,
+ }
+}
+
+// Any returns the concrete response message as an empty interface, so that
+// *Response implements the [AnyResponse] interface.
+func (r *Response[_]) Any() any {
+ return r.Msg
+}
+
+// Header returns the HTTP headers for this response. Headers beginning with
+// "Connect-" and "Grpc-" are reserved for use by the Connect and gRPC
+// protocols: applications may read them but shouldn't write them.
+func (r *Response[_]) Header() http.Header {
+ if r.header == nil {
+ r.header = make(http.Header)
+ }
+ return r.header
+}
+
+// Trailer returns the trailers for this response. Depending on the underlying
+// RPC protocol, trailers may be sent as HTTP trailers or a protocol-specific
+// block of in-body metadata.
+//
+// Trailers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols: applications may read them but shouldn't write
+// them.
+func (r *Response[_]) Trailer() http.Header {
+ if r.trailer == nil {
+ r.trailer = make(http.Header)
+ }
+ return r.trailer
+}
+
+// internalOnly implements AnyResponse.
+func (r *Response[_]) internalOnly() {}
+
+// AnyResponse is the common method set of every [Response], regardless of type
+// parameter. It's used in unary interceptors.
+//
+// Headers and trailers beginning with "Connect-" and "Grpc-" are reserved for
+// use by the gRPC and Connect protocols: applications may read them but
+// shouldn't write them.
+//
+// To preserve our ability to add methods to this interface without breaking
+// backward compatibility, only types defined in this package can implement
+// AnyResponse.
+type AnyResponse interface {
+ Any() any
+ Header() http.Header
+ Trailer() http.Header
+
+ internalOnly()
+}
+
+// HTTPClient is the interface connect expects HTTP clients to implement. The
+// standard library's *http.Client implements HTTPClient.
+type HTTPClient interface {
+ Do(*http.Request) (*http.Response, error)
+}
+
+// Spec is a description of a client call or a handler invocation.
+//
+// If you're using Protobuf, protoc-gen-connect-go generates a constant for the
+// fully-qualified Procedure corresponding to each RPC in your schema.
+type Spec struct {
+ StreamType StreamType
+ Schema any // for protobuf RPCs, a protoreflect.MethodDescriptor
+ Procedure string // for example, "/acme.foo.v1.FooService/Bar"
+ IsClient bool // otherwise we're in a handler
+ IdempotencyLevel IdempotencyLevel
+}
+
+// Peer describes the other party to an RPC.
+//
+// When accessed client-side, Addr contains the host or host:port from the
+// server's URL. When accessed server-side, Addr contains the client's address
+// in IP:port format.
+//
+// On both the client and the server, Protocol is the RPC protocol in use.
+// Currently, it's either [ProtocolConnect], [ProtocolGRPC], or
+// [ProtocolGRPCWeb], but additional protocols may be added in the future.
+//
+// Query contains the query parameters for the request. For the server, this
+// will reflect the actual query parameters sent. For the client, it is unset.
+type Peer struct {
+ Addr string
+ Protocol string
+ Query url.Values // server-only
+}
+
+func newPeerFromURL(url *url.URL, protocol string) Peer {
+ return Peer{
+ Addr: url.Host,
+ Protocol: protocol,
+ }
+}
+
+// handlerConnCloser extends StreamingHandlerConn with a method for handlers to
+// terminate the message exchange (and optionally send an error to the client).
+type handlerConnCloser interface {
+ StreamingHandlerConn
+
+ Close(error) error
+}
+
+// receiveConn represents the shared methods of both StreamingClientConn and StreamingHandlerConn
+// that the below helper functions use for implementing the rules around a "unary" stream, that
+// is expected to have exactly one message (or zero messages followed by a non-EOF error).
+type receiveConn interface {
+ Spec() Spec
+ Receive(any) error
+}
+
+// hasHTTPMethod is implemented by streaming connections that support HTTP methods other than
+// POST.
+type hasHTTPMethod interface {
+ getHTTPMethod() string
+}
+
+// receiveUnaryResponse unmarshals a message from a StreamingClientConn, then
+// envelopes the message and attaches headers and trailers. It attempts to
+// consume the response stream and isn't appropriate when receiving multiple
+// messages.
+func receiveUnaryResponse[T any](conn StreamingClientConn, initializer maybeInitializer) (*Response[T], error) {
+ msg, err := receiveUnaryMessage[T](conn, initializer, "response")
+ if err != nil {
+ return nil, err
+ }
+ return &Response[T]{
+ Msg: msg,
+ header: conn.ResponseHeader(),
+ trailer: conn.ResponseTrailer(),
+ }, nil
+}
+
+// receiveUnaryRequest unmarshals a message from a StreamingClientConn, then
+// envelopes the message and attaches headers and other request properties. It
+// attempts to consume the request stream and isn't appropriate when receiving
+// multiple messages.
+func receiveUnaryRequest[T any](conn StreamingHandlerConn, initializer maybeInitializer) (*Request[T], error) {
+ msg, err := receiveUnaryMessage[T](conn, initializer, "request")
+ if err != nil {
+ return nil, err
+ }
+ method := http.MethodPost
+ if hasRequestMethod, ok := conn.(hasHTTPMethod); ok {
+ method = hasRequestMethod.getHTTPMethod()
+ }
+ return &Request[T]{
+ Msg: msg,
+ spec: conn.Spec(),
+ peer: conn.Peer(),
+ header: conn.RequestHeader(),
+ method: method,
+ }, nil
+}
+
+func receiveUnaryMessage[T any](conn receiveConn, initializer maybeInitializer, what string) (*T, error) {
+ var msg T
+ if err := initializer.maybe(conn.Spec(), &msg); err != nil {
+ return nil, err
+ }
+ // Possibly counter-intuitive, but the gRPC specs about error codes state that both clients
+ // and servers should return "unimplemented" when they encounter a cardinality violation: where
+ // the number of messages in the stream is wrong. Search for "cardinality violation" in the
+ // following docs:
+ // https://grpc.github.io/grpc/core/md_doc_statuscodes.html
+ if err := conn.Receive(&msg); err != nil {
+ if errors.Is(err, io.EOF) {
+ err = NewError(CodeUnimplemented, fmt.Errorf("unary %s has zero messages", what))
+ }
+ return nil, err
+ }
+ // In a well-formed stream, the one message must be the only content in the body.
+ // To verify that it is well-formed, try to read another message from the stream.
+ // TODO: optimise this second receive: ideally do it w/out allocation, w/out
+ // fully reading next message (if one is present), and w/out trying to
+ // actually unmarshal the bytes)
+ var msg2 T
+ if err := initializer.maybe(conn.Spec(), &msg2); err != nil {
+ return nil, err
+ }
+ if err := conn.Receive(&msg2); !errors.Is(err, io.EOF) {
+ if err == nil {
+ err = NewError(CodeUnimplemented, fmt.Errorf("unary %s has multiple messages", what))
+ }
+ return nil, err
+ }
+ return &msg, nil
+}
diff --git a/vendor/connectrpc.com/connect/duplex_http_call.go b/vendor/connectrpc.com/connect/duplex_http_call.go
new file mode 100644
index 0000000..a1f8f36
--- /dev/null
+++ b/vendor/connectrpc.com/connect/duplex_http_call.go
@@ -0,0 +1,468 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "sync"
+ "sync/atomic"
+)
+
+// duplexHTTPCall is a full-duplex stream between the client and server. The
+// request body is the stream from client to server, and the response body is
+// the reverse.
+//
+// Be warned: we need to use some lesser-known APIs to do this with net/http.
+type duplexHTTPCall struct {
+ ctx context.Context
+ httpClient HTTPClient
+ streamType StreamType
+ onRequestSend func(*http.Request)
+ validateResponse func(*http.Response) *Error
+
+ // io.Pipe is used to implement the request body for client streaming calls.
+ // If the request is unary, requestBodyWriter is nil.
+ requestBodyWriter *io.PipeWriter
+
+ // requestSent ensures we only send the request once.
+ requestSent atomic.Bool
+ request *http.Request
+
+ // responseReady is closed when the response is ready or when the request
+ // fails. Any error on request initialisation will be set on the
+ // responseErr. There's always a response if responseErr is nil.
+ responseReady chan struct{}
+ response *http.Response
+ responseErr error
+}
+
+func newDuplexHTTPCall(
+ ctx context.Context,
+ httpClient HTTPClient,
+ url *url.URL,
+ spec Spec,
+ header http.Header,
+) *duplexHTTPCall {
+ // ensure we make a copy of the url before we pass along to the
+ // Request. This ensures if a transport out of our control wants
+ // to mutate the req.URL, we don't feel the effects of it.
+ url = cloneURL(url)
+
+ // This is mirroring what http.NewRequestContext did, but
+ // using an already parsed url.URL object, rather than a string
+ // and parsing it again. This is a bit funny with HTTP/1.1
+ // explicitly, but this is logic copied over from
+ // NewRequestContext and doesn't effect the actual version
+ // being transmitted.
+ request := (&http.Request{
+ Method: http.MethodPost,
+ URL: url,
+ Header: header,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Body: http.NoBody,
+ GetBody: getNoBody,
+ Host: url.Host,
+ }).WithContext(ctx)
+ return &duplexHTTPCall{
+ ctx: ctx,
+ httpClient: httpClient,
+ streamType: spec.StreamType,
+ request: request,
+ responseReady: make(chan struct{}),
+ }
+}
+
+// Send sends a message to the server.
+func (d *duplexHTTPCall) Send(payload messagePayload) (int64, error) {
+ if d.streamType&StreamTypeClient == 0 {
+ return d.sendUnary(payload)
+ }
+ isFirst := d.requestSent.CompareAndSwap(false, true)
+ if isFirst {
+ // This is the first time we're sending a message to the server.
+ // We need to send the request headers and start the request.
+ pipeReader, pipeWriter := io.Pipe()
+ d.requestBodyWriter = pipeWriter
+ d.request.Body = pipeReader
+ d.request.GetBody = nil // GetBody not supported for client streaming
+ d.request.ContentLength = -1
+ go d.makeRequest() // concurrent request
+ }
+ if err := d.ctx.Err(); err != nil {
+ return 0, wrapIfContextError(err)
+ }
+ if isFirst && payload.Len() == 0 {
+ // On first write a nil Send is used to send request headers. Avoid
+ // writing a zero-length payload to avoid superfluous errors with close.
+ return 0, nil
+ }
+ // It's safe to write to this side of the pipe while net/http concurrently
+ // reads from the other side.
+ bytesWritten, err := payload.WriteTo(d.requestBodyWriter)
+ if err != nil && errors.Is(err, io.ErrClosedPipe) {
+ // Signal that the stream is closed with the more-typical io.EOF instead of
+ // io.ErrClosedPipe. This makes it easier for protocol-specific wrappers to
+ // match grpc-go's behavior.
+ err = io.EOF
+ }
+ return bytesWritten, err
+}
+
+func (d *duplexHTTPCall) sendUnary(payload messagePayload) (int64, error) {
+ // Unary messages are sent as a single HTTP request. We don't need to use a
+ // pipe for the request body and we don't need to send headers separately.
+ if !d.requestSent.CompareAndSwap(false, true) {
+ return 0, fmt.Errorf("request already sent")
+ }
+ payloadLength := int64(payload.Len())
+ if payloadLength > 0 {
+ // Build the request body from the payload.
+ payloadBody := newPayloadCloser(payload)
+ d.request.Body = payloadBody
+ d.request.ContentLength = payloadLength
+ d.request.GetBody = func() (io.ReadCloser, error) {
+ if !payloadBody.Rewind() {
+ return nil, fmt.Errorf("payload cannot be retried")
+ }
+ return payloadBody, nil
+ }
+ // Release the payload ensuring that after Send returns the
+ // payload is safe to be reused. See [http.RoundTripper] for
+ // more details.
+ defer payloadBody.Release()
+ }
+ d.makeRequest() // synchronous request
+ if d.responseErr != nil {
+ // Check on response errors for context errors. Other errors are
+ // handled on read.
+ if err := d.ctx.Err(); err != nil {
+ return 0, wrapIfContextError(err)
+ }
+ }
+ return payloadLength, nil
+}
+
+// CloseWrite closes the request body. Callers *must* call CloseWrite before Read when
+// using HTTP/1.x.
+func (d *duplexHTTPCall) CloseWrite() error {
+ // Even if Write was never called, we need to make an HTTP request. This
+ // ensures that we've sent any headers to the server and that we have an HTTP
+ // response to read from.
+ if d.requestSent.CompareAndSwap(false, true) {
+ go d.makeRequest()
+ return nil
+ }
+ // The user calls CloseWrite to indicate that they're done sending data. It's
+ // safe to close the write side of the pipe while net/http is reading from
+ // it.
+ //
+ // Because connect also supports some RPC types over HTTP/1.1, we need to be
+ // careful how we expose this method to users. HTTP/1.1 doesn't support
+ // bidirectional streaming - the write side of the stream (aka request body)
+ // must be closed before we start reading the response or we'll just block
+ // forever. To make sure users don't have to worry about this, the generated
+ // code for unary, client streaming, and server streaming RPCs must call
+ // CloseWrite automatically rather than requiring the user to do it.
+ if d.requestBodyWriter != nil {
+ return d.requestBodyWriter.Close()
+ }
+ return d.request.Body.Close()
+}
+
+// Header returns the HTTP request headers.
+func (d *duplexHTTPCall) Header() http.Header {
+ return d.request.Header
+}
+
+// Trailer returns the HTTP request trailers.
+func (d *duplexHTTPCall) Trailer() http.Header {
+ return d.request.Trailer
+}
+
+// URL returns the URL for the request.
+func (d *duplexHTTPCall) URL() *url.URL {
+ return d.request.URL
+}
+
+// Method returns the HTTP method for the request (GET or POST).
+func (d *duplexHTTPCall) Method() string {
+ return d.request.Method
+}
+
+// SetMethod changes the method of the request before it is sent.
+func (d *duplexHTTPCall) SetMethod(method string) {
+ d.request.Method = method
+}
+
+// Read from the response body. Returns the first error passed to SetError.
+func (d *duplexHTTPCall) Read(data []byte) (int, error) {
+ // First, we wait until we've gotten the response headers and established the
+ // server-to-client side of the stream.
+ if err := d.BlockUntilResponseReady(); err != nil {
+ // The stream is already closed or corrupted.
+ return 0, err
+ }
+ // Before we read, check if the context has been canceled.
+ if err := d.ctx.Err(); err != nil {
+ return 0, wrapIfContextError(err)
+ }
+ n, err := d.response.Body.Read(data)
+ if err != nil && !errors.Is(err, io.EOF) {
+ err = wrapIfContextDone(d.ctx, err)
+ err = wrapIfRSTError(err)
+ }
+ return n, err
+}
+
+func (d *duplexHTTPCall) CloseRead() error {
+ _ = d.BlockUntilResponseReady()
+ if d.response == nil {
+ return nil
+ }
+ _, err := discard(d.response.Body)
+ closeErr := d.response.Body.Close()
+ if err == nil ||
+ errors.Is(err, context.Canceled) ||
+ errors.Is(err, context.DeadlineExceeded) {
+ err = closeErr
+ }
+ err = wrapIfContextDone(d.ctx, err)
+ return wrapIfRSTError(err)
+}
+
+// ResponseStatusCode is the response's HTTP status code.
+func (d *duplexHTTPCall) ResponseStatusCode() (int, error) {
+ if err := d.BlockUntilResponseReady(); err != nil {
+ return 0, err
+ }
+ return d.response.StatusCode, nil
+}
+
+// ResponseHeader returns the response HTTP headers.
+func (d *duplexHTTPCall) ResponseHeader() http.Header {
+ _ = d.BlockUntilResponseReady()
+ if d.response != nil {
+ return d.response.Header
+ }
+ return make(http.Header)
+}
+
+// ResponseTrailer returns the response HTTP trailers.
+func (d *duplexHTTPCall) ResponseTrailer() http.Header {
+ _ = d.BlockUntilResponseReady()
+ if d.response != nil {
+ return d.response.Trailer
+ }
+ return make(http.Header)
+}
+
+// SetValidateResponse sets the response validation function. The function runs
+// in a background goroutine.
+func (d *duplexHTTPCall) SetValidateResponse(validate func(*http.Response) *Error) {
+ d.validateResponse = validate
+}
+
+// BlockUntilResponseReady returns when the response is ready or reports an
+// error from initializing the request.
+func (d *duplexHTTPCall) BlockUntilResponseReady() error {
+ <-d.responseReady
+ return d.responseErr
+}
+
+func (d *duplexHTTPCall) makeRequest() {
+ // This runs concurrently with Write and CloseWrite. Read and CloseRead wait
+ // on d.responseReady, so we can't race with them.
+ defer close(d.responseReady)
+
+ // Promote the header Host to the request object.
+ if host := getHeaderCanonical(d.request.Header, headerHost); len(host) > 0 {
+ d.request.Host = host
+ }
+ if d.onRequestSend != nil {
+ d.onRequestSend(d.request)
+ }
+ // Once we send a message to the server, they send a message back and
+ // establish the receive side of the stream.
+ // On error, we close the request body using the Write side of the pipe.
+ // This ensures HTTP2 streams receive an io.EOF from the Read side of the
+ // pipe. Write's check for io.ErrClosedPipe and will convert this to io.EOF.
+ response, err := d.httpClient.Do(d.request) //nolint:bodyclose
+ if err != nil {
+ err = wrapIfContextError(err)
+ err = wrapIfLikelyH2CNotConfiguredError(d.request, err)
+ err = wrapIfLikelyWithGRPCNotUsedError(err)
+ err = wrapIfRSTError(err)
+ if _, ok := asError(err); !ok {
+ err = NewError(CodeUnavailable, err)
+ }
+ d.responseErr = err
+ _ = d.CloseWrite()
+ return
+ }
+ // We've got a response. We can now read from the response body.
+ // Closing the response body is delegated to the caller even on error.
+ d.response = response
+ if err := d.validateResponse(response); err != nil {
+ d.responseErr = err
+ _ = d.CloseWrite()
+ return
+ }
+ if (d.streamType&StreamTypeBidi) == StreamTypeBidi && response.ProtoMajor < 2 {
+ // If we somehow dialed an HTTP/1.x server, fail with an explicit message
+ // rather than returning a more cryptic error later on.
+ d.responseErr = errorf(
+ CodeUnimplemented,
+ "response from %v is HTTP/%d.%d: bidi streams require at least HTTP/2",
+ d.request.URL,
+ response.ProtoMajor,
+ response.ProtoMinor,
+ )
+ _ = d.CloseWrite()
+ }
+}
+
+// getNoBody is a GetBody function for http.NoBody.
+func getNoBody() (io.ReadCloser, error) {
+ return http.NoBody, nil
+}
+
+// messagePayload is a sized and seekable message payload. The interface is
+// implemented by [*bytes.Reader] and *envelope. Reads must be non-blocking.
+type messagePayload interface {
+ io.Reader
+ io.WriterTo
+ io.Seeker
+ Len() int
+}
+
+// nopPayload is a message payload that does nothing. It's used to send headers
+// to the server.
+type nopPayload struct{}
+
+var _ messagePayload = nopPayload{}
+
+func (nopPayload) Read([]byte) (int, error) {
+ return 0, io.EOF
+}
+func (nopPayload) WriteTo(io.Writer) (int64, error) {
+ return 0, nil
+}
+func (nopPayload) Seek(int64, int) (int64, error) {
+ return 0, nil
+}
+func (nopPayload) Len() int {
+ return 0
+}
+
+// messageSender sends a message payload. The interface is implemented by
+// [*duplexHTTPCall] and writeSender.
+type messageSender interface {
+ Send(messagePayload) (int64, error)
+}
+
+// writeSender is a sender that writes to an [io.Writer]. Useful for wrapping
+// [http.ResponseWriter].
+type writeSender struct {
+ writer io.Writer
+}
+
+var _ messageSender = writeSender{}
+
+func (w writeSender) Send(payload messagePayload) (int64, error) {
+ return payload.WriteTo(w.writer)
+}
+
+// See: https://cs.opensource.google/go/go/+/refs/tags/go1.20.1:src/net/http/clone.go;l=22-33
+func cloneURL(oldURL *url.URL) *url.URL {
+ if oldURL == nil {
+ return nil
+ }
+ newURL := new(url.URL)
+ *newURL = *oldURL
+ if oldURL.User != nil {
+ newURL.User = new(url.Userinfo)
+ *newURL.User = *oldURL.User
+ }
+ return newURL
+}
+
+// payloadCloser is an [io.ReadCloser] that wraps a messagePayload. It's used to
+// implement the request body for unary calls. To safely reuse the buffer
+// call Release after the response is received to ensure the payload is safe for
+// reuse.
+type payloadCloser struct {
+ mu sync.Mutex
+ payload messagePayload // nil after Release
+}
+
+func newPayloadCloser(payload messagePayload) *payloadCloser {
+ return &payloadCloser{
+ payload: payload,
+ }
+}
+
+// Read implements [io.Reader].
+func (p *payloadCloser) Read(dst []byte) (readN int, err error) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.payload == nil {
+ return 0, io.EOF
+ }
+ return p.payload.Read(dst)
+}
+
+// WriteTo implements [io.WriterTo].
+func (p *payloadCloser) WriteTo(dst io.Writer) (int64, error) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.payload == nil {
+ return 0, nil
+ }
+ return p.payload.WriteTo(dst)
+}
+
+// Close implements [io.Closer].
+func (p *payloadCloser) Close() error {
+ return nil
+}
+
+// Rewind rewinds the payload to the beginning. It returns false if the
+// payload has been discarded from a previous call to Release.
+func (p *payloadCloser) Rewind() bool {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.payload == nil {
+ return false
+ }
+ if _, err := p.payload.Seek(0, io.SeekStart); err != nil {
+ return false
+ }
+ return true
+}
+
+// Release discards the payload. After Release is called, the payload cannot be
+// rewound and the payload is safe to reuse.
+func (p *payloadCloser) Release() {
+ p.mu.Lock()
+ p.payload = nil
+ p.mu.Unlock()
+}
diff --git a/vendor/connectrpc.com/connect/envelope.go b/vendor/connectrpc.com/connect/envelope.go
new file mode 100644
index 0000000..bc85c55
--- /dev/null
+++ b/vendor/connectrpc.com/connect/envelope.go
@@ -0,0 +1,374 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bytes"
+ "context"
+ "encoding/binary"
+ "errors"
+ "io"
+)
+
+// flagEnvelopeCompressed indicates that the data is compressed. It has the
+// same meaning in the gRPC-Web, gRPC-HTTP2, and Connect protocols.
+const flagEnvelopeCompressed = 0b00000001
+
+var errSpecialEnvelope = errorf(
+ CodeUnknown,
+ "final message has protocol-specific flags: %w",
+ // User code checks for end of stream with errors.Is(err, io.EOF).
+ io.EOF,
+)
+
+// envelope is a block of arbitrary bytes wrapped in gRPC and Connect's framing
+// protocol.
+//
+// Each message is preceded by a 5-byte prefix. The first byte is a uint8 used
+// as a set of bitwise flags, and the remainder is a uint32 indicating the
+// message length. gRPC and Connect interpret the bitwise flags differently, so
+// envelope leaves their interpretation up to the caller.
+type envelope struct {
+ Data *bytes.Buffer
+ Flags uint8
+ offset int64
+}
+
+var _ messagePayload = (*envelope)(nil)
+
+func (e *envelope) IsSet(flag uint8) bool {
+ return e.Flags&flag == flag
+}
+
+// Read implements [io.Reader].
+func (e *envelope) Read(data []byte) (readN int, err error) {
+ if e.offset < 5 {
+ prefix := makeEnvelopePrefix(e.Flags, e.Data.Len())
+ readN = copy(data, prefix[e.offset:])
+ e.offset += int64(readN)
+ if e.offset < 5 {
+ return readN, nil
+ }
+ data = data[readN:]
+ }
+ n := copy(data, e.Data.Bytes()[e.offset-5:])
+ e.offset += int64(n)
+ readN += n
+ if readN == 0 && e.offset == int64(e.Data.Len()+5) {
+ err = io.EOF
+ }
+ return readN, err
+}
+
+// WriteTo implements [io.WriterTo].
+func (e *envelope) WriteTo(dst io.Writer) (wroteN int64, err error) {
+ if e.offset < 5 {
+ prefix := makeEnvelopePrefix(e.Flags, e.Data.Len())
+ prefixN, err := dst.Write(prefix[e.offset:])
+ e.offset += int64(prefixN)
+ wroteN += int64(prefixN)
+ if e.offset < 5 {
+ return wroteN, err
+ }
+ }
+ n, err := dst.Write(e.Data.Bytes()[e.offset-5:])
+ e.offset += int64(n)
+ wroteN += int64(n)
+ return wroteN, err
+}
+
+// Seek implements [io.Seeker]. Based on the implementation of [bytes.Reader].
+func (e *envelope) Seek(offset int64, whence int) (int64, error) {
+ var abs int64
+ switch whence {
+ case io.SeekStart:
+ abs = offset
+ case io.SeekCurrent:
+ abs = e.offset + offset
+ case io.SeekEnd:
+ abs = int64(e.Data.Len()) + offset
+ default:
+ return 0, errors.New("connect.envelope.Seek: invalid whence")
+ }
+ if abs < 0 {
+ return 0, errors.New("connect.envelope.Seek: negative position")
+ }
+ e.offset = abs
+ return abs, nil
+}
+
+// Len returns the number of bytes of the unread portion of the envelope.
+func (e *envelope) Len() int {
+ if length := int(int64(e.Data.Len()) + 5 - e.offset); length > 0 {
+ return length
+ }
+ return 0
+}
+
+type envelopeWriter struct {
+ ctx context.Context //nolint:containedctx
+ sender messageSender
+ codec Codec
+ compressMinBytes int
+ compressionPool *compressionPool
+ bufferPool *bufferPool
+ sendMaxBytes int
+}
+
+func (w *envelopeWriter) Marshal(message any) *Error {
+ if message == nil {
+ // Send no-op message to create the request and send headers.
+ payload := nopPayload{}
+ if _, err := w.sender.Send(payload); err != nil {
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return NewError(CodeUnknown, err)
+ }
+ return nil
+ }
+ if appender, ok := w.codec.(marshalAppender); ok {
+ return w.marshalAppend(message, appender)
+ }
+ return w.marshal(message)
+}
+
+// Write writes the enveloped message, compressing as necessary. It doesn't
+// retain any references to the supplied envelope or its underlying data.
+func (w *envelopeWriter) Write(env *envelope) *Error {
+ if env.IsSet(flagEnvelopeCompressed) ||
+ w.compressionPool == nil ||
+ env.Data.Len() < w.compressMinBytes {
+ if w.sendMaxBytes > 0 && env.Data.Len() > w.sendMaxBytes {
+ return errorf(CodeResourceExhausted, "message size %d exceeds sendMaxBytes %d", env.Data.Len(), w.sendMaxBytes)
+ }
+ return w.write(env)
+ }
+ data := w.bufferPool.Get()
+ defer w.bufferPool.Put(data)
+ if err := w.compressionPool.Compress(data, env.Data); err != nil {
+ return err
+ }
+ if w.sendMaxBytes > 0 && data.Len() > w.sendMaxBytes {
+ return errorf(CodeResourceExhausted, "compressed message size %d exceeds sendMaxBytes %d", data.Len(), w.sendMaxBytes)
+ }
+ return w.write(&envelope{
+ Data: data,
+ Flags: env.Flags | flagEnvelopeCompressed,
+ })
+}
+
+func (w *envelopeWriter) marshalAppend(message any, codec marshalAppender) *Error {
+ // Codec supports MarshalAppend; try to re-use a []byte from the pool.
+ buffer := w.bufferPool.Get()
+ defer w.bufferPool.Put(buffer)
+ raw, err := codec.MarshalAppend(buffer.Bytes(), message)
+ if err != nil {
+ return errorf(CodeInternal, "marshal message: %w", err)
+ }
+ if cap(raw) > buffer.Cap() {
+ // The buffer from the pool was too small, so MarshalAppend grew the slice.
+ // Pessimistically assume that the too-small buffer is insufficient for the
+ // application workload, so there's no point in keeping it in the pool.
+ // Instead, replace it with the larger, newly-allocated slice. This
+ // allocates, but it's a small, constant-size allocation.
+ *buffer = *bytes.NewBuffer(raw)
+ } else {
+ // MarshalAppend didn't allocate, but we need to fix the internal state of
+ // the buffer. Compared to replacing the buffer (as above), buffer.Write
+ // copies but avoids allocating.
+ buffer.Write(raw)
+ }
+ envelope := &envelope{Data: buffer}
+ return w.Write(envelope)
+}
+
+func (w *envelopeWriter) marshal(message any) *Error {
+ // Codec doesn't support MarshalAppend; let Marshal allocate a []byte.
+ raw, err := w.codec.Marshal(message)
+ if err != nil {
+ return errorf(CodeInternal, "marshal message: %w", err)
+ }
+ buffer := bytes.NewBuffer(raw)
+ // Put our new []byte into the pool for later reuse.
+ defer w.bufferPool.Put(buffer)
+ envelope := &envelope{Data: buffer}
+ return w.Write(envelope)
+}
+
+func (w *envelopeWriter) write(env *envelope) *Error {
+ if _, err := w.sender.Send(env); err != nil {
+ err = wrapIfContextDone(w.ctx, err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeUnknown, "write envelope: %w", err)
+ }
+ return nil
+}
+
+type envelopeReader struct {
+ ctx context.Context //nolint:containedctx
+ reader io.Reader
+ bytesRead int64 // detect trailers-only gRPC responses
+ codec Codec
+ last envelope
+ compressionPool *compressionPool
+ bufferPool *bufferPool
+ readMaxBytes int
+}
+
+func (r *envelopeReader) Unmarshal(message any) *Error {
+ buffer := r.bufferPool.Get()
+ var dontRelease *bytes.Buffer
+ defer func() {
+ if buffer != dontRelease {
+ r.bufferPool.Put(buffer)
+ }
+ }()
+
+ env := &envelope{Data: buffer}
+ err := r.Read(env)
+ switch {
+ case err == nil && env.IsSet(flagEnvelopeCompressed) && r.compressionPool == nil:
+ return errorf(
+ CodeInternal,
+ "protocol error: sent compressed message without compression support",
+ )
+ case err == nil &&
+ (env.Flags == 0 || env.Flags == flagEnvelopeCompressed) &&
+ env.Data.Len() == 0:
+ // This is a standard message (because none of the top 7 bits are set) and
+ // there's no data, so the zero value of the message is correct.
+ return nil
+ case err != nil && errors.Is(err, io.EOF):
+ // The stream has ended. Propagate the EOF to the caller.
+ return err
+ case err != nil:
+ // Something's wrong.
+ return err
+ }
+
+ data := env.Data
+ if data.Len() > 0 && env.IsSet(flagEnvelopeCompressed) {
+ decompressed := r.bufferPool.Get()
+ defer func() {
+ if decompressed != dontRelease {
+ r.bufferPool.Put(decompressed)
+ }
+ }()
+ if err := r.compressionPool.Decompress(decompressed, data, int64(r.readMaxBytes)); err != nil {
+ return err
+ }
+ data = decompressed
+ }
+
+ if env.Flags != 0 && env.Flags != flagEnvelopeCompressed {
+ // Drain the rest of the stream to ensure there is no extra data.
+ numBytes, err := discard(r.reader)
+ r.bytesRead += numBytes
+ if err != nil {
+ err = wrapIfContextError(err)
+ if connErr, ok := asError(err); ok {
+ return connErr
+ }
+ return errorf(CodeInternal, "corrupt response: I/O error after end-stream message: %w", err)
+ } else if numBytes > 0 {
+ return errorf(CodeInternal, "corrupt response: %d extra bytes after end of stream", numBytes)
+ }
+ // One of the protocol-specific flags are set, so this is the end of the
+ // stream. Save the message for protocol-specific code to process and
+ // return a sentinel error. We alias the buffer with dontRelease as a
+ // way of marking it so above defers don't release it to the pool.
+ r.last = envelope{
+ Data: data,
+ Flags: env.Flags,
+ }
+ dontRelease = data
+ return errSpecialEnvelope
+ }
+
+ if err := r.codec.Unmarshal(data.Bytes(), message); err != nil {
+ return errorf(CodeInvalidArgument, "unmarshal message: %w", err)
+ }
+ return nil
+}
+
+func (r *envelopeReader) Read(env *envelope) *Error {
+ prefixes := [5]byte{}
+ // io.ReadFull reads the number of bytes requested, or returns an error.
+ // io.EOF will only be returned if no bytes were read.
+ n, err := io.ReadFull(r.reader, prefixes[:])
+ r.bytesRead += int64(n)
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ // The stream ended cleanly. That's expected, but we need to propagate an EOF
+ // to the user so that they know that the stream has ended. We shouldn't
+ // add any alarming text about protocol errors, though.
+ return NewError(CodeUnknown, err)
+ }
+ err = wrapIfMaxBytesError(err, "read 5 byte message prefix")
+ err = wrapIfContextDone(r.ctx, err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ // Something else has gone wrong - the stream didn't end cleanly.
+ return errorf(
+ CodeInvalidArgument,
+ "protocol error: incomplete envelope: %w", err,
+ )
+ }
+ size := int64(binary.BigEndian.Uint32(prefixes[1:5]))
+ if r.readMaxBytes > 0 && size > int64(r.readMaxBytes) {
+ n, err := io.CopyN(io.Discard, r.reader, size)
+ r.bytesRead += n
+ if err != nil && !errors.Is(err, io.EOF) {
+ return errorf(CodeResourceExhausted, "message is larger than configured max %d - unable to determine message size: %w", r.readMaxBytes, err)
+ }
+ return errorf(CodeResourceExhausted, "message size %d is larger than configured max %d", size, r.readMaxBytes)
+ }
+ // We've read the prefix, so we know how many bytes to expect.
+ // CopyN will return an error if it doesn't read the requested
+ // number of bytes.
+ readN, err := io.CopyN(env.Data, r.reader, size)
+ r.bytesRead += readN
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ // We've gotten fewer bytes than we expected, so the stream has ended
+ // unexpectedly.
+ return errorf(
+ CodeInvalidArgument,
+ "protocol error: promised %d bytes in enveloped message, got %d bytes",
+ size,
+ readN,
+ )
+ }
+ err = wrapIfMaxBytesError(err, "read %d byte message", size)
+ err = wrapIfContextDone(r.ctx, err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeUnknown, "read enveloped message: %w", err)
+ }
+ env.Flags = prefixes[0]
+ return nil
+}
+
+func makeEnvelopePrefix(flags uint8, size int) [5]byte {
+ prefix := [5]byte{}
+ prefix[0] = flags
+ binary.BigEndian.PutUint32(prefix[1:5], uint32(size))
+ return prefix
+}
diff --git a/vendor/connectrpc.com/connect/error.go b/vendor/connectrpc.com/connect/error.go
new file mode 100644
index 0000000..f461d1b
--- /dev/null
+++ b/vendor/connectrpc.com/connect/error.go
@@ -0,0 +1,464 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+ "os"
+ "strings"
+
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/anypb"
+)
+
+const (
+ commonErrorsURL = "https://connectrpc.com/docs/go/common-errors"
+ defaultAnyResolverPrefix = "type.googleapis.com/"
+)
+
+var (
+ // errNotModified signals Connect-protocol responses to GET requests to use the
+ // 304 Not Modified HTTP error code.
+ errNotModified = errors.New("not modified")
+ // errNotModifiedClient wraps ErrNotModified for use client-side.
+ errNotModifiedClient = fmt.Errorf("HTTP 304: %w", errNotModified)
+)
+
+// An ErrorDetail is a self-describing Protobuf message attached to an [*Error].
+// Error details are sent over the network to clients, which can then work with
+// strongly-typed data rather than trying to parse a complex error message. For
+// example, you might use details to send a localized error message or retry
+// parameters to the client.
+//
+// The [google.golang.org/genproto/googleapis/rpc/errdetails] package contains a
+// variety of Protobuf messages commonly used as error details.
+type ErrorDetail struct {
+ pbAny *anypb.Any
+ pbInner proto.Message // if nil, must be extracted from pbAny
+ wireJSON string // preserve human-readable JSON
+}
+
+// NewErrorDetail constructs a new error detail. If msg is an *[anypb.Any] then
+// it is used as is. Otherwise, it is first marshalled into an *[anypb.Any]
+// value. This returns an error if msg cannot be marshalled.
+func NewErrorDetail(msg proto.Message) (*ErrorDetail, error) {
+ // If it's already an Any, don't wrap it inside another.
+ if pb, ok := msg.(*anypb.Any); ok {
+ return &ErrorDetail{pbAny: pb}, nil
+ }
+ pb, err := anypb.New(msg)
+ if err != nil {
+ return nil, err
+ }
+ return &ErrorDetail{pbAny: pb, pbInner: msg}, nil
+}
+
+// Type is the fully-qualified name of the detail's Protobuf message (for
+// example, acme.foo.v1.FooDetail).
+func (d *ErrorDetail) Type() string {
+ // proto.Any tries to make messages self-describing by using type URLs rather
+ // than plain type names, but there aren't any descriptor registries
+ // deployed. With the current state of the `Any` code, it's not possible to
+ // build a useful type registry either. To hide this from users, we should
+ // trim the URL prefix is added to the type name.
+ //
+ // If we ever want to support remote registries, we can add an explicit
+ // `TypeURL` method.
+ return typeNameFromURL(d.pbAny.GetTypeUrl())
+}
+
+// Bytes returns a copy of the Protobuf-serialized detail.
+func (d *ErrorDetail) Bytes() []byte {
+ out := make([]byte, len(d.pbAny.GetValue()))
+ copy(out, d.pbAny.GetValue())
+ return out
+}
+
+// Value uses the Protobuf runtime's package-global registry to unmarshal the
+// Detail into a strongly-typed message. Typically, clients use Go type
+// assertions to cast from the proto.Message interface to concrete types.
+func (d *ErrorDetail) Value() (proto.Message, error) {
+ if d.pbInner != nil {
+ // We clone it so that if the caller mutates the returned value,
+ // they don't inadvertently corrupt this error detail value.
+ return proto.Clone(d.pbInner), nil
+ }
+ return d.pbAny.UnmarshalNew()
+}
+
+// An Error captures four key pieces of information: a [Code], an underlying Go
+// error, a map of metadata, and an optional collection of arbitrary Protobuf
+// messages called "details" (more on those below). Servers send the code, the
+// underlying error's Error() output, the metadata, and details over the wire
+// to clients. Remember that the underlying error's message will be sent to
+// clients - take care not to leak sensitive information from public APIs!
+//
+// Service implementations and interceptors should return errors that can be
+// cast to an [*Error] (using the standard library's [errors.As]). If the returned
+// error can't be cast to an [*Error], connect will use [CodeUnknown] and the
+// returned error's message.
+//
+// Error details are an optional mechanism for servers, interceptors, and
+// proxies to attach arbitrary Protobuf messages to the error code and message.
+// They're a clearer and more performant alternative to HTTP header
+// microformats. See [the documentation on errors] for more details.
+//
+// [the documentation on errors]: https://connectrpc.com/docs/go/errors
+type Error struct {
+ code Code
+ err error
+ details []*ErrorDetail
+ meta http.Header
+ wireErr bool
+}
+
+// NewError annotates any Go error with a status code.
+func NewError(c Code, underlying error) *Error {
+ return &Error{code: c, err: underlying}
+}
+
+// NewWireError is similar to [NewError], but the resulting *Error returns true
+// when tested with [IsWireError].
+//
+// This is useful for clients trying to propagate partial failures from
+// streaming RPCs. Often, these RPCs include error information in their
+// response messages (for example, [gRPC server reflection] and
+// OpenTelemetry's [OTLP]). Clients propagating these errors up the stack
+// should use NewWireError to clarify that the error code, message, and details
+// (if any) were explicitly sent by the server rather than inferred from a
+// lower-level networking error or timeout.
+//
+// [gRPC server reflection]: https://github.com/grpc/grpc/blob/v1.49.2/src/proto/grpc/reflection/v1alpha/reflection.proto#L132-L136
+// [OTLP]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#partial-success
+func NewWireError(c Code, underlying error) *Error {
+ err := NewError(c, underlying)
+ err.wireErr = true
+ return err
+}
+
+// IsWireError checks whether the error was returned by the server, as opposed
+// to being synthesized by the client.
+//
+// Clients may find this useful when deciding how to propagate errors. For
+// example, an RPC-to-HTTP proxy might expose a server-sent CodeUnknown as an
+// HTTP 500 but a client-synthesized CodeUnknown as a 503.
+//
+// Handlers will strip [Error.Meta] headers propagated from wire errors to avoid
+// leaking response headers. To propagate headers recreate the error as a
+// non-wire error.
+func IsWireError(err error) bool {
+ se := new(Error)
+ if !errors.As(err, &se) {
+ return false
+ }
+ return se.wireErr
+}
+
+// NewNotModifiedError indicates that the requested resource hasn't changed. It
+// should be used only when handlers wish to respond to conditional HTTP GET
+// requests with a 304 Not Modified. In all other circumstances, including all
+// RPCs using the gRPC or gRPC-Web protocols, it's equivalent to sending an
+// error with [CodeUnknown]. The supplied headers should include Etag,
+// Cache-Control, or any other headers required by [RFC 9110 § 15.4.5].
+//
+// Clients should check for this error using [IsNotModifiedError].
+//
+// [RFC 9110 § 15.4.5]: https://httpwg.org/specs/rfc9110.html#status.304
+func NewNotModifiedError(headers http.Header) *Error {
+ err := NewError(CodeUnknown, errNotModified)
+ if headers != nil {
+ err.meta = headers
+ }
+ return err
+}
+
+func (e *Error) Error() string {
+ message := e.Message()
+ if message == "" {
+ return e.code.String()
+ }
+ return e.code.String() + ": " + message
+}
+
+// Message returns the underlying error message. It may be empty if the
+// original error was created with a status code and a nil error.
+func (e *Error) Message() string {
+ if e.err != nil {
+ return e.err.Error()
+ }
+ return ""
+}
+
+// Unwrap allows [errors.Is] and [errors.As] access to the underlying error.
+func (e *Error) Unwrap() error {
+ return e.err
+}
+
+// Code returns the error's status code.
+func (e *Error) Code() Code {
+ return e.code
+}
+
+// Details returns the error's details.
+func (e *Error) Details() []*ErrorDetail {
+ return e.details
+}
+
+// AddDetail appends to the error's details.
+func (e *Error) AddDetail(d *ErrorDetail) {
+ e.details = append(e.details, d)
+}
+
+// Meta allows the error to carry additional information as key-value pairs.
+//
+// Metadata attached to errors returned by unary handlers is always sent as
+// HTTP headers, regardless of the protocol. Metadata attached to errors
+// returned by streaming handlers may be sent as HTTP headers, HTTP trailers,
+// or a block of in-body metadata, depending on the protocol in use and whether
+// or not the handler has already written messages to the stream.
+//
+// Protocol-specific headers and trailers may be removed to avoid breaking
+// protocol semantics. For example, Content-Length and Content-Type headers
+// won't be propagated. See the documentation for each protocol for more
+// datails.
+//
+// When clients receive errors, the metadata contains the union of the HTTP
+// headers and the protocol-specific trailers (either HTTP trailers or in-body
+// metadata).
+func (e *Error) Meta() http.Header {
+ if e.meta == nil {
+ e.meta = make(http.Header)
+ }
+ return e.meta
+}
+
+func (e *Error) detailsAsAny() []*anypb.Any {
+ anys := make([]*anypb.Any, 0, len(e.details))
+ for _, detail := range e.details {
+ anys = append(anys, detail.pbAny)
+ }
+ return anys
+}
+
+// IsNotModifiedError checks whether the supplied error indicates that the
+// requested resource hasn't changed. It only returns true if the server used
+// [NewNotModifiedError] in response to a Connect-protocol RPC made with an
+// HTTP GET.
+func IsNotModifiedError(err error) bool {
+ return errors.Is(err, errNotModified)
+}
+
+// errorf calls fmt.Errorf with the supplied template and arguments, then wraps
+// the resulting error.
+func errorf(c Code, template string, args ...any) *Error {
+ return NewError(c, fmt.Errorf(template, args...))
+}
+
+// asError uses errors.As to unwrap any error and look for a connect *Error.
+func asError(err error) (*Error, bool) {
+ var connectErr *Error
+ ok := errors.As(err, &connectErr)
+ return connectErr, ok
+}
+
+// wrapIfUncoded ensures that all errors are wrapped. It leaves already-wrapped
+// errors unchanged, uses wrapIfContextError to apply codes to context.Canceled
+// and context.DeadlineExceeded, and falls back to wrapping other errors with
+// CodeUnknown.
+func wrapIfUncoded(err error) error {
+ if err == nil {
+ return nil
+ }
+ maybeCodedErr := wrapIfContextError(err)
+ if _, ok := asError(maybeCodedErr); ok {
+ return maybeCodedErr
+ }
+ return NewError(CodeUnknown, maybeCodedErr)
+}
+
+// wrapIfContextError applies CodeCanceled or CodeDeadlineExceeded to Go's
+// context.Canceled and context.DeadlineExceeded errors, but only if they
+// haven't already been wrapped.
+func wrapIfContextError(err error) error {
+ if err == nil {
+ return nil
+ }
+ if _, ok := asError(err); ok {
+ return err
+ }
+ if errors.Is(err, context.Canceled) {
+ return NewError(CodeCanceled, err)
+ }
+ if errors.Is(err, context.DeadlineExceeded) {
+ return NewError(CodeDeadlineExceeded, err)
+ }
+ // Ick, some dial errors can be returned as os.ErrDeadlineExceeded
+ // instead of context.DeadlineExceeded :(
+ // https://github.com/golang/go/issues/64449
+ if errors.Is(err, os.ErrDeadlineExceeded) {
+ return NewError(CodeDeadlineExceeded, err)
+ }
+ return err
+}
+
+// wrapIfContextDone wraps errors with CodeCanceled or CodeDeadlineExceeded
+// if the context is done. It leaves already-wrapped errors unchanged.
+func wrapIfContextDone(ctx context.Context, err error) error {
+ if err == nil {
+ return nil
+ }
+ err = wrapIfContextError(err)
+ if _, ok := asError(err); ok {
+ return err
+ }
+ ctxErr := ctx.Err()
+ if errors.Is(ctxErr, context.Canceled) {
+ return NewError(CodeCanceled, err)
+ } else if errors.Is(ctxErr, context.DeadlineExceeded) {
+ return NewError(CodeDeadlineExceeded, err)
+ }
+ return err
+}
+
+// wrapIfLikelyH2CNotConfiguredError adds a wrapping error that has a message
+// telling the caller that they likely need to use h2c but are using a raw http.Client{}.
+//
+// This happens when running a gRPC-only server.
+// This is fragile and may break over time, and this should be considered a best-effort.
+func wrapIfLikelyH2CNotConfiguredError(request *http.Request, err error) error {
+ if err == nil {
+ return nil
+ }
+ if _, ok := asError(err); ok {
+ return err
+ }
+ if url := request.URL; url != nil && url.Scheme != "http" {
+ // If the scheme is not http, we definitely do not have an h2c error, so just return.
+ return err
+ }
+ // net/http code has been investigated and there is no typing of any of these errors
+ // they are all created with fmt.Errorf
+ // grpc-go returns the first error 2/3-3/4 of the time, and the second error 1/4-1/3 of the time
+ if errString := err.Error(); strings.HasPrefix(errString, `Post "`) &&
+ (strings.Contains(errString, `net/http: HTTP/1.x transport connection broken: malformed HTTP response`) ||
+ strings.HasSuffix(errString, `write: broken pipe`)) {
+ return fmt.Errorf("possible h2c configuration issue when talking to gRPC server, see %s: %w", commonErrorsURL, err)
+ }
+ return err
+}
+
+// wrapIfLikelyWithGRPCNotUsedError adds a wrapping error that has a message
+// telling the caller that they likely forgot to use connect.WithGRPC().
+//
+// This happens when running a gRPC-only server.
+// This is fragile and may break over time, and this should be considered a best-effort.
+func wrapIfLikelyWithGRPCNotUsedError(err error) error {
+ if err == nil {
+ return nil
+ }
+ if _, ok := asError(err); ok {
+ return err
+ }
+ // golang.org/x/net code has been investigated and there is no typing of this error
+ // it is created with fmt.Errorf
+ // http2/transport.go:573: return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
+ if errString := err.Error(); strings.HasPrefix(errString, `Post "`) &&
+ strings.Contains(errString, `http2: Transport: cannot retry err`) &&
+ strings.HasSuffix(errString, `after Request.Body was written; define Request.GetBody to avoid this error`) {
+ return fmt.Errorf("possible missing connect.WithGPRC() client option when talking to gRPC server, see %s: %w", commonErrorsURL, err)
+ }
+ return err
+}
+
+// HTTP/2 has its own set of error codes, which it sends in RST_STREAM frames.
+// When the server sends one of these errors, we should map it back into our
+// RPC error codes following
+// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#http2-transport-mapping.
+//
+// This would be vastly simpler if we were using x/net/http2 directly, since
+// the StreamError type is exported. When x/net/http2 gets vendored into
+// net/http, though, all these types become unexported...so we're left with
+// string munging.
+func wrapIfRSTError(err error) error {
+ const (
+ streamErrPrefix = "stream error: "
+ fromPeerSuffix = "; received from peer"
+ )
+ if err == nil {
+ return nil
+ }
+ if _, ok := asError(err); ok {
+ return err
+ }
+ if urlErr := new(url.Error); errors.As(err, &urlErr) {
+ // If we get an RST_STREAM error from http.Client.Do, it's wrapped in a
+ // *url.Error.
+ err = urlErr.Unwrap()
+ }
+ msg := err.Error()
+ if !strings.HasPrefix(msg, streamErrPrefix) {
+ return err
+ }
+ if !strings.HasSuffix(msg, fromPeerSuffix) {
+ return err
+ }
+ msg = strings.TrimSuffix(msg, fromPeerSuffix)
+ i := strings.LastIndex(msg, ";")
+ if i < 0 || i >= len(msg)-1 {
+ return err
+ }
+ msg = msg[i+1:]
+ msg = strings.TrimSpace(msg)
+ switch msg {
+ case "NO_ERROR", "PROTOCOL_ERROR", "INTERNAL_ERROR", "FLOW_CONTROL_ERROR",
+ "SETTINGS_TIMEOUT", "FRAME_SIZE_ERROR", "COMPRESSION_ERROR", "CONNECT_ERROR":
+ return NewError(CodeInternal, err)
+ case "REFUSED_STREAM":
+ return NewError(CodeUnavailable, err)
+ case "CANCEL":
+ return NewError(CodeCanceled, err)
+ case "ENHANCE_YOUR_CALM":
+ return NewError(CodeResourceExhausted, fmt.Errorf("bandwidth exhausted: %w", err))
+ case "INADEQUATE_SECURITY":
+ return NewError(CodePermissionDenied, fmt.Errorf("transport protocol insecure: %w", err))
+ default:
+ return err
+ }
+}
+
+// wrapIfMaxBytesError wraps errors returned reading from a http.MaxBytesHandler
+// whose limit has been exceeded.
+func wrapIfMaxBytesError(err error, tmpl string, args ...any) error {
+ if err == nil {
+ return nil
+ }
+ if _, ok := asError(err); ok {
+ return err
+ }
+ var maxBytesErr *http.MaxBytesError
+ if ok := errors.As(err, &maxBytesErr); !ok {
+ return err
+ }
+ prefix := fmt.Sprintf(tmpl, args...)
+ return errorf(CodeResourceExhausted, "%s: exceeded %d byte http.MaxBytesReader limit", prefix, maxBytesErr.Limit)
+}
+
+func typeNameFromURL(url string) string {
+ return url[strings.LastIndexByte(url, '/')+1:]
+}
diff --git a/vendor/connectrpc.com/connect/error_writer.go b/vendor/connectrpc.com/connect/error_writer.go
new file mode 100644
index 0000000..58ce3c4
--- /dev/null
+++ b/vendor/connectrpc.com/connect/error_writer.go
@@ -0,0 +1,179 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+)
+
+// protocolType is one of the supported RPC protocols.
+type protocolType uint8
+
+const (
+ unknownProtocol protocolType = iota
+ connectUnaryProtocol
+ connectStreamProtocol
+ grpcProtocol
+ grpcWebProtocol
+)
+
+// An ErrorWriter writes errors to an [http.ResponseWriter] in the format
+// expected by an RPC client. This is especially useful in server-side net/http
+// middleware, where you may wish to handle requests from RPC and non-RPC
+// clients with the same code.
+//
+// ErrorWriters are safe to use concurrently.
+type ErrorWriter struct {
+ bufferPool *bufferPool
+ protobuf Codec
+ requireConnectProtocolHeader bool
+}
+
+// NewErrorWriter constructs an ErrorWriter. Handler options may be passed to
+// configure the error writer behaviour to match the handlers.
+// [WithRequiredConnectProtocolHeader] will assert that Connect protocol
+// requests include the version header allowing the error writer to correctly
+// classify the request.
+// Options supplied via [WithConditionalHandlerOptions] are ignored.
+func NewErrorWriter(opts ...HandlerOption) *ErrorWriter {
+ config := newHandlerConfig("", StreamTypeUnary, opts)
+ codecs := newReadOnlyCodecs(config.Codecs)
+ return &ErrorWriter{
+ bufferPool: config.BufferPool,
+ protobuf: codecs.Protobuf(),
+ requireConnectProtocolHeader: config.RequireConnectProtocolHeader,
+ }
+}
+
+func (w *ErrorWriter) classifyRequest(request *http.Request) protocolType {
+ ctype := canonicalizeContentType(getHeaderCanonical(request.Header, headerContentType))
+ isPost := request.Method == http.MethodPost
+ isGet := request.Method == http.MethodGet
+ switch {
+ case isPost && (ctype == grpcContentTypeDefault || strings.HasPrefix(ctype, grpcContentTypePrefix)):
+ return grpcProtocol
+ case isPost && (ctype == grpcWebContentTypeDefault || strings.HasPrefix(ctype, grpcWebContentTypePrefix)):
+ return grpcWebProtocol
+ case isPost && strings.HasPrefix(ctype, connectStreamingContentTypePrefix):
+ // Streaming ignores the requireConnectProtocolHeader option as the
+ // Content-Type is enough to determine the protocol.
+ if err := connectCheckProtocolVersion(request, false /* required */); err != nil {
+ return unknownProtocol
+ }
+ return connectStreamProtocol
+ case isPost && strings.HasPrefix(ctype, connectUnaryContentTypePrefix):
+ if err := connectCheckProtocolVersion(request, w.requireConnectProtocolHeader); err != nil {
+ return unknownProtocol
+ }
+ return connectUnaryProtocol
+ case isGet:
+ if err := connectCheckProtocolVersion(request, w.requireConnectProtocolHeader); err != nil {
+ return unknownProtocol
+ }
+ return connectUnaryProtocol
+ default:
+ return unknownProtocol
+ }
+}
+
+// IsSupported checks whether a request is using one of the ErrorWriter's
+// supported RPC protocols.
+func (w *ErrorWriter) IsSupported(request *http.Request) bool {
+ return w.classifyRequest(request) != unknownProtocol
+}
+
+// Write an error, using the format appropriate for the RPC protocol in use.
+// Callers should first use IsSupported to verify that the request is using one
+// of the ErrorWriter's supported RPC protocols. If the protocol is unknown,
+// Write will send the error as unprefixed, Connect-formatted JSON.
+//
+// Write does not read or close the request body.
+func (w *ErrorWriter) Write(response http.ResponseWriter, request *http.Request, err error) error {
+ ctype := canonicalizeContentType(getHeaderCanonical(request.Header, headerContentType))
+ switch protocolType := w.classifyRequest(request); protocolType {
+ case connectStreamProtocol:
+ setHeaderCanonical(response.Header(), headerContentType, ctype)
+ return w.writeConnectStreaming(response, err)
+ case grpcProtocol:
+ setHeaderCanonical(response.Header(), headerContentType, ctype)
+ return w.writeGRPC(response, err)
+ case grpcWebProtocol:
+ setHeaderCanonical(response.Header(), headerContentType, ctype)
+ return w.writeGRPCWeb(response, err)
+ case unknownProtocol, connectUnaryProtocol:
+ fallthrough
+ default:
+ // Unary errors are always JSON. Unknown protocols are treated as unary
+ // because they are likely to be Connect clients and will still be able to
+ // parse the error as it's in a human-readable format.
+ setHeaderCanonical(response.Header(), headerContentType, connectUnaryContentTypeJSON)
+ return w.writeConnectUnary(response, err)
+ }
+}
+
+func (w *ErrorWriter) writeConnectUnary(response http.ResponseWriter, err error) error {
+ if connectErr, ok := asError(err); ok && !connectErr.wireErr {
+ mergeMetadataHeaders(response.Header(), connectErr.meta)
+ }
+ response.WriteHeader(connectCodeToHTTP(CodeOf(err)))
+ data, marshalErr := json.Marshal(newConnectWireError(err))
+ if marshalErr != nil {
+ return fmt.Errorf("marshal error: %w", marshalErr)
+ }
+ _, writeErr := response.Write(data)
+ return writeErr
+}
+
+func (w *ErrorWriter) writeConnectStreaming(response http.ResponseWriter, err error) error {
+ response.WriteHeader(http.StatusOK)
+ marshaler := &connectStreamingMarshaler{
+ envelopeWriter: envelopeWriter{
+ sender: writeSender{writer: response},
+ bufferPool: w.bufferPool,
+ },
+ }
+ // MarshalEndStream returns *Error: check return value to avoid typed nils.
+ if marshalErr := marshaler.MarshalEndStream(err, make(http.Header)); marshalErr != nil {
+ return marshalErr
+ }
+ return nil
+}
+
+func (w *ErrorWriter) writeGRPC(response http.ResponseWriter, err error) error {
+ trailers := make(http.Header, 2) // need space for at least code & message
+ grpcErrorToTrailer(trailers, w.protobuf, err)
+ // To make net/http reliably send trailers without a body, we must set the
+ // Trailers header rather than using http.TrailerPrefix. See
+ // https://github.com/golang/go/issues/54723.
+ keys := make([]string, 0, len(trailers))
+ for k := range trailers {
+ keys = append(keys, k)
+ }
+ setHeaderCanonical(response.Header(), headerTrailer, strings.Join(keys, ","))
+ response.WriteHeader(http.StatusOK)
+ mergeHeaders(response.Header(), trailers)
+ return nil
+}
+
+func (w *ErrorWriter) writeGRPCWeb(response http.ResponseWriter, err error) error {
+ // This is a trailers-only response. To match the behavior of Envoy and
+ // protocol_grpc.go, put the trailers in the HTTP headers.
+ grpcErrorToTrailer(response.Header(), w.protobuf, err)
+ response.WriteHeader(http.StatusOK)
+ return nil
+}
diff --git a/vendor/connectrpc.com/connect/handler.go b/vendor/connectrpc.com/connect/handler.go
new file mode 100644
index 0000000..1d57329
--- /dev/null
+++ b/vendor/connectrpc.com/connect/handler.go
@@ -0,0 +1,328 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+)
+
+// A Handler is the server-side implementation of a single RPC defined by a
+// service schema.
+//
+// By default, Handlers support the Connect, gRPC, and gRPC-Web protocols with
+// the binary Protobuf and JSON codecs. They support gzip compression using the
+// standard library's [compress/gzip].
+type Handler struct {
+ spec Spec
+ implementation StreamingHandlerFunc
+ protocolHandlers map[string][]protocolHandler // Method to protocol handlers
+ allowMethod string // Allow header
+ acceptPost string // Accept-Post header
+}
+
+// NewUnaryHandler constructs a [Handler] for a request-response procedure.
+func NewUnaryHandler[Req, Res any](
+ procedure string,
+ unary func(context.Context, *Request[Req]) (*Response[Res], error),
+ options ...HandlerOption,
+) *Handler {
+ // Wrap the strongly-typed implementation so we can apply interceptors.
+ untyped := UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) {
+ if err := ctx.Err(); err != nil {
+ return nil, err
+ }
+ typed, ok := request.(*Request[Req])
+ if !ok {
+ return nil, errorf(CodeInternal, "unexpected handler request type %T", request)
+ }
+ res, err := unary(ctx, typed)
+ if res == nil && err == nil {
+ // This is going to panic during serialization. Debugging is much easier
+ // if we panic here instead, so we can include the procedure name.
+ panic(fmt.Sprintf("%s returned nil *connect.Response and nil error", procedure)) //nolint: forbidigo
+ }
+ return res, err
+ })
+ config := newHandlerConfig(procedure, StreamTypeUnary, options)
+ if interceptor := config.Interceptor; interceptor != nil {
+ untyped = interceptor.WrapUnary(untyped)
+ }
+ // Given a stream, how should we call the unary function?
+ implementation := func(ctx context.Context, conn StreamingHandlerConn) error {
+ request, err := receiveUnaryRequest[Req](conn, config.Initializer)
+ if err != nil {
+ return err
+ }
+ response, err := untyped(ctx, request)
+ if err != nil {
+ return err
+ }
+ mergeHeaders(conn.ResponseHeader(), response.Header())
+ mergeHeaders(conn.ResponseTrailer(), response.Trailer())
+ return conn.Send(response.Any())
+ }
+
+ protocolHandlers := config.newProtocolHandlers()
+ return &Handler{
+ spec: config.newSpec(),
+ implementation: implementation,
+ protocolHandlers: mappedMethodHandlers(protocolHandlers),
+ allowMethod: sortedAllowMethodValue(protocolHandlers),
+ acceptPost: sortedAcceptPostValue(protocolHandlers),
+ }
+}
+
+// NewClientStreamHandler constructs a [Handler] for a client streaming procedure.
+func NewClientStreamHandler[Req, Res any](
+ procedure string,
+ implementation func(context.Context, *ClientStream[Req]) (*Response[Res], error),
+ options ...HandlerOption,
+) *Handler {
+ config := newHandlerConfig(procedure, StreamTypeClient, options)
+ return newStreamHandler(
+ config,
+ func(ctx context.Context, conn StreamingHandlerConn) error {
+ stream := &ClientStream[Req]{
+ conn: conn,
+ initializer: config.Initializer,
+ }
+ res, err := implementation(ctx, stream)
+ if err != nil {
+ return err
+ }
+ if res == nil {
+ // This is going to panic during serialization. Debugging is much easier
+ // if we panic here instead, so we can include the procedure name.
+ panic(fmt.Sprintf("%s returned nil *connect.Response and nil error", procedure)) //nolint: forbidigo
+ }
+ mergeHeaders(conn.ResponseHeader(), res.header)
+ mergeHeaders(conn.ResponseTrailer(), res.trailer)
+ return conn.Send(res.Msg)
+ },
+ )
+}
+
+// NewServerStreamHandler constructs a [Handler] for a server streaming procedure.
+func NewServerStreamHandler[Req, Res any](
+ procedure string,
+ implementation func(context.Context, *Request[Req], *ServerStream[Res]) error,
+ options ...HandlerOption,
+) *Handler {
+ config := newHandlerConfig(procedure, StreamTypeServer, options)
+ return newStreamHandler(
+ config,
+ func(ctx context.Context, conn StreamingHandlerConn) error {
+ req, err := receiveUnaryRequest[Req](conn, config.Initializer)
+ if err != nil {
+ return err
+ }
+ return implementation(ctx, req, &ServerStream[Res]{conn: conn})
+ },
+ )
+}
+
+// NewBidiStreamHandler constructs a [Handler] for a bidirectional streaming procedure.
+func NewBidiStreamHandler[Req, Res any](
+ procedure string,
+ implementation func(context.Context, *BidiStream[Req, Res]) error,
+ options ...HandlerOption,
+) *Handler {
+ config := newHandlerConfig(procedure, StreamTypeBidi, options)
+ return newStreamHandler(
+ config,
+ func(ctx context.Context, conn StreamingHandlerConn) error {
+ return implementation(
+ ctx,
+ &BidiStream[Req, Res]{
+ conn: conn,
+ initializer: config.Initializer,
+ },
+ )
+ },
+ )
+}
+
+// ServeHTTP implements [http.Handler].
+func (h *Handler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
+ // We don't need to defer functions to close the request body or read to
+ // EOF: the stream we construct later on already does that, and we only
+ // return early when dealing with misbehaving clients. In those cases, it's
+ // okay if we can't re-use the connection.
+ isBidi := (h.spec.StreamType & StreamTypeBidi) == StreamTypeBidi
+ if isBidi && request.ProtoMajor < 2 {
+ // Clients coded to expect full-duplex connections may hang if they've
+ // mistakenly negotiated HTTP/1.1. To unblock them, we must close the
+ // underlying TCP connection.
+ responseWriter.Header().Set("Connection", "close")
+ responseWriter.WriteHeader(http.StatusHTTPVersionNotSupported)
+ return
+ }
+
+ protocolHandlers := h.protocolHandlers[request.Method]
+ if len(protocolHandlers) == 0 {
+ responseWriter.Header().Set("Allow", h.allowMethod)
+ responseWriter.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+
+ contentType := canonicalizeContentType(getHeaderCanonical(request.Header, headerContentType))
+
+ // Find our implementation of the RPC protocol in use.
+ var protocolHandler protocolHandler
+ for _, handler := range protocolHandlers {
+ if handler.CanHandlePayload(request, contentType) {
+ protocolHandler = handler
+ break
+ }
+ }
+ if protocolHandler == nil {
+ responseWriter.Header().Set("Accept-Post", h.acceptPost)
+ responseWriter.WriteHeader(http.StatusUnsupportedMediaType)
+ return
+ }
+
+ if request.Method == http.MethodGet {
+ // A body must not be present.
+ hasBody := request.ContentLength > 0
+ if request.ContentLength < 0 {
+ // No content-length header.
+ // Test if body is empty by trying to read a single byte.
+ var b [1]byte
+ n, _ := request.Body.Read(b[:])
+ hasBody = n > 0
+ }
+ if hasBody {
+ responseWriter.WriteHeader(http.StatusUnsupportedMediaType)
+ return
+ }
+ _ = request.Body.Close()
+ }
+
+ // Establish a stream and serve the RPC.
+ setHeaderCanonical(request.Header, headerContentType, contentType)
+ setHeaderCanonical(request.Header, headerHost, request.Host)
+ ctx, cancel, timeoutErr := protocolHandler.SetTimeout(request) //nolint: contextcheck
+ if timeoutErr != nil {
+ ctx = request.Context()
+ }
+ if cancel != nil {
+ defer cancel()
+ }
+ connCloser, ok := protocolHandler.NewConn(
+ responseWriter,
+ request.WithContext(ctx),
+ )
+ if !ok {
+ // Failed to create stream, usually because client used an unknown
+ // compression algorithm. Nothing further to do.
+ return
+ }
+ if timeoutErr != nil {
+ _ = connCloser.Close(timeoutErr)
+ return
+ }
+ _ = connCloser.Close(h.implementation(ctx, connCloser))
+}
+
+type handlerConfig struct {
+ CompressionPools map[string]*compressionPool
+ CompressionNames []string
+ Codecs map[string]Codec
+ CompressMinBytes int
+ Interceptor Interceptor
+ Procedure string
+ Schema any
+ Initializer maybeInitializer
+ RequireConnectProtocolHeader bool
+ IdempotencyLevel IdempotencyLevel
+ BufferPool *bufferPool
+ ReadMaxBytes int
+ SendMaxBytes int
+ StreamType StreamType
+}
+
+func newHandlerConfig(procedure string, streamType StreamType, options []HandlerOption) *handlerConfig {
+ protoPath := extractProtoPath(procedure)
+ config := handlerConfig{
+ Procedure: protoPath,
+ CompressionPools: make(map[string]*compressionPool),
+ Codecs: make(map[string]Codec),
+ BufferPool: newBufferPool(),
+ StreamType: streamType,
+ }
+ withProtoBinaryCodec().applyToHandler(&config)
+ withProtoJSONCodecs().applyToHandler(&config)
+ withGzip().applyToHandler(&config)
+ for _, opt := range options {
+ opt.applyToHandler(&config)
+ }
+ return &config
+}
+
+func (c *handlerConfig) newSpec() Spec {
+ return Spec{
+ Procedure: c.Procedure,
+ Schema: c.Schema,
+ StreamType: c.StreamType,
+ IdempotencyLevel: c.IdempotencyLevel,
+ }
+}
+
+func (c *handlerConfig) newProtocolHandlers() []protocolHandler {
+ protocols := []protocol{
+ &protocolConnect{},
+ &protocolGRPC{web: false},
+ &protocolGRPC{web: true},
+ }
+ handlers := make([]protocolHandler, 0, len(protocols))
+ codecs := newReadOnlyCodecs(c.Codecs)
+ compressors := newReadOnlyCompressionPools(
+ c.CompressionPools,
+ c.CompressionNames,
+ )
+ for _, protocol := range protocols {
+ handlers = append(handlers, protocol.NewHandler(&protocolHandlerParams{
+ Spec: c.newSpec(),
+ Codecs: codecs,
+ CompressionPools: compressors,
+ CompressMinBytes: c.CompressMinBytes,
+ BufferPool: c.BufferPool,
+ ReadMaxBytes: c.ReadMaxBytes,
+ SendMaxBytes: c.SendMaxBytes,
+ RequireConnectProtocolHeader: c.RequireConnectProtocolHeader,
+ IdempotencyLevel: c.IdempotencyLevel,
+ }))
+ }
+ return handlers
+}
+
+func newStreamHandler(
+ config *handlerConfig,
+ implementation StreamingHandlerFunc,
+) *Handler {
+ if ic := config.Interceptor; ic != nil {
+ implementation = ic.WrapStreamingHandler(implementation)
+ }
+ protocolHandlers := config.newProtocolHandlers()
+ return &Handler{
+ spec: config.newSpec(),
+ implementation: implementation,
+ protocolHandlers: mappedMethodHandlers(protocolHandlers),
+ allowMethod: sortedAllowMethodValue(protocolHandlers),
+ acceptPost: sortedAcceptPostValue(protocolHandlers),
+ }
+}
diff --git a/vendor/connectrpc.com/connect/handler_stream.go b/vendor/connectrpc.com/connect/handler_stream.go
new file mode 100644
index 0000000..e946163
--- /dev/null
+++ b/vendor/connectrpc.com/connect/handler_stream.go
@@ -0,0 +1,198 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "errors"
+ "io"
+ "net/http"
+)
+
+// ClientStream is the handler's view of a client streaming RPC.
+//
+// It's constructed as part of [Handler] invocation, but doesn't currently have
+// an exported constructor.
+type ClientStream[Req any] struct {
+ conn StreamingHandlerConn
+ initializer maybeInitializer
+ msg *Req
+ err error
+}
+
+// Spec returns the specification for the RPC.
+func (c *ClientStream[_]) Spec() Spec {
+ return c.conn.Spec()
+}
+
+// Peer describes the client for this RPC.
+func (c *ClientStream[_]) Peer() Peer {
+ return c.conn.Peer()
+}
+
+// RequestHeader returns the headers received from the client.
+func (c *ClientStream[Req]) RequestHeader() http.Header {
+ return c.conn.RequestHeader()
+}
+
+// Receive advances the stream to the next message, which will then be
+// available through the Msg method. It returns false when the stream stops,
+// either by reaching the end or by encountering an unexpected error. After
+// Receive returns false, the Err method will return any unexpected error
+// encountered.
+func (c *ClientStream[Req]) Receive() bool {
+ if c.err != nil {
+ return false
+ }
+ c.msg = new(Req)
+ if err := c.initializer.maybe(c.Spec(), c.msg); err != nil {
+ c.err = err
+ return false
+ }
+ c.err = c.conn.Receive(c.msg)
+ return c.err == nil
+}
+
+// Msg returns the most recent message unmarshaled by a call to Receive.
+func (c *ClientStream[Req]) Msg() *Req {
+ if c.msg == nil {
+ c.msg = new(Req)
+ }
+ return c.msg
+}
+
+// Err returns the first non-EOF error that was encountered by Receive.
+func (c *ClientStream[Req]) Err() error {
+ if c.err == nil || errors.Is(c.err, io.EOF) {
+ return nil
+ }
+ return c.err
+}
+
+// Conn exposes the underlying StreamingHandlerConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (c *ClientStream[Req]) Conn() StreamingHandlerConn {
+ return c.conn
+}
+
+// ServerStream is the handler's view of a server streaming RPC.
+//
+// It's constructed as part of [Handler] invocation, but doesn't currently have
+// an exported constructor.
+type ServerStream[Res any] struct {
+ conn StreamingHandlerConn
+}
+
+// ResponseHeader returns the response headers. Headers are sent with the first
+// call to Send.
+//
+// Headers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (s *ServerStream[Res]) ResponseHeader() http.Header {
+ return s.conn.ResponseHeader()
+}
+
+// ResponseTrailer returns the response trailers. Handlers may write to the
+// response trailers at any time before returning.
+//
+// Trailers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (s *ServerStream[Res]) ResponseTrailer() http.Header {
+ return s.conn.ResponseTrailer()
+}
+
+// Send a message to the client. The first call to Send also sends the response
+// headers.
+func (s *ServerStream[Res]) Send(msg *Res) error {
+ if msg == nil {
+ return s.conn.Send(nil)
+ }
+ return s.conn.Send(msg)
+}
+
+// Conn exposes the underlying StreamingHandlerConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (s *ServerStream[Res]) Conn() StreamingHandlerConn {
+ return s.conn
+}
+
+// BidiStream is the handler's view of a bidirectional streaming RPC.
+//
+// It's constructed as part of [Handler] invocation, but doesn't currently have
+// an exported constructor.
+type BidiStream[Req, Res any] struct {
+ conn StreamingHandlerConn
+ initializer maybeInitializer
+}
+
+// Spec returns the specification for the RPC.
+func (b *BidiStream[_, _]) Spec() Spec {
+ return b.conn.Spec()
+}
+
+// Peer describes the client for this RPC.
+func (b *BidiStream[_, _]) Peer() Peer {
+ return b.conn.Peer()
+}
+
+// RequestHeader returns the headers received from the client.
+func (b *BidiStream[Req, Res]) RequestHeader() http.Header {
+ return b.conn.RequestHeader()
+}
+
+// Receive a message. When the client is done sending messages, Receive will
+// return an error that wraps [io.EOF].
+func (b *BidiStream[Req, Res]) Receive() (*Req, error) {
+ var req Req
+ if err := b.initializer.maybe(b.Spec(), &req); err != nil {
+ return nil, err
+ }
+ if err := b.conn.Receive(&req); err != nil {
+ return nil, err
+ }
+ return &req, nil
+}
+
+// ResponseHeader returns the response headers. Headers are sent with the first
+// call to Send.
+//
+// Headers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (b *BidiStream[Req, Res]) ResponseHeader() http.Header {
+ return b.conn.ResponseHeader()
+}
+
+// ResponseTrailer returns the response trailers. Handlers may write to the
+// response trailers at any time before returning.
+//
+// Trailers beginning with "Connect-" and "Grpc-" are reserved for use by the
+// Connect and gRPC protocols. Applications shouldn't write them.
+func (b *BidiStream[Req, Res]) ResponseTrailer() http.Header {
+ return b.conn.ResponseTrailer()
+}
+
+// Send a message to the client. The first call to Send also sends the response
+// headers.
+func (b *BidiStream[Req, Res]) Send(msg *Res) error {
+ if msg == nil {
+ return b.conn.Send(nil)
+ }
+ return b.conn.Send(msg)
+}
+
+// Conn exposes the underlying StreamingHandlerConn. This may be useful if
+// you'd prefer to wrap the connection in a different high-level API.
+func (b *BidiStream[Req, Res]) Conn() StreamingHandlerConn {
+ return b.conn
+}
diff --git a/vendor/connectrpc.com/connect/header.go b/vendor/connectrpc.com/connect/header.go
new file mode 100644
index 0000000..f3c7cac
--- /dev/null
+++ b/vendor/connectrpc.com/connect/header.go
@@ -0,0 +1,126 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "encoding/base64"
+ "net/http"
+)
+
+// EncodeBinaryHeader base64-encodes the data. It always emits unpadded values.
+//
+// In the Connect, gRPC, and gRPC-Web protocols, binary headers must have keys
+// ending in "-Bin".
+func EncodeBinaryHeader(data []byte) string {
+ // gRPC specification says that implementations should emit unpadded values.
+ return base64.RawStdEncoding.EncodeToString(data)
+}
+
+// DecodeBinaryHeader base64-decodes the data. It can decode padded or unpadded
+// values. Following usual HTTP semantics, multiple base64-encoded values may
+// be joined with a comma. When receiving such comma-separated values, split
+// them with [strings.Split] before calling DecodeBinaryHeader.
+//
+// Binary headers sent using the Connect, gRPC, and gRPC-Web protocols have
+// keys ending in "-Bin".
+func DecodeBinaryHeader(data string) ([]byte, error) {
+ if len(data)%4 != 0 {
+ // Data definitely isn't padded.
+ return base64.RawStdEncoding.DecodeString(data)
+ }
+ // Either the data was padded, or padding wasn't necessary. In both cases,
+ // the padding-aware decoder works.
+ return base64.StdEncoding.DecodeString(data)
+}
+
+func mergeHeaders(into, from http.Header) {
+ for key, vals := range from {
+ if len(vals) == 0 {
+ // For response trailers, net/http will pre-populate entries
+ // with nil values based on the "Trailer" header. But if there
+ // are no actual values for those keys, we skip them.
+ continue
+ }
+ into[key] = append(into[key], vals...)
+ }
+}
+
+// mergeMetdataHeaders merges the metadata headers from the "from" header into
+// the "into" header. It skips over non metadata headers that should not be
+// propagated from the server to the client.
+func mergeMetadataHeaders(into, from http.Header) {
+ for key, vals := range from {
+ if len(vals) == 0 {
+ // For response trailers, net/http will pre-populate entries
+ // with nil values based on the "Trailer" header. But if there
+ // are no actual values for those keys, we skip them.
+ continue
+ }
+ switch http.CanonicalHeaderKey(key) {
+ case headerContentType,
+ headerContentLength,
+ headerContentEncoding,
+ headerHost,
+ headerUserAgent,
+ headerTrailer,
+ headerDate:
+ // HTTP headers.
+ case connectUnaryHeaderAcceptCompression,
+ connectUnaryTrailerPrefix,
+ connectStreamingHeaderCompression,
+ connectStreamingHeaderAcceptCompression,
+ connectHeaderTimeout,
+ connectHeaderProtocolVersion:
+ // Connect headers.
+ case grpcHeaderCompression,
+ grpcHeaderAcceptCompression,
+ grpcHeaderTimeout,
+ grpcHeaderStatus,
+ grpcHeaderMessage,
+ grpcHeaderDetails:
+ // gRPC headers.
+ default:
+ into[key] = append(into[key], vals...)
+ }
+ }
+}
+
+// getHeaderCanonical is a shortcut for Header.Get() which
+// bypasses the CanonicalMIMEHeaderKey operation when we
+// know the key is already in canonical form.
+func getHeaderCanonical(h http.Header, key string) string {
+ if h == nil {
+ return ""
+ }
+ v := h[key]
+ if len(v) == 0 {
+ return ""
+ }
+ return v[0]
+}
+
+// setHeaderCanonical is a shortcut for Header.Set() which
+// bypasses the CanonicalMIMEHeaderKey operation when we
+// know the key is already in canonical form.
+func setHeaderCanonical(h http.Header, key, value string) {
+ h[key] = []string{value}
+}
+
+// delHeaderCanonical is a shortcut for Header.Del() which
+// bypasses the CanonicalMIMEHeaderKey operation when we
+// know the key is already in canonical form.
+func delHeaderCanonical(h http.Header, key string) {
+ delete(h, key)
+}
diff --git a/vendor/connectrpc.com/connect/idempotency_level.go b/vendor/connectrpc.com/connect/idempotency_level.go
new file mode 100644
index 0000000..46ad746
--- /dev/null
+++ b/vendor/connectrpc.com/connect/idempotency_level.go
@@ -0,0 +1,68 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import "fmt"
+
+// An IdempotencyLevel is a value that declares how "idempotent" an RPC is. This
+// value can affect RPC behaviors, such as determining whether it is safe to
+// retry a request, or what kinds of request modalities are allowed for a given
+// procedure.
+type IdempotencyLevel int
+
+// NOTE: For simplicity, these should be kept in sync with the values of the
+// google.protobuf.MethodOptions.IdempotencyLevel enumeration.
+
+const (
+ // IdempotencyUnknown is the default idempotency level. A procedure with
+ // this idempotency level may not be idempotent. This is appropriate for
+ // any kind of procedure.
+ IdempotencyUnknown IdempotencyLevel = 0
+
+ // IdempotencyNoSideEffects is the idempotency level that specifies that a
+ // given call has no side-effects. This is equivalent to [RFC 9110 § 9.2.1]
+ // "safe" methods in terms of semantics. This procedure should not mutate
+ // any state. This idempotency level is appropriate for queries, or anything
+ // that would be suitable for an HTTP GET request. In addition, due to the
+ // lack of side-effects, such a procedure would be suitable to retry and
+ // expect that the results will not be altered by preceding attempts.
+ //
+ // [RFC 9110 § 9.2.1]: https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.1
+ IdempotencyNoSideEffects IdempotencyLevel = 1
+
+ // IdempotencyIdempotent is the idempotency level that specifies that a
+ // given call is "idempotent", such that multiple instances of the same
+ // request to this procedure would have the same side-effects as a single
+ // request. This is equivalent to [RFC 9110 § 9.2.2] "idempotent" methods.
+ // This level is a subset of the previous level. This idempotency level is
+ // appropriate for any procedure that is safe to retry multiple times
+ // and be guaranteed that the response and side-effects will not be altered
+ // as a result of multiple attempts, for example, entity deletion requests.
+ //
+ // [RFC 9110 § 9.2.2]: https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2
+ IdempotencyIdempotent IdempotencyLevel = 2
+)
+
+func (i IdempotencyLevel) String() string {
+ switch i {
+ case IdempotencyUnknown:
+ return "idempotency_unknown"
+ case IdempotencyNoSideEffects:
+ return "no_side_effects"
+ case IdempotencyIdempotent:
+ return "idempotent"
+ }
+ return fmt.Sprintf("idempotency_%d", i)
+}
diff --git a/vendor/connectrpc.com/connect/interceptor.go b/vendor/connectrpc.com/connect/interceptor.go
new file mode 100644
index 0000000..8d0beac
--- /dev/null
+++ b/vendor/connectrpc.com/connect/interceptor.go
@@ -0,0 +1,105 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+)
+
+// UnaryFunc is the generic signature of a unary RPC. Interceptors may wrap
+// Funcs.
+//
+// The type of the request and response structs depend on the codec being used.
+// When using Protobuf, request.Any() and response.Any() will always be
+// [proto.Message] implementations.
+type UnaryFunc func(context.Context, AnyRequest) (AnyResponse, error)
+
+// StreamingClientFunc is the generic signature of a streaming RPC from the client's
+// perspective. Interceptors may wrap StreamingClientFuncs.
+type StreamingClientFunc func(context.Context, Spec) StreamingClientConn
+
+// StreamingHandlerFunc is the generic signature of a streaming RPC from the
+// handler's perspective. Interceptors may wrap StreamingHandlerFuncs.
+type StreamingHandlerFunc func(context.Context, StreamingHandlerConn) error
+
+// An Interceptor adds logic to a generated handler or client, like the
+// decorators or middleware you may have seen in other libraries. Interceptors
+// may replace the context, mutate requests and responses, handle errors,
+// retry, recover from panics, emit logs and metrics, or do nearly anything
+// else.
+//
+// The returned functions must be safe to call concurrently.
+type Interceptor interface {
+ WrapUnary(UnaryFunc) UnaryFunc
+ WrapStreamingClient(StreamingClientFunc) StreamingClientFunc
+ WrapStreamingHandler(StreamingHandlerFunc) StreamingHandlerFunc
+}
+
+// UnaryInterceptorFunc is a simple Interceptor implementation that only
+// wraps unary RPCs. It has no effect on streaming RPCs.
+type UnaryInterceptorFunc func(UnaryFunc) UnaryFunc
+
+// WrapUnary implements [Interceptor] by applying the interceptor function.
+func (f UnaryInterceptorFunc) WrapUnary(next UnaryFunc) UnaryFunc { return f(next) }
+
+// WrapStreamingClient implements [Interceptor] with a no-op.
+func (f UnaryInterceptorFunc) WrapStreamingClient(next StreamingClientFunc) StreamingClientFunc {
+ return next
+}
+
+// WrapStreamingHandler implements [Interceptor] with a no-op.
+func (f UnaryInterceptorFunc) WrapStreamingHandler(next StreamingHandlerFunc) StreamingHandlerFunc {
+ return next
+}
+
+// A chain composes multiple interceptors into one.
+type chain struct {
+ interceptors []Interceptor
+}
+
+// newChain composes multiple interceptors into one.
+func newChain(interceptors []Interceptor) *chain {
+ // We usually wrap in reverse order to have the first interceptor from
+ // the slice act first. Rather than doing this dance repeatedly, reverse the
+ // interceptor order now.
+ var chain chain
+ for i := len(interceptors) - 1; i >= 0; i-- {
+ if interceptor := interceptors[i]; interceptor != nil {
+ chain.interceptors = append(chain.interceptors, interceptor)
+ }
+ }
+ return &chain
+}
+
+func (c *chain) WrapUnary(next UnaryFunc) UnaryFunc {
+ for _, interceptor := range c.interceptors {
+ next = interceptor.WrapUnary(next)
+ }
+ return next
+}
+
+func (c *chain) WrapStreamingClient(next StreamingClientFunc) StreamingClientFunc {
+ for _, interceptor := range c.interceptors {
+ next = interceptor.WrapStreamingClient(next)
+ }
+ return next
+}
+
+func (c *chain) WrapStreamingHandler(next StreamingHandlerFunc) StreamingHandlerFunc {
+ for _, interceptor := range c.interceptors {
+ next = interceptor.WrapStreamingHandler(next)
+ }
+ return next
+}
diff --git a/vendor/connectrpc.com/connect/internal/gen/connectext/grpc/status/v1/status.pb.go b/vendor/connectrpc.com/connect/internal/gen/connectext/grpc/status/v1/status.pb.go
new file mode 100644
index 0000000..d43c9bd
--- /dev/null
+++ b/vendor/connectrpc.com/connect/internal/gen/connectext/grpc/status/v1/status.pb.go
@@ -0,0 +1,201 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.33.0
+// protoc (unknown)
+// source: connectext/grpc/status/v1/status.proto
+
+// This package is for internal use by Connect, and provides no backward
+// compatibility guarantees whatsoever.
+
+package statusv1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ anypb "google.golang.org/protobuf/types/known/anypb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// See https://cloud.google.com/apis/design/errors.
+//
+// This struct must remain binary-compatible with
+// https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto.
+type Status struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // a google.rpc.Code
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // developer-facing, English (localize in details or client-side)
+ Details []*anypb.Any `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"`
+}
+
+func (x *Status) Reset() {
+ *x = Status{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_connectext_grpc_status_v1_status_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status) ProtoMessage() {}
+
+func (x *Status) ProtoReflect() protoreflect.Message {
+ mi := &file_connectext_grpc_status_v1_status_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status.ProtoReflect.Descriptor instead.
+func (*Status) Descriptor() ([]byte, []int) {
+ return file_connectext_grpc_status_v1_status_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Status) GetCode() int32 {
+ if x != nil {
+ return x.Code
+ }
+ return 0
+}
+
+func (x *Status) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+func (x *Status) GetDetails() []*anypb.Any {
+ if x != nil {
+ return x.Details
+ }
+ return nil
+}
+
+var File_connectext_grpc_status_v1_status_proto protoreflect.FileDescriptor
+
+var file_connectext_grpc_status_v1_status_proto_rawDesc = []byte{
+ 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x67, 0x72, 0x70,
+ 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x22, 0x66, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a,
+ 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64,
+ 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x64,
+ 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41,
+ 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0xc3, 0x01, 0x0a, 0x12,
+ 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e,
+ 0x76, 0x31, 0x42, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
+ 0x01, 0x5a, 0x46, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+ 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x78,
+ 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x76, 0x31,
+ 0x3b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x47, 0x53, 0x58, 0xaa,
+ 0x02, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x56, 0x31,
+ 0xca, 0x02, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x5c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5c, 0x56,
+ 0x31, 0xe2, 0x02, 0x1a, 0x47, 0x72, 0x70, 0x63, 0x5c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5c,
+ 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
+ 0x10, 0x47, 0x72, 0x70, 0x63, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x3a, 0x56,
+ 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_connectext_grpc_status_v1_status_proto_rawDescOnce sync.Once
+ file_connectext_grpc_status_v1_status_proto_rawDescData = file_connectext_grpc_status_v1_status_proto_rawDesc
+)
+
+func file_connectext_grpc_status_v1_status_proto_rawDescGZIP() []byte {
+ file_connectext_grpc_status_v1_status_proto_rawDescOnce.Do(func() {
+ file_connectext_grpc_status_v1_status_proto_rawDescData = protoimpl.X.CompressGZIP(file_connectext_grpc_status_v1_status_proto_rawDescData)
+ })
+ return file_connectext_grpc_status_v1_status_proto_rawDescData
+}
+
+var file_connectext_grpc_status_v1_status_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_connectext_grpc_status_v1_status_proto_goTypes = []interface{}{
+ (*Status)(nil), // 0: grpc.status.v1.Status
+ (*anypb.Any)(nil), // 1: google.protobuf.Any
+}
+var file_connectext_grpc_status_v1_status_proto_depIdxs = []int32{
+ 1, // 0: grpc.status.v1.Status.details:type_name -> google.protobuf.Any
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_connectext_grpc_status_v1_status_proto_init() }
+func file_connectext_grpc_status_v1_status_proto_init() {
+ if File_connectext_grpc_status_v1_status_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_connectext_grpc_status_v1_status_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_connectext_grpc_status_v1_status_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_connectext_grpc_status_v1_status_proto_goTypes,
+ DependencyIndexes: file_connectext_grpc_status_v1_status_proto_depIdxs,
+ MessageInfos: file_connectext_grpc_status_v1_status_proto_msgTypes,
+ }.Build()
+ File_connectext_grpc_status_v1_status_proto = out.File
+ file_connectext_grpc_status_v1_status_proto_rawDesc = nil
+ file_connectext_grpc_status_v1_status_proto_goTypes = nil
+ file_connectext_grpc_status_v1_status_proto_depIdxs = nil
+}
diff --git a/vendor/connectrpc.com/connect/option.go b/vendor/connectrpc.com/connect/option.go
new file mode 100644
index 0000000..9cc0c2e
--- /dev/null
+++ b/vendor/connectrpc.com/connect/option.go
@@ -0,0 +1,647 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "compress/gzip"
+ "context"
+ "io"
+ "net/http"
+)
+
+// A ClientOption configures a [Client].
+//
+// In addition to any options grouped in the documentation below, remember that
+// any [Option] is also a valid ClientOption.
+type ClientOption interface {
+ applyToClient(*clientConfig)
+}
+
+// WithAcceptCompression makes a compression algorithm available to a client.
+// Clients ask servers to compress responses using any of the registered
+// algorithms. The first registered algorithm is treated as the least
+// preferred, and the last registered algorithm is the most preferred.
+//
+// It's safe to use this option liberally: servers will ignore any
+// compression algorithms they don't support. To compress requests, pair this
+// option with [WithSendCompression]. To remove support for a
+// previously-registered compression algorithm, use WithAcceptCompression with
+// nil decompressor and compressor constructors.
+//
+// Clients accept gzipped responses by default, using a compressor backed by the
+// standard library's [gzip] package with the default compression level. Use
+// [WithSendGzip] to compress requests with gzip.
+//
+// Calling WithAcceptCompression with an empty name is a no-op.
+func WithAcceptCompression(
+ name string,
+ newDecompressor func() Decompressor,
+ newCompressor func() Compressor,
+) ClientOption {
+ return &compressionOption{
+ Name: name,
+ CompressionPool: newCompressionPool(newDecompressor, newCompressor),
+ }
+}
+
+// WithClientOptions composes multiple ClientOptions into one.
+func WithClientOptions(options ...ClientOption) ClientOption {
+ return &clientOptionsOption{options}
+}
+
+// WithGRPC configures clients to use the HTTP/2 gRPC protocol.
+func WithGRPC() ClientOption {
+ return &grpcOption{web: false}
+}
+
+// WithGRPCWeb configures clients to use the gRPC-Web protocol.
+func WithGRPCWeb() ClientOption {
+ return &grpcOption{web: true}
+}
+
+// WithProtoJSON configures a client to send JSON-encoded data instead of
+// binary Protobuf. It uses the standard Protobuf JSON mapping as implemented
+// by [google.golang.org/protobuf/encoding/protojson]: fields are named using
+// lowerCamelCase, zero values are omitted, missing required fields are errors,
+// enums are emitted as strings, etc.
+func WithProtoJSON() ClientOption {
+ return WithCodec(&protoJSONCodec{codecNameJSON})
+}
+
+// WithSendCompression configures the client to use the specified algorithm to
+// compress request messages. If the algorithm has not been registered using
+// [WithAcceptCompression], the client will return errors at runtime.
+//
+// Because some servers don't support compression, clients default to sending
+// uncompressed requests.
+func WithSendCompression(name string) ClientOption {
+ return &sendCompressionOption{Name: name}
+}
+
+// WithSendGzip configures the client to gzip requests. Since clients have
+// access to a gzip compressor by default, WithSendGzip doesn't require
+// [WithSendCompression].
+//
+// Some servers don't support gzip, so clients default to sending uncompressed
+// requests.
+func WithSendGzip() ClientOption {
+ return WithSendCompression(compressionGzip)
+}
+
+// A HandlerOption configures a [Handler].
+//
+// In addition to any options grouped in the documentation below, remember that
+// any [Option] is also a HandlerOption.
+type HandlerOption interface {
+ applyToHandler(*handlerConfig)
+}
+
+// WithCompression configures handlers to support a compression algorithm.
+// Clients may send messages compressed with that algorithm and/or request
+// compressed responses. The [Compressor] and [Decompressor] produced by the
+// supplied constructors must use the same algorithm. Internally, Connect pools
+// compressors and decompressors.
+//
+// By default, handlers support gzip using the standard library's
+// [compress/gzip] package at the default compression level. To remove support for
+// a previously-registered compression algorithm, use WithCompression with nil
+// decompressor and compressor constructors.
+//
+// Calling WithCompression with an empty name is a no-op.
+func WithCompression(
+ name string,
+ newDecompressor func() Decompressor,
+ newCompressor func() Compressor,
+) HandlerOption {
+ return &compressionOption{
+ Name: name,
+ CompressionPool: newCompressionPool(newDecompressor, newCompressor),
+ }
+}
+
+// WithHandlerOptions composes multiple HandlerOptions into one.
+func WithHandlerOptions(options ...HandlerOption) HandlerOption {
+ return &handlerOptionsOption{options}
+}
+
+// WithRecover adds an interceptor that recovers from panics. The supplied
+// function receives the context, [Spec], request headers, and the recovered
+// value (which may be nil). It must return an error to send back to the
+// client. It may also log the panic, emit metrics, or execute other
+// error-handling logic. Handler functions must be safe to call concurrently.
+//
+// To preserve compatibility with [net/http]'s semantics, this interceptor
+// doesn't handle panics with [http.ErrAbortHandler].
+//
+// By default, handlers don't recover from panics. Because the standard
+// library's [http.Server] recovers from panics by default, this option isn't
+// usually necessary to prevent crashes. Instead, it helps servers collect
+// RPC-specific data during panics and send a more detailed error to
+// clients.
+func WithRecover(handle func(context.Context, Spec, http.Header, any) error) HandlerOption {
+ return WithInterceptors(&recoverHandlerInterceptor{handle: handle})
+}
+
+// WithRequireConnectProtocolHeader configures the Handler to require requests
+// using the Connect RPC protocol to include the Connect-Protocol-Version
+// header. This ensures that HTTP proxies and net/http middleware can easily
+// identify valid Connect requests, even if they use a common Content-Type like
+// application/json. However, it makes ad-hoc requests with tools like cURL
+// more laborious. Streaming requests are not affected by this option.
+//
+// This option has no effect if the client uses the gRPC or gRPC-Web protocols.
+func WithRequireConnectProtocolHeader() HandlerOption {
+ return &requireConnectProtocolHeaderOption{}
+}
+
+// WithConditionalHandlerOptions allows procedures in the same service to have
+// different configurations: for example, one procedure may need a much larger
+// WithReadMaxBytes setting than the others.
+//
+// WithConditionalHandlerOptions takes a function which may inspect each
+// procedure's Spec before deciding which options to apply. Returning a nil
+// slice is safe.
+func WithConditionalHandlerOptions(conditional func(spec Spec) []HandlerOption) HandlerOption {
+ return &conditionalHandlerOptions{conditional: conditional}
+}
+
+// Option implements both [ClientOption] and [HandlerOption], so it can be
+// applied both client-side and server-side.
+type Option interface {
+ ClientOption
+ HandlerOption
+}
+
+// WithSchema provides a parsed representation of the schema for an RPC to a
+// client or handler. The supplied schema is exposed as [Spec.Schema]. This
+// option is typically added by generated code.
+//
+// For services using protobuf schemas, the supplied schema should be a
+// [protoreflect.MethodDescriptor].
+func WithSchema(schema any) Option {
+ return &schemaOption{Schema: schema}
+}
+
+// WithRequestInitializer provides a function that initializes a new message.
+// It may be used to dynamically construct request messages. It is called on
+// server receives to construct the message to be unmarshaled into. The message
+// will be a non nil pointer to the type created by the handler. Use the Schema
+// field of the [Spec] to determine the type of the message.
+func WithRequestInitializer(initializer func(spec Spec, message any) error) HandlerOption {
+ return &initializerOption{Initializer: initializer}
+}
+
+// WithResponseInitializer provides a function that initializes a new message.
+// It may be used to dynamically construct response messages. It is called on
+// client receives to construct the message to be unmarshaled into. The message
+// will be a non nil pointer to the type created by the client. Use the Schema
+// field of the [Spec] to determine the type of the message.
+func WithResponseInitializer(initializer func(spec Spec, message any) error) ClientOption {
+ return &initializerOption{Initializer: initializer}
+}
+
+// WithCodec registers a serialization method with a client or handler.
+// Handlers may have multiple codecs registered, and use whichever the client
+// chooses. Clients may only have a single codec.
+//
+// By default, handlers and clients support binary Protocol Buffer data using
+// [google.golang.org/protobuf/proto]. Handlers also support JSON by default,
+// using the standard Protobuf JSON mapping. Users with more specialized needs
+// may override the default codecs by registering a new codec under the "proto"
+// or "json" names. When supplying a custom "proto" codec, keep in mind that
+// some unexported, protocol-specific messages are serialized using Protobuf -
+// take care to fall back to the standard Protobuf implementation if
+// necessary.
+//
+// Registering a codec with an empty name is a no-op.
+func WithCodec(codec Codec) Option {
+ return &codecOption{Codec: codec}
+}
+
+// WithCompressMinBytes sets a minimum size threshold for compression:
+// regardless of compressor configuration, messages smaller than the configured
+// minimum are sent uncompressed.
+//
+// The default minimum is zero. Setting a minimum compression threshold may
+// improve overall performance, because the CPU cost of compressing very small
+// messages usually isn't worth the small reduction in network I/O.
+func WithCompressMinBytes(min int) Option {
+ return &compressMinBytesOption{Min: min}
+}
+
+// WithReadMaxBytes limits the performance impact of pathologically large
+// messages sent by the other party. For handlers, WithReadMaxBytes limits the size
+// of a message that the client can send. For clients, WithReadMaxBytes limits the
+// size of a message that the server can respond with. Limits apply to each Protobuf
+// message, not to the stream as a whole.
+//
+// Setting WithReadMaxBytes to zero allows any message size. Both clients and
+// handlers default to allowing any request size.
+//
+// Handlers may also use [http.MaxBytesHandler] to limit the total size of the
+// HTTP request stream (rather than the per-message size). Connect handles
+// [http.MaxBytesError] specially, so clients still receive errors with the
+// appropriate error code and informative messages.
+func WithReadMaxBytes(max int) Option {
+ return &readMaxBytesOption{Max: max}
+}
+
+// WithSendMaxBytes prevents sending messages too large for the client/handler
+// to handle without significant performance overhead. For handlers, WithSendMaxBytes
+// limits the size of a message that the handler can respond with. For clients,
+// WithSendMaxBytes limits the size of a message that the client can send. Limits
+// apply to each message, not to the stream as a whole.
+//
+// Setting WithSendMaxBytes to zero allows any message size. Both clients and
+// handlers default to allowing any message size.
+func WithSendMaxBytes(max int) Option {
+ return &sendMaxBytesOption{Max: max}
+}
+
+// WithIdempotency declares the idempotency of the procedure. This can determine
+// whether a procedure call can safely be retried, and may affect which request
+// modalities are allowed for a given procedure call.
+//
+// In most cases, you should not need to manually set this. It is normally set
+// by the code generator for your schema. For protobuf schemas, it can be set like this:
+//
+// rpc Ping(PingRequest) returns (PingResponse) {
+// option idempotency_level = NO_SIDE_EFFECTS;
+// }
+func WithIdempotency(idempotencyLevel IdempotencyLevel) Option {
+ return &idempotencyOption{idempotencyLevel: idempotencyLevel}
+}
+
+// WithHTTPGet allows Connect-protocol clients to use HTTP GET requests for
+// side-effect free unary RPC calls. Typically, the service schema indicates
+// which procedures are idempotent (see [WithIdempotency] for an example
+// protobuf schema). The gRPC and gRPC-Web protocols are POST-only, so this
+// option has no effect when combined with [WithGRPC] or [WithGRPCWeb].
+//
+// Using HTTP GET requests makes it easier to take advantage of CDNs, caching
+// reverse proxies, and browsers' built-in caching. Note, however, that servers
+// don't automatically set any cache headers; you can set cache headers using
+// interceptors or by adding headers in individual procedure implementations.
+//
+// By default, all requests are made as HTTP POSTs.
+func WithHTTPGet() ClientOption {
+ return &enableGet{}
+}
+
+// WithInterceptors configures a client or handler's interceptor stack. Repeated
+// WithInterceptors options are applied in order, so
+//
+// WithInterceptors(A) + WithInterceptors(B, C) == WithInterceptors(A, B, C)
+//
+// Unary interceptors compose like an onion. The first interceptor provided is
+// the outermost layer of the onion: it acts first on the context and request,
+// and last on the response and error.
+//
+// Stream interceptors also behave like an onion: the first interceptor
+// provided is the outermost wrapper for the [StreamingClientConn] or
+// [StreamingHandlerConn]. It's the first to see sent messages and the last to
+// see received messages.
+//
+// Applied to client and handler, WithInterceptors(A, B, ..., Y, Z) produces:
+//
+// client.Send() client.Receive()
+// | ^
+// v |
+// A --- --- A
+// B --- --- B
+// : ... ... :
+// Y --- --- Y
+// Z --- --- Z
+// | ^
+// v |
+// = = = = = = = = = = = = = = = =
+// network
+// = = = = = = = = = = = = = = = =
+// | ^
+// v |
+// A --- --- A
+// B --- --- B
+// : ... ... :
+// Y --- --- Y
+// Z --- --- Z
+// | ^
+// v |
+// handler.Receive() handler.Send()
+// | ^
+// | |
+// '-> handler logic >-'
+//
+// Note that in clients, Send handles the request message(s) and Receive
+// handles the response message(s). For handlers, it's the reverse. Depending
+// on your interceptor's logic, you may need to wrap one method in clients and
+// the other in handlers.
+func WithInterceptors(interceptors ...Interceptor) Option {
+ return &interceptorsOption{interceptors}
+}
+
+// WithOptions composes multiple Options into one.
+func WithOptions(options ...Option) Option {
+ return &optionsOption{options}
+}
+
+type schemaOption struct {
+ Schema any
+}
+
+func (o *schemaOption) applyToClient(config *clientConfig) {
+ config.Schema = o.Schema
+}
+
+func (o *schemaOption) applyToHandler(config *handlerConfig) {
+ config.Schema = o.Schema
+}
+
+type initializerOption struct {
+ Initializer func(spec Spec, message any) error
+}
+
+func (o *initializerOption) applyToHandler(config *handlerConfig) {
+ config.Initializer = maybeInitializer{initializer: o.Initializer}
+}
+
+func (o *initializerOption) applyToClient(config *clientConfig) {
+ config.Initializer = maybeInitializer{initializer: o.Initializer}
+}
+
+type maybeInitializer struct {
+ initializer func(spec Spec, message any) error
+}
+
+func (o maybeInitializer) maybe(spec Spec, message any) error {
+ if o.initializer != nil {
+ return o.initializer(spec, message)
+ }
+ return nil
+}
+
+type clientOptionsOption struct {
+ options []ClientOption
+}
+
+func (o *clientOptionsOption) applyToClient(config *clientConfig) {
+ for _, option := range o.options {
+ option.applyToClient(config)
+ }
+}
+
+type codecOption struct {
+ Codec Codec
+}
+
+func (o *codecOption) applyToClient(config *clientConfig) {
+ if o.Codec == nil || o.Codec.Name() == "" {
+ return
+ }
+ config.Codec = o.Codec
+}
+
+func (o *codecOption) applyToHandler(config *handlerConfig) {
+ if o.Codec == nil || o.Codec.Name() == "" {
+ return
+ }
+ config.Codecs[o.Codec.Name()] = o.Codec
+}
+
+type compressionOption struct {
+ Name string
+ CompressionPool *compressionPool
+}
+
+func (o *compressionOption) applyToClient(config *clientConfig) {
+ o.apply(&config.CompressionNames, config.CompressionPools)
+}
+
+func (o *compressionOption) applyToHandler(config *handlerConfig) {
+ o.apply(&config.CompressionNames, config.CompressionPools)
+}
+
+func (o *compressionOption) apply(configuredNames *[]string, configuredPools map[string]*compressionPool) {
+ if o.Name == "" {
+ return
+ }
+ if o.CompressionPool == nil {
+ delete(configuredPools, o.Name)
+ var names []string
+ for _, name := range *configuredNames {
+ if name == o.Name {
+ continue
+ }
+ names = append(names, name)
+ }
+ *configuredNames = names
+ return
+ }
+ configuredPools[o.Name] = o.CompressionPool
+ *configuredNames = append(*configuredNames, o.Name)
+}
+
+type compressMinBytesOption struct {
+ Min int
+}
+
+func (o *compressMinBytesOption) applyToClient(config *clientConfig) {
+ config.CompressMinBytes = o.Min
+}
+
+func (o *compressMinBytesOption) applyToHandler(config *handlerConfig) {
+ config.CompressMinBytes = o.Min
+}
+
+type readMaxBytesOption struct {
+ Max int
+}
+
+func (o *readMaxBytesOption) applyToClient(config *clientConfig) {
+ config.ReadMaxBytes = o.Max
+}
+
+func (o *readMaxBytesOption) applyToHandler(config *handlerConfig) {
+ config.ReadMaxBytes = o.Max
+}
+
+type sendMaxBytesOption struct {
+ Max int
+}
+
+func (o *sendMaxBytesOption) applyToClient(config *clientConfig) {
+ config.SendMaxBytes = o.Max
+}
+
+func (o *sendMaxBytesOption) applyToHandler(config *handlerConfig) {
+ config.SendMaxBytes = o.Max
+}
+
+type handlerOptionsOption struct {
+ options []HandlerOption
+}
+
+func (o *handlerOptionsOption) applyToHandler(config *handlerConfig) {
+ for _, option := range o.options {
+ option.applyToHandler(config)
+ }
+}
+
+type requireConnectProtocolHeaderOption struct{}
+
+func (o *requireConnectProtocolHeaderOption) applyToHandler(config *handlerConfig) {
+ config.RequireConnectProtocolHeader = true
+}
+
+type idempotencyOption struct {
+ idempotencyLevel IdempotencyLevel
+}
+
+func (o *idempotencyOption) applyToClient(config *clientConfig) {
+ config.IdempotencyLevel = o.idempotencyLevel
+}
+
+func (o *idempotencyOption) applyToHandler(config *handlerConfig) {
+ config.IdempotencyLevel = o.idempotencyLevel
+}
+
+type grpcOption struct {
+ web bool
+}
+
+func (o *grpcOption) applyToClient(config *clientConfig) {
+ config.Protocol = &protocolGRPC{web: o.web}
+}
+
+type enableGet struct{}
+
+func (o *enableGet) applyToClient(config *clientConfig) {
+ config.EnableGet = true
+}
+
+// WithHTTPGetMaxURLSize sets the maximum allowable URL length for GET requests
+// made using the Connect protocol. It has no effect on gRPC or gRPC-Web
+// clients, since those protocols are POST-only.
+//
+// Limiting the URL size is useful as most user agents, proxies, and servers
+// have limits on the allowable length of a URL. For example, Apache and Nginx
+// limit the size of a request line to around 8 KiB, meaning that maximum
+// length of a URL is a bit smaller than this. If you run into URL size
+// limitations imposed by your network infrastructure and don't know the
+// maximum allowable size, or if you'd prefer to be cautious from the start, a
+// 4096 byte (4 KiB) limit works with most common proxies and CDNs.
+//
+// If fallback is set to true and the URL would be longer than the configured
+// maximum value, the request will be sent as an HTTP POST instead. If fallback
+// is set to false, the request will fail with [CodeResourceExhausted].
+//
+// By default, Connect-protocol clients with GET requests enabled may send a
+// URL of any size.
+func WithHTTPGetMaxURLSize(bytes int, fallback bool) ClientOption {
+ return &getURLMaxBytes{Max: bytes, Fallback: fallback}
+}
+
+type getURLMaxBytes struct {
+ Max int
+ Fallback bool
+}
+
+func (o *getURLMaxBytes) applyToClient(config *clientConfig) {
+ config.GetURLMaxBytes = o.Max
+ config.GetUseFallback = o.Fallback
+}
+
+type interceptorsOption struct {
+ Interceptors []Interceptor
+}
+
+func (o *interceptorsOption) applyToClient(config *clientConfig) {
+ config.Interceptor = o.chainWith(config.Interceptor)
+}
+
+func (o *interceptorsOption) applyToHandler(config *handlerConfig) {
+ config.Interceptor = o.chainWith(config.Interceptor)
+}
+
+func (o *interceptorsOption) chainWith(current Interceptor) Interceptor {
+ if len(o.Interceptors) == 0 {
+ return current
+ }
+ if current == nil && len(o.Interceptors) == 1 {
+ return o.Interceptors[0]
+ }
+ if current == nil && len(o.Interceptors) > 1 {
+ return newChain(o.Interceptors)
+ }
+ return newChain(append([]Interceptor{current}, o.Interceptors...))
+}
+
+type optionsOption struct {
+ options []Option
+}
+
+func (o *optionsOption) applyToClient(config *clientConfig) {
+ for _, option := range o.options {
+ option.applyToClient(config)
+ }
+}
+
+func (o *optionsOption) applyToHandler(config *handlerConfig) {
+ for _, option := range o.options {
+ option.applyToHandler(config)
+ }
+}
+
+type sendCompressionOption struct {
+ Name string
+}
+
+func (o *sendCompressionOption) applyToClient(config *clientConfig) {
+ config.RequestCompressionName = o.Name
+}
+
+func withGzip() Option {
+ return &compressionOption{
+ Name: compressionGzip,
+ CompressionPool: newCompressionPool(
+ func() Decompressor { return &gzip.Reader{} },
+ func() Compressor { return gzip.NewWriter(io.Discard) },
+ ),
+ }
+}
+
+func withProtoBinaryCodec() Option {
+ return WithCodec(&protoBinaryCodec{})
+}
+
+func withProtoJSONCodecs() HandlerOption {
+ return WithHandlerOptions(
+ WithCodec(&protoJSONCodec{codecNameJSON}),
+ WithCodec(&protoJSONCodec{codecNameJSONCharsetUTF8}),
+ )
+}
+
+type conditionalHandlerOptions struct {
+ conditional func(spec Spec) []HandlerOption
+}
+
+func (o *conditionalHandlerOptions) applyToHandler(config *handlerConfig) {
+ spec := config.newSpec()
+ if spec.Procedure == "" {
+ return // ignore empty specs
+ }
+ for _, option := range o.conditional(spec) {
+ option.applyToHandler(config)
+ }
+}
diff --git a/vendor/connectrpc.com/connect/protobuf_util.go b/vendor/connectrpc.com/connect/protobuf_util.go
new file mode 100644
index 0000000..1c8dbdc
--- /dev/null
+++ b/vendor/connectrpc.com/connect/protobuf_util.go
@@ -0,0 +1,42 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "strings"
+)
+
+// extractProtoPath returns the trailing portion of the URL's path,
+// corresponding to the Protobuf package, service, and method. It always starts
+// with a slash. Within connect, we use this as (1) Spec.Procedure and (2) the
+// path when mounting handlers on muxes.
+func extractProtoPath(path string) string {
+ segments := strings.Split(path, "/")
+ var pkg, method string
+ if len(segments) > 0 {
+ pkg = segments[0]
+ }
+ if len(segments) > 1 {
+ pkg = segments[len(segments)-2]
+ method = segments[len(segments)-1]
+ }
+ if pkg == "" {
+ return "/"
+ }
+ if method == "" {
+ return "/" + pkg
+ }
+ return "/" + pkg + "/" + method
+}
diff --git a/vendor/connectrpc.com/connect/protocol.go b/vendor/connectrpc.com/connect/protocol.go
new file mode 100644
index 0000000..9add614
--- /dev/null
+++ b/vendor/connectrpc.com/connect/protocol.go
@@ -0,0 +1,424 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "mime"
+ "net/http"
+ "net/url"
+ "sort"
+ "strings"
+)
+
+// The names of the Connect, gRPC, and gRPC-Web protocols (as exposed by
+// [Peer.Protocol]). Additional protocols may be added in the future.
+const (
+ ProtocolConnect = "connect"
+ ProtocolGRPC = "grpc"
+ ProtocolGRPCWeb = "grpcweb"
+)
+
+const (
+ headerContentType = "Content-Type"
+ headerContentEncoding = "Content-Encoding"
+ headerContentLength = "Content-Length"
+ headerHost = "Host"
+ headerUserAgent = "User-Agent"
+ headerTrailer = "Trailer"
+ headerDate = "Date"
+
+ discardLimit = 1024 * 1024 * 4 // 4MiB
+)
+
+var errNoTimeout = errors.New("no timeout")
+
+// A Protocol defines the HTTP semantics to use when sending and receiving
+// messages. It ties together codecs, compressors, and net/http to produce
+// Senders and Receivers.
+//
+// For example, connect supports the gRPC protocol using this abstraction. Among
+// many other things, the protocol implementation is responsible for
+// translating timeouts from Go contexts to HTTP and vice versa. For gRPC, it
+// converts timeouts to and from strings (for example, 10*time.Second <->
+// "10S"), and puts those strings into the "Grpc-Timeout" HTTP header. Other
+// protocols might encode durations differently, put them into a different HTTP
+// header, or ignore them entirely.
+//
+// We don't have any short-term plans to export this interface; it's just here
+// to separate the protocol-specific portions of connect from the
+// protocol-agnostic plumbing.
+type protocol interface {
+ NewHandler(*protocolHandlerParams) protocolHandler
+ NewClient(*protocolClientParams) (protocolClient, error)
+}
+
+// HandlerParams are the arguments provided to a Protocol's NewHandler
+// method, bundled into a struct to allow backward-compatible argument
+// additions. Protocol implementations should take care to use the supplied
+// Spec rather than constructing their own, since new fields may have been
+// added.
+type protocolHandlerParams struct {
+ Spec Spec
+ Codecs readOnlyCodecs
+ CompressionPools readOnlyCompressionPools
+ CompressMinBytes int
+ BufferPool *bufferPool
+ ReadMaxBytes int
+ SendMaxBytes int
+ RequireConnectProtocolHeader bool
+ IdempotencyLevel IdempotencyLevel
+}
+
+// Handler is the server side of a protocol. HTTP handlers typically support
+// multiple protocols, codecs, and compressors.
+type protocolHandler interface {
+ // Methods is the set of HTTP methods the protocol can handle.
+ Methods() map[string]struct{}
+
+ // ContentTypes is the set of HTTP Content-Types that the protocol can
+ // handle.
+ ContentTypes() map[string]struct{}
+
+ // SetTimeout runs before NewStream. Implementations may inspect the HTTP
+ // request, parse any timeout set by the client, and return a modified
+ // context and cancellation function.
+ //
+ // If the client didn't send a timeout, SetTimeout should return the
+ // request's context, a nil cancellation function, and a nil error.
+ SetTimeout(*http.Request) (context.Context, context.CancelFunc, error)
+
+ // CanHandlePayload returns true if the protocol can handle an HTTP request.
+ // This is called after the request method is validated, so we only need to
+ // be concerned with the content type/payload specifically.
+ CanHandlePayload(*http.Request, string) bool
+
+ // NewConn constructs a HandlerConn for the message exchange.
+ NewConn(http.ResponseWriter, *http.Request) (handlerConnCloser, bool)
+}
+
+// ClientParams are the arguments provided to a Protocol's NewClient method,
+// bundled into a struct to allow backward-compatible argument additions.
+// Protocol implementations should take care to use the supplied Spec rather
+// than constructing their own, since new fields may have been added.
+type protocolClientParams struct {
+ CompressionName string
+ CompressionPools readOnlyCompressionPools
+ Codec Codec
+ CompressMinBytes int
+ HTTPClient HTTPClient
+ URL *url.URL
+ BufferPool *bufferPool
+ ReadMaxBytes int
+ SendMaxBytes int
+ EnableGet bool
+ GetURLMaxBytes int
+ GetUseFallback bool
+ // The gRPC family of protocols always needs access to a Protobuf codec to
+ // marshal and unmarshal errors.
+ Protobuf Codec
+}
+
+// Client is the client side of a protocol. HTTP clients typically use a single
+// protocol, codec, and compressor to send requests.
+type protocolClient interface {
+ // Peer describes the server for the RPC.
+ Peer() Peer
+
+ // WriteRequestHeader writes any protocol-specific request headers.
+ WriteRequestHeader(StreamType, http.Header)
+
+ // NewConn constructs a StreamingClientConn for the message exchange.
+ //
+ // Implementations should assume that the supplied HTTP headers have already
+ // been populated by WriteRequestHeader. When constructing a stream for a
+ // unary call, implementations may assume that the Sender's Send and Close
+ // methods return before the Receiver's Receive or Close methods are called.
+ NewConn(context.Context, Spec, http.Header) streamingClientConn
+}
+
+// streamingClientConn extends StreamingClientConn with a method for registering
+// a hook when the HTTP request is actually sent.
+type streamingClientConn interface {
+ StreamingClientConn
+
+ onRequestSend(fn func(*http.Request))
+}
+
+// errorTranslatingHandlerConnCloser wraps a handlerConnCloser to ensure that
+// we always return coded errors to users and write coded errors to the
+// network.
+//
+// It's used in protocol implementations.
+type errorTranslatingHandlerConnCloser struct {
+ handlerConnCloser
+
+ toWire func(error) error
+ fromWire func(error) error
+}
+
+func (hc *errorTranslatingHandlerConnCloser) Send(msg any) error {
+ return hc.fromWire(hc.handlerConnCloser.Send(msg))
+}
+
+func (hc *errorTranslatingHandlerConnCloser) Receive(msg any) error {
+ return hc.fromWire(hc.handlerConnCloser.Receive(msg))
+}
+
+func (hc *errorTranslatingHandlerConnCloser) Close(err error) error {
+ closeErr := hc.handlerConnCloser.Close(hc.toWire(err))
+ return hc.fromWire(closeErr)
+}
+
+func (hc *errorTranslatingHandlerConnCloser) getHTTPMethod() string {
+ if methoder, ok := hc.handlerConnCloser.(interface{ getHTTPMethod() string }); ok {
+ return methoder.getHTTPMethod()
+ }
+ return http.MethodPost
+}
+
+// errorTranslatingClientConn wraps a StreamingClientConn to make sure that we always
+// return coded errors from clients.
+//
+// It's used in protocol implementations.
+type errorTranslatingClientConn struct {
+ streamingClientConn
+
+ fromWire func(error) error
+}
+
+func (cc *errorTranslatingClientConn) Send(msg any) error {
+ return cc.fromWire(cc.streamingClientConn.Send(msg))
+}
+
+func (cc *errorTranslatingClientConn) Receive(msg any) error {
+ return cc.fromWire(cc.streamingClientConn.Receive(msg))
+}
+
+func (cc *errorTranslatingClientConn) CloseRequest() error {
+ return cc.fromWire(cc.streamingClientConn.CloseRequest())
+}
+
+func (cc *errorTranslatingClientConn) CloseResponse() error {
+ return cc.fromWire(cc.streamingClientConn.CloseResponse())
+}
+
+func (cc *errorTranslatingClientConn) onRequestSend(fn func(*http.Request)) {
+ cc.streamingClientConn.onRequestSend(fn)
+}
+
+// wrapHandlerConnWithCodedErrors ensures that we (1) automatically code
+// context-related errors correctly when writing them to the network, and (2)
+// return *Errors from all exported APIs.
+func wrapHandlerConnWithCodedErrors(conn handlerConnCloser) handlerConnCloser {
+ return &errorTranslatingHandlerConnCloser{
+ handlerConnCloser: conn,
+ toWire: wrapIfContextError,
+ fromWire: wrapIfUncoded,
+ }
+}
+
+// wrapClientConnWithCodedErrors ensures that we always return *Errors from
+// public APIs.
+func wrapClientConnWithCodedErrors(conn streamingClientConn) streamingClientConn {
+ return &errorTranslatingClientConn{
+ streamingClientConn: conn,
+ fromWire: wrapIfUncoded,
+ }
+}
+
+func mappedMethodHandlers(handlers []protocolHandler) map[string][]protocolHandler {
+ methodHandlers := make(map[string][]protocolHandler)
+ for _, handler := range handlers {
+ for method := range handler.Methods() {
+ methodHandlers[method] = append(methodHandlers[method], handler)
+ }
+ }
+ return methodHandlers
+}
+
+func sortedAcceptPostValue(handlers []protocolHandler) string {
+ contentTypes := make(map[string]struct{})
+ for _, handler := range handlers {
+ for contentType := range handler.ContentTypes() {
+ contentTypes[contentType] = struct{}{}
+ }
+ }
+ accept := make([]string, 0, len(contentTypes))
+ for ct := range contentTypes {
+ accept = append(accept, ct)
+ }
+ sort.Strings(accept)
+ return strings.Join(accept, ", ")
+}
+
+func sortedAllowMethodValue(handlers []protocolHandler) string {
+ methods := make(map[string]struct{})
+ for _, handler := range handlers {
+ for method := range handler.Methods() {
+ methods[method] = struct{}{}
+ }
+ }
+ allow := make([]string, 0, len(methods))
+ for ct := range methods {
+ allow = append(allow, ct)
+ }
+ sort.Strings(allow)
+ return strings.Join(allow, ", ")
+}
+
+func isCommaOrSpace(c rune) bool {
+ return c == ',' || c == ' '
+}
+
+func discard(reader io.Reader) (int64, error) {
+ if lr, ok := reader.(*io.LimitedReader); ok {
+ return io.Copy(io.Discard, lr)
+ }
+ // We don't want to get stuck throwing data away forever, so limit how much
+ // we're willing to do here.
+ lr := &io.LimitedReader{R: reader, N: discardLimit}
+ return io.Copy(io.Discard, lr)
+}
+
+// negotiateCompression determines and validates the request compression and
+// response compression using the available compressors and protocol-specific
+// Content-Encoding and Accept-Encoding headers.
+func negotiateCompression( //nolint:nonamedreturns
+ availableCompressors readOnlyCompressionPools,
+ sent, accept string,
+) (requestCompression, responseCompression string, clientVisibleErr *Error) {
+ requestCompression = compressionIdentity
+ if sent != "" && sent != compressionIdentity {
+ // We default to identity, so we only care if the client sends something
+ // other than the empty string or compressIdentity.
+ if availableCompressors.Contains(sent) {
+ requestCompression = sent
+ } else {
+ // To comply with
+ // https://github.com/grpc/grpc/blob/master/doc/compression.md and the
+ // Connect protocol, we should return CodeUnimplemented and specify
+ // acceptable compression(s) (in addition to setting the a
+ // protocol-specific accept-encoding header).
+ return "", "", errorf(
+ CodeUnimplemented,
+ "unknown compression %q: supported encodings are %v",
+ sent, availableCompressors.CommaSeparatedNames(),
+ )
+ }
+ }
+ // Support asymmetric compression. This logic follows
+ // https://github.com/grpc/grpc/blob/master/doc/compression.md and common
+ // sense.
+ responseCompression = requestCompression
+ // If we're not already planning to compress the response, check whether the
+ // client requested a compression algorithm we support.
+ if responseCompression == compressionIdentity && accept != "" {
+ for _, name := range strings.FieldsFunc(accept, isCommaOrSpace) {
+ if availableCompressors.Contains(name) {
+ // We found a mutually supported compression algorithm. Unlike standard
+ // HTTP, there's no preference weighting, so can bail out immediately.
+ responseCompression = name
+ break
+ }
+ }
+ }
+ return requestCompression, responseCompression, nil
+}
+
+// checkServerStreamsCanFlush ensures that bidi and server streaming handlers
+// have received an http.ResponseWriter that implements http.Flusher, since
+// they must flush data after sending each message.
+func checkServerStreamsCanFlush(spec Spec, responseWriter http.ResponseWriter) *Error {
+ requiresFlusher := (spec.StreamType & StreamTypeServer) == StreamTypeServer
+ if _, flushable := responseWriter.(http.Flusher); requiresFlusher && !flushable {
+ return NewError(CodeInternal, fmt.Errorf("%T does not implement http.Flusher", responseWriter))
+ }
+ return nil
+}
+
+func flushResponseWriter(w http.ResponseWriter) {
+ if f, ok := w.(http.Flusher); ok {
+ f.Flush()
+ }
+}
+
+func canonicalizeContentType(contentType string) string {
+ // Typically, clients send Content-Type in canonical form, without
+ // parameters. In those cases, we'd like to avoid parsing and
+ // canonicalization overhead.
+ //
+ // See https://www.rfc-editor.org/rfc/rfc2045.html#section-5.1 for a full
+ // grammar.
+ var slashes int
+ for _, r := range contentType {
+ switch {
+ case r >= 'a' && r <= 'z':
+ case r == '.' || r == '+' || r == '-':
+ case r == '/':
+ slashes++
+ default:
+ return canonicalizeContentTypeSlow(contentType)
+ }
+ }
+ if slashes == 1 {
+ return contentType
+ }
+ return canonicalizeContentTypeSlow(contentType)
+}
+
+func canonicalizeContentTypeSlow(contentType string) string {
+ base, params, err := mime.ParseMediaType(contentType)
+ if err != nil {
+ return contentType
+ }
+ // According to RFC 9110 Section 8.3.2, the charset parameter value should be treated as case-insensitive.
+ // mime.FormatMediaType canonicalizes parameter names, but not parameter values,
+ // because the case sensitivity of a parameter value depends on its semantics.
+ // Therefore, the charset parameter value should be canonicalized here.
+ // ref.) https://httpwg.org/specs/rfc9110.html#rfc.section.8.3.2
+ if charset, ok := params["charset"]; ok {
+ params["charset"] = strings.ToLower(charset)
+ }
+ return mime.FormatMediaType(base, params)
+}
+
+func httpToCode(httpCode int) Code {
+ // https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md
+ // Note that this is NOT the inverse of the gRPC-to-HTTP or Connect-to-HTTP
+ // mappings.
+
+ // Literals are easier to compare to the specification (vs named
+ // constants).
+ switch httpCode {
+ case 400:
+ return CodeInternal
+ case 401:
+ return CodeUnauthenticated
+ case 403:
+ return CodePermissionDenied
+ case 404:
+ return CodeUnimplemented
+ case 429:
+ return CodeUnavailable
+ case 502, 503, 504:
+ return CodeUnavailable
+ default:
+ return CodeUnknown
+ }
+}
diff --git a/vendor/connectrpc.com/connect/protocol_connect.go b/vendor/connectrpc.com/connect/protocol_connect.go
new file mode 100644
index 0000000..e3c5e4a
--- /dev/null
+++ b/vendor/connectrpc.com/connect/protocol_connect.go
@@ -0,0 +1,1446 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bytes"
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "net/http"
+ "net/url"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/anypb"
+)
+
+const (
+ connectUnaryHeaderCompression = "Content-Encoding"
+ connectUnaryHeaderAcceptCompression = "Accept-Encoding"
+ connectUnaryTrailerPrefix = "Trailer-"
+ connectStreamingHeaderCompression = "Connect-Content-Encoding"
+ connectStreamingHeaderAcceptCompression = "Connect-Accept-Encoding"
+ connectHeaderTimeout = "Connect-Timeout-Ms"
+ connectHeaderProtocolVersion = "Connect-Protocol-Version"
+ connectProtocolVersion = "1"
+ headerVary = "Vary"
+
+ connectFlagEnvelopeEndStream = 0b00000010
+
+ connectUnaryContentTypePrefix = "application/"
+ connectUnaryContentTypeJSON = connectUnaryContentTypePrefix + codecNameJSON
+ connectStreamingContentTypePrefix = "application/connect+"
+
+ connectUnaryEncodingQueryParameter = "encoding"
+ connectUnaryMessageQueryParameter = "message"
+ connectUnaryBase64QueryParameter = "base64"
+ connectUnaryCompressionQueryParameter = "compression"
+ connectUnaryConnectQueryParameter = "connect"
+ connectUnaryConnectQueryValue = "v" + connectProtocolVersion
+)
+
+// defaultConnectUserAgent returns a User-Agent string similar to those used in gRPC.
+var defaultConnectUserAgent = fmt.Sprintf("connect-go/%s (%s)", Version, runtime.Version())
+
+type protocolConnect struct{}
+
+// NewHandler implements protocol, so it must return an interface.
+func (*protocolConnect) NewHandler(params *protocolHandlerParams) protocolHandler {
+ methods := make(map[string]struct{})
+ methods[http.MethodPost] = struct{}{}
+
+ if params.Spec.StreamType == StreamTypeUnary && params.IdempotencyLevel == IdempotencyNoSideEffects {
+ methods[http.MethodGet] = struct{}{}
+ }
+
+ contentTypes := make(map[string]struct{})
+ for _, name := range params.Codecs.Names() {
+ if params.Spec.StreamType == StreamTypeUnary {
+ contentTypes[canonicalizeContentType(connectUnaryContentTypePrefix+name)] = struct{}{}
+ continue
+ }
+ contentTypes[canonicalizeContentType(connectStreamingContentTypePrefix+name)] = struct{}{}
+ }
+
+ return &connectHandler{
+ protocolHandlerParams: *params,
+ methods: methods,
+ accept: contentTypes,
+ }
+}
+
+// NewClient implements protocol, so it must return an interface.
+func (*protocolConnect) NewClient(params *protocolClientParams) (protocolClient, error) {
+ return &connectClient{
+ protocolClientParams: *params,
+ peer: newPeerFromURL(params.URL, ProtocolConnect),
+ }, nil
+}
+
+type connectHandler struct {
+ protocolHandlerParams
+
+ methods map[string]struct{}
+ accept map[string]struct{}
+}
+
+func (h *connectHandler) Methods() map[string]struct{} {
+ return h.methods
+}
+
+func (h *connectHandler) ContentTypes() map[string]struct{} {
+ return h.accept
+}
+
+func (*connectHandler) SetTimeout(request *http.Request) (context.Context, context.CancelFunc, error) {
+ timeout := getHeaderCanonical(request.Header, connectHeaderTimeout)
+ if timeout == "" {
+ return request.Context(), nil, nil
+ }
+ if len(timeout) > 10 {
+ return nil, nil, errorf(CodeInvalidArgument, "parse timeout: %q has >10 digits", timeout)
+ }
+ millis, err := strconv.ParseInt(timeout, 10 /* base */, 64 /* bitsize */)
+ if err != nil {
+ return nil, nil, errorf(CodeInvalidArgument, "parse timeout: %w", err)
+ }
+ ctx, cancel := context.WithTimeout(
+ request.Context(),
+ time.Duration(millis)*time.Millisecond,
+ )
+ return ctx, cancel, nil
+}
+
+func (h *connectHandler) CanHandlePayload(request *http.Request, contentType string) bool {
+ if request.Method == http.MethodGet {
+ query := request.URL.Query()
+ codecName := query.Get(connectUnaryEncodingQueryParameter)
+ contentType = connectContentTypeFromCodecName(
+ h.Spec.StreamType,
+ codecName,
+ )
+ }
+ _, ok := h.accept[contentType]
+ return ok
+}
+
+func (h *connectHandler) NewConn(
+ responseWriter http.ResponseWriter,
+ request *http.Request,
+) (handlerConnCloser, bool) {
+ ctx := request.Context()
+ query := request.URL.Query()
+ // We need to parse metadata before entering the interceptor stack; we'll
+ // send the error to the client later on.
+ var contentEncoding, acceptEncoding string
+ if h.Spec.StreamType == StreamTypeUnary {
+ if request.Method == http.MethodGet {
+ contentEncoding = query.Get(connectUnaryCompressionQueryParameter)
+ } else {
+ contentEncoding = getHeaderCanonical(request.Header, connectUnaryHeaderCompression)
+ }
+ acceptEncoding = getHeaderCanonical(request.Header, connectUnaryHeaderAcceptCompression)
+ } else {
+ contentEncoding = getHeaderCanonical(request.Header, connectStreamingHeaderCompression)
+ acceptEncoding = getHeaderCanonical(request.Header, connectStreamingHeaderAcceptCompression)
+ }
+ requestCompression, responseCompression, failed := negotiateCompression(
+ h.CompressionPools,
+ contentEncoding,
+ acceptEncoding,
+ )
+ if failed == nil {
+ failed = checkServerStreamsCanFlush(h.Spec, responseWriter)
+ }
+ if failed == nil {
+ required := h.RequireConnectProtocolHeader && (h.Spec.StreamType == StreamTypeUnary)
+ failed = connectCheckProtocolVersion(request, required)
+ }
+
+ var requestBody io.ReadCloser
+ var contentType, codecName string
+ if request.Method == http.MethodGet {
+ if failed == nil && !query.Has(connectUnaryEncodingQueryParameter) {
+ failed = errorf(CodeInvalidArgument, "missing %s parameter", connectUnaryEncodingQueryParameter)
+ } else if failed == nil && !query.Has(connectUnaryMessageQueryParameter) {
+ failed = errorf(CodeInvalidArgument, "missing %s parameter", connectUnaryMessageQueryParameter)
+ }
+ msg := query.Get(connectUnaryMessageQueryParameter)
+ msgReader := queryValueReader(msg, query.Get(connectUnaryBase64QueryParameter) == "1")
+ requestBody = io.NopCloser(msgReader)
+ codecName = query.Get(connectUnaryEncodingQueryParameter)
+ contentType = connectContentTypeFromCodecName(
+ h.Spec.StreamType,
+ codecName,
+ )
+ } else {
+ requestBody = request.Body
+ contentType = getHeaderCanonical(request.Header, headerContentType)
+ codecName = connectCodecFromContentType(
+ h.Spec.StreamType,
+ contentType,
+ )
+ }
+
+ codec := h.Codecs.Get(codecName)
+ // The codec can be nil in the GET request case; that's okay: when failed
+ // is non-nil, codec is never used.
+ if failed == nil && codec == nil {
+ failed = errorf(CodeInvalidArgument, "invalid message encoding: %q", codecName)
+ }
+
+ // Write any remaining headers here:
+ // (1) any writes to the stream will implicitly send the headers, so we
+ // should get all of gRPC's required response headers ready.
+ // (2) interceptors should be able to see these headers.
+ //
+ // Since we know that these header keys are already in canonical form, we can
+ // skip the normalization in Header.Set.
+ header := responseWriter.Header()
+ header[headerContentType] = []string{contentType}
+ acceptCompressionHeader := connectUnaryHeaderAcceptCompression
+ if h.Spec.StreamType != StreamTypeUnary {
+ acceptCompressionHeader = connectStreamingHeaderAcceptCompression
+ // We only write the request encoding header here for streaming calls,
+ // since the streaming envelope lets us choose whether to compress each
+ // message individually. For unary, we won't know whether we're compressing
+ // the request until we see how large the payload is.
+ if responseCompression != compressionIdentity {
+ header[connectStreamingHeaderCompression] = []string{responseCompression}
+ }
+ }
+ header[acceptCompressionHeader] = []string{h.CompressionPools.CommaSeparatedNames()}
+
+ var conn handlerConnCloser
+ peer := Peer{
+ Addr: request.RemoteAddr,
+ Protocol: ProtocolConnect,
+ Query: query,
+ }
+ if h.Spec.StreamType == StreamTypeUnary {
+ conn = &connectUnaryHandlerConn{
+ spec: h.Spec,
+ peer: peer,
+ request: request,
+ responseWriter: responseWriter,
+ marshaler: connectUnaryMarshaler{
+ ctx: ctx,
+ sender: writeSender{writer: responseWriter},
+ codec: codec,
+ compressMinBytes: h.CompressMinBytes,
+ compressionName: responseCompression,
+ compressionPool: h.CompressionPools.Get(responseCompression),
+ bufferPool: h.BufferPool,
+ header: responseWriter.Header(),
+ sendMaxBytes: h.SendMaxBytes,
+ },
+ unmarshaler: connectUnaryUnmarshaler{
+ ctx: ctx,
+ reader: requestBody,
+ codec: codec,
+ compressionPool: h.CompressionPools.Get(requestCompression),
+ bufferPool: h.BufferPool,
+ readMaxBytes: h.ReadMaxBytes,
+ },
+ responseTrailer: make(http.Header),
+ }
+ } else {
+ conn = &connectStreamingHandlerConn{
+ spec: h.Spec,
+ peer: peer,
+ request: request,
+ responseWriter: responseWriter,
+ marshaler: connectStreamingMarshaler{
+ envelopeWriter: envelopeWriter{
+ ctx: ctx,
+ sender: writeSender{responseWriter},
+ codec: codec,
+ compressMinBytes: h.CompressMinBytes,
+ compressionPool: h.CompressionPools.Get(responseCompression),
+ bufferPool: h.BufferPool,
+ sendMaxBytes: h.SendMaxBytes,
+ },
+ },
+ unmarshaler: connectStreamingUnmarshaler{
+ envelopeReader: envelopeReader{
+ ctx: ctx,
+ reader: requestBody,
+ codec: codec,
+ compressionPool: h.CompressionPools.Get(requestCompression),
+ bufferPool: h.BufferPool,
+ readMaxBytes: h.ReadMaxBytes,
+ },
+ },
+ responseTrailer: make(http.Header),
+ }
+ }
+ conn = wrapHandlerConnWithCodedErrors(conn)
+
+ if failed != nil {
+ // Negotiation failed, so we can't establish a stream.
+ _ = conn.Close(failed)
+ return nil, false
+ }
+ return conn, true
+}
+
+type connectClient struct {
+ protocolClientParams
+
+ peer Peer
+}
+
+func (c *connectClient) Peer() Peer {
+ return c.peer
+}
+
+func (c *connectClient) WriteRequestHeader(streamType StreamType, header http.Header) {
+ // We know these header keys are in canonical form, so we can bypass all the
+ // checks in Header.Set.
+ if getHeaderCanonical(header, headerUserAgent) == "" {
+ header[headerUserAgent] = []string{defaultConnectUserAgent}
+ }
+ header[connectHeaderProtocolVersion] = []string{connectProtocolVersion}
+ header[headerContentType] = []string{
+ connectContentTypeFromCodecName(streamType, c.Codec.Name()),
+ }
+ acceptCompressionHeader := connectUnaryHeaderAcceptCompression
+ if streamType != StreamTypeUnary {
+ // If we don't set Accept-Encoding, by default http.Client will ask the
+ // server to compress the whole stream. Since we're already compressing
+ // each message, this is a waste.
+ header[connectUnaryHeaderAcceptCompression] = []string{compressionIdentity}
+ acceptCompressionHeader = connectStreamingHeaderAcceptCompression
+ // We only write the request encoding header here for streaming calls,
+ // since the streaming envelope lets us choose whether to compress each
+ // message individually. For unary, we won't know whether we're compressing
+ // the request until we see how large the payload is.
+ if c.CompressionName != "" && c.CompressionName != compressionIdentity {
+ header[connectStreamingHeaderCompression] = []string{c.CompressionName}
+ }
+ }
+ if acceptCompression := c.CompressionPools.CommaSeparatedNames(); acceptCompression != "" {
+ header[acceptCompressionHeader] = []string{acceptCompression}
+ }
+}
+
+func (c *connectClient) NewConn(
+ ctx context.Context,
+ spec Spec,
+ header http.Header,
+) streamingClientConn {
+ if deadline, ok := ctx.Deadline(); ok {
+ millis := int64(time.Until(deadline) / time.Millisecond)
+ if millis > 0 {
+ encoded := strconv.FormatInt(millis, 10 /* base */)
+ if len(encoded) <= 10 {
+ header[connectHeaderTimeout] = []string{encoded}
+ } // else effectively unbounded
+ }
+ }
+ duplexCall := newDuplexHTTPCall(ctx, c.HTTPClient, c.URL, spec, header)
+ var conn streamingClientConn
+ if spec.StreamType == StreamTypeUnary {
+ unaryConn := &connectUnaryClientConn{
+ spec: spec,
+ peer: c.Peer(),
+ duplexCall: duplexCall,
+ compressionPools: c.CompressionPools,
+ bufferPool: c.BufferPool,
+ marshaler: connectUnaryRequestMarshaler{
+ connectUnaryMarshaler: connectUnaryMarshaler{
+ ctx: ctx,
+ sender: duplexCall,
+ codec: c.Codec,
+ compressMinBytes: c.CompressMinBytes,
+ compressionName: c.CompressionName,
+ compressionPool: c.CompressionPools.Get(c.CompressionName),
+ bufferPool: c.BufferPool,
+ header: duplexCall.Header(),
+ sendMaxBytes: c.SendMaxBytes,
+ },
+ },
+ unmarshaler: connectUnaryUnmarshaler{
+ ctx: ctx,
+ reader: duplexCall,
+ codec: c.Codec,
+ bufferPool: c.BufferPool,
+ readMaxBytes: c.ReadMaxBytes,
+ },
+ responseHeader: make(http.Header),
+ responseTrailer: make(http.Header),
+ }
+ if spec.IdempotencyLevel == IdempotencyNoSideEffects {
+ unaryConn.marshaler.enableGet = c.EnableGet
+ unaryConn.marshaler.getURLMaxBytes = c.GetURLMaxBytes
+ unaryConn.marshaler.getUseFallback = c.GetUseFallback
+ unaryConn.marshaler.duplexCall = duplexCall
+ if stableCodec, ok := c.Codec.(stableCodec); ok {
+ unaryConn.marshaler.stableCodec = stableCodec
+ }
+ }
+ conn = unaryConn
+ duplexCall.SetValidateResponse(unaryConn.validateResponse)
+ } else {
+ streamingConn := &connectStreamingClientConn{
+ spec: spec,
+ peer: c.Peer(),
+ duplexCall: duplexCall,
+ compressionPools: c.CompressionPools,
+ bufferPool: c.BufferPool,
+ codec: c.Codec,
+ marshaler: connectStreamingMarshaler{
+ envelopeWriter: envelopeWriter{
+ ctx: ctx,
+ sender: duplexCall,
+ codec: c.Codec,
+ compressMinBytes: c.CompressMinBytes,
+ compressionPool: c.CompressionPools.Get(c.CompressionName),
+ bufferPool: c.BufferPool,
+ sendMaxBytes: c.SendMaxBytes,
+ },
+ },
+ unmarshaler: connectStreamingUnmarshaler{
+ envelopeReader: envelopeReader{
+ ctx: ctx,
+ reader: duplexCall,
+ codec: c.Codec,
+ bufferPool: c.BufferPool,
+ readMaxBytes: c.ReadMaxBytes,
+ },
+ },
+ responseHeader: make(http.Header),
+ responseTrailer: make(http.Header),
+ }
+ conn = streamingConn
+ duplexCall.SetValidateResponse(streamingConn.validateResponse)
+ }
+ return wrapClientConnWithCodedErrors(conn)
+}
+
+type connectUnaryClientConn struct {
+ spec Spec
+ peer Peer
+ duplexCall *duplexHTTPCall
+ compressionPools readOnlyCompressionPools
+ bufferPool *bufferPool
+ marshaler connectUnaryRequestMarshaler
+ unmarshaler connectUnaryUnmarshaler
+ responseHeader http.Header
+ responseTrailer http.Header
+}
+
+func (cc *connectUnaryClientConn) Spec() Spec {
+ return cc.spec
+}
+
+func (cc *connectUnaryClientConn) Peer() Peer {
+ return cc.peer
+}
+
+func (cc *connectUnaryClientConn) Send(msg any) error {
+ if err := cc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (cc *connectUnaryClientConn) RequestHeader() http.Header {
+ return cc.duplexCall.Header()
+}
+
+func (cc *connectUnaryClientConn) CloseRequest() error {
+ return cc.duplexCall.CloseWrite()
+}
+
+func (cc *connectUnaryClientConn) Receive(msg any) error {
+ if err := cc.duplexCall.BlockUntilResponseReady(); err != nil {
+ return err
+ }
+ if err := cc.unmarshaler.Unmarshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (cc *connectUnaryClientConn) ResponseHeader() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseHeader
+}
+
+func (cc *connectUnaryClientConn) ResponseTrailer() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseTrailer
+}
+
+func (cc *connectUnaryClientConn) CloseResponse() error {
+ return cc.duplexCall.CloseRead()
+}
+
+func (cc *connectUnaryClientConn) onRequestSend(fn func(*http.Request)) {
+ cc.duplexCall.onRequestSend = fn
+}
+
+func (cc *connectUnaryClientConn) validateResponse(response *http.Response) *Error {
+ for k, v := range response.Header {
+ if !strings.HasPrefix(k, connectUnaryTrailerPrefix) {
+ cc.responseHeader[k] = v
+ continue
+ }
+ cc.responseTrailer[k[len(connectUnaryTrailerPrefix):]] = v
+ }
+ if err := connectValidateUnaryResponseContentType(
+ cc.marshaler.codec.Name(),
+ cc.duplexCall.Method(),
+ response.StatusCode,
+ response.Status,
+ getHeaderCanonical(response.Header, headerContentType),
+ ); err != nil {
+ if IsNotModifiedError(err) {
+ // Allow access to response headers for this kind of error.
+ // RFC 9110 doesn't allow trailers on 304s, so we only need to include headers.
+ err.meta = cc.responseHeader.Clone()
+ }
+ return err
+ }
+ compression := getHeaderCanonical(response.Header, connectUnaryHeaderCompression)
+ if compression != "" &&
+ compression != compressionIdentity &&
+ !cc.compressionPools.Contains(compression) {
+ return errorf(
+ CodeInternal,
+ "unknown encoding %q: accepted encodings are %v",
+ compression,
+ cc.compressionPools.CommaSeparatedNames(),
+ )
+ }
+ cc.unmarshaler.compressionPool = cc.compressionPools.Get(compression)
+ if response.StatusCode != http.StatusOK {
+ unmarshaler := connectUnaryUnmarshaler{
+ ctx: cc.unmarshaler.ctx,
+ reader: response.Body,
+ compressionPool: cc.unmarshaler.compressionPool,
+ bufferPool: cc.bufferPool,
+ }
+ var wireErr connectWireError
+ if err := unmarshaler.UnmarshalFunc(&wireErr, json.Unmarshal); err != nil {
+ return NewError(
+ httpToCode(response.StatusCode),
+ errors.New(response.Status),
+ )
+ }
+ if wireErr.Code == 0 {
+ // code not set? default to one implied by HTTP status
+ wireErr.Code = httpToCode(response.StatusCode)
+ }
+ serverErr := wireErr.asError()
+ if serverErr == nil {
+ return nil
+ }
+ serverErr.meta = cc.responseHeader.Clone()
+ mergeHeaders(serverErr.meta, cc.responseTrailer)
+ return serverErr
+ }
+ return nil
+}
+
+type connectStreamingClientConn struct {
+ spec Spec
+ peer Peer
+ duplexCall *duplexHTTPCall
+ compressionPools readOnlyCompressionPools
+ bufferPool *bufferPool
+ codec Codec
+ marshaler connectStreamingMarshaler
+ unmarshaler connectStreamingUnmarshaler
+ responseHeader http.Header
+ responseTrailer http.Header
+}
+
+func (cc *connectStreamingClientConn) Spec() Spec {
+ return cc.spec
+}
+
+func (cc *connectStreamingClientConn) Peer() Peer {
+ return cc.peer
+}
+
+func (cc *connectStreamingClientConn) Send(msg any) error {
+ if err := cc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (cc *connectStreamingClientConn) RequestHeader() http.Header {
+ return cc.duplexCall.Header()
+}
+
+func (cc *connectStreamingClientConn) CloseRequest() error {
+ return cc.duplexCall.CloseWrite()
+}
+
+func (cc *connectStreamingClientConn) Receive(msg any) error {
+ if err := cc.duplexCall.BlockUntilResponseReady(); err != nil {
+ return err
+ }
+ err := cc.unmarshaler.Unmarshal(msg)
+ if err == nil {
+ return nil
+ }
+ // See if the server sent an explicit error in the end-of-stream message.
+ mergeHeaders(cc.responseTrailer, cc.unmarshaler.Trailer())
+ if serverErr := cc.unmarshaler.EndStreamError(); serverErr != nil {
+ // This is expected from a protocol perspective, but receiving an
+ // end-of-stream message means that we're _not_ getting a regular message.
+ // For users to realize that the stream has ended, Receive must return an
+ // error.
+ serverErr.meta = cc.responseHeader.Clone()
+ mergeHeaders(serverErr.meta, cc.responseTrailer)
+ _ = cc.duplexCall.CloseWrite()
+ return serverErr
+ }
+ // If the error is EOF but not from a last message, we want to return
+ // io.ErrUnexpectedEOF instead.
+ if errors.Is(err, io.EOF) && !errors.Is(err, errSpecialEnvelope) {
+ err = errorf(CodeInternal, "protocol error: %w", io.ErrUnexpectedEOF)
+ }
+ // There's no error in the trailers, so this was probably an error
+ // converting the bytes to a message, an error reading from the network, or
+ // just an EOF. We're going to return it to the user, but we also want to
+ // close the writer so Send errors out.
+ _ = cc.duplexCall.CloseWrite()
+ return err
+}
+
+func (cc *connectStreamingClientConn) ResponseHeader() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseHeader
+}
+
+func (cc *connectStreamingClientConn) ResponseTrailer() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseTrailer
+}
+
+func (cc *connectStreamingClientConn) CloseResponse() error {
+ return cc.duplexCall.CloseRead()
+}
+
+func (cc *connectStreamingClientConn) onRequestSend(fn func(*http.Request)) {
+ cc.duplexCall.onRequestSend = fn
+}
+
+func (cc *connectStreamingClientConn) validateResponse(response *http.Response) *Error {
+ if response.StatusCode != http.StatusOK {
+ return errorf(httpToCode(response.StatusCode), "HTTP status %v", response.Status)
+ }
+ if err := connectValidateStreamResponseContentType(
+ cc.codec.Name(),
+ cc.spec.StreamType,
+ getHeaderCanonical(response.Header, headerContentType),
+ ); err != nil {
+ return err
+ }
+ compression := getHeaderCanonical(response.Header, connectStreamingHeaderCompression)
+ if compression != "" &&
+ compression != compressionIdentity &&
+ !cc.compressionPools.Contains(compression) {
+ return errorf(
+ CodeInternal,
+ "unknown encoding %q: accepted encodings are %v",
+ compression,
+ cc.compressionPools.CommaSeparatedNames(),
+ )
+ }
+ cc.unmarshaler.compressionPool = cc.compressionPools.Get(compression)
+ mergeHeaders(cc.responseHeader, response.Header)
+ return nil
+}
+
+type connectUnaryHandlerConn struct {
+ spec Spec
+ peer Peer
+ request *http.Request
+ responseWriter http.ResponseWriter
+ marshaler connectUnaryMarshaler
+ unmarshaler connectUnaryUnmarshaler
+ responseTrailer http.Header
+}
+
+func (hc *connectUnaryHandlerConn) Spec() Spec {
+ return hc.spec
+}
+
+func (hc *connectUnaryHandlerConn) Peer() Peer {
+ return hc.peer
+}
+
+func (hc *connectUnaryHandlerConn) Receive(msg any) error {
+ if err := hc.unmarshaler.Unmarshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *connectUnaryHandlerConn) RequestHeader() http.Header {
+ return hc.request.Header
+}
+
+func (hc *connectUnaryHandlerConn) Send(msg any) error {
+ hc.mergeResponseHeader(nil /* error */)
+ if err := hc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *connectUnaryHandlerConn) ResponseHeader() http.Header {
+ return hc.responseWriter.Header()
+}
+
+func (hc *connectUnaryHandlerConn) ResponseTrailer() http.Header {
+ return hc.responseTrailer
+}
+
+func (hc *connectUnaryHandlerConn) Close(err error) error {
+ if !hc.marshaler.wroteHeader {
+ hc.mergeResponseHeader(err)
+ // If the handler received a GET request and the resource hasn't changed,
+ // return a 304.
+ if len(hc.peer.Query) > 0 && IsNotModifiedError(err) {
+ hc.responseWriter.WriteHeader(http.StatusNotModified)
+ return hc.request.Body.Close()
+ }
+ }
+ if err == nil || hc.marshaler.wroteHeader {
+ return hc.request.Body.Close()
+ }
+ // In unary Connect, errors always use application/json.
+ setHeaderCanonical(hc.responseWriter.Header(), headerContentType, connectUnaryContentTypeJSON)
+ hc.responseWriter.WriteHeader(connectCodeToHTTP(CodeOf(err)))
+ data, marshalErr := json.Marshal(newConnectWireError(err))
+ if marshalErr != nil {
+ _ = hc.request.Body.Close()
+ return errorf(CodeInternal, "marshal error: %w", err)
+ }
+ if _, writeErr := hc.responseWriter.Write(data); writeErr != nil {
+ _ = hc.request.Body.Close()
+ return writeErr
+ }
+ return hc.request.Body.Close()
+}
+
+func (hc *connectUnaryHandlerConn) getHTTPMethod() string {
+ return hc.request.Method
+}
+
+func (hc *connectUnaryHandlerConn) mergeResponseHeader(err error) {
+ header := hc.responseWriter.Header()
+ if hc.request.Method == http.MethodGet {
+ // The response content varies depending on the compression that the client
+ // requested (if any). GETs are potentially cacheable, so we should ensure
+ // that the Vary header includes at least Accept-Encoding (and not overwrite any values already set).
+ header[headerVary] = append(header[headerVary], connectUnaryHeaderAcceptCompression)
+ }
+ if err != nil {
+ if connectErr, ok := asError(err); ok && !connectErr.wireErr {
+ mergeMetadataHeaders(header, connectErr.meta)
+ }
+ }
+ for k, v := range hc.responseTrailer {
+ header[connectUnaryTrailerPrefix+k] = v
+ }
+}
+
+type connectStreamingHandlerConn struct {
+ spec Spec
+ peer Peer
+ request *http.Request
+ responseWriter http.ResponseWriter
+ marshaler connectStreamingMarshaler
+ unmarshaler connectStreamingUnmarshaler
+ responseTrailer http.Header
+}
+
+func (hc *connectStreamingHandlerConn) Spec() Spec {
+ return hc.spec
+}
+
+func (hc *connectStreamingHandlerConn) Peer() Peer {
+ return hc.peer
+}
+
+func (hc *connectStreamingHandlerConn) Receive(msg any) error {
+ if err := hc.unmarshaler.Unmarshal(msg); err != nil {
+ // Clients may not send end-of-stream metadata, so we don't need to handle
+ // errSpecialEnvelope.
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *connectStreamingHandlerConn) RequestHeader() http.Header {
+ return hc.request.Header
+}
+
+func (hc *connectStreamingHandlerConn) Send(msg any) error {
+ defer flushResponseWriter(hc.responseWriter)
+ if err := hc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *connectStreamingHandlerConn) ResponseHeader() http.Header {
+ return hc.responseWriter.Header()
+}
+
+func (hc *connectStreamingHandlerConn) ResponseTrailer() http.Header {
+ return hc.responseTrailer
+}
+
+func (hc *connectStreamingHandlerConn) Close(err error) error {
+ defer flushResponseWriter(hc.responseWriter)
+ if err := hc.marshaler.MarshalEndStream(err, hc.responseTrailer); err != nil {
+ _ = hc.request.Body.Close()
+ return err
+ }
+ // We don't want to copy unread portions of the body to /dev/null here: if
+ // the client hasn't closed the request body, we'll block until the server
+ // timeout kicks in. This could happen because the client is malicious, but
+ // a well-intentioned client may just not expect the server to be returning
+ // an error for a streaming RPC. Better to accept that we can't always reuse
+ // TCP connections.
+ if err := hc.request.Body.Close(); err != nil {
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return NewError(CodeUnknown, err)
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+type connectStreamingMarshaler struct {
+ envelopeWriter
+}
+
+func (m *connectStreamingMarshaler) MarshalEndStream(err error, trailer http.Header) *Error {
+ end := &connectEndStreamMessage{Trailer: trailer}
+ if err != nil {
+ end.Error = newConnectWireError(err)
+ if connectErr, ok := asError(err); ok && !connectErr.wireErr {
+ mergeMetadataHeaders(end.Trailer, connectErr.meta)
+ }
+ }
+ data, marshalErr := json.Marshal(end)
+ if marshalErr != nil {
+ return errorf(CodeInternal, "marshal end stream: %w", marshalErr)
+ }
+ raw := bytes.NewBuffer(data)
+ defer m.envelopeWriter.bufferPool.Put(raw)
+ return m.Write(&envelope{
+ Data: raw,
+ Flags: connectFlagEnvelopeEndStream,
+ })
+}
+
+type connectStreamingUnmarshaler struct {
+ envelopeReader
+
+ endStreamErr *Error
+ trailer http.Header
+}
+
+func (u *connectStreamingUnmarshaler) Unmarshal(message any) *Error {
+ err := u.envelopeReader.Unmarshal(message)
+ if err == nil {
+ return nil
+ }
+ if !errors.Is(err, errSpecialEnvelope) {
+ return err
+ }
+ env := u.last
+ data := env.Data
+ u.last.Data = nil // don't keep a reference to it
+ defer u.bufferPool.Put(data)
+ if !env.IsSet(connectFlagEnvelopeEndStream) {
+ return errorf(CodeInternal, "protocol error: invalid envelope flags %d", env.Flags)
+ }
+ var end connectEndStreamMessage
+ if err := json.Unmarshal(data.Bytes(), &end); err != nil {
+ return errorf(CodeInternal, "unmarshal end stream message: %w", err)
+ }
+ for name, value := range end.Trailer {
+ canonical := http.CanonicalHeaderKey(name)
+ if name != canonical {
+ delHeaderCanonical(end.Trailer, name)
+ end.Trailer[canonical] = append(end.Trailer[canonical], value...)
+ }
+ }
+ u.trailer = end.Trailer
+ u.endStreamErr = end.Error.asError()
+ return errSpecialEnvelope
+}
+
+func (u *connectStreamingUnmarshaler) Trailer() http.Header {
+ return u.trailer
+}
+
+func (u *connectStreamingUnmarshaler) EndStreamError() *Error {
+ return u.endStreamErr
+}
+
+type connectUnaryMarshaler struct {
+ ctx context.Context //nolint:containedctx
+ sender messageSender
+ codec Codec
+ compressMinBytes int
+ compressionName string
+ compressionPool *compressionPool
+ bufferPool *bufferPool
+ header http.Header
+ sendMaxBytes int
+ wroteHeader bool
+}
+
+func (m *connectUnaryMarshaler) Marshal(message any) *Error {
+ if message == nil {
+ return m.write(nil)
+ }
+ var data []byte
+ var err error
+ if appender, ok := m.codec.(marshalAppender); ok {
+ data, err = appender.MarshalAppend(m.bufferPool.Get().Bytes(), message)
+ } else {
+ // Can't avoid allocating the slice, but we'll reuse it.
+ data, err = m.codec.Marshal(message)
+ }
+ if err != nil {
+ return errorf(CodeInternal, "marshal message: %w", err)
+ }
+ uncompressed := bytes.NewBuffer(data)
+ defer m.bufferPool.Put(uncompressed)
+ if len(data) < m.compressMinBytes || m.compressionPool == nil {
+ if m.sendMaxBytes > 0 && len(data) > m.sendMaxBytes {
+ return NewError(CodeResourceExhausted, fmt.Errorf("message size %d exceeds sendMaxBytes %d", len(data), m.sendMaxBytes))
+ }
+ return m.write(data)
+ }
+ compressed := m.bufferPool.Get()
+ defer m.bufferPool.Put(compressed)
+ if err := m.compressionPool.Compress(compressed, uncompressed); err != nil {
+ return err
+ }
+ if m.sendMaxBytes > 0 && compressed.Len() > m.sendMaxBytes {
+ return NewError(CodeResourceExhausted, fmt.Errorf("compressed message size %d exceeds sendMaxBytes %d", compressed.Len(), m.sendMaxBytes))
+ }
+ setHeaderCanonical(m.header, connectUnaryHeaderCompression, m.compressionName)
+ return m.write(compressed.Bytes())
+}
+
+func (m *connectUnaryMarshaler) write(data []byte) *Error {
+ m.wroteHeader = true
+ payload := bytes.NewReader(data)
+ if _, err := m.sender.Send(payload); err != nil {
+ err = wrapIfContextError(err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeUnknown, "write message: %w", err)
+ }
+ return nil
+}
+
+type connectUnaryRequestMarshaler struct {
+ connectUnaryMarshaler
+
+ enableGet bool
+ getURLMaxBytes int
+ getUseFallback bool
+ stableCodec stableCodec
+ duplexCall *duplexHTTPCall
+}
+
+func (m *connectUnaryRequestMarshaler) Marshal(message any) *Error {
+ if m.enableGet {
+ if m.stableCodec == nil && !m.getUseFallback {
+ return errorf(CodeInternal, "codec %s doesn't support stable marshal; can't use get", m.codec.Name())
+ }
+ if m.stableCodec != nil {
+ return m.marshalWithGet(message)
+ }
+ }
+ return m.connectUnaryMarshaler.Marshal(message)
+}
+
+func (m *connectUnaryRequestMarshaler) marshalWithGet(message any) *Error {
+ // TODO(jchadwick-buf): This function is mostly a superset of
+ // connectUnaryMarshaler.Marshal. This should be reconciled at some point.
+ var data []byte
+ var err error
+ if message != nil {
+ data, err = m.stableCodec.MarshalStable(message)
+ if err != nil {
+ return errorf(CodeInternal, "marshal message stable: %w", err)
+ }
+ }
+ isTooBig := m.sendMaxBytes > 0 && len(data) > m.sendMaxBytes
+ if isTooBig && m.compressionPool == nil {
+ return NewError(CodeResourceExhausted, fmt.Errorf(
+ "message size %d exceeds sendMaxBytes %d: enabling request compression may help",
+ len(data),
+ m.sendMaxBytes,
+ ))
+ }
+ if !isTooBig {
+ url := m.buildGetURL(data, false /* compressed */)
+ if m.getURLMaxBytes <= 0 || len(url.String()) < m.getURLMaxBytes {
+ return m.writeWithGet(url)
+ }
+ if m.compressionPool == nil {
+ if m.getUseFallback {
+ return m.write(data)
+ }
+ return NewError(CodeResourceExhausted, fmt.Errorf(
+ "url size %d exceeds getURLMaxBytes %d: enabling request compression may help",
+ len(url.String()),
+ m.getURLMaxBytes,
+ ))
+ }
+ }
+ // Compress message to try to make it fit in the URL.
+ uncompressed := bytes.NewBuffer(data)
+ defer m.bufferPool.Put(uncompressed)
+ compressed := m.bufferPool.Get()
+ defer m.bufferPool.Put(compressed)
+ if err := m.compressionPool.Compress(compressed, uncompressed); err != nil {
+ return err
+ }
+ if m.sendMaxBytes > 0 && compressed.Len() > m.sendMaxBytes {
+ return NewError(CodeResourceExhausted, fmt.Errorf("compressed message size %d exceeds sendMaxBytes %d", compressed.Len(), m.sendMaxBytes))
+ }
+ url := m.buildGetURL(compressed.Bytes(), true /* compressed */)
+ if m.getURLMaxBytes <= 0 || len(url.String()) < m.getURLMaxBytes {
+ return m.writeWithGet(url)
+ }
+ if m.getUseFallback {
+ setHeaderCanonical(m.header, connectUnaryHeaderCompression, m.compressionName)
+ return m.write(compressed.Bytes())
+ }
+ return NewError(CodeResourceExhausted, fmt.Errorf("compressed url size %d exceeds getURLMaxBytes %d", len(url.String()), m.getURLMaxBytes))
+}
+
+func (m *connectUnaryRequestMarshaler) buildGetURL(data []byte, compressed bool) *url.URL {
+ url := *m.duplexCall.URL()
+ query := url.Query()
+ query.Set(connectUnaryConnectQueryParameter, connectUnaryConnectQueryValue)
+ query.Set(connectUnaryEncodingQueryParameter, m.codec.Name())
+ if m.stableCodec.IsBinary() || compressed {
+ query.Set(connectUnaryMessageQueryParameter, encodeBinaryQueryValue(data))
+ query.Set(connectUnaryBase64QueryParameter, "1")
+ } else {
+ query.Set(connectUnaryMessageQueryParameter, string(data))
+ }
+ if compressed {
+ query.Set(connectUnaryCompressionQueryParameter, m.compressionName)
+ }
+ url.RawQuery = query.Encode()
+ return &url
+}
+
+func (m *connectUnaryRequestMarshaler) writeWithGet(url *url.URL) *Error {
+ delHeaderCanonical(m.header, connectHeaderProtocolVersion)
+ delHeaderCanonical(m.header, headerContentType)
+ delHeaderCanonical(m.header, headerContentEncoding)
+ delHeaderCanonical(m.header, headerContentLength)
+ m.duplexCall.SetMethod(http.MethodGet)
+ *m.duplexCall.URL() = *url
+ return nil
+}
+
+type connectUnaryUnmarshaler struct {
+ ctx context.Context //nolint:containedctx
+ reader io.Reader
+ codec Codec
+ compressionPool *compressionPool
+ bufferPool *bufferPool
+ alreadyRead bool
+ readMaxBytes int
+}
+
+func (u *connectUnaryUnmarshaler) Unmarshal(message any) *Error {
+ return u.UnmarshalFunc(message, u.codec.Unmarshal)
+}
+
+func (u *connectUnaryUnmarshaler) UnmarshalFunc(message any, unmarshal func([]byte, any) error) *Error {
+ if u.alreadyRead {
+ return NewError(CodeInternal, io.EOF)
+ }
+ u.alreadyRead = true
+ data := u.bufferPool.Get()
+ defer u.bufferPool.Put(data)
+ reader := u.reader
+ if u.readMaxBytes > 0 && int64(u.readMaxBytes) < math.MaxInt64 {
+ reader = io.LimitReader(u.reader, int64(u.readMaxBytes)+1)
+ }
+ // ReadFrom ignores io.EOF, so any error here is real.
+ bytesRead, err := data.ReadFrom(reader)
+ if err != nil {
+ err = wrapIfMaxBytesError(err, "read first %d bytes of message", bytesRead)
+ err = wrapIfContextDone(u.ctx, err)
+ if connectErr, ok := asError(err); ok {
+ return connectErr
+ }
+ return errorf(CodeUnknown, "read message: %w", err)
+ }
+ if u.readMaxBytes > 0 && bytesRead > int64(u.readMaxBytes) {
+ // Attempt to read to end in order to allow connection re-use
+ discardedBytes, err := io.Copy(io.Discard, u.reader)
+ if err != nil {
+ return errorf(CodeResourceExhausted, "message is larger than configured max %d - unable to determine message size: %w", u.readMaxBytes, err)
+ }
+ return errorf(CodeResourceExhausted, "message size %d is larger than configured max %d", bytesRead+discardedBytes, u.readMaxBytes)
+ }
+ if data.Len() > 0 && u.compressionPool != nil {
+ decompressed := u.bufferPool.Get()
+ defer u.bufferPool.Put(decompressed)
+ if err := u.compressionPool.Decompress(decompressed, data, int64(u.readMaxBytes)); err != nil {
+ return err
+ }
+ data = decompressed
+ }
+ if err := unmarshal(data.Bytes(), message); err != nil {
+ return errorf(CodeInvalidArgument, "unmarshal message: %w", err)
+ }
+ return nil
+}
+
+type connectWireDetail ErrorDetail
+
+func (d *connectWireDetail) MarshalJSON() ([]byte, error) {
+ if d.wireJSON != "" {
+ // If we unmarshaled this detail from JSON, return the original data. This
+ // lets proxies w/o protobuf descriptors preserve human-readable details.
+ return []byte(d.wireJSON), nil
+ }
+ wire := struct {
+ Type string `json:"type"`
+ Value string `json:"value"`
+ Debug json.RawMessage `json:"debug,omitempty"`
+ }{
+ Type: typeNameFromURL(d.pbAny.GetTypeUrl()),
+ Value: base64.RawStdEncoding.EncodeToString(d.pbAny.GetValue()),
+ }
+ // Try to produce debug info, but expect failure when we don't have
+ // descriptors.
+ msg, err := d.getInner()
+ if err == nil {
+ var codec protoJSONCodec
+ debug, err := codec.Marshal(msg)
+ if err == nil {
+ wire.Debug = debug
+ }
+ }
+ return json.Marshal(wire)
+}
+
+func (d *connectWireDetail) UnmarshalJSON(data []byte) error {
+ var wire struct {
+ Type string `json:"type"`
+ Value string `json:"value"`
+ }
+ if err := json.Unmarshal(data, &wire); err != nil {
+ return err
+ }
+ if !strings.Contains(wire.Type, "/") {
+ wire.Type = defaultAnyResolverPrefix + wire.Type
+ }
+ decoded, err := DecodeBinaryHeader(wire.Value)
+ if err != nil {
+ return fmt.Errorf("decode base64: %w", err)
+ }
+ *d = connectWireDetail{
+ pbAny: &anypb.Any{
+ TypeUrl: wire.Type,
+ Value: decoded,
+ },
+ wireJSON: string(data),
+ }
+ return nil
+}
+
+func (d *connectWireDetail) getInner() (proto.Message, error) {
+ if d.pbInner != nil {
+ return d.pbInner, nil
+ }
+ return d.pbAny.UnmarshalNew()
+}
+
+type connectWireError struct {
+ Code Code `json:"code"`
+ Message string `json:"message,omitempty"`
+ Details []*connectWireDetail `json:"details,omitempty"`
+}
+
+func newConnectWireError(err error) *connectWireError {
+ wire := &connectWireError{
+ Code: CodeUnknown,
+ Message: err.Error(),
+ }
+ if connectErr, ok := asError(err); ok {
+ wire.Code = connectErr.Code()
+ wire.Message = connectErr.Message()
+ if len(connectErr.details) > 0 {
+ wire.Details = make([]*connectWireDetail, len(connectErr.details))
+ for i, detail := range connectErr.details {
+ wire.Details[i] = (*connectWireDetail)(detail)
+ }
+ }
+ }
+ return wire
+}
+
+func (e *connectWireError) asError() *Error {
+ if e == nil {
+ return nil
+ }
+ if e.Code < minCode || e.Code > maxCode {
+ e.Code = CodeUnknown
+ }
+ err := NewWireError(e.Code, errors.New(e.Message))
+ if len(e.Details) > 0 {
+ err.details = make([]*ErrorDetail, len(e.Details))
+ for i, detail := range e.Details {
+ err.details[i] = (*ErrorDetail)(detail)
+ }
+ }
+ return err
+}
+
+func (e *connectWireError) UnmarshalJSON(data []byte) error {
+ // We want to be lenient if the JSON has an unrecognized or invalid code.
+ // So if that occurs, we leave the code unset but can still de-serialize
+ // the other fields from the input JSON.
+ var wireError struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+ Details []*connectWireDetail `json:"details"`
+ }
+ err := json.Unmarshal(data, &wireError)
+ if err != nil {
+ return err
+ }
+ e.Message = wireError.Message
+ e.Details = wireError.Details
+ // This will leave e.Code unset if we can't unmarshal the given string.
+ _ = e.Code.UnmarshalText([]byte(wireError.Code))
+ return nil
+}
+
+type connectEndStreamMessage struct {
+ Error *connectWireError `json:"error,omitempty"`
+ Trailer http.Header `json:"metadata,omitempty"`
+}
+
+func connectCodeToHTTP(code Code) int {
+ // Return literals rather than named constants from the HTTP package to make
+ // it easier to compare this function to the Connect specification.
+ switch code {
+ case CodeCanceled:
+ return 499
+ case CodeUnknown:
+ return 500
+ case CodeInvalidArgument:
+ return 400
+ case CodeDeadlineExceeded:
+ return 504
+ case CodeNotFound:
+ return 404
+ case CodeAlreadyExists:
+ return 409
+ case CodePermissionDenied:
+ return 403
+ case CodeResourceExhausted:
+ return 429
+ case CodeFailedPrecondition:
+ return 400
+ case CodeAborted:
+ return 409
+ case CodeOutOfRange:
+ return 400
+ case CodeUnimplemented:
+ return 501
+ case CodeInternal:
+ return 500
+ case CodeUnavailable:
+ return 503
+ case CodeDataLoss:
+ return 500
+ case CodeUnauthenticated:
+ return 401
+ default:
+ return 500 // same as CodeUnknown
+ }
+}
+
+func connectCodecFromContentType(streamType StreamType, contentType string) string {
+ if streamType == StreamTypeUnary {
+ return strings.TrimPrefix(contentType, connectUnaryContentTypePrefix)
+ }
+ return strings.TrimPrefix(contentType, connectStreamingContentTypePrefix)
+}
+
+func connectContentTypeFromCodecName(streamType StreamType, name string) string {
+ if streamType == StreamTypeUnary {
+ return connectUnaryContentTypePrefix + name
+ }
+ return connectStreamingContentTypePrefix + name
+}
+
+// encodeBinaryQueryValue URL-safe base64-encodes data, without padding.
+func encodeBinaryQueryValue(data []byte) string {
+ return base64.RawURLEncoding.EncodeToString(data)
+}
+
+// binaryQueryValueReader creates a reader that can read either padded or
+// unpadded URL-safe base64 from a string.
+func binaryQueryValueReader(data string) io.Reader {
+ stringReader := strings.NewReader(data)
+ if len(data)%4 != 0 {
+ // Data definitely isn't padded.
+ return base64.NewDecoder(base64.RawURLEncoding, stringReader)
+ }
+ // Data is padded, or no padding was necessary.
+ return base64.NewDecoder(base64.URLEncoding, stringReader)
+}
+
+// queryValueReader creates a reader for a string that may be URL-safe base64
+// encoded.
+func queryValueReader(data string, base64Encoded bool) io.Reader {
+ if base64Encoded {
+ return binaryQueryValueReader(data)
+ }
+ return strings.NewReader(data)
+}
+
+func connectValidateUnaryResponseContentType(
+ requestCodecName string,
+ httpMethod string,
+ statusCode int,
+ statusMsg string,
+ responseContentType string,
+) *Error {
+ if statusCode != http.StatusOK {
+ if statusCode == http.StatusNotModified && httpMethod == http.MethodGet {
+ return NewWireError(CodeUnknown, errNotModifiedClient)
+ }
+ // Error responses must be JSON-encoded.
+ if responseContentType == connectUnaryContentTypePrefix+codecNameJSON ||
+ responseContentType == connectUnaryContentTypePrefix+codecNameJSONCharsetUTF8 {
+ return nil
+ }
+ return NewError(
+ httpToCode(statusCode),
+ errors.New(statusMsg),
+ )
+ }
+ // Normal responses must have valid content-type that indicates same codec as the request.
+ if !strings.HasPrefix(responseContentType, connectUnaryContentTypePrefix) {
+ // Doesn't even look like a Connect response? Use code "unknown".
+ return errorf(
+ CodeUnknown,
+ "invalid content-type: %q; expecting %q",
+ responseContentType,
+ connectUnaryContentTypePrefix+requestCodecName,
+ )
+ }
+ responseCodecName := connectCodecFromContentType(
+ StreamTypeUnary,
+ responseContentType,
+ )
+ if responseCodecName == requestCodecName {
+ return nil
+ }
+ // HACK: We likely want a better way to handle the optional "charset" parameter
+ // for application/json, instead of hard-coding. But this suffices for now.
+ if (responseCodecName == codecNameJSON && requestCodecName == codecNameJSONCharsetUTF8) ||
+ (responseCodecName == codecNameJSONCharsetUTF8 && requestCodecName == codecNameJSON) {
+ // Both are JSON
+ return nil
+ }
+ return errorf(
+ CodeInternal,
+ "invalid content-type: %q; expecting %q",
+ responseContentType,
+ connectUnaryContentTypePrefix+requestCodecName,
+ )
+}
+
+func connectValidateStreamResponseContentType(requestCodecName string, streamType StreamType, responseContentType string) *Error {
+ // Responses must have valid content-type that indicates same codec as the request.
+ if !strings.HasPrefix(responseContentType, connectStreamingContentTypePrefix) {
+ // Doesn't even look like a Connect response? Use code "unknown".
+ return errorf(
+ CodeUnknown,
+ "invalid content-type: %q; expecting %q",
+ responseContentType,
+ connectUnaryContentTypePrefix+requestCodecName,
+ )
+ }
+ responseCodecName := connectCodecFromContentType(
+ streamType,
+ responseContentType,
+ )
+ if responseCodecName != requestCodecName {
+ return errorf(
+ CodeInternal,
+ "invalid content-type: %q; expecting %q",
+ responseContentType,
+ connectStreamingContentTypePrefix+requestCodecName,
+ )
+ }
+ return nil
+}
+
+func connectCheckProtocolVersion(request *http.Request, required bool) *Error {
+ switch request.Method {
+ case http.MethodGet:
+ version := request.URL.Query().Get(connectUnaryConnectQueryParameter)
+ if version == "" && required {
+ return errorf(CodeInvalidArgument, "missing required query parameter: set %s to %q", connectUnaryConnectQueryParameter, connectUnaryConnectQueryValue)
+ } else if version != "" && version != connectUnaryConnectQueryValue {
+ return errorf(CodeInvalidArgument, "%s must be %q: got %q", connectUnaryConnectQueryParameter, connectUnaryConnectQueryValue, version)
+ }
+ case http.MethodPost:
+ version := getHeaderCanonical(request.Header, connectHeaderProtocolVersion)
+ if version == "" && required {
+ return errorf(CodeInvalidArgument, "missing required header: set %s to %q", connectHeaderProtocolVersion, connectProtocolVersion)
+ } else if version != "" && version != connectProtocolVersion {
+ return errorf(CodeInvalidArgument, "%s must be %q: got %q", connectHeaderProtocolVersion, connectProtocolVersion, version)
+ }
+ default:
+ return errorf(CodeInvalidArgument, "unsupported method: %q", request.Method)
+ }
+ return nil
+}
diff --git a/vendor/connectrpc.com/connect/protocol_grpc.go b/vendor/connectrpc.com/connect/protocol_grpc.go
new file mode 100644
index 0000000..32b116f
--- /dev/null
+++ b/vendor/connectrpc.com/connect/protocol_grpc.go
@@ -0,0 +1,1007 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "bufio"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "net/http"
+ "net/textproto"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+
+ statusv1 "connectrpc.com/connect/internal/gen/connectext/grpc/status/v1"
+)
+
+const (
+ grpcHeaderCompression = "Grpc-Encoding"
+ grpcHeaderAcceptCompression = "Grpc-Accept-Encoding"
+ grpcHeaderTimeout = "Grpc-Timeout"
+ grpcHeaderStatus = "Grpc-Status"
+ grpcHeaderMessage = "Grpc-Message"
+ grpcHeaderDetails = "Grpc-Status-Details-Bin"
+
+ grpcFlagEnvelopeTrailer = 0b10000000
+
+ grpcContentTypeDefault = "application/grpc"
+ grpcWebContentTypeDefault = "application/grpc-web"
+ grpcContentTypePrefix = grpcContentTypeDefault + "+"
+ grpcWebContentTypePrefix = grpcWebContentTypeDefault + "+"
+
+ headerXUserAgent = "X-User-Agent"
+
+ upperhex = "0123456789ABCDEF"
+)
+
+var (
+ errTrailersWithoutGRPCStatus = fmt.Errorf("protocol error: no %s trailer: %w", grpcHeaderStatus, io.ErrUnexpectedEOF)
+
+ // defaultGrpcUserAgent follows
+ // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents:
+ //
+ // While the protocol does not require a user-agent to function it is recommended
+ // that clients provide a structured user-agent string that provides a basic
+ // description of the calling library, version & platform to facilitate issue diagnosis
+ // in heterogeneous environments. The following structure is recommended to library developers:
+ //
+ // User-Agent → "grpc-" Language ?("-" Variant) "/" Version ?( " (" *(AdditionalProperty ";") ")" )
+ defaultGrpcUserAgent = fmt.Sprintf("grpc-go-connect/%s (%s)", Version, runtime.Version())
+ grpcAllowedMethods = map[string]struct{}{
+ http.MethodPost: {},
+ }
+)
+
+type protocolGRPC struct {
+ web bool
+}
+
+// NewHandler implements protocol, so it must return an interface.
+func (g *protocolGRPC) NewHandler(params *protocolHandlerParams) protocolHandler {
+ bare, prefix := grpcContentTypeDefault, grpcContentTypePrefix
+ if g.web {
+ bare, prefix = grpcWebContentTypeDefault, grpcWebContentTypePrefix
+ }
+ contentTypes := make(map[string]struct{})
+ for _, name := range params.Codecs.Names() {
+ contentTypes[canonicalizeContentType(prefix+name)] = struct{}{}
+ }
+ if params.Codecs.Get(codecNameProto) != nil {
+ contentTypes[bare] = struct{}{}
+ }
+ return &grpcHandler{
+ protocolHandlerParams: *params,
+ web: g.web,
+ accept: contentTypes,
+ }
+}
+
+// NewClient implements protocol, so it must return an interface.
+func (g *protocolGRPC) NewClient(params *protocolClientParams) (protocolClient, error) {
+ peer := newPeerFromURL(params.URL, ProtocolGRPC)
+ if g.web {
+ peer = newPeerFromURL(params.URL, ProtocolGRPCWeb)
+ }
+ return &grpcClient{
+ protocolClientParams: *params,
+ web: g.web,
+ peer: peer,
+ }, nil
+}
+
+type grpcHandler struct {
+ protocolHandlerParams
+
+ web bool
+ accept map[string]struct{}
+}
+
+func (g *grpcHandler) Methods() map[string]struct{} {
+ return grpcAllowedMethods
+}
+
+func (g *grpcHandler) ContentTypes() map[string]struct{} {
+ return g.accept
+}
+
+func (*grpcHandler) SetTimeout(request *http.Request) (context.Context, context.CancelFunc, error) {
+ timeout, err := grpcParseTimeout(getHeaderCanonical(request.Header, grpcHeaderTimeout))
+ if err != nil && !errors.Is(err, errNoTimeout) {
+ // Errors here indicate that the client sent an invalid timeout header, so
+ // the error text is safe to send back.
+ return nil, nil, NewError(CodeInvalidArgument, err)
+ } else if err != nil {
+ // err wraps errNoTimeout, nothing to do.
+ return request.Context(), nil, nil //nolint:nilerr
+ }
+ ctx, cancel := context.WithTimeout(request.Context(), timeout)
+ return ctx, cancel, nil
+}
+
+func (g *grpcHandler) CanHandlePayload(_ *http.Request, contentType string) bool {
+ _, ok := g.accept[contentType]
+ return ok
+}
+
+func (g *grpcHandler) NewConn(
+ responseWriter http.ResponseWriter,
+ request *http.Request,
+) (handlerConnCloser, bool) {
+ ctx := request.Context()
+ // We need to parse metadata before entering the interceptor stack; we'll
+ // send the error to the client later on.
+ requestCompression, responseCompression, failed := negotiateCompression(
+ g.CompressionPools,
+ getHeaderCanonical(request.Header, grpcHeaderCompression),
+ getHeaderCanonical(request.Header, grpcHeaderAcceptCompression),
+ )
+ if failed == nil {
+ failed = checkServerStreamsCanFlush(g.Spec, responseWriter)
+ }
+
+ // Write any remaining headers here:
+ // (1) any writes to the stream will implicitly send the headers, so we
+ // should get all of gRPC's required response headers ready.
+ // (2) interceptors should be able to see these headers.
+ //
+ // Since we know that these header keys are already in canonical form, we can
+ // skip the normalization in Header.Set.
+ header := responseWriter.Header()
+ header[headerContentType] = []string{getHeaderCanonical(request.Header, headerContentType)}
+ header[grpcHeaderAcceptCompression] = []string{g.CompressionPools.CommaSeparatedNames()}
+ if responseCompression != compressionIdentity {
+ header[grpcHeaderCompression] = []string{responseCompression}
+ }
+
+ codecName := grpcCodecFromContentType(g.web, getHeaderCanonical(request.Header, headerContentType))
+ codec := g.Codecs.Get(codecName) // handler.go guarantees this is not nil
+ protocolName := ProtocolGRPC
+ if g.web {
+ protocolName = ProtocolGRPCWeb
+ }
+ conn := wrapHandlerConnWithCodedErrors(&grpcHandlerConn{
+ spec: g.Spec,
+ peer: Peer{
+ Addr: request.RemoteAddr,
+ Protocol: protocolName,
+ },
+ web: g.web,
+ bufferPool: g.BufferPool,
+ protobuf: g.Codecs.Protobuf(), // for errors
+ marshaler: grpcMarshaler{
+ envelopeWriter: envelopeWriter{
+ ctx: ctx,
+ sender: writeSender{writer: responseWriter},
+ compressionPool: g.CompressionPools.Get(responseCompression),
+ codec: codec,
+ compressMinBytes: g.CompressMinBytes,
+ bufferPool: g.BufferPool,
+ sendMaxBytes: g.SendMaxBytes,
+ },
+ },
+ responseWriter: responseWriter,
+ responseHeader: make(http.Header),
+ responseTrailer: make(http.Header),
+ request: request,
+ unmarshaler: grpcUnmarshaler{
+ envelopeReader: envelopeReader{
+ ctx: ctx,
+ reader: request.Body,
+ codec: codec,
+ compressionPool: g.CompressionPools.Get(requestCompression),
+ bufferPool: g.BufferPool,
+ readMaxBytes: g.ReadMaxBytes,
+ },
+ web: g.web,
+ },
+ })
+ if failed != nil {
+ // Negotiation failed, so we can't establish a stream.
+ _ = conn.Close(failed)
+ return nil, false
+ }
+ return conn, true
+}
+
+type grpcClient struct {
+ protocolClientParams
+
+ web bool
+ peer Peer
+}
+
+func (g *grpcClient) Peer() Peer {
+ return g.peer
+}
+
+func (g *grpcClient) WriteRequestHeader(_ StreamType, header http.Header) {
+ // We know these header keys are in canonical form, so we can bypass all the
+ // checks in Header.Set.
+ if getHeaderCanonical(header, headerUserAgent) == "" {
+ header[headerUserAgent] = []string{defaultGrpcUserAgent}
+ }
+ if g.web && getHeaderCanonical(header, headerXUserAgent) == "" {
+ // The gRPC-Web pseudo-specification seems to require X-User-Agent rather
+ // than User-Agent for all clients, even if they're not browser-based. This
+ // is very odd for a backend client, so we'll split the difference and set
+ // both.
+ header[headerXUserAgent] = []string{defaultGrpcUserAgent}
+ }
+ header[headerContentType] = []string{grpcContentTypeFromCodecName(g.web, g.Codec.Name())}
+ // gRPC handles compression on a per-message basis, so we don't want to
+ // compress the whole stream. By default, http.Client will ask the server
+ // to gzip the stream if we don't set Accept-Encoding.
+ header["Accept-Encoding"] = []string{compressionIdentity}
+ if g.CompressionName != "" && g.CompressionName != compressionIdentity {
+ header[grpcHeaderCompression] = []string{g.CompressionName}
+ }
+ if acceptCompression := g.CompressionPools.CommaSeparatedNames(); acceptCompression != "" {
+ header[grpcHeaderAcceptCompression] = []string{acceptCompression}
+ }
+ if !g.web {
+ // The gRPC-HTTP2 specification requires this - it flushes out proxies that
+ // don't support HTTP trailers.
+ header["Te"] = []string{"trailers"}
+ }
+}
+
+func (g *grpcClient) NewConn(
+ ctx context.Context,
+ spec Spec,
+ header http.Header,
+) streamingClientConn {
+ if deadline, ok := ctx.Deadline(); ok {
+ encodedDeadline := grpcEncodeTimeout(time.Until(deadline))
+ header[grpcHeaderTimeout] = []string{encodedDeadline}
+ }
+ duplexCall := newDuplexHTTPCall(
+ ctx,
+ g.HTTPClient,
+ g.URL,
+ spec,
+ header,
+ )
+ conn := &grpcClientConn{
+ spec: spec,
+ peer: g.Peer(),
+ duplexCall: duplexCall,
+ compressionPools: g.CompressionPools,
+ bufferPool: g.BufferPool,
+ protobuf: g.Protobuf,
+ marshaler: grpcMarshaler{
+ envelopeWriter: envelopeWriter{
+ ctx: ctx,
+ sender: duplexCall,
+ compressionPool: g.CompressionPools.Get(g.CompressionName),
+ codec: g.Codec,
+ compressMinBytes: g.CompressMinBytes,
+ bufferPool: g.BufferPool,
+ sendMaxBytes: g.SendMaxBytes,
+ },
+ },
+ unmarshaler: grpcUnmarshaler{
+ envelopeReader: envelopeReader{
+ ctx: ctx,
+ reader: duplexCall,
+ codec: g.Codec,
+ bufferPool: g.BufferPool,
+ readMaxBytes: g.ReadMaxBytes,
+ },
+ },
+ responseHeader: make(http.Header),
+ responseTrailer: make(http.Header),
+ }
+ duplexCall.SetValidateResponse(conn.validateResponse)
+ if g.web {
+ conn.unmarshaler.web = true
+ conn.readTrailers = func(unmarshaler *grpcUnmarshaler, _ *duplexHTTPCall) http.Header {
+ return unmarshaler.WebTrailer()
+ }
+ } else {
+ conn.readTrailers = func(_ *grpcUnmarshaler, call *duplexHTTPCall) http.Header {
+ // To access HTTP trailers, we need to read the body to EOF.
+ _, _ = discard(call)
+ return call.ResponseTrailer()
+ }
+ }
+ return wrapClientConnWithCodedErrors(conn)
+}
+
+// grpcClientConn works for both gRPC and gRPC-Web.
+type grpcClientConn struct {
+ spec Spec
+ peer Peer
+ duplexCall *duplexHTTPCall
+ compressionPools readOnlyCompressionPools
+ bufferPool *bufferPool
+ protobuf Codec // for errors
+ marshaler grpcMarshaler
+ unmarshaler grpcUnmarshaler
+ responseHeader http.Header
+ responseTrailer http.Header
+ readTrailers func(*grpcUnmarshaler, *duplexHTTPCall) http.Header
+}
+
+func (cc *grpcClientConn) Spec() Spec {
+ return cc.spec
+}
+
+func (cc *grpcClientConn) Peer() Peer {
+ return cc.peer
+}
+
+func (cc *grpcClientConn) Send(msg any) error {
+ if err := cc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (cc *grpcClientConn) RequestHeader() http.Header {
+ return cc.duplexCall.Header()
+}
+
+func (cc *grpcClientConn) CloseRequest() error {
+ return cc.duplexCall.CloseWrite()
+}
+
+func (cc *grpcClientConn) Receive(msg any) error {
+ if err := cc.duplexCall.BlockUntilResponseReady(); err != nil {
+ return err
+ }
+ err := cc.unmarshaler.Unmarshal(msg)
+ if err == nil {
+ return nil
+ }
+ mergeHeaders(
+ cc.responseTrailer,
+ cc.readTrailers(&cc.unmarshaler, cc.duplexCall),
+ )
+ if errors.Is(err, io.EOF) && cc.unmarshaler.bytesRead == 0 && len(cc.responseTrailer) == 0 {
+ // No body and no trailers means a trailers-only response.
+ // Note: per the specification, only the HTTP status code and Content-Type
+ // should be treated as headers. The rest should be treated as trailing
+ // metadata. But it would be unsafe to mutate cc.responseHeader at this
+ // point. So we'll leave cc.responseHeader alone but copy the relevant
+ // metadata into cc.responseTrailer.
+ mergeHeaders(cc.responseTrailer, cc.responseHeader)
+ delHeaderCanonical(cc.responseTrailer, headerContentType)
+
+ // Try to read the status out of the headers.
+ serverErr := grpcErrorFromTrailer(cc.protobuf, cc.responseHeader)
+ if serverErr == nil {
+ // Status says "OK". So return original error (io.EOF).
+ return err
+ }
+ serverErr.meta = cc.responseHeader.Clone()
+ return serverErr
+ }
+
+ // See if the server sent an explicit error in the HTTP or gRPC-Web trailers.
+ serverErr := grpcErrorFromTrailer(cc.protobuf, cc.responseTrailer)
+ if serverErr != nil && (errors.Is(err, io.EOF) || !errors.Is(serverErr, errTrailersWithoutGRPCStatus)) {
+ // We've either:
+ // - Cleanly read until the end of the response body and *not* received
+ // gRPC status trailers, which is a protocol error, or
+ // - Received an explicit error from the server.
+ //
+ // This is expected from a protocol perspective, but receiving trailers
+ // means that we're _not_ getting a message. For users to realize that
+ // the stream has ended, Receive must return an error.
+ serverErr.meta = cc.responseHeader.Clone()
+ mergeHeaders(serverErr.meta, cc.responseTrailer)
+ _ = cc.duplexCall.CloseWrite()
+ return serverErr
+ }
+ // This was probably an error converting the bytes to a message or an error
+ // reading from the network. We're going to return it to the
+ // user, but we also want to close writes so Send errors out.
+ _ = cc.duplexCall.CloseWrite()
+ return err
+}
+
+func (cc *grpcClientConn) ResponseHeader() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseHeader
+}
+
+func (cc *grpcClientConn) ResponseTrailer() http.Header {
+ _ = cc.duplexCall.BlockUntilResponseReady()
+ return cc.responseTrailer
+}
+
+func (cc *grpcClientConn) CloseResponse() error {
+ return cc.duplexCall.CloseRead()
+}
+
+func (cc *grpcClientConn) onRequestSend(fn func(*http.Request)) {
+ cc.duplexCall.onRequestSend = fn
+}
+
+func (cc *grpcClientConn) validateResponse(response *http.Response) *Error {
+ if err := grpcValidateResponse(
+ response,
+ cc.responseHeader,
+ cc.compressionPools,
+ cc.unmarshaler.web,
+ cc.marshaler.codec.Name(),
+ ); err != nil {
+ return err
+ }
+ compression := getHeaderCanonical(response.Header, grpcHeaderCompression)
+ cc.unmarshaler.compressionPool = cc.compressionPools.Get(compression)
+ return nil
+}
+
+type grpcHandlerConn struct {
+ spec Spec
+ peer Peer
+ web bool
+ bufferPool *bufferPool
+ protobuf Codec // for errors
+ marshaler grpcMarshaler
+ responseWriter http.ResponseWriter
+ responseHeader http.Header
+ responseTrailer http.Header
+ wroteToBody bool
+ request *http.Request
+ unmarshaler grpcUnmarshaler
+}
+
+func (hc *grpcHandlerConn) Spec() Spec {
+ return hc.spec
+}
+
+func (hc *grpcHandlerConn) Peer() Peer {
+ return hc.peer
+}
+
+func (hc *grpcHandlerConn) Receive(msg any) error {
+ if err := hc.unmarshaler.Unmarshal(msg); err != nil {
+ return err // already coded
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *grpcHandlerConn) RequestHeader() http.Header {
+ return hc.request.Header
+}
+
+func (hc *grpcHandlerConn) Send(msg any) error {
+ defer flushResponseWriter(hc.responseWriter)
+ if !hc.wroteToBody {
+ mergeHeaders(hc.responseWriter.Header(), hc.responseHeader)
+ hc.wroteToBody = true
+ }
+ if err := hc.marshaler.Marshal(msg); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+}
+
+func (hc *grpcHandlerConn) ResponseHeader() http.Header {
+ return hc.responseHeader
+}
+
+func (hc *grpcHandlerConn) ResponseTrailer() http.Header {
+ return hc.responseTrailer
+}
+
+func (hc *grpcHandlerConn) Close(err error) (retErr error) {
+ defer func() {
+ // We don't want to copy unread portions of the body to /dev/null here: if
+ // the client hasn't closed the request body, we'll block until the server
+ // timeout kicks in. This could happen because the client is malicious, but
+ // a well-intentioned client may just not expect the server to be returning
+ // an error for a streaming RPC. Better to accept that we can't always reuse
+ // TCP connections.
+ closeErr := hc.request.Body.Close()
+ if retErr == nil {
+ retErr = closeErr
+ }
+ }()
+ defer flushResponseWriter(hc.responseWriter)
+ // If we haven't written the headers yet, do so.
+ if !hc.wroteToBody {
+ mergeHeaders(hc.responseWriter.Header(), hc.responseHeader)
+ }
+ // gRPC always sends the error's code, message, details, and metadata as
+ // trailing metadata. The Connect protocol doesn't do this, so we don't want
+ // to mutate the trailers map that the user sees.
+ mergedTrailers := make(
+ http.Header,
+ len(hc.responseTrailer)+2, // always make space for status & message
+ )
+ mergeHeaders(mergedTrailers, hc.responseTrailer)
+ grpcErrorToTrailer(mergedTrailers, hc.protobuf, err)
+ if hc.web && !hc.wroteToBody && len(hc.responseHeader) == 0 {
+ // We're using gRPC-Web, we haven't yet written to the body, and there are no
+ // custom headers. That means we can send a "trailers-only" response and send
+ // trailing metadata as HTTP headers (instead of as trailers).
+ mergeHeaders(hc.responseWriter.Header(), mergedTrailers)
+ return nil
+ }
+ if hc.web {
+ // We're using gRPC-Web and we've already sent the headers, so we write
+ // trailing metadata to the HTTP body.
+ if err := hc.marshaler.MarshalWebTrailers(mergedTrailers); err != nil {
+ return err
+ }
+ return nil // must be a literal nil: nil *Error is a non-nil error
+ }
+ // We're using standard gRPC. Even if we haven't written to the body and
+ // we're sending a "trailers-only" response, we must send trailing metadata
+ // as HTTP trailers. (If we had frame-level control of the HTTP/2 layer, we
+ // could send trailers-only responses as a single HEADER frame and no DATA
+ // frames, but net/http doesn't expose APIs that low-level.)
+ //
+ // In net/http's ResponseWriter API, we send HTTP trailers by writing to the
+ // headers map with a special prefix. This prefixing is an implementation
+ // detail, so we should hide it and _not_ mutate the user-visible headers.
+ //
+ // Note that this is _very_ finicky and difficult to test with net/http,
+ // since correctness depends on low-level framing details. Breaking this
+ // logic breaks Envoy's gRPC-Web translation.
+ for key, values := range mergedTrailers {
+ for _, value := range values {
+ // These are potentially user-supplied, so we can't assume they're in
+ // canonical form.
+ hc.responseWriter.Header().Add(http.TrailerPrefix+key, value)
+ }
+ }
+ return nil
+}
+
+type grpcMarshaler struct {
+ envelopeWriter
+}
+
+func (m *grpcMarshaler) MarshalWebTrailers(trailer http.Header) *Error {
+ raw := m.envelopeWriter.bufferPool.Get()
+ defer m.envelopeWriter.bufferPool.Put(raw)
+ for key, values := range trailer {
+ // Per the Go specification, keys inserted during iteration may be produced
+ // later in the iteration or may be skipped. For safety, avoid mutating the
+ // map if the key is already lower-cased.
+ lower := strings.ToLower(key)
+ if key == lower {
+ continue
+ }
+ delete(trailer, key)
+ trailer[lower] = values
+ }
+ if err := trailer.Write(raw); err != nil {
+ return errorf(CodeInternal, "format trailers: %w", err)
+ }
+ return m.Write(&envelope{
+ Data: raw,
+ Flags: grpcFlagEnvelopeTrailer,
+ })
+}
+
+type grpcUnmarshaler struct {
+ envelopeReader
+
+ web bool
+ webTrailer http.Header
+}
+
+func (u *grpcUnmarshaler) Unmarshal(message any) *Error {
+ err := u.envelopeReader.Unmarshal(message)
+ if err == nil {
+ return nil
+ }
+ if !errors.Is(err, errSpecialEnvelope) {
+ return err
+ }
+ env := u.last
+ data := env.Data
+ u.last.Data = nil // don't keep a reference to it
+ defer u.bufferPool.Put(data)
+ if !u.web || !env.IsSet(grpcFlagEnvelopeTrailer) {
+ return errorf(CodeInternal, "protocol error: invalid envelope flags %d", env.Flags)
+ }
+
+ // Per the gRPC-Web specification, trailers should be encoded as an HTTP/1
+ // headers block _without_ the terminating newline. To make the headers
+ // parseable by net/textproto, we need to add the newline.
+ if err := data.WriteByte('\n'); err != nil {
+ return errorf(CodeInternal, "unmarshal web trailers: %w", err)
+ }
+ bufferedReader := bufio.NewReader(data)
+ mimeReader := textproto.NewReader(bufferedReader)
+ mimeHeader, mimeErr := mimeReader.ReadMIMEHeader()
+ if mimeErr != nil {
+ return errorf(
+ CodeInternal,
+ "gRPC-Web protocol error: trailers invalid: %w",
+ mimeErr,
+ )
+ }
+ u.webTrailer = http.Header(mimeHeader)
+ return errSpecialEnvelope
+}
+
+func (u *grpcUnmarshaler) WebTrailer() http.Header {
+ return u.webTrailer
+}
+
+func grpcValidateResponse(
+ response *http.Response,
+ header http.Header,
+ availableCompressors readOnlyCompressionPools,
+ web bool,
+ codecName string,
+) *Error {
+ if response.StatusCode != http.StatusOK {
+ return errorf(httpToCode(response.StatusCode), "HTTP status %v", response.Status)
+ }
+ if err := grpcValidateResponseContentType(
+ web,
+ codecName,
+ getHeaderCanonical(response.Header, headerContentType),
+ ); err != nil {
+ return err
+ }
+ if compression := getHeaderCanonical(response.Header, grpcHeaderCompression); compression != "" &&
+ compression != compressionIdentity &&
+ !availableCompressors.Contains(compression) {
+ // Per https://github.com/grpc/grpc/blob/master/doc/compression.md, we
+ // should return CodeInternal and specify acceptable compression(s) (in
+ // addition to setting the Grpc-Accept-Encoding header).
+ return errorf(
+ CodeInternal,
+ "unknown encoding %q: accepted encodings are %v",
+ compression,
+ availableCompressors.CommaSeparatedNames(),
+ )
+ }
+ // The response is valid, so we should expose the headers.
+ mergeHeaders(header, response.Header)
+ return nil
+}
+
+// The gRPC wire protocol specifies that errors should be serialized using the
+// binary Protobuf format, even if the messages in the request/response stream
+// use a different codec. Consequently, this function needs a Protobuf codec to
+// unmarshal error information in the headers.
+//
+// A nil error is only returned when a grpc-status key IS present, but it
+// indicates a code of zero (no error). If no grpc-status key is present, this
+// returns a non-nil *Error that wraps errTrailersWithoutGRPCStatus.
+func grpcErrorFromTrailer(protobuf Codec, trailer http.Header) *Error {
+ codeHeader := getHeaderCanonical(trailer, grpcHeaderStatus)
+ if codeHeader == "" {
+ // If there are no trailers at all, that's an internal error.
+ // But if it's an error determining the status code from the
+ // trailers, it's unknown.
+ code := CodeUnknown
+ if len(trailer) == 0 {
+ code = CodeInternal
+ }
+ return NewError(code, errTrailersWithoutGRPCStatus)
+ }
+ if codeHeader == "0" {
+ return nil
+ }
+
+ code, err := strconv.ParseUint(codeHeader, 10 /* base */, 32 /* bitsize */)
+ if err != nil {
+ return errorf(CodeUnknown, "protocol error: invalid error code %q", codeHeader)
+ }
+ message, err := grpcPercentDecode(getHeaderCanonical(trailer, grpcHeaderMessage))
+ if err != nil {
+ return errorf(CodeInternal, "protocol error: invalid error message %q", message)
+ }
+ retErr := NewWireError(Code(code), errors.New(message))
+
+ detailsBinaryEncoded := getHeaderCanonical(trailer, grpcHeaderDetails)
+ if len(detailsBinaryEncoded) > 0 {
+ detailsBinary, err := DecodeBinaryHeader(detailsBinaryEncoded)
+ if err != nil {
+ return errorf(CodeInternal, "server returned invalid grpc-status-details-bin trailer: %w", err)
+ }
+ var status statusv1.Status
+ if err := protobuf.Unmarshal(detailsBinary, &status); err != nil {
+ return errorf(CodeInternal, "server returned invalid protobuf for error details: %w", err)
+ }
+ for _, d := range status.GetDetails() {
+ retErr.details = append(retErr.details, &ErrorDetail{pbAny: d})
+ }
+ // Prefer the Protobuf-encoded data to the headers (grpc-go does this too).
+ retErr.code = Code(status.GetCode())
+ retErr.err = errors.New(status.GetMessage())
+ }
+
+ return retErr
+}
+
+func grpcParseTimeout(timeout string) (time.Duration, error) {
+ if timeout == "" {
+ return 0, errNoTimeout
+ }
+ unit, err := grpcTimeoutUnitLookup(timeout[len(timeout)-1])
+ if err != nil {
+ return 0, err
+ }
+ num, err := strconv.ParseInt(timeout[:len(timeout)-1], 10 /* base */, 64 /* bitsize */)
+ if err != nil || num < 0 {
+ return 0, fmt.Errorf("protocol error: invalid timeout %q", timeout)
+ }
+ if num > 99999999 { // timeout must be ASCII string of at most 8 digits
+ return 0, fmt.Errorf("protocol error: timeout %q is too long", timeout)
+ }
+ const grpcTimeoutMaxHours = math.MaxInt64 / int64(time.Hour) // how many hours fit into a time.Duration?
+ if unit == time.Hour && num > grpcTimeoutMaxHours {
+ // Timeout is effectively unbounded, so ignore it. The grpc-go
+ // implementation does the same thing.
+ return 0, errNoTimeout
+ }
+ return time.Duration(num) * unit, nil
+}
+
+func grpcEncodeTimeout(timeout time.Duration) string {
+ if timeout <= 0 {
+ return "0n"
+ }
+ // The gRPC protocol limits timeouts to 8 characters (not counting the unit),
+ // so timeouts must be strictly less than 1e8 of the appropriate unit.
+ const grpcTimeoutMaxValue = 1e8
+ var (
+ size time.Duration
+ unit byte
+ )
+ switch {
+ case timeout < time.Nanosecond*grpcTimeoutMaxValue:
+ size, unit = time.Nanosecond, 'n'
+ case timeout < time.Microsecond*grpcTimeoutMaxValue:
+ size, unit = time.Microsecond, 'u'
+ case timeout < time.Millisecond*grpcTimeoutMaxValue:
+ size, unit = time.Millisecond, 'm'
+ case timeout < time.Second*grpcTimeoutMaxValue:
+ size, unit = time.Second, 'S'
+ case timeout < time.Minute*grpcTimeoutMaxValue:
+ size, unit = time.Minute, 'M'
+ default:
+ // time.Duration is an int64 number of nanoseconds, so the largest
+ // expressible duration is less than 1e8 hours.
+ size, unit = time.Hour, 'H'
+ }
+ buf := make([]byte, 0, 9)
+ buf = strconv.AppendInt(buf, int64(timeout/size), 10 /* base */)
+ buf = append(buf, unit)
+ return string(buf)
+}
+
+func grpcTimeoutUnitLookup(unit byte) (time.Duration, error) {
+ switch unit {
+ case 'n':
+ return time.Nanosecond, nil
+ case 'u':
+ return time.Microsecond, nil
+ case 'm':
+ return time.Millisecond, nil
+ case 'S':
+ return time.Second, nil
+ case 'M':
+ return time.Minute, nil
+ case 'H':
+ return time.Hour, nil
+ default:
+ return 0, fmt.Errorf("protocol error: timeout has invalid unit %q", unit)
+ }
+}
+
+func grpcCodecFromContentType(web bool, contentType string) string {
+ if (!web && contentType == grpcContentTypeDefault) || (web && contentType == grpcWebContentTypeDefault) {
+ // implicitly protobuf
+ return codecNameProto
+ }
+ prefix := grpcContentTypePrefix
+ if web {
+ prefix = grpcWebContentTypePrefix
+ }
+ return strings.TrimPrefix(contentType, prefix)
+}
+
+func grpcContentTypeFromCodecName(web bool, name string) string {
+ if web {
+ return grpcWebContentTypePrefix + name
+ }
+ if name == codecNameProto {
+ // For compatibility with Google Cloud Platform's frontends, prefer an
+ // implicit default codec. See
+ // https://github.com/connectrpc/connect-go/pull/655#issuecomment-1915754523
+ // for details.
+ return grpcContentTypeDefault
+ }
+ return grpcContentTypePrefix + name
+}
+
+func grpcErrorToTrailer(trailer http.Header, protobuf Codec, err error) {
+ if err == nil {
+ setHeaderCanonical(trailer, grpcHeaderStatus, "0") // zero is the gRPC OK status
+ return
+ }
+ if connectErr, ok := asError(err); ok && !connectErr.wireErr {
+ mergeMetadataHeaders(trailer, connectErr.meta)
+ }
+ var (
+ status = grpcStatusFromError(err)
+ code = status.GetCode()
+ message = status.GetMessage()
+ bin []byte
+ )
+ if len(status.Details) > 0 {
+ var binErr error
+ bin, binErr = protobuf.Marshal(status)
+ if binErr != nil {
+ code = int32(CodeInternal)
+ message = fmt.Sprintf("marshal protobuf status: %v", binErr)
+ }
+ }
+ setHeaderCanonical(trailer, grpcHeaderStatus, strconv.Itoa(int(code)))
+ setHeaderCanonical(trailer, grpcHeaderMessage, grpcPercentEncode(message))
+ if len(bin) > 0 {
+ setHeaderCanonical(trailer, grpcHeaderDetails, EncodeBinaryHeader(bin))
+ }
+}
+
+func grpcStatusFromError(err error) *statusv1.Status {
+ status := &statusv1.Status{
+ Code: int32(CodeUnknown),
+ Message: err.Error(),
+ }
+ if connectErr, ok := asError(err); ok {
+ status.Code = int32(connectErr.Code())
+ status.Message = connectErr.Message()
+ status.Details = connectErr.detailsAsAny()
+ }
+ return status
+}
+
+// grpcPercentEncode follows RFC 3986 Section 2.1 and the gRPC HTTP/2 spec.
+// It's a variant of URL-encoding with fewer reserved characters. It's intended
+// to take UTF-8 encoded text and escape non-ASCII bytes so that they're valid
+// HTTP/1 headers, while still maximizing readability of the data on the wire.
+//
+// The grpc-message trailer (used for human-readable error messages) should be
+// percent-encoded.
+//
+// References:
+//
+// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses
+// https://datatracker.ietf.org/doc/html/rfc3986#section-2.1
+func grpcPercentEncode(msg string) string {
+ var hexCount int
+ for i := 0; i < len(msg); i++ {
+ if grpcShouldEscape(msg[i]) {
+ hexCount++
+ }
+ }
+ if hexCount == 0 {
+ return msg
+ }
+ // We need to escape some characters, so we'll need to allocate a new string.
+ var out strings.Builder
+ out.Grow(len(msg) + 2*hexCount)
+ for i := 0; i < len(msg); i++ {
+ switch char := msg[i]; {
+ case grpcShouldEscape(char):
+ out.WriteByte('%')
+ out.WriteByte(upperhex[char>>4])
+ out.WriteByte(upperhex[char&15])
+ default:
+ out.WriteByte(char)
+ }
+ }
+ return out.String()
+}
+
+func grpcPercentDecode(input string) (string, error) {
+ percentCount := 0
+ for i := 0; i < len(input); {
+ switch input[i] {
+ case '%':
+ percentCount++
+ if err := validateHex(input[i:]); err != nil {
+ return "", err
+ }
+ i += 3
+ default:
+ i++
+ }
+ }
+ if percentCount == 0 {
+ return input, nil
+ }
+ // We need to unescape some characters, so we'll need to allocate a new string.
+ var out strings.Builder
+ out.Grow(len(input) - 2*percentCount)
+ for i := 0; i < len(input); i++ {
+ switch input[i] {
+ case '%':
+ out.WriteByte(unhex(input[i+1])<<4 | unhex(input[i+2]))
+ i += 2
+ default:
+ out.WriteByte(input[i])
+ }
+ }
+ return out.String(), nil
+}
+
+// Characters that need to be escaped are defined in gRPC's HTTP/2 spec.
+// They're different from the generic set defined in RFC 3986.
+func grpcShouldEscape(char byte) bool {
+ return char < ' ' || char > '~' || char == '%'
+}
+
+func unhex(char byte) byte {
+ switch {
+ case '0' <= char && char <= '9':
+ return char - '0'
+ case 'a' <= char && char <= 'f':
+ return char - 'a' + 10
+ case 'A' <= char && char <= 'F':
+ return char - 'A' + 10
+ }
+ return 0
+}
+
+func isHex(char byte) bool {
+ return ('0' <= char && char <= '9') || ('a' <= char && char <= 'f') || ('A' <= char && char <= 'F')
+}
+
+func validateHex(input string) error {
+ if len(input) < 3 || input[0] != '%' || !isHex(input[1]) || !isHex(input[2]) {
+ if len(input) > 3 {
+ input = input[:3]
+ }
+ return fmt.Errorf("invalid percent-encoded string %q", input)
+ }
+ return nil
+}
+
+func grpcValidateResponseContentType(web bool, requestCodecName string, responseContentType string) *Error {
+ // Responses must have valid content-type that indicates same codec as the request.
+ bare, prefix := grpcContentTypeDefault, grpcContentTypePrefix
+ if web {
+ bare, prefix = grpcWebContentTypeDefault, grpcWebContentTypePrefix
+ }
+ if responseContentType == prefix+requestCodecName ||
+ (requestCodecName == codecNameProto && responseContentType == bare) {
+ return nil
+ }
+ expectedContentType := bare
+ if requestCodecName != codecNameProto {
+ expectedContentType = prefix + requestCodecName
+ }
+ code := CodeInternal
+ if responseContentType != bare && !strings.HasPrefix(responseContentType, prefix) {
+ // Doesn't even look like a gRPC response? Use code "unknown".
+ code = CodeUnknown
+ }
+ return errorf(
+ code,
+ "invalid content-type: %q; expecting %q",
+ responseContentType,
+ expectedContentType,
+ )
+}
diff --git a/vendor/connectrpc.com/connect/recover.go b/vendor/connectrpc.com/connect/recover.go
new file mode 100644
index 0000000..72f535e
--- /dev/null
+++ b/vendor/connectrpc.com/connect/recover.go
@@ -0,0 +1,80 @@
+// Copyright 2021-2024 The Connect Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package connect
+
+import (
+ "context"
+ "net/http"
+)
+
+// recoverHandlerInterceptor lets handlers trap panics, perform side effects
+// (like emitting logs or metrics), and present a friendlier error message to
+// clients.
+//
+// This interceptor uses a somewhat unusual strategy to recover from panics.
+// The standard recovery idiom:
+//
+// if r := recover(); r != nil { ... }
+//
+// isn't robust in the face of user error, because it doesn't handle
+// panic(nil). This occasionally happens by mistake, and it's a beast to debug
+// without a more robust idiom. See https://github.com/golang/go/issues/25448
+// for details.
+type recoverHandlerInterceptor struct {
+ Interceptor
+
+ handle func(context.Context, Spec, http.Header, any) error
+}
+
+func (i *recoverHandlerInterceptor) WrapUnary(next UnaryFunc) UnaryFunc {
+ return func(ctx context.Context, req AnyRequest) (_ AnyResponse, retErr error) {
+ if req.Spec().IsClient {
+ return next(ctx, req)
+ }
+ panicked := true
+ defer func() {
+ if panicked {
+ r := recover()
+ // net/http checks for ErrAbortHandler with ==, so we should too.
+ if r == http.ErrAbortHandler { //nolint:errorlint,goerr113
+ panic(r) //nolint:forbidigo
+ }
+ retErr = i.handle(ctx, req.Spec(), req.Header(), r)
+ }
+ }()
+ res, err := next(ctx, req)
+ panicked = false
+ return res, err
+ }
+}
+
+func (i *recoverHandlerInterceptor) WrapStreamingHandler(next StreamingHandlerFunc) StreamingHandlerFunc {
+ return func(ctx context.Context, conn StreamingHandlerConn) (retErr error) {
+ panicked := true
+ defer func() {
+ if panicked {
+ r := recover()
+ // net/http checks for ErrAbortHandler with ==, so we should too.
+ if r == http.ErrAbortHandler { //nolint:errorlint,goerr113
+ panic(r) //nolint:forbidigo
+ }
+ retErr = i.handle(ctx, Spec{}, nil, r)
+ }
+ }()
+ err := next(ctx, conn)
+ panicked = false
+ return err
+ }
+}
diff --git a/vendor/dario.cat/mergo/.deepsource.toml b/vendor/dario.cat/mergo/.deepsource.toml
new file mode 100644
index 0000000..a8bc979
--- /dev/null
+++ b/vendor/dario.cat/mergo/.deepsource.toml
@@ -0,0 +1,12 @@
+version = 1
+
+test_patterns = [
+ "*_test.go"
+]
+
+[[analyzers]]
+name = "go"
+enabled = true
+
+ [analyzers.meta]
+ import_path = "dario.cat/mergo"
\ No newline at end of file
diff --git a/vendor/dario.cat/mergo/.gitignore b/vendor/dario.cat/mergo/.gitignore
new file mode 100644
index 0000000..529c341
--- /dev/null
+++ b/vendor/dario.cat/mergo/.gitignore
@@ -0,0 +1,33 @@
+#### joe made this: http://goel.io/joe
+
+#### go ####
+# Binaries for programs and plugins
+*.exe
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
+.glide/
+
+#### vim ####
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-v][a-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+
+# Temporary
+.netrwhist
+*~
+# Auto-generated tag files
+tags
diff --git a/vendor/dario.cat/mergo/.travis.yml b/vendor/dario.cat/mergo/.travis.yml
new file mode 100644
index 0000000..d324c43
--- /dev/null
+++ b/vendor/dario.cat/mergo/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+arch:
+ - amd64
+ - ppc64le
+install:
+ - go get -t
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+script:
+ - go test -race -v ./...
+after_script:
+ - $HOME/gopath/bin/goveralls -service=travis-ci -repotoken $COVERALLS_TOKEN
diff --git a/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md b/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..469b449
--- /dev/null
+++ b/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at i@dario.im. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/dario.cat/mergo/CONTRIBUTING.md b/vendor/dario.cat/mergo/CONTRIBUTING.md
new file mode 100644
index 0000000..0a1ff9f
--- /dev/null
+++ b/vendor/dario.cat/mergo/CONTRIBUTING.md
@@ -0,0 +1,112 @@
+
+# Contributing to mergo
+
+First off, thanks for taking the time to contribute! ❤️
+
+All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
+
+> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
+> - Star the project
+> - Tweet about it
+> - Refer this project in your project's readme
+> - Mention the project at local meetups and tell your friends/colleagues
+
+
+## Table of Contents
+
+- [Code of Conduct](#code-of-conduct)
+- [I Have a Question](#i-have-a-question)
+- [I Want To Contribute](#i-want-to-contribute)
+- [Reporting Bugs](#reporting-bugs)
+- [Suggesting Enhancements](#suggesting-enhancements)
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by the
+[mergo Code of Conduct](https://github.com/imdario/mergoblob/master/CODE_OF_CONDUCT.md).
+By participating, you are expected to uphold this code. Please report unacceptable behavior
+to <>.
+
+
+## I Have a Question
+
+> If you want to ask a question, we assume that you have read the available [Documentation](https://pkg.go.dev/github.com/imdario/mergo).
+
+Before you ask a question, it is best to search for existing [Issues](https://github.com/imdario/mergo/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
+
+If you then still feel the need to ask a question and need clarification, we recommend the following:
+
+- Open an [Issue](https://github.com/imdario/mergo/issues/new).
+- Provide as much context as you can about what you're running into.
+- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.
+
+We will then take care of the issue as soon as possible.
+
+## I Want To Contribute
+
+> ### Legal Notice
+> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
+
+### Reporting Bugs
+
+
+#### Before Submitting a Bug Report
+
+A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
+
+- Make sure that you are using the latest version.
+- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)).
+- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/imdario/mergoissues?q=label%3Abug).
+- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
+- Collect information about the bug:
+- Stack trace (Traceback)
+- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
+- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
+- Possibly your input and the output
+- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
+
+
+#### How Do I Submit a Good Bug Report?
+
+> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to .
+
+
+We use GitHub issues to track bugs and errors. If you run into an issue with the project:
+
+- Open an [Issue](https://github.com/imdario/mergo/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
+- Explain the behavior you would expect and the actual behavior.
+- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
+- Provide the information you collected in the previous section.
+
+Once it's filed:
+
+- The project team will label the issue accordingly.
+- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
+- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be implemented by someone.
+
+### Suggesting Enhancements
+
+This section guides you through submitting an enhancement suggestion for mergo, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
+
+
+#### Before Submitting an Enhancement
+
+- Make sure that you are using the latest version.
+- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration.
+- Perform a [search](https://github.com/imdario/mergo/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
+- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
+
+
+#### How Do I Submit a Good Enhancement Suggestion?
+
+Enhancement suggestions are tracked as [GitHub issues](https://github.com/imdario/mergo/issues).
+
+- Use a **clear and descriptive title** for the issue to identify the suggestion.
+- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
+- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
+- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
+- **Explain why this enhancement would be useful** to most mergo users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
+
+
+## Attribution
+This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!
diff --git a/vendor/dario.cat/mergo/LICENSE b/vendor/dario.cat/mergo/LICENSE
new file mode 100644
index 0000000..6866802
--- /dev/null
+++ b/vendor/dario.cat/mergo/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2013 Dario Castañé. All rights reserved.
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/dario.cat/mergo/README.md b/vendor/dario.cat/mergo/README.md
new file mode 100644
index 0000000..7d0cf9f
--- /dev/null
+++ b/vendor/dario.cat/mergo/README.md
@@ -0,0 +1,248 @@
+# Mergo
+
+[![GitHub release][5]][6]
+[![GoCard][7]][8]
+[![Test status][1]][2]
+[![OpenSSF Scorecard][21]][22]
+[![OpenSSF Best Practices][19]][20]
+[![Coverage status][9]][10]
+[![Sourcegraph][11]][12]
+[![FOSSA status][13]][14]
+
+[![GoDoc][3]][4]
+[![Become my sponsor][15]][16]
+[![Tidelift][17]][18]
+
+[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master
+[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml
+[3]: https://godoc.org/github.com/imdario/mergo?status.svg
+[4]: https://godoc.org/github.com/imdario/mergo
+[5]: https://img.shields.io/github/release/imdario/mergo.svg
+[6]: https://github.com/imdario/mergo/releases
+[7]: https://goreportcard.com/badge/imdario/mergo
+[8]: https://goreportcard.com/report/github.com/imdario/mergo
+[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
+[10]: https://coveralls.io/github/imdario/mergo?branch=master
+[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
+[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
+[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
+[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
+[15]: https://img.shields.io/github/sponsors/imdario
+[16]: https://github.com/sponsors/imdario
+[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo
+[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo
+[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge
+[20]: https://bestpractices.coreinfrastructure.org/projects/7177
+[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge
+[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo
+
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
+
+## Status
+
+It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
+
+### Important notes
+
+#### 1.0.0
+
+In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`.
+
+#### 0.3.9
+
+Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.
+
+Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u dario.cat/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+### Donations
+
+If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
+
+
+
+
+
+### Mergo in the wild
+
+- [moby/moby](https://github.com/moby/moby)
+- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
+- [vmware/dispatch](https://github.com/vmware/dispatch)
+- [Shopify/themekit](https://github.com/Shopify/themekit)
+- [imdario/zas](https://github.com/imdario/zas)
+- [matcornic/hermes](https://github.com/matcornic/hermes)
+- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
+- [kataras/iris](https://github.com/kataras/iris)
+- [michaelsauter/crane](https://github.com/michaelsauter/crane)
+- [go-task/task](https://github.com/go-task/task)
+- [sensu/uchiwa](https://github.com/sensu/uchiwa)
+- [ory/hydra](https://github.com/ory/hydra)
+- [sisatech/vcli](https://github.com/sisatech/vcli)
+- [dairycart/dairycart](https://github.com/dairycart/dairycart)
+- [projectcalico/felix](https://github.com/projectcalico/felix)
+- [resin-os/balena](https://github.com/resin-os/balena)
+- [go-kivik/kivik](https://github.com/go-kivik/kivik)
+- [Telefonica/govice](https://github.com/Telefonica/govice)
+- [supergiant/supergiant](supergiant/supergiant)
+- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
+- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
+- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
+- [EagerIO/Stout](https://github.com/EagerIO/Stout)
+- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
+- [russross/canvasassignments](https://github.com/russross/canvasassignments)
+- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
+- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
+- [divshot/gitling](https://github.com/divshot/gitling)
+- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
+- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
+- [elwinar/rambler](https://github.com/elwinar/rambler)
+- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
+- [jfbus/impressionist](https://github.com/jfbus/impressionist)
+- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
+- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
+- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
+- [thoas/picfit](https://github.com/thoas/picfit)
+- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
+- [jnuthong/item_search](https://github.com/jnuthong/item_search)
+- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
+- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
+- [tjpnz/structbot](https://github.com/tjpnz/structbot)
+
+## Install
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+## Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+```go
+if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+}
+```
+
+Also, you can merge overwriting values using the transformer `WithOverride`.
+
+```go
+if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+}
+```
+
+Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
+
+```go
+if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+}
+```
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
+
+Here is a nice example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+)
+
+type Foo struct {
+ A string
+ B int64
+}
+
+func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+}
+```
+
+Note: if test are failing due missing package, please execute:
+
+ go get gopkg.in/yaml.v3
+
+### Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+)
+
+type timeTransformer struct {
+}
+
+func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+}
+
+type Snapshot struct {
+ Time time.Time
+ // ...
+}
+
+func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+}
+```
+
+## Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)
+
+## About
+
+Written by [Dario Castañé](http://dario.im).
+
+## License
+
+[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).
+
+[](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)
diff --git a/vendor/dario.cat/mergo/SECURITY.md b/vendor/dario.cat/mergo/SECURITY.md
new file mode 100644
index 0000000..a5de61f
--- /dev/null
+++ b/vendor/dario.cat/mergo/SECURITY.md
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| 0.3.x | :white_check_mark: |
+| < 0.3 | :x: |
+
+## Security contact information
+
+To report a security vulnerability, please use the
+[Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
diff --git a/vendor/dario.cat/mergo/doc.go b/vendor/dario.cat/mergo/doc.go
new file mode 100644
index 0000000..7d96ec0
--- /dev/null
+++ b/vendor/dario.cat/mergo/doc.go
@@ -0,0 +1,148 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+# Status
+
+It is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.
+
+# Important notes
+
+1.0.0
+
+In 1.0.0 Mergo moves to a vanity URL `dario.cat/mergo`.
+
+0.3.9
+
+Please keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.
+
+Keep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u dario.cat/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+# Install
+
+Do your usual installation procedure:
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+# Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+ if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+ }
+
+Also, you can merge overwriting values using the transformer WithOverride.
+
+ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+ }
+
+Additionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.
+
+ if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+ }
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
+
+Here is a nice example:
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ )
+
+ type Foo struct {
+ A string
+ B int64
+ }
+
+ func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+ }
+
+# Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+ )
+
+ type timeTransformer struct {
+ }
+
+ func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+ }
+
+ type Snapshot struct {
+ Time time.Time
+ // ...
+ }
+
+ func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+ }
+
+# Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario
+
+# About
+
+Written by Dario Castañé: https://da.rio.hn
+
+# License
+
+BSD 3-Clause license, as Go language.
+*/
+package mergo
diff --git a/vendor/dario.cat/mergo/map.go b/vendor/dario.cat/mergo/map.go
new file mode 100644
index 0000000..b50d5c2
--- /dev/null
+++ b/vendor/dario.cat/mergo/map.go
@@ -0,0 +1,178 @@
+// Copyright 2014 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "fmt"
+ "reflect"
+ "unicode"
+ "unicode/utf8"
+)
+
+func changeInitialCase(s string, mapper func(rune) rune) string {
+ if s == "" {
+ return s
+ }
+ r, n := utf8.DecodeRuneInString(s)
+ return string(mapper(r)) + s[n:]
+}
+
+func isExported(field reflect.StructField) bool {
+ r, _ := utf8.DecodeRuneInString(field.Name)
+ return r >= 'A' && r <= 'Z'
+}
+
+// Traverses recursively both values, assigning src's fields values to dst.
+// The map argument tracks comparisons that have already been seen, which allows
+// short circuiting on recursive types.
+func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
+ overwrite := config.Overwrite
+ if dst.CanAddr() {
+ addr := dst.UnsafeAddr()
+ h := 17 * addr
+ seen := visited[h]
+ typ := dst.Type()
+ for p := seen; p != nil; p = p.next {
+ if p.ptr == addr && p.typ == typ {
+ return nil
+ }
+ }
+ // Remember, remember...
+ visited[h] = &visit{typ, seen, addr}
+ }
+ zeroValue := reflect.Value{}
+ switch dst.Kind() {
+ case reflect.Map:
+ dstMap := dst.Interface().(map[string]interface{})
+ for i, n := 0, src.NumField(); i < n; i++ {
+ srcType := src.Type()
+ field := srcType.Field(i)
+ if !isExported(field) {
+ continue
+ }
+ fieldName := field.Name
+ fieldName = changeInitialCase(fieldName, unicode.ToLower)
+ if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
+ dstMap[fieldName] = src.Field(i).Interface()
+ }
+ }
+ case reflect.Ptr:
+ if dst.IsNil() {
+ v := reflect.New(dst.Type().Elem())
+ dst.Set(v)
+ }
+ dst = dst.Elem()
+ fallthrough
+ case reflect.Struct:
+ srcMap := src.Interface().(map[string]interface{})
+ for key := range srcMap {
+ config.overwriteWithEmptyValue = true
+ srcValue := srcMap[key]
+ fieldName := changeInitialCase(key, unicode.ToUpper)
+ dstElement := dst.FieldByName(fieldName)
+ if dstElement == zeroValue {
+ // We discard it because the field doesn't exist.
+ continue
+ }
+ srcElement := reflect.ValueOf(srcValue)
+ dstKind := dstElement.Kind()
+ srcKind := srcElement.Kind()
+ if srcKind == reflect.Ptr && dstKind != reflect.Ptr {
+ srcElement = srcElement.Elem()
+ srcKind = reflect.TypeOf(srcElement.Interface()).Kind()
+ } else if dstKind == reflect.Ptr {
+ // Can this work? I guess it can't.
+ if srcKind != reflect.Ptr && srcElement.CanAddr() {
+ srcPtr := srcElement.Addr()
+ srcElement = reflect.ValueOf(srcPtr)
+ srcKind = reflect.Ptr
+ }
+ }
+
+ if !srcElement.IsValid() {
+ continue
+ }
+ if srcKind == dstKind {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if srcKind == reflect.Map {
+ if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind)
+ }
+ }
+ }
+ return
+}
+
+// Map sets fields' values in dst from src.
+// src can be a map with string keys or a struct. dst must be the opposite:
+// if src is a map, dst must be a valid pointer to struct. If src is a struct,
+// dst must be map[string]interface{}.
+// It won't merge unexported (private) fields and will do recursively
+// any exported field.
+// If dst is a map, keys will be src fields' names in lower camel case.
+// Missing key in src that doesn't match a field in dst will be skipped. This
+// doesn't apply if dst is a map.
+// This is separated method from Merge because it is cleaner and it keeps sane
+// semantics: merging equal types, mapping different (restricted) types.
+func Map(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, opts...)
+}
+
+// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by
+// non-empty src attribute values.
+// Deprecated: Use Map(…) with WithOverride
+func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, append(opts, WithOverride)...)
+}
+
+func _map(dst, src interface{}, opts ...func(*Config)) error {
+ if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
+ return ErrNonPointerArgument
+ }
+ var (
+ vDst, vSrc reflect.Value
+ err error
+ )
+ config := &Config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if vDst, vSrc, err = resolveValues(dst, src); err != nil {
+ return err
+ }
+ // To be friction-less, we redirect equal-type arguments
+ // to deepMerge. Only because arguments can be anything.
+ if vSrc.Kind() == vDst.Kind() {
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+ }
+ switch vSrc.Kind() {
+ case reflect.Struct:
+ if vDst.Kind() != reflect.Map {
+ return ErrExpectedMapAsDestination
+ }
+ case reflect.Map:
+ if vDst.Kind() != reflect.Struct {
+ return ErrExpectedStructAsDestination
+ }
+ default:
+ return ErrNotSupported
+ }
+ return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+}
diff --git a/vendor/dario.cat/mergo/merge.go b/vendor/dario.cat/mergo/merge.go
new file mode 100644
index 0000000..0ef9b21
--- /dev/null
+++ b/vendor/dario.cat/mergo/merge.go
@@ -0,0 +1,409 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func hasMergeableFields(dst reflect.Value) (exported bool) {
+ for i, n := 0, dst.NumField(); i < n; i++ {
+ field := dst.Type().Field(i)
+ if field.Anonymous && dst.Field(i).Kind() == reflect.Struct {
+ exported = exported || hasMergeableFields(dst.Field(i))
+ } else if isExportedComponent(&field) {
+ exported = exported || len(field.PkgPath) == 0
+ }
+ }
+ return
+}
+
+func isExportedComponent(field *reflect.StructField) bool {
+ pkgPath := field.PkgPath
+ if len(pkgPath) > 0 {
+ return false
+ }
+ c := field.Name[0]
+ if 'a' <= c && c <= 'z' || c == '_' {
+ return false
+ }
+ return true
+}
+
+type Config struct {
+ Transformers Transformers
+ Overwrite bool
+ ShouldNotDereference bool
+ AppendSlice bool
+ TypeCheck bool
+ overwriteWithEmptyValue bool
+ overwriteSliceWithEmptyValue bool
+ sliceDeepCopy bool
+ debug bool
+}
+
+type Transformers interface {
+ Transformer(reflect.Type) func(dst, src reflect.Value) error
+}
+
+// Traverses recursively both values, assigning src's fields values to dst.
+// The map argument tracks comparisons that have already been seen, which allows
+// short circuiting on recursive types.
+func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
+ overwrite := config.Overwrite
+ typeCheck := config.TypeCheck
+ overwriteWithEmptySrc := config.overwriteWithEmptyValue
+ overwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue
+ sliceDeepCopy := config.sliceDeepCopy
+
+ if !src.IsValid() {
+ return
+ }
+ if dst.CanAddr() {
+ addr := dst.UnsafeAddr()
+ h := 17 * addr
+ seen := visited[h]
+ typ := dst.Type()
+ for p := seen; p != nil; p = p.next {
+ if p.ptr == addr && p.typ == typ {
+ return nil
+ }
+ }
+ // Remember, remember...
+ visited[h] = &visit{typ, seen, addr}
+ }
+
+ if config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() {
+ if fn := config.Transformers.Transformer(dst.Type()); fn != nil {
+ err = fn(dst, src)
+ return
+ }
+ }
+
+ switch dst.Kind() {
+ case reflect.Struct:
+ if hasMergeableFields(dst) {
+ for i, n := 0, dst.NumField(); i < n; i++ {
+ if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil {
+ return
+ }
+ }
+ } else {
+ if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) {
+ dst.Set(src)
+ }
+ }
+ case reflect.Map:
+ if dst.IsNil() && !src.IsNil() {
+ if dst.CanSet() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ } else {
+ dst = src
+ return
+ }
+ }
+
+ if src.Kind() != reflect.Map {
+ if overwrite && dst.CanSet() {
+ dst.Set(src)
+ }
+ return
+ }
+
+ for _, key := range src.MapKeys() {
+ srcElement := src.MapIndex(key)
+ if !srcElement.IsValid() {
+ continue
+ }
+ dstElement := dst.MapIndex(key)
+ switch srcElement.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Map, reflect.Interface, reflect.Slice:
+ if srcElement.IsNil() {
+ if overwrite {
+ dst.SetMapIndex(key, srcElement)
+ }
+ continue
+ }
+ fallthrough
+ default:
+ if !srcElement.CanInterface() {
+ continue
+ }
+ switch reflect.TypeOf(srcElement.Interface()).Kind() {
+ case reflect.Struct:
+ fallthrough
+ case reflect.Ptr:
+ fallthrough
+ case reflect.Map:
+ srcMapElm := srcElement
+ dstMapElm := dstElement
+ if srcMapElm.CanInterface() {
+ srcMapElm = reflect.ValueOf(srcMapElm.Interface())
+ if dstMapElm.IsValid() {
+ dstMapElm = reflect.ValueOf(dstMapElm.Interface())
+ }
+ }
+ if err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil {
+ return
+ }
+ case reflect.Slice:
+ srcSlice := reflect.ValueOf(srcElement.Interface())
+
+ var dstSlice reflect.Value
+ if !dstElement.IsValid() || dstElement.IsNil() {
+ dstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len())
+ } else {
+ dstSlice = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy {
+ if typeCheck && srcSlice.Type() != dstSlice.Type() {
+ return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
+ }
+ dstSlice = srcSlice
+ } else if config.AppendSlice {
+ if srcSlice.Type() != dstSlice.Type() {
+ return fmt.Errorf("cannot append two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
+ }
+ dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
+ } else if sliceDeepCopy {
+ i := 0
+ for ; i < srcSlice.Len() && i < dstSlice.Len(); i++ {
+ srcElement := srcSlice.Index(i)
+ dstElement := dstSlice.Index(i)
+
+ if srcElement.CanInterface() {
+ srcElement = reflect.ValueOf(srcElement.Interface())
+ }
+ if dstElement.CanInterface() {
+ dstElement = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ }
+
+ }
+ dst.SetMapIndex(key, dstSlice)
+ }
+ }
+
+ if dstElement.IsValid() && !isEmptyValue(dstElement, !config.ShouldNotDereference) {
+ if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice {
+ continue
+ }
+ if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map {
+ continue
+ }
+ }
+
+ if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement, !config.ShouldNotDereference)) {
+ if dst.IsNil() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ }
+ dst.SetMapIndex(key, srcElement)
+ }
+ }
+
+ // Ensure that all keys in dst are deleted if they are not in src.
+ if overwriteWithEmptySrc {
+ for _, key := range dst.MapKeys() {
+ srcElement := src.MapIndex(key)
+ if !srcElement.IsValid() {
+ dst.SetMapIndex(key, reflect.Value{})
+ }
+ }
+ }
+ case reflect.Slice:
+ if !dst.CanSet() {
+ break
+ }
+ if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy {
+ dst.Set(src)
+ } else if config.AppendSlice {
+ if src.Type() != dst.Type() {
+ return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type())
+ }
+ dst.Set(reflect.AppendSlice(dst, src))
+ } else if sliceDeepCopy {
+ for i := 0; i < src.Len() && i < dst.Len(); i++ {
+ srcElement := src.Index(i)
+ dstElement := dst.Index(i)
+ if srcElement.CanInterface() {
+ srcElement = reflect.ValueOf(srcElement.Interface())
+ }
+ if dstElement.CanInterface() {
+ dstElement = reflect.ValueOf(dstElement.Interface())
+ }
+
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ }
+ }
+ case reflect.Ptr:
+ fallthrough
+ case reflect.Interface:
+ if isReflectNil(src) {
+ if overwriteWithEmptySrc && dst.CanSet() && src.Type().AssignableTo(dst.Type()) {
+ dst.Set(src)
+ }
+ break
+ }
+
+ if src.Kind() != reflect.Interface {
+ if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) {
+ if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) {
+ dst.Set(src)
+ }
+ } else if src.Kind() == reflect.Ptr {
+ if !config.ShouldNotDereference {
+ if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
+ dst.Set(src)
+ }
+ }
+ } else if dst.Elem().Type() == src.Type() {
+ if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ return ErrDifferentArgumentsTypes
+ }
+ break
+ }
+
+ if dst.IsNil() || overwrite {
+ if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) {
+ dst.Set(src)
+ }
+ break
+ }
+
+ if dst.Elem().Kind() == src.Elem().Kind() {
+ if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
+ return
+ }
+ break
+ }
+ default:
+ mustSet := (isEmptyValue(dst, !config.ShouldNotDereference) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc)
+ if mustSet {
+ if dst.CanSet() {
+ dst.Set(src)
+ } else {
+ dst = src
+ }
+ }
+ }
+
+ return
+}
+
+// Merge will fill any empty for value type attributes on the dst struct using corresponding
+// src attributes if they themselves are not empty. dst and src must be valid same-type structs
+// and dst must be a pointer to struct.
+// It won't merge unexported (private) fields and will do recursively any exported field.
+func Merge(dst, src interface{}, opts ...func(*Config)) error {
+ return merge(dst, src, opts...)
+}
+
+// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by
+// non-empty src attribute values.
+// Deprecated: use Merge(…) with WithOverride
+func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
+ return merge(dst, src, append(opts, WithOverride)...)
+}
+
+// WithTransformers adds transformers to merge, allowing to customize the merging of some types.
+func WithTransformers(transformers Transformers) func(*Config) {
+ return func(config *Config) {
+ config.Transformers = transformers
+ }
+}
+
+// WithOverride will make merge override non-empty dst attributes with non-empty src attributes values.
+func WithOverride(config *Config) {
+ config.Overwrite = true
+}
+
+// WithOverwriteWithEmptyValue will make merge override non empty dst attributes with empty src attributes values.
+func WithOverwriteWithEmptyValue(config *Config) {
+ config.Overwrite = true
+ config.overwriteWithEmptyValue = true
+}
+
+// WithOverrideEmptySlice will make merge override empty dst slice with empty src slice.
+func WithOverrideEmptySlice(config *Config) {
+ config.overwriteSliceWithEmptyValue = true
+}
+
+// WithoutDereference prevents dereferencing pointers when evaluating whether they are empty
+// (i.e. a non-nil pointer is never considered empty).
+func WithoutDereference(config *Config) {
+ config.ShouldNotDereference = true
+}
+
+// WithAppendSlice will make merge append slices instead of overwriting it.
+func WithAppendSlice(config *Config) {
+ config.AppendSlice = true
+}
+
+// WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride).
+func WithTypeCheck(config *Config) {
+ config.TypeCheck = true
+}
+
+// WithSliceDeepCopy will merge slice element one by one with Overwrite flag.
+func WithSliceDeepCopy(config *Config) {
+ config.sliceDeepCopy = true
+ config.Overwrite = true
+}
+
+func merge(dst, src interface{}, opts ...func(*Config)) error {
+ if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
+ return ErrNonPointerArgument
+ }
+ var (
+ vDst, vSrc reflect.Value
+ err error
+ )
+
+ config := &Config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if vDst, vSrc, err = resolveValues(dst, src); err != nil {
+ return err
+ }
+ if vDst.Type() != vSrc.Type() {
+ return ErrDifferentArgumentsTypes
+ }
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+}
+
+// IsReflectNil is the reflect value provided nil
+func isReflectNil(v reflect.Value) bool {
+ k := v.Kind()
+ switch k {
+ case reflect.Interface, reflect.Slice, reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr:
+ // Both interface and slice are nil if first word is 0.
+ // Both are always bigger than a word; assume flagIndir.
+ return v.IsNil()
+ default:
+ return false
+ }
+}
diff --git a/vendor/dario.cat/mergo/mergo.go b/vendor/dario.cat/mergo/mergo.go
new file mode 100644
index 0000000..0a721e2
--- /dev/null
+++ b/vendor/dario.cat/mergo/mergo.go
@@ -0,0 +1,81 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "errors"
+ "reflect"
+)
+
+// Errors reported by Mergo when it finds invalid arguments.
+var (
+ ErrNilArguments = errors.New("src and dst must not be nil")
+ ErrDifferentArgumentsTypes = errors.New("src and dst must be of same type")
+ ErrNotSupported = errors.New("only structs, maps, and slices are supported")
+ ErrExpectedMapAsDestination = errors.New("dst was expected to be a map")
+ ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct")
+ ErrNonPointerArgument = errors.New("dst must be a pointer")
+)
+
+// During deepMerge, must keep track of checks that are
+// in progress. The comparison algorithm assumes that all
+// checks in progress are true when it reencounters them.
+// Visited are stored in a map indexed by 17 * a1 + a2;
+type visit struct {
+ typ reflect.Type
+ next *visit
+ ptr uintptr
+}
+
+// From src/pkg/encoding/json/encode.go.
+func isEmptyValue(v reflect.Value, shouldDereference bool) bool {
+ switch v.Kind() {
+ case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+ return v.Len() == 0
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.Interface, reflect.Ptr:
+ if v.IsNil() {
+ return true
+ }
+ if shouldDereference {
+ return isEmptyValue(v.Elem(), shouldDereference)
+ }
+ return false
+ case reflect.Func:
+ return v.IsNil()
+ case reflect.Invalid:
+ return true
+ }
+ return false
+}
+
+func resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) {
+ if dst == nil || src == nil {
+ err = ErrNilArguments
+ return
+ }
+ vDst = reflect.ValueOf(dst).Elem()
+ if vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map && vDst.Kind() != reflect.Slice {
+ err = ErrNotSupported
+ return
+ }
+ vSrc = reflect.ValueOf(src)
+ // We check if vSrc is a pointer to dereference it.
+ if vSrc.Kind() == reflect.Ptr {
+ vSrc = vSrc.Elem()
+ }
+ return
+}
diff --git a/vendor/github.com/Masterminds/semver/.travis.yml b/vendor/github.com/Masterminds/semver/.travis.yml
new file mode 100644
index 0000000..096369d
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/.travis.yml
@@ -0,0 +1,29 @@
+language: go
+
+go:
+ - 1.6.x
+ - 1.7.x
+ - 1.8.x
+ - 1.9.x
+ - 1.10.x
+ - 1.11.x
+ - 1.12.x
+ - tip
+
+# Setting sudo access to false will let Travis CI use containers rather than
+# VMs to run the tests. For more details see:
+# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
+# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
+sudo: false
+
+script:
+ - make setup
+ - make test
+
+notifications:
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/06e3328629952dabe3e0
+ on_success: change # options: [always|never|change] default: always
+ on_failure: always # options: [always|never|change] default: always
+ on_start: never # options: [always|never|change] default: always
diff --git a/vendor/github.com/Masterminds/semver/CHANGELOG.md b/vendor/github.com/Masterminds/semver/CHANGELOG.md
new file mode 100644
index 0000000..e405c9a
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/CHANGELOG.md
@@ -0,0 +1,109 @@
+# 1.5.0 (2019-09-11)
+
+## Added
+
+- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c)
+
+## Changed
+
+- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil)
+- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil)
+- #72: Adding docs comment pointing to vert for a cli
+- #71: Update the docs on pre-release comparator handling
+- #89: Test with new go versions (thanks @thedevsaddam)
+- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll)
+
+## Fixed
+
+- #78: Fix unchecked error in example code (thanks @ravron)
+- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
+- #97: Fixed copyright file for proper display on GitHub
+- #107: Fix handling prerelease when sorting alphanum and num
+- #109: Fixed where Validate sometimes returns wrong message on error
+
+# 1.4.2 (2018-04-10)
+
+## Changed
+- #72: Updated the docs to point to vert for a console appliaction
+- #71: Update the docs on pre-release comparator handling
+
+## Fixed
+- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
+
+# 1.4.1 (2018-04-02)
+
+## Fixed
+- Fixed #64: Fix pre-release precedence issue (thanks @uudashr)
+
+# 1.4.0 (2017-10-04)
+
+## Changed
+- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill)
+
+# 1.3.1 (2017-07-10)
+
+## Fixed
+- Fixed #57: number comparisons in prerelease sometimes inaccurate
+
+# 1.3.0 (2017-05-02)
+
+## Added
+- #45: Added json (un)marshaling support (thanks @mh-cbon)
+- Stability marker. See https://masterminds.github.io/stability/
+
+## Fixed
+- #51: Fix handling of single digit tilde constraint (thanks @dgodd)
+
+## Changed
+- #55: The godoc icon moved from png to svg
+
+# 1.2.3 (2017-04-03)
+
+## Fixed
+- #46: Fixed 0.x.x and 0.0.x in constraints being treated as *
+
+# Release 1.2.2 (2016-12-13)
+
+## Fixed
+- #34: Fixed issue where hyphen range was not working with pre-release parsing.
+
+# Release 1.2.1 (2016-11-28)
+
+## Fixed
+- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
+ properly.
+
+# Release 1.2.0 (2016-11-04)
+
+## Added
+- #20: Added MustParse function for versions (thanks @adamreese)
+- #15: Added increment methods on versions (thanks @mh-cbon)
+
+## Fixed
+- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
+ might not satisfy the intended compatibility. The change here ignores pre-releases
+ on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
+ constraint. For example, `^1.2.3` will ignore pre-releases while
+ `^1.2.3-alpha` will include them.
+
+# Release 1.1.1 (2016-06-30)
+
+## Changed
+- Issue #9: Speed up version comparison performance (thanks @sdboyer)
+- Issue #8: Added benchmarks (thanks @sdboyer)
+- Updated Go Report Card URL to new location
+- Updated Readme to add code snippet formatting (thanks @mh-cbon)
+- Updating tagging to v[SemVer] structure for compatibility with other tools.
+
+# Release 1.1.0 (2016-03-11)
+
+- Issue #2: Implemented validation to provide reasons a versions failed a
+ constraint.
+
+# Release 1.0.1 (2015-12-31)
+
+- Fixed #1: * constraint failing on valid versions.
+
+# Release 1.0.0 (2015-10-20)
+
+- Initial release
diff --git a/vendor/github.com/Masterminds/semver/LICENSE.txt b/vendor/github.com/Masterminds/semver/LICENSE.txt
new file mode 100644
index 0000000..9ff7da9
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (C) 2014-2019, Matt Butcher and Matt Farina
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/Masterminds/semver/Makefile b/vendor/github.com/Masterminds/semver/Makefile
new file mode 100644
index 0000000..a7a1b4e
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/Makefile
@@ -0,0 +1,36 @@
+.PHONY: setup
+setup:
+ go get -u gopkg.in/alecthomas/gometalinter.v1
+ gometalinter.v1 --install
+
+.PHONY: test
+test: validate lint
+ @echo "==> Running tests"
+ go test -v
+
+.PHONY: validate
+validate:
+ @echo "==> Running static validations"
+ @gometalinter.v1 \
+ --disable-all \
+ --enable deadcode \
+ --severity deadcode:error \
+ --enable gofmt \
+ --enable gosimple \
+ --enable ineffassign \
+ --enable misspell \
+ --enable vet \
+ --tests \
+ --vendor \
+ --deadline 60s \
+ ./... || exit_code=1
+
+.PHONY: lint
+lint:
+ @echo "==> Running linters"
+ @gometalinter.v1 \
+ --disable-all \
+ --enable golint \
+ --vendor \
+ --deadline 60s \
+ ./... || :
diff --git a/vendor/github.com/Masterminds/semver/README.md b/vendor/github.com/Masterminds/semver/README.md
new file mode 100644
index 0000000..1b52d2f
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/README.md
@@ -0,0 +1,194 @@
+# SemVer
+
+The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
+
+* Parse semantic versions
+* Sort semantic versions
+* Check if a semantic version fits within a set of constraints
+* Optionally work with a `v` prefix
+
+[](https://masterminds.github.io/stability/active.html)
+[](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](https://goreportcard.com/report/github.com/Masterminds/semver)
+
+If you are looking for a command line tool for version comparisons please see
+[vert](https://github.com/Masterminds/vert) which uses this library.
+
+## Parsing Semantic Versions
+
+To parse a semantic version use the `NewVersion` function. For example,
+
+```go
+ v, err := semver.NewVersion("1.2.3-beta.1+build345")
+```
+
+If there is an error the version wasn't parseable. The version object has methods
+to get the parts of the version, compare it to other versions, convert the
+version back into a string, and get the original string. For more details
+please see the [documentation](https://godoc.org/github.com/Masterminds/semver).
+
+## Sorting Semantic Versions
+
+A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
+package from the standard library. For example,
+
+```go
+ raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
+ vs := make([]*semver.Version, len(raw))
+ for i, r := range raw {
+ v, err := semver.NewVersion(r)
+ if err != nil {
+ t.Errorf("Error parsing version: %s", err)
+ }
+
+ vs[i] = v
+ }
+
+ sort.Sort(semver.Collection(vs))
+```
+
+## Checking Version Constraints
+
+Checking a version against version constraints is one of the most featureful
+parts of the package.
+
+```go
+ c, err := semver.NewConstraint(">= 1.2.3")
+ if err != nil {
+ // Handle constraint not being parseable.
+ }
+
+ v, _ := semver.NewVersion("1.3")
+ if err != nil {
+ // Handle version not being parseable.
+ }
+ // Check if the version meets the constraints. The a variable will be true.
+ a := c.Check(v)
+```
+
+## Basic Comparisons
+
+There are two elements to the comparisons. First, a comparison string is a list
+of comma separated and comparisons. These are then separated by || separated or
+comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
+comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
+greater than or equal to 4.2.3.
+
+The basic comparisons are:
+
+* `=`: equal (aliased to no operator)
+* `!=`: not equal
+* `>`: greater than
+* `<`: less than
+* `>=`: greater than or equal to
+* `<=`: less than or equal to
+
+## Working With Pre-release Versions
+
+Pre-releases, for those not familiar with them, are used for software releases
+prior to stable or generally available releases. Examples of pre-releases include
+development, alpha, beta, and release candidate releases. A pre-release may be
+a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
+order of precidence, pre-releases come before their associated releases. In this
+example `1.2.3-beta.1 < 1.2.3`.
+
+According to the Semantic Version specification pre-releases may not be
+API compliant with their release counterpart. It says,
+
+> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.
+
+SemVer comparisons without a pre-release comparator will skip pre-release versions.
+For example, `>=1.2.3` will skip pre-releases when looking at a list of releases
+while `>=1.2.3-0` will evaluate and find pre-releases.
+
+The reason for the `0` as a pre-release version in the example comparison is
+because pre-releases can only contain ASCII alphanumerics and hyphens (along with
+`.` separators), per the spec. Sorting happens in ASCII sort order, again per the spec. The lowest character is a `0` in ASCII sort order (see an [ASCII Table](http://www.asciitable.com/))
+
+Understanding ASCII sort ordering is important because A-Z comes before a-z. That
+means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
+sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
+the spec specifies.
+
+## Hyphen Range Comparisons
+
+There are multiple methods to handle ranges and the first is hyphens ranges.
+These look like:
+
+* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
+* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
+
+## Wildcards In Comparisons
+
+The `x`, `X`, and `*` characters can be used as a wildcard character. This works
+for all comparison operators. When used on the `=` operator it falls
+back to the pack level comparison (see tilde below). For example,
+
+* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
+* `>= 1.2.x` is equivalent to `>= 1.2.0`
+* `<= 2.x` is equivalent to `< 3`
+* `*` is equivalent to `>= 0.0.0`
+
+## Tilde Range Comparisons (Patch)
+
+The tilde (`~`) comparison operator is for patch level ranges when a minor
+version is specified and major level changes when the minor number is missing.
+For example,
+
+* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
+* `~1` is equivalent to `>= 1, < 2`
+* `~2.3` is equivalent to `>= 2.3, < 2.4`
+* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
+* `~1.x` is equivalent to `>= 1, < 2`
+
+## Caret Range Comparisons (Major)
+
+The caret (`^`) comparison operator is for major level changes. This is useful
+when comparisons of API versions as a major change is API breaking. For example,
+
+* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
+* `^0.0.1` is equivalent to `>= 0.0.1, < 1.0.0`
+* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
+* `^2.3` is equivalent to `>= 2.3, < 3`
+* `^2.x` is equivalent to `>= 2.0.0, < 3`
+
+# Validation
+
+In addition to testing a version against a constraint, a version can be validated
+against a constraint. When validation fails a slice of errors containing why a
+version didn't meet the constraint is returned. For example,
+
+```go
+ c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
+ if err != nil {
+ // Handle constraint not being parseable.
+ }
+
+ v, _ := semver.NewVersion("1.3")
+ if err != nil {
+ // Handle version not being parseable.
+ }
+
+ // Validate a version against a constraint.
+ a, msgs := c.Validate(v)
+ // a is false
+ for _, m := range msgs {
+ fmt.Println(m)
+
+ // Loops over the errors which would read
+ // "1.3 is greater than 1.2.3"
+ // "1.3 is less than 1.4"
+ }
+```
+
+# Fuzzing
+
+ [dvyukov/go-fuzz](https://github.com/dvyukov/go-fuzz) is used for fuzzing.
+
+1. `go-fuzz-build`
+2. `go-fuzz -workdir=fuzz`
+
+# Contribute
+
+If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
+or [create a pull request](https://github.com/Masterminds/semver/pulls).
diff --git a/vendor/github.com/Masterminds/semver/appveyor.yml b/vendor/github.com/Masterminds/semver/appveyor.yml
new file mode 100644
index 0000000..b2778df
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/appveyor.yml
@@ -0,0 +1,44 @@
+version: build-{build}.{branch}
+
+clone_folder: C:\gopath\src\github.com\Masterminds\semver
+shallow_clone: true
+
+environment:
+ GOPATH: C:\gopath
+
+platform:
+ - x64
+
+install:
+ - go version
+ - go env
+ - go get -u gopkg.in/alecthomas/gometalinter.v1
+ - set PATH=%PATH%;%GOPATH%\bin
+ - gometalinter.v1.exe --install
+
+build_script:
+ - go install -v ./...
+
+test_script:
+ - "gometalinter.v1 \
+ --disable-all \
+ --enable deadcode \
+ --severity deadcode:error \
+ --enable gofmt \
+ --enable gosimple \
+ --enable ineffassign \
+ --enable misspell \
+ --enable vet \
+ --tests \
+ --vendor \
+ --deadline 60s \
+ ./... || exit_code=1"
+ - "gometalinter.v1 \
+ --disable-all \
+ --enable golint \
+ --vendor \
+ --deadline 60s \
+ ./... || :"
+ - go test -v
+
+deploy: off
diff --git a/vendor/github.com/Masterminds/semver/collection.go b/vendor/github.com/Masterminds/semver/collection.go
new file mode 100644
index 0000000..a782358
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/collection.go
@@ -0,0 +1,24 @@
+package semver
+
+// Collection is a collection of Version instances and implements the sort
+// interface. See the sort package for more details.
+// https://golang.org/pkg/sort/
+type Collection []*Version
+
+// Len returns the length of a collection. The number of Version instances
+// on the slice.
+func (c Collection) Len() int {
+ return len(c)
+}
+
+// Less is needed for the sort interface to compare two Version objects on the
+// slice. If checks if one is less than the other.
+func (c Collection) Less(i, j int) bool {
+ return c[i].LessThan(c[j])
+}
+
+// Swap is needed for the sort interface to replace the Version objects
+// at two different positions in the slice.
+func (c Collection) Swap(i, j int) {
+ c[i], c[j] = c[j], c[i]
+}
diff --git a/vendor/github.com/Masterminds/semver/constraints.go b/vendor/github.com/Masterminds/semver/constraints.go
new file mode 100644
index 0000000..b94b934
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/constraints.go
@@ -0,0 +1,423 @@
+package semver
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+// Constraints is one or more constraint that a semantic version can be
+// checked against.
+type Constraints struct {
+ constraints [][]*constraint
+}
+
+// NewConstraint returns a Constraints instance that a Version instance can
+// be checked against. If there is a parse error it will be returned.
+func NewConstraint(c string) (*Constraints, error) {
+
+ // Rewrite - ranges into a comparison operation.
+ c = rewriteRange(c)
+
+ ors := strings.Split(c, "||")
+ or := make([][]*constraint, len(ors))
+ for k, v := range ors {
+ cs := strings.Split(v, ",")
+ result := make([]*constraint, len(cs))
+ for i, s := range cs {
+ pc, err := parseConstraint(s)
+ if err != nil {
+ return nil, err
+ }
+
+ result[i] = pc
+ }
+ or[k] = result
+ }
+
+ o := &Constraints{constraints: or}
+ return o, nil
+}
+
+// Check tests if a version satisfies the constraints.
+func (cs Constraints) Check(v *Version) bool {
+ // loop over the ORs and check the inner ANDs
+ for _, o := range cs.constraints {
+ joy := true
+ for _, c := range o {
+ if !c.check(v) {
+ joy = false
+ break
+ }
+ }
+
+ if joy {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Validate checks if a version satisfies a constraint. If not a slice of
+// reasons for the failure are returned in addition to a bool.
+func (cs Constraints) Validate(v *Version) (bool, []error) {
+ // loop over the ORs and check the inner ANDs
+ var e []error
+
+ // Capture the prerelease message only once. When it happens the first time
+ // this var is marked
+ var prerelesase bool
+ for _, o := range cs.constraints {
+ joy := true
+ for _, c := range o {
+ // Before running the check handle the case there the version is
+ // a prerelease and the check is not searching for prereleases.
+ if c.con.pre == "" && v.pre != "" {
+ if !prerelesase {
+ em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ e = append(e, em)
+ prerelesase = true
+ }
+ joy = false
+
+ } else {
+
+ if !c.check(v) {
+ em := fmt.Errorf(c.msg, v, c.orig)
+ e = append(e, em)
+ joy = false
+ }
+ }
+ }
+
+ if joy {
+ return true, []error{}
+ }
+ }
+
+ return false, e
+}
+
+var constraintOps map[string]cfunc
+var constraintMsg map[string]string
+var constraintRegex *regexp.Regexp
+
+func init() {
+ constraintOps = map[string]cfunc{
+ "": constraintTildeOrEqual,
+ "=": constraintTildeOrEqual,
+ "!=": constraintNotEqual,
+ ">": constraintGreaterThan,
+ "<": constraintLessThan,
+ ">=": constraintGreaterThanEqual,
+ "=>": constraintGreaterThanEqual,
+ "<=": constraintLessThanEqual,
+ "=<": constraintLessThanEqual,
+ "~": constraintTilde,
+ "~>": constraintTilde,
+ "^": constraintCaret,
+ }
+
+ constraintMsg = map[string]string{
+ "": "%s is not equal to %s",
+ "=": "%s is not equal to %s",
+ "!=": "%s is equal to %s",
+ ">": "%s is less than or equal to %s",
+ "<": "%s is greater than or equal to %s",
+ ">=": "%s is less than %s",
+ "=>": "%s is less than %s",
+ "<=": "%s is greater than %s",
+ "=<": "%s is greater than %s",
+ "~": "%s does not have same major and minor version as %s",
+ "~>": "%s does not have same major and minor version as %s",
+ "^": "%s does not have same major version as %s",
+ }
+
+ ops := make([]string, 0, len(constraintOps))
+ for k := range constraintOps {
+ ops = append(ops, regexp.QuoteMeta(k))
+ }
+
+ constraintRegex = regexp.MustCompile(fmt.Sprintf(
+ `^\s*(%s)\s*(%s)\s*$`,
+ strings.Join(ops, "|"),
+ cvRegex))
+
+ constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
+ `\s*(%s)\s+-\s+(%s)\s*`,
+ cvRegex, cvRegex))
+}
+
+// An individual constraint
+type constraint struct {
+ // The callback function for the restraint. It performs the logic for
+ // the constraint.
+ function cfunc
+
+ msg string
+
+ // The version used in the constraint check. For example, if a constraint
+ // is '<= 2.0.0' the con a version instance representing 2.0.0.
+ con *Version
+
+ // The original parsed version (e.g., 4.x from != 4.x)
+ orig string
+
+ // When an x is used as part of the version (e.g., 1.x)
+ minorDirty bool
+ dirty bool
+ patchDirty bool
+}
+
+// Check if a version meets the constraint
+func (c *constraint) check(v *Version) bool {
+ return c.function(v, c)
+}
+
+type cfunc func(v *Version, c *constraint) bool
+
+func parseConstraint(c string) (*constraint, error) {
+ m := constraintRegex.FindStringSubmatch(c)
+ if m == nil {
+ return nil, fmt.Errorf("improper constraint: %s", c)
+ }
+
+ ver := m[2]
+ orig := ver
+ minorDirty := false
+ patchDirty := false
+ dirty := false
+ if isX(m[3]) {
+ ver = "0.0.0"
+ dirty = true
+ } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" {
+ minorDirty = true
+ dirty = true
+ ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
+ } else if isX(strings.TrimPrefix(m[5], ".")) {
+ dirty = true
+ patchDirty = true
+ ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
+ }
+
+ con, err := NewVersion(ver)
+ if err != nil {
+
+ // The constraintRegex should catch any regex parsing errors. So,
+ // we should never get here.
+ return nil, errors.New("constraint Parser Error")
+ }
+
+ cs := &constraint{
+ function: constraintOps[m[1]],
+ msg: constraintMsg[m[1]],
+ con: con,
+ orig: orig,
+ minorDirty: minorDirty,
+ patchDirty: patchDirty,
+ dirty: dirty,
+ }
+ return cs, nil
+}
+
+// Constraint functions
+func constraintNotEqual(v *Version, c *constraint) bool {
+ if c.dirty {
+
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if c.con.Major() != v.Major() {
+ return true
+ }
+ if c.con.Minor() != v.Minor() && !c.minorDirty {
+ return true
+ } else if c.minorDirty {
+ return false
+ }
+
+ return false
+ }
+
+ return !v.Equal(c.con)
+}
+
+func constraintGreaterThan(v *Version, c *constraint) bool {
+
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ return v.Compare(c.con) == 1
+}
+
+func constraintLessThan(v *Version, c *constraint) bool {
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if !c.dirty {
+ return v.Compare(c.con) < 0
+ }
+
+ if v.Major() > c.con.Major() {
+ return false
+ } else if v.Minor() > c.con.Minor() && !c.minorDirty {
+ return false
+ }
+
+ return true
+}
+
+func constraintGreaterThanEqual(v *Version, c *constraint) bool {
+
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ return v.Compare(c.con) >= 0
+}
+
+func constraintLessThanEqual(v *Version, c *constraint) bool {
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if !c.dirty {
+ return v.Compare(c.con) <= 0
+ }
+
+ if v.Major() > c.con.Major() {
+ return false
+ } else if v.Minor() > c.con.Minor() && !c.minorDirty {
+ return false
+ }
+
+ return true
+}
+
+// ~*, ~>* --> >= 0.0.0 (any)
+// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
+// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
+// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
+// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
+// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
+func constraintTilde(v *Version, c *constraint) bool {
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if v.LessThan(c.con) {
+ return false
+ }
+
+ // ~0.0.0 is a special case where all constraints are accepted. It's
+ // equivalent to >= 0.0.0.
+ if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 &&
+ !c.minorDirty && !c.patchDirty {
+ return true
+ }
+
+ if v.Major() != c.con.Major() {
+ return false
+ }
+
+ if v.Minor() != c.con.Minor() && !c.minorDirty {
+ return false
+ }
+
+ return true
+}
+
+// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
+// it's a straight =
+func constraintTildeOrEqual(v *Version, c *constraint) bool {
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if c.dirty {
+ c.msg = constraintMsg["~"]
+ return constraintTilde(v, c)
+ }
+
+ return v.Equal(c.con)
+}
+
+// ^* --> (any)
+// ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0
+// ^2.0, ^2.0.x --> >=2.0.0, <3.0.0
+// ^1.2, ^1.2.x --> >=1.2.0, <2.0.0
+// ^1.2.3 --> >=1.2.3, <2.0.0
+// ^1.2.0 --> >=1.2.0, <2.0.0
+func constraintCaret(v *Version, c *constraint) bool {
+ // If there is a pre-release on the version but the constraint isn't looking
+ // for them assume that pre-releases are not compatible. See issue 21 for
+ // more details.
+ if v.Prerelease() != "" && c.con.Prerelease() == "" {
+ return false
+ }
+
+ if v.LessThan(c.con) {
+ return false
+ }
+
+ if v.Major() != c.con.Major() {
+ return false
+ }
+
+ return true
+}
+
+var constraintRangeRegex *regexp.Regexp
+
+const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
+ `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
+ `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
+
+func isX(x string) bool {
+ switch x {
+ case "x", "*", "X":
+ return true
+ default:
+ return false
+ }
+}
+
+func rewriteRange(i string) string {
+ m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
+ if m == nil {
+ return i
+ }
+ o := i
+ for _, v := range m {
+ t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
+ o = strings.Replace(o, v[0], t, 1)
+ }
+
+ return o
+}
diff --git a/vendor/github.com/Masterminds/semver/doc.go b/vendor/github.com/Masterminds/semver/doc.go
new file mode 100644
index 0000000..6a6c24c
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/doc.go
@@ -0,0 +1,115 @@
+/*
+Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
+
+Specifically it provides the ability to:
+
+ * Parse semantic versions
+ * Sort semantic versions
+ * Check if a semantic version fits within a set of constraints
+ * Optionally work with a `v` prefix
+
+Parsing Semantic Versions
+
+To parse a semantic version use the `NewVersion` function. For example,
+
+ v, err := semver.NewVersion("1.2.3-beta.1+build345")
+
+If there is an error the version wasn't parseable. The version object has methods
+to get the parts of the version, compare it to other versions, convert the
+version back into a string, and get the original string. For more details
+please see the documentation at https://godoc.org/github.com/Masterminds/semver.
+
+Sorting Semantic Versions
+
+A set of versions can be sorted using the `sort` package from the standard library.
+For example,
+
+ raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
+ vs := make([]*semver.Version, len(raw))
+ for i, r := range raw {
+ v, err := semver.NewVersion(r)
+ if err != nil {
+ t.Errorf("Error parsing version: %s", err)
+ }
+
+ vs[i] = v
+ }
+
+ sort.Sort(semver.Collection(vs))
+
+Checking Version Constraints
+
+Checking a version against version constraints is one of the most featureful
+parts of the package.
+
+ c, err := semver.NewConstraint(">= 1.2.3")
+ if err != nil {
+ // Handle constraint not being parseable.
+ }
+
+ v, err := semver.NewVersion("1.3")
+ if err != nil {
+ // Handle version not being parseable.
+ }
+ // Check if the version meets the constraints. The a variable will be true.
+ a := c.Check(v)
+
+Basic Comparisons
+
+There are two elements to the comparisons. First, a comparison string is a list
+of comma separated and comparisons. These are then separated by || separated or
+comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
+comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
+greater than or equal to 4.2.3.
+
+The basic comparisons are:
+
+ * `=`: equal (aliased to no operator)
+ * `!=`: not equal
+ * `>`: greater than
+ * `<`: less than
+ * `>=`: greater than or equal to
+ * `<=`: less than or equal to
+
+Hyphen Range Comparisons
+
+There are multiple methods to handle ranges and the first is hyphens ranges.
+These look like:
+
+ * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
+ * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
+
+Wildcards In Comparisons
+
+The `x`, `X`, and `*` characters can be used as a wildcard character. This works
+for all comparison operators. When used on the `=` operator it falls
+back to the pack level comparison (see tilde below). For example,
+
+ * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
+ * `>= 1.2.x` is equivalent to `>= 1.2.0`
+ * `<= 2.x` is equivalent to `<= 3`
+ * `*` is equivalent to `>= 0.0.0`
+
+Tilde Range Comparisons (Patch)
+
+The tilde (`~`) comparison operator is for patch level ranges when a minor
+version is specified and major level changes when the minor number is missing.
+For example,
+
+ * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
+ * `~1` is equivalent to `>= 1, < 2`
+ * `~2.3` is equivalent to `>= 2.3, < 2.4`
+ * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
+ * `~1.x` is equivalent to `>= 1, < 2`
+
+Caret Range Comparisons (Major)
+
+The caret (`^`) comparison operator is for major level changes. This is useful
+when comparisons of API versions as a major change is API breaking. For example,
+
+ * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
+ * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
+ * `^2.3` is equivalent to `>= 2.3, < 3`
+ * `^2.x` is equivalent to `>= 2.0.0, < 3`
+*/
+package semver
diff --git a/vendor/github.com/Masterminds/semver/version.go b/vendor/github.com/Masterminds/semver/version.go
new file mode 100644
index 0000000..400d4f9
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/version.go
@@ -0,0 +1,425 @@
+package semver
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// The compiled version of the regex created at init() is cached here so it
+// only needs to be created once.
+var versionRegex *regexp.Regexp
+var validPrereleaseRegex *regexp.Regexp
+
+var (
+ // ErrInvalidSemVer is returned a version is found to be invalid when
+ // being parsed.
+ ErrInvalidSemVer = errors.New("Invalid Semantic Version")
+
+ // ErrInvalidMetadata is returned when the metadata is an invalid format
+ ErrInvalidMetadata = errors.New("Invalid Metadata string")
+
+ // ErrInvalidPrerelease is returned when the pre-release is an invalid format
+ ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
+)
+
+// SemVerRegex is the regular expression used to parse a semantic version.
+const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
+ `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
+ `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
+
+// ValidPrerelease is the regular expression which validates
+// both prerelease and metadata values.
+const ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)$`
+
+// Version represents a single semantic version.
+type Version struct {
+ major, minor, patch int64
+ pre string
+ metadata string
+ original string
+}
+
+func init() {
+ versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
+ validPrereleaseRegex = regexp.MustCompile(ValidPrerelease)
+}
+
+// NewVersion parses a given version and returns an instance of Version or
+// an error if unable to parse the version.
+func NewVersion(v string) (*Version, error) {
+ m := versionRegex.FindStringSubmatch(v)
+ if m == nil {
+ return nil, ErrInvalidSemVer
+ }
+
+ sv := &Version{
+ metadata: m[8],
+ pre: m[5],
+ original: v,
+ }
+
+ var temp int64
+ temp, err := strconv.ParseInt(m[1], 10, 64)
+ if err != nil {
+ return nil, fmt.Errorf("Error parsing version segment: %s", err)
+ }
+ sv.major = temp
+
+ if m[2] != "" {
+ temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64)
+ if err != nil {
+ return nil, fmt.Errorf("Error parsing version segment: %s", err)
+ }
+ sv.minor = temp
+ } else {
+ sv.minor = 0
+ }
+
+ if m[3] != "" {
+ temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 64)
+ if err != nil {
+ return nil, fmt.Errorf("Error parsing version segment: %s", err)
+ }
+ sv.patch = temp
+ } else {
+ sv.patch = 0
+ }
+
+ return sv, nil
+}
+
+// MustParse parses a given version and panics on error.
+func MustParse(v string) *Version {
+ sv, err := NewVersion(v)
+ if err != nil {
+ panic(err)
+ }
+ return sv
+}
+
+// String converts a Version object to a string.
+// Note, if the original version contained a leading v this version will not.
+// See the Original() method to retrieve the original value. Semantic Versions
+// don't contain a leading v per the spec. Instead it's optional on
+// implementation.
+func (v *Version) String() string {
+ var buf bytes.Buffer
+
+ fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
+ if v.pre != "" {
+ fmt.Fprintf(&buf, "-%s", v.pre)
+ }
+ if v.metadata != "" {
+ fmt.Fprintf(&buf, "+%s", v.metadata)
+ }
+
+ return buf.String()
+}
+
+// Original returns the original value passed in to be parsed.
+func (v *Version) Original() string {
+ return v.original
+}
+
+// Major returns the major version.
+func (v *Version) Major() int64 {
+ return v.major
+}
+
+// Minor returns the minor version.
+func (v *Version) Minor() int64 {
+ return v.minor
+}
+
+// Patch returns the patch version.
+func (v *Version) Patch() int64 {
+ return v.patch
+}
+
+// Prerelease returns the pre-release version.
+func (v *Version) Prerelease() string {
+ return v.pre
+}
+
+// Metadata returns the metadata on the version.
+func (v *Version) Metadata() string {
+ return v.metadata
+}
+
+// originalVPrefix returns the original 'v' prefix if any.
+func (v *Version) originalVPrefix() string {
+
+ // Note, only lowercase v is supported as a prefix by the parser.
+ if v.original != "" && v.original[:1] == "v" {
+ return v.original[:1]
+ }
+ return ""
+}
+
+// IncPatch produces the next patch version.
+// If the current version does not have prerelease/metadata information,
+// it unsets metadata and prerelease values, increments patch number.
+// If the current version has any of prerelease or metadata information,
+// it unsets both values and keeps curent patch value
+func (v Version) IncPatch() Version {
+ vNext := v
+ // according to http://semver.org/#spec-item-9
+ // Pre-release versions have a lower precedence than the associated normal version.
+ // according to http://semver.org/#spec-item-10
+ // Build metadata SHOULD be ignored when determining version precedence.
+ if v.pre != "" {
+ vNext.metadata = ""
+ vNext.pre = ""
+ } else {
+ vNext.metadata = ""
+ vNext.pre = ""
+ vNext.patch = v.patch + 1
+ }
+ vNext.original = v.originalVPrefix() + "" + vNext.String()
+ return vNext
+}
+
+// IncMinor produces the next minor version.
+// Sets patch to 0.
+// Increments minor number.
+// Unsets metadata.
+// Unsets prerelease status.
+func (v Version) IncMinor() Version {
+ vNext := v
+ vNext.metadata = ""
+ vNext.pre = ""
+ vNext.patch = 0
+ vNext.minor = v.minor + 1
+ vNext.original = v.originalVPrefix() + "" + vNext.String()
+ return vNext
+}
+
+// IncMajor produces the next major version.
+// Sets patch to 0.
+// Sets minor to 0.
+// Increments major number.
+// Unsets metadata.
+// Unsets prerelease status.
+func (v Version) IncMajor() Version {
+ vNext := v
+ vNext.metadata = ""
+ vNext.pre = ""
+ vNext.patch = 0
+ vNext.minor = 0
+ vNext.major = v.major + 1
+ vNext.original = v.originalVPrefix() + "" + vNext.String()
+ return vNext
+}
+
+// SetPrerelease defines the prerelease value.
+// Value must not include the required 'hypen' prefix.
+func (v Version) SetPrerelease(prerelease string) (Version, error) {
+ vNext := v
+ if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) {
+ return vNext, ErrInvalidPrerelease
+ }
+ vNext.pre = prerelease
+ vNext.original = v.originalVPrefix() + "" + vNext.String()
+ return vNext, nil
+}
+
+// SetMetadata defines metadata value.
+// Value must not include the required 'plus' prefix.
+func (v Version) SetMetadata(metadata string) (Version, error) {
+ vNext := v
+ if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) {
+ return vNext, ErrInvalidMetadata
+ }
+ vNext.metadata = metadata
+ vNext.original = v.originalVPrefix() + "" + vNext.String()
+ return vNext, nil
+}
+
+// LessThan tests if one version is less than another one.
+func (v *Version) LessThan(o *Version) bool {
+ return v.Compare(o) < 0
+}
+
+// GreaterThan tests if one version is greater than another one.
+func (v *Version) GreaterThan(o *Version) bool {
+ return v.Compare(o) > 0
+}
+
+// Equal tests if two versions are equal to each other.
+// Note, versions can be equal with different metadata since metadata
+// is not considered part of the comparable version.
+func (v *Version) Equal(o *Version) bool {
+ return v.Compare(o) == 0
+}
+
+// Compare compares this version to another one. It returns -1, 0, or 1 if
+// the version smaller, equal, or larger than the other version.
+//
+// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
+// lower than the version without a prerelease.
+func (v *Version) Compare(o *Version) int {
+ // Compare the major, minor, and patch version for differences. If a
+ // difference is found return the comparison.
+ if d := compareSegment(v.Major(), o.Major()); d != 0 {
+ return d
+ }
+ if d := compareSegment(v.Minor(), o.Minor()); d != 0 {
+ return d
+ }
+ if d := compareSegment(v.Patch(), o.Patch()); d != 0 {
+ return d
+ }
+
+ // At this point the major, minor, and patch versions are the same.
+ ps := v.pre
+ po := o.Prerelease()
+
+ if ps == "" && po == "" {
+ return 0
+ }
+ if ps == "" {
+ return 1
+ }
+ if po == "" {
+ return -1
+ }
+
+ return comparePrerelease(ps, po)
+}
+
+// UnmarshalJSON implements JSON.Unmarshaler interface.
+func (v *Version) UnmarshalJSON(b []byte) error {
+ var s string
+ if err := json.Unmarshal(b, &s); err != nil {
+ return err
+ }
+ temp, err := NewVersion(s)
+ if err != nil {
+ return err
+ }
+ v.major = temp.major
+ v.minor = temp.minor
+ v.patch = temp.patch
+ v.pre = temp.pre
+ v.metadata = temp.metadata
+ v.original = temp.original
+ temp = nil
+ return nil
+}
+
+// MarshalJSON implements JSON.Marshaler interface.
+func (v *Version) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.String())
+}
+
+func compareSegment(v, o int64) int {
+ if v < o {
+ return -1
+ }
+ if v > o {
+ return 1
+ }
+
+ return 0
+}
+
+func comparePrerelease(v, o string) int {
+
+ // split the prelease versions by their part. The separator, per the spec,
+ // is a .
+ sparts := strings.Split(v, ".")
+ oparts := strings.Split(o, ".")
+
+ // Find the longer length of the parts to know how many loop iterations to
+ // go through.
+ slen := len(sparts)
+ olen := len(oparts)
+
+ l := slen
+ if olen > slen {
+ l = olen
+ }
+
+ // Iterate over each part of the prereleases to compare the differences.
+ for i := 0; i < l; i++ {
+ // Since the lentgh of the parts can be different we need to create
+ // a placeholder. This is to avoid out of bounds issues.
+ stemp := ""
+ if i < slen {
+ stemp = sparts[i]
+ }
+
+ otemp := ""
+ if i < olen {
+ otemp = oparts[i]
+ }
+
+ d := comparePrePart(stemp, otemp)
+ if d != 0 {
+ return d
+ }
+ }
+
+ // Reaching here means two versions are of equal value but have different
+ // metadata (the part following a +). They are not identical in string form
+ // but the version comparison finds them to be equal.
+ return 0
+}
+
+func comparePrePart(s, o string) int {
+ // Fastpath if they are equal
+ if s == o {
+ return 0
+ }
+
+ // When s or o are empty we can use the other in an attempt to determine
+ // the response.
+ if s == "" {
+ if o != "" {
+ return -1
+ }
+ return 1
+ }
+
+ if o == "" {
+ if s != "" {
+ return 1
+ }
+ return -1
+ }
+
+ // When comparing strings "99" is greater than "103". To handle
+ // cases like this we need to detect numbers and compare them. According
+ // to the semver spec, numbers are always positive. If there is a - at the
+ // start like -99 this is to be evaluated as an alphanum. numbers always
+ // have precedence over alphanum. Parsing as Uints because negative numbers
+ // are ignored.
+
+ oi, n1 := strconv.ParseUint(o, 10, 64)
+ si, n2 := strconv.ParseUint(s, 10, 64)
+
+ // The case where both are strings compare the strings
+ if n1 != nil && n2 != nil {
+ if s > o {
+ return 1
+ }
+ return -1
+ } else if n1 != nil {
+ // o is a string and s is a number
+ return -1
+ } else if n2 != nil {
+ // s is a string and o is a number
+ return 1
+ }
+ // Both are numbers
+ if si > oi {
+ return 1
+ }
+ return -1
+
+}
diff --git a/vendor/github.com/Masterminds/semver/version_fuzz.go b/vendor/github.com/Masterminds/semver/version_fuzz.go
new file mode 100644
index 0000000..b42bcd6
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/version_fuzz.go
@@ -0,0 +1,10 @@
+// +build gofuzz
+
+package semver
+
+func Fuzz(data []byte) int {
+ if _, err := NewVersion(string(data)); err != nil {
+ return 0
+ }
+ return 1
+}
diff --git a/vendor/github.com/Microsoft/go-winio/.gitattributes b/vendor/github.com/Microsoft/go-winio/.gitattributes
new file mode 100644
index 0000000..94f480d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
\ No newline at end of file
diff --git a/vendor/github.com/Microsoft/go-winio/.gitignore b/vendor/github.com/Microsoft/go-winio/.gitignore
new file mode 100644
index 0000000..815e206
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.gitignore
@@ -0,0 +1,10 @@
+.vscode/
+
+*.exe
+
+# testing
+testdata
+
+# go workspaces
+go.work
+go.work.sum
diff --git a/vendor/github.com/Microsoft/go-winio/.golangci.yml b/vendor/github.com/Microsoft/go-winio/.golangci.yml
new file mode 100644
index 0000000..faedfe9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/.golangci.yml
@@ -0,0 +1,147 @@
+linters:
+ enable:
+ # style
+ - containedctx # struct contains a context
+ - dupl # duplicate code
+ - errname # erorrs are named correctly
+ - nolintlint # "//nolint" directives are properly explained
+ - revive # golint replacement
+ - unconvert # unnecessary conversions
+ - wastedassign
+
+ # bugs, performance, unused, etc ...
+ - contextcheck # function uses a non-inherited context
+ - errorlint # errors not wrapped for 1.13
+ - exhaustive # check exhaustiveness of enum switch statements
+ - gofmt # files are gofmt'ed
+ - gosec # security
+ - nilerr # returns nil even with non-nil error
+ - thelper # test helpers without t.Helper()
+ - unparam # unused function params
+
+issues:
+ exclude-dirs:
+ - pkg/etw/sample
+
+ exclude-rules:
+ # err is very often shadowed in nested scopes
+ - linters:
+ - govet
+ text: '^shadow: declaration of "err" shadows declaration'
+
+ # ignore long lines for skip autogen directives
+ - linters:
+ - revive
+ text: "^line-length-limit: "
+ source: "^//(go:generate|sys) "
+
+ #TODO: remove after upgrading to go1.18
+ # ignore comment spacing for nolint and sys directives
+ - linters:
+ - revive
+ text: "^comment-spacings: no space between comment delimiter and comment text"
+ source: "//(cspell:|nolint:|sys |todo)"
+
+ # not on go 1.18 yet, so no any
+ - linters:
+ - revive
+ text: "^use-any: since GO 1.18 'interface{}' can be replaced by 'any'"
+
+ # allow unjustified ignores of error checks in defer statements
+ - linters:
+ - nolintlint
+ text: "^directive `//nolint:errcheck` should provide explanation"
+ source: '^\s*defer '
+
+ # allow unjustified ignores of error lints for io.EOF
+ - linters:
+ - nolintlint
+ text: "^directive `//nolint:errorlint` should provide explanation"
+ source: '[=|!]= io.EOF'
+
+
+linters-settings:
+ exhaustive:
+ default-signifies-exhaustive: true
+ govet:
+ enable-all: true
+ disable:
+ # struct order is often for Win32 compat
+ # also, ignore pointer bytes/GC issues for now until performance becomes an issue
+ - fieldalignment
+ nolintlint:
+ require-explanation: true
+ require-specific: true
+ revive:
+ # revive is more configurable than static check, so likely the preferred alternative to static-check
+ # (once the perf issue is solved: https://github.com/golangci/golangci-lint/issues/2997)
+ enable-all-rules:
+ true
+ # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
+ rules:
+ # rules with required arguments
+ - name: argument-limit
+ disabled: true
+ - name: banned-characters
+ disabled: true
+ - name: cognitive-complexity
+ disabled: true
+ - name: cyclomatic
+ disabled: true
+ - name: file-header
+ disabled: true
+ - name: function-length
+ disabled: true
+ - name: function-result-limit
+ disabled: true
+ - name: max-public-structs
+ disabled: true
+ # geneally annoying rules
+ - name: add-constant # complains about any and all strings and integers
+ disabled: true
+ - name: confusing-naming # we frequently use "Foo()" and "foo()" together
+ disabled: true
+ - name: flag-parameter # excessive, and a common idiom we use
+ disabled: true
+ - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead
+ disabled: true
+ # general config
+ - name: line-length-limit
+ arguments:
+ - 140
+ - name: var-naming
+ arguments:
+ - []
+ - - CID
+ - CRI
+ - CTRD
+ - DACL
+ - DLL
+ - DOS
+ - ETW
+ - FSCTL
+ - GCS
+ - GMSA
+ - HCS
+ - HV
+ - IO
+ - LCOW
+ - LDAP
+ - LPAC
+ - LTSC
+ - MMIO
+ - NT
+ - OCI
+ - PMEM
+ - PWSH
+ - RX
+ - SACl
+ - SID
+ - SMB
+ - TX
+ - VHD
+ - VHDX
+ - VMID
+ - VPCI
+ - WCOW
+ - WIM
diff --git a/vendor/github.com/Microsoft/go-winio/CODEOWNERS b/vendor/github.com/Microsoft/go-winio/CODEOWNERS
new file mode 100644
index 0000000..ae1b494
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/CODEOWNERS
@@ -0,0 +1 @@
+ * @microsoft/containerplat
diff --git a/vendor/github.com/Microsoft/go-winio/LICENSE b/vendor/github.com/Microsoft/go-winio/LICENSE
new file mode 100644
index 0000000..b8b569d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Microsoft
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/github.com/Microsoft/go-winio/README.md b/vendor/github.com/Microsoft/go-winio/README.md
new file mode 100644
index 0000000..7474b4f
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/README.md
@@ -0,0 +1,89 @@
+# go-winio [](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)
+
+This repository contains utilities for efficiently performing Win32 IO operations in
+Go. Currently, this is focused on accessing named pipes and other file handles, and
+for using named pipes as a net transport.
+
+This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
+to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
+newer operating systems. This is similar to the implementation of network sockets in Go's net
+package.
+
+Please see the LICENSE file for licensing information.
+
+## Contributing
+
+This project welcomes contributions and suggestions.
+Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
+you have the right to, and actually do, grant us the rights to use your contribution.
+For details, visit [Microsoft CLA](https://cla.microsoft.com).
+
+When you submit a pull request, a CLA-bot will automatically determine whether you need to
+provide a CLA and decorate the PR appropriately (e.g., label, comment).
+Simply follow the instructions provided by the bot.
+You will only need to do this once across all repos using our CLA.
+
+Additionally, the pull request pipeline requires the following steps to be performed before
+mergining.
+
+### Code Sign-Off
+
+We require that contributors sign their commits using [`git commit --signoff`][git-commit-s]
+to certify they either authored the work themselves or otherwise have permission to use it in this project.
+
+A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].
+
+Please see [the developer certificate](https://developercertificate.org) for more info,
+as well as to make sure that you can attest to the rules listed.
+Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off.
+
+### Linting
+
+Code must pass a linting stage, which uses [`golangci-lint`][lint].
+The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run
+automatically with VSCode by adding the following to your workspace or folder settings:
+
+```json
+ "go.lintTool": "golangci-lint",
+ "go.lintOnSave": "package",
+```
+
+Additional editor [integrations options are also available][lint-ide].
+
+Alternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root:
+
+```shell
+# use . or specify a path to only lint a package
+# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0"
+> golangci-lint run ./...
+```
+
+### Go Generate
+
+The pipeline checks that auto-generated code, via `go generate`, are up to date.
+
+This can be done for the entire repo:
+
+```shell
+> go generate ./...
+```
+
+## Code of Conduct
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
+contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Special Thanks
+
+Thanks to [natefinch][natefinch] for the inspiration for this library.
+See [npipe](https://github.com/natefinch/npipe) for another named pipe implementation.
+
+[lint]: https://golangci-lint.run/
+[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration
+[lint-install]: https://golangci-lint.run/usage/install/#local-installation
+
+[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s
+[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff
+
+[natefinch]: https://github.com/natefinch
diff --git a/vendor/github.com/Microsoft/go-winio/SECURITY.md b/vendor/github.com/Microsoft/go-winio/SECURITY.md
new file mode 100644
index 0000000..869fdfe
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/SECURITY.md
@@ -0,0 +1,41 @@
+
+
+## Security
+
+Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
+
+If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
+
+## Reporting Security Issues
+
+**Please do not report security vulnerabilities through public GitHub issues.**
+
+Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
+
+If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
+
+You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
+
+Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
+
+ * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
+ * Full paths of source file(s) related to the manifestation of the issue
+ * The location of the affected source code (tag/branch/commit or direct URL)
+ * Any special configuration required to reproduce the issue
+ * Step-by-step instructions to reproduce the issue
+ * Proof-of-concept or exploit code (if possible)
+ * Impact of the issue, including how an attacker might exploit the issue
+
+This information will help us triage your report more quickly.
+
+If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
+
+## Preferred Languages
+
+We prefer all communications to be in English.
+
+## Policy
+
+Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
+
+
diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go
new file mode 100644
index 0000000..b54341d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/backup.go
@@ -0,0 +1,287 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "unicode/utf16"
+
+ "github.com/Microsoft/go-winio/internal/fs"
+ "golang.org/x/sys/windows"
+)
+
+//sys backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
+//sys backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
+
+const (
+ BackupData = uint32(iota + 1)
+ BackupEaData
+ BackupSecurity
+ BackupAlternateData
+ BackupLink
+ BackupPropertyData
+ BackupObjectId //revive:disable-line:var-naming ID, not Id
+ BackupReparseData
+ BackupSparseBlock
+ BackupTxfsData
+)
+
+const (
+ StreamSparseAttributes = uint32(8)
+)
+
+//nolint:revive // var-naming: ALL_CAPS
+const (
+ WRITE_DAC = windows.WRITE_DAC
+ WRITE_OWNER = windows.WRITE_OWNER
+ ACCESS_SYSTEM_SECURITY = windows.ACCESS_SYSTEM_SECURITY
+)
+
+// BackupHeader represents a backup stream of a file.
+type BackupHeader struct {
+ //revive:disable-next-line:var-naming ID, not Id
+ Id uint32 // The backup stream ID
+ Attributes uint32 // Stream attributes
+ Size int64 // The size of the stream in bytes
+ Name string // The name of the stream (for BackupAlternateData only).
+ Offset int64 // The offset of the stream in the file (for BackupSparseBlock only).
+}
+
+type win32StreamID struct {
+ StreamID uint32
+ Attributes uint32
+ Size uint64
+ NameSize uint32
+}
+
+// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series
+// of BackupHeader values.
+type BackupStreamReader struct {
+ r io.Reader
+ bytesLeft int64
+}
+
+// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.
+func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
+ return &BackupStreamReader{r, 0}
+}
+
+// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
+// it was not completely read.
+func (r *BackupStreamReader) Next() (*BackupHeader, error) {
+ if r.bytesLeft > 0 { //nolint:nestif // todo: flatten this
+ if s, ok := r.r.(io.Seeker); ok {
+ // Make sure Seek on io.SeekCurrent sometimes succeeds
+ // before trying the actual seek.
+ if _, err := s.Seek(0, io.SeekCurrent); err == nil {
+ if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ r.bytesLeft = 0
+ }
+ }
+ if _, err := io.Copy(io.Discard, r); err != nil {
+ return nil, err
+ }
+ }
+ var wsi win32StreamID
+ if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
+ return nil, err
+ }
+ hdr := &BackupHeader{
+ Id: wsi.StreamID,
+ Attributes: wsi.Attributes,
+ Size: int64(wsi.Size),
+ }
+ if wsi.NameSize != 0 {
+ name := make([]uint16, int(wsi.NameSize/2))
+ if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
+ return nil, err
+ }
+ hdr.Name = windows.UTF16ToString(name)
+ }
+ if wsi.StreamID == BackupSparseBlock {
+ if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
+ return nil, err
+ }
+ hdr.Size -= 8
+ }
+ r.bytesLeft = hdr.Size
+ return hdr, nil
+}
+
+// Read reads from the current backup stream.
+func (r *BackupStreamReader) Read(b []byte) (int, error) {
+ if r.bytesLeft == 0 {
+ return 0, io.EOF
+ }
+ if int64(len(b)) > r.bytesLeft {
+ b = b[:r.bytesLeft]
+ }
+ n, err := r.r.Read(b)
+ r.bytesLeft -= int64(n)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ } else if r.bytesLeft == 0 && err == nil {
+ err = io.EOF
+ }
+ return n, err
+}
+
+// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.
+type BackupStreamWriter struct {
+ w io.Writer
+ bytesLeft int64
+}
+
+// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.
+func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {
+ return &BackupStreamWriter{w, 0}
+}
+
+// WriteHeader writes the next backup stream header and prepares for calls to Write().
+func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
+ if w.bytesLeft != 0 {
+ return fmt.Errorf("missing %d bytes", w.bytesLeft)
+ }
+ name := utf16.Encode([]rune(hdr.Name))
+ wsi := win32StreamID{
+ StreamID: hdr.Id,
+ Attributes: hdr.Attributes,
+ Size: uint64(hdr.Size),
+ NameSize: uint32(len(name) * 2),
+ }
+ if hdr.Id == BackupSparseBlock {
+ // Include space for the int64 block offset
+ wsi.Size += 8
+ }
+ if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {
+ return err
+ }
+ if len(name) != 0 {
+ if err := binary.Write(w.w, binary.LittleEndian, name); err != nil {
+ return err
+ }
+ }
+ if hdr.Id == BackupSparseBlock {
+ if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {
+ return err
+ }
+ }
+ w.bytesLeft = hdr.Size
+ return nil
+}
+
+// Write writes to the current backup stream.
+func (w *BackupStreamWriter) Write(b []byte) (int, error) {
+ if w.bytesLeft < int64(len(b)) {
+ return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft)
+ }
+ n, err := w.w.Write(b)
+ w.bytesLeft -= int64(n)
+ return n, err
+}
+
+// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.
+type BackupFileReader struct {
+ f *os.File
+ includeSecurity bool
+ ctx uintptr
+}
+
+// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,
+// Read will attempt to read the security descriptor of the file.
+func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
+ r := &BackupFileReader{f, includeSecurity, 0}
+ return r
+}
+
+// Read reads a backup stream from the file by calling the Win32 API BackupRead().
+func (r *BackupFileReader) Read(b []byte) (int, error) {
+ var bytesRead uint32
+ err := backupRead(windows.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
+ if err != nil {
+ return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err}
+ }
+ runtime.KeepAlive(r.f)
+ if bytesRead == 0 {
+ return 0, io.EOF
+ }
+ return int(bytesRead), nil
+}
+
+// Close frees Win32 resources associated with the BackupFileReader. It does not close
+// the underlying file.
+func (r *BackupFileReader) Close() error {
+ if r.ctx != 0 {
+ _ = backupRead(windows.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
+ runtime.KeepAlive(r.f)
+ r.ctx = 0
+ }
+ return nil
+}
+
+// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.
+type BackupFileWriter struct {
+ f *os.File
+ includeSecurity bool
+ ctx uintptr
+}
+
+// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,
+// Write() will attempt to restore the security descriptor from the stream.
+func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
+ w := &BackupFileWriter{f, includeSecurity, 0}
+ return w
+}
+
+// Write restores a portion of the file using the provided backup stream.
+func (w *BackupFileWriter) Write(b []byte) (int, error) {
+ var bytesWritten uint32
+ err := backupWrite(windows.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
+ if err != nil {
+ return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err}
+ }
+ runtime.KeepAlive(w.f)
+ if int(bytesWritten) != len(b) {
+ return int(bytesWritten), errors.New("not all bytes could be written")
+ }
+ return len(b), nil
+}
+
+// Close frees Win32 resources associated with the BackupFileWriter. It does not
+// close the underlying file.
+func (w *BackupFileWriter) Close() error {
+ if w.ctx != 0 {
+ _ = backupWrite(windows.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
+ runtime.KeepAlive(w.f)
+ w.ctx = 0
+ }
+ return nil
+}
+
+// OpenForBackup opens a file or directory, potentially skipping access checks if the backup
+// or restore privileges have been acquired.
+//
+// If the file opened was a directory, it cannot be used with Readdir().
+func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
+ h, err := fs.CreateFile(path,
+ fs.AccessMask(access),
+ fs.FileShareMode(share),
+ nil,
+ fs.FileCreationDisposition(createmode),
+ fs.FILE_FLAG_BACKUP_SEMANTICS|fs.FILE_FLAG_OPEN_REPARSE_POINT,
+ 0,
+ )
+ if err != nil {
+ err = &os.PathError{Op: "open", Path: path, Err: err}
+ return nil, err
+ }
+ return os.NewFile(uintptr(h), path), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/doc.go b/vendor/github.com/Microsoft/go-winio/doc.go
new file mode 100644
index 0000000..1f5bfe2
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/doc.go
@@ -0,0 +1,22 @@
+// This package provides utilities for efficiently performing Win32 IO operations in Go.
+// Currently, this package is provides support for genreal IO and management of
+// - named pipes
+// - files
+// - [Hyper-V sockets]
+//
+// This code is similar to Go's [net] package, and uses IO completion ports to avoid
+// blocking IO on system threads, allowing Go to reuse the thread to schedule other goroutines.
+//
+// This limits support to Windows Vista and newer operating systems.
+//
+// Additionally, this package provides support for:
+// - creating and managing GUIDs
+// - writing to [ETW]
+// - opening and manageing VHDs
+// - parsing [Windows Image files]
+// - auto-generating Win32 API code
+//
+// [Hyper-V sockets]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
+// [ETW]: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-
+// [Windows Image files]: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/work-with-windows-images
+package winio
diff --git a/vendor/github.com/Microsoft/go-winio/ea.go b/vendor/github.com/Microsoft/go-winio/ea.go
new file mode 100644
index 0000000..e104dbd
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/ea.go
@@ -0,0 +1,137 @@
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+)
+
+type fileFullEaInformation struct {
+ NextEntryOffset uint32
+ Flags uint8
+ NameLength uint8
+ ValueLength uint16
+}
+
+var (
+ fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
+
+ errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
+ errEaNameTooLarge = errors.New("extended attribute name too large")
+ errEaValueTooLarge = errors.New("extended attribute value too large")
+)
+
+// ExtendedAttribute represents a single Windows EA.
+type ExtendedAttribute struct {
+ Name string
+ Value []byte
+ Flags uint8
+}
+
+func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
+ var info fileFullEaInformation
+ err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
+ if err != nil {
+ err = errInvalidEaBuffer
+ return ea, nb, err
+ }
+
+ nameOffset := fileFullEaInformationSize
+ nameLen := int(info.NameLength)
+ valueOffset := nameOffset + int(info.NameLength) + 1
+ valueLen := int(info.ValueLength)
+ nextOffset := int(info.NextEntryOffset)
+ if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
+ err = errInvalidEaBuffer
+ return ea, nb, err
+ }
+
+ ea.Name = string(b[nameOffset : nameOffset+nameLen])
+ ea.Value = b[valueOffset : valueOffset+valueLen]
+ ea.Flags = info.Flags
+ if info.NextEntryOffset != 0 {
+ nb = b[info.NextEntryOffset:]
+ }
+ return ea, nb, err
+}
+
+// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
+// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
+func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
+ for len(b) != 0 {
+ ea, nb, err := parseEa(b)
+ if err != nil {
+ return nil, err
+ }
+
+ eas = append(eas, ea)
+ b = nb
+ }
+ return eas, err
+}
+
+func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
+ if int(uint8(len(ea.Name))) != len(ea.Name) {
+ return errEaNameTooLarge
+ }
+ if int(uint16(len(ea.Value))) != len(ea.Value) {
+ return errEaValueTooLarge
+ }
+ entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
+ withPadding := (entrySize + 3) &^ 3
+ nextOffset := uint32(0)
+ if !last {
+ nextOffset = withPadding
+ }
+ info := fileFullEaInformation{
+ NextEntryOffset: nextOffset,
+ Flags: ea.Flags,
+ NameLength: uint8(len(ea.Name)),
+ ValueLength: uint16(len(ea.Value)),
+ }
+
+ err := binary.Write(buf, binary.LittleEndian, &info)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte(ea.Name))
+ if err != nil {
+ return err
+ }
+
+ err = buf.WriteByte(0)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write(ea.Value)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
+// buffer for use with BackupWrite, ZwSetEaFile, etc.
+func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
+ var buf bytes.Buffer
+ for i := range eas {
+ last := false
+ if i == len(eas)-1 {
+ last = true
+ }
+
+ err := writeEa(&buf, &eas[i], last)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return buf.Bytes(), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go
new file mode 100644
index 0000000..fe82a18
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/file.go
@@ -0,0 +1,320 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "errors"
+ "io"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "syscall"
+ "time"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) = CancelIoEx
+//sys createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) = CreateIoCompletionPort
+//sys getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
+//sys setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
+//sys wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
+
+var (
+ ErrFileClosed = errors.New("file has already been closed")
+ ErrTimeout = &timeoutError{}
+)
+
+type timeoutError struct{}
+
+func (*timeoutError) Error() string { return "i/o timeout" }
+func (*timeoutError) Timeout() bool { return true }
+func (*timeoutError) Temporary() bool { return true }
+
+type timeoutChan chan struct{}
+
+var ioInitOnce sync.Once
+var ioCompletionPort windows.Handle
+
+// ioResult contains the result of an asynchronous IO operation.
+type ioResult struct {
+ bytes uint32
+ err error
+}
+
+// ioOperation represents an outstanding asynchronous Win32 IO.
+type ioOperation struct {
+ o windows.Overlapped
+ ch chan ioResult
+}
+
+func initIO() {
+ h, err := createIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff)
+ if err != nil {
+ panic(err)
+ }
+ ioCompletionPort = h
+ go ioCompletionProcessor(h)
+}
+
+// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
+// It takes ownership of this handle and will close it if it is garbage collected.
+type win32File struct {
+ handle windows.Handle
+ wg sync.WaitGroup
+ wgLock sync.RWMutex
+ closing atomic.Bool
+ socket bool
+ readDeadline deadlineHandler
+ writeDeadline deadlineHandler
+}
+
+type deadlineHandler struct {
+ setLock sync.Mutex
+ channel timeoutChan
+ channelLock sync.RWMutex
+ timer *time.Timer
+ timedout atomic.Bool
+}
+
+// makeWin32File makes a new win32File from an existing file handle.
+func makeWin32File(h windows.Handle) (*win32File, error) {
+ f := &win32File{handle: h}
+ ioInitOnce.Do(initIO)
+ _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
+ if err != nil {
+ return nil, err
+ }
+ err = setFileCompletionNotificationModes(h, windows.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS|windows.FILE_SKIP_SET_EVENT_ON_HANDLE)
+ if err != nil {
+ return nil, err
+ }
+ f.readDeadline.channel = make(timeoutChan)
+ f.writeDeadline.channel = make(timeoutChan)
+ return f, nil
+}
+
+// Deprecated: use NewOpenFile instead.
+func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
+ return NewOpenFile(windows.Handle(h))
+}
+
+func NewOpenFile(h windows.Handle) (io.ReadWriteCloser, error) {
+ // If we return the result of makeWin32File directly, it can result in an
+ // interface-wrapped nil, rather than a nil interface value.
+ f, err := makeWin32File(h)
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
+// closeHandle closes the resources associated with a Win32 handle.
+func (f *win32File) closeHandle() {
+ f.wgLock.Lock()
+ // Atomically set that we are closing, releasing the resources only once.
+ if !f.closing.Swap(true) {
+ f.wgLock.Unlock()
+ // cancel all IO and wait for it to complete
+ _ = cancelIoEx(f.handle, nil)
+ f.wg.Wait()
+ // at this point, no new IO can start
+ windows.Close(f.handle)
+ f.handle = 0
+ } else {
+ f.wgLock.Unlock()
+ }
+}
+
+// Close closes a win32File.
+func (f *win32File) Close() error {
+ f.closeHandle()
+ return nil
+}
+
+// IsClosed checks if the file has been closed.
+func (f *win32File) IsClosed() bool {
+ return f.closing.Load()
+}
+
+// prepareIO prepares for a new IO operation.
+// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
+func (f *win32File) prepareIO() (*ioOperation, error) {
+ f.wgLock.RLock()
+ if f.closing.Load() {
+ f.wgLock.RUnlock()
+ return nil, ErrFileClosed
+ }
+ f.wg.Add(1)
+ f.wgLock.RUnlock()
+ c := &ioOperation{}
+ c.ch = make(chan ioResult)
+ return c, nil
+}
+
+// ioCompletionProcessor processes completed async IOs forever.
+func ioCompletionProcessor(h windows.Handle) {
+ for {
+ var bytes uint32
+ var key uintptr
+ var op *ioOperation
+ err := getQueuedCompletionStatus(h, &bytes, &key, &op, windows.INFINITE)
+ if op == nil {
+ panic(err)
+ }
+ op.ch <- ioResult{bytes, err}
+ }
+}
+
+// todo: helsaawy - create an asyncIO version that takes a context
+
+// asyncIO processes the return value from ReadFile or WriteFile, blocking until
+// the operation has actually completed.
+func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
+ if err != windows.ERROR_IO_PENDING { //nolint:errorlint // err is Errno
+ return int(bytes), err
+ }
+
+ if f.closing.Load() {
+ _ = cancelIoEx(f.handle, &c.o)
+ }
+
+ var timeout timeoutChan
+ if d != nil {
+ d.channelLock.Lock()
+ timeout = d.channel
+ d.channelLock.Unlock()
+ }
+
+ var r ioResult
+ select {
+ case r = <-c.ch:
+ err = r.err
+ if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
+ if f.closing.Load() {
+ err = ErrFileClosed
+ }
+ } else if err != nil && f.socket {
+ // err is from Win32. Query the overlapped structure to get the winsock error.
+ var bytes, flags uint32
+ err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
+ }
+ case <-timeout:
+ _ = cancelIoEx(f.handle, &c.o)
+ r = <-c.ch
+ err = r.err
+ if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
+ err = ErrTimeout
+ }
+ }
+
+ // runtime.KeepAlive is needed, as c is passed via native
+ // code to ioCompletionProcessor, c must remain alive
+ // until the channel read is complete.
+ // todo: (de)allocate *ioOperation via win32 heap functions, instead of needing to KeepAlive?
+ runtime.KeepAlive(c)
+ return int(r.bytes), err
+}
+
+// Read reads from a file handle.
+func (f *win32File) Read(b []byte) (int, error) {
+ c, err := f.prepareIO()
+ if err != nil {
+ return 0, err
+ }
+ defer f.wg.Done()
+
+ if f.readDeadline.timedout.Load() {
+ return 0, ErrTimeout
+ }
+
+ var bytes uint32
+ err = windows.ReadFile(f.handle, b, &bytes, &c.o)
+ n, err := f.asyncIO(c, &f.readDeadline, bytes, err)
+ runtime.KeepAlive(b)
+
+ // Handle EOF conditions.
+ if err == nil && n == 0 && len(b) != 0 {
+ return 0, io.EOF
+ } else if err == windows.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
+ return 0, io.EOF
+ }
+ return n, err
+}
+
+// Write writes to a file handle.
+func (f *win32File) Write(b []byte) (int, error) {
+ c, err := f.prepareIO()
+ if err != nil {
+ return 0, err
+ }
+ defer f.wg.Done()
+
+ if f.writeDeadline.timedout.Load() {
+ return 0, ErrTimeout
+ }
+
+ var bytes uint32
+ err = windows.WriteFile(f.handle, b, &bytes, &c.o)
+ n, err := f.asyncIO(c, &f.writeDeadline, bytes, err)
+ runtime.KeepAlive(b)
+ return n, err
+}
+
+func (f *win32File) SetReadDeadline(deadline time.Time) error {
+ return f.readDeadline.set(deadline)
+}
+
+func (f *win32File) SetWriteDeadline(deadline time.Time) error {
+ return f.writeDeadline.set(deadline)
+}
+
+func (f *win32File) Flush() error {
+ return windows.FlushFileBuffers(f.handle)
+}
+
+func (f *win32File) Fd() uintptr {
+ return uintptr(f.handle)
+}
+
+func (d *deadlineHandler) set(deadline time.Time) error {
+ d.setLock.Lock()
+ defer d.setLock.Unlock()
+
+ if d.timer != nil {
+ if !d.timer.Stop() {
+ <-d.channel
+ }
+ d.timer = nil
+ }
+ d.timedout.Store(false)
+
+ select {
+ case <-d.channel:
+ d.channelLock.Lock()
+ d.channel = make(chan struct{})
+ d.channelLock.Unlock()
+ default:
+ }
+
+ if deadline.IsZero() {
+ return nil
+ }
+
+ timeoutIO := func() {
+ d.timedout.Store(true)
+ close(d.channel)
+ }
+
+ now := time.Now()
+ duration := deadline.Sub(now)
+ if deadline.After(now) {
+ // Deadline is in the future, set a timer to wait
+ d.timer = time.AfterFunc(duration, timeoutIO)
+ } else {
+ // Deadline is in the past. Cancel all pending IO now.
+ timeoutIO()
+ }
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/fileinfo.go b/vendor/github.com/Microsoft/go-winio/fileinfo.go
new file mode 100644
index 0000000..c860eb9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/fileinfo.go
@@ -0,0 +1,106 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "os"
+ "runtime"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// FileBasicInfo contains file access time and file attributes information.
+type FileBasicInfo struct {
+ CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
+ FileAttributes uint32
+ _ uint32 // padding
+}
+
+// alignedFileBasicInfo is a FileBasicInfo, but aligned to uint64 by containing
+// uint64 rather than windows.Filetime. Filetime contains two uint32s. uint64
+// alignment is necessary to pass this as FILE_BASIC_INFO.
+type alignedFileBasicInfo struct {
+ CreationTime, LastAccessTime, LastWriteTime, ChangeTime uint64
+ FileAttributes uint32
+ _ uint32 // padding
+}
+
+// GetFileBasicInfo retrieves times and attributes for a file.
+func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
+ bi := &alignedFileBasicInfo{}
+ if err := windows.GetFileInformationByHandleEx(
+ windows.Handle(f.Fd()),
+ windows.FileBasicInfo,
+ (*byte)(unsafe.Pointer(bi)),
+ uint32(unsafe.Sizeof(*bi)),
+ ); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ // Reinterpret the alignedFileBasicInfo as a FileBasicInfo so it matches the
+ // public API of this module. The data may be unnecessarily aligned.
+ return (*FileBasicInfo)(unsafe.Pointer(bi)), nil
+}
+
+// SetFileBasicInfo sets times and attributes for a file.
+func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
+ // Create an alignedFileBasicInfo based on a FileBasicInfo. The copy is
+ // suitable to pass to GetFileInformationByHandleEx.
+ biAligned := *(*alignedFileBasicInfo)(unsafe.Pointer(bi))
+ if err := windows.SetFileInformationByHandle(
+ windows.Handle(f.Fd()),
+ windows.FileBasicInfo,
+ (*byte)(unsafe.Pointer(&biAligned)),
+ uint32(unsafe.Sizeof(biAligned)),
+ ); err != nil {
+ return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return nil
+}
+
+// FileStandardInfo contains extended information for the file.
+// FILE_STANDARD_INFO in WinBase.h
+// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
+type FileStandardInfo struct {
+ AllocationSize, EndOfFile int64
+ NumberOfLinks uint32
+ DeletePending, Directory bool
+}
+
+// GetFileStandardInfo retrieves ended information for the file.
+func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
+ si := &FileStandardInfo{}
+ if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()),
+ windows.FileStandardInfo,
+ (*byte)(unsafe.Pointer(si)),
+ uint32(unsafe.Sizeof(*si))); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return si, nil
+}
+
+// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
+// unique on a system.
+type FileIDInfo struct {
+ VolumeSerialNumber uint64
+ FileID [16]byte
+}
+
+// GetFileID retrieves the unique (volume, file ID) pair for a file.
+func GetFileID(f *os.File) (*FileIDInfo, error) {
+ fileID := &FileIDInfo{}
+ if err := windows.GetFileInformationByHandleEx(
+ windows.Handle(f.Fd()),
+ windows.FileIdInfo,
+ (*byte)(unsafe.Pointer(fileID)),
+ uint32(unsafe.Sizeof(*fileID)),
+ ); err != nil {
+ return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+ }
+ runtime.KeepAlive(f)
+ return fileID, nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/hvsock.go b/vendor/github.com/Microsoft/go-winio/hvsock.go
new file mode 100644
index 0000000..c4fdd9d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/hvsock.go
@@ -0,0 +1,582 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "time"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/socket"
+ "github.com/Microsoft/go-winio/pkg/guid"
+)
+
+const afHVSock = 34 // AF_HYPERV
+
+// Well known Service and VM IDs
+// https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#vmid-wildcards
+
+// HvsockGUIDWildcard is the wildcard VmId for accepting connections from all partitions.
+func HvsockGUIDWildcard() guid.GUID { // 00000000-0000-0000-0000-000000000000
+ return guid.GUID{}
+}
+
+// HvsockGUIDBroadcast is the wildcard VmId for broadcasting sends to all partitions.
+func HvsockGUIDBroadcast() guid.GUID { // ffffffff-ffff-ffff-ffff-ffffffffffff
+ return guid.GUID{
+ Data1: 0xffffffff,
+ Data2: 0xffff,
+ Data3: 0xffff,
+ Data4: [8]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+ }
+}
+
+// HvsockGUIDLoopback is the Loopback VmId for accepting connections to the same partition as the connector.
+func HvsockGUIDLoopback() guid.GUID { // e0e16197-dd56-4a10-9195-5ee7a155a838
+ return guid.GUID{
+ Data1: 0xe0e16197,
+ Data2: 0xdd56,
+ Data3: 0x4a10,
+ Data4: [8]uint8{0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38},
+ }
+}
+
+// HvsockGUIDSiloHost is the address of a silo's host partition:
+// - The silo host of a hosted silo is the utility VM.
+// - The silo host of a silo on a physical host is the physical host.
+func HvsockGUIDSiloHost() guid.GUID { // 36bd0c5c-7276-4223-88ba-7d03b654c568
+ return guid.GUID{
+ Data1: 0x36bd0c5c,
+ Data2: 0x7276,
+ Data3: 0x4223,
+ Data4: [8]byte{0x88, 0xba, 0x7d, 0x03, 0xb6, 0x54, 0xc5, 0x68},
+ }
+}
+
+// HvsockGUIDChildren is the wildcard VmId for accepting connections from the connector's child partitions.
+func HvsockGUIDChildren() guid.GUID { // 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd
+ return guid.GUID{
+ Data1: 0x90db8b89,
+ Data2: 0xd35,
+ Data3: 0x4f79,
+ Data4: [8]uint8{0x8c, 0xe9, 0x49, 0xea, 0xa, 0xc8, 0xb7, 0xcd},
+ }
+}
+
+// HvsockGUIDParent is the wildcard VmId for accepting connections from the connector's parent partition.
+// Listening on this VmId accepts connection from:
+// - Inside silos: silo host partition.
+// - Inside hosted silo: host of the VM.
+// - Inside VM: VM host.
+// - Physical host: Not supported.
+func HvsockGUIDParent() guid.GUID { // a42e7cda-d03f-480c-9cc2-a4de20abb878
+ return guid.GUID{
+ Data1: 0xa42e7cda,
+ Data2: 0xd03f,
+ Data3: 0x480c,
+ Data4: [8]uint8{0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78},
+ }
+}
+
+// hvsockVsockServiceTemplate is the Service GUID used for the VSOCK protocol.
+func hvsockVsockServiceTemplate() guid.GUID { // 00000000-facb-11e6-bd58-64006a7986d3
+ return guid.GUID{
+ Data2: 0xfacb,
+ Data3: 0x11e6,
+ Data4: [8]uint8{0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3},
+ }
+}
+
+// An HvsockAddr is an address for a AF_HYPERV socket.
+type HvsockAddr struct {
+ VMID guid.GUID
+ ServiceID guid.GUID
+}
+
+type rawHvsockAddr struct {
+ Family uint16
+ _ uint16
+ VMID guid.GUID
+ ServiceID guid.GUID
+}
+
+var _ socket.RawSockaddr = &rawHvsockAddr{}
+
+// Network returns the address's network name, "hvsock".
+func (*HvsockAddr) Network() string {
+ return "hvsock"
+}
+
+func (addr *HvsockAddr) String() string {
+ return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
+}
+
+// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
+func VsockServiceID(port uint32) guid.GUID {
+ g := hvsockVsockServiceTemplate() // make a copy
+ g.Data1 = port
+ return g
+}
+
+func (addr *HvsockAddr) raw() rawHvsockAddr {
+ return rawHvsockAddr{
+ Family: afHVSock,
+ VMID: addr.VMID,
+ ServiceID: addr.ServiceID,
+ }
+}
+
+func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
+ addr.VMID = raw.VMID
+ addr.ServiceID = raw.ServiceID
+}
+
+// Sockaddr returns a pointer to and the size of this struct.
+//
+// Implements the [socket.RawSockaddr] interface, and allows use in
+// [socket.Bind] and [socket.ConnectEx].
+func (r *rawHvsockAddr) Sockaddr() (unsafe.Pointer, int32, error) {
+ return unsafe.Pointer(r), int32(unsafe.Sizeof(rawHvsockAddr{})), nil
+}
+
+// Sockaddr interface allows use with `sockets.Bind()` and `.ConnectEx()`.
+func (r *rawHvsockAddr) FromBytes(b []byte) error {
+ n := int(unsafe.Sizeof(rawHvsockAddr{}))
+
+ if len(b) < n {
+ return fmt.Errorf("got %d, want %d: %w", len(b), n, socket.ErrBufferSize)
+ }
+
+ copy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), b[:n])
+ if r.Family != afHVSock {
+ return fmt.Errorf("got %d, want %d: %w", r.Family, afHVSock, socket.ErrAddrFamily)
+ }
+
+ return nil
+}
+
+// HvsockListener is a socket listener for the AF_HYPERV address family.
+type HvsockListener struct {
+ sock *win32File
+ addr HvsockAddr
+}
+
+var _ net.Listener = &HvsockListener{}
+
+// HvsockConn is a connected socket of the AF_HYPERV address family.
+type HvsockConn struct {
+ sock *win32File
+ local, remote HvsockAddr
+}
+
+var _ net.Conn = &HvsockConn{}
+
+func newHVSocket() (*win32File, error) {
+ fd, err := windows.Socket(afHVSock, windows.SOCK_STREAM, 1)
+ if err != nil {
+ return nil, os.NewSyscallError("socket", err)
+ }
+ f, err := makeWin32File(fd)
+ if err != nil {
+ windows.Close(fd)
+ return nil, err
+ }
+ f.socket = true
+ return f, nil
+}
+
+// ListenHvsock listens for connections on the specified hvsock address.
+func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
+ l := &HvsockListener{addr: *addr}
+
+ var sock *win32File
+ sock, err = newHVSocket()
+ if err != nil {
+ return nil, l.opErr("listen", err)
+ }
+ defer func() {
+ if err != nil {
+ _ = sock.Close()
+ }
+ }()
+
+ sa := addr.raw()
+ err = socket.Bind(sock.handle, &sa)
+ if err != nil {
+ return nil, l.opErr("listen", os.NewSyscallError("socket", err))
+ }
+ err = windows.Listen(sock.handle, 16)
+ if err != nil {
+ return nil, l.opErr("listen", os.NewSyscallError("listen", err))
+ }
+ return &HvsockListener{sock: sock, addr: *addr}, nil
+}
+
+func (l *HvsockListener) opErr(op string, err error) error {
+ return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
+}
+
+// Addr returns the listener's network address.
+func (l *HvsockListener) Addr() net.Addr {
+ return &l.addr
+}
+
+// Accept waits for the next connection and returns it.
+func (l *HvsockListener) Accept() (_ net.Conn, err error) {
+ sock, err := newHVSocket()
+ if err != nil {
+ return nil, l.opErr("accept", err)
+ }
+ defer func() {
+ if sock != nil {
+ sock.Close()
+ }
+ }()
+ c, err := l.sock.prepareIO()
+ if err != nil {
+ return nil, l.opErr("accept", err)
+ }
+ defer l.sock.wg.Done()
+
+ // AcceptEx, per documentation, requires an extra 16 bytes per address.
+ //
+ // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex
+ const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
+ var addrbuf [addrlen * 2]byte
+
+ var bytes uint32
+ err = windows.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)
+ if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil {
+ return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
+ }
+
+ conn := &HvsockConn{
+ sock: sock,
+ }
+ // The local address returned in the AcceptEx buffer is the same as the Listener socket's
+ // address. However, the service GUID reported by GetSockName is different from the Listeners
+ // socket, and is sometimes the same as the local address of the socket that dialed the
+ // address, with the service GUID.Data1 incremented, but othertimes is different.
+ // todo: does the local address matter? is the listener's address or the actual address appropriate?
+ conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
+ conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
+
+ // initialize the accepted socket and update its properties with those of the listening socket
+ if err = windows.Setsockopt(sock.handle,
+ windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT,
+ (*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil {
+ return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err))
+ }
+
+ sock = nil
+ return conn, nil
+}
+
+// Close closes the listener, causing any pending Accept calls to fail.
+func (l *HvsockListener) Close() error {
+ return l.sock.Close()
+}
+
+// HvsockDialer configures and dials a Hyper-V Socket (ie, [HvsockConn]).
+type HvsockDialer struct {
+ // Deadline is the time the Dial operation must connect before erroring.
+ Deadline time.Time
+
+ // Retries is the number of additional connects to try if the connection times out, is refused,
+ // or the host is unreachable
+ Retries uint
+
+ // RetryWait is the time to wait after a connection error to retry
+ RetryWait time.Duration
+
+ rt *time.Timer // redial wait timer
+}
+
+// Dial the Hyper-V socket at addr.
+//
+// See [HvsockDialer.Dial] for more information.
+func Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
+ return (&HvsockDialer{}).Dial(ctx, addr)
+}
+
+// Dial attempts to connect to the Hyper-V socket at addr, and returns a connection if successful.
+// Will attempt (HvsockDialer).Retries if dialing fails, waiting (HvsockDialer).RetryWait between
+// retries.
+//
+// Dialing can be cancelled either by providing (HvsockDialer).Deadline, or cancelling ctx.
+func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
+ op := "dial"
+ // create the conn early to use opErr()
+ conn = &HvsockConn{
+ remote: *addr,
+ }
+
+ if !d.Deadline.IsZero() {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithDeadline(ctx, d.Deadline)
+ defer cancel()
+ }
+
+ // preemptive timeout/cancellation check
+ if err = ctx.Err(); err != nil {
+ return nil, conn.opErr(op, err)
+ }
+
+ sock, err := newHVSocket()
+ if err != nil {
+ return nil, conn.opErr(op, err)
+ }
+ defer func() {
+ if sock != nil {
+ sock.Close()
+ }
+ }()
+
+ sa := addr.raw()
+ err = socket.Bind(sock.handle, &sa)
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("bind", err))
+ }
+
+ c, err := sock.prepareIO()
+ if err != nil {
+ return nil, conn.opErr(op, err)
+ }
+ defer sock.wg.Done()
+ var bytes uint32
+ for i := uint(0); i <= d.Retries; i++ {
+ err = socket.ConnectEx(
+ sock.handle,
+ &sa,
+ nil, // sendBuf
+ 0, // sendDataLen
+ &bytes,
+ (*windows.Overlapped)(unsafe.Pointer(&c.o)))
+ _, err = sock.asyncIO(c, nil, bytes, err)
+ if i < d.Retries && canRedial(err) {
+ if err = d.redialWait(ctx); err == nil {
+ continue
+ }
+ }
+ break
+ }
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("connectex", err))
+ }
+
+ // update the connection properties, so shutdown can be used
+ if err = windows.Setsockopt(
+ sock.handle,
+ windows.SOL_SOCKET,
+ windows.SO_UPDATE_CONNECT_CONTEXT,
+ nil, // optvalue
+ 0, // optlen
+ ); err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("setsockopt", err))
+ }
+
+ // get the local name
+ var sal rawHvsockAddr
+ err = socket.GetSockName(sock.handle, &sal)
+ if err != nil {
+ return nil, conn.opErr(op, os.NewSyscallError("getsockname", err))
+ }
+ conn.local.fromRaw(&sal)
+
+ // one last check for timeout, since asyncIO doesn't check the context
+ if err = ctx.Err(); err != nil {
+ return nil, conn.opErr(op, err)
+ }
+
+ conn.sock = sock
+ sock = nil
+
+ return conn, nil
+}
+
+// redialWait waits before attempting to redial, resetting the timer as appropriate.
+func (d *HvsockDialer) redialWait(ctx context.Context) (err error) {
+ if d.RetryWait == 0 {
+ return nil
+ }
+
+ if d.rt == nil {
+ d.rt = time.NewTimer(d.RetryWait)
+ } else {
+ // should already be stopped and drained
+ d.rt.Reset(d.RetryWait)
+ }
+
+ select {
+ case <-ctx.Done():
+ case <-d.rt.C:
+ return nil
+ }
+
+ // stop and drain the timer
+ if !d.rt.Stop() {
+ <-d.rt.C
+ }
+ return ctx.Err()
+}
+
+// assumes error is a plain, unwrapped windows.Errno provided by direct syscall.
+func canRedial(err error) bool {
+ //nolint:errorlint // guaranteed to be an Errno
+ switch err {
+ case windows.WSAECONNREFUSED, windows.WSAENETUNREACH, windows.WSAETIMEDOUT,
+ windows.ERROR_CONNECTION_REFUSED, windows.ERROR_CONNECTION_UNAVAIL:
+ return true
+ default:
+ return false
+ }
+}
+
+func (conn *HvsockConn) opErr(op string, err error) error {
+ // translate from "file closed" to "socket closed"
+ if errors.Is(err, ErrFileClosed) {
+ err = socket.ErrSocketClosed
+ }
+ return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
+}
+
+func (conn *HvsockConn) Read(b []byte) (int, error) {
+ c, err := conn.sock.prepareIO()
+ if err != nil {
+ return 0, conn.opErr("read", err)
+ }
+ defer conn.sock.wg.Done()
+ buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))}
+ var flags, bytes uint32
+ err = windows.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
+ n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err)
+ if err != nil {
+ var eno windows.Errno
+ if errors.As(err, &eno) {
+ err = os.NewSyscallError("wsarecv", eno)
+ }
+ return 0, conn.opErr("read", err)
+ } else if n == 0 {
+ err = io.EOF
+ }
+ return n, err
+}
+
+func (conn *HvsockConn) Write(b []byte) (int, error) {
+ t := 0
+ for len(b) != 0 {
+ n, err := conn.write(b)
+ if err != nil {
+ return t + n, err
+ }
+ t += n
+ b = b[n:]
+ }
+ return t, nil
+}
+
+func (conn *HvsockConn) write(b []byte) (int, error) {
+ c, err := conn.sock.prepareIO()
+ if err != nil {
+ return 0, conn.opErr("write", err)
+ }
+ defer conn.sock.wg.Done()
+ buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))}
+ var bytes uint32
+ err = windows.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
+ n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err)
+ if err != nil {
+ var eno windows.Errno
+ if errors.As(err, &eno) {
+ err = os.NewSyscallError("wsasend", eno)
+ }
+ return 0, conn.opErr("write", err)
+ }
+ return n, err
+}
+
+// Close closes the socket connection, failing any pending read or write calls.
+func (conn *HvsockConn) Close() error {
+ return conn.sock.Close()
+}
+
+func (conn *HvsockConn) IsClosed() bool {
+ return conn.sock.IsClosed()
+}
+
+// shutdown disables sending or receiving on a socket.
+func (conn *HvsockConn) shutdown(how int) error {
+ if conn.IsClosed() {
+ return socket.ErrSocketClosed
+ }
+
+ err := windows.Shutdown(conn.sock.handle, how)
+ if err != nil {
+ // If the connection was closed, shutdowns fail with "not connected"
+ if errors.Is(err, windows.WSAENOTCONN) ||
+ errors.Is(err, windows.WSAESHUTDOWN) {
+ err = socket.ErrSocketClosed
+ }
+ return os.NewSyscallError("shutdown", err)
+ }
+ return nil
+}
+
+// CloseRead shuts down the read end of the socket, preventing future read operations.
+func (conn *HvsockConn) CloseRead() error {
+ err := conn.shutdown(windows.SHUT_RD)
+ if err != nil {
+ return conn.opErr("closeread", err)
+ }
+ return nil
+}
+
+// CloseWrite shuts down the write end of the socket, preventing future write operations and
+// notifying the other endpoint that no more data will be written.
+func (conn *HvsockConn) CloseWrite() error {
+ err := conn.shutdown(windows.SHUT_WR)
+ if err != nil {
+ return conn.opErr("closewrite", err)
+ }
+ return nil
+}
+
+// LocalAddr returns the local address of the connection.
+func (conn *HvsockConn) LocalAddr() net.Addr {
+ return &conn.local
+}
+
+// RemoteAddr returns the remote address of the connection.
+func (conn *HvsockConn) RemoteAddr() net.Addr {
+ return &conn.remote
+}
+
+// SetDeadline implements the net.Conn SetDeadline method.
+func (conn *HvsockConn) SetDeadline(t time.Time) error {
+ // todo: implement `SetDeadline` for `win32File`
+ if err := conn.SetReadDeadline(t); err != nil {
+ return fmt.Errorf("set read deadline: %w", err)
+ }
+ if err := conn.SetWriteDeadline(t); err != nil {
+ return fmt.Errorf("set write deadline: %w", err)
+ }
+ return nil
+}
+
+// SetReadDeadline implements the net.Conn SetReadDeadline method.
+func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
+ return conn.sock.SetReadDeadline(t)
+}
+
+// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
+func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
+ return conn.sock.SetWriteDeadline(t)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go b/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
new file mode 100644
index 0000000..1f65388
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
@@ -0,0 +1,2 @@
+// This package contains Win32 filesystem functionality.
+package fs
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
new file mode 100644
index 0000000..0cd9621
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
@@ -0,0 +1,262 @@
+//go:build windows
+
+package fs
+
+import (
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/stringbuffer"
+)
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go
+
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
+//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
+
+const NullHandle windows.Handle = 0
+
+// AccessMask defines standard, specific, and generic rights.
+//
+// Used with CreateFile and NtCreateFile (and co.).
+//
+// Bitmask:
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +---------------+---------------+-------------------------------+
+// |G|G|G|G|Resvd|A| StandardRights| SpecificRights |
+// |R|W|E|A| |S| | |
+// +-+-------------+---------------+-------------------------------+
+//
+// GR Generic Read
+// GW Generic Write
+// GE Generic Exectue
+// GA Generic All
+// Resvd Reserved
+// AS Access Security System
+//
+// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask
+//
+// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
+//
+// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants
+type AccessMask = windows.ACCESS_MASK
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // Not actually any.
+ //
+ // For CreateFile: "query certain metadata such as file, directory, or device attributes without accessing that file or device"
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters
+ FILE_ANY_ACCESS AccessMask = 0
+
+ GENERIC_READ AccessMask = 0x8000_0000
+ GENERIC_WRITE AccessMask = 0x4000_0000
+ GENERIC_EXECUTE AccessMask = 0x2000_0000
+ GENERIC_ALL AccessMask = 0x1000_0000
+ ACCESS_SYSTEM_SECURITY AccessMask = 0x0100_0000
+
+ // Specific Object Access
+ // from ntioapi.h
+
+ FILE_READ_DATA AccessMask = (0x0001) // file & pipe
+ FILE_LIST_DIRECTORY AccessMask = (0x0001) // directory
+
+ FILE_WRITE_DATA AccessMask = (0x0002) // file & pipe
+ FILE_ADD_FILE AccessMask = (0x0002) // directory
+
+ FILE_APPEND_DATA AccessMask = (0x0004) // file
+ FILE_ADD_SUBDIRECTORY AccessMask = (0x0004) // directory
+ FILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe
+
+ FILE_READ_EA AccessMask = (0x0008) // file & directory
+ FILE_READ_PROPERTIES AccessMask = FILE_READ_EA
+
+ FILE_WRITE_EA AccessMask = (0x0010) // file & directory
+ FILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA
+
+ FILE_EXECUTE AccessMask = (0x0020) // file
+ FILE_TRAVERSE AccessMask = (0x0020) // directory
+
+ FILE_DELETE_CHILD AccessMask = (0x0040) // directory
+
+ FILE_READ_ATTRIBUTES AccessMask = (0x0080) // all
+
+ FILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all
+
+ FILE_ALL_ACCESS AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
+ FILE_GENERIC_READ AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)
+ FILE_GENERIC_WRITE AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
+ FILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
+
+ SPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF
+
+ // Standard Access
+ // from ntseapi.h
+
+ DELETE AccessMask = 0x0001_0000
+ READ_CONTROL AccessMask = 0x0002_0000
+ WRITE_DAC AccessMask = 0x0004_0000
+ WRITE_OWNER AccessMask = 0x0008_0000
+ SYNCHRONIZE AccessMask = 0x0010_0000
+
+ STANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000
+
+ STANDARD_RIGHTS_READ AccessMask = READ_CONTROL
+ STANDARD_RIGHTS_WRITE AccessMask = READ_CONTROL
+ STANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL
+
+ STANDARD_RIGHTS_ALL AccessMask = 0x001F_0000
+)
+
+type FileShareMode uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ FILE_SHARE_NONE FileShareMode = 0x00
+ FILE_SHARE_READ FileShareMode = 0x01
+ FILE_SHARE_WRITE FileShareMode = 0x02
+ FILE_SHARE_DELETE FileShareMode = 0x04
+ FILE_SHARE_VALID_FLAGS FileShareMode = 0x07
+)
+
+type FileCreationDisposition uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // from winbase.h
+
+ CREATE_NEW FileCreationDisposition = 0x01
+ CREATE_ALWAYS FileCreationDisposition = 0x02
+ OPEN_EXISTING FileCreationDisposition = 0x03
+ OPEN_ALWAYS FileCreationDisposition = 0x04
+ TRUNCATE_EXISTING FileCreationDisposition = 0x05
+)
+
+// Create disposition values for NtCreate*
+type NTFileCreationDisposition uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // From ntioapi.h
+
+ FILE_SUPERSEDE NTFileCreationDisposition = 0x00
+ FILE_OPEN NTFileCreationDisposition = 0x01
+ FILE_CREATE NTFileCreationDisposition = 0x02
+ FILE_OPEN_IF NTFileCreationDisposition = 0x03
+ FILE_OVERWRITE NTFileCreationDisposition = 0x04
+ FILE_OVERWRITE_IF NTFileCreationDisposition = 0x05
+ FILE_MAXIMUM_DISPOSITION NTFileCreationDisposition = 0x05
+)
+
+// CreateFile and co. take flags or attributes together as one parameter.
+// Define alias until we can use generics to allow both
+//
+// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+type FileFlagOrAttribute uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // from winnt.h
+
+ FILE_FLAG_WRITE_THROUGH FileFlagOrAttribute = 0x8000_0000
+ FILE_FLAG_OVERLAPPED FileFlagOrAttribute = 0x4000_0000
+ FILE_FLAG_NO_BUFFERING FileFlagOrAttribute = 0x2000_0000
+ FILE_FLAG_RANDOM_ACCESS FileFlagOrAttribute = 0x1000_0000
+ FILE_FLAG_SEQUENTIAL_SCAN FileFlagOrAttribute = 0x0800_0000
+ FILE_FLAG_DELETE_ON_CLOSE FileFlagOrAttribute = 0x0400_0000
+ FILE_FLAG_BACKUP_SEMANTICS FileFlagOrAttribute = 0x0200_0000
+ FILE_FLAG_POSIX_SEMANTICS FileFlagOrAttribute = 0x0100_0000
+ FILE_FLAG_OPEN_REPARSE_POINT FileFlagOrAttribute = 0x0020_0000
+ FILE_FLAG_OPEN_NO_RECALL FileFlagOrAttribute = 0x0010_0000
+ FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000
+)
+
+// NtCreate* functions take a dedicated CreateOptions parameter.
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/Winternl/nf-winternl-ntcreatefile
+//
+// https://learn.microsoft.com/en-us/windows/win32/devnotes/nt-create-named-pipe-file
+type NTCreateOptions uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // From ntioapi.h
+
+ FILE_DIRECTORY_FILE NTCreateOptions = 0x0000_0001
+ FILE_WRITE_THROUGH NTCreateOptions = 0x0000_0002
+ FILE_SEQUENTIAL_ONLY NTCreateOptions = 0x0000_0004
+ FILE_NO_INTERMEDIATE_BUFFERING NTCreateOptions = 0x0000_0008
+
+ FILE_SYNCHRONOUS_IO_ALERT NTCreateOptions = 0x0000_0010
+ FILE_SYNCHRONOUS_IO_NONALERT NTCreateOptions = 0x0000_0020
+ FILE_NON_DIRECTORY_FILE NTCreateOptions = 0x0000_0040
+ FILE_CREATE_TREE_CONNECTION NTCreateOptions = 0x0000_0080
+
+ FILE_COMPLETE_IF_OPLOCKED NTCreateOptions = 0x0000_0100
+ FILE_NO_EA_KNOWLEDGE NTCreateOptions = 0x0000_0200
+ FILE_DISABLE_TUNNELING NTCreateOptions = 0x0000_0400
+ FILE_RANDOM_ACCESS NTCreateOptions = 0x0000_0800
+
+ FILE_DELETE_ON_CLOSE NTCreateOptions = 0x0000_1000
+ FILE_OPEN_BY_FILE_ID NTCreateOptions = 0x0000_2000
+ FILE_OPEN_FOR_BACKUP_INTENT NTCreateOptions = 0x0000_4000
+ FILE_NO_COMPRESSION NTCreateOptions = 0x0000_8000
+)
+
+type FileSQSFlag = FileFlagOrAttribute
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ // from winbase.h
+
+ SECURITY_ANONYMOUS FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)
+ SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)
+ SECURITY_IMPERSONATION FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)
+ SECURITY_DELEGATION FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)
+
+ SECURITY_SQOS_PRESENT FileSQSFlag = 0x0010_0000
+ SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F_0000
+)
+
+// GetFinalPathNameByHandle flags
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters
+type GetFinalPathFlag uint32
+
+//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
+const (
+ GetFinalPathDefaultFlag GetFinalPathFlag = 0x0
+
+ FILE_NAME_NORMALIZED GetFinalPathFlag = 0x0
+ FILE_NAME_OPENED GetFinalPathFlag = 0x8
+
+ VOLUME_NAME_DOS GetFinalPathFlag = 0x0
+ VOLUME_NAME_GUID GetFinalPathFlag = 0x1
+ VOLUME_NAME_NT GetFinalPathFlag = 0x2
+ VOLUME_NAME_NONE GetFinalPathFlag = 0x4
+)
+
+// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle
+// with the given handle and flags. It transparently takes care of creating a buffer of the
+// correct size for the call.
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
+func GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) {
+ b := stringbuffer.NewWString()
+ //TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n?
+ for {
+ n, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags))
+ if err != nil {
+ return "", err
+ }
+ // If the buffer wasn't large enough, n will be the total size needed (including null terminator).
+ // Resize and try again.
+ if n > b.Cap() {
+ b.ResizeTo(n)
+ continue
+ }
+ // If the buffer is large enough, n will be the size not including the null terminator.
+ // Convert to a Go string and return.
+ return b.String(), nil
+ }
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/security.go b/vendor/github.com/Microsoft/go-winio/internal/fs/security.go
new file mode 100644
index 0000000..81760ac
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/security.go
@@ -0,0 +1,12 @@
+package fs
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
+type SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32`
+
+// Impersonation levels
+const (
+ SecurityAnonymous SecurityImpersonationLevel = 0
+ SecurityIdentification SecurityImpersonationLevel = 1
+ SecurityImpersonation SecurityImpersonationLevel = 2
+ SecurityDelegation SecurityImpersonationLevel = 3
+)
diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
new file mode 100644
index 0000000..a94e234
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
@@ -0,0 +1,61 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package fs
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ return e
+}
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+ procCreateFileW = modkernel32.NewProc("CreateFileW")
+)
+
+func CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile)
+}
+
+func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
+ r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile))
+ handle = windows.Handle(r0)
+ if handle == windows.InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go b/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
new file mode 100644
index 0000000..7e82f9a
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
@@ -0,0 +1,20 @@
+package socket
+
+import (
+ "unsafe"
+)
+
+// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The
+// struct must meet the Win32 sockaddr requirements specified here:
+// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2
+//
+// Specifically, the struct size must be least larger than an int16 (unsigned short)
+// for the address family.
+type RawSockaddr interface {
+ // Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing
+ // for the RawSockaddr's data to be overwritten by syscalls (if necessary).
+ //
+ // It is the callers responsibility to validate that the values are valid; invalid
+ // pointers or size can cause a panic.
+ Sockaddr() (unsafe.Pointer, int32, error)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
new file mode 100644
index 0000000..88580d9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
@@ -0,0 +1,177 @@
+//go:build windows
+
+package socket
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "syscall"
+ "unsafe"
+
+ "github.com/Microsoft/go-winio/pkg/guid"
+ "golang.org/x/sys/windows"
+)
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go
+
+//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname
+//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername
+//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
+
+const socketError = uintptr(^uint32(0))
+
+var (
+ // todo(helsaawy): create custom error types to store the desired vs actual size and addr family?
+
+ ErrBufferSize = errors.New("buffer size")
+ ErrAddrFamily = errors.New("address family")
+ ErrInvalidPointer = errors.New("invalid pointer")
+ ErrSocketClosed = fmt.Errorf("socket closed: %w", net.ErrClosed)
+)
+
+// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error)
+
+// GetSockName writes the local address of socket s to the [RawSockaddr] rsa.
+// If rsa is not large enough, the [windows.WSAEFAULT] is returned.
+func GetSockName(s windows.Handle, rsa RawSockaddr) error {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ // although getsockname returns WSAEFAULT if the buffer is too small, it does not set
+ // &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy
+ return getsockname(s, ptr, &l)
+}
+
+// GetPeerName returns the remote address the socket is connected to.
+//
+// See [GetSockName] for more information.
+func GetPeerName(s windows.Handle, rsa RawSockaddr) error {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ return getpeername(s, ptr, &l)
+}
+
+func Bind(s windows.Handle, rsa RawSockaddr) (err error) {
+ ptr, l, err := rsa.Sockaddr()
+ if err != nil {
+ return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
+ }
+
+ return bind(s, ptr, l)
+}
+
+// "golang.org/x/sys/windows".ConnectEx and .Bind only accept internal implementations of the
+// their sockaddr interface, so they cannot be used with HvsockAddr
+// Replicate functionality here from
+// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go
+
+// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at
+// runtime via a WSAIoctl call:
+// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks
+
+type runtimeFunc struct {
+ id guid.GUID
+ once sync.Once
+ addr uintptr
+ err error
+}
+
+func (f *runtimeFunc) Load() error {
+ f.once.Do(func() {
+ var s windows.Handle
+ s, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP)
+ if f.err != nil {
+ return
+ }
+ defer windows.CloseHandle(s) //nolint:errcheck
+
+ var n uint32
+ f.err = windows.WSAIoctl(s,
+ windows.SIO_GET_EXTENSION_FUNCTION_POINTER,
+ (*byte)(unsafe.Pointer(&f.id)),
+ uint32(unsafe.Sizeof(f.id)),
+ (*byte)(unsafe.Pointer(&f.addr)),
+ uint32(unsafe.Sizeof(f.addr)),
+ &n,
+ nil, // overlapped
+ 0, // completionRoutine
+ )
+ })
+ return f.err
+}
+
+var (
+ // todo: add `AcceptEx` and `GetAcceptExSockaddrs`
+ WSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS
+ Data1: 0x25a207b9,
+ Data2: 0xddf3,
+ Data3: 0x4660,
+ Data4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
+ }
+
+ connectExFunc = runtimeFunc{id: WSAID_CONNECTEX}
+)
+
+func ConnectEx(
+ fd windows.Handle,
+ rsa RawSockaddr,
+ sendBuf *byte,
+ sendDataLen uint32,
+ bytesSent *uint32,
+ overlapped *windows.Overlapped,
+) error {
+ if err := connectExFunc.Load(); err != nil {
+ return fmt.Errorf("failed to load ConnectEx function pointer: %w", err)
+ }
+ ptr, n, err := rsa.Sockaddr()
+ if err != nil {
+ return err
+ }
+ return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+// BOOL LpfnConnectex(
+// [in] SOCKET s,
+// [in] const sockaddr *name,
+// [in] int namelen,
+// [in, optional] PVOID lpSendBuffer,
+// [in] DWORD dwSendDataLength,
+// [out] LPDWORD lpdwBytesSent,
+// [in] LPOVERLAPPED lpOverlapped
+// )
+
+func connectEx(
+ s windows.Handle,
+ name unsafe.Pointer,
+ namelen int32,
+ sendBuf *byte,
+ sendDataLen uint32,
+ bytesSent *uint32,
+ overlapped *windows.Overlapped,
+) (err error) {
+ r1, _, e1 := syscall.SyscallN(connectExFunc.addr,
+ uintptr(s),
+ uintptr(name),
+ uintptr(namelen),
+ uintptr(unsafe.Pointer(sendBuf)),
+ uintptr(sendDataLen),
+ uintptr(unsafe.Pointer(bytesSent)),
+ uintptr(unsafe.Pointer(overlapped)),
+ )
+
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return err
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
new file mode 100644
index 0000000..e150412
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
@@ -0,0 +1,69 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package socket
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ return e
+}
+
+var (
+ modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
+
+ procbind = modws2_32.NewProc("bind")
+ procgetpeername = modws2_32.NewProc("getpeername")
+ procgetsockname = modws2_32.NewProc("getsockname")
+)
+
+func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
+ if r1 == socketError {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
new file mode 100644
index 0000000..42ebc01
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
@@ -0,0 +1,132 @@
+package stringbuffer
+
+import (
+ "sync"
+ "unicode/utf16"
+)
+
+// TODO: worth exporting and using in mkwinsyscall?
+
+// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate
+// large path strings:
+// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.
+const MinWStringCap = 310
+
+// use *[]uint16 since []uint16 creates an extra allocation where the slice header
+// is copied to heap and then referenced via pointer in the interface header that sync.Pool
+// stores.
+var pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly
+ New: func() interface{} {
+ b := make([]uint16, MinWStringCap)
+ return &b
+ },
+}
+
+func newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) }
+
+// freeBuffer copies the slice header data, and puts a pointer to that in the pool.
+// This avoids taking a pointer to the slice header in WString, which can be set to nil.
+func freeBuffer(b []uint16) { pathPool.Put(&b) }
+
+// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings
+// for interacting with Win32 APIs.
+// Sizes are specified as uint32 and not int.
+//
+// It is not thread safe.
+type WString struct {
+ // type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future.
+
+ // raw buffer
+ b []uint16
+}
+
+// NewWString returns a [WString] allocated from a shared pool with an
+// initial capacity of at least [MinWStringCap].
+// Since the buffer may have been previously used, its contents are not guaranteed to be empty.
+//
+// The buffer should be freed via [WString.Free]
+func NewWString() *WString {
+ return &WString{
+ b: newBuffer(),
+ }
+}
+
+func (b *WString) Free() {
+ if b.empty() {
+ return
+ }
+ freeBuffer(b.b)
+ b.b = nil
+}
+
+// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the
+// previous buffer back into pool.
+func (b *WString) ResizeTo(c uint32) uint32 {
+ // already sufficient (or n is 0)
+ if c <= b.Cap() {
+ return b.Cap()
+ }
+
+ if c <= MinWStringCap {
+ c = MinWStringCap
+ }
+ // allocate at-least double buffer size, as is done in [bytes.Buffer] and other places
+ if c <= 2*b.Cap() {
+ c = 2 * b.Cap()
+ }
+
+ b2 := make([]uint16, c)
+ if !b.empty() {
+ copy(b2, b.b)
+ freeBuffer(b.b)
+ }
+ b.b = b2
+ return c
+}
+
+// Buffer returns the underlying []uint16 buffer.
+func (b *WString) Buffer() []uint16 {
+ if b.empty() {
+ return nil
+ }
+ return b.b
+}
+
+// Pointer returns a pointer to the first uint16 in the buffer.
+// If the [WString.Free] has already been called, the pointer will be nil.
+func (b *WString) Pointer() *uint16 {
+ if b.empty() {
+ return nil
+ }
+ return &b.b[0]
+}
+
+// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer.
+//
+// It assumes that the data is null-terminated.
+func (b *WString) String() string {
+ // Using [windows.UTF16ToString] would require importing "golang.org/x/sys/windows"
+ // and would make this code Windows-only, which makes no sense.
+ // So copy UTF16ToString code into here.
+ // If other windows-specific code is added, switch to [windows.UTF16ToString]
+
+ s := b.b
+ for i, v := range s {
+ if v == 0 {
+ s = s[:i]
+ break
+ }
+ }
+ return string(utf16.Decode(s))
+}
+
+// Cap returns the underlying buffer capacity.
+func (b *WString) Cap() uint32 {
+ if b.empty() {
+ return 0
+ }
+ return b.cap()
+}
+
+func (b *WString) cap() uint32 { return uint32(cap(b.b)) }
+func (b *WString) empty() bool { return b == nil || b.cap() == 0 }
diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go
new file mode 100644
index 0000000..a2da663
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pipe.go
@@ -0,0 +1,586 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "runtime"
+ "time"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+
+ "github.com/Microsoft/go-winio/internal/fs"
+)
+
+//sys connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) = ConnectNamedPipe
+//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateNamedPipeW
+//sys disconnectNamedPipe(pipe windows.Handle) (err error) = DisconnectNamedPipe
+//sys getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
+//sys getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
+//sys ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile
+//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
+//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U
+//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl
+
+type PipeConn interface {
+ net.Conn
+ Disconnect() error
+ Flush() error
+}
+
+// type aliases for mkwinsyscall code
+type (
+ ntAccessMask = fs.AccessMask
+ ntFileShareMode = fs.FileShareMode
+ ntFileCreationDisposition = fs.NTFileCreationDisposition
+ ntFileOptions = fs.NTCreateOptions
+)
+
+type ioStatusBlock struct {
+ Status, Information uintptr
+}
+
+// typedef struct _OBJECT_ATTRIBUTES {
+// ULONG Length;
+// HANDLE RootDirectory;
+// PUNICODE_STRING ObjectName;
+// ULONG Attributes;
+// PVOID SecurityDescriptor;
+// PVOID SecurityQualityOfService;
+// } OBJECT_ATTRIBUTES;
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_attributes
+type objectAttributes struct {
+ Length uintptr
+ RootDirectory uintptr
+ ObjectName *unicodeString
+ Attributes uintptr
+ SecurityDescriptor *securityDescriptor
+ SecurityQoS uintptr
+}
+
+type unicodeString struct {
+ Length uint16
+ MaximumLength uint16
+ Buffer uintptr
+}
+
+// typedef struct _SECURITY_DESCRIPTOR {
+// BYTE Revision;
+// BYTE Sbz1;
+// SECURITY_DESCRIPTOR_CONTROL Control;
+// PSID Owner;
+// PSID Group;
+// PACL Sacl;
+// PACL Dacl;
+// } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
+//
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor
+type securityDescriptor struct {
+ Revision byte
+ Sbz1 byte
+ Control uint16
+ Owner uintptr
+ Group uintptr
+ Sacl uintptr //revive:disable-line:var-naming SACL, not Sacl
+ Dacl uintptr //revive:disable-line:var-naming DACL, not Dacl
+}
+
+type ntStatus int32
+
+func (status ntStatus) Err() error {
+ if status >= 0 {
+ return nil
+ }
+ return rtlNtStatusToDosError(status)
+}
+
+var (
+ // ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
+ ErrPipeListenerClosed = net.ErrClosed
+
+ errPipeWriteClosed = errors.New("pipe has been closed for write")
+)
+
+type win32Pipe struct {
+ *win32File
+ path string
+}
+
+var _ PipeConn = (*win32Pipe)(nil)
+
+type win32MessageBytePipe struct {
+ win32Pipe
+ writeClosed bool
+ readEOF bool
+}
+
+type pipeAddress string
+
+func (f *win32Pipe) LocalAddr() net.Addr {
+ return pipeAddress(f.path)
+}
+
+func (f *win32Pipe) RemoteAddr() net.Addr {
+ return pipeAddress(f.path)
+}
+
+func (f *win32Pipe) SetDeadline(t time.Time) error {
+ if err := f.SetReadDeadline(t); err != nil {
+ return err
+ }
+ return f.SetWriteDeadline(t)
+}
+
+func (f *win32Pipe) Disconnect() error {
+ return disconnectNamedPipe(f.win32File.handle)
+}
+
+// CloseWrite closes the write side of a message pipe in byte mode.
+func (f *win32MessageBytePipe) CloseWrite() error {
+ if f.writeClosed {
+ return errPipeWriteClosed
+ }
+ err := f.win32File.Flush()
+ if err != nil {
+ return err
+ }
+ _, err = f.win32File.Write(nil)
+ if err != nil {
+ return err
+ }
+ f.writeClosed = true
+ return nil
+}
+
+// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since
+// they are used to implement CloseWrite().
+func (f *win32MessageBytePipe) Write(b []byte) (int, error) {
+ if f.writeClosed {
+ return 0, errPipeWriteClosed
+ }
+ if len(b) == 0 {
+ return 0, nil
+ }
+ return f.win32File.Write(b)
+}
+
+// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message
+// mode pipe will return io.EOF, as will all subsequent reads.
+func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
+ if f.readEOF {
+ return 0, io.EOF
+ }
+ n, err := f.win32File.Read(b)
+ if err == io.EOF { //nolint:errorlint
+ // If this was the result of a zero-byte read, then
+ // it is possible that the read was due to a zero-size
+ // message. Since we are simulating CloseWrite with a
+ // zero-byte message, ensure that all future Read() calls
+ // also return EOF.
+ f.readEOF = true
+ } else if err == windows.ERROR_MORE_DATA { //nolint:errorlint // err is Errno
+ // ERROR_MORE_DATA indicates that the pipe's read mode is message mode
+ // and the message still has more bytes. Treat this as a success, since
+ // this package presents all named pipes as byte streams.
+ err = nil
+ }
+ return n, err
+}
+
+func (pipeAddress) Network() string {
+ return "pipe"
+}
+
+func (s pipeAddress) String() string {
+ return string(s)
+}
+
+// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
+func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask, impLevel PipeImpLevel) (windows.Handle, error) {
+ for {
+ select {
+ case <-ctx.Done():
+ return windows.Handle(0), ctx.Err()
+ default:
+ h, err := fs.CreateFile(*path,
+ access,
+ 0, // mode
+ nil, // security attributes
+ fs.OPEN_EXISTING,
+ fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.FileSQSFlag(impLevel),
+ 0, // template file handle
+ )
+ if err == nil {
+ return h, nil
+ }
+ if err != windows.ERROR_PIPE_BUSY { //nolint:errorlint // err is Errno
+ return h, &os.PathError{Err: err, Op: "open", Path: *path}
+ }
+ // Wait 10 msec and try again. This is a rather simplistic
+ // view, as we always try each 10 milliseconds.
+ time.Sleep(10 * time.Millisecond)
+ }
+ }
+}
+
+// DialPipe connects to a named pipe by path, timing out if the connection
+// takes longer than the specified duration. If timeout is nil, then we use
+// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
+func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
+ var absTimeout time.Time
+ if timeout != nil {
+ absTimeout = time.Now().Add(*timeout)
+ } else {
+ absTimeout = time.Now().Add(2 * time.Second)
+ }
+ ctx, cancel := context.WithDeadline(context.Background(), absTimeout)
+ defer cancel()
+ conn, err := DialPipeContext(ctx, path)
+ if errors.Is(err, context.DeadlineExceeded) {
+ return nil, ErrTimeout
+ }
+ return conn, err
+}
+
+// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
+// cancellation or timeout.
+func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
+ return DialPipeAccess(ctx, path, uint32(fs.GENERIC_READ|fs.GENERIC_WRITE))
+}
+
+// PipeImpLevel is an enumeration of impersonation levels that may be set
+// when calling DialPipeAccessImpersonation.
+type PipeImpLevel uint32
+
+const (
+ PipeImpLevelAnonymous = PipeImpLevel(fs.SECURITY_ANONYMOUS)
+ PipeImpLevelIdentification = PipeImpLevel(fs.SECURITY_IDENTIFICATION)
+ PipeImpLevelImpersonation = PipeImpLevel(fs.SECURITY_IMPERSONATION)
+ PipeImpLevelDelegation = PipeImpLevel(fs.SECURITY_DELEGATION)
+)
+
+// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`
+// cancellation or timeout.
+func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) {
+ return DialPipeAccessImpLevel(ctx, path, access, PipeImpLevelAnonymous)
+}
+
+// DialPipeAccessImpLevel attempts to connect to a named pipe by `path` with
+// `access` at `impLevel` until `ctx` cancellation or timeout. The other
+// DialPipe* implementations use PipeImpLevelAnonymous.
+func DialPipeAccessImpLevel(ctx context.Context, path string, access uint32, impLevel PipeImpLevel) (net.Conn, error) {
+ var err error
+ var h windows.Handle
+ h, err = tryDialPipe(ctx, &path, fs.AccessMask(access), impLevel)
+ if err != nil {
+ return nil, err
+ }
+
+ var flags uint32
+ err = getNamedPipeInfo(h, &flags, nil, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ f, err := makeWin32File(h)
+ if err != nil {
+ windows.Close(h)
+ return nil, err
+ }
+
+ // If the pipe is in message mode, return a message byte pipe, which
+ // supports CloseWrite().
+ if flags&windows.PIPE_TYPE_MESSAGE != 0 {
+ return &win32MessageBytePipe{
+ win32Pipe: win32Pipe{win32File: f, path: path},
+ }, nil
+ }
+ return &win32Pipe{win32File: f, path: path}, nil
+}
+
+type acceptResponse struct {
+ f *win32File
+ err error
+}
+
+type win32PipeListener struct {
+ firstHandle windows.Handle
+ path string
+ config PipeConfig
+ acceptCh chan (chan acceptResponse)
+ closeCh chan int
+ doneCh chan int
+}
+
+func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (windows.Handle, error) {
+ path16, err := windows.UTF16FromString(path)
+ if err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+
+ var oa objectAttributes
+ oa.Length = unsafe.Sizeof(oa)
+
+ var ntPath unicodeString
+ if err := rtlDosPathNameToNtPathName(&path16[0],
+ &ntPath,
+ 0,
+ 0,
+ ).Err(); err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+ defer windows.LocalFree(windows.Handle(ntPath.Buffer)) //nolint:errcheck
+ oa.ObjectName = &ntPath
+ oa.Attributes = windows.OBJ_CASE_INSENSITIVE
+
+ // The security descriptor is only needed for the first pipe.
+ if first {
+ if sd != nil {
+ //todo: does `sdb` need to be allocated on the heap, or can go allocate it?
+ l := uint32(len(sd))
+ sdb, err := windows.LocalAlloc(0, l)
+ if err != nil {
+ return 0, fmt.Errorf("LocalAlloc for security descriptor with of length %d: %w", l, err)
+ }
+ defer windows.LocalFree(windows.Handle(sdb)) //nolint:errcheck
+ copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
+ oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
+ } else {
+ // Construct the default named pipe security descriptor.
+ var dacl uintptr
+ if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
+ return 0, fmt.Errorf("getting default named pipe ACL: %w", err)
+ }
+ defer windows.LocalFree(windows.Handle(dacl)) //nolint:errcheck
+
+ sdb := &securityDescriptor{
+ Revision: 1,
+ Control: windows.SE_DACL_PRESENT,
+ Dacl: dacl,
+ }
+ oa.SecurityDescriptor = sdb
+ }
+ }
+
+ typ := uint32(windows.FILE_PIPE_REJECT_REMOTE_CLIENTS)
+ if c.MessageMode {
+ typ |= windows.FILE_PIPE_MESSAGE_TYPE
+ }
+
+ disposition := fs.FILE_OPEN
+ access := fs.GENERIC_READ | fs.GENERIC_WRITE | fs.SYNCHRONIZE
+ if first {
+ disposition = fs.FILE_CREATE
+ // By not asking for read or write access, the named pipe file system
+ // will put this pipe into an initially disconnected state, blocking
+ // client connections until the next call with first == false.
+ access = fs.SYNCHRONIZE
+ }
+
+ timeout := int64(-50 * 10000) // 50ms
+
+ var (
+ h windows.Handle
+ iosb ioStatusBlock
+ )
+ err = ntCreateNamedPipeFile(&h,
+ access,
+ &oa,
+ &iosb,
+ fs.FILE_SHARE_READ|fs.FILE_SHARE_WRITE,
+ disposition,
+ 0,
+ typ,
+ 0,
+ 0,
+ 0xffffffff,
+ uint32(c.InputBufferSize),
+ uint32(c.OutputBufferSize),
+ &timeout).Err()
+ if err != nil {
+ return 0, &os.PathError{Op: "open", Path: path, Err: err}
+ }
+
+ runtime.KeepAlive(ntPath)
+ return h, nil
+}
+
+func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
+ h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
+ if err != nil {
+ return nil, err
+ }
+ f, err := makeWin32File(h)
+ if err != nil {
+ windows.Close(h)
+ return nil, err
+ }
+ return f, nil
+}
+
+func (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) {
+ p, err := l.makeServerPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ // Wait for the client to connect.
+ ch := make(chan error)
+ go func(p *win32File) {
+ ch <- connectPipe(p)
+ }(p)
+
+ select {
+ case err = <-ch:
+ if err != nil {
+ p.Close()
+ p = nil
+ }
+ case <-l.closeCh:
+ // Abort the connect request by closing the handle.
+ p.Close()
+ p = nil
+ err = <-ch
+ if err == nil || err == ErrFileClosed { //nolint:errorlint // err is Errno
+ err = ErrPipeListenerClosed
+ }
+ }
+ return p, err
+}
+
+func (l *win32PipeListener) listenerRoutine() {
+ closed := false
+ for !closed {
+ select {
+ case <-l.closeCh:
+ closed = true
+ case responseCh := <-l.acceptCh:
+ var (
+ p *win32File
+ err error
+ )
+ for {
+ p, err = l.makeConnectedServerPipe()
+ // If the connection was immediately closed by the client, try
+ // again.
+ if err != windows.ERROR_NO_DATA { //nolint:errorlint // err is Errno
+ break
+ }
+ }
+ responseCh <- acceptResponse{p, err}
+ closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno
+ }
+ }
+ windows.Close(l.firstHandle)
+ l.firstHandle = 0
+ // Notify Close() and Accept() callers that the handle has been closed.
+ close(l.doneCh)
+}
+
+// PipeConfig contain configuration for the pipe listener.
+type PipeConfig struct {
+ // SecurityDescriptor contains a Windows security descriptor in SDDL format.
+ SecurityDescriptor string
+
+ // MessageMode determines whether the pipe is in byte or message mode. In either
+ // case the pipe is read in byte mode by default. The only practical difference in
+ // this implementation is that CloseWrite() is only supported for message mode pipes;
+ // CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only
+ // transferred to the reader (and returned as io.EOF in this implementation)
+ // when the pipe is in message mode.
+ MessageMode bool
+
+ // InputBufferSize specifies the size of the input buffer, in bytes.
+ InputBufferSize int32
+
+ // OutputBufferSize specifies the size of the output buffer, in bytes.
+ OutputBufferSize int32
+}
+
+// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe.
+// The pipe must not already exist.
+func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
+ var (
+ sd []byte
+ err error
+ )
+ if c == nil {
+ c = &PipeConfig{}
+ }
+ if c.SecurityDescriptor != "" {
+ sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
+ if err != nil {
+ return nil, err
+ }
+ }
+ h, err := makeServerPipeHandle(path, sd, c, true)
+ if err != nil {
+ return nil, err
+ }
+ l := &win32PipeListener{
+ firstHandle: h,
+ path: path,
+ config: *c,
+ acceptCh: make(chan (chan acceptResponse)),
+ closeCh: make(chan int),
+ doneCh: make(chan int),
+ }
+ go l.listenerRoutine()
+ return l, nil
+}
+
+func connectPipe(p *win32File) error {
+ c, err := p.prepareIO()
+ if err != nil {
+ return err
+ }
+ defer p.wg.Done()
+
+ err = connectNamedPipe(p.handle, &c.o)
+ _, err = p.asyncIO(c, nil, 0, err)
+ if err != nil && err != windows.ERROR_PIPE_CONNECTED { //nolint:errorlint // err is Errno
+ return err
+ }
+ return nil
+}
+
+func (l *win32PipeListener) Accept() (net.Conn, error) {
+ ch := make(chan acceptResponse)
+ select {
+ case l.acceptCh <- ch:
+ response := <-ch
+ err := response.err
+ if err != nil {
+ return nil, err
+ }
+ if l.config.MessageMode {
+ return &win32MessageBytePipe{
+ win32Pipe: win32Pipe{win32File: response.f, path: l.path},
+ }, nil
+ }
+ return &win32Pipe{win32File: response.f, path: l.path}, nil
+ case <-l.doneCh:
+ return nil, ErrPipeListenerClosed
+ }
+}
+
+func (l *win32PipeListener) Close() error {
+ select {
+ case l.closeCh <- 1:
+ <-l.doneCh
+ case <-l.doneCh:
+ }
+ return nil
+}
+
+func (l *win32PipeListener) Addr() net.Addr {
+ return pipeAddress(l.path)
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
new file mode 100644
index 0000000..48ce4e9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
@@ -0,0 +1,232 @@
+// Package guid provides a GUID type. The backing structure for a GUID is
+// identical to that used by the golang.org/x/sys/windows GUID type.
+// There are two main binary encodings used for a GUID, the big-endian encoding,
+// and the Windows (mixed-endian) encoding. See here for details:
+// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
+package guid
+
+import (
+ "crypto/rand"
+ "crypto/sha1" //nolint:gosec // not used for secure application
+ "encoding"
+ "encoding/binary"
+ "fmt"
+ "strconv"
+)
+
+//go:generate go run golang.org/x/tools/cmd/stringer -type=Variant -trimprefix=Variant -linecomment
+
+// Variant specifies which GUID variant (or "type") of the GUID. It determines
+// how the entirety of the rest of the GUID is interpreted.
+type Variant uint8
+
+// The variants specified by RFC 4122 section 4.1.1.
+const (
+ // VariantUnknown specifies a GUID variant which does not conform to one of
+ // the variant encodings specified in RFC 4122.
+ VariantUnknown Variant = iota
+ VariantNCS
+ VariantRFC4122 // RFC 4122
+ VariantMicrosoft
+ VariantFuture
+)
+
+// Version specifies how the bits in the GUID were generated. For instance, a
+// version 4 GUID is randomly generated, and a version 5 is generated from the
+// hash of an input string.
+type Version uint8
+
+func (v Version) String() string {
+ return strconv.FormatUint(uint64(v), 10)
+}
+
+var _ = (encoding.TextMarshaler)(GUID{})
+var _ = (encoding.TextUnmarshaler)(&GUID{})
+
+// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
+func NewV4() (GUID, error) {
+ var b [16]byte
+ if _, err := rand.Read(b[:]); err != nil {
+ return GUID{}, err
+ }
+
+ g := FromArray(b)
+ g.setVersion(4) // Version 4 means randomly generated.
+ g.setVariant(VariantRFC4122)
+
+ return g, nil
+}
+
+// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
+// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
+// and the sample code treats it as a series of bytes, so we do the same here.
+//
+// Some implementations, such as those found on Windows, treat the name as a
+// big-endian UTF16 stream of bytes. If that is desired, the string can be
+// encoded as such before being passed to this function.
+func NewV5(namespace GUID, name []byte) (GUID, error) {
+ b := sha1.New() //nolint:gosec // not used for secure application
+ namespaceBytes := namespace.ToArray()
+ b.Write(namespaceBytes[:])
+ b.Write(name)
+
+ a := [16]byte{}
+ copy(a[:], b.Sum(nil))
+
+ g := FromArray(a)
+ g.setVersion(5) // Version 5 means generated from a string.
+ g.setVariant(VariantRFC4122)
+
+ return g, nil
+}
+
+func fromArray(b [16]byte, order binary.ByteOrder) GUID {
+ var g GUID
+ g.Data1 = order.Uint32(b[0:4])
+ g.Data2 = order.Uint16(b[4:6])
+ g.Data3 = order.Uint16(b[6:8])
+ copy(g.Data4[:], b[8:16])
+ return g
+}
+
+func (g GUID) toArray(order binary.ByteOrder) [16]byte {
+ b := [16]byte{}
+ order.PutUint32(b[0:4], g.Data1)
+ order.PutUint16(b[4:6], g.Data2)
+ order.PutUint16(b[6:8], g.Data3)
+ copy(b[8:16], g.Data4[:])
+ return b
+}
+
+// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
+func FromArray(b [16]byte) GUID {
+ return fromArray(b, binary.BigEndian)
+}
+
+// ToArray returns an array of 16 bytes representing the GUID in big-endian
+// encoding.
+func (g GUID) ToArray() [16]byte {
+ return g.toArray(binary.BigEndian)
+}
+
+// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
+func FromWindowsArray(b [16]byte) GUID {
+ return fromArray(b, binary.LittleEndian)
+}
+
+// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
+// encoding.
+func (g GUID) ToWindowsArray() [16]byte {
+ return g.toArray(binary.LittleEndian)
+}
+
+func (g GUID) String() string {
+ return fmt.Sprintf(
+ "%08x-%04x-%04x-%04x-%012x",
+ g.Data1,
+ g.Data2,
+ g.Data3,
+ g.Data4[:2],
+ g.Data4[2:])
+}
+
+// FromString parses a string containing a GUID and returns the GUID. The only
+// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
+// format.
+func FromString(s string) (GUID, error) {
+ if len(s) != 36 {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+
+ var g GUID
+
+ data1, err := strconv.ParseUint(s[0:8], 16, 32)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data1 = uint32(data1)
+
+ data2, err := strconv.ParseUint(s[9:13], 16, 16)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data2 = uint16(data2)
+
+ data3, err := strconv.ParseUint(s[14:18], 16, 16)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data3 = uint16(data3)
+
+ for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
+ v, err := strconv.ParseUint(s[x:x+2], 16, 8)
+ if err != nil {
+ return GUID{}, fmt.Errorf("invalid GUID %q", s)
+ }
+ g.Data4[i] = uint8(v)
+ }
+
+ return g, nil
+}
+
+func (g *GUID) setVariant(v Variant) {
+ d := g.Data4[0]
+ switch v {
+ case VariantNCS:
+ d = (d & 0x7f)
+ case VariantRFC4122:
+ d = (d & 0x3f) | 0x80
+ case VariantMicrosoft:
+ d = (d & 0x1f) | 0xc0
+ case VariantFuture:
+ d = (d & 0x0f) | 0xe0
+ case VariantUnknown:
+ fallthrough
+ default:
+ panic(fmt.Sprintf("invalid variant: %d", v))
+ }
+ g.Data4[0] = d
+}
+
+// Variant returns the GUID variant, as defined in RFC 4122.
+func (g GUID) Variant() Variant {
+ b := g.Data4[0]
+ if b&0x80 == 0 {
+ return VariantNCS
+ } else if b&0xc0 == 0x80 {
+ return VariantRFC4122
+ } else if b&0xe0 == 0xc0 {
+ return VariantMicrosoft
+ } else if b&0xe0 == 0xe0 {
+ return VariantFuture
+ }
+ return VariantUnknown
+}
+
+func (g *GUID) setVersion(v Version) {
+ g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
+}
+
+// Version returns the GUID version, as defined in RFC 4122.
+func (g GUID) Version() Version {
+ return Version((g.Data3 & 0xF000) >> 12)
+}
+
+// MarshalText returns the textual representation of the GUID.
+func (g GUID) MarshalText() ([]byte, error) {
+ return []byte(g.String()), nil
+}
+
+// UnmarshalText takes the textual representation of a GUID, and unmarhals it
+// into this GUID.
+func (g *GUID) UnmarshalText(text []byte) error {
+ g2, err := FromString(string(text))
+ if err != nil {
+ return err
+ }
+ *g = g2
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
new file mode 100644
index 0000000..805bd35
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
@@ -0,0 +1,16 @@
+//go:build !windows
+// +build !windows
+
+package guid
+
+// GUID represents a GUID/UUID. It has the same structure as
+// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
+// that type. It is defined as its own type as that is only available to builds
+// targeted at `windows`. The representation matches that used by native Windows
+// code.
+type GUID struct {
+ Data1 uint32
+ Data2 uint16
+ Data3 uint16
+ Data4 [8]byte
+}
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
new file mode 100644
index 0000000..27e45ee
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
@@ -0,0 +1,13 @@
+//go:build windows
+// +build windows
+
+package guid
+
+import "golang.org/x/sys/windows"
+
+// GUID represents a GUID/UUID. It has the same structure as
+// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
+// that type. It is defined as its own type so that stringification and
+// marshaling can be supported. The representation matches that used by native
+// Windows code.
+type GUID windows.GUID
diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
new file mode 100644
index 0000000..4076d31
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
@@ -0,0 +1,27 @@
+// Code generated by "stringer -type=Variant -trimprefix=Variant -linecomment"; DO NOT EDIT.
+
+package guid
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[VariantUnknown-0]
+ _ = x[VariantNCS-1]
+ _ = x[VariantRFC4122-2]
+ _ = x[VariantMicrosoft-3]
+ _ = x[VariantFuture-4]
+}
+
+const _Variant_name = "UnknownNCSRFC 4122MicrosoftFuture"
+
+var _Variant_index = [...]uint8{0, 7, 10, 18, 27, 33}
+
+func (i Variant) String() string {
+ if i >= Variant(len(_Variant_index)-1) {
+ return "Variant(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _Variant_name[_Variant_index[i]:_Variant_index[i+1]]
+}
diff --git a/vendor/github.com/Microsoft/go-winio/privilege.go b/vendor/github.com/Microsoft/go-winio/privilege.go
new file mode 100644
index 0000000..d9b90b6
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/privilege.go
@@ -0,0 +1,196 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "runtime"
+ "sync"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
+//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
+//sys revertToSelf() (err error) = advapi32.RevertToSelf
+//sys openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
+//sys getCurrentThread() (h windows.Handle) = GetCurrentThread
+//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
+//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
+//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
+
+const (
+ //revive:disable-next-line:var-naming ALL_CAPS
+ SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED
+
+ //revive:disable-next-line:var-naming ALL_CAPS
+ ERROR_NOT_ALL_ASSIGNED windows.Errno = windows.ERROR_NOT_ALL_ASSIGNED
+
+ SeBackupPrivilege = "SeBackupPrivilege"
+ SeRestorePrivilege = "SeRestorePrivilege"
+ SeSecurityPrivilege = "SeSecurityPrivilege"
+)
+
+var (
+ privNames = make(map[string]uint64)
+ privNameMutex sync.Mutex
+)
+
+// PrivilegeError represents an error enabling privileges.
+type PrivilegeError struct {
+ privileges []uint64
+}
+
+func (e *PrivilegeError) Error() string {
+ s := "Could not enable privilege "
+ if len(e.privileges) > 1 {
+ s = "Could not enable privileges "
+ }
+ for i, p := range e.privileges {
+ if i != 0 {
+ s += ", "
+ }
+ s += `"`
+ s += getPrivilegeName(p)
+ s += `"`
+ }
+ return s
+}
+
+// RunWithPrivilege enables a single privilege for a function call.
+func RunWithPrivilege(name string, fn func() error) error {
+ return RunWithPrivileges([]string{name}, fn)
+}
+
+// RunWithPrivileges enables privileges for a function call.
+func RunWithPrivileges(names []string, fn func() error) error {
+ privileges, err := mapPrivileges(names)
+ if err != nil {
+ return err
+ }
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ token, err := newThreadToken()
+ if err != nil {
+ return err
+ }
+ defer releaseThreadToken(token)
+ err = adjustPrivileges(token, privileges, SE_PRIVILEGE_ENABLED)
+ if err != nil {
+ return err
+ }
+ return fn()
+}
+
+func mapPrivileges(names []string) ([]uint64, error) {
+ privileges := make([]uint64, 0, len(names))
+ privNameMutex.Lock()
+ defer privNameMutex.Unlock()
+ for _, name := range names {
+ p, ok := privNames[name]
+ if !ok {
+ err := lookupPrivilegeValue("", name, &p)
+ if err != nil {
+ return nil, err
+ }
+ privNames[name] = p
+ }
+ privileges = append(privileges, p)
+ }
+ return privileges, nil
+}
+
+// EnableProcessPrivileges enables privileges globally for the process.
+func EnableProcessPrivileges(names []string) error {
+ return enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED)
+}
+
+// DisableProcessPrivileges disables privileges globally for the process.
+func DisableProcessPrivileges(names []string) error {
+ return enableDisableProcessPrivilege(names, 0)
+}
+
+func enableDisableProcessPrivilege(names []string, action uint32) error {
+ privileges, err := mapPrivileges(names)
+ if err != nil {
+ return err
+ }
+
+ p := windows.CurrentProcess()
+ var token windows.Token
+ err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
+ if err != nil {
+ return err
+ }
+
+ defer token.Close()
+ return adjustPrivileges(token, privileges, action)
+}
+
+func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {
+ var b bytes.Buffer
+ _ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
+ for _, p := range privileges {
+ _ = binary.Write(&b, binary.LittleEndian, p)
+ _ = binary.Write(&b, binary.LittleEndian, action)
+ }
+ prevState := make([]byte, b.Len())
+ reqSize := uint32(0)
+ success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
+ if !success {
+ return err
+ }
+ if err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno
+ return &PrivilegeError{privileges}
+ }
+ return nil
+}
+
+func getPrivilegeName(luid uint64) string {
+ var nameBuffer [256]uint16
+ bufSize := uint32(len(nameBuffer))
+ err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
+ if err != nil {
+ return fmt.Sprintf("", luid)
+ }
+
+ var displayNameBuffer [256]uint16
+ displayBufSize := uint32(len(displayNameBuffer))
+ var langID uint32
+ err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)
+ if err != nil {
+ return fmt.Sprintf("", string(utf16.Decode(nameBuffer[:bufSize])))
+ }
+
+ return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
+}
+
+func newThreadToken() (windows.Token, error) {
+ err := impersonateSelf(windows.SecurityImpersonation)
+ if err != nil {
+ return 0, err
+ }
+
+ var token windows.Token
+ err = openThreadToken(getCurrentThread(), windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, false, &token)
+ if err != nil {
+ rerr := revertToSelf()
+ if rerr != nil {
+ panic(rerr)
+ }
+ return 0, err
+ }
+ return token, nil
+}
+
+func releaseThreadToken(h windows.Token) {
+ err := revertToSelf()
+ if err != nil {
+ panic(err)
+ }
+ h.Close()
+}
diff --git a/vendor/github.com/Microsoft/go-winio/reparse.go b/vendor/github.com/Microsoft/go-winio/reparse.go
new file mode 100644
index 0000000..67d1a10
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/reparse.go
@@ -0,0 +1,131 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "strings"
+ "unicode/utf16"
+ "unsafe"
+)
+
+const (
+ reparseTagMountPoint = 0xA0000003
+ reparseTagSymlink = 0xA000000C
+)
+
+type reparseDataBuffer struct {
+ ReparseTag uint32
+ ReparseDataLength uint16
+ Reserved uint16
+ SubstituteNameOffset uint16
+ SubstituteNameLength uint16
+ PrintNameOffset uint16
+ PrintNameLength uint16
+}
+
+// ReparsePoint describes a Win32 symlink or mount point.
+type ReparsePoint struct {
+ Target string
+ IsMountPoint bool
+}
+
+// UnsupportedReparsePointError is returned when trying to decode a non-symlink or
+// mount point reparse point.
+type UnsupportedReparsePointError struct {
+ Tag uint32
+}
+
+func (e *UnsupportedReparsePointError) Error() string {
+ return fmt.Sprintf("unsupported reparse point %x", e.Tag)
+}
+
+// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
+// or a mount point.
+func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
+ tag := binary.LittleEndian.Uint32(b[0:4])
+ return DecodeReparsePointData(tag, b[8:])
+}
+
+func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) {
+ isMountPoint := false
+ switch tag {
+ case reparseTagMountPoint:
+ isMountPoint = true
+ case reparseTagSymlink:
+ default:
+ return nil, &UnsupportedReparsePointError{tag}
+ }
+ nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6])
+ if !isMountPoint {
+ nameOffset += 4
+ }
+ nameLength := binary.LittleEndian.Uint16(b[6:8])
+ name := make([]uint16, nameLength/2)
+ err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
+ if err != nil {
+ return nil, err
+ }
+ return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil
+}
+
+func isDriveLetter(c byte) bool {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or
+// mount point.
+func EncodeReparsePoint(rp *ReparsePoint) []byte {
+ // Generate an NT path and determine if this is a relative path.
+ var ntTarget string
+ relative := false
+ if strings.HasPrefix(rp.Target, `\\?\`) {
+ ntTarget = `\??\` + rp.Target[4:]
+ } else if strings.HasPrefix(rp.Target, `\\`) {
+ ntTarget = `\??\UNC\` + rp.Target[2:]
+ } else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {
+ ntTarget = `\??\` + rp.Target
+ } else {
+ ntTarget = rp.Target
+ relative = true
+ }
+
+ // The paths must be NUL-terminated even though they are counted strings.
+ target16 := utf16.Encode([]rune(rp.Target + "\x00"))
+ ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00"))
+
+ size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8
+ size += len(ntTarget16)*2 + len(target16)*2
+
+ tag := uint32(reparseTagMountPoint)
+ if !rp.IsMountPoint {
+ tag = reparseTagSymlink
+ size += 4 // Add room for symlink flags
+ }
+
+ data := reparseDataBuffer{
+ ReparseTag: tag,
+ ReparseDataLength: uint16(size),
+ SubstituteNameOffset: 0,
+ SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),
+ PrintNameOffset: uint16(len(ntTarget16) * 2),
+ PrintNameLength: uint16((len(target16) - 1) * 2),
+ }
+
+ var b bytes.Buffer
+ _ = binary.Write(&b, binary.LittleEndian, &data)
+ if !rp.IsMountPoint {
+ flags := uint32(0)
+ if relative {
+ flags |= 1
+ }
+ _ = binary.Write(&b, binary.LittleEndian, flags)
+ }
+
+ _ = binary.Write(&b, binary.LittleEndian, ntTarget16)
+ _ = binary.Write(&b, binary.LittleEndian, target16)
+ return b.Bytes()
+}
diff --git a/vendor/github.com/Microsoft/go-winio/sd.go b/vendor/github.com/Microsoft/go-winio/sd.go
new file mode 100644
index 0000000..c3685e9
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/sd.go
@@ -0,0 +1,133 @@
+//go:build windows
+// +build windows
+
+package winio
+
+import (
+ "errors"
+ "fmt"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
+//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW
+//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW
+
+type AccountLookupError struct {
+ Name string
+ Err error
+}
+
+func (e *AccountLookupError) Error() string {
+ if e.Name == "" {
+ return "lookup account: empty account name specified"
+ }
+ var s string
+ switch {
+ case errors.Is(e.Err, windows.ERROR_INVALID_SID):
+ s = "the security ID structure is invalid"
+ case errors.Is(e.Err, windows.ERROR_NONE_MAPPED):
+ s = "not found"
+ default:
+ s = e.Err.Error()
+ }
+ return "lookup account " + e.Name + ": " + s
+}
+
+func (e *AccountLookupError) Unwrap() error { return e.Err }
+
+type SddlConversionError struct {
+ Sddl string
+ Err error
+}
+
+func (e *SddlConversionError) Error() string {
+ return "convert " + e.Sddl + ": " + e.Err.Error()
+}
+
+func (e *SddlConversionError) Unwrap() error { return e.Err }
+
+// LookupSidByName looks up the SID of an account by name
+//
+//revive:disable-next-line:var-naming SID, not Sid
+func LookupSidByName(name string) (sid string, err error) {
+ if name == "" {
+ return "", &AccountLookupError{name, windows.ERROR_NONE_MAPPED}
+ }
+
+ var sidSize, sidNameUse, refDomainSize uint32
+ err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
+ if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
+ return "", &AccountLookupError{name, err}
+ }
+ sidBuffer := make([]byte, sidSize)
+ refDomainBuffer := make([]uint16, refDomainSize)
+ err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
+ if err != nil {
+ return "", &AccountLookupError{name, err}
+ }
+ var strBuffer *uint16
+ err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
+ if err != nil {
+ return "", &AccountLookupError{name, err}
+ }
+ sid = windows.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
+ _, _ = windows.LocalFree(windows.Handle(unsafe.Pointer(strBuffer)))
+ return sid, nil
+}
+
+// LookupNameBySid looks up the name of an account by SID
+//
+//revive:disable-next-line:var-naming SID, not Sid
+func LookupNameBySid(sid string) (name string, err error) {
+ if sid == "" {
+ return "", &AccountLookupError{sid, windows.ERROR_NONE_MAPPED}
+ }
+
+ sidBuffer, err := windows.UTF16PtrFromString(sid)
+ if err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+
+ var sidPtr *byte
+ if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+ defer windows.LocalFree(windows.Handle(unsafe.Pointer(sidPtr))) //nolint:errcheck
+
+ var nameSize, refDomainSize, sidNameUse uint32
+ err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse)
+ if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
+ return "", &AccountLookupError{sid, err}
+ }
+
+ nameBuffer := make([]uint16, nameSize)
+ refDomainBuffer := make([]uint16, refDomainSize)
+ err = lookupAccountSid(nil, sidPtr, &nameBuffer[0], &nameSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
+ if err != nil {
+ return "", &AccountLookupError{sid, err}
+ }
+
+ name = windows.UTF16ToString(nameBuffer)
+ return name, nil
+}
+
+func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
+ sd, err := windows.SecurityDescriptorFromString(sddl)
+ if err != nil {
+ return nil, &SddlConversionError{Sddl: sddl, Err: err}
+ }
+ b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length())
+ return b, nil
+}
+
+func SecurityDescriptorToSddl(sd []byte) (string, error) {
+ if l := int(unsafe.Sizeof(windows.SECURITY_DESCRIPTOR{})); len(sd) < l {
+ return "", fmt.Errorf("SecurityDescriptor (%d) smaller than expected (%d): %w", len(sd), l, windows.ERROR_INCORRECT_SIZE)
+ }
+ s := (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&sd[0]))
+ return s.String(), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/syscall.go b/vendor/github.com/Microsoft/go-winio/syscall.go
new file mode 100644
index 0000000..a6ca111
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/syscall.go
@@ -0,0 +1,5 @@
+//go:build windows
+
+package winio
+
+//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go
diff --git a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
new file mode 100644
index 0000000..89b66ed
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
@@ -0,0 +1,378 @@
+//go:build windows
+
+// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
+
+package winio
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ return e
+}
+
+var (
+ modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ modntdll = windows.NewLazySystemDLL("ntdll.dll")
+ modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
+
+ procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
+ procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
+ procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
+ procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
+ procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
+ procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
+ procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
+ procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
+ procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
+ procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
+ procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
+ procBackupRead = modkernel32.NewProc("BackupRead")
+ procBackupWrite = modkernel32.NewProc("BackupWrite")
+ procCancelIoEx = modkernel32.NewProc("CancelIoEx")
+ procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
+ procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
+ procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
+ procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe")
+ procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
+ procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
+ procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
+ procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
+ procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+ procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
+ procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
+ procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
+ procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
+ procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
+)
+
+func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
+ var _p0 uint32
+ if releaseAll {
+ _p0 = 1
+ }
+ r0, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
+ success = r0 != 0
+ if true {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertSidToStringSid(sid *byte, str **uint16) (err error) {
+ r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func convertStringSidToSid(str *uint16, sid **byte) (err error) {
+ r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func impersonateSelf(level uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(level))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(accountName)
+ if err != nil {
+ return
+ }
+ return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
+}
+
+func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
+}
+
+func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procLookupPrivilegeDisplayNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeName(_p0, luid, buffer, size)
+}
+
+func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procLookupPrivilegeNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ var _p1 *uint16
+ _p1, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _lookupPrivilegeValue(_p0, _p1, luid)
+}
+
+func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
+ r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
+ var _p0 uint32
+ if openAsSelf {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func revertToSelf() (err error) {
+ r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr())
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
+ var _p0 *byte
+ if len(b) > 0 {
+ _p0 = &b[0]
+ }
+ var _p1 uint32
+ if abort {
+ _p1 = 1
+ }
+ var _p2 uint32
+ if processSecurity {
+ _p2 = 1
+ }
+ r1, _, e1 := syscall.SyscallN(procBackupRead.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
+ var _p0 *byte
+ if len(b) > 0 {
+ _p0 = &b[0]
+ }
+ var _p1 uint32
+ if abort {
+ _p1 = 1
+ }
+ var _p2 uint32
+ if processSecurity {
+ _p2 = 1
+ }
+ r1, _, e1 := syscall.SyscallN(procBackupWrite.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) {
+ r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(file), uintptr(unsafe.Pointer(o)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) {
+ r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(o)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) {
+ r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount))
+ newport = windows.Handle(r0)
+ if newport == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
+}
+
+func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) {
+ r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)))
+ handle = windows.Handle(r0)
+ if handle == windows.InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func disconnectNamedPipe(pipe windows.Handle) (err error) {
+ r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getCurrentThread() (h windows.Handle) {
+ r0, _, _ := syscall.SyscallN(procGetCurrentThread.Addr())
+ h = windows.Handle(r0)
+ return
+}
+
+func getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
+ r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) {
+ r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(h), uintptr(flags))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) {
+ r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)))
+ status = ntStatus(r0)
+ return
+}
+
+func rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) {
+ r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(dacl)))
+ status = ntStatus(r0)
+ return
+}
+
+func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) {
+ r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved))
+ status = ntStatus(r0)
+ return
+}
+
+func rtlNtStatusToDosError(status ntStatus) (winerr error) {
+ r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(status))
+ if r0 != 0 {
+ winerr = syscall.Errno(r0)
+ }
+ return
+}
+
+func wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
+ var _p0 uint32
+ if wait {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/AUTHORS b/vendor/github.com/ProtonMail/go-crypto/AUTHORS
new file mode 100644
index 0000000..2b00ddb
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at https://tip.golang.org/AUTHORS.
diff --git a/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS b/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS
new file mode 100644
index 0000000..1fbd3e9
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/github.com/ProtonMail/go-crypto/LICENSE b/vendor/github.com/ProtonMail/go-crypto/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/ProtonMail/go-crypto/PATENTS b/vendor/github.com/ProtonMail/go-crypto/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
new file mode 100644
index 0000000..c85e6be
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/bitcurves/bitcurve.go
@@ -0,0 +1,381 @@
+package bitcurves
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2011 ThePiachu. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bitelliptic implements several Koblitz elliptic curves over prime
+// fields.
+
+// This package operates, internally, on Jacobian coordinates. For a given
+// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
+// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
+// calculation can be performed within the transform (as in ScalarMult and
+// ScalarBaseMult). But even for Add and Double, it's faster to apply and
+// reverse the transform than to operate in affine coordinates.
+
+import (
+ "crypto/elliptic"
+ "io"
+ "math/big"
+ "sync"
+)
+
+// A BitCurve represents a Koblitz Curve with a=0.
+// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
+type BitCurve struct {
+ Name string
+ P *big.Int // the order of the underlying field
+ N *big.Int // the order of the base point
+ B *big.Int // the constant of the BitCurve equation
+ Gx, Gy *big.Int // (x,y) of the base point
+ BitSize int // the size of the underlying field
+}
+
+// Params returns the parameters of the given BitCurve (see BitCurve struct)
+func (bitCurve *BitCurve) Params() (cp *elliptic.CurveParams) {
+ cp = new(elliptic.CurveParams)
+ cp.Name = bitCurve.Name
+ cp.P = bitCurve.P
+ cp.N = bitCurve.N
+ cp.Gx = bitCurve.Gx
+ cp.Gy = bitCurve.Gy
+ cp.BitSize = bitCurve.BitSize
+ return cp
+}
+
+// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
+func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
+ // y² = x³ + b
+ y2 := new(big.Int).Mul(y, y) //y²
+ y2.Mod(y2, bitCurve.P) //y²%P
+
+ x3 := new(big.Int).Mul(x, x) //x²
+ x3.Mul(x3, x) //x³
+
+ x3.Add(x3, bitCurve.B) //x³+B
+ x3.Mod(x3, bitCurve.P) //(x³+B)%P
+
+ return x3.Cmp(y2) == 0
+}
+
+// affineFromJacobian reverses the Jacobian transform. See the comment at the
+// top of the file.
+func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
+ if z.Cmp(big.NewInt(0)) == 0 {
+ panic("bitcurve: Can't convert to affine with Jacobian Z = 0")
+ }
+ // x = YZ^2 mod P
+ zinv := new(big.Int).ModInverse(z, bitCurve.P)
+ zinvsq := new(big.Int).Mul(zinv, zinv)
+
+ xOut = new(big.Int).Mul(x, zinvsq)
+ xOut.Mod(xOut, bitCurve.P)
+ // y = YZ^3 mod P
+ zinvsq.Mul(zinvsq, zinv)
+ yOut = new(big.Int).Mul(y, zinvsq)
+ yOut.Mod(yOut, bitCurve.P)
+ return xOut, yOut
+}
+
+// Add returns the sum of (x1,y1) and (x2,y2)
+func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+ z := new(big.Int).SetInt64(1)
+ x, y, z := bitCurve.addJacobian(x1, y1, z, x2, y2, z)
+ return bitCurve.affineFromJacobian(x, y, z)
+}
+
+// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
+// (x2, y2, z2) and returns their sum, also in Jacobian form.
+func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
+ z1z1 := new(big.Int).Mul(z1, z1)
+ z1z1.Mod(z1z1, bitCurve.P)
+ z2z2 := new(big.Int).Mul(z2, z2)
+ z2z2.Mod(z2z2, bitCurve.P)
+
+ u1 := new(big.Int).Mul(x1, z2z2)
+ u1.Mod(u1, bitCurve.P)
+ u2 := new(big.Int).Mul(x2, z1z1)
+ u2.Mod(u2, bitCurve.P)
+ h := new(big.Int).Sub(u2, u1)
+ if h.Sign() == -1 {
+ h.Add(h, bitCurve.P)
+ }
+ i := new(big.Int).Lsh(h, 1)
+ i.Mul(i, i)
+ j := new(big.Int).Mul(h, i)
+
+ s1 := new(big.Int).Mul(y1, z2)
+ s1.Mul(s1, z2z2)
+ s1.Mod(s1, bitCurve.P)
+ s2 := new(big.Int).Mul(y2, z1)
+ s2.Mul(s2, z1z1)
+ s2.Mod(s2, bitCurve.P)
+ r := new(big.Int).Sub(s2, s1)
+ if r.Sign() == -1 {
+ r.Add(r, bitCurve.P)
+ }
+ r.Lsh(r, 1)
+ v := new(big.Int).Mul(u1, i)
+
+ x3 := new(big.Int).Set(r)
+ x3.Mul(x3, x3)
+ x3.Sub(x3, j)
+ x3.Sub(x3, v)
+ x3.Sub(x3, v)
+ x3.Mod(x3, bitCurve.P)
+
+ y3 := new(big.Int).Set(r)
+ v.Sub(v, x3)
+ y3.Mul(y3, v)
+ s1.Mul(s1, j)
+ s1.Lsh(s1, 1)
+ y3.Sub(y3, s1)
+ y3.Mod(y3, bitCurve.P)
+
+ z3 := new(big.Int).Add(z1, z2)
+ z3.Mul(z3, z3)
+ z3.Sub(z3, z1z1)
+ if z3.Sign() == -1 {
+ z3.Add(z3, bitCurve.P)
+ }
+ z3.Sub(z3, z2z2)
+ if z3.Sign() == -1 {
+ z3.Add(z3, bitCurve.P)
+ }
+ z3.Mul(z3, h)
+ z3.Mod(z3, bitCurve.P)
+
+ return x3, y3, z3
+}
+
+// Double returns 2*(x,y)
+func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+ z1 := new(big.Int).SetInt64(1)
+ return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1))
+}
+
+// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
+// returns its double, also in Jacobian form.
+func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
+
+ a := new(big.Int).Mul(x, x) //X1²
+ b := new(big.Int).Mul(y, y) //Y1²
+ c := new(big.Int).Mul(b, b) //B²
+
+ d := new(big.Int).Add(x, b) //X1+B
+ d.Mul(d, d) //(X1+B)²
+ d.Sub(d, a) //(X1+B)²-A
+ d.Sub(d, c) //(X1+B)²-A-C
+ d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C)
+
+ e := new(big.Int).Mul(big.NewInt(3), a) //3*A
+ f := new(big.Int).Mul(e, e) //E²
+
+ x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D
+ x3.Sub(f, x3) //F-2*D
+ x3.Mod(x3, bitCurve.P)
+
+ y3 := new(big.Int).Sub(d, x3) //D-X3
+ y3.Mul(e, y3) //E*(D-X3)
+ y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C
+ y3.Mod(y3, bitCurve.P)
+
+ z3 := new(big.Int).Mul(y, z) //Y1*Z1
+ z3.Mul(big.NewInt(2), z3) //3*Y1*Z1
+ z3.Mod(z3, bitCurve.P)
+
+ return x3, y3, z3
+}
+
+// TODO: double check if it is okay
+// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
+func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
+ // We have a slight problem in that the identity of the group (the
+ // point at infinity) cannot be represented in (x, y) form on a finite
+ // machine. Thus the standard add/double algorithm has to be tweaked
+ // slightly: our initial state is not the identity, but x, and we
+ // ignore the first true bit in |k|. If we don't find any true bits in
+ // |k|, then we return nil, nil, because we cannot return the identity
+ // element.
+
+ Bz := new(big.Int).SetInt64(1)
+ x := Bx
+ y := By
+ z := Bz
+
+ seenFirstTrue := false
+ for _, byte := range k {
+ for bitNum := 0; bitNum < 8; bitNum++ {
+ if seenFirstTrue {
+ x, y, z = bitCurve.doubleJacobian(x, y, z)
+ }
+ if byte&0x80 == 0x80 {
+ if !seenFirstTrue {
+ seenFirstTrue = true
+ } else {
+ x, y, z = bitCurve.addJacobian(Bx, By, Bz, x, y, z)
+ }
+ }
+ byte <<= 1
+ }
+ }
+
+ if !seenFirstTrue {
+ return nil, nil
+ }
+
+ return bitCurve.affineFromJacobian(x, y, z)
+}
+
+// ScalarBaseMult returns k*G, where G is the base point of the group and k is
+// an integer in big-endian form.
+func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+ return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k)
+}
+
+var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
+
+// TODO: double check if it is okay
+// GenerateKey returns a public/private key pair. The private key is generated
+// using the given reader, which must return random data.
+func (bitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+ priv = make([]byte, byteLen)
+
+ for x == nil {
+ _, err = io.ReadFull(rand, priv)
+ if err != nil {
+ return
+ }
+ // We have to mask off any excess bits in the case that the size of the
+ // underlying field is not a whole number of bytes.
+ priv[0] &= mask[bitCurve.BitSize%8]
+ // This is because, in tests, rand will return all zeros and we don't
+ // want to get the point at infinity and loop forever.
+ priv[1] ^= 0x42
+ x, y = bitCurve.ScalarBaseMult(priv)
+ }
+ return
+}
+
+// Marshal converts a point into the form specified in section 4.3.6 of ANSI
+// X9.62.
+func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+
+ ret := make([]byte, 1+2*byteLen)
+ ret[0] = 4 // uncompressed point
+
+ xBytes := x.Bytes()
+ copy(ret[1+byteLen-len(xBytes):], xBytes)
+ yBytes := y.Bytes()
+ copy(ret[1+2*byteLen-len(yBytes):], yBytes)
+ return ret
+}
+
+// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On
+// error, x = nil.
+func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
+ byteLen := (bitCurve.BitSize + 7) >> 3
+ if len(data) != 1+2*byteLen {
+ return
+ }
+ if data[0] != 4 { // uncompressed form
+ return
+ }
+ x = new(big.Int).SetBytes(data[1 : 1+byteLen])
+ y = new(big.Int).SetBytes(data[1+byteLen:])
+ return
+}
+
+//curve parameters taken from:
+//http://www.secg.org/collateral/sec2_final.pdf
+
+var initonce sync.Once
+var secp160k1 *BitCurve
+var secp192k1 *BitCurve
+var secp224k1 *BitCurve
+var secp256k1 *BitCurve
+
+func initAll() {
+ initS160()
+ initS192()
+ initS224()
+ initS256()
+}
+
+func initS160() {
+ // See SEC 2 section 2.4.1
+ secp160k1 = new(BitCurve)
+ secp160k1.Name = "secp160k1"
+ secp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16)
+ secp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16)
+ secp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16)
+ secp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16)
+ secp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16)
+ secp160k1.BitSize = 160
+}
+
+func initS192() {
+ // See SEC 2 section 2.5.1
+ secp192k1 = new(BitCurve)
+ secp192k1.Name = "secp192k1"
+ secp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16)
+ secp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16)
+ secp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16)
+ secp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16)
+ secp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16)
+ secp192k1.BitSize = 192
+}
+
+func initS224() {
+ // See SEC 2 section 2.6.1
+ secp224k1 = new(BitCurve)
+ secp224k1.Name = "secp224k1"
+ secp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16)
+ secp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16)
+ secp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16)
+ secp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16)
+ secp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16)
+ secp224k1.BitSize = 224
+}
+
+func initS256() {
+ // See SEC 2 section 2.7.1
+ secp256k1 = new(BitCurve)
+ secp256k1.Name = "secp256k1"
+ secp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
+ secp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
+ secp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
+ secp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
+ secp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
+ secp256k1.BitSize = 256
+}
+
+// S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1)
+func S160() *BitCurve {
+ initonce.Do(initAll)
+ return secp160k1
+}
+
+// S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1)
+func S192() *BitCurve {
+ initonce.Do(initAll)
+ return secp192k1
+}
+
+// S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1)
+func S224() *BitCurve {
+ initonce.Do(initAll)
+ return secp224k1
+}
+
+// S256 returns a BitCurve which implements bitcurves (see SEC 2 section 2.7.1)
+func S256() *BitCurve {
+ initonce.Do(initAll)
+ return secp256k1
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go b/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
new file mode 100644
index 0000000..cb6676d
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/brainpool/brainpool.go
@@ -0,0 +1,134 @@
+// Package brainpool implements Brainpool elliptic curves.
+// Implementation of rcurves is from github.com/ebfe/brainpool
+// Note that these curves are implemented with naive, non-constant time operations
+// and are likely not suitable for environments where timing attacks are a concern.
+package brainpool
+
+import (
+ "crypto/elliptic"
+ "math/big"
+ "sync"
+)
+
+var (
+ once sync.Once
+ p256t1, p384t1, p512t1 *elliptic.CurveParams
+ p256r1, p384r1, p512r1 *rcurve
+)
+
+func initAll() {
+ initP256t1()
+ initP384t1()
+ initP512t1()
+ initP256r1()
+ initP384r1()
+ initP512r1()
+}
+
+func initP256t1() {
+ p256t1 = &elliptic.CurveParams{Name: "brainpoolP256t1"}
+ p256t1.P, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16)
+ p256t1.N, _ = new(big.Int).SetString("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16)
+ p256t1.B, _ = new(big.Int).SetString("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16)
+ p256t1.Gx, _ = new(big.Int).SetString("A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4", 16)
+ p256t1.Gy, _ = new(big.Int).SetString("2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE", 16)
+ p256t1.BitSize = 256
+}
+
+func initP256r1() {
+ twisted := p256t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP256r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", 16)
+ params.Gy, _ = new(big.Int).SetString("547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", 16)
+ z, _ := new(big.Int).SetString("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0", 16)
+ p256r1 = newrcurve(twisted, params, z)
+}
+
+func initP384t1() {
+ p384t1 = &elliptic.CurveParams{Name: "brainpoolP384t1"}
+ p384t1.P, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16)
+ p384t1.N, _ = new(big.Int).SetString("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16)
+ p384t1.B, _ = new(big.Int).SetString("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16)
+ p384t1.Gx, _ = new(big.Int).SetString("18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC", 16)
+ p384t1.Gy, _ = new(big.Int).SetString("25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928", 16)
+ p384t1.BitSize = 384
+}
+
+func initP384r1() {
+ twisted := p384t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP384r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", 16)
+ params.Gy, _ = new(big.Int).SetString("8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", 16)
+ z, _ := new(big.Int).SetString("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C", 16)
+ p384r1 = newrcurve(twisted, params, z)
+}
+
+func initP512t1() {
+ p512t1 = &elliptic.CurveParams{Name: "brainpoolP512t1"}
+ p512t1.P, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16)
+ p512t1.N, _ = new(big.Int).SetString("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16)
+ p512t1.B, _ = new(big.Int).SetString("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16)
+ p512t1.Gx, _ = new(big.Int).SetString("640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA", 16)
+ p512t1.Gy, _ = new(big.Int).SetString("5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332", 16)
+ p512t1.BitSize = 512
+}
+
+func initP512r1() {
+ twisted := p512t1
+ params := &elliptic.CurveParams{
+ Name: "brainpoolP512r1",
+ P: twisted.P,
+ N: twisted.N,
+ BitSize: twisted.BitSize,
+ }
+ params.Gx, _ = new(big.Int).SetString("81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", 16)
+ params.Gy, _ = new(big.Int).SetString("7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", 16)
+ z, _ := new(big.Int).SetString("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB", 16)
+ p512r1 = newrcurve(twisted, params, z)
+}
+
+// P256t1 returns a Curve which implements Brainpool P256t1 (see RFC 5639, section 3.4)
+func P256t1() elliptic.Curve {
+ once.Do(initAll)
+ return p256t1
+}
+
+// P256r1 returns a Curve which implements Brainpool P256r1 (see RFC 5639, section 3.4)
+func P256r1() elliptic.Curve {
+ once.Do(initAll)
+ return p256r1
+}
+
+// P384t1 returns a Curve which implements Brainpool P384t1 (see RFC 5639, section 3.6)
+func P384t1() elliptic.Curve {
+ once.Do(initAll)
+ return p384t1
+}
+
+// P384r1 returns a Curve which implements Brainpool P384r1 (see RFC 5639, section 3.6)
+func P384r1() elliptic.Curve {
+ once.Do(initAll)
+ return p384r1
+}
+
+// P512t1 returns a Curve which implements Brainpool P512t1 (see RFC 5639, section 3.7)
+func P512t1() elliptic.Curve {
+ once.Do(initAll)
+ return p512t1
+}
+
+// P512r1 returns a Curve which implements Brainpool P512r1 (see RFC 5639, section 3.7)
+func P512r1() elliptic.Curve {
+ once.Do(initAll)
+ return p512r1
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
new file mode 100644
index 0000000..7e291d6
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/brainpool/rcurve.go
@@ -0,0 +1,83 @@
+package brainpool
+
+import (
+ "crypto/elliptic"
+ "math/big"
+)
+
+var _ elliptic.Curve = (*rcurve)(nil)
+
+type rcurve struct {
+ twisted elliptic.Curve
+ params *elliptic.CurveParams
+ z *big.Int
+ zinv *big.Int
+ z2 *big.Int
+ z3 *big.Int
+ zinv2 *big.Int
+ zinv3 *big.Int
+}
+
+var (
+ two = big.NewInt(2)
+ three = big.NewInt(3)
+)
+
+func newrcurve(twisted elliptic.Curve, params *elliptic.CurveParams, z *big.Int) *rcurve {
+ zinv := new(big.Int).ModInverse(z, params.P)
+ return &rcurve{
+ twisted: twisted,
+ params: params,
+ z: z,
+ zinv: zinv,
+ z2: new(big.Int).Exp(z, two, params.P),
+ z3: new(big.Int).Exp(z, three, params.P),
+ zinv2: new(big.Int).Exp(zinv, two, params.P),
+ zinv3: new(big.Int).Exp(zinv, three, params.P),
+ }
+}
+
+func (curve *rcurve) toTwisted(x, y *big.Int) (*big.Int, *big.Int) {
+ var tx, ty big.Int
+ tx.Mul(x, curve.z2)
+ tx.Mod(&tx, curve.params.P)
+ ty.Mul(y, curve.z3)
+ ty.Mod(&ty, curve.params.P)
+ return &tx, &ty
+}
+
+func (curve *rcurve) fromTwisted(tx, ty *big.Int) (*big.Int, *big.Int) {
+ var x, y big.Int
+ x.Mul(tx, curve.zinv2)
+ x.Mod(&x, curve.params.P)
+ y.Mul(ty, curve.zinv3)
+ y.Mod(&y, curve.params.P)
+ return &x, &y
+}
+
+func (curve *rcurve) Params() *elliptic.CurveParams {
+ return curve.params
+}
+
+func (curve *rcurve) IsOnCurve(x, y *big.Int) bool {
+ return curve.twisted.IsOnCurve(curve.toTwisted(x, y))
+}
+
+func (curve *rcurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
+ tx1, ty1 := curve.toTwisted(x1, y1)
+ tx2, ty2 := curve.toTwisted(x2, y2)
+ return curve.fromTwisted(curve.twisted.Add(tx1, ty1, tx2, ty2))
+}
+
+func (curve *rcurve) Double(x1, y1 *big.Int) (x, y *big.Int) {
+ return curve.fromTwisted(curve.twisted.Double(curve.toTwisted(x1, y1)))
+}
+
+func (curve *rcurve) ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int) {
+ tx1, ty1 := curve.toTwisted(x1, y1)
+ return curve.fromTwisted(curve.twisted.ScalarMult(tx1, ty1, scalar))
+}
+
+func (curve *rcurve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
+ return curve.fromTwisted(curve.twisted.ScalarBaseMult(scalar))
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/eax.go b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go
new file mode 100644
index 0000000..3ae91d5
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/eax.go
@@ -0,0 +1,162 @@
+// Copyright (C) 2019 ProtonTech AG
+
+// Package eax provides an implementation of the EAX
+// (encrypt-authenticate-translate) mode of operation, as described in
+// Bellare, Rogaway, and Wagner "THE EAX MODE OF OPERATION: A TWO-PASS
+// AUTHENTICATED-ENCRYPTION SCHEME OPTIMIZED FOR SIMPLICITY AND EFFICIENCY."
+// In FSE'04, volume 3017 of LNCS, 2004
+package eax
+
+import (
+ "crypto/cipher"
+ "crypto/subtle"
+ "errors"
+ "github.com/ProtonMail/go-crypto/internal/byteutil"
+)
+
+const (
+ defaultTagSize = 16
+ defaultNonceSize = 16
+)
+
+type eax struct {
+ block cipher.Block // Only AES-{128, 192, 256} supported
+ tagSize int // At least 12 bytes recommended
+ nonceSize int
+}
+
+func (e *eax) NonceSize() int {
+ return e.nonceSize
+}
+
+func (e *eax) Overhead() int {
+ return e.tagSize
+}
+
+// NewEAX returns an EAX instance with AES-{KEYLENGTH} and default nonce and
+// tag lengths. Supports {128, 192, 256}- bit key length.
+func NewEAX(block cipher.Block) (cipher.AEAD, error) {
+ return NewEAXWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
+}
+
+// NewEAXWithNonceAndTagSize returns an EAX instance with AES-{keyLength} and
+// given nonce and tag lengths in bytes. Panics on zero nonceSize and
+// exceedingly long tags.
+//
+// It is recommended to use at least 12 bytes as tag length (see, for instance,
+// NIST SP 800-38D).
+//
+// Only to be used for compatibility with existing cryptosystems with
+// non-standard parameters. For all other cases, prefer NewEAX.
+func NewEAXWithNonceAndTagSize(
+ block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
+ if nonceSize < 1 {
+ return nil, eaxError("Cannot initialize EAX with nonceSize = 0")
+ }
+ if tagSize > block.BlockSize() {
+ return nil, eaxError("Custom tag length exceeds blocksize")
+ }
+ return &eax{
+ block: block,
+ tagSize: tagSize,
+ nonceSize: nonceSize,
+ }, nil
+}
+
+func (e *eax) Seal(dst, nonce, plaintext, adata []byte) []byte {
+ if len(nonce) > e.nonceSize {
+ panic("crypto/eax: Nonce too long for this instance")
+ }
+ ret, out := byteutil.SliceForAppend(dst, len(plaintext)+e.tagSize)
+ omacNonce := e.omacT(0, nonce)
+ omacAdata := e.omacT(1, adata)
+
+ // Encrypt message using CTR mode and omacNonce as IV
+ ctr := cipher.NewCTR(e.block, omacNonce)
+ ciphertextData := out[:len(plaintext)]
+ ctr.XORKeyStream(ciphertextData, plaintext)
+
+ omacCiphertext := e.omacT(2, ciphertextData)
+
+ tag := out[len(plaintext):]
+ for i := 0; i < e.tagSize; i++ {
+ tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
+ }
+ return ret
+}
+
+func (e *eax) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
+ if len(nonce) > e.nonceSize {
+ panic("crypto/eax: Nonce too long for this instance")
+ }
+ if len(ciphertext) < e.tagSize {
+ return nil, eaxError("Ciphertext shorter than tag length")
+ }
+ sep := len(ciphertext) - e.tagSize
+
+ // Compute tag
+ omacNonce := e.omacT(0, nonce)
+ omacAdata := e.omacT(1, adata)
+ omacCiphertext := e.omacT(2, ciphertext[:sep])
+
+ tag := make([]byte, e.tagSize)
+ for i := 0; i < e.tagSize; i++ {
+ tag[i] = omacCiphertext[i] ^ omacNonce[i] ^ omacAdata[i]
+ }
+
+ // Compare tags
+ if subtle.ConstantTimeCompare(ciphertext[sep:], tag) != 1 {
+ return nil, eaxError("Tag authentication failed")
+ }
+
+ // Decrypt ciphertext
+ ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
+ ctr := cipher.NewCTR(e.block, omacNonce)
+ ctr.XORKeyStream(out, ciphertext[:sep])
+
+ return ret[:sep], nil
+}
+
+// Tweakable OMAC - Calls OMAC_K([t]_n || plaintext)
+func (e *eax) omacT(t byte, plaintext []byte) []byte {
+ blockSize := e.block.BlockSize()
+ byteT := make([]byte, blockSize)
+ byteT[blockSize-1] = t
+ concat := append(byteT, plaintext...)
+ return e.omac(concat)
+}
+
+func (e *eax) omac(plaintext []byte) []byte {
+ blockSize := e.block.BlockSize()
+ // L ← E_K(0^n); B ← 2L; P ← 4L
+ L := make([]byte, blockSize)
+ e.block.Encrypt(L, L)
+ B := byteutil.GfnDouble(L)
+ P := byteutil.GfnDouble(B)
+
+ // CBC with IV = 0
+ cbc := cipher.NewCBCEncrypter(e.block, make([]byte, blockSize))
+ padded := e.pad(plaintext, B, P)
+ cbcCiphertext := make([]byte, len(padded))
+ cbc.CryptBlocks(cbcCiphertext, padded)
+
+ return cbcCiphertext[len(cbcCiphertext)-blockSize:]
+}
+
+func (e *eax) pad(plaintext, B, P []byte) []byte {
+ // if |M| in {n, 2n, 3n, ...}
+ blockSize := e.block.BlockSize()
+ if len(plaintext) != 0 && len(plaintext)%blockSize == 0 {
+ return byteutil.RightXor(plaintext, B)
+ }
+
+ // else return (M || 1 || 0^(n−1−(|M| % n))) xor→ P
+ ending := make([]byte, blockSize-len(plaintext)%blockSize)
+ ending[0] = 0x80
+ padded := append(plaintext, ending...)
+ return byteutil.RightXor(padded, P)
+}
+
+func eaxError(err string) error {
+ return errors.New("crypto/eax: " + err)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go b/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
new file mode 100644
index 0000000..ddb53d0
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/eax_test_vectors.go
@@ -0,0 +1,58 @@
+package eax
+
+// Test vectors from
+// https://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf
+var testVectors = []struct {
+ msg, key, nonce, header, ciphertext string
+}{
+ {"",
+ "233952DEE4D5ED5F9B9C6D6FF80FF478",
+ "62EC67F9C3A4A407FCB2A8C49031A8B3",
+ "6BFB914FD07EAE6B",
+ "E037830E8389F27B025A2D6527E79D01"},
+ {"F7FB",
+ "91945D3F4DCBEE0BF45EF52255F095A4",
+ "BECAF043B0A23D843194BA972C66DEBD",
+ "FA3BFD4806EB53FA",
+ "19DD5C4C9331049D0BDAB0277408F67967E5"},
+ {"1A47CB4933",
+ "01F74AD64077F2E704C0F60ADA3DD523",
+ "70C3DB4F0D26368400A10ED05D2BFF5E",
+ "234A3463C1264AC6",
+ "D851D5BAE03A59F238A23E39199DC9266626C40F80"},
+ {"481C9E39B1",
+ "D07CF6CBB7F313BDDE66B727AFD3C5E8",
+ "8408DFFF3C1A2B1292DC199E46B7D617",
+ "33CCE2EABFF5A79D",
+ "632A9D131AD4C168A4225D8E1FF755939974A7BEDE"},
+ {"40D0C07DA5E4",
+ "35B6D0580005BBC12B0587124557D2C2",
+ "FDB6B06676EEDC5C61D74276E1F8E816",
+ "AEB96EAEBE2970E9",
+ "071DFE16C675CB0677E536F73AFE6A14B74EE49844DD"},
+ {"4DE3B35C3FC039245BD1FB7D",
+ "BD8E6E11475E60B268784C38C62FEB22",
+ "6EAC5C93072D8E8513F750935E46DA1B",
+ "D4482D1CA78DCE0F",
+ "835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F"},
+ {"8B0A79306C9CE7ED99DAE4F87F8DD61636",
+ "7C77D6E813BED5AC98BAA417477A2E7D",
+ "1A8C98DCD73D38393B2BF1569DEEFC19",
+ "65D2017990D62528",
+ "02083E3979DA014812F59F11D52630DA30137327D10649B0AA6E1C181DB617D7F2"},
+ {"1BDA122BCE8A8DBAF1877D962B8592DD2D56",
+ "5FFF20CAFAB119CA2FC73549E20F5B0D",
+ "DDE59B97D722156D4D9AFF2BC7559826",
+ "54B9F04E6A09189A",
+ "2EC47B2C4954A489AFC7BA4897EDCDAE8CC33B60450599BD02C96382902AEF7F832A"},
+ {"6CF36720872B8513F6EAB1A8A44438D5EF11",
+ "A4A4782BCFFD3EC5E7EF6D8C34A56123",
+ "B781FCF2F75FA5A8DE97A9CA48E522EC",
+ "899A175897561D7E",
+ "0DE18FD0FDD91E7AF19F1D8EE8733938B1E8E7F6D2231618102FDB7FE55FF1991700"},
+ {"CA40D7446E545FFAED3BD12A740A659FFBBB3CEAB7",
+ "8395FCF1E95BEBD697BD010BC766AAC3",
+ "22E7ADD93CFC6393C57EC0B3C17D6B44",
+ "126735FCC320D25A",
+ "CB8920F87A6C75CFF39627B56E3ED197C552D295A7CFC46AFC253B4652B1AF3795B124AB6E"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go b/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
new file mode 100644
index 0000000..4eb19f2
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/eax/random_vectors.go
@@ -0,0 +1,131 @@
+// These vectors include key length in {128, 192, 256}, tag size 128, and
+// random nonce, header, and plaintext lengths.
+
+// This file was automatically generated.
+
+package eax
+
+var randomVectors = []struct {
+ key, nonce, header, plaintext, ciphertext string
+}{
+ {"DFDE093F36B0356E5A81F609786982E3",
+ "1D8AC604419001816905BA72B14CED7E",
+ "152A1517A998D7A24163FCDD146DE81AC347C8B97088F502093C1ABB8F6E33D9A219C34D7603A18B1F5ABE02E56661B7D7F67E81EC08C1302EF38D80A859486D450E94A4F26AD9E68EEBBC0C857A0FC5CF9E641D63D565A7E361BC8908F5A8DC8FD6",
+ "1C8EAAB71077FE18B39730A3156ADE29C5EE824C7EE86ED2A253B775603FB237116E654F6FEC588DD27F523A0E01246FE73FE348491F2A8E9ABC6CA58D663F71CDBCF4AD798BE46C42AE6EE8B599DB44A1A48D7BBBBA0F7D2750181E1C5E66967F7D57CBD30AFBDA5727",
+ "79E7E150934BBEBF7013F61C60462A14D8B15AF7A248AFB8A344EF021C1500E16666891D6E973D8BB56B71A371F12CA34660C4410C016982B20F547E3762A58B7BF4F20236CADCF559E2BE7D783B13723B2741FC7CDC8997D839E39A3DDD2BADB96743DD7049F1BDB0516A262869915B3F70498AFB7B191BF960"},
+ {"F10619EF02E5D94D7550EB84ED364A21",
+ "8DC0D4F2F745BBAE835CC5574B942D20",
+ "FE561358F2E8DF7E1024FF1AE9A8D36EBD01352214505CB99D644777A8A1F6027FA2BDBFC529A9B91136D5F2416CFC5F0F4EC3A1AFD32BDDA23CA504C5A5CB451785FABF4DFE4CD50D817491991A60615B30286361C100A95D1712F2A45F8E374461F4CA2B",
+ "D7B5A971FC219631D30EFC3664AE3127D9CF3097DAD9C24AC7905D15E8D9B25B026B31D68CAE00975CDB81EB1FD96FD5E1A12E2BB83FA25F1B1D91363457657FC03875C27F2946C5",
+ "2F336ED42D3CC38FC61660C4CD60BA4BD438B05F5965D8B7B399D2E7167F5D34F792D318F94DB15D67463AC449E13D568CC09BFCE32A35EE3EE96A041927680AE329811811E27F2D1E8E657707AF99BA96D13A478D695D59"},
+ {"429F514EFC64D98A698A9247274CFF45",
+ "976AA5EB072F912D126ACEBC954FEC38",
+ "A71D89DC5B6CEDBB7451A27C3C2CAE09126DB4C421",
+ "5632FE62AB1DC549D54D3BC3FC868ACCEDEFD9ECF5E9F8",
+ "848AE4306CA8C7F416F8707625B7F55881C0AB430353A5C967CDA2DA787F581A70E34DBEBB2385"},
+ {"398138F309085F47F8457CDF53895A63",
+ "F8A8A7F2D28E5FFF7BBC2F24353F7A36",
+ "5D633C21BA7764B8855CAB586F3746E236AD486039C83C6B56EFA9C651D38A41D6B20DAEE3418BFEA44B8BD6",
+ "A3BBAA91920AF5E10659818B1B3B300AC79BFC129C8329E75251F73A66D3AE0128EB91D5031E0A65C329DB7D1E9C0493E268",
+ "D078097267606E5FB07CFB7E2B4B718172A82C6A4CEE65D549A4DFB9838003BD2FBF64A7A66988AC1A632FD88F9E9FBB57C5A78AD2E086EACBA3DB68511D81C2970A"},
+ {"7A4151EBD3901B42CBA45DAFB2E931BA",
+ "0FC88ACEE74DD538040321C330974EB8",
+ "250464FB04733BAB934C59E6AD2D6AE8D662CBCFEFBE61E5A308D4211E58C4C25935B72C69107722E946BFCBF416796600542D76AEB73F2B25BF53BAF97BDEB36ED3A7A51C31E7F170EB897457E7C17571D1BA0A908954E9",
+ "88C41F3EBEC23FAB8A362D969CAC810FAD4F7CA6A7F7D0D44F060F92E37E1183768DD4A8C733F71C96058D362A39876D183B86C103DE",
+ "74A25B2182C51096D48A870D80F18E1CE15867778E34FCBA6BD7BFB3739FDCD42AD0F2D9F4EBA29085285C6048C15BCE5E5166F1F962D3337AA88E6062F05523029D0A7F0BF9"},
+ {"BFB147E1CD5459424F8C0271FC0E0DC5",
+ "EABCC126442BF373969EA3015988CC45",
+ "4C0880E1D71AA2C7",
+ "BE1B5EC78FBF73E7A6682B21BA7E0E5D2D1C7ABE",
+ "5660D7C1380E2F306895B1402CB2D6C37876504276B414D120F4CF92FDDDBB293A238EA0"},
+ {"595DD6F52D18BC2CA8EB4EDAA18D9FA3",
+ "0F84B5D36CF4BC3B863313AF3B4D2E97",
+ "30AE6CC5F99580F12A779D98BD379A60948020C0B6FBD5746B30BA3A15C6CD33DAF376C70A9F15B6C0EB410A93161F7958AE23",
+ "8EF3687A1642B070970B0B91462229D1D76ABC154D18211F7152AA9FF368",
+ "317C1DDB11417E5A9CC4DDE7FDFF6659A5AC4B31DE025212580A05CDAC6024D3E4AE7C2966E52B9129E9ECDBED86"},
+ {"44E6F2DC8FDC778AD007137D11410F50",
+ "270A237AD977F7187AA6C158A0BAB24F",
+ "509B0F0EB12E2AA5C5BA2DE553C07FAF4CE0C9E926531AA709A3D6224FCB783ACCF1559E10B1123EBB7D52E8AB54E6B5352A9ED0D04124BF0E9D9BACFD7E32B817B2E625F5EE94A64EDE9E470DE7FE6886C19B294F9F828209FE257A78",
+ "8B3D7815DF25618A5D0C55A601711881483878F113A12EC36CF64900549A3199555528559DC118F789788A55FAFD944E6E99A9CA3F72F238CD3F4D88223F7A745992B3FAED1848",
+ "1CC00D79F7AD82FDA71B58D286E5F34D0CC4CEF30704E771CC1E50746BDF83E182B078DB27149A42BAE619DF0F85B0B1090AD55D3B4471B0D6F6ECCD09C8F876B30081F0E7537A9624F8AAF29DA85E324122EFB4D68A56"},
+ {"BB7BC352A03044B4428D8DBB4B0701FDEC4649FD17B81452",
+ "8B4BBE26CCD9859DCD84884159D6B0A4",
+ "2212BEB0E78E0F044A86944CF33C8D5C80D9DBE1034BF3BCF73611835C7D3A52F5BD2D81B68FD681B68540A496EE5DA16FD8AC8824E60E1EC2042BE28FB0BFAD4E4B03596446BDD8C37D936D9B3D5295BE19F19CF5ACE1D33A46C952CE4DE5C12F92C1DD051E04AEED",
+ "9037234CC44FFF828FABED3A7084AF40FA7ABFF8E0C0EFB57A1CC361E18FC4FAC1AB54F3ABFE9FF77263ACE16C3A",
+ "A9391B805CCD956081E0B63D282BEA46E7025126F1C1631239C33E92AA6F92CD56E5A4C56F00FF9658E93D48AF4EF0EF81628E34AD4DB0CDAEDCD2A17EE7"},
+ {"99C0AD703196D2F60A74E6B378B838B31F82EA861F06FC4E",
+ "92745C018AA708ECFEB1667E9F3F1B01",
+ "828C69F376C0C0EC651C67749C69577D589EE39E51404D80EBF70C8660A8F5FD375473F4A7C611D59CB546A605D67446CE2AA844135FCD78BB5FBC90222A00D42920BB1D7EEDFB0C4672554F583EF23184F89063CDECBE482367B5F9AF3ACBC3AF61392BD94CBCD9B64677",
+ "A879214658FD0A5B0E09836639BF82E05EC7A5EF71D4701934BDA228435C68AC3D5CEB54997878B06A655EEACEFB1345C15867E7FE6C6423660C8B88DF128EBD6BCD85118DBAE16E9252FFB204324E5C8F38CA97759BDBF3CB0083",
+ "51FE87996F194A2585E438B023B345439EA60D1AEBED4650CDAF48A4D4EEC4FC77DC71CC4B09D3BEEF8B7B7AF716CE2B4EFFB3AC9E6323C18AC35E0AA6E2BBBC8889490EB6226C896B0D105EAB42BFE7053CCF00ED66BA94C1BA09A792AA873F0C3B26C5C5F9A936E57B25"},
+ {"7086816D00D648FB8304AA8C9E552E1B69A9955FB59B25D1",
+ "0F45CF7F0BF31CCEB85D9DA10F4D749F",
+ "93F27C60A417D9F0669E86ACC784FC8917B502DAF30A6338F11B30B94D74FEFE2F8BE1BBE2EAD10FAB7EED3C6F72B7C3ECEE1937C32ED4970A6404E139209C05",
+ "877F046601F3CBE4FB1491943FA29487E738F94B99AF206262A1D6FF856C9AA0B8D4D08A54370C98F8E88FA3DCC2B14C1F76D71B2A4C7963AEE8AF960464C5BEC8357AD00DC8",
+ "FE96906B895CE6A8E72BC72344E2C8BB3C63113D70EAFA26C299BAFE77A8A6568172EB447FB3E86648A0AF3512DEB1AAC0819F3EC553903BF28A9FB0F43411237A774BF9EE03E445D280FBB9CD12B9BAAB6EF5E52691"},
+ {"062F65A896D5BF1401BADFF70E91B458E1F9BD4888CB2E4D",
+ "5B11EA1D6008EBB41CF892FCA5B943D1",
+ "BAF4FF5C8242",
+ "A8870E091238355984EB2F7D61A865B9170F440BFF999A5993DD41A10F4440D21FF948DDA2BF663B2E03AC3324492DC5E40262ECC6A65C07672353BE23E7FB3A9D79FF6AA38D97960905A38DECC312CB6A59E5467ECF06C311CD43ADC0B543EDF34FE8BE611F176460D5627CA51F8F8D9FED71F55C",
+ "B10E127A632172CF8AA7539B140D2C9C2590E6F28C3CB892FC498FCE56A34F732FBFF32E79C7B9747D9094E8635A0C084D6F0247F9768FB5FF83493799A9BEC6C39572120C40E9292C8C947AE8573462A9108C36D9D7112E6995AE5867E6C8BB387D1C5D4BEF524F391B9FD9F0A3B4BFA079E915BCD920185CFD38D114C558928BD7D47877"},
+ {"38A8E45D6D705A11AF58AED5A1344896998EACF359F2E26A",
+ "FD82B5B31804FF47D44199B533D0CF84",
+ "DE454D4E62FE879F2050EE3E25853623D3E9AC52EEC1A1779A48CFAF5ECA0BFDE44749391866D1",
+ "B804",
+ "164BB965C05EBE0931A1A63293EDF9C38C27"},
+ {"34C33C97C6D7A0850DA94D78A58DC61EC717CD7574833068",
+ "343BE00DA9483F05C14F2E9EB8EA6AE8",
+ "78312A43EFDE3CAE34A65796FF059A3FE15304EEA5CF1D9306949FE5BF3349D4977D4EBE76C040FE894C5949E4E4D6681153DA87FB9AC5062063CA2EA183566343362370944CE0362D25FC195E124FD60E8682E665D13F2229DDA3E4B2CB1DCA",
+ "CC11BB284B1153578E4A5ED9D937B869DAF00F5B1960C23455CA9CC43F486A3BE0B66254F1041F04FDF459C8640465B6E1D2CF899A381451E8E7FCB50CF87823BE77E24B132BBEEDC72E53369B275E1D8F49ECE59F4F215230AC4FE133FC80E4F634EE80BA4682B62C86",
+ "E7F703DC31A95E3A4919FF957836CB76C063D81702AEA4703E1C2BF30831E58C4609D626EC6810E12EAA5B930F049FF9EFC22C3E3F1EBD4A1FB285CB02A1AC5AD46B425199FC0A85670A5C4E3DAA9636C8F64C199F42F18AAC8EA7457FD377F322DD7752D7D01B946C8F0A97E6113F0D50106F319AFD291AAACE"},
+ {"C6ECF7F053573E403E61B83052A343D93CBCC179D1E835BE",
+ "E280E13D7367042E3AA09A80111B6184",
+ "21486C9D7A9647",
+ "5F2639AFA6F17931853791CD8C92382BBB677FD72D0AB1A080D0E49BFAA21810E963E4FACD422E92F65CBFAD5884A60CD94740DF31AF02F95AA57DA0C4401B0ED906",
+ "5C51DB20755302070C45F52E50128A67C8B2E4ED0EACB7E29998CCE2E8C289DD5655913EC1A51CC3AABE5CDC2402B2BE7D6D4BF6945F266FBD70BA9F37109067157AE7530678B45F64475D4EBFCB5FFF46A5"},
+ {"5EC6CF7401BC57B18EF154E8C38ACCA8959E57D2F3975FF5",
+ "656B41CB3F9CF8C08BAD7EBFC80BD225",
+ "6B817C2906E2AF425861A7EF59BA5801F143EE2A139EE72697CDE168B4",
+ "2C0E1DDC9B1E5389BA63845B18B1F8A1DB062037151BCC56EF7C21C0BB4DAE366636BBA975685D7CC5A94AFBE89C769016388C56FB7B57CE750A12B718A8BDCF70E80E8659A8330EFC8F86640F21735E8C80E23FE43ABF23507CE3F964AE4EC99D",
+ "ED780CF911E6D1AA8C979B889B0B9DC1ABE261832980BDBFB576901D9EF5AB8048998E31A15BE54B3E5845A4D136AD24D0BDA1C3006168DF2F8AC06729CB0818867398150020131D8F04EDF1923758C9EABB5F735DE5EA1758D4BC0ACFCA98AFD202E9839B8720253693B874C65586C6F0"},
+ {"C92F678EB2208662F5BCF3403EC05F5961E957908A3E79421E1D25FC19054153",
+ "DA0F3A40983D92F2D4C01FED33C7A192",
+ "2B6E9D26DB406A0FAB47608657AA10EFC2B4AA5F459B29FF85AC9A40BFFE7AEB04F77E9A11FAAA116D7F6D4DA417671A9AB02C588E0EF59CB1BFB4B1CC931B63A3B3A159FCEC97A04D1E6F0C7E6A9CEF6B0ABB04758A69F1FE754DF4C2610E8C46B6CF413BDB31351D55BEDCB7B4A13A1C98E10984475E0F2F957853",
+ "F37326A80E08",
+ "83519E53E321D334F7C10B568183775C0E9AAE55F806"},
+ {"6847E0491BE57E72995D186D50094B0B3593957A5146798FCE68B287B2FB37B5",
+ "3EE1182AEBB19A02B128F28E1D5F7F99",
+ "D9F35ABB16D776CE",
+ "DB7566ED8EA95BDF837F23DB277BAFBC5E70D1105ADFD0D9EF15475051B1EF94709C67DCA9F8D5",
+ "2CDCED0C9EBD6E2A508822A685F7DCD1CDD99E7A5FCA786C234E7F7F1D27EC49751AD5DCFA30C5EDA87C43CAE3B919B6BBCFE34C8EDA59"},
+ {"82B019673642C08388D3E42075A4D5D587558C229E4AB8F660E37650C4C41A0A",
+ "336F5D681E0410FAE7B607246092C6DC",
+ "D430CBD8FE435B64214E9E9CDC5DE99D31CFCFB8C10AA0587A49DF276611",
+ "998404153AD77003E1737EDE93ED79859EE6DCCA93CB40C4363AA817ABF2DBBD46E42A14A7183B6CC01E12A577888141363D0AE011EB6E8D28C0B235",
+ "9BEF69EEB60BD3D6065707B7557F25292A8872857CFBD24F2F3C088E4450995333088DA50FD9121221C504DF1D0CD5EFE6A12666C5D5BB12282CF4C19906E9CFAB97E9BDF7F49DC17CFC384B"},
+ {"747B2E269B1859F0622C15C8BAD6A725028B1F94B8DB7326948D1E6ED663A8BC",
+ "AB91F7245DDCE3F1C747872D47BE0A8A",
+ "3B03F786EF1DDD76E1D42646DA4CD2A5165DC5383CE86D1A0B5F13F910DC278A4E451EE0192CBA178E13B3BA27FDC7840DF73D2E104B",
+ "6B803F4701114F3E5FE21718845F8416F70F626303F545BE197189E0A2BA396F37CE06D389EB2658BC7D56D67868708F6D0D32",
+ "1570DDB0BCE75AA25D1957A287A2C36B1A5F2270186DA81BA6112B7F43B0F3D1D0ED072591DCF1F1C99BBB25621FC39B896FF9BD9413A2845363A9DCD310C32CF98E57"},
+ {"02E59853FB29AEDA0FE1C5F19180AD99A12FF2F144670BB2B8BADF09AD812E0A",
+ "C691294EF67CD04D1B9242AF83DD1421",
+ "879334DAE3",
+ "1E17F46A98FEF5CBB40759D95354",
+ "FED8C3FF27DDF6313AED444A2985B36CBA268AAD6AAC563C0BA28F6DB5DB"},
+ {"F6C1FB9B4188F2288FF03BD716023198C3582CF2A037FC2F29760916C2B7FCDB",
+ "4228DA0678CA3534588859E77DFF014C",
+ "D8153CAF35539A61DD8D05B3C9B44F01E564FB9348BCD09A1C23B84195171308861058F0A3CD2A55B912A3AAEE06FF4D356C77275828F2157C2FC7C115DA39E443210CCC56BEDB0CC99BBFB227ABD5CC454F4E7F547C7378A659EEB6A7E809101A84F866503CB18D4484E1FA09B3EC7FC75EB2E35270800AA7",
+ "23B660A779AD285704B12EC1C580387A47BEC7B00D452C6570",
+ "5AA642BBABA8E49849002A2FAF31DB8FC7773EFDD656E469CEC19B3206D4174C9A263D0A05484261F6"},
+ {"8FF6086F1FADB9A3FBE245EAC52640C43B39D43F89526BB5A6EBA47710931446",
+ "943188480C99437495958B0AE4831AA9",
+ "AD5CD0BDA426F6EBA23C8EB23DC73FF9FEC173355EDBD6C9344C4C4383F211888F7CE6B29899A6801DF6B38651A7C77150941A",
+ "80CD5EA8D7F81DDF5070B934937912E8F541A5301877528EB41AB60C020968D459960ED8FB73083329841A",
+ "ABAE8EB7F36FCA2362551E72DAC890BA1BB6794797E0FC3B67426EC9372726ED4725D379EA0AC9147E48DCD0005C502863C2C5358A38817C8264B5"},
+ {"A083B54E6B1FE01B65D42FCD248F97BB477A41462BBFE6FD591006C022C8FD84",
+ "B0490F5BD68A52459556B3749ACDF40E",
+ "8892E047DA5CFBBDF7F3CFCBD1BD21C6D4C80774B1826999234394BD3E513CC7C222BB40E1E3140A152F19B3802F0D036C24A590512AD0E8",
+ "D7B15752789DC94ED0F36778A5C7BBB207BEC32BAC66E702B39966F06E381E090C6757653C3D26A81EC6AD6C364D66867A334C91BB0B8A8A4B6EACDF0783D09010AEBA2DD2062308FE99CC1F",
+ "C071280A732ADC93DF272BF1E613B2BB7D46FC6665EF2DC1671F3E211D6BDE1D6ADDD28DF3AA2E47053FC8BB8AE9271EC8BC8B2CFFA320D225B451685B6D23ACEFDD241FE284F8ADC8DB07F456985B14330BBB66E0FB212213E05B3E"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
new file mode 100644
index 0000000..affb74a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/internal/byteutil/byteutil.go
@@ -0,0 +1,90 @@
+// Copyright (C) 2019 ProtonTech AG
+// This file contains necessary tools for the aex and ocb packages.
+//
+// These functions SHOULD NOT be used elsewhere, since they are optimized for
+// specific input nature in the EAX and OCB modes of operation.
+
+package byteutil
+
+// GfnDouble computes 2 * input in the field of 2^n elements.
+// The irreducible polynomial in the finite field for n=128 is
+// x^128 + x^7 + x^2 + x + 1 (equals 0x87)
+// Constant-time execution in order to avoid side-channel attacks
+func GfnDouble(input []byte) []byte {
+ if len(input) != 16 {
+ panic("Doubling in GFn only implemented for n = 128")
+ }
+ // If the first bit is zero, return 2L = L << 1
+ // Else return (L << 1) xor 0^120 10000111
+ shifted := ShiftBytesLeft(input)
+ shifted[15] ^= ((input[0] >> 7) * 0x87)
+ return shifted
+}
+
+// ShiftBytesLeft outputs the byte array corresponding to x << 1 in binary.
+func ShiftBytesLeft(x []byte) []byte {
+ l := len(x)
+ dst := make([]byte, l)
+ for i := 0; i < l-1; i++ {
+ dst[i] = (x[i] << 1) | (x[i+1] >> 7)
+ }
+ dst[l-1] = x[l-1] << 1
+ return dst
+}
+
+// ShiftNBytesLeft puts in dst the byte array corresponding to x << n in binary.
+func ShiftNBytesLeft(dst, x []byte, n int) {
+ // Erase first n / 8 bytes
+ copy(dst, x[n/8:])
+
+ // Shift the remaining n % 8 bits
+ bits := uint(n % 8)
+ l := len(dst)
+ for i := 0; i < l-1; i++ {
+ dst[i] = (dst[i] << bits) | (dst[i+1] >> uint(8-bits))
+ }
+ dst[l-1] = dst[l-1] << bits
+
+ // Append trailing zeroes
+ dst = append(dst, make([]byte, n/8)...)
+}
+
+// XorBytesMut assumes equal input length, replaces X with X XOR Y
+func XorBytesMut(X, Y []byte) {
+ for i := 0; i < len(X); i++ {
+ X[i] ^= Y[i]
+ }
+}
+
+// XorBytes assumes equal input length, puts X XOR Y into Z
+func XorBytes(Z, X, Y []byte) {
+ for i := 0; i < len(X); i++ {
+ Z[i] = X[i] ^ Y[i]
+ }
+}
+
+// RightXor XORs smaller input (assumed Y) at the right of the larger input (assumed X)
+func RightXor(X, Y []byte) []byte {
+ offset := len(X) - len(Y)
+ xored := make([]byte, len(X))
+ copy(xored, X)
+ for i := 0; i < len(Y); i++ {
+ xored[offset+i] ^= Y[i]
+ }
+ return xored
+}
+
+// SliceForAppend takes a slice and a requested number of bytes. It returns a
+// slice with the contents of the given slice followed by that many bytes and a
+// second slice that aliases into it and contains only the extra bytes. If the
+// original slice has sufficient capacity then no allocation is performed.
+func SliceForAppend(in []byte, n int) (head, tail []byte) {
+ if total := len(in) + n; cap(in) >= total {
+ head = in[:total]
+ } else {
+ head = make([]byte, total)
+ copy(head, in)
+ }
+ tail = head[len(in):]
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
new file mode 100644
index 0000000..1a6f735
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/ocb.go
@@ -0,0 +1,317 @@
+// Copyright (C) 2019 ProtonTech AG
+
+// Package ocb provides an implementation of the OCB (offset codebook) mode of
+// operation, as described in RFC-7253 of the IRTF and in Rogaway, Bellare,
+// Black and Krovetz - OCB: A BLOCK-CIPHER MODE OF OPERATION FOR EFFICIENT
+// AUTHENTICATED ENCRYPTION (2003).
+// Security considerations (from RFC-7253): A private key MUST NOT be used to
+// encrypt more than 2^48 blocks. Tag length should be at least 12 bytes (a
+// brute-force forging adversary succeeds after 2^{tag length} attempts). A
+// single key SHOULD NOT be used to decrypt ciphertext with different tag
+// lengths. Nonces need not be secret, but MUST NOT be reused.
+// This package only supports underlying block ciphers with 128-bit blocks,
+// such as AES-{128, 192, 256}, but may be extended to other sizes.
+package ocb
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/subtle"
+ "errors"
+ "github.com/ProtonMail/go-crypto/internal/byteutil"
+ "math/bits"
+)
+
+type ocb struct {
+ block cipher.Block
+ tagSize int
+ nonceSize int
+ mask mask
+ // Optimized en/decrypt: For each nonce N used to en/decrypt, the 'Ktop'
+ // internal variable can be reused for en/decrypting with nonces sharing
+ // all but the last 6 bits with N. The prefix of the first nonce used to
+ // compute the new Ktop, and the Ktop value itself, are stored in
+ // reusableKtop. If using incremental nonces, this saves one block cipher
+ // call every 63 out of 64 OCB encryptions, and stores one nonce and one
+ // output of the block cipher in memory only.
+ reusableKtop reusableKtop
+}
+
+type mask struct {
+ // L_*, L_$, (L_i)_{i ∈ N}
+ lAst []byte
+ lDol []byte
+ L [][]byte
+}
+
+type reusableKtop struct {
+ noncePrefix []byte
+ Ktop []byte
+}
+
+const (
+ defaultTagSize = 16
+ defaultNonceSize = 15
+)
+
+const (
+ enc = iota
+ dec
+)
+
+func (o *ocb) NonceSize() int {
+ return o.nonceSize
+}
+
+func (o *ocb) Overhead() int {
+ return o.tagSize
+}
+
+// NewOCB returns an OCB instance with the given block cipher and default
+// tag and nonce sizes.
+func NewOCB(block cipher.Block) (cipher.AEAD, error) {
+ return NewOCBWithNonceAndTagSize(block, defaultNonceSize, defaultTagSize)
+}
+
+// NewOCBWithNonceAndTagSize returns an OCB instance with the given block
+// cipher, nonce length, and tag length. Panics on zero nonceSize and
+// exceedingly long tag size.
+//
+// It is recommended to use at least 12 bytes as tag length.
+func NewOCBWithNonceAndTagSize(
+ block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) {
+ if block.BlockSize() != 16 {
+ return nil, ocbError("Block cipher must have 128-bit blocks")
+ }
+ if nonceSize < 1 {
+ return nil, ocbError("Incorrect nonce length")
+ }
+ if nonceSize >= block.BlockSize() {
+ return nil, ocbError("Nonce length exceeds blocksize - 1")
+ }
+ if tagSize > block.BlockSize() {
+ return nil, ocbError("Custom tag length exceeds blocksize")
+ }
+ return &ocb{
+ block: block,
+ tagSize: tagSize,
+ nonceSize: nonceSize,
+ mask: initializeMaskTable(block),
+ reusableKtop: reusableKtop{
+ noncePrefix: nil,
+ Ktop: nil,
+ },
+ }, nil
+}
+
+func (o *ocb) Seal(dst, nonce, plaintext, adata []byte) []byte {
+ if len(nonce) > o.nonceSize {
+ panic("crypto/ocb: Incorrect nonce length given to OCB")
+ }
+ ret, out := byteutil.SliceForAppend(dst, len(plaintext)+o.tagSize)
+ o.crypt(enc, out, nonce, adata, plaintext)
+ return ret
+}
+
+func (o *ocb) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
+ if len(nonce) > o.nonceSize {
+ panic("Nonce too long for this instance")
+ }
+ if len(ciphertext) < o.tagSize {
+ return nil, ocbError("Ciphertext shorter than tag length")
+ }
+ sep := len(ciphertext) - o.tagSize
+ ret, out := byteutil.SliceForAppend(dst, len(ciphertext))
+ ciphertextData := ciphertext[:sep]
+ tag := ciphertext[sep:]
+ o.crypt(dec, out, nonce, adata, ciphertextData)
+ if subtle.ConstantTimeCompare(ret[sep:], tag) == 1 {
+ ret = ret[:sep]
+ return ret, nil
+ }
+ for i := range out {
+ out[i] = 0
+ }
+ return nil, ocbError("Tag authentication failed")
+}
+
+// On instruction enc (resp. dec), crypt is the encrypt (resp. decrypt)
+// function. It returns the resulting plain/ciphertext with the tag appended.
+func (o *ocb) crypt(instruction int, Y, nonce, adata, X []byte) []byte {
+ //
+ // Consider X as a sequence of 128-bit blocks
+ //
+ // Note: For encryption (resp. decryption), X is the plaintext (resp., the
+ // ciphertext without the tag).
+ blockSize := o.block.BlockSize()
+
+ //
+ // Nonce-dependent and per-encryption variables
+ //
+ // Zero out the last 6 bits of the nonce into truncatedNonce to see if Ktop
+ // is already computed.
+ truncatedNonce := make([]byte, len(nonce))
+ copy(truncatedNonce, nonce)
+ truncatedNonce[len(truncatedNonce)-1] &= 192
+ Ktop := make([]byte, blockSize)
+ if bytes.Equal(truncatedNonce, o.reusableKtop.noncePrefix) {
+ Ktop = o.reusableKtop.Ktop
+ } else {
+ // Nonce = num2str(TAGLEN mod 128, 7) || zeros(120 - bitlen(N)) || 1 || N
+ paddedNonce := append(make([]byte, blockSize-1-len(nonce)), 1)
+ paddedNonce = append(paddedNonce, truncatedNonce...)
+ paddedNonce[0] |= byte(((8 * o.tagSize) % (8 * blockSize)) << 1)
+ // Last 6 bits of paddedNonce are already zero. Encrypt into Ktop
+ paddedNonce[blockSize-1] &= 192
+ Ktop = paddedNonce
+ o.block.Encrypt(Ktop, Ktop)
+ o.reusableKtop.noncePrefix = truncatedNonce
+ o.reusableKtop.Ktop = Ktop
+ }
+
+ // Stretch = Ktop || ((lower half of Ktop) XOR (lower half of Ktop << 8))
+ xorHalves := make([]byte, blockSize/2)
+ byteutil.XorBytes(xorHalves, Ktop[:blockSize/2], Ktop[1:1+blockSize/2])
+ stretch := append(Ktop, xorHalves...)
+ bottom := int(nonce[len(nonce)-1] & 63)
+ offset := make([]byte, len(stretch))
+ byteutil.ShiftNBytesLeft(offset, stretch, bottom)
+ offset = offset[:blockSize]
+
+ //
+ // Process any whole blocks
+ //
+ // Note: For encryption Y is ciphertext || tag, for decryption Y is
+ // plaintext || tag.
+ checksum := make([]byte, blockSize)
+ m := len(X) / blockSize
+ for i := 0; i < m; i++ {
+ index := bits.TrailingZeros(uint(i + 1))
+ if len(o.mask.L)-1 < index {
+ o.mask.extendTable(index)
+ }
+ byteutil.XorBytesMut(offset, o.mask.L[bits.TrailingZeros(uint(i+1))])
+ blockX := X[i*blockSize : (i+1)*blockSize]
+ blockY := Y[i*blockSize : (i+1)*blockSize]
+ byteutil.XorBytes(blockY, blockX, offset)
+ switch instruction {
+ case enc:
+ o.block.Encrypt(blockY, blockY)
+ byteutil.XorBytesMut(blockY, offset)
+ byteutil.XorBytesMut(checksum, blockX)
+ case dec:
+ o.block.Decrypt(blockY, blockY)
+ byteutil.XorBytesMut(blockY, offset)
+ byteutil.XorBytesMut(checksum, blockY)
+ }
+ }
+ //
+ // Process any final partial block and compute raw tag
+ //
+ tag := make([]byte, blockSize)
+ if len(X)%blockSize != 0 {
+ byteutil.XorBytesMut(offset, o.mask.lAst)
+ pad := make([]byte, blockSize)
+ o.block.Encrypt(pad, offset)
+ chunkX := X[blockSize*m:]
+ chunkY := Y[blockSize*m : len(X)]
+ byteutil.XorBytes(chunkY, chunkX, pad[:len(chunkX)])
+ // P_* || bit(1) || zeroes(127) - len(P_*)
+ switch instruction {
+ case enc:
+ paddedY := append(chunkX, byte(128))
+ paddedY = append(paddedY, make([]byte, blockSize-len(chunkX)-1)...)
+ byteutil.XorBytesMut(checksum, paddedY)
+ case dec:
+ paddedX := append(chunkY, byte(128))
+ paddedX = append(paddedX, make([]byte, blockSize-len(chunkY)-1)...)
+ byteutil.XorBytesMut(checksum, paddedX)
+ }
+ byteutil.XorBytes(tag, checksum, offset)
+ byteutil.XorBytesMut(tag, o.mask.lDol)
+ o.block.Encrypt(tag, tag)
+ byteutil.XorBytesMut(tag, o.hash(adata))
+ copy(Y[blockSize*m+len(chunkY):], tag[:o.tagSize])
+ } else {
+ byteutil.XorBytes(tag, checksum, offset)
+ byteutil.XorBytesMut(tag, o.mask.lDol)
+ o.block.Encrypt(tag, tag)
+ byteutil.XorBytesMut(tag, o.hash(adata))
+ copy(Y[blockSize*m:], tag[:o.tagSize])
+ }
+ return Y
+}
+
+// This hash function is used to compute the tag. Per design, on empty input it
+// returns a slice of zeros, of the same length as the underlying block cipher
+// block size.
+func (o *ocb) hash(adata []byte) []byte {
+ //
+ // Consider A as a sequence of 128-bit blocks
+ //
+ A := make([]byte, len(adata))
+ copy(A, adata)
+ blockSize := o.block.BlockSize()
+
+ //
+ // Process any whole blocks
+ //
+ sum := make([]byte, blockSize)
+ offset := make([]byte, blockSize)
+ m := len(A) / blockSize
+ for i := 0; i < m; i++ {
+ chunk := A[blockSize*i : blockSize*(i+1)]
+ index := bits.TrailingZeros(uint(i + 1))
+ // If the mask table is too short
+ if len(o.mask.L)-1 < index {
+ o.mask.extendTable(index)
+ }
+ byteutil.XorBytesMut(offset, o.mask.L[index])
+ byteutil.XorBytesMut(chunk, offset)
+ o.block.Encrypt(chunk, chunk)
+ byteutil.XorBytesMut(sum, chunk)
+ }
+
+ //
+ // Process any final partial block; compute final hash value
+ //
+ if len(A)%blockSize != 0 {
+ byteutil.XorBytesMut(offset, o.mask.lAst)
+ // Pad block with 1 || 0 ^ 127 - bitlength(a)
+ ending := make([]byte, blockSize-len(A)%blockSize)
+ ending[0] = 0x80
+ encrypted := append(A[blockSize*m:], ending...)
+ byteutil.XorBytesMut(encrypted, offset)
+ o.block.Encrypt(encrypted, encrypted)
+ byteutil.XorBytesMut(sum, encrypted)
+ }
+ return sum
+}
+
+func initializeMaskTable(block cipher.Block) mask {
+ //
+ // Key-dependent variables
+ //
+ lAst := make([]byte, block.BlockSize())
+ block.Encrypt(lAst, lAst)
+ lDol := byteutil.GfnDouble(lAst)
+ L := make([][]byte, 1)
+ L[0] = byteutil.GfnDouble(lDol)
+
+ return mask{
+ lAst: lAst,
+ lDol: lDol,
+ L: L,
+ }
+}
+
+// Extends the L array of mask m up to L[limit], with L[i] = GfnDouble(L[i-1])
+func (m *mask) extendTable(limit int) {
+ for i := len(m.L); i <= limit; i++ {
+ m.L = append(m.L, byteutil.GfnDouble(m.L[i-1]))
+ }
+}
+
+func ocbError(err string) error {
+ return errors.New("crypto/ocb: " + err)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go b/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
new file mode 100644
index 0000000..0efaf34
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/random_vectors.go
@@ -0,0 +1,136 @@
+// In the test vectors provided by RFC 7253, the "bottom"
+// internal variable, which defines "offset" for the first time, does not
+// exceed 15. However, it can attain values up to 63.
+
+// These vectors include key length in {128, 192, 256}, tag size 128, and
+// random nonce, header, and plaintext lengths.
+
+// This file was automatically generated.
+
+package ocb
+
+var randomVectors = []struct {
+ key, nonce, header, plaintext, ciphertext string
+}{
+
+ {"9438C5D599308EAF13F800D2D31EA7F0",
+ "C38EE4801BEBFFA1CD8635BE",
+ "0E507B7DADD8A98CDFE272D3CB6B3E8332B56AE583FB049C0874D4200BED16BD1A044182434E9DA0E841F182DFD5B3016B34641CED0784F1745F63AB3D0DA22D3351C9EF9A658B8081E24498EBF61FCE40DA6D8E184536",
+ "962D227786FB8913A8BAD5DC3250",
+ "EEDEF5FFA5986D1E3BF86DDD33EF9ADC79DCA06E215FA772CCBA814F63AD"},
+ {"BA7DE631C7D6712167C6724F5B9A2B1D",
+ "35263EBDA05765DC0E71F1F5",
+ "0103257B4224507C0242FEFE821EA7FA42E0A82863E5F8B68F7D881B4B44FA428A2B6B21D2F591260802D8AB6D83",
+ "9D6D1FC93AE8A64E7889B7B2E3521EFA9B920A8DDB692E6F833DDC4A38AFA535E5E2A3ED82CB7E26404AB86C54D01C4668F28398C2DF33D5D561CBA1C8DCFA7A912F5048E545B59483C0E3221F54B14DAA2E4EB657B3BEF9554F34CAD69B2724AE962D3D8A",
+ "E93852D1985C5E775655E937FA79CE5BF28A585F2AF53A5018853B9634BE3C84499AC0081918FDCE0624494D60E25F76ACD6853AC7576E3C350F332249BFCABD4E73CEABC36BE4EDDA40914E598AE74174A0D7442149B26990899491BDDFE8FC54D6C18E83AE9E9A6FFBF5D376565633862EEAD88D"},
+ {"2E74B25289F6FD3E578C24866E9C72A5",
+ "FD912F15025AF8414642BA1D1D",
+ "FB5FB8C26F365EEDAB5FE260C6E3CCD27806729C8335F146063A7F9EA93290E56CF84576EB446350D22AD730547C267B1F0BBB97EB34E1E2C41A",
+ "6C092EBF78F76EE8C1C6E592277D9545BA16EDB67BC7D8480B9827702DC2F8A129E2B08A2CE710CA7E1DA45CE162BB6CD4B512E632116E2211D3C90871EFB06B8D4B902681C7FB",
+ "6AC0A77F26531BF4F354A1737F99E49BE32ECD909A7A71AD69352906F54B08A9CE9B8CA5D724CBFFC5673437F23F630697F3B84117A1431D6FA8CC13A974FB4AD360300522E09511B99E71065D5AC4BBCB1D791E864EF4"},
+ {"E7EC507C802528F790AFF5303A017B17",
+ "4B97A7A568940A9E3CE7A99E93031E",
+ "28349BDC5A09390C480F9B8AA3EDEA3DDB8B9D64BCA322C570B8225DF0E31190DAB25A4014BA39519E02ABFB12B89AA28BBFD29E486E7FB28734258C817B63CED9912DBAFEBB93E2798AB2890DE3B0ACFCFF906AB15563EF7823CE83D27CDB251195E22BD1337BCBDE65E7C2C427321C463C2777BFE5AEAA",
+ "9455B3EA706B74",
+ "7F33BA3EA848D48A96B9530E26888F43EBD4463C9399B6"},
+ {"6C928AA3224736F28EE7378DE0090191",
+ "8936138E2E4C6A13280017A1622D",
+ "6202717F2631565BDCDC57C6584543E72A7C8BD444D0D108ED35069819633C",
+ "DA0691439E5F035F3E455269D14FE5C201C8C9B0A3FE2D3F86BCC59387C868FE65733D388360B31E3CE28B4BF6A8BE636706B536D5720DB66B47CF1C7A5AFD6F61E0EF90F1726D6B0E169F9A768B2B7AE4EE00A17F630AC905FCAAA1B707FFF25B3A1AAE83B504837C64A5639B2A34002B300EC035C9B43654DA55",
+ "B8804D182AB0F0EEB464FA7BD1329AD6154F982013F3765FEDFE09E26DAC078C9C1439BFC1159D6C02A25E3FF83EF852570117B315852AD5EE20E0FA3AA0A626B0E43BC0CEA38B44579DD36803455FB46989B90E6D229F513FD727AF8372517E9488384C515D6067704119C931299A0982EDDFB9C2E86A90C450C077EB222511EC9CCABC9FCFDB19F70088"},
+ {"ECEA315CA4B3F425B0C9957A17805EA4",
+ "664CDAE18403F4F9BA13015A44FC",
+ "642AFB090D6C6DB46783F08B01A3EF2A8FEB5736B531EAC226E7888FCC8505F396818F83105065FACB3267485B9E5E4A0261F621041C08FCCB2A809A49AB5252A91D0971BCC620B9D614BD77E57A0EED2FA5",
+ "6852C31F8083E20E364CEA21BB7854D67CEE812FE1C9ED2425C0932A90D3780728D1BB",
+ "2ECEF962A9695A463ADABB275BDA9FF8B2BA57AEC2F52EFFB700CD9271A74D2A011C24AEA946051BD6291776429B7E681BA33E"},
+ {"4EE616C4A58AAA380878F71A373461F6",
+ "91B8C9C176D9C385E9C47E52",
+ "CDA440B7F9762C572A718AC754EDEECC119E5EE0CCB9FEA4FFB22EEE75087C032EBF3DA9CDD8A28CC010B99ED45143B41A4BA50EA2A005473F89639237838867A57F23B0F0ED3BF22490E4501DAC9C658A9B9F",
+ "D6E645FA9AE410D15B8123FD757FA356A8DBE9258DDB5BE88832E615910993F497EC",
+ "B70ED7BF959FB2AAED4F36174A2A99BFB16992C8CDF369C782C4DB9C73DE78C5DB8E0615F647243B97ACDB24503BC9CADC48"},
+ {"DCD475773136C830D5E3D0C5FE05B7FF",
+ "BB8E1FBB483BE7616A922C4A",
+ "36FEF2E1CB29E76A6EA663FC3AF66ECD7404F466382F7B040AABED62293302B56E8783EF7EBC21B4A16C3E78A7483A0A403F253A2CDC5BBF79DC3DAE6C73F39A961D8FBBE8D41B",
+ "441E886EA38322B2437ECA7DEB5282518865A66780A454E510878E61BFEC3106A3CD93D2A02052E6F9E1832F9791053E3B76BF4C07EFDD6D4106E3027FABB752E60C1AA425416A87D53938163817A1051EBA1D1DEEB4B9B25C7E97368B52E5911A31810B0EC5AF547559B6142D9F4C4A6EF24A4CF75271BF9D48F62B",
+ "1BE4DD2F4E25A6512C2CC71D24BBB07368589A94C2714962CD0ACE5605688F06342587521E75F0ACAFFD86212FB5C34327D238DB36CF2B787794B9A4412E7CD1410EA5DDD2450C265F29CF96013CD213FD2880657694D718558964BC189B4A84AFCF47EB012935483052399DBA5B088B0A0477F20DFE0E85DCB735E21F22A439FB837DD365A93116D063E607"},
+ {"3FBA2B3D30177FFE15C1C59ED2148BB2C091F5615FBA7C07",
+ "FACF804A4BEBF998505FF9DE",
+ "8213B9263B2971A5BDA18DBD02208EE1",
+ "15B323926993B326EA19F892D704439FC478828322AF72118748284A1FD8A6D814E641F70512FD706980337379F31DC63355974738D7FEA87AD2858C0C2EBBFBE74371C21450072373C7B651B334D7C4D43260B9D7CCD3AF9EDB",
+ "6D35DC1469B26E6AAB26272A41B46916397C24C485B61162E640A062D9275BC33DDCFD3D9E1A53B6C8F51AC89B66A41D59B3574197A40D9B6DCF8A4E2A001409C8112F16B9C389E0096179DB914E05D6D11ED0005AD17E1CE105A2F0BAB8F6B1540DEB968B7A5428FF44"},
+ {"53B52B8D4D748BCDF1DDE68857832FA46227FA6E2F32EFA1",
+ "0B0EF53D4606B28D1398355F",
+ "F23882436349094AF98BCACA8218E81581A043B19009E28EFBF2DE37883E04864148CC01D240552CA8844EC1456F42034653067DA67E80F87105FD06E14FF771246C9612867BE4D215F6D761",
+ "F15030679BD4088D42CAC9BF2E9606EAD4798782FA3ED8C57EBE7F84A53236F51B25967C6489D0CD20C9EEA752F9BC",
+ "67B96E2D67C3729C96DAEAEDF821D61C17E648643A2134C5621FEC621186915AD80864BFD1EB5B238BF526A679385E012A457F583AFA78134242E9D9C1B4E4"},
+ {"0272DD80F23399F49BFC320381A5CD8225867245A49A7D41",
+ "5C83F4896D0738E1366B1836",
+ "69B0337289B19F73A12BAEEA857CCAF396C11113715D9500CCCF48BA08CFF12BC8B4BADB3084E63B85719DB5058FA7C2C11DEB096D7943CFA7CAF5",
+ "C01AD10FC8B562CD17C7BC2FAB3E26CBDFF8D7F4DEA816794BBCC12336991712972F52816AABAB244EB43B0137E2BAC1DD413CE79531E78BEF782E6B439612BB3AEF154DE3502784F287958EBC159419F9EBA27916A28D6307324129F506B1DE80C1755A929F87",
+ "FEFE52DD7159C8DD6E8EC2D3D3C0F37AB6CB471A75A071D17EC4ACDD8F3AA4D7D4F7BB559F3C09099E3D9003E5E8AA1F556B79CECDE66F85B08FA5955E6976BF2695EA076388A62D2AD5BAB7CBF1A7F3F4C8D5CDF37CDE99BD3E30B685D9E5EEE48C7C89118EF4878EB89747F28271FA2CC45F8E9E7601"},
+ {"3EEAED04A455D6E5E5AB53CFD5AFD2F2BC625C7BF4BE49A5",
+ "36B88F63ADBB5668588181D774",
+ "D367E3CB3703E762D23C6533188EF7028EFF9D935A3977150361997EC9DEAF1E4794BDE26AA8B53C124980B1362EC86FCDDFC7A90073171C1BAEE351A53234B86C66E8AB92FAE99EC6967A6D3428892D80",
+ "573454C719A9A55E04437BF7CBAAF27563CCCD92ADD5E515CD63305DFF0687E5EEF790C5DCA5C0033E9AB129505E2775438D92B38F08F3B0356BA142C6F694",
+ "E9F79A5B432D9E682C9AAA5661CFC2E49A0FCB81A431E54B42EB73DD3BED3F377FEC556ABA81624BA64A5D739AD41467460088F8D4F442180A9382CA635745473794C382FCDDC49BA4EB6D8A44AE3C"},
+ {"B695C691538F8CBD60F039D0E28894E3693CC7C36D92D79D",
+ "BC099AEB637361BAC536B57618",
+ "BFFF1A65AE38D1DC142C71637319F5F6508E2CB33C9DCB94202B359ED5A5ED8042E7F4F09231D32A7242976677E6F4C549BF65FADC99E5AF43F7A46FD95E16C2",
+ "081DF3FD85B415D803F0BE5AC58CFF0023FDDED99788296C3731D8",
+ "E50C64E3614D94FE69C47092E46ACC9957C6FEA2CCBF96BC62FBABE7424753C75F9C147C42AE26FE171531"},
+ {"C9ACBD2718F0689A1BE9802A551B6B8D9CF5614DAF5E65ED",
+ "B1B0AAF373B8B026EB80422051D8",
+ "6648C0E61AC733C76119D23FB24548D637751387AA2EAE9D80E912B7BD486CAAD9EAF4D7A5FE2B54AAD481E8EC94BB4D558000896E2010462B70C9FED1E7273080D1",
+ "189F591F6CB6D59AFEDD14C341741A8F1037DC0DF00FC57CE65C30F49E860255CEA5DC6019380CC0FE8880BC1A9E685F41C239C38F36E3F2A1388865C5C311059C0A",
+ "922A5E949B61D03BE34AB5F4E58607D4504EA14017BB363DAE3C873059EA7A1C77A746FB78981671D26C2CF6D9F24952D510044CE02A10177E9DB42D0145211DFE6E84369C5E3BC2669EAB4147B2822895F9"},
+ {"7A832BD2CF5BF4919F353CE2A8C86A5E406DA2D52BE16A72",
+ "2F2F17CECF7E5A756D10785A3CB9DB",
+ "61DA05E3788CC2D8405DBA70C7A28E5AF699863C9F72E6C6770126929F5D6FA267F005EBCF49495CB46400958A3AE80D1289D1C671",
+ "44E91121195A41AF14E8CFDBD39A4B517BE0DF1A72977ED8A3EEF8EEDA1166B2EB6DB2C4AE2E74FA0F0C74537F659BFBD141E5DDEC67E64EDA85AABD3F52C85A785B9FB3CECD70E7DF",
+ "BEDF596EA21288D2B84901E188F6EE1468B14D5161D3802DBFE00D60203A24E2AB62714BF272A45551489838C3A7FEAADC177B591836E73684867CCF4E12901DCF2064058726BBA554E84ADC5136F507E961188D4AF06943D3"},
+ {"1508E8AE9079AA15F1CEC4F776B4D11BCCB061B58AA56C18",
+ "BCA625674F41D1E3AB47672DC0C3",
+ "8B12CF84F16360F0EAD2A41BC021530FFCEC7F3579CAE658E10E2D3D81870F65AFCED0C77C6C4C6E6BA424FF23088C796BA6195ABA35094BF1829E089662E7A95FC90750AE16D0C8AFA55DAC789D7735B970B58D4BE7CEC7341DA82A0179A01929C27A59C5063215B859EA43",
+ "E525422519ECE070E82C",
+ "B47BC07C3ED1C0A43BA52C43CBACBCDBB29CAF1001E09FDF7107"},
+ {"7550C2761644E911FE9ADD119BAC07376BEA442845FEAD876D7E7AC1B713E464",
+ "36D2EC25ADD33CDEDF495205BBC923",
+ "7FCFE81A3790DE97FFC3DE160C470847EA7E841177C2F759571CBD837EA004A6CA8C6F4AEBFF2E9FD552D73EB8A30705D58D70C0B67AEEA280CBBF0A477358ACEF1E7508F2735CD9A0E4F9AC92B8C008F575D3B6278F1C18BD01227E3502E5255F3AB1893632AD00C717C588EF652A51A43209E7EE90",
+ "2B1A62F8FDFAA3C16470A21AD307C9A7D03ADE8EF72C69B06F8D738CDE578D7AEFD0D40BD9C022FB9F580DF5394C998ACCCEFC5471A3996FB8F1045A81FDC6F32D13502EA65A211390C8D882B8E0BEFD8DD8CBEF51D1597B124E9F7F",
+ "C873E02A22DB89EB0787DB6A60B99F7E4A0A085D5C4232A81ADCE2D60AA36F92DDC33F93DD8640AC0E08416B187FB382B3EC3EE85A64B0E6EE41C1366A5AD2A282F66605E87031CCBA2FA7B2DA201D975994AADE3DD1EE122AE09604AD489B84BF0C1AB7129EE16C6934850E"},
+ {"A51300285E554FDBDE7F771A9A9A80955639DD87129FAEF74987C91FB9687C71",
+ "81691D5D20EC818FCFF24B33DECC",
+ "C948093218AA9EB2A8E44A87EEA73FC8B6B75A196819A14BD83709EA323E8DF8B491045220E1D88729A38DBCFFB60D3056DAD4564498FD6574F74512945DEB34B69329ACED9FFC05D5D59DFCD5B973E2ACAFE6AD1EF8BBBC49351A2DD12508ED89ED",
+ "EB861165DAF7625F827C6B574ED703F03215",
+ "C6CD1CE76D2B3679C1B5AA1CFD67CCB55444B6BFD3E22C81CBC9BB738796B83E54E3"},
+ {"8CE0156D26FAEB7E0B9B800BBB2E9D4075B5EAC5C62358B0E7F6FCE610223282",
+ "D2A7B94DD12CDACA909D3AD7",
+ "E021A78F374FC271389AB9A3E97077D755",
+ "7C26000B58929F5095E1CEE154F76C2A299248E299F9B5ADE6C403AA1FD4A67FD4E0232F214CE7B919EE7A1027D2B76C57475715CD078461",
+ "C556FB38DF069B56F337B5FF5775CE6EAA16824DFA754F20B78819028EA635C3BB7AA731DE8776B2DCB67DCA2D33EEDF3C7E52EA450013722A41755A0752433ED17BDD5991AAE77A"},
+ {"1E8000A2CE00A561C9920A30BF0D7B983FEF8A1014C8F04C35CA6970E6BA02BD",
+ "65ED3D63F79F90BBFD19775E",
+ "336A8C0B7243582A46B221AA677647FCAE91",
+ "134A8B34824A290E7B",
+ "914FBEF80D0E6E17F8BDBB6097EBF5FBB0554952DC2B9E5151"},
+ {"53D5607BBE690B6E8D8F6D97F3DF2BA853B682597A214B8AA0EA6E598650AF15",
+ "C391A856B9FE234E14BA1AC7BB40FF",
+ "479682BC21349C4BE1641D5E78FE2C79EC1B9CF5470936DCAD9967A4DCD7C4EFADA593BC9EDE71E6A08829B8580901B61E274227E9D918502DE3",
+ "EAD154DC09C5E26C5D26FF33ED148B27120C7F2C23225CC0D0631B03E1F6C6D96FEB88C1A4052ACB4CE746B884B6502931F407021126C6AAB8C514C077A5A38438AE88EE",
+ "938821286EBB671D999B87C032E1D6055392EB564E57970D55E545FC5E8BAB90E6E3E3C0913F6320995FC636D72CD9919657CC38BD51552F4A502D8D1FE56DB33EBAC5092630E69EBB986F0E15CEE9FC8C052501"},
+ {"294362FCC984F440CEA3E9F7D2C06AF20C53AAC1B3738CA2186C914A6E193ABB",
+ "B15B61C8BB39261A8F55AB178EC3",
+ "D0729B6B75BB",
+ "2BD089ADCE9F334BAE3B065996C7D616DD0C27DF4218DCEEA0FBCA0F968837CE26B0876083327E25681FDDD620A32EC0DA12F73FAE826CC94BFF2B90A54D2651",
+ "AC94B25E4E21DE2437B806966CCD5D9385EF0CD4A51AB9FA6DE675C7B8952D67802E9FEC1FDE9F5D1EAB06057498BC0EEA454804FC9D2068982A3E24182D9AC2E7AB9994DDC899A604264583F63D066B"},
+ {"959DBFEB039B1A5B8CE6A44649B602AAA5F98A906DB96143D202CD2024F749D9",
+ "01D7BDB1133E9C347486C1EFA6",
+ "F3843955BD741F379DD750585EDC55E2CDA05CCBA8C1F4622AC2FE35214BC3A019B8BD12C4CC42D9213D1E1556941E8D8450830287FFB3B763A13722DD4140ED9846FB5FFF745D7B0B967D810A068222E10B259AF1D392035B0D83DC1498A6830B11B2418A840212599171E0258A1C203B05362978",
+ "A21811232C950FA8B12237C2EBD6A7CD2C3A155905E9E0C7C120",
+ "63C1CE397B22F1A03F1FA549B43178BC405B152D3C95E977426D519B3DFCA28498823240592B6EEE7A14"},
+ {"096AE499F5294173F34FF2B375F0E5D5AB79D0D03B33B1A74D7D576826345DF4",
+ "0C52B3D11D636E5910A4DD76D32C",
+ "229E9ECA3053789E937447BC719467075B6138A142DA528DA8F0CF8DDF022FD9AF8E74779BA3AC306609",
+ "8B7A00038783E8BAF6EDEAE0C4EAB48FC8FD501A588C7E4A4DB71E3604F2155A97687D3D2FFF8569261375A513CF4398CE0F87CA1658A1050F6EF6C4EA3E25",
+ "C20B6CF8D3C8241825FD90B2EDAC7593600646E579A8D8DAAE9E2E40C3835FE801B2BE4379131452BC5182C90307B176DFBE2049544222FE7783147B690774F6D9D7CEF52A91E61E298E9AA15464AC"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
new file mode 100644
index 0000000..330309f
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_a.go
@@ -0,0 +1,78 @@
+package ocb
+
+import (
+ "encoding/hex"
+)
+
+// Test vectors from https://tools.ietf.org/html/rfc7253. Note that key is
+// shared across tests.
+var testKey, _ = hex.DecodeString("000102030405060708090A0B0C0D0E0F")
+
+var rfc7253testVectors = []struct {
+ nonce, header, plaintext, ciphertext string
+}{
+ {"BBAA99887766554433221100",
+ "",
+ "",
+ "785407BFFFC8AD9EDCC5520AC9111EE6"},
+ {"BBAA99887766554433221101",
+ "0001020304050607",
+ "0001020304050607",
+ "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"},
+ {"BBAA99887766554433221102",
+ "0001020304050607",
+ "",
+ "81017F8203F081277152FADE694A0A00"},
+ {"BBAA99887766554433221103",
+ "",
+ "0001020304050607",
+ "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"},
+ {"BBAA99887766554433221104",
+ "000102030405060708090A0B0C0D0E0F",
+ "000102030405060708090A0B0C0D0E0F",
+ "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5701C1CCEC8FC3358"},
+ {"BBAA99887766554433221105",
+ "000102030405060708090A0B0C0D0E0F",
+ "",
+ "8CF761B6902EF764462AD86498CA6B97"},
+ {"BBAA99887766554433221106",
+ "",
+ "000102030405060708090A0B0C0D0E0F",
+ "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436BDF06D8FA1ECA343D"},
+ {"BBAA99887766554433221107",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "1CA2207308C87C010756104D8840CE1952F09673A448A122C92C62241051F57356D7F3C90BB0E07F"},
+ {"BBAA99887766554433221108",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "",
+ "6DC225A071FC1B9F7C69F93B0F1E10DE"},
+ {"BBAA99887766554433221109",
+ "",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3CE725F32494B9F914D85C0B1EB38357FF"},
+ {"BBAA9988776655443322110A",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DEAFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"},
+ {"BBAA9988776655443322110B",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "",
+ "FE80690BEE8A485D11F32965BC9D2A32"},
+ {"BBAA9988776655443322110C",
+ "",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF46040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"},
+ {"BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "D5CA91748410C1751FF8A2F618255B68A0A12E093FF454606E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483A7035490C5769E60"},
+ {"BBAA9988776655443322110E",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "",
+ "C5CD9D1850C141E358649994EE701B68"},
+ {"BBAA9988776655443322110F",
+ "",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95A98CA5F3000B1479"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
new file mode 100644
index 0000000..14a3c33
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/ocb/rfc7253_test_vectors_suite_b.go
@@ -0,0 +1,25 @@
+package ocb
+
+// Second set of test vectors from https://tools.ietf.org/html/rfc7253
+var rfc7253TestVectorTaglen96 = struct {
+ key, nonce, header, plaintext, ciphertext string
+}{"0F0E0D0C0B0A09080706050403020100",
+ "BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627",
+ "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA"}
+
+var rfc7253AlgorithmTest = []struct {
+ KEYLEN, TAGLEN int
+ OUTPUT string
+}{
+ {128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"},
+ {192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"},
+ {256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"},
+ {128, 96, "77A3D8E73589158D25D01209"},
+ {192, 96, "05D56EAD2752C86BE6932C5E"},
+ {256, 96, "5458359AC23B0CBA9E6330DD"},
+ {128, 64, "192C9B7BD90BA06A"},
+ {192, 64, "0066BC6E0EF34E24"},
+ {256, 64, "7D4EA5D445501CBE"},
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
new file mode 100644
index 0000000..3c6251d
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/aes/keywrap/keywrap.go
@@ -0,0 +1,153 @@
+// Copyright 2014 Matthew Endsley
+// All rights reserved
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted providing that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+// Package keywrap is an implementation of the RFC 3394 AES key wrapping
+// algorithm. This is used in OpenPGP with elliptic curve keys.
+package keywrap
+
+import (
+ "crypto/aes"
+ "encoding/binary"
+ "errors"
+)
+
+var (
+ // ErrWrapPlaintext is returned if the plaintext is not a multiple
+ // of 64 bits.
+ ErrWrapPlaintext = errors.New("keywrap: plainText must be a multiple of 64 bits")
+
+ // ErrUnwrapCiphertext is returned if the ciphertext is not a
+ // multiple of 64 bits.
+ ErrUnwrapCiphertext = errors.New("keywrap: cipherText must by a multiple of 64 bits")
+
+ // ErrUnwrapFailed is returned if unwrapping a key fails.
+ ErrUnwrapFailed = errors.New("keywrap: failed to unwrap key")
+
+ // NB: the AES NewCipher call only fails if the key is an invalid length.
+
+ // ErrInvalidKey is returned when the AES key is invalid.
+ ErrInvalidKey = errors.New("keywrap: invalid AES key")
+)
+
+// Wrap a key using the RFC 3394 AES Key Wrap Algorithm.
+func Wrap(key, plainText []byte) ([]byte, error) {
+ if len(plainText)%8 != 0 {
+ return nil, ErrWrapPlaintext
+ }
+
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, ErrInvalidKey
+ }
+
+ nblocks := len(plainText) / 8
+
+ // 1) Initialize variables.
+ var block [aes.BlockSize]byte
+ // - Set A = IV, an initial value (see 2.2.3)
+ for ii := 0; ii < 8; ii++ {
+ block[ii] = 0xA6
+ }
+
+ // - For i = 1 to n
+ // - Set R[i] = P[i]
+ intermediate := make([]byte, len(plainText))
+ copy(intermediate, plainText)
+
+ // 2) Calculate intermediate values.
+ for ii := 0; ii < 6; ii++ {
+ for jj := 0; jj < nblocks; jj++ {
+ // - B = AES(K, A | R[i])
+ copy(block[8:], intermediate[jj*8:jj*8+8])
+ c.Encrypt(block[:], block[:])
+
+ // - A = MSB(64, B) ^ t where t = (n*j)+1
+ t := uint64(ii*nblocks + jj + 1)
+ val := binary.BigEndian.Uint64(block[:8]) ^ t
+ binary.BigEndian.PutUint64(block[:8], val)
+
+ // - R[i] = LSB(64, B)
+ copy(intermediate[jj*8:jj*8+8], block[8:])
+ }
+ }
+
+ // 3) Output results.
+ // - Set C[0] = A
+ // - For i = 1 to n
+ // - C[i] = R[i]
+ return append(block[:8], intermediate...), nil
+}
+
+// Unwrap a key using the RFC 3394 AES Key Wrap Algorithm.
+func Unwrap(key, cipherText []byte) ([]byte, error) {
+ if len(cipherText)%8 != 0 {
+ return nil, ErrUnwrapCiphertext
+ }
+
+ c, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, ErrInvalidKey
+ }
+
+ nblocks := len(cipherText)/8 - 1
+
+ // 1) Initialize variables.
+ var block [aes.BlockSize]byte
+ // - Set A = C[0]
+ copy(block[:8], cipherText[:8])
+
+ // - For i = 1 to n
+ // - Set R[i] = C[i]
+ intermediate := make([]byte, len(cipherText)-8)
+ copy(intermediate, cipherText[8:])
+
+ // 2) Compute intermediate values.
+ for jj := 5; jj >= 0; jj-- {
+ for ii := nblocks - 1; ii >= 0; ii-- {
+ // - B = AES-1(K, (A ^ t) | R[i]) where t = n*j+1
+ // - A = MSB(64, B)
+ t := uint64(jj*nblocks + ii + 1)
+ val := binary.BigEndian.Uint64(block[:8]) ^ t
+ binary.BigEndian.PutUint64(block[:8], val)
+
+ copy(block[8:], intermediate[ii*8:ii*8+8])
+ c.Decrypt(block[:], block[:])
+
+ // - R[i] = LSB(B, 64)
+ copy(intermediate[ii*8:ii*8+8], block[8:])
+ }
+ }
+
+ // 3) Output results.
+ // - If A is an appropriate initial value (see 2.2.3),
+ for ii := 0; ii < 8; ii++ {
+ if block[ii] != 0xA6 {
+ return nil, ErrUnwrapFailed
+ }
+ }
+
+ // - For i = 1 to n
+ // - P[i] = R[i]
+ return intermediate, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go
new file mode 100644
index 0000000..d7af914
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go
@@ -0,0 +1,231 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
+// very similar to PEM except that it has an additional CRC checksum.
+package armor // import "github.com/ProtonMail/go-crypto/openpgp/armor"
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/base64"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// A Block represents an OpenPGP armored structure.
+//
+// The encoded form is:
+//
+// -----BEGIN Type-----
+// Headers
+//
+// base64-encoded Bytes
+// '=' base64 encoded checksum
+// -----END Type-----
+//
+// where Headers is a possibly empty sequence of Key: Value lines.
+//
+// Since the armored data can be very large, this package presents a streaming
+// interface.
+type Block struct {
+ Type string // The type, taken from the preamble (i.e. "PGP SIGNATURE").
+ Header map[string]string // Optional headers.
+ Body io.Reader // A Reader from which the contents can be read
+ lReader lineReader
+ oReader openpgpReader
+}
+
+var ArmorCorrupt error = errors.StructuralError("armor invalid")
+
+const crc24Init = 0xb704ce
+const crc24Poly = 0x1864cfb
+const crc24Mask = 0xffffff
+
+// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
+func crc24(crc uint32, d []byte) uint32 {
+ for _, b := range d {
+ crc ^= uint32(b) << 16
+ for i := 0; i < 8; i++ {
+ crc <<= 1
+ if crc&0x1000000 != 0 {
+ crc ^= crc24Poly
+ }
+ }
+ }
+ return crc
+}
+
+var armorStart = []byte("-----BEGIN ")
+var armorEnd = []byte("-----END ")
+var armorEndOfLine = []byte("-----")
+
+// lineReader wraps a line based reader. It watches for the end of an armor
+// block and records the expected CRC value.
+type lineReader struct {
+ in *bufio.Reader
+ buf []byte
+ eof bool
+ crc uint32
+ crcSet bool
+}
+
+func (l *lineReader) Read(p []byte) (n int, err error) {
+ if l.eof {
+ return 0, io.EOF
+ }
+
+ if len(l.buf) > 0 {
+ n = copy(p, l.buf)
+ l.buf = l.buf[n:]
+ return
+ }
+
+ line, isPrefix, err := l.in.ReadLine()
+ if err != nil {
+ return
+ }
+ if isPrefix {
+ return 0, ArmorCorrupt
+ }
+
+ if bytes.HasPrefix(line, armorEnd) {
+ l.eof = true
+ return 0, io.EOF
+ }
+
+ if len(line) == 5 && line[0] == '=' {
+ // This is the checksum line
+ var expectedBytes [3]byte
+ var m int
+ m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:])
+ if m != 3 || err != nil {
+ return
+ }
+ l.crc = uint32(expectedBytes[0])<<16 |
+ uint32(expectedBytes[1])<<8 |
+ uint32(expectedBytes[2])
+
+ line, _, err = l.in.ReadLine()
+ if err != nil && err != io.EOF {
+ return
+ }
+ if !bytes.HasPrefix(line, armorEnd) {
+ return 0, ArmorCorrupt
+ }
+
+ l.eof = true
+ l.crcSet = true
+ return 0, io.EOF
+ }
+
+ if len(line) > 96 {
+ return 0, ArmorCorrupt
+ }
+
+ n = copy(p, line)
+ bytesToSave := len(line) - n
+ if bytesToSave > 0 {
+ if cap(l.buf) < bytesToSave {
+ l.buf = make([]byte, 0, bytesToSave)
+ }
+ l.buf = l.buf[0:bytesToSave]
+ copy(l.buf, line[n:])
+ }
+
+ return
+}
+
+// openpgpReader passes Read calls to the underlying base64 decoder, but keeps
+// a running CRC of the resulting data and checks the CRC against the value
+// found by the lineReader at EOF.
+type openpgpReader struct {
+ lReader *lineReader
+ b64Reader io.Reader
+ currentCRC uint32
+}
+
+func (r *openpgpReader) Read(p []byte) (n int, err error) {
+ n, err = r.b64Reader.Read(p)
+ r.currentCRC = crc24(r.currentCRC, p[:n])
+
+ if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
+ return 0, ArmorCorrupt
+ }
+
+ return
+}
+
+// Decode reads a PGP armored block from the given Reader. It will ignore
+// leading garbage. If it doesn't find a block, it will return nil, io.EOF. The
+// given Reader is not usable after calling this function: an arbitrary amount
+// of data may have been read past the end of the block.
+func Decode(in io.Reader) (p *Block, err error) {
+ r := bufio.NewReaderSize(in, 100)
+ var line []byte
+ ignoreNext := false
+
+TryNextBlock:
+ p = nil
+
+ // Skip leading garbage
+ for {
+ ignoreThis := ignoreNext
+ line, ignoreNext, err = r.ReadLine()
+ if err != nil {
+ return
+ }
+ if ignoreNext || ignoreThis {
+ continue
+ }
+ line = bytes.TrimSpace(line)
+ if len(line) > len(armorStart)+len(armorEndOfLine) && bytes.HasPrefix(line, armorStart) {
+ break
+ }
+ }
+
+ p = new(Block)
+ p.Type = string(line[len(armorStart) : len(line)-len(armorEndOfLine)])
+ p.Header = make(map[string]string)
+ nextIsContinuation := false
+ var lastKey string
+
+ // Read headers
+ for {
+ isContinuation := nextIsContinuation
+ line, nextIsContinuation, err = r.ReadLine()
+ if err != nil {
+ p = nil
+ return
+ }
+ if isContinuation {
+ p.Header[lastKey] += string(line)
+ continue
+ }
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 {
+ break
+ }
+
+ i := bytes.Index(line, []byte(":"))
+ if i == -1 {
+ goto TryNextBlock
+ }
+ lastKey = string(line[:i])
+ var value string
+ if len(line) > i+2 {
+ value = string(line[i+2:])
+ }
+ p.Header[lastKey] = value
+ }
+
+ p.lReader.in = r
+ p.oReader.currentCRC = crc24Init
+ p.oReader.lReader = &p.lReader
+ p.oReader.b64Reader = base64.NewDecoder(base64.StdEncoding, &p.lReader)
+ p.Body = &p.oReader
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go
new file mode 100644
index 0000000..5b6e16c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/encode.go
@@ -0,0 +1,161 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package armor
+
+import (
+ "encoding/base64"
+ "io"
+)
+
+var armorHeaderSep = []byte(": ")
+var blockEnd = []byte("\n=")
+var newline = []byte("\n")
+var armorEndOfLineOut = []byte("-----\n")
+
+// writeSlices writes its arguments to the given Writer.
+func writeSlices(out io.Writer, slices ...[]byte) (err error) {
+ for _, s := range slices {
+ _, err = out.Write(s)
+ if err != nil {
+ return err
+ }
+ }
+ return
+}
+
+// lineBreaker breaks data across several lines, all of the same byte length
+// (except possibly the last). Lines are broken with a single '\n'.
+type lineBreaker struct {
+ lineLength int
+ line []byte
+ used int
+ out io.Writer
+ haveWritten bool
+}
+
+func newLineBreaker(out io.Writer, lineLength int) *lineBreaker {
+ return &lineBreaker{
+ lineLength: lineLength,
+ line: make([]byte, lineLength),
+ used: 0,
+ out: out,
+ }
+}
+
+func (l *lineBreaker) Write(b []byte) (n int, err error) {
+ n = len(b)
+
+ if n == 0 {
+ return
+ }
+
+ if l.used == 0 && l.haveWritten {
+ _, err = l.out.Write([]byte{'\n'})
+ if err != nil {
+ return
+ }
+ }
+
+ if l.used+len(b) < l.lineLength {
+ l.used += copy(l.line[l.used:], b)
+ return
+ }
+
+ l.haveWritten = true
+ _, err = l.out.Write(l.line[0:l.used])
+ if err != nil {
+ return
+ }
+ excess := l.lineLength - l.used
+ l.used = 0
+
+ _, err = l.out.Write(b[0:excess])
+ if err != nil {
+ return
+ }
+
+ _, err = l.Write(b[excess:])
+ return
+}
+
+func (l *lineBreaker) Close() (err error) {
+ if l.used > 0 {
+ _, err = l.out.Write(l.line[0:l.used])
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// encoding keeps track of a running CRC24 over the data which has been written
+// to it and outputs a OpenPGP checksum when closed, followed by an armor
+// trailer.
+//
+// It's built into a stack of io.Writers:
+//
+// encoding -> base64 encoder -> lineBreaker -> out
+type encoding struct {
+ out io.Writer
+ breaker *lineBreaker
+ b64 io.WriteCloser
+ crc uint32
+ blockType []byte
+}
+
+func (e *encoding) Write(data []byte) (n int, err error) {
+ e.crc = crc24(e.crc, data)
+ return e.b64.Write(data)
+}
+
+func (e *encoding) Close() (err error) {
+ err = e.b64.Close()
+ if err != nil {
+ return
+ }
+ e.breaker.Close()
+
+ var checksumBytes [3]byte
+ checksumBytes[0] = byte(e.crc >> 16)
+ checksumBytes[1] = byte(e.crc >> 8)
+ checksumBytes[2] = byte(e.crc)
+
+ var b64ChecksumBytes [4]byte
+ base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:])
+
+ return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine)
+}
+
+// Encode returns a WriteCloser which will encode the data written to it in
+// OpenPGP armor.
+func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) {
+ bType := []byte(blockType)
+ err = writeSlices(out, armorStart, bType, armorEndOfLineOut)
+ if err != nil {
+ return
+ }
+
+ for k, v := range headers {
+ err = writeSlices(out, []byte(k), armorHeaderSep, []byte(v), newline)
+ if err != nil {
+ return
+ }
+ }
+
+ _, err = out.Write(newline)
+ if err != nil {
+ return
+ }
+
+ e := &encoding{
+ out: out,
+ breaker: newLineBreaker(out, 64),
+ crc: crc24Init,
+ blockType: bType,
+ }
+ e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker)
+ return e, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go
new file mode 100644
index 0000000..a94f615
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/canonical_text.go
@@ -0,0 +1,65 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "hash"
+ "io"
+)
+
+// NewCanonicalTextHash reformats text written to it into the canonical
+// form and then applies the hash h. See RFC 4880, section 5.2.1.
+func NewCanonicalTextHash(h hash.Hash) hash.Hash {
+ return &canonicalTextHash{h, 0}
+}
+
+type canonicalTextHash struct {
+ h hash.Hash
+ s int
+}
+
+var newline = []byte{'\r', '\n'}
+
+func writeCanonical(cw io.Writer, buf []byte, s *int) (int, error) {
+ start := 0
+ for i, c := range buf {
+ switch *s {
+ case 0:
+ if c == '\r' {
+ *s = 1
+ } else if c == '\n' {
+ cw.Write(buf[start:i])
+ cw.Write(newline)
+ start = i + 1
+ }
+ case 1:
+ *s = 0
+ }
+ }
+
+ cw.Write(buf[start:])
+ return len(buf), nil
+}
+
+func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
+ return writeCanonical(cth.h, buf, &cth.s)
+}
+
+func (cth *canonicalTextHash) Sum(in []byte) []byte {
+ return cth.h.Sum(in)
+}
+
+func (cth *canonicalTextHash) Reset() {
+ cth.h.Reset()
+ cth.s = 0
+}
+
+func (cth *canonicalTextHash) Size() int {
+ return cth.h.Size()
+}
+
+func (cth *canonicalTextHash) BlockSize() int {
+ return cth.h.BlockSize()
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go
new file mode 100644
index 0000000..c895bad
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdh/ecdh.go
@@ -0,0 +1,210 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ecdh implements ECDH encryption, suitable for OpenPGP,
+// as specified in RFC 6637, section 8.
+package ecdh
+
+import (
+ "bytes"
+ "errors"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+)
+
+type KDF struct {
+ Hash algorithm.Hash
+ Cipher algorithm.Cipher
+}
+
+type PublicKey struct {
+ curve ecc.ECDHCurve
+ Point []byte
+ KDF
+}
+
+type PrivateKey struct {
+ PublicKey
+ D []byte
+}
+
+func NewPublicKey(curve ecc.ECDHCurve, kdfHash algorithm.Hash, kdfCipher algorithm.Cipher) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ KDF: KDF{
+ Hash: kdfHash,
+ Cipher: kdfCipher,
+ },
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.ECDHCurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalBytePoint(pk.Point)
+}
+
+func (pk *PublicKey) UnmarshalPoint(p []byte) error {
+ pk.Point = pk.curve.UnmarshalBytePoint(p)
+ if pk.Point == nil {
+ return errors.New("ecdh: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalByteSecret() []byte {
+ return sk.curve.MarshalByteSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalByteSecret(d)
+
+ if sk.D == nil {
+ return errors.New("ecdh: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.ECDHCurve, kdf KDF) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.KDF = kdf
+ priv.PublicKey.Point, priv.D, err = c.GenerateECDH(rand)
+ return
+}
+
+func Encrypt(random io.Reader, pub *PublicKey, msg, curveOID, fingerprint []byte) (vsG, c []byte, err error) {
+ if len(msg) > 40 {
+ return nil, nil, errors.New("ecdh: message too long")
+ }
+ // the sender MAY use 21, 13, and 5 bytes of padding for AES-128,
+ // AES-192, and AES-256, respectively, to provide the same number of
+ // octets, 40 total, as an input to the key wrapping method.
+ padding := make([]byte, 40-len(msg))
+ for i := range padding {
+ padding[i] = byte(40 - len(msg))
+ }
+ m := append(msg, padding...)
+
+ ephemeral, zb, err := pub.curve.Encaps(random, pub.Point)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ vsG = pub.curve.MarshalBytePoint(ephemeral)
+
+ z, err := buildKey(pub, zb, curveOID, fingerprint, false, false)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if c, err = keywrap.Wrap(z, m); err != nil {
+ return nil, nil, err
+ }
+
+ return vsG, c, nil
+
+}
+
+func Decrypt(priv *PrivateKey, vsG, c, curveOID, fingerprint []byte) (msg []byte, err error) {
+ var m []byte
+ zb, err := priv.PublicKey.curve.Decaps(priv.curve.UnmarshalBytePoint(vsG), priv.D)
+
+ // Try buildKey three times to workaround an old bug, see comments in buildKey.
+ for i := 0; i < 3; i++ {
+ var z []byte
+ // RFC6637 §8: "Compute Z = KDF( S, Z_len, Param );"
+ z, err = buildKey(&priv.PublicKey, zb, curveOID, fingerprint, i == 1, i == 2)
+ if err != nil {
+ return nil, err
+ }
+
+ // RFC6637 §8: "Compute C = AESKeyWrap( Z, c ) as per [RFC3394]"
+ m, err = keywrap.Unwrap(z, c)
+ if err == nil {
+ break
+ }
+ }
+
+ // Only return an error after we've tried all (required) variants of buildKey.
+ if err != nil {
+ return nil, err
+ }
+
+ // RFC6637 §8: "m = symm_alg_ID || session key || checksum || pkcs5_padding"
+ // The last byte should be the length of the padding, as per PKCS5; strip it off.
+ return m[:len(m)-int(m[len(m)-1])], nil
+}
+
+func buildKey(pub *PublicKey, zb []byte, curveOID, fingerprint []byte, stripLeading, stripTrailing bool) ([]byte, error) {
+ // Param = curve_OID_len || curve_OID || public_key_alg_ID || 03
+ // || 01 || KDF_hash_ID || KEK_alg_ID for AESKeyWrap
+ // || "Anonymous Sender " || recipient_fingerprint;
+ param := new(bytes.Buffer)
+ if _, err := param.Write(curveOID); err != nil {
+ return nil, err
+ }
+ algKDF := []byte{18, 3, 1, pub.KDF.Hash.Id(), pub.KDF.Cipher.Id()}
+ if _, err := param.Write(algKDF); err != nil {
+ return nil, err
+ }
+ if _, err := param.Write([]byte("Anonymous Sender ")); err != nil {
+ return nil, err
+ }
+ // For v5 keys, the 20 leftmost octets of the fingerprint are used.
+ if _, err := param.Write(fingerprint[:20]); err != nil {
+ return nil, err
+ }
+ if param.Len()-len(curveOID) != 45 {
+ return nil, errors.New("ecdh: malformed KDF Param")
+ }
+
+ // MB = Hash ( 00 || 00 || 00 || 01 || ZB || Param );
+ h := pub.KDF.Hash.New()
+ if _, err := h.Write([]byte{0x0, 0x0, 0x0, 0x1}); err != nil {
+ return nil, err
+ }
+ zbLen := len(zb)
+ i := 0
+ j := zbLen - 1
+ if stripLeading {
+ // Work around old go crypto bug where the leading zeros are missing.
+ for i < zbLen && zb[i] == 0 {
+ i++
+ }
+ }
+ if stripTrailing {
+ // Work around old OpenPGP.js bug where insignificant trailing zeros in
+ // this little-endian number are missing.
+ // (See https://github.com/openpgpjs/openpgpjs/pull/853.)
+ for j >= 0 && zb[j] == 0 {
+ j--
+ }
+ }
+ if _, err := h.Write(zb[i : j+1]); err != nil {
+ return nil, err
+ }
+ if _, err := h.Write(param.Bytes()); err != nil {
+ return nil, err
+ }
+ mb := h.Sum(nil)
+
+ return mb[:pub.KDF.Cipher.KeySize()], nil // return oBits leftmost bits of MB.
+
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateECDH(priv.Point, priv.D)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go
new file mode 100644
index 0000000..f94ae1b
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/ecdsa/ecdsa.go
@@ -0,0 +1,80 @@
+// Package ecdsa implements ECDSA signature, suitable for OpenPGP,
+// as specified in RFC 6637, section 5.
+package ecdsa
+
+import (
+ "errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "io"
+ "math/big"
+)
+
+type PublicKey struct {
+ X, Y *big.Int
+ curve ecc.ECDSACurve
+}
+
+type PrivateKey struct {
+ PublicKey
+ D *big.Int
+}
+
+func NewPublicKey(curve ecc.ECDSACurve) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.ECDSACurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalIntegerPoint(pk.X, pk.Y)
+}
+
+func (pk *PublicKey) UnmarshalPoint(p []byte) error {
+ pk.X, pk.Y = pk.curve.UnmarshalIntegerPoint(p)
+ if pk.X == nil {
+ return errors.New("ecdsa: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalIntegerSecret() []byte {
+ return sk.curve.MarshalIntegerSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalIntegerSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalIntegerSecret(d)
+
+ if sk.D == nil {
+ return errors.New("ecdsa: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.ECDSACurve) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.X, priv.PublicKey.Y, priv.D, err = c.GenerateECDSA(rand)
+ return
+}
+
+func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+ return priv.PublicKey.curve.Sign(rand, priv.X, priv.Y, priv.D, hash)
+}
+
+func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+ return pub.curve.Verify(pub.X, pub.Y, hash, r, s)
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateECDSA(priv.X, priv.Y, priv.D.Bytes())
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go
new file mode 100644
index 0000000..99ecfc7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/eddsa/eddsa.go
@@ -0,0 +1,91 @@
+// Package eddsa implements EdDSA signature, suitable for OpenPGP, as specified in
+// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+package eddsa
+
+import (
+ "errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "io"
+)
+
+type PublicKey struct {
+ X []byte
+ curve ecc.EdDSACurve
+}
+
+type PrivateKey struct {
+ PublicKey
+ D []byte
+}
+
+func NewPublicKey(curve ecc.EdDSACurve) *PublicKey {
+ return &PublicKey{
+ curve: curve,
+ }
+}
+
+func NewPrivateKey(key PublicKey) *PrivateKey {
+ return &PrivateKey{
+ PublicKey: key,
+ }
+}
+
+func (pk *PublicKey) GetCurve() ecc.EdDSACurve {
+ return pk.curve
+}
+
+func (pk *PublicKey) MarshalPoint() []byte {
+ return pk.curve.MarshalBytePoint(pk.X)
+}
+
+func (pk *PublicKey) UnmarshalPoint(x []byte) error {
+ pk.X = pk.curve.UnmarshalBytePoint(x)
+
+ if pk.X == nil {
+ return errors.New("eddsa: failed to parse EC point")
+ }
+ return nil
+}
+
+func (sk *PrivateKey) MarshalByteSecret() []byte {
+ return sk.curve.MarshalByteSecret(sk.D)
+}
+
+func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
+ sk.D = sk.curve.UnmarshalByteSecret(d)
+
+ if sk.D == nil {
+ return errors.New("eddsa: failed to parse scalar")
+ }
+ return nil
+}
+
+func GenerateKey(rand io.Reader, c ecc.EdDSACurve) (priv *PrivateKey, err error) {
+ priv = new(PrivateKey)
+ priv.PublicKey.curve = c
+ priv.PublicKey.X, priv.D, err = c.GenerateEdDSA(rand)
+ return
+}
+
+func Sign(priv *PrivateKey, message []byte) (r, s []byte, err error) {
+ sig, err := priv.PublicKey.curve.Sign(priv.PublicKey.X, priv.D, message)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ r, s = priv.PublicKey.curve.MarshalSignature(sig)
+ return
+}
+
+func Verify(pub *PublicKey, message, r, s []byte) bool {
+ sig := pub.curve.UnmarshalSignature(r, s)
+ if sig == nil {
+ return false
+ }
+
+ return pub.curve.Verify(pub.X, message, sig)
+}
+
+func Validate(priv *PrivateKey) error {
+ return priv.curve.ValidateEdDSA(priv.PublicKey.X, priv.D)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go
new file mode 100644
index 0000000..bad2774
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/elgamal/elgamal.go
@@ -0,0 +1,124 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package elgamal implements ElGamal encryption, suitable for OpenPGP,
+// as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on
+// Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31,
+// n. 4, 1985, pp. 469-472.
+//
+// This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it
+// unsuitable for other protocols. RSA should be used in preference in any
+// case.
+package elgamal // import "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+
+import (
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "io"
+ "math/big"
+)
+
+// PublicKey represents an ElGamal public key.
+type PublicKey struct {
+ G, P, Y *big.Int
+}
+
+// PrivateKey represents an ElGamal private key.
+type PrivateKey struct {
+ PublicKey
+ X *big.Int
+}
+
+// Encrypt encrypts the given message to the given public key. The result is a
+// pair of integers. Errors can result from reading random, or because msg is
+// too large to be encrypted to the public key.
+func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
+ pLen := (pub.P.BitLen() + 7) / 8
+ if len(msg) > pLen-11 {
+ err = errors.New("elgamal: message too long")
+ return
+ }
+
+ // EM = 0x02 || PS || 0x00 || M
+ em := make([]byte, pLen-1)
+ em[0] = 2
+ ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
+ err = nonZeroRandomBytes(ps, random)
+ if err != nil {
+ return
+ }
+ em[len(em)-len(msg)-1] = 0
+ copy(mm, msg)
+
+ m := new(big.Int).SetBytes(em)
+
+ k, err := rand.Int(random, pub.P)
+ if err != nil {
+ return
+ }
+
+ c1 = new(big.Int).Exp(pub.G, k, pub.P)
+ s := new(big.Int).Exp(pub.Y, k, pub.P)
+ c2 = s.Mul(s, m)
+ c2.Mod(c2, pub.P)
+
+ return
+}
+
+// Decrypt takes two integers, resulting from an ElGamal encryption, and
+// returns the plaintext of the message. An error can result only if the
+// ciphertext is invalid. Users should keep in mind that this is a padding
+// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
+// be used to break the cryptosystem. See “Chosen Ciphertext Attacks
+// Against Protocols Based on the RSA Encryption Standard PKCS #1”, Daniel
+// Bleichenbacher, Advances in Cryptology (Crypto '98),
+func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
+ s := new(big.Int).Exp(c1, priv.X, priv.P)
+ if s.ModInverse(s, priv.P) == nil {
+ return nil, errors.New("elgamal: invalid private key")
+ }
+ s.Mul(s, c2)
+ s.Mod(s, priv.P)
+ em := s.Bytes()
+
+ firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)
+
+ // The remainder of the plaintext must be a string of non-zero random
+ // octets, followed by a 0, followed by the message.
+ // lookingForIndex: 1 iff we are still looking for the zero.
+ // index: the offset of the first zero byte.
+ var lookingForIndex, index int
+ lookingForIndex = 1
+
+ for i := 1; i < len(em); i++ {
+ equals0 := subtle.ConstantTimeByteEq(em[i], 0)
+ index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
+ lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
+ }
+
+ if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
+ return nil, errors.New("elgamal: decryption error")
+ }
+ return em[index+1:], nil
+}
+
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
+func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
+ _, err = io.ReadFull(rand, s)
+ if err != nil {
+ return
+ }
+
+ for i := 0; i < len(s); i++ {
+ for s[i] == 0 {
+ _, err = io.ReadFull(rand, s[i:i+1])
+ if err != nil {
+ return
+ }
+ }
+ }
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
new file mode 100644
index 0000000..17e2bcf
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
@@ -0,0 +1,116 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package errors contains common error types for the OpenPGP packages.
+package errors // import "github.com/ProtonMail/go-crypto/openpgp/errors"
+
+import (
+ "strconv"
+)
+
+// A StructuralError is returned when OpenPGP data is found to be syntactically
+// invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+ return "openpgp: invalid data: " + string(s)
+}
+
+// UnsupportedError indicates that, although the OpenPGP data is valid, it
+// makes use of currently unimplemented features.
+type UnsupportedError string
+
+func (s UnsupportedError) Error() string {
+ return "openpgp: unsupported feature: " + string(s)
+}
+
+// InvalidArgumentError indicates that the caller is in error and passed an
+// incorrect value.
+type InvalidArgumentError string
+
+func (i InvalidArgumentError) Error() string {
+ return "openpgp: invalid argument: " + string(i)
+}
+
+// SignatureError indicates that a syntactically valid signature failed to
+// validate.
+type SignatureError string
+
+func (b SignatureError) Error() string {
+ return "openpgp: invalid signature: " + string(b)
+}
+
+var ErrMDCHashMismatch error = SignatureError("MDC hash mismatch")
+var ErrMDCMissing error = SignatureError("MDC packet not found")
+
+type signatureExpiredError int
+
+func (se signatureExpiredError) Error() string {
+ return "openpgp: signature expired"
+}
+
+var ErrSignatureExpired error = signatureExpiredError(0)
+
+type keyExpiredError int
+
+func (ke keyExpiredError) Error() string {
+ return "openpgp: key expired"
+}
+
+var ErrKeyExpired error = keyExpiredError(0)
+
+type keyIncorrectError int
+
+func (ki keyIncorrectError) Error() string {
+ return "openpgp: incorrect key"
+}
+
+var ErrKeyIncorrect error = keyIncorrectError(0)
+
+// KeyInvalidError indicates that the public key parameters are invalid
+// as they do not match the private ones
+type KeyInvalidError string
+
+func (e KeyInvalidError) Error() string {
+ return "openpgp: invalid key: " + string(e)
+}
+
+type unknownIssuerError int
+
+func (unknownIssuerError) Error() string {
+ return "openpgp: signature made by unknown entity"
+}
+
+var ErrUnknownIssuer error = unknownIssuerError(0)
+
+type keyRevokedError int
+
+func (keyRevokedError) Error() string {
+ return "openpgp: signature made by revoked key"
+}
+
+var ErrKeyRevoked error = keyRevokedError(0)
+
+type UnknownPacketTypeError uint8
+
+func (upte UnknownPacketTypeError) Error() string {
+ return "openpgp: unknown packet type: " + strconv.Itoa(int(upte))
+}
+
+// AEADError indicates that there is a problem when initializing or using a
+// AEAD instance, configuration struct, nonces or index values.
+type AEADError string
+
+func (ae AEADError) Error() string {
+ return "openpgp: aead error: " + string(ae)
+}
+
+// ErrDummyPrivateKey results when operations are attempted on a private key
+// that is just a dummy key. See
+// https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109
+type ErrDummyPrivateKey string
+
+func (dke ErrDummyPrivateKey) Error() string {
+ return "openpgp: s2k GNU dummy key: " + string(dke)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go
new file mode 100644
index 0000000..526bd77
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/hash.go
@@ -0,0 +1,24 @@
+package openpgp
+
+import (
+ "crypto"
+
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id.
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
+ return algorithm.HashIdToHash(id)
+}
+
+// HashIdToString returns the name of the hash function corresponding to the
+// given OpenPGP hash id.
+func HashIdToString(id byte) (name string, ok bool) {
+ return algorithm.HashIdToString(id)
+}
+
+// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
+ return algorithm.HashToHashId(h)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go
new file mode 100644
index 0000000..d067065
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/aead.go
@@ -0,0 +1,65 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package algorithm
+
+import (
+ "crypto/cipher"
+ "github.com/ProtonMail/go-crypto/eax"
+ "github.com/ProtonMail/go-crypto/ocb"
+)
+
+// AEADMode defines the Authenticated Encryption with Associated Data mode of
+// operation.
+type AEADMode uint8
+
+// Supported modes of operation (see RFC4880bis [EAX] and RFC7253)
+const (
+ AEADModeEAX = AEADMode(1)
+ AEADModeOCB = AEADMode(2)
+ AEADModeGCM = AEADMode(3)
+)
+
+// TagLength returns the length in bytes of authentication tags.
+func (mode AEADMode) TagLength() int {
+ switch mode {
+ case AEADModeEAX:
+ return 16
+ case AEADModeOCB:
+ return 16
+ case AEADModeGCM:
+ return 16
+ default:
+ return 0
+ }
+}
+
+// NonceLength returns the length in bytes of nonces.
+func (mode AEADMode) NonceLength() int {
+ switch mode {
+ case AEADModeEAX:
+ return 16
+ case AEADModeOCB:
+ return 15
+ case AEADModeGCM:
+ return 12
+ default:
+ return 0
+ }
+}
+
+// New returns a fresh instance of the given mode
+func (mode AEADMode) New(block cipher.Block) (alg cipher.AEAD) {
+ var err error
+ switch mode {
+ case AEADModeEAX:
+ alg, err = eax.NewEAX(block)
+ case AEADModeOCB:
+ alg, err = ocb.NewOCB(block)
+ case AEADModeGCM:
+ alg, err = cipher.NewGCM(block)
+ }
+ if err != nil {
+ panic(err.Error())
+ }
+ return alg
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go
new file mode 100644
index 0000000..5760cff
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/cipher.go
@@ -0,0 +1,107 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package algorithm
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+
+ "golang.org/x/crypto/cast5"
+)
+
+// Cipher is an official symmetric key cipher algorithm. See RFC 4880,
+// section 9.2.
+type Cipher interface {
+ // Id returns the algorithm ID, as a byte, of the cipher.
+ Id() uint8
+ // KeySize returns the key size, in bytes, of the cipher.
+ KeySize() int
+ // BlockSize returns the block size, in bytes, of the cipher.
+ BlockSize() int
+ // New returns a fresh instance of the given cipher.
+ New(key []byte) cipher.Block
+}
+
+// The following constants mirror the OpenPGP standard (RFC 4880).
+const (
+ TripleDES = CipherFunction(2)
+ CAST5 = CipherFunction(3)
+ AES128 = CipherFunction(7)
+ AES192 = CipherFunction(8)
+ AES256 = CipherFunction(9)
+)
+
+// CipherById represents the different block ciphers specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
+var CipherById = map[uint8]Cipher{
+ TripleDES.Id(): TripleDES,
+ CAST5.Id(): CAST5,
+ AES128.Id(): AES128,
+ AES192.Id(): AES192,
+ AES256.Id(): AES256,
+}
+
+type CipherFunction uint8
+
+// ID returns the algorithm Id, as a byte, of cipher.
+func (sk CipherFunction) Id() uint8 {
+ return uint8(sk)
+}
+
+var keySizeByID = map[uint8]int{
+ TripleDES.Id(): 24,
+ CAST5.Id(): cast5.KeySize,
+ AES128.Id(): 16,
+ AES192.Id(): 24,
+ AES256.Id(): 32,
+}
+
+// KeySize returns the key size, in bytes, of cipher.
+func (cipher CipherFunction) KeySize() int {
+ switch cipher {
+ case TripleDES:
+ return 24
+ case CAST5:
+ return cast5.KeySize
+ case AES128:
+ return 16
+ case AES192:
+ return 24
+ case AES256:
+ return 32
+ }
+ return 0
+}
+
+// BlockSize returns the block size, in bytes, of cipher.
+func (cipher CipherFunction) BlockSize() int {
+ switch cipher {
+ case TripleDES:
+ return des.BlockSize
+ case CAST5:
+ return 8
+ case AES128, AES192, AES256:
+ return 16
+ }
+ return 0
+}
+
+// New returns a fresh instance of the given cipher.
+func (cipher CipherFunction) New(key []byte) (block cipher.Block) {
+ var err error
+ switch cipher {
+ case TripleDES:
+ block, err = des.NewTripleDESCipher(key)
+ case CAST5:
+ block, err = cast5.NewCipher(key)
+ case AES128, AES192, AES256:
+ block, err = aes.NewCipher(key)
+ }
+ if err != nil {
+ panic(err.Error())
+ }
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go
new file mode 100644
index 0000000..d1a00fc
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/algorithm/hash.go
@@ -0,0 +1,143 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package algorithm
+
+import (
+ "crypto"
+ "fmt"
+ "hash"
+)
+
+// Hash is an official hash function algorithm. See RFC 4880, section 9.4.
+type Hash interface {
+ // Id returns the algorithm ID, as a byte, of Hash.
+ Id() uint8
+ // Available reports whether the given hash function is linked into the binary.
+ Available() bool
+ // HashFunc simply returns the value of h so that Hash implements SignerOpts.
+ HashFunc() crypto.Hash
+ // New returns a new hash.Hash calculating the given hash function. New
+ // panics if the hash function is not linked into the binary.
+ New() hash.Hash
+ // Size returns the length, in bytes, of a digest resulting from the given
+ // hash function. It doesn't require that the hash function in question be
+ // linked into the program.
+ Size() int
+ // String is the name of the hash function corresponding to the given
+ // OpenPGP hash id.
+ String() string
+}
+
+// The following vars mirror the crypto/Hash supported hash functions.
+var (
+ SHA1 Hash = cryptoHash{2, crypto.SHA1}
+ SHA256 Hash = cryptoHash{8, crypto.SHA256}
+ SHA384 Hash = cryptoHash{9, crypto.SHA384}
+ SHA512 Hash = cryptoHash{10, crypto.SHA512}
+ SHA224 Hash = cryptoHash{11, crypto.SHA224}
+ SHA3_256 Hash = cryptoHash{12, crypto.SHA3_256}
+ SHA3_512 Hash = cryptoHash{14, crypto.SHA3_512}
+)
+
+// HashById represents the different hash functions specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-14
+var (
+ HashById = map[uint8]Hash{
+ SHA256.Id(): SHA256,
+ SHA384.Id(): SHA384,
+ SHA512.Id(): SHA512,
+ SHA224.Id(): SHA224,
+ SHA3_256.Id(): SHA3_256,
+ SHA3_512.Id(): SHA3_512,
+ }
+)
+
+// cryptoHash contains pairs relating OpenPGP's hash identifier with
+// Go's crypto.Hash type. See RFC 4880, section 9.4.
+type cryptoHash struct {
+ id uint8
+ crypto.Hash
+}
+
+// Id returns the algorithm ID, as a byte, of cryptoHash.
+func (h cryptoHash) Id() uint8 {
+ return h.id
+}
+
+var hashNames = map[uint8]string{
+ SHA256.Id(): "SHA256",
+ SHA384.Id(): "SHA384",
+ SHA512.Id(): "SHA512",
+ SHA224.Id(): "SHA224",
+ SHA3_256.Id(): "SHA3-256",
+ SHA3_512.Id(): "SHA3-512",
+}
+
+func (h cryptoHash) String() string {
+ s, ok := hashNames[h.id]
+ if !ok {
+ panic(fmt.Sprintf("Unsupported hash function %d", h.id))
+ }
+ return s
+}
+
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id.
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.HashFunc(), true
+ }
+ return 0, false
+}
+
+// HashIdToHashWithSha1 returns a crypto.Hash which corresponds to the given OpenPGP
+// hash id, allowing sha1.
+func HashIdToHashWithSha1(id byte) (h crypto.Hash, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.HashFunc(), true
+ }
+
+ if id == SHA1.Id() {
+ return SHA1.HashFunc(), true
+ }
+
+ return 0, false
+}
+
+// HashIdToString returns the name of the hash function corresponding to the
+// given OpenPGP hash id.
+func HashIdToString(id byte) (name string, ok bool) {
+ if hash, ok := HashById[id]; ok {
+ return hash.String(), true
+ }
+ return "", false
+}
+
+// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
+ for id, hash := range HashById {
+ if hash.HashFunc() == h {
+ return id, true
+ }
+ }
+
+ return 0, false
+}
+
+// HashToHashIdWithSha1 returns an OpenPGP hash id which corresponds the given Hash,
+// allowing instances of SHA1
+func HashToHashIdWithSha1(h crypto.Hash) (id byte, ok bool) {
+ for id, hash := range HashById {
+ if hash.HashFunc() == h {
+ return id, true
+ }
+ }
+
+ if h == SHA1.HashFunc() {
+ return SHA1.Id(), true
+ }
+
+ return 0, false
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go
new file mode 100644
index 0000000..888767c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve25519.go
@@ -0,0 +1,171 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ x25519lib "github.com/cloudflare/circl/dh/x25519"
+)
+
+type curve25519 struct{}
+
+func NewCurve25519() *curve25519 {
+ return &curve25519{}
+}
+
+func (c *curve25519) GetCurveName() string {
+ return "curve25519"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *curve25519) MarshalBytePoint(point []byte) []byte {
+ return append([]byte{0x40}, point...)
+}
+
+// UnmarshalBytePoint decodes the public point to native format, removing the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *curve25519) UnmarshalBytePoint(point []byte) []byte {
+ if len(point) != x25519lib.Size+1 {
+ return nil
+ }
+
+ // Remove prefix
+ return point[1:]
+}
+
+// MarshalByteSecret encodes the secret scalar from native format.
+// Note that the EC secret scalar differs from the definition of public keys in
+// [Curve25519] in two ways: (1) the byte-ordering is big-endian, which is
+// more uniform with how big integers are represented in OpenPGP, and (2) the
+// leading zeros are truncated.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.1
+// Note that leading zero bytes are stripped later when encoding as an MPI.
+func (c *curve25519) MarshalByteSecret(secret []byte) []byte {
+ d := make([]byte, x25519lib.Size)
+ copyReversed(d, secret)
+
+ // The following ensures that the private key is a number of the form
+ // 2^{254} + 8 * [0, 2^{251}), in order to avoid the small subgroup of
+ // the curve.
+ //
+ // This masking is done internally in the underlying lib and so is unnecessary
+ // for security, but OpenPGP implementations require that private keys be
+ // pre-masked.
+ d[0] &= 127
+ d[0] |= 64
+ d[31] &= 248
+
+ return d
+}
+
+// UnmarshalByteSecret decodes the secret scalar from native format.
+// Note that the EC secret scalar differs from the definition of public keys in
+// [Curve25519] in two ways: (1) the byte-ordering is big-endian, which is
+// more uniform with how big integers are represented in OpenPGP, and (2) the
+// leading zeros are truncated.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.1
+func (c *curve25519) UnmarshalByteSecret(d []byte) []byte {
+ if len(d) > x25519lib.Size {
+ return nil
+ }
+
+ // Ensure truncated leading bytes are re-added
+ secret := make([]byte, x25519lib.Size)
+ copyReversed(secret, d)
+
+ return secret
+}
+
+// generateKeyPairBytes Generates a private-public key-pair.
+// 'priv' is a private key; a little-endian scalar belonging to the set
+// 2^{254} + 8 * [0, 2^{251}), in order to avoid the small subgroup of the
+// curve. 'pub' is simply 'priv' * G where G is the base point.
+// See https://cr.yp.to/ecdh.html and RFC7748, sec 5.
+func (c *curve25519) generateKeyPairBytes(rand io.Reader) (priv, pub x25519lib.Key, err error) {
+ _, err = io.ReadFull(rand, priv[:])
+ if err != nil {
+ return
+ }
+
+ x25519lib.KeyGen(&pub, &priv)
+ return
+}
+
+func (c *curve25519) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) {
+ priv, pub, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return
+ }
+
+ return pub[:], priv[:], nil
+}
+
+func (c *genericCurve) MaskSecret(secret []byte) []byte {
+ return secret
+}
+
+func (c *curve25519) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ // RFC6637 §8: "Generate an ephemeral key pair {v, V=vG}"
+ // ephemeralPrivate corresponds to `v`.
+ // ephemeralPublic corresponds to `V`.
+ ephemeralPrivate, ephemeralPublic, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // RFC6637 §8: "Obtain the authenticated recipient public key R"
+ // pubKey corresponds to `R`.
+ var pubKey x25519lib.Key
+ copy(pubKey[:], point)
+
+ // RFC6637 §8: "Compute the shared point S = vR"
+ // "VB = convert point V to the octet string"
+ // sharedPoint corresponds to `VB`.
+ var sharedPoint x25519lib.Key
+ x25519lib.Shared(&sharedPoint, &ephemeralPrivate, &pubKey)
+
+ return ephemeralPublic[:], sharedPoint[:], nil
+}
+
+func (c *curve25519) Decaps(vsG, secret []byte) (sharedSecret []byte, err error) {
+ var ephemeralPublic, decodedPrivate, sharedPoint x25519lib.Key
+ // RFC6637 §8: "The decryption is the inverse of the method given."
+ // All quoted descriptions in comments below describe encryption, and
+ // the reverse is performed.
+ // vsG corresponds to `VB` in RFC6637 §8 .
+
+ // RFC6637 §8: "VB = convert point V to the octet string"
+ copy(ephemeralPublic[:], vsG)
+
+ // decodedPrivate corresponds to `r` in RFC6637 §8 .
+ copy(decodedPrivate[:], secret)
+
+ // RFC6637 §8: "Note that the recipient obtains the shared secret by calculating
+ // S = rV = rvG, where (r,R) is the recipient's key pair."
+ // sharedPoint corresponds to `S`.
+ x25519lib.Shared(&sharedPoint, &decodedPrivate, &ephemeralPublic)
+
+ return sharedPoint[:], nil
+}
+
+func (c *curve25519) ValidateECDH(point []byte, secret []byte) (err error) {
+ var pk, sk x25519lib.Key
+ copy(sk[:], secret)
+ x25519lib.KeyGen(&pk, &sk)
+
+ if subtle.ConstantTimeCompare(point, pk[:]) == 0 {
+ return errors.KeyInvalidError("ecc: invalid curve25519 public point")
+ }
+
+ return nil
+}
+
+func copyReversed(out []byte, in []byte) {
+ l := len(in)
+ for i := 0; i < l; i++ {
+ out[i] = in[l-i-1]
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go
new file mode 100644
index 0000000..3575103
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curve_info.go
@@ -0,0 +1,140 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "bytes"
+ "crypto/elliptic"
+ "github.com/ProtonMail/go-crypto/bitcurves"
+ "github.com/ProtonMail/go-crypto/brainpool"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+type CurveInfo struct {
+ GenName string
+ Oid *encoding.OID
+ Curve Curve
+}
+
+var Curves = []CurveInfo{
+ {
+ // NIST P-256
+ GenName: "P256",
+ Oid: encoding.NewOID([]byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}),
+ Curve: NewGenericCurve(elliptic.P256()),
+ },
+ {
+ // NIST P-384
+ GenName: "P384",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x22}),
+ Curve: NewGenericCurve(elliptic.P384()),
+ },
+ {
+ // NIST P-521
+ GenName: "P521",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x23}),
+ Curve: NewGenericCurve(elliptic.P521()),
+ },
+ {
+ // SecP256k1
+ GenName: "SecP256k1",
+ Oid: encoding.NewOID([]byte{0x2B, 0x81, 0x04, 0x00, 0x0A}),
+ Curve: NewGenericCurve(bitcurves.S256()),
+ },
+ {
+ // Curve25519
+ GenName: "Curve25519",
+ Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01}),
+ Curve: NewCurve25519(),
+ },
+ {
+ // X448
+ GenName: "Curve448",
+ Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x6F}),
+ Curve: NewX448(),
+ },
+ {
+ // Ed25519
+ GenName: "Curve25519",
+ Oid: encoding.NewOID([]byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}),
+ Curve: NewEd25519(),
+ },
+ {
+ // Ed448
+ GenName: "Curve448",
+ Oid: encoding.NewOID([]byte{0x2B, 0x65, 0x71}),
+ Curve: NewEd448(),
+ },
+ {
+ // BrainpoolP256r1
+ GenName: "BrainpoolP256",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}),
+ Curve: NewGenericCurve(brainpool.P256r1()),
+ },
+ {
+ // BrainpoolP384r1
+ GenName: "BrainpoolP384",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}),
+ Curve: NewGenericCurve(brainpool.P384r1()),
+ },
+ {
+ // BrainpoolP512r1
+ GenName: "BrainpoolP512",
+ Oid: encoding.NewOID([]byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}),
+ Curve: NewGenericCurve(brainpool.P512r1()),
+ },
+}
+
+func FindByCurve(curve Curve) *CurveInfo {
+ for _, curveInfo := range Curves {
+ if curveInfo.Curve.GetCurveName() == curve.GetCurveName() {
+ return &curveInfo
+ }
+ }
+ return nil
+}
+
+func FindByOid(oid encoding.Field) *CurveInfo {
+ var rawBytes = oid.Bytes()
+ for _, curveInfo := range Curves {
+ if bytes.Equal(curveInfo.Oid.Bytes(), rawBytes) {
+ return &curveInfo
+ }
+ }
+ return nil
+}
+
+func FindEdDSAByGenName(curveGenName string) EdDSACurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(EdDSACurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
+
+func FindECDSAByGenName(curveGenName string) ECDSACurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(ECDSACurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
+
+func FindECDHByGenName(curveGenName string) ECDHCurve {
+ for _, curveInfo := range Curves {
+ if curveInfo.GenName == curveGenName {
+ curve, ok := curveInfo.Curve.(ECDHCurve)
+ if ok {
+ return curve
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go
new file mode 100644
index 0000000..5ed9c93
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/curves.go
@@ -0,0 +1,48 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "io"
+ "math/big"
+)
+
+type Curve interface {
+ GetCurveName() string
+}
+
+type ECDSACurve interface {
+ Curve
+ MarshalIntegerPoint(x, y *big.Int) []byte
+ UnmarshalIntegerPoint([]byte) (x, y *big.Int)
+ MarshalIntegerSecret(d *big.Int) []byte
+ UnmarshalIntegerSecret(d []byte) *big.Int
+ GenerateECDSA(rand io.Reader) (x, y, secret *big.Int, err error)
+ Sign(rand io.Reader, x, y, d *big.Int, hash []byte) (r, s *big.Int, err error)
+ Verify(x, y *big.Int, hash []byte, r, s *big.Int) bool
+ ValidateECDSA(x, y *big.Int, secret []byte) error
+}
+
+type EdDSACurve interface {
+ Curve
+ MarshalBytePoint(x []byte) []byte
+ UnmarshalBytePoint([]byte) (x []byte)
+ MarshalByteSecret(d []byte) []byte
+ UnmarshalByteSecret(d []byte) []byte
+ MarshalSignature(sig []byte) (r, s []byte)
+ UnmarshalSignature(r, s []byte) (sig []byte)
+ GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error)
+ Sign(publicKey, privateKey, message []byte) (sig []byte, err error)
+ Verify(publicKey, message, sig []byte) bool
+ ValidateEdDSA(publicKey, privateKey []byte) (err error)
+}
+type ECDHCurve interface {
+ Curve
+ MarshalBytePoint([]byte) (encoded []byte)
+ UnmarshalBytePoint(encoded []byte) []byte
+ MarshalByteSecret(d []byte) []byte
+ UnmarshalByteSecret(d []byte) []byte
+ GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error)
+ Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error)
+ Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error)
+ ValidateECDH(public []byte, secret []byte) error
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go
new file mode 100644
index 0000000..54a08a8
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed25519.go
@@ -0,0 +1,112 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ ed25519lib "github.com/cloudflare/circl/sign/ed25519"
+)
+
+const ed25519Size = 32
+
+type ed25519 struct{}
+
+func NewEd25519() *ed25519 {
+ return &ed25519{}
+}
+
+func (c *ed25519) GetCurveName() string {
+ return "ed25519"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) MarshalBytePoint(x []byte) []byte {
+ return append([]byte{0x40}, x...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) UnmarshalBytePoint(point []byte) (x []byte) {
+ if len(point) != ed25519lib.PublicKeySize+1 {
+ return nil
+ }
+
+ // Return unprefixed
+ return point[1:]
+}
+
+// MarshalByteSecret encodes a scalar in native format.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) MarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+// UnmarshalByteSecret decodes a scalar in native format and re-adds the stripped leading zeroes
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed25519) UnmarshalByteSecret(s []byte) (d []byte) {
+ if len(s) > ed25519lib.SeedSize {
+ return nil
+ }
+
+ // Handle stripped leading zeroes
+ d = make([]byte, ed25519lib.SeedSize)
+ copy(d[ed25519lib.SeedSize-len(s):], s)
+ return
+}
+
+// MarshalSignature splits a signature in R and S.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.1
+func (c *ed25519) MarshalSignature(sig []byte) (r, s []byte) {
+ return sig[:ed25519Size], sig[ed25519Size:]
+}
+
+// UnmarshalSignature decodes R and S in the native format, re-adding the stripped leading zeroes
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.1
+func (c *ed25519) UnmarshalSignature(r, s []byte) (sig []byte) {
+ // Check size
+ if len(r) > 32 || len(s) > 32 {
+ return nil
+ }
+
+ sig = make([]byte, ed25519lib.SignatureSize)
+
+ // Handle stripped leading zeroes
+ copy(sig[ed25519Size-len(r):ed25519Size], r)
+ copy(sig[ed25519lib.SignatureSize-len(s):], s)
+ return sig
+}
+
+func (c *ed25519) GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error) {
+ pk, sk, err := ed25519lib.GenerateKey(rand)
+
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return pk, sk[:ed25519lib.SeedSize], nil
+}
+
+func getEd25519Sk(publicKey, privateKey []byte) ed25519lib.PrivateKey {
+ return append(privateKey, publicKey...)
+}
+
+func (c *ed25519) Sign(publicKey, privateKey, message []byte) (sig []byte, err error) {
+ sig = ed25519lib.Sign(getEd25519Sk(publicKey, privateKey), message)
+ return sig, nil
+}
+
+func (c *ed25519) Verify(publicKey, message, sig []byte) bool {
+ return ed25519lib.Verify(publicKey, message, sig)
+}
+
+func (c *ed25519) ValidateEdDSA(publicKey, privateKey []byte) (err error) {
+ priv := getEd25519Sk(publicKey, privateKey)
+ expectedPriv := ed25519lib.NewKeyFromSeed(priv.Seed())
+ if subtle.ConstantTimeCompare(priv, expectedPriv) == 0 {
+ return errors.KeyInvalidError("ecc: invalid ed25519 secret")
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go
new file mode 100644
index 0000000..18cd804
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/ed448.go
@@ -0,0 +1,111 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ ed448lib "github.com/cloudflare/circl/sign/ed448"
+)
+
+type ed448 struct{}
+
+func NewEd448() *ed448 {
+ return &ed448{}
+}
+
+func (c *ed448) GetCurveName() string {
+ return "ed448"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) MarshalBytePoint(x []byte) []byte {
+ // Return prefixed
+ return append([]byte{0x40}, x...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) UnmarshalBytePoint(point []byte) (x []byte) {
+ if len(point) != ed448lib.PublicKeySize+1 {
+ return nil
+ }
+
+ // Strip prefix
+ return point[1:]
+}
+
+// MarshalByteSecret encoded a scalar from native format to prefixed.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) MarshalByteSecret(d []byte) []byte {
+ // Return prefixed
+ return append([]byte{0x40}, d...)
+}
+
+// UnmarshalByteSecret decodes a scalar from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.5
+func (c *ed448) UnmarshalByteSecret(s []byte) (d []byte) {
+ // Check prefixed size
+ if len(s) != ed448lib.SeedSize+1 {
+ return nil
+ }
+
+ // Strip prefix
+ return s[1:]
+}
+
+// MarshalSignature splits a signature in R and S, where R is in prefixed native format and
+// S is an MPI with value zero.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.2
+func (c *ed448) MarshalSignature(sig []byte) (r, s []byte) {
+ return append([]byte{0x40}, sig...), []byte{}
+}
+
+// UnmarshalSignature decodes R and S in the native format. Only R is used, in prefixed native format.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.2.3.3.2
+func (c *ed448) UnmarshalSignature(r, s []byte) (sig []byte) {
+ if len(r) != ed448lib.SignatureSize+1 {
+ return nil
+ }
+
+ return r[1:]
+}
+
+func (c *ed448) GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error) {
+ pk, sk, err := ed448lib.GenerateKey(rand)
+
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return pk, sk[:ed448lib.SeedSize], nil
+}
+
+func getEd448Sk(publicKey, privateKey []byte) ed448lib.PrivateKey {
+ return append(privateKey, publicKey...)
+}
+
+func (c *ed448) Sign(publicKey, privateKey, message []byte) (sig []byte, err error) {
+ // Ed448 is used with the empty string as a context string.
+ // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+ sig = ed448lib.Sign(getEd448Sk(publicKey, privateKey), message, "")
+
+ return sig, nil
+}
+
+func (c *ed448) Verify(publicKey, message, sig []byte) bool {
+ // Ed448 is used with the empty string as a context string.
+ // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
+ return ed448lib.Verify(publicKey, message, sig, "")
+}
+
+func (c *ed448) ValidateEdDSA(publicKey, privateKey []byte) (err error) {
+ priv := getEd448Sk(publicKey, privateKey)
+ expectedPriv := ed448lib.NewKeyFromSeed(priv.Seed())
+ if subtle.ConstantTimeCompare(priv, expectedPriv) == 0 {
+ return errors.KeyInvalidError("ecc: invalid ed448 secret")
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go
new file mode 100644
index 0000000..e28d7c7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/generic.go
@@ -0,0 +1,149 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "fmt"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "io"
+ "math/big"
+)
+
+type genericCurve struct {
+ Curve elliptic.Curve
+}
+
+func NewGenericCurve(c elliptic.Curve) *genericCurve {
+ return &genericCurve{
+ Curve: c,
+ }
+}
+
+func (c *genericCurve) GetCurveName() string {
+ return c.Curve.Params().Name
+}
+
+func (c *genericCurve) MarshalBytePoint(point []byte) []byte {
+ return point
+}
+
+func (c *genericCurve) UnmarshalBytePoint(point []byte) []byte {
+ return point
+}
+
+func (c *genericCurve) MarshalIntegerPoint(x, y *big.Int) []byte {
+ return elliptic.Marshal(c.Curve, x, y)
+}
+
+func (c *genericCurve) UnmarshalIntegerPoint(point []byte) (x, y *big.Int) {
+ return elliptic.Unmarshal(c.Curve, point)
+}
+
+func (c *genericCurve) MarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+func (c *genericCurve) UnmarshalByteSecret(d []byte) []byte {
+ return d
+}
+
+func (c *genericCurve) MarshalIntegerSecret(d *big.Int) []byte {
+ return d.Bytes()
+}
+
+func (c *genericCurve) UnmarshalIntegerSecret(d []byte) *big.Int {
+ return new(big.Int).SetBytes(d)
+}
+
+func (c *genericCurve) GenerateECDH(rand io.Reader) (point, secret []byte, err error) {
+ secret, x, y, err := elliptic.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ point = elliptic.Marshal(c.Curve, x, y)
+ return point, secret, nil
+}
+
+func (c *genericCurve) GenerateECDSA(rand io.Reader) (x, y, secret *big.Int, err error) {
+ priv, err := ecdsa.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return
+ }
+
+ return priv.X, priv.Y, priv.D, nil
+}
+
+func (c *genericCurve) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ xP, yP := elliptic.Unmarshal(c.Curve, point)
+ if xP == nil {
+ panic("invalid point")
+ }
+
+ d, x, y, err := elliptic.GenerateKey(c.Curve, rand)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ vsG := elliptic.Marshal(c.Curve, x, y)
+ zbBig, _ := c.Curve.ScalarMult(xP, yP, d)
+
+ byteLen := (c.Curve.Params().BitSize + 7) >> 3
+ zb := make([]byte, byteLen)
+ zbBytes := zbBig.Bytes()
+ copy(zb[byteLen-len(zbBytes):], zbBytes)
+
+ return vsG, zb, nil
+}
+
+func (c *genericCurve) Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error) {
+ x, y := elliptic.Unmarshal(c.Curve, ephemeral)
+ zbBig, _ := c.Curve.ScalarMult(x, y, secret)
+ byteLen := (c.Curve.Params().BitSize + 7) >> 3
+ zb := make([]byte, byteLen)
+ zbBytes := zbBig.Bytes()
+ copy(zb[byteLen-len(zbBytes):], zbBytes)
+
+ return zb, nil
+}
+
+func (c *genericCurve) Sign(rand io.Reader, x, y, d *big.Int, hash []byte) (r, s *big.Int, err error) {
+ priv := &ecdsa.PrivateKey{D: d, PublicKey: ecdsa.PublicKey{X: x, Y: y, Curve: c.Curve}}
+ return ecdsa.Sign(rand, priv, hash)
+}
+
+func (c *genericCurve) Verify(x, y *big.Int, hash []byte, r, s *big.Int) bool {
+ pub := &ecdsa.PublicKey{X: x, Y: y, Curve: c.Curve}
+ return ecdsa.Verify(pub, hash, r, s)
+}
+
+func (c *genericCurve) validate(xP, yP *big.Int, secret []byte) error {
+ // the public point should not be at infinity (0,0)
+ zero := new(big.Int)
+ if xP.Cmp(zero) == 0 && yP.Cmp(zero) == 0 {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): infinity point", c.Curve.Params().Name))
+ }
+
+ // re-derive the public point Q' = (X,Y) = dG
+ // to compare to declared Q in public key
+ expectedX, expectedY := c.Curve.ScalarBaseMult(secret)
+ if xP.Cmp(expectedX) != 0 || yP.Cmp(expectedY) != 0 {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): invalid point", c.Curve.Params().Name))
+ }
+
+ return nil
+}
+
+func (c *genericCurve) ValidateECDSA(xP, yP *big.Int, secret []byte) error {
+ return c.validate(xP, yP, secret)
+}
+
+func (c *genericCurve) ValidateECDH(point []byte, secret []byte) error {
+ xP, yP := elliptic.Unmarshal(c.Curve, point)
+ if xP == nil {
+ return errors.KeyInvalidError(fmt.Sprintf("ecc (%s): invalid point", c.Curve.Params().Name))
+ }
+
+ return c.validate(xP, yP, secret)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go
new file mode 100644
index 0000000..df04262
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go
@@ -0,0 +1,107 @@
+// Package ecc implements a generic interface for ECDH, ECDSA, and EdDSA.
+package ecc
+
+import (
+ "crypto/subtle"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ x448lib "github.com/cloudflare/circl/dh/x448"
+)
+
+type x448 struct{}
+
+func NewX448() *x448 {
+ return &x448{}
+}
+
+func (c *x448) GetCurveName() string {
+ return "x448"
+}
+
+// MarshalBytePoint encodes the public point from native format, adding the prefix.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *x448) MarshalBytePoint(point []byte) []byte {
+ return append([]byte{0x40}, point...)
+}
+
+// UnmarshalBytePoint decodes a point from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6
+func (c *x448) UnmarshalBytePoint(point []byte) []byte {
+ if len(point) != x448lib.Size+1 {
+ return nil
+ }
+
+ return point[1:]
+}
+
+// MarshalByteSecret encoded a scalar from native format to prefixed.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.2
+func (c *x448) MarshalByteSecret(d []byte) []byte {
+ return append([]byte{0x40}, d...)
+}
+
+// UnmarshalByteSecret decodes a scalar from prefixed format to native.
+// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-5.5.5.6.1.2
+func (c *x448) UnmarshalByteSecret(d []byte) []byte {
+ if len(d) != x448lib.Size+1 {
+ return nil
+ }
+
+ // Store without prefix
+ return d[1:]
+}
+
+func (c *x448) generateKeyPairBytes(rand io.Reader) (sk, pk x448lib.Key, err error) {
+ if _, err = rand.Read(sk[:]); err != nil {
+ return
+ }
+
+ x448lib.KeyGen(&pk, &sk)
+ return
+}
+
+func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) {
+ priv, pub, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return
+ }
+
+ return pub[:], priv[:], nil
+}
+
+func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
+ var pk, ss x448lib.Key
+ seed, e, err := c.generateKeyPairBytes(rand)
+ if err != nil {
+ return nil, nil, err
+ }
+ copy(pk[:], point)
+ x448lib.Shared(&ss, &seed, &pk)
+
+ return e[:], ss[:], nil
+}
+
+func (c *x448) Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error) {
+ var ss, sk, e x448lib.Key
+
+ copy(sk[:], secret)
+ copy(e[:], ephemeral)
+ x448lib.Shared(&ss, &sk, &e)
+
+ return ss[:], nil
+}
+
+func (c *x448) ValidateECDH(point []byte, secret []byte) error {
+ var sk, pk, expectedPk x448lib.Key
+
+ copy(pk[:], point)
+ copy(sk[:], secret)
+ x448lib.KeyGen(&expectedPk, &sk)
+
+ if subtle.ConstantTimeCompare(expectedPk[:], pk[:]) == 0 {
+ return errors.KeyInvalidError("ecc: invalid curve25519 public point")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go
new file mode 100644
index 0000000..6c92148
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/encoding.go
@@ -0,0 +1,27 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package encoding implements openpgp packet field encodings as specified in
+// RFC 4880 and 6637.
+package encoding
+
+import "io"
+
+// Field is an encoded field of an openpgp packet.
+type Field interface {
+ // Bytes returns the decoded data.
+ Bytes() []byte
+
+ // BitLength is the size in bits of the decoded data.
+ BitLength() uint16
+
+ // EncodedBytes returns the encoded data.
+ EncodedBytes() []byte
+
+ // EncodedLength is the size in bytes of the encoded data.
+ EncodedLength() uint16
+
+ // ReadFrom reads the next Field from r.
+ ReadFrom(r io.Reader) (int64, error)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go
new file mode 100644
index 0000000..02e5e69
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/mpi.go
@@ -0,0 +1,91 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package encoding
+
+import (
+ "io"
+ "math/big"
+ "math/bits"
+)
+
+// An MPI is used to store the contents of a big integer, along with the bit
+// length that was specified in the original input. This allows the MPI to be
+// reserialized exactly.
+type MPI struct {
+ bytes []byte
+ bitLength uint16
+}
+
+// NewMPI returns a MPI initialized with bytes.
+func NewMPI(bytes []byte) *MPI {
+ for len(bytes) != 0 && bytes[0] == 0 {
+ bytes = bytes[1:]
+ }
+ if len(bytes) == 0 {
+ bitLength := uint16(0)
+ return &MPI{bytes, bitLength}
+ }
+ bitLength := 8*uint16(len(bytes)-1) + uint16(bits.Len8(bytes[0]))
+ return &MPI{bytes, bitLength}
+}
+
+// Bytes returns the decoded data.
+func (m *MPI) Bytes() []byte {
+ return m.bytes
+}
+
+// BitLength is the size in bits of the decoded data.
+func (m *MPI) BitLength() uint16 {
+ return m.bitLength
+}
+
+// EncodedBytes returns the encoded data.
+func (m *MPI) EncodedBytes() []byte {
+ return append([]byte{byte(m.bitLength >> 8), byte(m.bitLength)}, m.bytes...)
+}
+
+// EncodedLength is the size in bytes of the encoded data.
+func (m *MPI) EncodedLength() uint16 {
+ return uint16(2 + len(m.bytes))
+}
+
+// ReadFrom reads into m the next MPI from r.
+func (m *MPI) ReadFrom(r io.Reader) (int64, error) {
+ var buf [2]byte
+ n, err := io.ReadFull(r, buf[0:])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return int64(n), err
+ }
+
+ m.bitLength = uint16(buf[0])<<8 | uint16(buf[1])
+ m.bytes = make([]byte, (int(m.bitLength)+7)/8)
+
+ nn, err := io.ReadFull(r, m.bytes)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+
+ // remove leading zero bytes from malformed GnuPG encoded MPIs:
+ // https://bugs.gnupg.org/gnupg/issue1853
+ // for _, b := range m.bytes {
+ // if b != 0 {
+ // break
+ // }
+ // m.bytes = m.bytes[1:]
+ // m.bitLength -= 8
+ // }
+
+ return int64(n) + int64(nn), err
+}
+
+// SetBig initializes m with the bits from n.
+func (m *MPI) SetBig(n *big.Int) *MPI {
+ m.bytes = n.Bytes()
+ m.bitLength = uint16(n.BitLen())
+ return m
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go
new file mode 100644
index 0000000..c9df9fe
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/encoding/oid.go
@@ -0,0 +1,88 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package encoding
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// OID is used to store a variable-length field with a one-octet size
+// prefix. See https://tools.ietf.org/html/rfc6637#section-9.
+type OID struct {
+ bytes []byte
+}
+
+const (
+ // maxOID is the maximum number of bytes in a OID.
+ maxOID = 254
+ // reservedOIDLength1 and reservedOIDLength2 are OID lengths that the RFC
+ // specifies are reserved.
+ reservedOIDLength1 = 0
+ reservedOIDLength2 = 0xff
+)
+
+// NewOID returns a OID initialized with bytes.
+func NewOID(bytes []byte) *OID {
+ switch len(bytes) {
+ case reservedOIDLength1, reservedOIDLength2:
+ panic("encoding: NewOID argument length is reserved")
+ default:
+ if len(bytes) > maxOID {
+ panic("encoding: NewOID argument too large")
+ }
+ }
+
+ return &OID{
+ bytes: bytes,
+ }
+}
+
+// Bytes returns the decoded data.
+func (o *OID) Bytes() []byte {
+ return o.bytes
+}
+
+// BitLength is the size in bits of the decoded data.
+func (o *OID) BitLength() uint16 {
+ return uint16(len(o.bytes) * 8)
+}
+
+// EncodedBytes returns the encoded data.
+func (o *OID) EncodedBytes() []byte {
+ return append([]byte{byte(len(o.bytes))}, o.bytes...)
+}
+
+// EncodedLength is the size in bytes of the encoded data.
+func (o *OID) EncodedLength() uint16 {
+ return uint16(1 + len(o.bytes))
+}
+
+// ReadFrom reads into b the next OID from r.
+func (o *OID) ReadFrom(r io.Reader) (int64, error) {
+ var buf [1]byte
+ n, err := io.ReadFull(r, buf[:])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return int64(n), err
+ }
+
+ switch buf[0] {
+ case reservedOIDLength1, reservedOIDLength2:
+ return int64(n), errors.UnsupportedError("reserved for future extensions")
+ }
+
+ o.bytes = make([]byte, buf[0])
+
+ nn, err := io.ReadFull(r, o.bytes)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+
+ return int64(n) + int64(nn), err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go
new file mode 100644
index 0000000..0e71934
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/key_generation.go
@@ -0,0 +1,389 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ goerrors "errors"
+ "io"
+ "math/big"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
+// single identity composed of the given full name, comment and email, any of
+// which may be empty but must not contain any of "()<>\x00".
+// If config is nil, sensible defaults will be used.
+func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+
+ // Generate a primary signing key
+ primaryPrivRaw, err := newSigner(config)
+ if err != nil {
+ return nil, err
+ }
+ primary := packet.NewSignerPrivateKey(creationTime, primaryPrivRaw)
+ if config != nil && config.V5Keys {
+ primary.UpgradeToV5()
+ }
+
+ e := &Entity{
+ PrimaryKey: &primary.PublicKey,
+ PrivateKey: primary,
+ Identities: make(map[string]*Identity),
+ Subkeys: []Subkey{},
+ }
+
+ err = e.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs)
+ if err != nil {
+ return nil, err
+ }
+
+ // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey()
+ // if the primary/master key has expired.
+ err = e.addEncryptionSubkey(config, creationTime, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ return e, nil
+}
+
+func (t *Entity) AddUserId(name, comment, email string, config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+ return t.addUserId(name, comment, email, config, creationTime, keyLifetimeSecs)
+}
+
+func (t *Entity) addUserId(name, comment, email string, config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32) error {
+ uid := packet.NewUserId(name, comment, email)
+ if uid == nil {
+ return errors.InvalidArgumentError("user id field contained invalid characters")
+ }
+
+ if _, ok := t.Identities[uid.Id]; ok {
+ return errors.InvalidArgumentError("user id exist")
+ }
+
+ primary := t.PrivateKey
+
+ isPrimaryId := len(t.Identities) == 0
+
+ selfSignature := createSignaturePacket(&primary.PublicKey, packet.SigTypePositiveCert, config)
+ selfSignature.CreationTime = creationTime
+ selfSignature.KeyLifetimeSecs = &keyLifetimeSecs
+ selfSignature.IsPrimaryId = &isPrimaryId
+ selfSignature.FlagsValid = true
+ selfSignature.FlagSign = true
+ selfSignature.FlagCertify = true
+ selfSignature.SEIPDv1 = true // true by default, see 5.8 vs. 5.14
+ selfSignature.SEIPDv2 = config.AEAD() != nil
+
+ // Set the PreferredHash for the SelfSignature from the packet.Config.
+ // If it is not the must-implement algorithm from rfc4880bis, append that.
+ hash, ok := algorithm.HashToHashId(config.Hash())
+ if !ok {
+ return errors.UnsupportedError("unsupported preferred hash function")
+ }
+
+ selfSignature.PreferredHash = []uint8{hash}
+ if config.Hash() != crypto.SHA256 {
+ selfSignature.PreferredHash = append(selfSignature.PreferredHash, hashToHashId(crypto.SHA256))
+ }
+
+ // Likewise for DefaultCipher.
+ selfSignature.PreferredSymmetric = []uint8{uint8(config.Cipher())}
+ if config.Cipher() != packet.CipherAES128 {
+ selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, uint8(packet.CipherAES128))
+ }
+
+ // We set CompressionNone as the preferred compression algorithm because
+ // of compression side channel attacks, then append the configured
+ // DefaultCompressionAlgo if any is set (to signal support for cases
+ // where the application knows that using compression is safe).
+ selfSignature.PreferredCompression = []uint8{uint8(packet.CompressionNone)}
+ if config.Compression() != packet.CompressionNone {
+ selfSignature.PreferredCompression = append(selfSignature.PreferredCompression, uint8(config.Compression()))
+ }
+
+ // And for DefaultMode.
+ modes := []uint8{uint8(config.AEAD().Mode())}
+ if config.AEAD().Mode() != packet.AEADModeOCB {
+ modes = append(modes, uint8(packet.AEADModeOCB))
+ }
+
+ // For preferred (AES256, GCM), we'll generate (AES256, GCM), (AES256, OCB), (AES128, GCM), (AES128, OCB)
+ for _, cipher := range selfSignature.PreferredSymmetric {
+ for _, mode := range modes {
+ selfSignature.PreferredCipherSuites = append(selfSignature.PreferredCipherSuites, [2]uint8{cipher, mode})
+ }
+ }
+
+ // User ID binding signature
+ err := selfSignature.SignUserId(uid.Id, &primary.PublicKey, primary, config)
+ if err != nil {
+ return err
+ }
+ t.Identities[uid.Id] = &Identity{
+ Name: uid.Id,
+ UserId: uid,
+ SelfSignature: selfSignature,
+ Signatures: []*packet.Signature{selfSignature},
+ }
+ return nil
+}
+
+// AddSigningSubkey adds a signing keypair as a subkey to the Entity.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) AddSigningSubkey(config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+
+ subPrivRaw, err := newSigner(config)
+ if err != nil {
+ return err
+ }
+ sub := packet.NewSignerPrivateKey(creationTime, subPrivRaw)
+ sub.IsSubkey = true
+ if config != nil && config.V5Keys {
+ sub.UpgradeToV5()
+ }
+
+ subkey := Subkey{
+ PublicKey: &sub.PublicKey,
+ PrivateKey: sub,
+ }
+ subkey.Sig = createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyBinding, config)
+ subkey.Sig.CreationTime = creationTime
+ subkey.Sig.KeyLifetimeSecs = &keyLifetimeSecs
+ subkey.Sig.FlagsValid = true
+ subkey.Sig.FlagSign = true
+ subkey.Sig.EmbeddedSignature = createSignaturePacket(subkey.PublicKey, packet.SigTypePrimaryKeyBinding, config)
+ subkey.Sig.EmbeddedSignature.CreationTime = creationTime
+
+ err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey, subkey.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ e.Subkeys = append(e.Subkeys, subkey)
+ return nil
+}
+
+// AddEncryptionSubkey adds an encryption keypair as a subkey to the Entity.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) AddEncryptionSubkey(config *packet.Config) error {
+ creationTime := config.Now()
+ keyLifetimeSecs := config.KeyLifetime()
+ return e.addEncryptionSubkey(config, creationTime, keyLifetimeSecs)
+}
+
+func (e *Entity) addEncryptionSubkey(config *packet.Config, creationTime time.Time, keyLifetimeSecs uint32) error {
+ subPrivRaw, err := newDecrypter(config)
+ if err != nil {
+ return err
+ }
+ sub := packet.NewDecrypterPrivateKey(creationTime, subPrivRaw)
+ sub.IsSubkey = true
+ if config != nil && config.V5Keys {
+ sub.UpgradeToV5()
+ }
+
+ subkey := Subkey{
+ PublicKey: &sub.PublicKey,
+ PrivateKey: sub,
+ }
+ subkey.Sig = createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyBinding, config)
+ subkey.Sig.CreationTime = creationTime
+ subkey.Sig.KeyLifetimeSecs = &keyLifetimeSecs
+ subkey.Sig.FlagsValid = true
+ subkey.Sig.FlagEncryptStorage = true
+ subkey.Sig.FlagEncryptCommunications = true
+
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return err
+ }
+
+ e.Subkeys = append(e.Subkeys, subkey)
+ return nil
+}
+
+// Generates a signing key
+func newSigner(config *packet.Config) (signer interface{}, err error) {
+ switch config.PublicKeyAlgorithm() {
+ case packet.PubKeyAlgoRSA:
+ bits := config.RSAModulusBits()
+ if bits < 1024 {
+ return nil, errors.InvalidArgumentError("bits must be >= 1024")
+ }
+ if config != nil && len(config.RSAPrimes) >= 2 {
+ primes := config.RSAPrimes[0:2]
+ config.RSAPrimes = config.RSAPrimes[2:]
+ return generateRSAKeyWithPrimes(config.Random(), 2, bits, primes)
+ }
+ return rsa.GenerateKey(config.Random(), bits)
+ case packet.PubKeyAlgoEdDSA:
+ curve := ecc.FindEdDSAByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+
+ priv, err := eddsa.GenerateKey(config.Random(), curve)
+ if err != nil {
+ return nil, err
+ }
+ return priv, nil
+ case packet.PubKeyAlgoECDSA:
+ curve := ecc.FindECDSAByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+
+ priv, err := ecdsa.GenerateKey(config.Random(), curve)
+ if err != nil {
+ return nil, err
+ }
+ return priv, nil
+ default:
+ return nil, errors.InvalidArgumentError("unsupported public key algorithm")
+ }
+}
+
+// Generates an encryption/decryption key
+func newDecrypter(config *packet.Config) (decrypter interface{}, err error) {
+ switch config.PublicKeyAlgorithm() {
+ case packet.PubKeyAlgoRSA:
+ bits := config.RSAModulusBits()
+ if bits < 1024 {
+ return nil, errors.InvalidArgumentError("bits must be >= 1024")
+ }
+ if config != nil && len(config.RSAPrimes) >= 2 {
+ primes := config.RSAPrimes[0:2]
+ config.RSAPrimes = config.RSAPrimes[2:]
+ return generateRSAKeyWithPrimes(config.Random(), 2, bits, primes)
+ }
+ return rsa.GenerateKey(config.Random(), bits)
+ case packet.PubKeyAlgoEdDSA, packet.PubKeyAlgoECDSA:
+ fallthrough // When passing EdDSA or ECDSA, we generate an ECDH subkey
+ case packet.PubKeyAlgoECDH:
+ var kdf = ecdh.KDF{
+ Hash: algorithm.SHA512,
+ Cipher: algorithm.AES256,
+ }
+ curve := ecc.FindECDHByGenName(string(config.CurveName()))
+ if curve == nil {
+ return nil, errors.InvalidArgumentError("unsupported curve")
+ }
+ return ecdh.GenerateKey(config.Random(), curve, kdf)
+ default:
+ return nil, errors.InvalidArgumentError("unsupported public key algorithm")
+ }
+}
+
+var bigOne = big.NewInt(1)
+
+// generateRSAKeyWithPrimes generates a multi-prime RSA keypair of the
+// given bit size, using the given random source and prepopulated primes.
+func generateRSAKeyWithPrimes(random io.Reader, nprimes int, bits int, prepopulatedPrimes []*big.Int) (*rsa.PrivateKey, error) {
+ priv := new(rsa.PrivateKey)
+ priv.E = 65537
+
+ if nprimes < 2 {
+ return nil, goerrors.New("generateRSAKeyWithPrimes: nprimes must be >= 2")
+ }
+
+ if bits < 1024 {
+ return nil, goerrors.New("generateRSAKeyWithPrimes: bits must be >= 1024")
+ }
+
+ primes := make([]*big.Int, nprimes)
+
+NextSetOfPrimes:
+ for {
+ todo := bits
+ // crypto/rand should set the top two bits in each prime.
+ // Thus each prime has the form
+ // p_i = 2^bitlen(p_i) × 0.11... (in base 2).
+ // And the product is:
+ // P = 2^todo × α
+ // where α is the product of nprimes numbers of the form 0.11...
+ //
+ // If α < 1/2 (which can happen for nprimes > 2), we need to
+ // shift todo to compensate for lost bits: the mean value of 0.11...
+ // is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
+ // will give good results.
+ if nprimes >= 7 {
+ todo += (nprimes - 2) / 5
+ }
+ for i := 0; i < nprimes; i++ {
+ var err error
+ if len(prepopulatedPrimes) == 0 {
+ primes[i], err = rand.Prime(random, todo/(nprimes-i))
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ primes[i] = prepopulatedPrimes[0]
+ prepopulatedPrimes = prepopulatedPrimes[1:]
+ }
+
+ todo -= primes[i].BitLen()
+ }
+
+ // Make sure that primes is pairwise unequal.
+ for i, prime := range primes {
+ for j := 0; j < i; j++ {
+ if prime.Cmp(primes[j]) == 0 {
+ continue NextSetOfPrimes
+ }
+ }
+ }
+
+ n := new(big.Int).Set(bigOne)
+ totient := new(big.Int).Set(bigOne)
+ pminus1 := new(big.Int)
+ for _, prime := range primes {
+ n.Mul(n, prime)
+ pminus1.Sub(prime, bigOne)
+ totient.Mul(totient, pminus1)
+ }
+ if n.BitLen() != bits {
+ // This should never happen for nprimes == 2 because
+ // crypto/rand should set the top two bits in each prime.
+ // For nprimes > 2 we hope it does not happen often.
+ continue NextSetOfPrimes
+ }
+
+ priv.D = new(big.Int)
+ e := big.NewInt(int64(priv.E))
+ ok := priv.D.ModInverse(e, totient)
+
+ if ok != nil {
+ priv.Primes = primes
+ priv.N = n
+ break
+ }
+ }
+
+ priv.Precompute()
+ return priv, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
new file mode 100644
index 0000000..2d7b0cf
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go
@@ -0,0 +1,842 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ goerrors "errors"
+ "io"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// PublicKeyType is the armor type for a PGP public key.
+var PublicKeyType = "PGP PUBLIC KEY BLOCK"
+
+// PrivateKeyType is the armor type for a PGP private key.
+var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
+
+// An Entity represents the components of an OpenPGP key: a primary public key
+// (which must be a signing key), one or more identities claimed by that key,
+// and zero or more subkeys, which may be encryption keys.
+type Entity struct {
+ PrimaryKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ Identities map[string]*Identity // indexed by Identity.Name
+ Revocations []*packet.Signature
+ Subkeys []Subkey
+}
+
+// An Identity represents an identity claimed by an Entity and zero or more
+// assertions by other entities about that claim.
+type Identity struct {
+ Name string // by convention, has the form "Full Name (comment) "
+ UserId *packet.UserId
+ SelfSignature *packet.Signature
+ Revocations []*packet.Signature
+ Signatures []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures
+}
+
+// A Subkey is an additional public key in an Entity. Subkeys can be used for
+// encryption.
+type Subkey struct {
+ PublicKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ Sig *packet.Signature
+ Revocations []*packet.Signature
+}
+
+// A Key identifies a specific public key in an Entity. This is either the
+// Entity's primary key or a subkey.
+type Key struct {
+ Entity *Entity
+ PublicKey *packet.PublicKey
+ PrivateKey *packet.PrivateKey
+ SelfSignature *packet.Signature
+ Revocations []*packet.Signature
+}
+
+// A KeyRing provides access to public and private keys.
+type KeyRing interface {
+ // KeysById returns the set of keys that have the given key id.
+ KeysById(id uint64) []Key
+ // KeysByIdAndUsage returns the set of keys with the given id
+ // that also meet the key usage given by requiredUsage.
+ // The requiredUsage is expressed as the bitwise-OR of
+ // packet.KeyFlag* values.
+ KeysByIdUsage(id uint64, requiredUsage byte) []Key
+ // DecryptionKeys returns all private keys that are valid for
+ // decryption.
+ DecryptionKeys() []Key
+}
+
+// PrimaryIdentity returns an Identity, preferring non-revoked identities,
+// identities marked as primary, or the latest-created identity, in that order.
+func (e *Entity) PrimaryIdentity() *Identity {
+ var primaryIdentity *Identity
+ for _, ident := range e.Identities {
+ if shouldPreferIdentity(primaryIdentity, ident) {
+ primaryIdentity = ident
+ }
+ }
+ return primaryIdentity
+}
+
+func shouldPreferIdentity(existingId, potentialNewId *Identity) bool {
+ if existingId == nil {
+ return true
+ }
+
+ if len(existingId.Revocations) > len(potentialNewId.Revocations) {
+ return true
+ }
+
+ if len(existingId.Revocations) < len(potentialNewId.Revocations) {
+ return false
+ }
+
+ if existingId.SelfSignature == nil {
+ return true
+ }
+
+ if existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId &&
+ !(potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId) {
+ return false
+ }
+
+ if !(existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId) &&
+ potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId {
+ return true
+ }
+
+ return potentialNewId.SelfSignature.CreationTime.After(existingId.SelfSignature.CreationTime)
+}
+
+// EncryptionKey returns the best candidate Key for encrypting a message to the
+// given Entity.
+func (e *Entity) EncryptionKey(now time.Time) (Key, bool) {
+ // Fail to find any encryption key if the...
+ i := e.PrimaryIdentity()
+ if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired
+ i.SelfSignature == nil || // user ID has no self-signature
+ i.SelfSignature.SigExpired(now) || // user ID self-signature has expired
+ e.Revoked(now) || // primary key has been revoked
+ i.Revoked(now) { // user ID has been revoked
+ return Key{}, false
+ }
+
+ // Iterate the keys to find the newest, unexpired one
+ candidateSubkey := -1
+ var maxTime time.Time
+ for i, subkey := range e.Subkeys {
+ if subkey.Sig.FlagsValid &&
+ subkey.Sig.FlagEncryptCommunications &&
+ subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
+ !subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
+ !subkey.Sig.SigExpired(now) &&
+ !subkey.Revoked(now) &&
+ (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
+ candidateSubkey = i
+ maxTime = subkey.Sig.CreationTime
+ }
+ }
+
+ if candidateSubkey != -1 {
+ subkey := e.Subkeys[candidateSubkey]
+ return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
+ }
+
+ // If we don't have any subkeys for encryption and the primary key
+ // is marked as OK to encrypt with, then we can use it.
+ if i.SelfSignature.FlagsValid && i.SelfSignature.FlagEncryptCommunications &&
+ e.PrimaryKey.PubKeyAlgo.CanEncrypt() {
+ return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true
+ }
+
+ return Key{}, false
+}
+
+// CertificationKey return the best candidate Key for certifying a key with this
+// Entity.
+func (e *Entity) CertificationKey(now time.Time) (Key, bool) {
+ return e.CertificationKeyById(now, 0)
+}
+
+// CertificationKeyById return the Key for key certification with this
+// Entity and keyID.
+func (e *Entity) CertificationKeyById(now time.Time, id uint64) (Key, bool) {
+ return e.signingKeyByIdUsage(now, id, packet.KeyFlagCertify)
+}
+
+// SigningKey return the best candidate Key for signing a message with this
+// Entity.
+func (e *Entity) SigningKey(now time.Time) (Key, bool) {
+ return e.SigningKeyById(now, 0)
+}
+
+// SigningKeyById return the Key for signing a message with this
+// Entity and keyID.
+func (e *Entity) SigningKeyById(now time.Time, id uint64) (Key, bool) {
+ return e.signingKeyByIdUsage(now, id, packet.KeyFlagSign)
+}
+
+func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, bool) {
+ // Fail to find any signing key if the...
+ i := e.PrimaryIdentity()
+ if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired
+ i.SelfSignature == nil || // user ID has no self-signature
+ i.SelfSignature.SigExpired(now) || // user ID self-signature has expired
+ e.Revoked(now) || // primary key has been revoked
+ i.Revoked(now) { // user ID has been revoked
+ return Key{}, false
+ }
+
+ // Iterate the keys to find the newest, unexpired one
+ candidateSubkey := -1
+ var maxTime time.Time
+ for idx, subkey := range e.Subkeys {
+ if subkey.Sig.FlagsValid &&
+ (flags&packet.KeyFlagCertify == 0 || subkey.Sig.FlagCertify) &&
+ (flags&packet.KeyFlagSign == 0 || subkey.Sig.FlagSign) &&
+ subkey.PublicKey.PubKeyAlgo.CanSign() &&
+ !subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
+ !subkey.Sig.SigExpired(now) &&
+ !subkey.Revoked(now) &&
+ (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) &&
+ (id == 0 || subkey.PublicKey.KeyId == id) {
+ candidateSubkey = idx
+ maxTime = subkey.Sig.CreationTime
+ }
+ }
+
+ if candidateSubkey != -1 {
+ subkey := e.Subkeys[candidateSubkey]
+ return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
+ }
+
+ // If we don't have any subkeys for signing and the primary key
+ // is marked as OK to sign with, then we can use it.
+ if i.SelfSignature.FlagsValid &&
+ (flags&packet.KeyFlagCertify == 0 || i.SelfSignature.FlagCertify) &&
+ (flags&packet.KeyFlagSign == 0 || i.SelfSignature.FlagSign) &&
+ e.PrimaryKey.PubKeyAlgo.CanSign() &&
+ (id == 0 || e.PrimaryKey.KeyId == id) {
+ return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true
+ }
+
+ // No keys with a valid Signing Flag or no keys matched the id passed in
+ return Key{}, false
+}
+
+func revoked(revocations []*packet.Signature, now time.Time) bool {
+ for _, revocation := range revocations {
+ if revocation.RevocationReason != nil && *revocation.RevocationReason == packet.KeyCompromised {
+ // If the key is compromised, the key is considered revoked even before the revocation date.
+ return true
+ }
+ if !revocation.SigExpired(now) {
+ return true
+ }
+ }
+ return false
+}
+
+// Revoked returns whether the entity has any direct key revocation signatures.
+// Note that third-party revocation signatures are not supported.
+// Note also that Identity and Subkey revocation should be checked separately.
+func (e *Entity) Revoked(now time.Time) bool {
+ return revoked(e.Revocations, now)
+}
+
+// EncryptPrivateKeys encrypts all non-encrypted keys in the entity with the same key
+// derived from the provided passphrase. Public keys and dummy keys are ignored,
+// and don't cause an error to be returned.
+func (e *Entity) EncryptPrivateKeys(passphrase []byte, config *packet.Config) error {
+ var keysToEncrypt []*packet.PrivateKey
+ // Add entity private key to encrypt.
+ if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted {
+ keysToEncrypt = append(keysToEncrypt, e.PrivateKey)
+ }
+
+ // Add subkeys to encrypt.
+ for _, sub := range e.Subkeys {
+ if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && !sub.PrivateKey.Encrypted {
+ keysToEncrypt = append(keysToEncrypt, sub.PrivateKey)
+ }
+ }
+ return packet.EncryptPrivateKeys(keysToEncrypt, passphrase, config)
+}
+
+// DecryptPrivateKeys decrypts all encrypted keys in the entitiy with the given passphrase.
+// Avoids recomputation of similar s2k key derivations. Public keys and dummy keys are ignored,
+// and don't cause an error to be returned.
+func (e *Entity) DecryptPrivateKeys(passphrase []byte) error {
+ var keysToDecrypt []*packet.PrivateKey
+ // Add entity private key to decrypt.
+ if e.PrivateKey != nil && !e.PrivateKey.Dummy() && e.PrivateKey.Encrypted {
+ keysToDecrypt = append(keysToDecrypt, e.PrivateKey)
+ }
+
+ // Add subkeys to decrypt.
+ for _, sub := range e.Subkeys {
+ if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
+ keysToDecrypt = append(keysToDecrypt, sub.PrivateKey)
+ }
+ }
+ return packet.DecryptPrivateKeys(keysToDecrypt, passphrase)
+}
+
+// Revoked returns whether the identity has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+func (i *Identity) Revoked(now time.Time) bool {
+ return revoked(i.Revocations, now)
+}
+
+// Revoked returns whether the subkey has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+func (s *Subkey) Revoked(now time.Time) bool {
+ return revoked(s.Revocations, now)
+}
+
+// Revoked returns whether the key or subkey has been revoked by a self-signature.
+// Note that third-party revocation signatures are not supported.
+// Note also that Identity revocation should be checked separately.
+// Normally, it's not necessary to call this function, except on keys returned by
+// KeysById or KeysByIdUsage.
+func (key *Key) Revoked(now time.Time) bool {
+ return revoked(key.Revocations, now)
+}
+
+// An EntityList contains one or more Entities.
+type EntityList []*Entity
+
+// KeysById returns the set of keys that have the given key id.
+func (el EntityList) KeysById(id uint64) (keys []Key) {
+ for _, e := range el {
+ if e.PrimaryKey.KeyId == id {
+ ident := e.PrimaryIdentity()
+ selfSig := ident.SelfSignature
+ keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig, e.Revocations})
+ }
+
+ for _, subKey := range e.Subkeys {
+ if subKey.PublicKey.KeyId == id {
+ keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
+ }
+ }
+ }
+ return
+}
+
+// KeysByIdAndUsage returns the set of keys with the given id that also meet
+// the key usage given by requiredUsage. The requiredUsage is expressed as
+// the bitwise-OR of packet.KeyFlag* values.
+func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
+ for _, key := range el.KeysById(id) {
+ if requiredUsage != 0 {
+ if key.SelfSignature == nil || !key.SelfSignature.FlagsValid {
+ continue
+ }
+
+ var usage byte
+ if key.SelfSignature.FlagCertify {
+ usage |= packet.KeyFlagCertify
+ }
+ if key.SelfSignature.FlagSign {
+ usage |= packet.KeyFlagSign
+ }
+ if key.SelfSignature.FlagEncryptCommunications {
+ usage |= packet.KeyFlagEncryptCommunications
+ }
+ if key.SelfSignature.FlagEncryptStorage {
+ usage |= packet.KeyFlagEncryptStorage
+ }
+ if usage&requiredUsage != requiredUsage {
+ continue
+ }
+ }
+
+ keys = append(keys, key)
+ }
+ return
+}
+
+// DecryptionKeys returns all private keys that are valid for decryption.
+func (el EntityList) DecryptionKeys() (keys []Key) {
+ for _, e := range el {
+ for _, subKey := range e.Subkeys {
+ if subKey.PrivateKey != nil && subKey.Sig.FlagsValid && (subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
+ keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
+ }
+ }
+ }
+ return
+}
+
+// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
+func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
+ block, err := armor.Decode(r)
+ if err == io.EOF {
+ return nil, errors.InvalidArgumentError("no armored data found")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if block.Type != PublicKeyType && block.Type != PrivateKeyType {
+ return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
+ }
+
+ return ReadKeyRing(block.Body)
+}
+
+// ReadKeyRing reads one or more public/private keys. Unsupported keys are
+// ignored as long as at least a single valid key is found.
+func ReadKeyRing(r io.Reader) (el EntityList, err error) {
+ packets := packet.NewReader(r)
+ var lastUnsupportedError error
+
+ for {
+ var e *Entity
+ e, err = ReadEntity(packets)
+ if err != nil {
+ // TODO: warn about skipped unsupported/unreadable keys
+ if _, ok := err.(errors.UnsupportedError); ok {
+ lastUnsupportedError = err
+ err = readToNextPublicKey(packets)
+ } else if _, ok := err.(errors.StructuralError); ok {
+ // Skip unreadable, badly-formatted keys
+ lastUnsupportedError = err
+ err = readToNextPublicKey(packets)
+ }
+ if err == io.EOF {
+ err = nil
+ break
+ }
+ if err != nil {
+ el = nil
+ break
+ }
+ } else {
+ el = append(el, e)
+ }
+ }
+
+ if len(el) == 0 && err == nil {
+ err = lastUnsupportedError
+ }
+ return
+}
+
+// readToNextPublicKey reads packets until the start of the entity and leaves
+// the first packet of the new entity in the Reader.
+func readToNextPublicKey(packets *packet.Reader) (err error) {
+ var p packet.Packet
+ for {
+ p, err = packets.Next()
+ if err == io.EOF {
+ return
+ } else if err != nil {
+ if _, ok := err.(errors.UnsupportedError); ok {
+ err = nil
+ continue
+ }
+ return
+ }
+
+ if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
+ packets.Unread(p)
+ return
+ }
+ }
+}
+
+// ReadEntity reads an entity (public key, identities, subkeys etc) from the
+// given Reader.
+func ReadEntity(packets *packet.Reader) (*Entity, error) {
+ e := new(Entity)
+ e.Identities = make(map[string]*Identity)
+
+ p, err := packets.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ var ok bool
+ if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
+ if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
+ packets.Unread(p)
+ return nil, errors.StructuralError("first packet was not a public/private key")
+ }
+ e.PrimaryKey = &e.PrivateKey.PublicKey
+ }
+
+ if !e.PrimaryKey.PubKeyAlgo.CanSign() {
+ return nil, errors.StructuralError("primary key cannot be used for signatures")
+ }
+
+ var revocations []*packet.Signature
+EachPacket:
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+
+ switch pkt := p.(type) {
+ case *packet.UserId:
+ if err := addUserID(e, packets, pkt); err != nil {
+ return nil, err
+ }
+ case *packet.Signature:
+ if pkt.SigType == packet.SigTypeKeyRevocation {
+ revocations = append(revocations, pkt)
+ } else if pkt.SigType == packet.SigTypeDirectSignature {
+ // TODO: RFC4880 5.2.1 permits signatures
+ // directly on keys (eg. to bind additional
+ // revocation keys).
+ }
+ // Else, ignoring the signature as it does not follow anything
+ // we would know to attach it to.
+ case *packet.PrivateKey:
+ if !pkt.IsSubkey {
+ packets.Unread(p)
+ break EachPacket
+ }
+ err = addSubkey(e, packets, &pkt.PublicKey, pkt)
+ if err != nil {
+ return nil, err
+ }
+ case *packet.PublicKey:
+ if !pkt.IsSubkey {
+ packets.Unread(p)
+ break EachPacket
+ }
+ err = addSubkey(e, packets, pkt, nil)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ // we ignore unknown packets
+ }
+ }
+
+ if len(e.Identities) == 0 {
+ return nil, errors.StructuralError("entity without any identities")
+ }
+
+ for _, revocation := range revocations {
+ err = e.PrimaryKey.VerifyRevocationSignature(revocation)
+ if err == nil {
+ e.Revocations = append(e.Revocations, revocation)
+ } else {
+ // TODO: RFC 4880 5.2.3.15 defines revocation keys.
+ return nil, errors.StructuralError("revocation signature signed by alternate key")
+ }
+ }
+
+ return e, nil
+}
+
+func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error {
+ // Make a new Identity object, that we might wind up throwing away.
+ // We'll only add it if we get a valid self-signature over this
+ // userID.
+ identity := new(Identity)
+ identity.Name = pkt.Id
+ identity.UserId = pkt
+
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return err
+ }
+
+ sig, ok := p.(*packet.Signature)
+ if !ok {
+ packets.Unread(p)
+ break
+ }
+
+ if sig.SigType != packet.SigTypeGenericCert &&
+ sig.SigType != packet.SigTypePersonaCert &&
+ sig.SigType != packet.SigTypeCasualCert &&
+ sig.SigType != packet.SigTypePositiveCert &&
+ sig.SigType != packet.SigTypeCertificationRevocation {
+ return errors.StructuralError("user ID signature with wrong type")
+ }
+
+ if sig.CheckKeyIdOrFingerprint(e.PrimaryKey) {
+ if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
+ return errors.StructuralError("user ID self-signature invalid: " + err.Error())
+ }
+ if sig.SigType == packet.SigTypeCertificationRevocation {
+ identity.Revocations = append(identity.Revocations, sig)
+ } else if identity.SelfSignature == nil || sig.CreationTime.After(identity.SelfSignature.CreationTime) {
+ identity.SelfSignature = sig
+ }
+ identity.Signatures = append(identity.Signatures, sig)
+ e.Identities[pkt.Id] = identity
+ } else {
+ identity.Signatures = append(identity.Signatures, sig)
+ }
+ }
+
+ return nil
+}
+
+func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
+ var subKey Subkey
+ subKey.PublicKey = pub
+ subKey.PrivateKey = priv
+
+ for {
+ p, err := packets.Next()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return errors.StructuralError("subkey signature invalid: " + err.Error())
+ }
+
+ sig, ok := p.(*packet.Signature)
+ if !ok {
+ packets.Unread(p)
+ break
+ }
+
+ if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation {
+ return errors.StructuralError("subkey signature with wrong type")
+ }
+
+ if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil {
+ return errors.StructuralError("subkey signature invalid: " + err.Error())
+ }
+
+ switch sig.SigType {
+ case packet.SigTypeSubkeyRevocation:
+ subKey.Revocations = append(subKey.Revocations, sig)
+ case packet.SigTypeSubkeyBinding:
+ if subKey.Sig == nil || sig.CreationTime.After(subKey.Sig.CreationTime) {
+ subKey.Sig = sig
+ }
+ }
+ }
+
+ if subKey.Sig == nil {
+ return errors.StructuralError("subkey packet not followed by signature")
+ }
+
+ e.Subkeys = append(e.Subkeys, subKey)
+
+ return nil
+}
+
+// SerializePrivate serializes an Entity, including private key material, but
+// excluding signatures from other entities, to the given Writer.
+// Identities and subkeys are re-signed in case they changed since NewEntry.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
+ if e.PrivateKey.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy private key cannot re-sign identities")
+ }
+ return e.serializePrivate(w, config, true)
+}
+
+// SerializePrivateWithoutSigning serializes an Entity, including private key
+// material, but excluding signatures from other entities, to the given Writer.
+// Self-signatures of identities and subkeys are not re-signed. This is useful
+// when serializing GNU dummy keys, among other things.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivateWithoutSigning(w io.Writer, config *packet.Config) (err error) {
+ return e.serializePrivate(w, config, false)
+}
+
+func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign bool) (err error) {
+ if e.PrivateKey == nil {
+ return goerrors.New("openpgp: private key is missing")
+ }
+ err = e.PrivateKey.Serialize(w)
+ if err != nil {
+ return
+ }
+ for _, revocation := range e.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ for _, ident := range e.Identities {
+ err = ident.UserId.Serialize(w)
+ if err != nil {
+ return
+ }
+ if reSign {
+ if ident.SelfSignature == nil {
+ return goerrors.New("openpgp: can't re-sign identity without valid self-signature")
+ }
+ err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ }
+ for _, sig := range ident.Signatures {
+ err = sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ for _, subkey := range e.Subkeys {
+ err = subkey.PrivateKey.Serialize(w)
+ if err != nil {
+ return
+ }
+ if reSign {
+ err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ if subkey.Sig.EmbeddedSignature != nil {
+ err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey,
+ subkey.PrivateKey, config)
+ if err != nil {
+ return
+ }
+ }
+ }
+ for _, revocation := range subkey.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ err = subkey.Sig.Serialize(w)
+ if err != nil {
+ return
+ }
+ }
+ return nil
+}
+
+// Serialize writes the public part of the given Entity to w, including
+// signatures from other entities. No private key material will be output.
+func (e *Entity) Serialize(w io.Writer) error {
+ err := e.PrimaryKey.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, revocation := range e.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ for _, ident := range e.Identities {
+ err = ident.UserId.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, sig := range ident.Signatures {
+ err = sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ for _, subkey := range e.Subkeys {
+ err = subkey.PublicKey.Serialize(w)
+ if err != nil {
+ return err
+ }
+ for _, revocation := range subkey.Revocations {
+ err := revocation.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ err = subkey.Sig.Serialize(w)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// SignIdentity adds a signature to e, from signer, attesting that identity is
+// associated with e. The provided identity must already be an element of
+// e.Identities and the private key of signer must have been decrypted if
+// necessary.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
+ certificationKey, ok := signer.CertificationKey(config.Now())
+ if !ok {
+ return errors.InvalidArgumentError("no valid certification key found")
+ }
+
+ if certificationKey.PrivateKey.Encrypted {
+ return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
+ }
+
+ ident, ok := e.Identities[identity]
+ if !ok {
+ return errors.InvalidArgumentError("given identity string not found in Entity")
+ }
+
+ sig := createSignaturePacket(certificationKey.PublicKey, packet.SigTypeGenericCert, config)
+
+ signingUserID := config.SigningUserId()
+ if signingUserID != "" {
+ if _, ok := signer.Identities[signingUserID]; !ok {
+ return errors.InvalidArgumentError("signer identity string not found in signer Entity")
+ }
+ sig.SignerUserId = &signingUserID
+ }
+
+ if err := sig.SignUserId(identity, e.PrimaryKey, certificationKey.PrivateKey, config); err != nil {
+ return err
+ }
+ ident.Signatures = append(ident.Signatures, sig)
+ return nil
+}
+
+// RevokeKey generates a key revocation signature (packet.SigTypeKeyRevocation) with the
+// specified reason code and text (RFC4880 section-5.2.3.23).
+// If config is nil, sensible defaults will be used.
+func (e *Entity) RevokeKey(reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
+ revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeKeyRevocation, config)
+ revSig.RevocationReason = &reason
+ revSig.RevocationReasonText = reasonText
+
+ if err := revSig.RevokeKey(e.PrimaryKey, e.PrivateKey, config); err != nil {
+ return err
+ }
+ e.Revocations = append(e.Revocations, revSig)
+ return nil
+}
+
+// RevokeSubkey generates a subkey revocation signature (packet.SigTypeSubkeyRevocation) for
+// a subkey with the specified reason code and text (RFC4880 section-5.2.3.23).
+// If config is nil, sensible defaults will be used.
+func (e *Entity) RevokeSubkey(sk *Subkey, reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
+ if err := e.PrimaryKey.VerifyKeySignature(sk.PublicKey, sk.Sig); err != nil {
+ return errors.InvalidArgumentError("given subkey is not associated with this key")
+ }
+
+ revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyRevocation, config)
+ revSig.RevocationReason = &reason
+ revSig.RevocationReasonText = reasonText
+
+ if err := revSig.RevokeSubkey(sk.PublicKey, e.PrivateKey, config); err != nil {
+ return err
+ }
+
+ sk.Revocations = append(sk.Revocations, revSig)
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go
new file mode 100644
index 0000000..108fd09
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys_test_data.go
@@ -0,0 +1,538 @@
+package openpgp
+
+const expiringKeyHex = "c6c04d0451d0c680010800abbb021fd03ffc4e96618901180c3fdcb060ee69eeead97b91256d11420d80b5f1b51930248044130bd300605cf8a05b7a40d3d8cfb0a910be2e3db50dcd50a9c54064c2a5550801daa834ff4480b33d3d3ca495ff8a4e84a886977d17d998f881241a874083d8b995beab555b6d22b8a4817ab17ac3e7304f7d4d2c05c495fb2218348d3bc13651db1d92732e368a9dd7dcefa6eddff30b94706a9aaee47e9d39321460b740c59c6fc3c2fd8ab6c0fb868cb87c0051f0321301fe0f0e1820b15e7fb7063395769b525005c7e30a7ce85984f5cac00504e7b4fdc45d74958de8388436fd5c7ba9ea121f1c851b5911dd1b47a14d81a09e92ef37721e2325b6790011010001cd00c2c07b041001080025050251d0c680050900278d00060b09070803020415080a0203160201021901021b03021e01000a0910e7b484133a890a35ae4b0800a1beb82e7f28eaf5273d6af9d3391314f6280b2b624eaca2851f89a9ebcaf80ac589ebd509f168bc4322106ca2e2ce77a76e071a3c7444787d65216b5f05e82c77928860b92aace3b7d0327db59492f422eb9dfab7249266d37429870b091a98aba8724c2259ebf8f85093f21255eafa75aa841e31d94f2ac891b9755fed455e539044ee69fc47950b80e003fc9f298d695660f28329eaa38037c367efde1727458e514faf990d439a21461b719edaddf9296d3d0647b43ca56cb8dbf63b4fcf8b9968e7928c463470fab3b98e44d0d95645062f94b2d04fe56bd52822b71934db8ce845622c40b92fcbe765a142e7f38b61a6aa9606c8e8858dcd3b6eb1894acec04d0451d1f06b01080088bea67444e1789390e7c0335c86775502d58ec783d99c8ef4e06de235ed3dd4b0467f6f358d818c7d8989d43ec6d69fcbc8c32632d5a1b605e3fa8e41d695fcdcaa535936cd0157f9040dce362519803b908eafe838bb13216c885c6f93e9e8d5745607f0d062322085d6bdc760969149a8ff8dd9f5c18d9bfe2e6f63a06e17694cf1f67587c6fb70e9aebf90ffc528ca3b615ac7c9d4a21ea4f7c06f2e98fbbd90a859b8608bf9ea638e3a54289ce44c283110d0c45fa458de6251cd6e7baf71f80f12c8978340490fd90c92b81736ae902ed958e478dceae2835953d189c45d182aff02ea2be61b81d8e94430f041d638647b43e2fcb45fd512fbf5068b810011010001c2c06504180108000f050251d1f06b050900081095021b0c000a0910e7b484133a890a35e63407fe2ec88d6d1e6c9ce7553ece0cb2524747217bad29f251d33df84599ffcc900141a355abd62126800744068a5e05dc167056aa9205273dc7765a2ed49db15c2a83b8d6e6429c902136f1e12229086c1c10c0053242c2a4ae1930db58163387a48cad64607ff2153c320e42843dec28e3fce90e7399d63ac0affa2fee1f0adc0953c89eb3f46ef1d6c04328ed13b491669d5120a3782e3ffb7c69575fb77eebd108794f4dda9d34be2bae57e8e59ec8ebfda2f6f06104b2321be408ea146e2db482b00c5055c8618de36ac9716f80da2617e225556d0fce61b01c8cea2d1e0ea982c31711060ca370f2739366e1e708f38405d784b49d16a26cf62d152eae734327cec04d0451d1f07b010800d5af91c5e7c2fd8951c8d254eab0c97cdcb66822f868b79b78c366255059a68fd74ebca9adb9b970cd9e586690e6e0756705432306878c897b10a4b4ca0005966f99ac8fa4e6f9caf54bf8e53844544beee9872a7ac64c119cf1393d96e674254b661f61ee975633d0e8a8672531edb6bb8e211204e7754a9efa802342118eee850beea742bac95a3f706cc2024cf6037a308bb68162b2f53b9a6346a96e6d31871a2456186e24a1c7a82b82ac04afdfd57cd7fb9ba77a9c760d40b76a170f7be525e5fb6a9848cc726e806187710d9b190387df28700f321f988a392899f93815cc937f309129eb94d5299c5547cb2c085898e6639496e70d746c9d3fb9881d0011010001c2c06504180108000f050251d1f07b050900266305021b0c000a0910e7b484133a890a35bff207fd10dfe8c4a6ea1dd30568012b6fd6891a763c87ad0f7a1d112aad9e8e3239378a3b85588c235865bac2e614348cb4f216d7217f53b3ef48c192e0a4d31d64d7bfa5faccf21155965fa156e887056db644a05ad08a85cc6152d1377d9e37b46f4ff462bbe68ace2dc586ef90070314576c985d8037c2ba63f0a7dc17a62e15bd77e88bc61d9d00858979709f12304264a4cf4225c5cf86f12c8e19486cb9cdcc69f18f027e5f16f4ca8b50e28b3115eaff3a345acd21f624aef81f6ede515c1b55b26b84c1e32264754eab672d5489b287e7277ea855e0a5ff2aa9e8b8c76d579a964ec225255f4d57bf66639ccb34b64798846943e162a41096a7002ca21c7f56"
+const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
+const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"
+const revokedSubkeyHex = "988d04533121f6010400aefc803a3e4bb1a61c86e8a86d2726c6a43e0079e9f2713f1fa017e9854c83877f4aced8e331d675c67ea83ddab80aacbfa0b9040bb12d96f5a3d6be09455e2a76546cbd21677537db941cab710216b6d24ec277ee0bd65b910f416737ed120f6b93a9d3b306245c8cfd8394606fdb462e5cf43c551438d2864506c63367fc890011010001b41d416c696365203c616c69636540626d626172697374612e636f2e61753e88bb041301020025021b03060b090807030206150802090a0b0416020301021e01021780050253312798021901000a09104ef7e4beccde97f015a803ff5448437780f63263b0df8442a995e7f76c221351a51edd06f2063d8166cf3157aada4923dfc44aa0f2a6a4da5cf83b7fe722ba8ab416c976e77c6b5682e7f1069026673bd0de56ba06fd5d7a9f177607f277d9b55ff940a638c3e68525c67517e2b3d976899b93ca267f705b3e5efad7d61220e96b618a4497eab8d04403d23f8846041011020006050253312910000a09107b15a67f0b3ddc03d96e009f50b6365d86c4be5d5e9d0ea42d5e56f5794c617700a0ab274e19c2827780016d23417ce89e0a2c0d987d889c04100102000605025331cf7a000a0910a401d9f09a34f7c0ee970400aca292f213041c9f3b3fc49148cbda9d84afee6183c8dd6c5ff2600b29482db5fecd4303797be1ee6d544a20a858080fec43412061c9a71fae4039fd58013b4ae341273e6c66ad4c7cdd9e68245bedb260562e7b166f2461a1032f2b38c0e0e5715fb3d1656979e052b55ca827a76f872b78a9fdae64bc298170bfcebedc1271b41a416c696365203c616c696365407379646973702e6f722e61753e88b804130102002205025331278b021b03060b090807030206150802090a0b0416020301021e01021780000a09104ef7e4beccde97f06a7003fa03c3af68d272ebc1fa08aa72a03b02189c26496a2833d90450801c4e42c5b5f51ad96ce2d2c9cef4b7c02a6a2fcf1412d6a2d486098eb762f5010a201819c17fd2888aec8eda20c65a3b75744de7ee5cc8ac7bfc470cbe3cb982720405a27a3c6a8c229cfe36905f881b02ed5680f6a8f05866efb9d6c5844897e631deb949ca8846041011020006050253312910000a09107b15a67f0b3ddc0347bc009f7fa35db59147469eb6f2c5aaf6428accb138b22800a0caa2f5f0874bacc5909c652a57a31beda65eddd5889c04100102000605025331cf7a000a0910a401d9f09a34f7c0316403ff46f2a5c101256627f16384d34a38fb47a6c88ba60506843e532d91614339fccae5f884a5741e7582ffaf292ba38ee10a270a05f139bde3814b6a077e8cd2db0f105ebea2a83af70d385f13b507fac2ad93ff79d84950328bb86f3074745a8b7f9b64990fb142e2a12976e27e8d09a28dc5621f957ac49091116da410ac3cbde1b88d04533121f6010400cbd785b56905e4192e2fb62a720727d43c4fa487821203cf72138b884b78b701093243e1d8c92a0248a6c0203a5a88693da34af357499abacaf4b3309c640797d03093870a323b4b6f37865f6eaa2838148a67df4735d43a90ca87942554cdf1c4a751b1e75f9fd4ce4e97e278d6c1c7ed59d33441df7d084f3f02beb68896c70011010001889f0418010200090502533121f6021b0c000a09104ef7e4beccde97f0b98b03fc0a5ccf6a372995835a2f5da33b282a7d612c0ab2a97f59cf9fff73e9110981aac2858c41399afa29624a7fd8a0add11654e3d882c0fd199e161bdad65e5e2548f7b68a437ea64293db1246e3011cbb94dc1bcdeaf0f2539bd88ff16d95547144d97cead6a8c5927660a91e6db0d16eb36b7b49a3525b54d1644e65599b032b7eb901a204533127a0110400bd3edaa09eff9809c4edc2c2a0ebe52e53c50a19c1e49ab78e6167bf61473bb08f2050d78a5cbbc6ed66aff7b42cd503f16b4a0b99fa1609681fca9b7ce2bbb1a5b3864d6cdda4d7ef7849d156d534dea30fb0efb9e4cf8959a2b2ce623905882d5430b995a15c3b9fe92906086788b891002924f94abe139b42cbbfaaabe42f00a0b65dc1a1ad27d798adbcb5b5ad02d2688c89477b03ff4eebb6f7b15a73b96a96bed201c0e5e4ea27e4c6e2dd1005b94d4b90137a5b1cf5e01c6226c070c4cc999938101578877ee76d296b9aab8246d57049caacf489e80a3f40589cade790a020b1ac146d6f7a6241184b8c7fcde680eae3188f5dcbe846d7f7bdad34f6fcfca08413e19c1d5df83fc7c7c627d493492e009c2f52a80400a2fe82de87136fd2e8845888c4431b032ba29d9a29a804277e31002a8201fb8591a3e55c7a0d0881496caf8b9fb07544a5a4879291d0dc026a0ea9e5bd88eb4aa4947bbd694b25012e208a250d65ddc6f1eea59d3aed3b4ec15fcab85e2afaa23a40ab1ef9ce3e11e1bc1c34a0e758e7aa64deb8739276df0af7d4121f834a9b88e70418010200090502533127a0021b02005209104ef7e4beccde97f047200419110200060502533127a0000a0910dbce4ee19529437fe045009c0b32f5ead48ee8a7e98fac0dea3d3e6c0e2c552500a0ad71fadc5007cfaf842d9b7db3335a8cdad15d3d1a6404009b08e2c68fe8f3b45c1bb72a4b3278cdf3012aa0f229883ad74aa1f6000bb90b18301b2f85372ca5d6b9bf478d235b733b1b197d19ccca48e9daf8e890cb64546b4ce1b178faccfff07003c172a2d4f5ebaba9f57153955f3f61a9b80a4f5cb959908f8b211b03b7026a8a82fc612bfedd3794969bcf458c4ce92be215a1176ab88d045331d144010400a5063000c5aaf34953c1aa3bfc95045b3aab9882b9a8027fecfe2142dc6b47ba8aca667399990244d513dd0504716908c17d92c65e74219e004f7b83fc125e575dd58efec3ab6dd22e3580106998523dea42ec75bf9aa111734c82df54630bebdff20fe981cfc36c76f865eb1c2fb62c9e85bc3a6e5015a361a2eb1c8431578d0011010001889f04280102000905025331d433021d03000a09104ef7e4beccde97f02e5503ff5e0630d1b65291f4882b6d40a29da4616bb5088717d469fbcc3648b8276de04a04988b1f1b9f3e18f52265c1f8b6c85861691c1a6b8a3a25a1809a0b32ad330aec5667cb4262f4450649184e8113849b05e5ad06a316ea80c001e8e71838190339a6e48bbde30647bcf245134b9a97fa875c1d83a9862cae87ffd7e2c4ce3a1b89013d04180102000905025331d144021b0200a809104ef7e4beccde97f09d2004190102000605025331d144000a0910677815e371c2fd23522203fe22ab62b8e7a151383cea3edd3a12995693911426f8ccf125e1f6426388c0010f88d9ca7da2224aee8d1c12135998640c5e1813d55a93df472faae75bef858457248db41b4505827590aeccf6f9eb646da7f980655dd3050c6897feddddaca90676dee856d66db8923477d251712bb9b3186b4d0114daf7d6b59272b53218dd1da94a03ff64006fcbe71211e5daecd9961fba66cdb6de3f914882c58ba5beddeba7dcb950c1156d7fba18c19ea880dccc800eae335deec34e3b84ac75ffa24864f782f87815cda1c0f634b3dd2fa67cea30811d21723d21d9551fa12ccbcfa62b6d3a15d01307b99925707992556d50065505b090aadb8579083a20fe65bd2a270da9b011"
+
+const missingCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Charset: UTF-8
+
+mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY
+ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG
+zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54
+QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ
+QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo
+9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu
+Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/
+dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R
+JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL
+ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew
+RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW
+/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu
+yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAJcXQeP+NmuciE99YcJoffxv
+2gVLU4ZXBNHEaP0mgaJ1+tmMD089vUQAcyGRvw8jfsNsVZQIOAuRxY94aHQhIRHR
+bUzBN28ofo/AJJtfx62C15xt6fDKRV6HXYqAiygrHIpEoRLyiN69iScUsjIJeyFL
+C8wa72e8pSL6dkHoaV1N9ZH/xmrJ+k0vsgkQaAh9CzYufncDxcwkoP+aOlGtX1gP
+WwWoIbz0JwLEMPHBWvDDXQcQPQTYQyj+LGC9U6f9VZHN25E94subM1MjuT9OhN9Y
+MLfWaaIc5WyhLFyQKW2Upofn9wSFi8ubyBnv640Dfd0rVmaWv7LNTZpoZ/GbJAMA
+EQEAAYkBHwQYAQIACQUCU5ygeQIbAgAKCRDt1A0FCB6SP0zCB/sEzaVR38vpx+OQ
+MMynCBJrakiqDmUZv9xtplY7zsHSQjpd6xGflbU2n+iX99Q+nav0ETQZifNUEd4N
+1ljDGQejcTyKD6Pkg6wBL3x9/RJye7Zszazm4+toJXZ8xJ3800+BtaPoI39akYJm
++ijzbskvN0v/j5GOFJwQO0pPRAFtdHqRs9Kf4YanxhedB4dIUblzlIJuKsxFit6N
+lgGRblagG3Vv2eBszbxzPbJjHCgVLR3RmrVezKOsZjr/2i7X+xLWIR0uD3IN1qOW
+CXQxLBizEEmSNVNxsp7KPGTLnqO3bPtqFirxS9PJLIMPTPLNBY7ZYuPNTMqVIUWF
+4artDmrG
+=7FfJ
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const invalidCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFMYynYBCACVOZ3/e8Bm2b9KH9QyIlHGo/i1bnkpqsgXj8tpJ2MIUOnXMMAY
+ztW7kKFLCmgVdLIC0vSoLA4yhaLcMojznh/2CcUglZeb6Ao8Gtelr//Rd5DRfPpG
+zqcfUo+m+eO1co2Orabw0tZDfGpg5p3AYl0hmxhUyYSc/xUq93xL1UJzBFgYXY54
+QsM8dgeQgFseSk/YvdP5SMx1ev+eraUyiiUtWzWrWC1TdyRa5p4UZg6Rkoppf+WJ
+QrW6BWrhAtqATHc8ozV7uJjeONjUEq24roRc/OFZdmQQGK6yrzKnnbA6MdHhqpdo
+9kWDcXYb7pSE63Lc+OBa5X2GUVvXJLS/3nrtABEBAAG0F2ludmFsaWQtc2lnbmlu
+Zy1zdWJrZXlziQEoBBMBAgASBQJTnKB5AhsBAgsHAhUIAh4BAAoJEO3UDQUIHpI/
+dN4H/idX4FQ1LIZCnpHS/oxoWQWfpRgdKAEM0qCqjMgiipJeEwSQbqjTCynuh5/R
+JlODDz85ABR06aoF4l5ebGLQWFCYifPnJZ/Yf5OYcMGtb7dIbqxWVFL9iLMO/oDL
+ioI3dotjPui5e+2hI9pVH1UHB/bZ/GvMGo6Zg0XxLPolKQODMVjpjLAQ0YJ3spew
+RAmOGre6tIvbDsMBnm8qREt7a07cBJ6XK7xjxYaZHQBiHVxyEWDa6gyANONx8duW
+/fhQ/zDTnyVM/ik6VO0Ty9BhPpcEYLFwh5c1ilFari1ta3e6qKo6ZGa9YMk/REhu
+yBHd9nTkI+0CiQUmbckUiVjDKKe5AQ0EUxjKdgEIAIINDqlj7X6jYKc6DjwrOkjQ
+UIRWbQQar0LwmNilehmt70g5DCL1SYm9q4LcgJJ2Nhxj0/5qqsYib50OSWMcKeEe
+iRXpXzv1ObpcQtI5ithp0gR53YPXBib80t3bUzomQ5UyZqAAHzMp3BKC54/vUrSK
+FeRaxDzNLrCeyI00+LHNUtwghAqHvdNcsIf8VRumK8oTm3RmDh0TyjASWYbrt9c8
+R1Um3zuoACOVy+mEIgIzsfHq0u7dwYwJB5+KeM7ZLx+HGIYdUYzHuUE1sLwVoELh
++SHIGHI1HDicOjzqgajShuIjj5hZTyQySVprrsLKiXS6NEwHAP20+XjayJ/R3tEA
+EQEAAYkCPgQYAQIBKAUCU5ygeQIbAsBdIAQZAQIABgUCU5ygeQAKCRCpVlnFZmhO
+52RJB/9uD1MSa0wjY6tHOIgquZcP3bHBvHmrHNMw9HR2wRCMO91ZkhrpdS3ZHtgb
+u3/55etj0FdvDo1tb8P8FGSVtO5Vcwf5APM8sbbqoi8L951Q3i7qt847lfhu6sMl
+w0LWFvPTOLHrliZHItPRjOltS1WAWfr2jUYhsU9ytaDAJmvf9DujxEOsN5G1YJep
+54JCKVCkM/y585Zcnn+yxk/XwqoNQ0/iJUT9qRrZWvoeasxhl1PQcwihCwss44A+
+YXaAt3hbk+6LEQuZoYS73yR3WHj+42tfm7YxRGeubXfgCEz/brETEWXMh4pe0vCL
+bfWrmfSPq2rDegYcAybxRQz0lF8PAAoJEO3UDQUIHpI/exkH/0vQfdHA8g/N4T6E
+i6b1CUVBAkvtdJpCATZjWPhXmShOw62gkDw306vHPilL4SCvEEi4KzG72zkp6VsB
+DSRcpxCwT4mHue+duiy53/aRMtSJ+vDfiV1Vhq+3sWAck/yUtfDU9/u4eFaiNok1
+8/Gd7reyuZt5CiJnpdPpjCwelK21l2w7sHAnJF55ITXdOxI8oG3BRKufz0z5lyDY
+s2tXYmhhQIggdgelN8LbcMhWs/PBbtUr6uZlNJG2lW1yscD4aI529VjwJlCeo745
+U7pO4eF05VViUJ2mmfoivL3tkhoTUWhx8xs8xCUcCg8DoEoSIhxtOmoTPR22Z9BL
+6LCg2mg=
+=Dhm4
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const goodCrossSignatureKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mI0EVUqeVwEEAMufHRrMPWK3gyvi0O0tABCs/oON9zV9KDZlr1a1M91ShCSFwCPo
+7r80PxdWVWcj0V5h50/CJYtpN3eE/mUIgW2z1uDYQF1OzrQ8ubrksfsJvpAhENom
+lTQEppv9mV8qhcM278teb7TX0pgrUHLYF5CfPdp1L957JLLXoQR/lwLVABEBAAG0
+E2dvb2Qtc2lnbmluZy1zdWJrZXmIuAQTAQIAIgUCVUqeVwIbAwYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQNRjL95IRWP69XQQAlH6+eyXJN4DZTLX78KGjHrsw
+6FCvxxClEPtPUjcJy/1KCRQmtLAt9PbbA78dvgzjDeZMZqRAwdjyJhjyg/fkU2OH
+7wq4ktjUu+dLcOBb+BFMEY+YjKZhf6EJuVfxoTVr5f82XNPbYHfTho9/OABKH6kv
+X70PaKZhbwnwij8Nts65AaIEVUqftREEAJ3WxZfqAX0bTDbQPf2CMT2IVMGDfhK7
+GyubOZgDFFjwUJQvHNvsrbeGLZ0xOBumLINyPO1amIfTgJNm1iiWFWfmnHReGcDl
+y5mpYG60Mb79Whdcer7CMm3AqYh/dW4g6IB02NwZMKoUHo3PXmFLxMKXnWyJ0clw
+R0LI/Qn509yXAKDh1SO20rqrBM+EAP2c5bfI98kyNwQAi3buu94qo3RR1ZbvfxgW
+CKXDVm6N99jdZGNK7FbRifXqzJJDLcXZKLnstnC4Sd3uyfyf1uFhmDLIQRryn5m+
+LBYHfDBPN3kdm7bsZDDq9GbTHiFZUfm/tChVKXWxkhpAmHhU/tH6GGzNSMXuIWSO
+aOz3Rqq0ED4NXyNKjdF9MiwD/i83S0ZBc0LmJYt4Z10jtH2B6tYdqnAK29uQaadx
+yZCX2scE09UIm32/w7pV77CKr1Cp/4OzAXS1tmFzQ+bX7DR+Gl8t4wxr57VeEMvl
+BGw4Vjh3X8//m3xynxycQU18Q1zJ6PkiMyPw2owZ/nss3hpSRKFJsxMLhW3fKmKr
+Ey2KiOcEGAECAAkFAlVKn7UCGwIAUgkQNRjL95IRWP5HIAQZEQIABgUCVUqftQAK
+CRD98VjDN10SqkWrAKDTpEY8D8HC02E/KVC5YUI01B30wgCgurpILm20kXEDCeHp
+C5pygfXw1DJrhAP+NyPJ4um/bU1I+rXaHHJYroYJs8YSweiNcwiHDQn0Engh/mVZ
+SqLHvbKh2dL/RXymC3+rjPvQf5cup9bPxNMa6WagdYBNAfzWGtkVISeaQW+cTEp/
+MtgVijRGXR/lGLGETPg2X3Afwn9N9bLMBkBprKgbBqU7lpaoPupxT61bL70=
+=vtbN
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const revokedUserIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2e
+DZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/
+uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBW
+ClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkx
+nmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJ
+x1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAG0I0dvbGFuZyBHb3BoZXIg
+PG5vLXJlcGx5QGdvbGFuZy5jb20+iQFUBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy
+9I6cUoMFAlsgO5ECGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
+1oFy9I6cUoMIkwf8DNPeD23i4jRwd/pylbvxwZintZl1fSwTJW1xcOa1emXaEtX2
+depuqhP04fjlRQGfsYAQh7X9jOJxAHjTmhqFBi5sD7QvKU00cPFYbJ/JTx0B41bl
+aXnSbGhRPh63QtEZL7ACAs+shwvvojJqysx7kyVRu0EW2wqjXdHwR/SJO6nhNBa2
+DXzSiOU/SUA42mmG+5kjF8Aabq9wPwT9wjraHShEweNerNMmOqJExBOy3yFeyDpa
+XwEZFzBfOKoxFNkIaVf5GSdIUGhFECkGvBMB935khftmgR8APxdU4BE7XrXexFJU
+8RCuPXonm4WQOwTWR0vQg64pb2WKAzZ8HhwTGbQiR29sYW5nIEdvcGhlciA8cmV2
+b2tlZEBnb2xhbmcuY29tPokBNgQwAQoAIBYhBOSJOSS3Dcepeq2X8NaBcvSOnFKD
+BQJbIDv3Ah0AAAoJENaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT6bC1JttG
+0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZq8KxHn/KvN6N
+s85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy+I0sGyI/Inro0Pzb
+tvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarYbYB2idtGRci4b9tObOK0
+BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8jSwEr2O2sUR0yjbgUAXbTxDVE
+/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3FazkkSYQD6b97+dkWwb1iWG5AQ0EWyA7
+kQEIALkg04REDZo1JgdYV4x8HJKFS4xAYWbIva1ZPqvDNmZRUbQZR2+gpJGEwn7z
+VofGvnOYiGW56AS5j31SFf5kro1+1bZQ5iOONBng08OOo58/l1hRseIIVGB5TGSa
+PCdChKKHreJI6hS3mShxH6hdfFtiZuB45rwoaArMMsYcjaezLwKeLc396cpUwwcZ
+snLUNd1Xu5EWEF2OdFkZ2a1qYdxBvAYdQf4+1Nr+NRIx1u1NS9c8jp3PuMOkrQEi
+bNtc1v6v0Jy52mKLG4y7mC/erIkvkQBYJdxPaP7LZVaPYc3/xskcyijrJ/5ufoD8
+K71/ShtsZUXSQn9jlRaYR0EbojMAEQEAAYkBPAQYAQoAJhYhBOSJOSS3Dcepeq2X
+8NaBcvSOnFKDBQJbIDuRAhsMBQkDwmcAAAoJENaBcvSOnFKDkFMIAIt64bVZ8x7+
+TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2NnDyf1cLOSimSTILpwLIuv9Uft5Pb
+OraQbYt3xi9yrqdKqGLv80bxqK0NuryNkvh9yyx5WoG1iKqMj9/FjGghuPrRaT4l
+QinNAghGVkEy1+aXGFrG2DsOC1FFI51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2V
+yJl9bD5R4SUNy8oQmhOxi+gbhD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+U
+heiQvzkApQup5c+BhH5zFDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB
+7qTZOahrETw=
+=IKnw
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const keyWithFirstUserIDRevoked = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: OpenPGP.js v4.10.10
+Comment: https://openpgpjs.org
+
+xsBNBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0q
+lX2eDZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN
+91KtLsz/uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xO
+XO3YtLdmJMBWClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBb
+naIYO6fXVXELUjkxnmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX
+8vY7vwC34pm22fAUVLCJx1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEB
+AAHNIkdvbGFuZyBHb3BoZXIgPHJldm9rZWRAZ29sYW5nLmNvbT7CwI0EMAEK
+ACAWIQTkiTkktw3HqXqtl/DWgXL0jpxSgwUCWyA79wIdAAAhCRDWgXL0jpxS
+gxYhBOSJOSS3Dcepeq2X8NaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT
+6bC1JttG0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZ
+q8KxHn/KvN6Ns85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy
++I0sGyI/Inro0Pzbtvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarY
+bYB2idtGRci4b9tObOK0BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8j
+SwEr2O2sUR0yjbgUAXbTxDVE/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3Fazk
+kSYQD6b97+dkWwb1iWHNI0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFu
+Zy5jb20+wsCrBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy9I6cUoMFAlsgO5EC
+GwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AAIQkQ1oFy9I6cUoMW
+IQTkiTkktw3HqXqtl/DWgXL0jpxSgwiTB/wM094PbeLiNHB3+nKVu/HBmKe1
+mXV9LBMlbXFw5rV6ZdoS1fZ16m6qE/Th+OVFAZ+xgBCHtf2M4nEAeNOaGoUG
+LmwPtC8pTTRw8Vhsn8lPHQHjVuVpedJsaFE+HrdC0RkvsAICz6yHC++iMmrK
+zHuTJVG7QRbbCqNd0fBH9Ik7qeE0FrYNfNKI5T9JQDjaaYb7mSMXwBpur3A/
+BP3COtodKETB416s0yY6okTEE7LfIV7IOlpfARkXMF84qjEU2QhpV/kZJ0hQ
+aEUQKQa8EwH3fmSF+2aBHwA/F1TgETtetd7EUlTxEK49eiebhZA7BNZHS9CD
+rilvZYoDNnweHBMZzsBNBFsgO5EBCAC5INOERA2aNSYHWFeMfByShUuMQGFm
+yL2tWT6rwzZmUVG0GUdvoKSRhMJ+81aHxr5zmIhluegEuY99UhX+ZK6NftW2
+UOYjjjQZ4NPDjqOfP5dYUbHiCFRgeUxkmjwnQoSih63iSOoUt5kocR+oXXxb
+YmbgeOa8KGgKzDLGHI2nsy8Cni3N/enKVMMHGbJy1DXdV7uRFhBdjnRZGdmt
+amHcQbwGHUH+PtTa/jUSMdbtTUvXPI6dz7jDpK0BImzbXNb+r9CcudpiixuM
+u5gv3qyJL5EAWCXcT2j+y2VWj2HN/8bJHMoo6yf+bn6A/Cu9f0obbGVF0kJ/
+Y5UWmEdBG6IzABEBAAHCwJMEGAEKACYWIQTkiTkktw3HqXqtl/DWgXL0jpxS
+gwUCWyA7kQIbDAUJA8JnAAAhCRDWgXL0jpxSgxYhBOSJOSS3Dcepeq2X8NaB
+cvSOnFKDkFMIAIt64bVZ8x7+TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2N
+nDyf1cLOSimSTILpwLIuv9Uft5PbOraQbYt3xi9yrqdKqGLv80bxqK0NuryN
+kvh9yyx5WoG1iKqMj9/FjGghuPrRaT4lQinNAghGVkEy1+aXGFrG2DsOC1FF
+I51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2VyJl9bD5R4SUNy8oQmhOxi+gb
+hD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+UheiQvzkApQup5c+BhH5z
+FDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB7qTZOahrETw=
+=+2T8
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const keyWithOnlyUserIDRevoked = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEYYwB7RYJKwYBBAHaRw8BAQdARimqhPPzyGAXmfQJjcqM1QVPzLtURJSzNVll
+JV4tEaW0KVJldm9rZWQgUHJpbWFyeSBVc2VyIElEIDxyZXZva2VkQGtleS5jb20+
+iHgEMBYIACAWIQSpyJZAXYqVEFkjyKutFcS0yeB0LQUCYYwCtgIdAAAKCRCtFcS0
+yeB0LbSsAQD8OYMaaBjrdzzpwIkP1stgmPd4/kzN/ZG28Ywl6a5F5QEA5Xg7aq4e
+/t6Fsb4F5iqB956kSPe6YJrikobD/tBbMwSIkAQTFggAOBYhBKnIlkBdipUQWSPI
+q60VxLTJ4HQtBQJhjAHtAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEK0V
+xLTJ4HQtBaoBAPZL7luTCji+Tqhn7XNfFE/0QIahCt8k9wfO1cGlB3inAQDf8Tzw
+ZGR5fNluUcNoVxQT7bUSFStbaGo3k0BaOYPbCLg4BGGMAe0SCisGAQQBl1UBBQEB
+B0DLwSpveSrbIO/IVZD13yrs1XuB3FURZUnafGrRq7+jUAMBCAeIeAQYFggAIBYh
+BKnIlkBdipUQWSPIq60VxLTJ4HQtBQJhjAHtAhsMAAoJEK0VxLTJ4HQtZ1oA/j9u
+8+p3xTNzsmabTL6BkNbMeB/RUKCrlm6woM6AV+vxAQCcXTn3JC2sNoNrLoXuVzaA
+mcG3/TwG5GSQUUPkrDsGDA==
+=mFWy
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const keyWithSubKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EWyKwKQEEALwXhKBnyaaNFeK3ljfc/qn9X/QFw+28EUfgZPHjRmHubuXLE2uR
+s3ZoSXY2z7Dkv+NyHYMt8p+X8q5fR7JvUjK2XbPyKoiJVnHINll83yl67DaWfKNL
+EjNoO0kIfbXfCkZ7EG6DL+iKtuxniGTcnGT47e+HJSqb/STpLMnWwXjBABEBAAG0
+I0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFuZy5jb20+iM4EEwEKADgWIQQ/
+lRafP/p9PytHbwxMvYJsOQdOOAUCWyKwKQIbAwULCQgHAwUVCgkICwUWAgMBAAIe
+AQIXgAAKCRBMvYJsOQdOOOsFBAC62mXww8XuqvYLcVOvHkWLT6mhxrQOJXnlfpn7
+2uBV9CMhoG/Ycd43NONsJrB95Apr9TDIqWnVszNbqPCuBhZQSGLdbiDKjxnCWBk0
+69qv4RNtkpOhYB7jK4s8F5oQZqId6JasT/PmJTH92mhBYhhTQr0GYFuPX2UJdkw9
+Sn9C67iNBFsisDUBBAC3A+Yo9lgCnxi/pfskyLrweYif6kIXWLAtLTsM6g/6jt7b
+wTrknuCPyTv0QKGXsAEe/cK/Xq3HvX9WfXPGIHc/X56ZIsHQ+RLowbZV/Lhok1IW
+FAuQm8axr/by80cRwFnzhfPc/ukkAq2Qyj4hLsGblu6mxeAhzcp8aqmWOO2H9QAR
+AQABiLYEKAEKACAWIQQ/lRafP/p9PytHbwxMvYJsOQdOOAUCWyK16gIdAAAKCRBM
+vYJsOQdOOB1vA/4u4uLONsE+2GVOyBsHyy7uTdkuxaR9b54A/cz6jT/tzUbeIzgx
+22neWhgvIEghnUZd0vEyK9k1wy5vbDlEo6nKzHso32N1QExGr5upRERAxweDxGOj
+7luDwNypI7QcifE64lS/JmlnunwRCdRWMKc0Fp+7jtRc5mpwyHN/Suf5RokBagQY
+AQoAIBYhBD+VFp8/+n0/K0dvDEy9gmw5B044BQJbIrA1AhsCAL8JEEy9gmw5B044
+tCAEGQEKAB0WIQSNdnkaWY6t62iX336UXbGvYdhXJwUCWyKwNQAKCRCUXbGvYdhX
+JxJSA/9fCPHP6sUtGF1o3G1a3yvOUDGr1JWcct9U+QpbCt1mZoNopCNDDQAJvDWl
+mvDgHfuogmgNJRjOMznvahbF+wpTXmB7LS0SK412gJzl1fFIpK4bgnhu0TwxNsO1
+8UkCZWqxRMgcNUn9z6XWONK8dgt5JNvHSHrwF4CxxwjL23AAtK+FA/UUoi3U4kbC
+0XnSr1Sl+mrzQi1+H7xyMe7zjqe+gGANtskqexHzwWPUJCPZ5qpIa2l8ghiUim6b
+4ymJ+N8/T8Yva1FaPEqfMzzqJr8McYFm0URioXJPvOAlRxdHPteZ0qUopt/Jawxl
+Xt6B9h1YpeLoJwjwsvbi98UTRs0jXwoY
+=3fWu
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const keyWithSubKeyAndBadSelfSigOrder = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EWyLLDQEEAOqIOpJ/ha1OYAGduu9tS3rBz5vyjbNgJO4sFveEM0mgsHQ0X9/L
+plonW+d0gRoO1dhJ8QICjDAc6+cna1DE3tEb5m6JtQ30teLZuqrR398Cf6w7NNVz
+r3lrlmnH9JaKRuXl7tZciwyovneBfZVCdtsRZjaLI1uMQCz/BToiYe3DABEBAAG0
+I0dvbGFuZyBHb3BoZXIgPG5vLXJlcGx5QGdvbGFuZy5jb20+iM4EEwEKADgWIQRZ
+sixZOfQcZdW0wUqmgmdsv1O9xgUCWyLLDQIbAwULCQgHAwUVCgkICwUWAgMBAAIe
+AQIXgAAKCRCmgmdsv1O9xql2A/4pix98NxjhdsXtazA9agpAKeADf9tG4Za27Gj+
+3DCww/E4iP2X35jZimSm/30QRB6j08uGCqd9vXkkJxtOt63y/IpVOtWX6vMWSTUm
+k8xKkaYMP0/IzKNJ1qC/qYEUYpwERBKg9Z+k99E2Ql4kRHdxXUHq6OzY79H18Y+s
+GdeM/riNBFsiyxsBBAC54Pxg/8ZWaZX1phGdwfe5mek27SOYpC0AxIDCSOdMeQ6G
+HPk38pywl1d+S+KmF/F4Tdi+kWro62O4eG2uc/T8JQuRDUhSjX0Qa51gPzJrUOVT
+CFyUkiZ/3ZDhtXkgfuso8ua2ChBgR9Ngr4v43tSqa9y6AK7v0qjxD1x+xMrjXQAR
+AQABiQFxBBgBCgAmAhsCFiEEWbIsWTn0HGXVtMFKpoJnbL9TvcYFAlsizTIFCQAN
+MRcAv7QgBBkBCgAdFiEEJcoVUVJIk5RWj1c/o62jUpRPICQFAlsiyxsACgkQo62j
+UpRPICQq5gQApoWIigZxXFoM0uw4uJBS5JFZtirTANvirZV5RhndwHeMN6JttaBS
+YnjyA4+n1D+zB2VqliD2QrsX12KJN6rGOehCtEIClQ1Hodo9nC6kMzzAwW1O8bZs
+nRJmXV+bsvD4sidLZLjdwOVa3Cxh6pvq4Uur6a7/UYx121hEY0Qx0s8JEKaCZ2y/
+U73GGi0D/i20VW8AWYAPACm2zMlzExKTOAV01YTQH/3vW0WLrOse53WcIVZga6es
+HuO4So0SOEAvxKMe5HpRIu2dJxTvd99Bo9xk9xJU0AoFrO0vNCRnL+5y68xMlODK
+lEw5/kl0jeaTBp6xX0HDQOEVOpPGUwWV4Ij2EnvfNDXaE1vK1kffiQFrBBgBCgAg
+AhsCFiEEWbIsWTn0HGXVtMFKpoJnbL9TvcYFAlsi0AYAv7QgBBkBCgAdFiEEJcoV
+UVJIk5RWj1c/o62jUpRPICQFAlsiyxsACgkQo62jUpRPICQq5gQApoWIigZxXFoM
+0uw4uJBS5JFZtirTANvirZV5RhndwHeMN6JttaBSYnjyA4+n1D+zB2VqliD2QrsX
+12KJN6rGOehCtEIClQ1Hodo9nC6kMzzAwW1O8bZsnRJmXV+bsvD4sidLZLjdwOVa
+3Cxh6pvq4Uur6a7/UYx121hEY0Qx0s8JEKaCZ2y/U73GRl0EAJokkXmy4zKDHWWi
+wvK9gi2gQgRkVnu2AiONxJb5vjeLhM/07BRmH6K1o+w3fOeEQp4FjXj1eQ5fPSM6
+Hhwx2CTl9SDnPSBMiKXsEFRkmwQ2AAsQZLmQZvKBkLZYeBiwf+IY621eYDhZfo+G
+1dh1WoUCyREZsJQg2YoIpWIcvw+a
+=bNRo
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const onlySubkeyNoPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1
+
+lQCVBFggvocBBAC7vBsHn7MKmS6IiiZNTXdciplVgS9cqVd+RTdIAoyNTcsiV1H0
+GQ3QtodOPeDlQDNoqinqaobd7R9g3m3hS53Nor7yBZkCWQ5x9v9JxRtoAq0sklh1
+I1X2zEqZk2l6YrfBF/64zWrhjnW3j23szkrAIVu0faQXbQ4z56tmZrw11wARAQAB
+/gdlAkdOVQG0CUdOVSBEdW1teYi4BBMBAgAiBQJYIL6HAhsDBgsJCAcDAgYVCAIJ
+CgsEFgIDAQIeAQIXgAAKCRCd1xxWp1CYAnjGA/9synn6ZXJUKAXQzySgmCZvCIbl
+rqBfEpxwLG4Q/lONhm5vthAE0z49I8hj5Gc5e2tLYUtq0o0OCRdCrYHa/efOYWpJ
+6RsK99bePOisVzmOABLIgZkcr022kHoMCmkPgv9CUGKP1yqbGl+zzAwQfUjRUmvD
+ZIcWLHi2ge4GzPMPi50B2ARYIL6cAQQAxWHnicKejAFcFcF1/3gUSgSH7eiwuBPX
+M7vDdgGzlve1o1jbV4tzrjN9jsCl6r0nJPDMfBSzgLr1auNTRG6HpJ4abcOx86ED
+Ad+avDcQPZb7z3dPhH/gb2lQejZsHh7bbeOS8WMSzHV3RqCLd8J/xwWPNR5zKn1f
+yp4IGfopidMAEQEAAQAD+wQOelnR82+dxyM2IFmZdOB9wSXQeCVOvxSaNMh6Y3lk
+UOOkO8Nlic4x0ungQRvjoRs4wBmCuwFK/MII6jKui0B7dn/NDf51i7rGdNGuJXDH
+e676By1sEY/NGkc74jr74T+5GWNU64W0vkpfgVmjSAzsUtpmhJMXsc7beBhJdnVl
+AgDKCb8hZqj1alcdmLoNvb7ibA3K/V8J462CPD7bMySPBa/uayoFhNxibpoXml2r
+oOtHa5izF3b0/9JY97F6rqkdAgD6GdTJ+xmlCoz1Sewoif1I6krq6xoa7gOYpIXo
+UL1Afr+LiJeyAnF/M34j/kjIVmPanZJjry0kkjHE5ILjH3uvAf4/6n9np+Th8ujS
+YDCIzKwR7639+H+qccOaddCep8Y6KGUMVdD/vTKEx1rMtK+hK/CDkkkxnFslifMJ
+kqoqv3WUqCWJAT0EGAECAAkFAlggvpwCGwIAqAkQndccVqdQmAKdIAQZAQIABgUC
+WCC+nAAKCRDmGUholQPwvQk+A/9latnSsR5s5/1A9TFki11GzSEnfLbx46FYOdkW
+n3YBxZoPQGxNA1vIn8GmouxZInw9CF4jdOJxEdzLlYQJ9YLTLtN5tQEMl/19/bR8
+/qLacAZ9IOezYRWxxZsyn6//jfl7A0Y+FV59d4YajKkEfItcIIlgVBSW6T+TNQT3
+R+EH5HJ/A/4/AN0CmBhhE2vGzTnVU0VPrE4V64pjn1rufFdclgpixNZCuuqpKpoE
+VVHn6mnBf4njKjZrAGPs5kfQ+H4NsM7v3Zz4yV6deu9FZc4O6E+V1WJ38rO8eBix
+7G2jko106CC6vtxsCPVIzY7aaG3H5pjRtomw+pX7SzrQ7FUg2PGumg==
+=F/T0
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const ecdsaPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+xaUEX1KsSRMIKoZIzj0DAQcCAwTpYqJsnJiFhKKh+8TulWD+lVmerBFNS+Ii
+B+nlG3T0xQQ4Sy5eIjJ0CExIQQzi3EElF/Z2l4F3WC5taFA11NgA/gkDCHSS
+PThf1M2K4LN8F1MRcvR+sb7i0nH55ojkwuVB1DE6jqIT9m9i+mX1tzjSAS+6
+lPQiweCJvG7xTC7Hs3AzRapf/r1At4TB+v+5G2/CKynNFEJpbGwgPGJpbGxA
+aG9tZS5jb20+wncEEBMIAB8FAl9SrEkGCwkHCAMCBBUICgIDFgIBAhkBAhsD
+Ah4BAAoJEMpwT3+q3+xqw5UBAMebZN9isEZ1ML+R/jWAAWMwa/knMugrEZ1v
+Bl9+ZwM0AQCZdf80/wYY4Nve01qSRFv8OmKswLli3TvDv6FKc4cLz8epBF9S
+rEkSCCqGSM49AwEHAgMEAjKnT9b5wY2bf9TpAV3d7OUfPOxKj9c4VzeVzSrH
+AtQgo/MuI1cdYVURicV4i76DNjFhQHQFTk7BrC+C2u1yqQMBCAf+CQMIHImA
+iYfzQtjgQWSFZYUkCFpbbwhNF0ch+3HNaZkaHCnZRIsWsRnc6FCb6lRQyK9+
+Dq59kHlduE5QgY40894jfmP2JdJHU6nBdYrivbEdbMJhBBgTCAAJBQJfUqxJ
+AhsMAAoJEMpwT3+q3+xqUI0BAMykhV08kQ4Ip9Qlbss6Jdufv7YrU0Vd5hou
+b5TmiPd0APoDBh3qIic+aLLUcAuG3+Gt1P1AbUlmqV61ozn1WfHxfw==
+=KLN8
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const dsaPrivateKeyWithElGamalSubkey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lQOBBF9/MLsRCACeaF6BI0jTgDAs86t8/kXPfwlPvR2MCYzB0BCqAdcq1hV/GTYd
+oNmJRna/ZJfsI/vf+d8Nv+EYOQkPheFS1MJVBitkAXjQPgm8i1tQWen1FCWZxqGk
+/vwZYF4yo8GhZ+Wxi3w09W9Cp9QM/CTmyE1Xe7wpPBGe+oD+me8Zxjyt8JBS4Qx+
+gvWbfHxfHnggh4pz7U8QkItlLsBNQEdX4R5+zwRN66g2ZSX/shaa/EkVnihUhD7r
+njP9I51ORWucTQD6OvgooaNQZCkQ/Se9TzdakwWKS2XSIFXiY/e2E5ZgKI/pfKDU
+iA/KessxddPb7nP/05OIJqg9AoDrD4vmehLzAQD+zsUS3LDU1m9/cG4LMsQbT2VK
+Te4HqbGIAle+eu/asQf8DDJMrbZpiJZvADum9j0TJ0oep6VdMbzo9RSDKvlLKT9m
+kG63H8oDWnCZm1a+HmGq9YIX+JHWmsLXXsFLeEouLzHO+mZo0X28eji3V2T87hyR
+MmUM0wFo4k7jK8uVmkDXv3XwNp2uByWxUKZd7EnWmcEZWqIiexJ7XpCS0Pg3tRaI
+zxve0SRe/dxfUPnTk/9KQ9hS6DWroBKquL182zx1Fggh4LIWWE2zq+UYn8BI0E8A
+rmIDFJdF8ymFQGRrEy6g79NnkPmkrZWsgMRYY65P6v4zLVmqohJKkpm3/Uxa6QAP
+CCoPh/JTOvPeCP2bOJH8z4Z9Py3ouMIjofQW8sXqRgf/RIHbh0KsINHrwwZ4gVIr
+MK3RofpaYxw1ztPIWb4cMWoWZHH1Pxh7ggTGSBpAhKXkiWw2Rxat8QF5aA7e962c
+bLvVv8dqsPrD/RnVJHag89cbPTzjn7gY9elE8EM8ithV3oQkwHTr4avYlpDZsgNd
+hUW3YgRwGo31tdzxoG04AcpV2t+07P8XMPr9hsfWs4rHohXPi38Hseu1Ji+dBoWQ
+3+1w/HH3o55s+jy4Ruaz78AIrjbmAJq+6rA2mIcCgrhw3DnzuwQAKeBvSeqn9zfS
+ZC812osMBVmkycwelpaIh64WZ0vWL3GvdXDctV2kXM+qVpDTLEny0LuiXxrwCKQL
+Ev4HAwK9uQBcreDEEud7pfRb8EYP5lzO2ZA7RaIvje6EWAGBvJGMRT0QQE5SGqc7
+Fw5geigBdt+vVyRuNNhg3c2fdn/OBQaYu0J/8AiOogG8EaM8tCFlbGdhbWFsQGRz
+YS5jb20gPGVsZ2FtYWxAZHNhLmNvbT6IkAQTEQgAOBYhBI+gnfiHQxB35/Dp0XAQ
+aE/rsWC5BQJffzC7AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEHAQaE/r
+sWC5A4EA/0GcJmyPtN+Klc7b9sVT3JgKTRnB/URxOJfYJofP0hZLAQCkqyMO+adV
+JvbgDH0zaITQWZSSXPqpgMpCA6juTrDsd50CawRffzC7EAgAxFFFSAAEQzWTgKU5
+EBtpxxoPzHqcChawTHRxHxjcELXzmUBS5PzfA1HXSPnNqK/x3Ut5ycC3CsW41Fnt
+Gm3706Wu9VFbFZVn55F9lPiplUo61n5pqMvOr1gmuQsdXiTa0t5FRa4TZ2VSiHFw
+vdAVSPTUsT4ZxJ1rPyFYRtq1n3pQcvdZowd07r0JnzTMjLLMFYCKhwIowoOC4zqJ
+iB8enjwOlpaqBATRm9xpVF7SJkroPF6/B1vdhj7E3c1aJyHlo0PYBAg756sSHWHg
+UuLyUQ4TA0hcCVenn/L/aSY2LnbdZB1EBhlYjA7dTCgwIqsQhfQmPkjz6g64A7+Y
+HbbrLwADBQgAk14QIEQ+J/VHetpQV/jt2pNsFK1kVK7mXK0spTExaC2yj2sXlHjL
+Ie3bO5T/KqmIaBEB5db5fA5xK9cZt79qrQHDKsEqUetUeMUWLBx77zBsus3grIgy
+bwDZKseRzQ715pwxquxQlScGoDIBKEh08HpwHkq140eIj3w+MAIfndaZaSCNaxaP
+Snky7BQmJ7Wc7qrIwoQP6yrnUqyW2yNi81nJYUhxjChqaFSlwzLs/iNGryBKo0ic
+BqVIRjikKHBlwBng6WyrltQo/Vt9GG8w+lqaAVXbJRlaBZJUR+2NKi/YhP3qQse3
+v8fi4kns0gh5LK+2C01RvdX4T49QSExuIf4HAwLJqYIGwadA2uem5v7/765ZtFWV
+oL0iZ0ueTJDby4wTFDpLVzzDi/uVcB0ZRFrGOp7w6OYcNYTtV8n3xmli2Q5Trw0c
+wZVzvg+ABKWiv7faBjMczIFF8y6WZKOIeAQYEQgAIBYhBI+gnfiHQxB35/Dp0XAQ
+aE/rsWC5BQJffzC7AhsMAAoJEHAQaE/rsWC5ZmIA/jhS4r4lClbvjuPWt0Yqdn7R
+fss2SPMYvMrrDh42aE0OAQD8xn4G6CN8UtW9xihXOY6FpxiJ/sMc2VaneeUd34oa
+4g==
+=XZm8
+-----END PGP PRIVATE KEY BLOCK-----`
+
+// https://tests.sequoia-pgp.org/#Certificate_expiration
+// P _ U p
+const expiringPrimaryUIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv
+/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz
+/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/
+5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3
+X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv
+9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0
+qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb
+SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb
+vLIwa3T4CyshfT0AEQEAAc0hQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w
+bGU+wsFcBBMBCgCQBYJhesp/BYkEWQPJBQsJCAcCCRD7/MgqAV5zMEcUAAAAAAAe
+ACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmeEOQlNyTLFkc9I/elp+BpY
+495V7KatqtDmsyDr+zDAdwYVCgkICwIEFgIDAQIXgAIbAwIeARYhBNGmbhojsYLJ
+mA94jPv8yCoBXnMwAABSCQv/av8hKyynMtXVKFuWOGJw0mR8auDm84WdhMFRZg8t
+yTJ1L88+Ny4WUAFeqo2j7DU2yPGrm5rmuvzlEedFYFeOWt+A4adz+oumgRd0nsgG
+Lf3QYUWQhLWVlz+H7zubgKqSB2A2RqV65S7mTTVro42nb2Mng6rvGWiqeKG5nrXN
+/01p1mIBQGR/KnZSqYLzA2Pw2PiJoSkXT26PDz/kiEMXpjKMR6sicV4bKVlEdUvm
+pIImIPBHZq1EsKXEyWtWC41w/pc+FofGE+uSFs2aef1vvEHFkj3BHSK8gRcH3kfR
+eFroTET8C2q9V1AOELWm+Ys6PzGzF72URK1MKXlThuL4t4LjvXWGNA78IKW+/RQH
+DzK4U0jqSO0mL6qxqVS5Ij6jjL6OTrVEGdtDf5n0vI8tcUTBKtVqYAYk+t2YGT05
+ayxALtb7viVKo8f10WEcCuKshn0gdsEFMRZQzJ89uQIY3R3FbsdRCaE6OEaDgKMQ
+UTFROyfhthgzRKbRxfcplMUCzsDNBF2lnPIBDADWML9cbGMrp12CtF9b2P6z9TTT
+74S8iyBOzaSvdGDQY/sUtZXRg21HWamXnn9sSXvIDEINOQ6A9QxdxoqWdCHrOuW3
+ofneYXoG+zeKc4dC86wa1TR2q9vW+RMXSO4uImA+Uzula/6k1DogDf28qhCxMwG/
+i/m9g1c/0aApuDyKdQ1PXsHHNlgd/Dn6rrd5y2AObaifV7wIhEJnvqgFXDN2RXGj
+LeCOHV4Q2WTYPg/S4k1nMXVDwZXrvIsA0YwIMgIT86Rafp1qKlgPNbiIlC1g9RY/
+iFaGN2b4Ir6GDohBQSfZW2+LXoPZuVE/wGlQ01rh827KVZW4lXvqsge+wtnWlszc
+selGATyzqOK9LdHPdZGzROZYI2e8c+paLNDdVPL6vdRBUnkCaEkOtl1mr2JpQi5n
+TU+gTX4IeInC7E+1a9UDF/Y85ybUz8XV8rUnR76UqVC7KidNepdHbZjjXCt8/Zo+
+Tec9JNbYNQB/e9ExmDntmlHEsSEQzFwzj8sxH48AEQEAAcLA9gQYAQoAIBYhBNGm
+bhojsYLJmA94jPv8yCoBXnMwBQJdpZzyAhsMAAoJEPv8yCoBXnMw6f8L/26C34dk
+jBffTzMj5Bdzm8MtF67OYneJ4TQMw7+41IL4rVcSKhIhk/3Ud5knaRtP2ef1+5F6
+6h9/RPQOJ5+tvBwhBAcUWSupKnUrdVaZQanYmtSxcVV2PL9+QEiNN3tzluhaWO//
+rACxJ+K/ZXQlIzwQVTpNhfGzAaMVV9zpf3u0k14itcv6alKY8+rLZvO1wIIeRZLm
+U0tZDD5HtWDvUV7rIFI1WuoLb+KZgbYn3OWjCPHVdTrdZ2CqnZbG3SXw6awH9bzR
+LV9EXkbhIMez0deCVdeo+wFFklh8/5VK2b0vk/+wqMJxfpa1lHvJLobzOP9fvrsw
+sr92MA2+k901WeISR7qEzcI0Fdg8AyFAExaEK6VyjP7SXGLwvfisw34OxuZr3qmx
+1Sufu4toH3XrB7QJN8XyqqbsGxUCBqWif9RSK4xjzRTe56iPeiSJJOIciMP9i2ld
+I+KgLycyeDvGoBj0HCLO3gVaBe4ubVrj5KjhX2PVNEJd3XZRzaXZE2aAMQ==
+=AmgT
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const rsa2048PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: gpg (GnuPG) 2.2.27 with libgcrypt 1.9.4
+
+lQPGBGL07P0BCADL0etN8efyAXA6sL2WfQvHe5wEKYXPWeN2+jiqSppfeRZAOlzP
+kZ3U+cloeJriplYvVJwI3ID2aw52Z/TRn8iKRP5eOUFrEgcgl06lazLtOndK7o7p
+oBV5mLtHEirFHm6W61fNt10jzM0jx0PV6nseLhFB2J42F1cmU/aBgFo41wjLSZYr
+owR+v+O9S5sUXblQF6sEDcY01sBEu09zrIgT49VFwQ1Cvdh9XZEOTQBfdiugoj5a
+DS3fAqAka3r1VoQK4eR7/upnYSgSACGeaQ4pUelKku5rpm50gdWTY8ppq0k9e1eT
+y2x0OQcW3hWE+j4os1ca0ZEADMdqr/99MOxrABEBAAH+BwMCJWxU4VOZOJ7/I6vX
+FxdfBhIBEXlJ52FM3S/oYtXqLhkGyrtmZOeEazVvUtuCe3M3ScHI8xCthcmE8E0j
+bi+ZEHPS2NiBZtgHFF27BLn7zZuTc+oD5WKduZdK3463egnyThTqIIMl25WZBuab
+k5ycwYrWwBH0jfA4gwJ13ai4pufKC2RM8qIu6YAVPglYBKFLKGvvJHa5vI+LuA0E
+K+k35hIic7yVUcQneNnAF2598X5yWiieYnOZpmHlRw1zfbMwOJr3ZNj2v94u7b+L
+sTa/1Uv9887Vb6sJp0c2Sh4cwEccoPYkvMqFn3ZrJUr3UdDu1K2vWohPtswzhrYV
++RdPZE5RLoCQufKvlPezk0Pzhzb3bBU7XjUbdGY1nH/EyQeBNp+Gw6qldKvzcBaB
+cyOK1c6hPSszpJX93m5UxCN55IeifmcNjmbDh8vGCCdajy6d56qV2n4F3k7vt1J1
+0UlxIGhqijJoaTCX66xjLMC6VXkSz6aHQ35rnXosm/cqPcQshsZTdlfSyWkorfdr
+4Hj8viBER26mjYurTMLBKDtUN724ZrR0Ev5jorX9uoKlgl87bDZHty2Ku2S+vR68
+VAvnj6Fi1BYNclnDoqxdRB2z5T9JbWE52HuG83/QsplhEqXxESDxriTyTHMbNxEe
+88soVCDh4tgflZFa2ucUr6gEKJKij7jgahARnyaXfPZlQBUAS1YUeILYmN+VR+M/
+sHENpwDWc7TInn8VN638nJV+ScZGMih3AwWZTIoiLju3MMt1K0YZ3NuiqwGH4Jwg
+/BbEdTWeCci9y3NEQHQ3uZZ5p6j2CwFVlK11idemCMvAiTVxF+gKdaLMkeCwKxru
+J3YzhKEo+iDVYbPYBYizx/EHBn2U5kITQ5SBXzjTaaFMNZJEf9JYsL1ybPB6HOFY
+VNVB2KT8CGVwtCJHb2xhbmcgR29waGVyIDxnb2xhbmdAZXhhbXBsZS5vcmc+iQFO
+BBMBCgA4FiEEC6K7U7f4qesybTnqSkra7gHusm0FAmL07P0CGwMFCwkIBwIGFQoJ
+CAsCBBYCAwECHgECF4AACgkQSkra7gHusm1MvwgAxpClWkeSqIhMQfbiuz0+lOkE
+89y1DCFw8bHjZoUf4/4K8hFA3dGkk+q72XFgiyaCpfXxMt6Gi+dN47t+tTv9NIqC
+sukbaoJBmJDhN6+djmJOgOYy+FWsW2LAk2LOwKYulpnBZdcA5rlMAhBg7gevQpF+
+ruSU69P7UUaFJl/DC7hDmaIcj+4cjBE/HO26SnVQjoTfjZT82rDh1Wsuf8LnkJUk
+b3wezBLpXKjDvdHikdv4gdlR4AputVM38aZntYYglh/EASo5TneyZ7ZscdLNRdcF
+r5O2fKqrOJLOdaoYRFZZWOvP5GtEVFDU7WGivOSVfiszBE0wZR3dgZRJipHCXJ0D
+xgRi9Oz9AQgAtMJcJqLLVANJHl90tWuoizDkm+Imcwq2ubQAjpclnNrODnDK+7o4
+pBsWmXbZSdkC4gY+LhOQA6bPDD0JEHM58DOnrm49BddxXAyK0HPsk4sGGt2SS86B
+OawWNdfJVyqw4bAiHWDmQg4PcjBbt3ocOIxAR6I5kBSiQVxuGQs9T+Zvg3G1r3Or
+fS6DzlgY3HFUML5YsGH4lOxNSOoKAP68GIH/WNdUZ+feiRg9knIib6I3Hgtf5eO8
+JRH7aWE/TD7eNu36bLLjT5TZPq5r6xaD2plbtPOyXbNPWs9qI1yG+VnErfaLY0w8
+Qo0aqzbgID+CTZVomXSOpOcQseaFKw8ZfQARAQAB/gcDArha6+/+d4OY/w9N32K9
+hFNYt4LufTETMQ+k/sBeaMuAVzmT47DlAXzkrZhGW4dZOtXMu1rXaUwHlqkhEyzL
+L4MYEWVXfD+LbZNEK3MEFss6RK+UAMeT/PTV9aA8cXQVPcSJYzfBXHQ1U1hnOgrO
+apn92MN8RmkhX8wJLyeWTMMuP4lXByJMmmGo8WvifeRD2kFY4y0WVBDAXJAV4Ljf
+Di/bBiwoc5a+gxHuZT2W9ZSxBQJNXdt4Un2IlyZuo58s5MLx2N0EaNJ8PwRUE6fM
+RZYO8aZCEPUtINE4njbvsWOMCtrblsMPwZ1B0SiIaWmLaNyGdCNKea+fCIW7kasC
+JYMhnLumpUTXg5HNexkCsl7ABWj0PYBflOE61h8EjWpnQ7JBBVKS2ua4lMjwHRX7
+5o5yxym9k5UZNFdGoXVL7xpizCcdGawxTJvwhs3vBqu1ZWYCegOAZWDrOkCyhUpq
+8uKMROZFbn+FwE+7tjt+v2ed62FVEvD6g4V3ThCA6mQqeOARfJWN8GZY8BDm8lht
+crOXriUkrx+FlrgGtm2CkwjW5/9Xd7AhFpHnQdFeozOHyq1asNSgJF9sNi9Lz94W
+skQSVRi0IExxSXYGI3Y0nnAZUe2BAQflYPJdEveSr3sKlUqXiETTA1VXsTPK3kOC
+92CbLzj/Hz199jZvywwyu53I+GKMpF42rMq7zxr2oa61YWY4YE/GDezwwys/wLx/
+QpCW4X3ppI7wJjCSSqEV0baYZSSli1ayheS6dxi8QnSpX1Bmpz6gU7m/M9Sns+hl
+J7ZvgpjCAiV7KJTjtclr5/S02zP78LTVkoTWoz/6MOTROwaP63VBUXX8pbJhf/vu
+DLmNnDk8joMJxoDXWeNU0EnNl4hP7Z/jExRBOEO4oAnUf/Sf6gCWQhL5qcajtg6w
+tGv7vx3f2IkBNgQYAQoAIBYhBAuiu1O3+KnrMm056kpK2u4B7rJtBQJi9Oz9AhsM
+AAoJEEpK2u4B7rJt6lgIAMBWqP4BCOGnQXBbgJ0+ACVghpkFUXZTb/tXJc8UUvTM
+8uov6k/RsqDGZrvhhufD7Wwt7j9v7dD7VPp7bPyjVWyimglQzWguTUUqLDGlstYH
+5uYv1pzma0ZsAGNqFeGlTLsKOSGKFMH4rB2KfN2n51L8POvtp1y7GKZQbWIWneaB
+cZr3BINU5GMvYYU7pAYcoR+mJPdJx5Up3Ocn+bn8Tu1sy9C/ArtCQucazGnoE9u1
+HhNLrh0CdzzX7TNH6TQ8LwPOvq0K5l/WqbN9lE0WBBhMv2HydxhluO8AhU+A5GqC
+C+wET7nVDnhoOm/fstIeb7/LN7OYejKPeHdFBJEL9GA=
+=u442
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const curve25519PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: gpg (GnuPG) 2.2.27 with libgcrypt 1.9.4
+
+lFgEYvTtQBYJKwYBBAHaRw8BAQdAxsNXLbrk5xOjpO24VhOMvQ0/F+JcyIkckMDH
+X3FIGxcAAQDFOlunZWYuPsCx5JLp78vKqUTfgef9TGG4oD6I/Sa0zBMstCJHb2xh
+bmcgR29waGVyIDxnb2xhbmdAZXhhbXBsZS5vcmc+iJAEExYIADgWIQSFQHEOazmo
+h1ldII4MvfnLQ4JBNwUCYvTtQAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK
+CRAMvfnLQ4JBN5yeAQCKdry8B5ScCPrev2+UByMCss7Sdu5RhomCFsHdNPLcKAEA
+8ugei+1owHsV+3cGwWWzKk6sLa8ZN87i3SKuOGp9DQycXQRi9O1AEgorBgEEAZdV
+AQUBAQdA5CubPp8l7lrVQ25h7Hx5XN2C8xanRnnpcjzEooCaEA0DAQgHAAD/Rpc+
+sOZUXrFk9HOWB1XU41LoWbDBoG8sP8RWAVYwD5AQRYh4BBgWCAAgFiEEhUBxDms5
+qIdZXSCODL35y0OCQTcFAmL07UACGwwACgkQDL35y0OCQTcvdwEA7lb5g/YisrEf
+iq660uwMGoepLUfvtqKzuQ6heYe83y0BAN65Ffg5HYOJzUEi0kZQRf7OhdtuL2kJ
+SRXn8DmCTfEB
+=cELM
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const curve448PrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: C1DB 65D5 80D7 B922 7254 4B1E A699 9895 FABA CE52
+
+xYUEYV2UmRYDK2VxAc9AFyxgh5xnSbyt50TWl558mw9xdMN+/UBLr5+UMP8IsrvV
+MdXuTIE8CyaUQKSotHtH2RkYEXj5nsMAAAHPQIbTMSzjIWug8UFECzAex5FHgAgH
+gYF3RK+TS8D24wX8kOu2C/NoVxwGY+p+i0JHaB+7yljriSKAGxs6wsBEBB8WCgCD
+BYJhXZSZBYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlv
+bnMuc2VxdW9pYS1wZ3Aub3Jn5wSpIutJ5HncJWk4ruUV8GzQF390rR5+qWEAnAoY
+akcDFQoIApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAALzdA5dA/fsgYg/J
+qaQriYKaPUkyHL7EB3BXhV2d1h/gk+qJLvXQuU2WEJ/XSs3GrsBRiiZwvPH4o+7b
+mleAxjy5wpS523vqrrBR2YZ5FwIku7WS4litSdn4AtVam/TlLdMNIf41CtFeZKBe
+c5R5VNdQy8y7qy8AAADNEUN1cnZlNDQ4IE9wdGlvbiA4wsBHBBMWCgCGBYJhXZSZ
+BYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2Vx
+dW9pYS1wZ3Aub3JnD55UsYMzE6OACP+mgw5zvT+BBgol8/uFQjHg4krjUCMDFQoI
+ApkBApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAPQJA5dA0Xqwzn/0uwCq
+RlsOVCB3f5NOj1exKnlBvRw0xT1VBee1yxvlUt5eIAoCxWoRlWBJob3TTkhm9AEA
+8dyhwPmyGfWHzPw5NFG3xsXrZdNXNvit9WMVAPcmsyR7teXuDlJItxRAdJJc/qfJ
+YVbBFoaNrhYAAADHhQRhXZSZFgMrZXEBz0BL7THZ9MnCLfSPJ1FMLim9eGkQ3Bfn
+M3he5rOwO3t14QI1LjI96OjkeJipMgcFAmEP1Bq/ZHGO7oAAAc9AFnE8iNBaT3OU
+EFtxkmWHXtdaYMmGGRdopw9JPXr/UxuunDln5o9dxPxf7q7z26zXrZen+qed/Isa
+HsDCwSwEGBYKAWsFgmFdlJkFiQWkj70JEKaZmJX6us5SRxQAAAAAAB4AIHNhbHRA
+bm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZxREUizdTcepBzgSMOv2VWQCWbl++3CZ
+EbgAWDryvSsyApsCwDGgBBkWCgBvBYJhXZSZCRBKo3SL4S5djkcUAAAAAAAeACBz
+YWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmemoGTDjmNQiIzw6HOEddvS0OB7
+UZ/P07jM/EVmnYxTlBYhBAxsnkGpx1UCiH6gUUqjdIvhLl2OAAALYQOXQAMB1oKq
+OWxSFmvmgCKNcbAAyA3piF5ERIqs4z07oJvqDYrOWt75UsEIH/04gU/vHc4EmfG2
+JDLJgOLlyTUPkL/08f0ydGZPofFQBhn8HkuFFjnNtJ5oz3GIP4cdWMQFaUw0uvjb
+PM9Tm3ptENGd6Ts1AAAAFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAGpTA5dATR6i
+U2GrpUcQgpG+JqfAsGmF4yAOhgFxc1UfidFk3nTup3fLgjipkYY170WLRNbyKkVO
+Sodx93GAs58rizO1acDAWiLq3cyEPBFXbyFThbcNPcLl+/77Uk/mgkYrPQFAQWdK
+1kSRm4SizDBK37K8ChAAAADHhwRhXZSZEgMrZW8Bx0DMhzvhQo+OsXeqQ6QVw4sF
+CaexHh6rLohh7TzL3hQSjoJ27fV6JBkIWdn0LfrMlJIDbSv2SLdlgQMBCgkAAcdA
+MO7Dc1myF6Co1fAH+EuP+OxhxP/7V6ljuSCZENDfA49tQkzTta+PniG+pOVB2LHb
+huyaKBkqiaogo8LAOQQYFgoAeAWCYV2UmQWJBaSPvQkQppmYlfq6zlJHFAAAAAAA
+HgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnEjBMQAmc/2u45u5FQGmB
+QAytjSG2LM3JQN+PPVl5vEkCmwwWIQTB22XVgNe5InJUSx6mmZiV+rrOUgAASdYD
+l0DXEHQ9ykNP2rZP35ET1dmiFagFtTj/hLQcWlg16LqvJNGqOgYXuqTerbiOOt02
+XLCBln+wdewpU4ChEffMUDRBfqfQco/YsMqWV7bHJHAO0eC/DMKCjyU90xdH7R/d
+QgqsfguR1PqPuJxpXV4bSr6CGAAAAA==
+=MSvh
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const keyWithNotation = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+xVgEY9gIshYJKwYBBAHaRw8BAQdAF25fSM8OpFlXZhop4Qpqo5ywGZ4jgWlR
+ppjhIKDthREAAQC+LFpzFcMJYcjxGKzBGHN0Px2jU4d04YSRnFAik+lVVQ6u
+zRdUZXN0IDx0ZXN0QGV4YW1wbGUuY29tPsLACgQQFgoAfAUCY9gIsgQLCQcI
+CRD/utJOCym8pR0UgAAAAAAQAAR0ZXh0QGV4YW1wbGUuY29tdGVzdB8UAAAA
+AAASAARiaW5hcnlAZXhhbXBsZS5jb20AAQIDAxUICgQWAAIBAhkBAhsDAh4B
+FiEEEMCQTUVGKgCX5rDQ/7rSTgspvKUAAPl5AP9Npz90LxzrB97Qr2DrGwfG
+wuYn4FSYwtuPfZHHeoIabwD/QEbvpQJ/NBb9EAZuow4Rirlt1yv19mmnF+j5
+8yUzhQjHXQRj2AiyEgorBgEEAZdVAQUBAQdARXAo30DmKcyUg6co7OUm0RNT
+z9iqFbDBzA8A47JEt1MDAQgHAAD/XKK3lBm0SqMR558HLWdBrNG6NqKuqb5X
+joCML987ZNgRD8J4BBgWCAAqBQJj2AiyCRD/utJOCym8pQIbDBYhBBDAkE1F
+RioAl+aw0P+60k4LKbylAADRxgEAg7UfBDiDPp5LHcW9D+SgFHk6+GyEU4ev
+VppQxdtxPvAA/34snHBX7Twnip1nMt7P4e2hDiw/hwQ7oqioOvc6jMkP
+=Z8YJ
+-----END PGP PRIVATE KEY BLOCK-----
+`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
new file mode 100644
index 0000000..fec41a0
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
@@ -0,0 +1,67 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import "math/bits"
+
+// CipherSuite contains a combination of Cipher and Mode
+type CipherSuite struct {
+ // The cipher function
+ Cipher CipherFunction
+ // The AEAD mode of operation.
+ Mode AEADMode
+}
+
+// AEADConfig collects a number of AEAD parameters along with sensible defaults.
+// A nil AEADConfig is valid and results in all default values.
+type AEADConfig struct {
+ // The AEAD mode of operation.
+ DefaultMode AEADMode
+ // Amount of octets in each chunk of data
+ ChunkSize uint64
+}
+
+// Mode returns the AEAD mode of operation.
+func (conf *AEADConfig) Mode() AEADMode {
+ // If no preference is specified, OCB is used (which is mandatory to implement).
+ if conf == nil || conf.DefaultMode == 0 {
+ return AEADModeOCB
+ }
+
+ mode := conf.DefaultMode
+ if mode != AEADModeEAX && mode != AEADModeOCB && mode != AEADModeGCM {
+ panic("AEAD mode unsupported")
+ }
+ return mode
+}
+
+// ChunkSizeByte returns the byte indicating the chunk size. The effective
+// chunk size is computed with the formula uint64(1) << (chunkSizeByte + 6)
+// limit to 16 = 4 MiB
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (conf *AEADConfig) ChunkSizeByte() byte {
+ if conf == nil || conf.ChunkSize == 0 {
+ return 12 // 1 << (12 + 6) == 262144 bytes
+ }
+
+ chunkSize := conf.ChunkSize
+ exponent := bits.Len64(chunkSize) - 1
+ switch {
+ case exponent < 6:
+ exponent = 6
+ case exponent > 16:
+ exponent = 16
+ }
+
+ return byte(exponent - 6)
+}
+
+// decodeAEADChunkSize returns the effective chunk size. In 32-bit systems, the
+// maximum returned value is 1 << 30.
+func decodeAEADChunkSize(c byte) int {
+ size := uint64(1 << (c + 6))
+ if size != uint64(int(size)) {
+ return 1 << 30
+ }
+ return int(size)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go
new file mode 100644
index 0000000..cee83bd
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_crypter.go
@@ -0,0 +1,264 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "encoding/binary"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// aeadCrypter is an AEAD opener/sealer, its configuration, and data for en/decryption.
+type aeadCrypter struct {
+ aead cipher.AEAD
+ chunkSize int
+ initialNonce []byte
+ associatedData []byte // Chunk-independent associated data
+ chunkIndex []byte // Chunk counter
+ packetTag packetType // SEIP packet (v2) or AEAD Encrypted Data packet
+ bytesProcessed int // Amount of plaintext bytes encrypted/decrypted
+ buffer bytes.Buffer // Buffered bytes across chunks
+}
+
+// computeNonce takes the incremental index and computes an eXclusive OR with
+// the least significant 8 bytes of the receivers' initial nonce (see sec.
+// 5.16.1 and 5.16.2). It returns the resulting nonce.
+func (wo *aeadCrypter) computeNextNonce() (nonce []byte) {
+ if wo.packetTag == packetTypeSymmetricallyEncryptedIntegrityProtected {
+ return append(wo.initialNonce, wo.chunkIndex...)
+ }
+
+ nonce = make([]byte, len(wo.initialNonce))
+ copy(nonce, wo.initialNonce)
+ offset := len(wo.initialNonce) - 8
+ for i := 0; i < 8; i++ {
+ nonce[i+offset] ^= wo.chunkIndex[i]
+ }
+ return
+}
+
+// incrementIndex performs an integer increment by 1 of the integer represented by the
+// slice, modifying it accordingly.
+func (wo *aeadCrypter) incrementIndex() error {
+ index := wo.chunkIndex
+ if len(index) == 0 {
+ return errors.AEADError("Index has length 0")
+ }
+ for i := len(index) - 1; i >= 0; i-- {
+ if index[i] < 255 {
+ index[i]++
+ return nil
+ }
+ index[i] = 0
+ }
+ return errors.AEADError("cannot further increment index")
+}
+
+// aeadDecrypter reads and decrypts bytes. It buffers extra decrypted bytes when
+// necessary, similar to aeadEncrypter.
+type aeadDecrypter struct {
+ aeadCrypter // Embedded ciphertext opener
+ reader io.Reader // 'reader' is a partialLengthReader
+ peekedBytes []byte // Used to detect last chunk
+ eof bool
+}
+
+// Read decrypts bytes and reads them into dst. It decrypts when necessary and
+// buffers extra decrypted bytes. It returns the number of bytes copied into dst
+// and an error.
+func (ar *aeadDecrypter) Read(dst []byte) (n int, err error) {
+ // Return buffered plaintext bytes from previous calls
+ if ar.buffer.Len() > 0 {
+ return ar.buffer.Read(dst)
+ }
+
+ // Return EOF if we've previously validated the final tag
+ if ar.eof {
+ return 0, io.EOF
+ }
+
+ // Read a chunk
+ tagLen := ar.aead.Overhead()
+ cipherChunkBuf := new(bytes.Buffer)
+ _, errRead := io.CopyN(cipherChunkBuf, ar.reader, int64(ar.chunkSize+tagLen))
+ cipherChunk := cipherChunkBuf.Bytes()
+ if errRead != nil && errRead != io.EOF {
+ return 0, errRead
+ }
+ decrypted, errChunk := ar.openChunk(cipherChunk)
+ if errChunk != nil {
+ return 0, errChunk
+ }
+
+ // Return decrypted bytes, buffering if necessary
+ if len(dst) < len(decrypted) {
+ n = copy(dst, decrypted[:len(dst)])
+ ar.buffer.Write(decrypted[len(dst):])
+ } else {
+ n = copy(dst, decrypted)
+ }
+
+ // Check final authentication tag
+ if errRead == io.EOF {
+ errChunk := ar.validateFinalTag(ar.peekedBytes)
+ if errChunk != nil {
+ return n, errChunk
+ }
+ ar.eof = true // Mark EOF for when we've returned all buffered data
+ }
+ return
+}
+
+// Close is noOp. The final authentication tag of the stream was already
+// checked in the last Read call. In the future, this function could be used to
+// wipe the reader and peeked, decrypted bytes, if necessary.
+func (ar *aeadDecrypter) Close() (err error) {
+ return nil
+}
+
+// openChunk decrypts and checks integrity of an encrypted chunk, returning
+// the underlying plaintext and an error. It accesses peeked bytes from next
+// chunk, to identify the last chunk and decrypt/validate accordingly.
+func (ar *aeadDecrypter) openChunk(data []byte) ([]byte, error) {
+ tagLen := ar.aead.Overhead()
+ // Restore carried bytes from last call
+ chunkExtra := append(ar.peekedBytes, data...)
+ // 'chunk' contains encrypted bytes, followed by an authentication tag.
+ chunk := chunkExtra[:len(chunkExtra)-tagLen]
+ ar.peekedBytes = chunkExtra[len(chunkExtra)-tagLen:]
+
+ adata := ar.associatedData
+ if ar.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ adata = append(ar.associatedData, ar.chunkIndex...)
+ }
+
+ nonce := ar.computeNextNonce()
+ plainChunk, err := ar.aead.Open(nil, nonce, chunk, adata)
+ if err != nil {
+ return nil, err
+ }
+ ar.bytesProcessed += len(plainChunk)
+ if err = ar.aeadCrypter.incrementIndex(); err != nil {
+ return nil, err
+ }
+ return plainChunk, nil
+}
+
+// Checks the summary tag. It takes into account the total decrypted bytes into
+// the associated data. It returns an error, or nil if the tag is valid.
+func (ar *aeadDecrypter) validateFinalTag(tag []byte) error {
+ // Associated: tag, version, cipher, aead, chunk size, ...
+ amountBytes := make([]byte, 8)
+ binary.BigEndian.PutUint64(amountBytes, uint64(ar.bytesProcessed))
+
+ adata := ar.associatedData
+ if ar.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ // ... index ...
+ adata = append(ar.associatedData, ar.chunkIndex...)
+ }
+
+ // ... and total number of encrypted octets
+ adata = append(adata, amountBytes...)
+ nonce := ar.computeNextNonce()
+ _, err := ar.aead.Open(nil, nonce, tag, adata)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// aeadEncrypter encrypts and writes bytes. It encrypts when necessary according
+// to the AEAD block size, and buffers the extra encrypted bytes for next write.
+type aeadEncrypter struct {
+ aeadCrypter // Embedded plaintext sealer
+ writer io.WriteCloser // 'writer' is a partialLengthWriter
+}
+
+// Write encrypts and writes bytes. It encrypts when necessary and buffers extra
+// plaintext bytes for next call. When the stream is finished, Close() MUST be
+// called to append the final tag.
+func (aw *aeadEncrypter) Write(plaintextBytes []byte) (n int, err error) {
+ // Append plaintextBytes to existing buffered bytes
+ n, err = aw.buffer.Write(plaintextBytes)
+ if err != nil {
+ return n, err
+ }
+ // Encrypt and write chunks
+ for aw.buffer.Len() >= aw.chunkSize {
+ plainChunk := aw.buffer.Next(aw.chunkSize)
+ encryptedChunk, err := aw.sealChunk(plainChunk)
+ if err != nil {
+ return n, err
+ }
+ _, err = aw.writer.Write(encryptedChunk)
+ if err != nil {
+ return n, err
+ }
+ }
+ return
+}
+
+// Close encrypts and writes the remaining buffered plaintext if any, appends
+// the final authentication tag, and closes the embedded writer. This function
+// MUST be called at the end of a stream.
+func (aw *aeadEncrypter) Close() (err error) {
+ // Encrypt and write a chunk if there's buffered data left, or if we haven't
+ // written any chunks yet.
+ if aw.buffer.Len() > 0 || aw.bytesProcessed == 0 {
+ plainChunk := aw.buffer.Bytes()
+ lastEncryptedChunk, err := aw.sealChunk(plainChunk)
+ if err != nil {
+ return err
+ }
+ _, err = aw.writer.Write(lastEncryptedChunk)
+ if err != nil {
+ return err
+ }
+ }
+ // Compute final tag (associated data: packet tag, version, cipher, aead,
+ // chunk size...
+ adata := aw.associatedData
+
+ if aw.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ // ... index ...
+ adata = append(aw.associatedData, aw.chunkIndex...)
+ }
+
+ // ... and total number of encrypted octets
+ amountBytes := make([]byte, 8)
+ binary.BigEndian.PutUint64(amountBytes, uint64(aw.bytesProcessed))
+ adata = append(adata, amountBytes...)
+
+ nonce := aw.computeNextNonce()
+ finalTag := aw.aead.Seal(nil, nonce, nil, adata)
+ _, err = aw.writer.Write(finalTag)
+ if err != nil {
+ return err
+ }
+ return aw.writer.Close()
+}
+
+// sealChunk Encrypts and authenticates the given chunk.
+func (aw *aeadEncrypter) sealChunk(data []byte) ([]byte, error) {
+ if len(data) > aw.chunkSize {
+ return nil, errors.AEADError("chunk exceeds maximum length")
+ }
+ if aw.associatedData == nil {
+ return nil, errors.AEADError("can't seal without headers")
+ }
+ adata := aw.associatedData
+ if aw.aeadCrypter.packetTag == packetTypeAEADEncrypted {
+ adata = append(aw.associatedData, aw.chunkIndex...)
+ }
+
+ nonce := aw.computeNextNonce()
+ encrypted := aw.aead.Seal(nil, nonce, data, adata)
+ aw.bytesProcessed += len(data)
+ if err := aw.aeadCrypter.incrementIndex(); err != nil {
+ return nil, err
+ }
+ return encrypted, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go
new file mode 100644
index 0000000..98bd876
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_encrypted.go
@@ -0,0 +1,96 @@
+// Copyright (C) 2019 ProtonTech AG
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// AEADEncrypted represents an AEAD Encrypted Packet.
+// See https://www.ietf.org/archive/id/draft-koch-openpgp-2015-rfc4880bis-00.html#name-aead-encrypted-data-packet-t
+type AEADEncrypted struct {
+ cipher CipherFunction
+ mode AEADMode
+ chunkSizeByte byte
+ Contents io.Reader // Encrypted chunks and tags
+ initialNonce []byte // Referred to as IV in RFC4880-bis
+}
+
+// Only currently defined version
+const aeadEncryptedVersion = 1
+
+func (ae *AEADEncrypted) parse(buf io.Reader) error {
+ headerData := make([]byte, 4)
+ if n, err := io.ReadFull(buf, headerData); n < 4 {
+ return errors.AEADError("could not read aead header:" + err.Error())
+ }
+ // Read initial nonce
+ mode := AEADMode(headerData[2])
+ nonceLen := mode.IvLength()
+
+ // This packet supports only EAX and OCB
+ // https://www.ietf.org/archive/id/draft-koch-openpgp-2015-rfc4880bis-00.html#name-aead-encrypted-data-packet-t
+ if nonceLen == 0 || mode > AEADModeOCB {
+ return errors.AEADError("unknown mode")
+ }
+
+ initialNonce := make([]byte, nonceLen)
+ if n, err := io.ReadFull(buf, initialNonce); n < nonceLen {
+ return errors.AEADError("could not read aead nonce:" + err.Error())
+ }
+ ae.Contents = buf
+ ae.initialNonce = initialNonce
+ c := headerData[1]
+ if _, ok := algorithm.CipherById[c]; !ok {
+ return errors.UnsupportedError("unknown cipher: " + string(c))
+ }
+ ae.cipher = CipherFunction(c)
+ ae.mode = mode
+ ae.chunkSizeByte = headerData[3]
+ return nil
+}
+
+// Decrypt returns a io.ReadCloser from which decrypted bytes can be read, or
+// an error.
+func (ae *AEADEncrypted) Decrypt(ciph CipherFunction, key []byte) (io.ReadCloser, error) {
+ return ae.decrypt(key)
+}
+
+// decrypt prepares an aeadCrypter and returns a ReadCloser from which
+// decrypted bytes can be read (see aeadDecrypter.Read()).
+func (ae *AEADEncrypted) decrypt(key []byte) (io.ReadCloser, error) {
+ blockCipher := ae.cipher.new(key)
+ aead := ae.mode.new(blockCipher)
+ // Carry the first tagLen bytes
+ tagLen := ae.mode.TagLength()
+ peekedBytes := make([]byte, tagLen)
+ n, err := io.ReadFull(ae.Contents, peekedBytes)
+ if n < tagLen || (err != nil && err != io.EOF) {
+ return nil, errors.AEADError("Not enough data to decrypt:" + err.Error())
+ }
+ chunkSize := decodeAEADChunkSize(ae.chunkSizeByte)
+ return &aeadDecrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: chunkSize,
+ initialNonce: ae.initialNonce,
+ associatedData: ae.associatedData(),
+ chunkIndex: make([]byte, 8),
+ packetTag: packetTypeAEADEncrypted,
+ },
+ reader: ae.Contents,
+ peekedBytes: peekedBytes}, nil
+}
+
+// associatedData for chunks: tag, version, cipher, mode, chunk size byte
+func (ae *AEADEncrypted) associatedData() []byte {
+ return []byte{
+ 0xD4,
+ aeadEncryptedVersion,
+ byte(ae.cipher),
+ byte(ae.mode),
+ ae.chunkSizeByte}
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
new file mode 100644
index 0000000..2f5cad7
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
@@ -0,0 +1,125 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "compress/bzip2"
+ "compress/flate"
+ "compress/zlib"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "io"
+ "strconv"
+)
+
+// Compressed represents a compressed OpenPGP packet. The decompressed contents
+// will contain more OpenPGP packets. See RFC 4880, section 5.6.
+type Compressed struct {
+ Body io.Reader
+}
+
+const (
+ NoCompression = flate.NoCompression
+ BestSpeed = flate.BestSpeed
+ BestCompression = flate.BestCompression
+ DefaultCompression = flate.DefaultCompression
+)
+
+// CompressionConfig contains compressor configuration settings.
+type CompressionConfig struct {
+ // Level is the compression level to use. It must be set to
+ // between -1 and 9, with -1 causing the compressor to use the
+ // default compression level, 0 causing the compressor to use
+ // no compression and 1 to 9 representing increasing (better,
+ // slower) compression levels. If Level is less than -1 or
+ // more then 9, a non-nil error will be returned during
+ // encryption. See the constants above for convenient common
+ // settings for Level.
+ Level int
+}
+
+func (c *Compressed) parse(r io.Reader) error {
+ var buf [1]byte
+ _, err := readFull(r, buf[:])
+ if err != nil {
+ return err
+ }
+
+ switch buf[0] {
+ case 0:
+ c.Body = r
+ case 1:
+ c.Body = flate.NewReader(r)
+ case 2:
+ c.Body, err = zlib.NewReader(r)
+ case 3:
+ c.Body = bzip2.NewReader(r)
+ default:
+ err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
+ }
+
+ return err
+}
+
+// compressedWriterCloser represents the serialized compression stream
+// header and the compressor. Its Close() method ensures that both the
+// compressor and serialized stream header are closed. Its Write()
+// method writes to the compressor.
+type compressedWriteCloser struct {
+ sh io.Closer // Stream Header
+ c io.WriteCloser // Compressor
+}
+
+func (cwc compressedWriteCloser) Write(p []byte) (int, error) {
+ return cwc.c.Write(p)
+}
+
+func (cwc compressedWriteCloser) Close() (err error) {
+ err = cwc.c.Close()
+ if err != nil {
+ return err
+ }
+
+ return cwc.sh.Close()
+}
+
+// SerializeCompressed serializes a compressed data packet to w and
+// returns a WriteCloser to which the literal data packets themselves
+// can be written and which MUST be closed on completion. If cc is
+// nil, sensible defaults will be used to configure the compression
+// algorithm.
+func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) {
+ compressed, err := serializeStreamHeader(w, packetTypeCompressed)
+ if err != nil {
+ return
+ }
+
+ _, err = compressed.Write([]byte{uint8(algo)})
+ if err != nil {
+ return
+ }
+
+ level := DefaultCompression
+ if cc != nil {
+ level = cc.Level
+ }
+
+ var compressor io.WriteCloser
+ switch algo {
+ case CompressionZIP:
+ compressor, err = flate.NewWriter(compressed, level)
+ case CompressionZLIB:
+ compressor, err = zlib.NewWriterLevel(compressed, level)
+ default:
+ s := strconv.Itoa(int(algo))
+ err = errors.UnsupportedError("Unsupported compression algorithm: " + s)
+ }
+ if err != nil {
+ return
+ }
+
+ literaldata = compressedWriteCloser{compressed, compressor}
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
new file mode 100644
index 0000000..04994be
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
@@ -0,0 +1,248 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/rand"
+ "io"
+ "math/big"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// Config collects a number of parameters along with sensible defaults.
+// A nil *Config is valid and results in all default values.
+type Config struct {
+ // Rand provides the source of entropy.
+ // If nil, the crypto/rand Reader is used.
+ Rand io.Reader
+ // DefaultHash is the default hash function to be used.
+ // If zero, SHA-256 is used.
+ DefaultHash crypto.Hash
+ // DefaultCipher is the cipher to be used.
+ // If zero, AES-128 is used.
+ DefaultCipher CipherFunction
+ // Time returns the current time as the number of seconds since the
+ // epoch. If Time is nil, time.Now is used.
+ Time func() time.Time
+ // DefaultCompressionAlgo is the compression algorithm to be
+ // applied to the plaintext before encryption. If zero, no
+ // compression is done.
+ DefaultCompressionAlgo CompressionAlgo
+ // CompressionConfig configures the compression settings.
+ CompressionConfig *CompressionConfig
+ // S2K (String to Key) config, used for key derivation in the context of secret key encryption
+ // and password-encrypted data.
+ // If nil, the default configuration is used
+ S2KConfig *s2k.Config
+ // Iteration count for Iterated S2K (String to Key).
+ // Only used if sk2.Mode is nil.
+ // This value is duplicated here from s2k.Config for backwards compatibility.
+ // It determines the strength of the passphrase stretching when
+ // the said passphrase is hashed to produce a key. S2KCount
+ // should be between 65536 and 65011712, inclusive. If Config
+ // is nil or S2KCount is 0, the value 16777216 used. Not all
+ // values in the above range can be represented. S2KCount will
+ // be rounded up to the next representable value if it cannot
+ // be encoded exactly. When set, it is strongly encrouraged to
+ // use a value that is at least 65536. See RFC 4880 Section
+ // 3.7.1.3.
+ //
+ // Deprecated: SK2Count should be configured in S2KConfig instead.
+ S2KCount int
+ // RSABits is the number of bits in new RSA keys made with NewEntity.
+ // If zero, then 2048 bit keys are created.
+ RSABits int
+ // The public key algorithm to use - will always create a signing primary
+ // key and encryption subkey.
+ Algorithm PublicKeyAlgorithm
+ // Some known primes that are optionally prepopulated by the caller
+ RSAPrimes []*big.Int
+ // Curve configures the desired packet.Curve if the Algorithm is PubKeyAlgoECDSA,
+ // PubKeyAlgoEdDSA, or PubKeyAlgoECDH. If empty Curve25519 is used.
+ Curve Curve
+ // AEADConfig configures the use of the new AEAD Encrypted Data Packet,
+ // defined in the draft of the next version of the OpenPGP specification.
+ // If a non-nil AEADConfig is passed, usage of this packet is enabled. By
+ // default, it is disabled. See the documentation of AEADConfig for more
+ // configuration options related to AEAD.
+ // **Note: using this option may break compatibility with other OpenPGP
+ // implementations, as well as future versions of this library.**
+ AEADConfig *AEADConfig
+ // V5Keys configures version 5 key generation. If false, this package still
+ // supports version 5 keys, but produces version 4 keys.
+ V5Keys bool
+ // "The validity period of the key. This is the number of seconds after
+ // the key creation time that the key expires. If this is not present
+ // or has a value of zero, the key never expires. This is found only on
+ // a self-signature.""
+ // https://tools.ietf.org/html/rfc4880#section-5.2.3.6
+ KeyLifetimeSecs uint32
+ // "The validity period of the signature. This is the number of seconds
+ // after the signature creation time that the signature expires. If
+ // this is not present or has a value of zero, it never expires."
+ // https://tools.ietf.org/html/rfc4880#section-5.2.3.10
+ SigLifetimeSecs uint32
+ // SigningKeyId is used to specify the signing key to use (by Key ID).
+ // By default, the signing key is selected automatically, preferring
+ // signing subkeys if available.
+ SigningKeyId uint64
+ // SigningIdentity is used to specify a user ID (packet Signer's User ID, type 28)
+ // when producing a generic certification signature onto an existing user ID.
+ // The identity must be present in the signer Entity.
+ SigningIdentity string
+ // InsecureAllowUnauthenticatedMessages controls, whether it is tolerated to read
+ // encrypted messages without Modification Detection Code (MDC).
+ // MDC is mandated by the IETF OpenPGP Crypto Refresh draft and has long been implemented
+ // in most OpenPGP implementations. Messages without MDC are considered unnecessarily
+ // insecure and should be prevented whenever possible.
+ // In case one needs to deal with messages from very old OpenPGP implementations, there
+ // might be no other way than to tolerate the missing MDC. Setting this flag, allows this
+ // mode of operation. It should be considered a measure of last resort.
+ InsecureAllowUnauthenticatedMessages bool
+ // KnownNotations is a map of Notation Data names to bools, which controls
+ // the notation names that are allowed to be present in critical Notation Data
+ // signature subpackets.
+ KnownNotations map[string]bool
+ // SignatureNotations is a list of Notations to be added to any signatures.
+ SignatureNotations []*Notation
+}
+
+func (c *Config) Random() io.Reader {
+ if c == nil || c.Rand == nil {
+ return rand.Reader
+ }
+ return c.Rand
+}
+
+func (c *Config) Hash() crypto.Hash {
+ if c == nil || uint(c.DefaultHash) == 0 {
+ return crypto.SHA256
+ }
+ return c.DefaultHash
+}
+
+func (c *Config) Cipher() CipherFunction {
+ if c == nil || uint8(c.DefaultCipher) == 0 {
+ return CipherAES128
+ }
+ return c.DefaultCipher
+}
+
+func (c *Config) Now() time.Time {
+ if c == nil || c.Time == nil {
+ return time.Now().Truncate(time.Second)
+ }
+ return c.Time().Truncate(time.Second)
+}
+
+// KeyLifetime returns the validity period of the key.
+func (c *Config) KeyLifetime() uint32 {
+ if c == nil {
+ return 0
+ }
+ return c.KeyLifetimeSecs
+}
+
+// SigLifetime returns the validity period of the signature.
+func (c *Config) SigLifetime() uint32 {
+ if c == nil {
+ return 0
+ }
+ return c.SigLifetimeSecs
+}
+
+func (c *Config) Compression() CompressionAlgo {
+ if c == nil {
+ return CompressionNone
+ }
+ return c.DefaultCompressionAlgo
+}
+
+func (c *Config) RSAModulusBits() int {
+ if c == nil || c.RSABits == 0 {
+ return 2048
+ }
+ return c.RSABits
+}
+
+func (c *Config) PublicKeyAlgorithm() PublicKeyAlgorithm {
+ if c == nil || c.Algorithm == 0 {
+ return PubKeyAlgoRSA
+ }
+ return c.Algorithm
+}
+
+func (c *Config) CurveName() Curve {
+ if c == nil || c.Curve == "" {
+ return Curve25519
+ }
+ return c.Curve
+}
+
+// Deprecated: The hash iterations should now be queried via the S2K() method.
+func (c *Config) PasswordHashIterations() int {
+ if c == nil || c.S2KCount == 0 {
+ return 0
+ }
+ return c.S2KCount
+}
+
+func (c *Config) S2K() *s2k.Config {
+ if c == nil {
+ return nil
+ }
+ // for backwards compatibility
+ if c != nil && c.S2KCount > 0 && c.S2KConfig == nil {
+ return &s2k.Config{
+ S2KCount: c.S2KCount,
+ }
+ }
+ return c.S2KConfig
+}
+
+func (c *Config) AEAD() *AEADConfig {
+ if c == nil {
+ return nil
+ }
+ return c.AEADConfig
+}
+
+func (c *Config) SigningKey() uint64 {
+ if c == nil {
+ return 0
+ }
+ return c.SigningKeyId
+}
+
+func (c *Config) SigningUserId() string {
+ if c == nil {
+ return ""
+ }
+ return c.SigningIdentity
+}
+
+func (c *Config) AllowUnauthenticatedMessages() bool {
+ if c == nil {
+ return false
+ }
+ return c.InsecureAllowUnauthenticatedMessages
+}
+
+func (c *Config) KnownNotation(notationName string) bool {
+ if c == nil {
+ return false
+ }
+ return c.KnownNotations[notationName]
+}
+
+func (c *Config) Notations() []*Notation {
+ if c == nil {
+ return nil
+ }
+ return c.SignatureNotations
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go
new file mode 100644
index 0000000..eeff290
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/encrypted_key.go
@@ -0,0 +1,286 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/rsa"
+ "encoding/binary"
+ "io"
+ "math/big"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+const encryptedKeyVersion = 3
+
+// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
+// section 5.1.
+type EncryptedKey struct {
+ KeyId uint64
+ Algo PublicKeyAlgorithm
+ CipherFunc CipherFunction // only valid after a successful Decrypt for a v3 packet
+ Key []byte // only valid after a successful Decrypt
+
+ encryptedMPI1, encryptedMPI2 encoding.Field
+}
+
+func (e *EncryptedKey) parse(r io.Reader) (err error) {
+ var buf [10]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != encryptedKeyVersion {
+ return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
+ }
+ e.KeyId = binary.BigEndian.Uint64(buf[1:9])
+ e.Algo = PublicKeyAlgorithm(buf[9])
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+ case PubKeyAlgoElGamal:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+
+ e.encryptedMPI2 = new(encoding.MPI)
+ if _, err = e.encryptedMPI2.ReadFrom(r); err != nil {
+ return
+ }
+ case PubKeyAlgoECDH:
+ e.encryptedMPI1 = new(encoding.MPI)
+ if _, err = e.encryptedMPI1.ReadFrom(r); err != nil {
+ return
+ }
+
+ e.encryptedMPI2 = new(encoding.OID)
+ if _, err = e.encryptedMPI2.ReadFrom(r); err != nil {
+ return
+ }
+ }
+ _, err = consumeAll(r)
+ return
+}
+
+func checksumKeyMaterial(key []byte) uint16 {
+ var checksum uint16
+ for _, v := range key {
+ checksum += uint16(v)
+ }
+ return checksum
+}
+
+// Decrypt decrypts an encrypted session key with the given private key. The
+// private key must have been decrypted first.
+// If config is nil, sensible defaults will be used.
+func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
+ if e.KeyId != 0 && e.KeyId != priv.KeyId {
+ return errors.InvalidArgumentError("cannot decrypt encrypted session key for key id " + strconv.FormatUint(e.KeyId, 16) + " with private key id " + strconv.FormatUint(priv.KeyId, 16))
+ }
+ if e.Algo != priv.PubKeyAlgo {
+ return errors.InvalidArgumentError("cannot decrypt encrypted session key of type " + strconv.Itoa(int(e.Algo)) + " with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+ }
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+
+ var err error
+ var b []byte
+
+ // TODO(agl): use session key decryption routines here to avoid
+ // padding oracle attacks.
+ switch priv.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ // Supports both *rsa.PrivateKey and crypto.Decrypter
+ k := priv.PrivateKey.(crypto.Decrypter)
+ b, err = k.Decrypt(config.Random(), padToKeySize(k.Public().(*rsa.PublicKey), e.encryptedMPI1.Bytes()), nil)
+ case PubKeyAlgoElGamal:
+ c1 := new(big.Int).SetBytes(e.encryptedMPI1.Bytes())
+ c2 := new(big.Int).SetBytes(e.encryptedMPI2.Bytes())
+ b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
+ case PubKeyAlgoECDH:
+ vsG := e.encryptedMPI1.Bytes()
+ m := e.encryptedMPI2.Bytes()
+ oid := priv.PublicKey.oid.EncodedBytes()
+ b, err = ecdh.Decrypt(priv.PrivateKey.(*ecdh.PrivateKey), vsG, m, oid, priv.PublicKey.Fingerprint[:])
+ default:
+ err = errors.InvalidArgumentError("cannot decrypt encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
+ }
+
+ if err != nil {
+ return err
+ }
+
+ e.CipherFunc = CipherFunction(b[0])
+ if !e.CipherFunc.IsSupported() {
+ return errors.UnsupportedError("unsupported encryption function")
+ }
+
+ e.Key = b[1 : len(b)-2]
+ expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
+ checksum := checksumKeyMaterial(e.Key)
+ if checksum != expectedChecksum {
+ return errors.StructuralError("EncryptedKey checksum incorrect")
+ }
+
+ return nil
+}
+
+// Serialize writes the encrypted key packet, e, to w.
+func (e *EncryptedKey) Serialize(w io.Writer) error {
+ var mpiLen int
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ mpiLen = int(e.encryptedMPI1.EncodedLength())
+ case PubKeyAlgoElGamal:
+ mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength())
+ case PubKeyAlgoECDH:
+ mpiLen = int(e.encryptedMPI1.EncodedLength()) + int(e.encryptedMPI2.EncodedLength())
+ default:
+ return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo)))
+ }
+
+ err := serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen)
+ if err != nil {
+ return err
+ }
+
+ w.Write([]byte{encryptedKeyVersion})
+ binary.Write(w, binary.BigEndian, e.KeyId)
+ w.Write([]byte{byte(e.Algo)})
+
+ switch e.Algo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ _, err := w.Write(e.encryptedMPI1.EncodedBytes())
+ return err
+ case PubKeyAlgoElGamal:
+ if _, err := w.Write(e.encryptedMPI1.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(e.encryptedMPI2.EncodedBytes())
+ return err
+ case PubKeyAlgoECDH:
+ if _, err := w.Write(e.encryptedMPI1.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(e.encryptedMPI2.EncodedBytes())
+ return err
+ default:
+ panic("internal error")
+ }
+}
+
+// SerializeEncryptedKey serializes an encrypted key packet to w that contains
+// key, encrypted to pub.
+// If config is nil, sensible defaults will be used.
+func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error {
+ var buf [10]byte
+ buf[0] = encryptedKeyVersion
+ binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
+ buf[9] = byte(pub.PubKeyAlgo)
+
+ keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */)
+ keyBlock[0] = byte(cipherFunc)
+ copy(keyBlock[1:], key)
+ checksum := checksumKeyMaterial(key)
+ keyBlock[1+len(key)] = byte(checksum >> 8)
+ keyBlock[1+len(key)+1] = byte(checksum)
+
+ switch pub.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
+ return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
+ case PubKeyAlgoElGamal:
+ return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
+ case PubKeyAlgoECDH:
+ return serializeEncryptedKeyECDH(w, config.Random(), buf, pub.PublicKey.(*ecdh.PublicKey), keyBlock, pub.oid, pub.Fingerprint)
+ case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
+ return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+ }
+
+ return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
+}
+
+func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error {
+ cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
+ if err != nil {
+ return errors.InvalidArgumentError("RSA encryption failed: " + err.Error())
+ }
+
+ cipherMPI := encoding.NewMPI(cipherText)
+ packetLen := 10 /* header length */ + int(cipherMPI.EncodedLength())
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(cipherMPI.EncodedBytes())
+ return err
+}
+
+func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error {
+ c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
+ if err != nil {
+ return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
+ }
+
+ packetLen := 10 /* header length */
+ packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8
+ packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ if _, err = w.Write(new(encoding.MPI).SetBig(c1).EncodedBytes()); err != nil {
+ return err
+ }
+ _, err = w.Write(new(encoding.MPI).SetBig(c2).EncodedBytes())
+ return err
+}
+
+func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub *ecdh.PublicKey, keyBlock []byte, oid encoding.Field, fingerprint []byte) error {
+ vsG, c, err := ecdh.Encrypt(rand, pub, keyBlock, oid.EncodedBytes(), fingerprint)
+ if err != nil {
+ return errors.InvalidArgumentError("ECDH encryption failed: " + err.Error())
+ }
+
+ g := encoding.NewMPI(vsG)
+ m := encoding.NewOID(c)
+
+ packetLen := 10 /* header length */
+ packetLen += int(g.EncodedLength()) + int(m.EncodedLength())
+
+ err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(header[:])
+ if err != nil {
+ return err
+ }
+ if _, err = w.Write(g.EncodedBytes()); err != nil {
+ return err
+ }
+ _, err = w.Write(m.EncodedBytes())
+ return err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go
new file mode 100644
index 0000000..4be9876
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/literal.go
@@ -0,0 +1,91 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "encoding/binary"
+ "io"
+)
+
+// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
+type LiteralData struct {
+ Format uint8
+ IsBinary bool
+ FileName string
+ Time uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined.
+ Body io.Reader
+}
+
+// ForEyesOnly returns whether the contents of the LiteralData have been marked
+// as especially sensitive.
+func (l *LiteralData) ForEyesOnly() bool {
+ return l.FileName == "_CONSOLE"
+}
+
+func (l *LiteralData) parse(r io.Reader) (err error) {
+ var buf [256]byte
+
+ _, err = readFull(r, buf[:2])
+ if err != nil {
+ return
+ }
+
+ l.Format = buf[0]
+ l.IsBinary = l.Format == 'b'
+ fileNameLen := int(buf[1])
+
+ _, err = readFull(r, buf[:fileNameLen])
+ if err != nil {
+ return
+ }
+
+ l.FileName = string(buf[:fileNameLen])
+
+ _, err = readFull(r, buf[:4])
+ if err != nil {
+ return
+ }
+
+ l.Time = binary.BigEndian.Uint32(buf[:4])
+ l.Body = r
+ return
+}
+
+// SerializeLiteral serializes a literal data packet to w and returns a
+// WriteCloser to which the data itself can be written and which MUST be closed
+// on completion. The fileName is truncated to 255 bytes.
+func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) {
+ var buf [4]byte
+ buf[0] = 't'
+ if isBinary {
+ buf[0] = 'b'
+ }
+ if len(fileName) > 255 {
+ fileName = fileName[:255]
+ }
+ buf[1] = byte(len(fileName))
+
+ inner, err := serializeStreamHeader(w, packetTypeLiteralData)
+ if err != nil {
+ return
+ }
+
+ _, err = inner.Write(buf[:2])
+ if err != nil {
+ return
+ }
+ _, err = inner.Write([]byte(fileName))
+ if err != nil {
+ return
+ }
+ binary.BigEndian.PutUint32(buf[:], time)
+ _, err = inner.Write(buf[:])
+ if err != nil {
+ return
+ }
+
+ plaintext = inner
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go
new file mode 100644
index 0000000..2c3e3f5
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/notation.go
@@ -0,0 +1,29 @@
+package packet
+
+// Notation type represents a Notation Data subpacket
+// see https://tools.ietf.org/html/rfc4880#section-5.2.3.16
+type Notation struct {
+ Name string
+ Value []byte
+ IsCritical bool
+ IsHumanReadable bool
+}
+
+func (notation *Notation) getData() []byte {
+ nameData := []byte(notation.Name)
+ nameLen := len(nameData)
+ valueLen := len(notation.Value)
+
+ data := make([]byte, 8+nameLen+valueLen)
+ if notation.IsHumanReadable {
+ data[0] = 0x80
+ }
+
+ data[4] = byte(nameLen >> 8)
+ data[5] = byte(nameLen)
+ data[6] = byte(valueLen >> 8)
+ data[7] = byte(valueLen)
+ copy(data[8:8+nameLen], nameData)
+ copy(data[8+nameLen:], notation.Value)
+ return data
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go
new file mode 100644
index 0000000..4f26d0a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/ocfb.go
@@ -0,0 +1,137 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
+
+package packet
+
+import (
+ "crypto/cipher"
+)
+
+type ocfbEncrypter struct {
+ b cipher.Block
+ fre []byte
+ outUsed int
+}
+
+// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
+// performed.
+type OCFBResyncOption bool
+
+const (
+ OCFBResync OCFBResyncOption = true
+ OCFBNoResync OCFBResyncOption = false
+)
+
+// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block, and an initial amount of
+// ciphertext. randData must be random bytes and be the same length as the
+// cipher.Block's block size. Resync determines if the "resynchronization step"
+// from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
+// this point.
+func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
+ blockSize := block.BlockSize()
+ if len(randData) != blockSize {
+ return nil, nil
+ }
+
+ x := &ocfbEncrypter{
+ b: block,
+ fre: make([]byte, blockSize),
+ outUsed: 0,
+ }
+ prefix := make([]byte, blockSize+2)
+
+ block.Encrypt(x.fre, x.fre)
+ for i := 0; i < blockSize; i++ {
+ prefix[i] = randData[i] ^ x.fre[i]
+ }
+
+ block.Encrypt(x.fre, prefix[:blockSize])
+ prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
+ prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
+
+ if resync {
+ block.Encrypt(x.fre, prefix[2:])
+ } else {
+ x.fre[0] = prefix[blockSize]
+ x.fre[1] = prefix[blockSize+1]
+ x.outUsed = 2
+ }
+ return x, prefix
+}
+
+func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
+ for i := 0; i < len(src); i++ {
+ if x.outUsed == len(x.fre) {
+ x.b.Encrypt(x.fre, x.fre)
+ x.outUsed = 0
+ }
+
+ x.fre[x.outUsed] ^= src[i]
+ dst[i] = x.fre[x.outUsed]
+ x.outUsed++
+ }
+}
+
+type ocfbDecrypter struct {
+ b cipher.Block
+ fre []byte
+ outUsed int
+}
+
+// NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
+// cipher feedback mode using the given cipher.Block. Prefix must be the first
+// blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
+// block size. On successful exit, blockSize+2 bytes of decrypted data are written into
+// prefix. Resync determines if the "resynchronization step" from RFC 4880,
+// 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
+func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
+ blockSize := block.BlockSize()
+ if len(prefix) != blockSize+2 {
+ return nil
+ }
+
+ x := &ocfbDecrypter{
+ b: block,
+ fre: make([]byte, blockSize),
+ outUsed: 0,
+ }
+ prefixCopy := make([]byte, len(prefix))
+ copy(prefixCopy, prefix)
+
+ block.Encrypt(x.fre, x.fre)
+ for i := 0; i < blockSize; i++ {
+ prefixCopy[i] ^= x.fre[i]
+ }
+
+ block.Encrypt(x.fre, prefix[:blockSize])
+ prefixCopy[blockSize] ^= x.fre[0]
+ prefixCopy[blockSize+1] ^= x.fre[1]
+
+ if resync {
+ block.Encrypt(x.fre, prefix[2:])
+ } else {
+ x.fre[0] = prefix[blockSize]
+ x.fre[1] = prefix[blockSize+1]
+ x.outUsed = 2
+ }
+ copy(prefix, prefixCopy)
+ return x
+}
+
+func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
+ for i := 0; i < len(src); i++ {
+ if x.outUsed == len(x.fre) {
+ x.b.Encrypt(x.fre, x.fre)
+ x.outUsed = 0
+ }
+
+ c := src[i]
+ dst[i] = x.fre[x.outUsed] ^ src[i]
+ x.fre[x.outUsed] = c
+ x.outUsed++
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go
new file mode 100644
index 0000000..033fb2d
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/one_pass_signature.go
@@ -0,0 +1,73 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "encoding/binary"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "io"
+ "strconv"
+)
+
+// OnePassSignature represents a one-pass signature packet. See RFC 4880,
+// section 5.4.
+type OnePassSignature struct {
+ SigType SignatureType
+ Hash crypto.Hash
+ PubKeyAlgo PublicKeyAlgorithm
+ KeyId uint64
+ IsLast bool
+}
+
+const onePassSignatureVersion = 3
+
+func (ops *OnePassSignature) parse(r io.Reader) (err error) {
+ var buf [13]byte
+
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != onePassSignatureVersion {
+ err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
+ }
+
+ var ok bool
+ ops.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
+ if !ok {
+ return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
+ }
+
+ ops.SigType = SignatureType(buf[1])
+ ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3])
+ ops.KeyId = binary.BigEndian.Uint64(buf[4:12])
+ ops.IsLast = buf[12] != 0
+ return
+}
+
+// Serialize marshals the given OnePassSignature to w.
+func (ops *OnePassSignature) Serialize(w io.Writer) error {
+ var buf [13]byte
+ buf[0] = onePassSignatureVersion
+ buf[1] = uint8(ops.SigType)
+ var ok bool
+ buf[2], ok = algorithm.HashToHashIdWithSha1(ops.Hash)
+ if !ok {
+ return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
+ }
+ buf[3] = uint8(ops.PubKeyAlgo)
+ binary.BigEndian.PutUint64(buf[4:12], ops.KeyId)
+ if ops.IsLast {
+ buf[12] = 1
+ }
+
+ if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil {
+ return err
+ }
+ _, err := w.Write(buf[:])
+ return err
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go
new file mode 100644
index 0000000..4f82040
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/opaque.go
@@ -0,0 +1,171 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
+// useful for splitting and storing the original packet contents separately,
+// handling unsupported packet types or accessing parts of the packet not yet
+// implemented by this package.
+type OpaquePacket struct {
+ // Packet type
+ Tag uint8
+ // Reason why the packet was parsed opaquely
+ Reason error
+ // Binary contents of the packet data
+ Contents []byte
+}
+
+func (op *OpaquePacket) parse(r io.Reader) (err error) {
+ op.Contents, err = ioutil.ReadAll(r)
+ return
+}
+
+// Serialize marshals the packet to a writer in its original form, including
+// the packet header.
+func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
+ err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
+ if err == nil {
+ _, err = w.Write(op.Contents)
+ }
+ return
+}
+
+// Parse attempts to parse the opaque contents into a structure supported by
+// this package. If the packet is not known then the result will be another
+// OpaquePacket.
+func (op *OpaquePacket) Parse() (p Packet, err error) {
+ hdr := bytes.NewBuffer(nil)
+ err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
+ if err != nil {
+ op.Reason = err
+ return op, err
+ }
+ p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
+ if err != nil {
+ op.Reason = err
+ p = op
+ }
+ return
+}
+
+// OpaqueReader reads OpaquePackets from an io.Reader.
+type OpaqueReader struct {
+ r io.Reader
+}
+
+func NewOpaqueReader(r io.Reader) *OpaqueReader {
+ return &OpaqueReader{r: r}
+}
+
+// Read the next OpaquePacket.
+func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
+ tag, _, contents, err := readHeader(or.r)
+ if err != nil {
+ return
+ }
+ op = &OpaquePacket{Tag: uint8(tag), Reason: err}
+ err = op.parse(contents)
+ if err != nil {
+ consumeAll(contents)
+ }
+ return
+}
+
+// OpaqueSubpacket represents an unparsed OpenPGP subpacket,
+// as found in signature and user attribute packets.
+type OpaqueSubpacket struct {
+ SubType uint8
+ EncodedLength []byte // Store the original encoded length for signature verifications.
+ Contents []byte
+}
+
+// OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
+// their byte representation.
+func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
+ var (
+ subHeaderLen int
+ subPacket *OpaqueSubpacket
+ )
+ for len(contents) > 0 {
+ subHeaderLen, subPacket, err = nextSubpacket(contents)
+ if err != nil {
+ break
+ }
+ result = append(result, subPacket)
+ contents = contents[subHeaderLen+len(subPacket.Contents):]
+ }
+ return
+}
+
+func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
+ // RFC 4880, section 5.2.3.1
+ var subLen uint32
+ var encodedLength []byte
+ if len(contents) < 1 {
+ goto Truncated
+ }
+ subPacket = &OpaqueSubpacket{}
+ switch {
+ case contents[0] < 192:
+ subHeaderLen = 2 // 1 length byte, 1 subtype byte
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:1]
+ subLen = uint32(contents[0])
+ contents = contents[1:]
+ case contents[0] < 255:
+ subHeaderLen = 3 // 2 length bytes, 1 subtype
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:2]
+ subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
+ contents = contents[2:]
+ default:
+ subHeaderLen = 6 // 5 length bytes, 1 subtype
+ if len(contents) < subHeaderLen {
+ goto Truncated
+ }
+ encodedLength = contents[0:5]
+ subLen = uint32(contents[1])<<24 |
+ uint32(contents[2])<<16 |
+ uint32(contents[3])<<8 |
+ uint32(contents[4])
+ contents = contents[5:]
+
+ }
+ if subLen > uint32(len(contents)) || subLen == 0 {
+ goto Truncated
+ }
+ subPacket.SubType = contents[0]
+ subPacket.EncodedLength = encodedLength
+ subPacket.Contents = contents[1:subLen]
+ return
+Truncated:
+ err = errors.StructuralError("subpacket truncated")
+ return
+}
+
+func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
+ buf := make([]byte, 6)
+ copy(buf, osp.EncodedLength)
+ n := len(osp.EncodedLength)
+
+ buf[n] = osp.SubType
+ if _, err = w.Write(buf[:n+1]); err != nil {
+ return
+ }
+ _, err = w.Write(osp.Contents)
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go
new file mode 100644
index 0000000..4d86a7d
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go
@@ -0,0 +1,551 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package packet implements parsing and serialization of OpenPGP packets, as
+// specified in RFC 4880.
+package packet // import "github.com/ProtonMail/go-crypto/openpgp/packet"
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/rsa"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+)
+
+// readFull is the same as io.ReadFull except that reading zero bytes returns
+// ErrUnexpectedEOF rather than EOF.
+func readFull(r io.Reader, buf []byte) (n int, err error) {
+ n, err = io.ReadFull(r, buf)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
+func readLength(r io.Reader) (length int64, isPartial bool, err error) {
+ var buf [4]byte
+ _, err = readFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ switch {
+ case buf[0] < 192:
+ length = int64(buf[0])
+ case buf[0] < 224:
+ length = int64(buf[0]-192) << 8
+ _, err = readFull(r, buf[0:1])
+ if err != nil {
+ return
+ }
+ length += int64(buf[0]) + 192
+ case buf[0] < 255:
+ length = int64(1) << (buf[0] & 0x1f)
+ isPartial = true
+ default:
+ _, err = readFull(r, buf[0:4])
+ if err != nil {
+ return
+ }
+ length = int64(buf[0])<<24 |
+ int64(buf[1])<<16 |
+ int64(buf[2])<<8 |
+ int64(buf[3])
+ }
+ return
+}
+
+// partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
+// The continuation lengths are parsed and removed from the stream and EOF is
+// returned at the end of the packet. See RFC 4880, section 4.2.2.4.
+type partialLengthReader struct {
+ r io.Reader
+ remaining int64
+ isPartial bool
+}
+
+func (r *partialLengthReader) Read(p []byte) (n int, err error) {
+ for r.remaining == 0 {
+ if !r.isPartial {
+ return 0, io.EOF
+ }
+ r.remaining, r.isPartial, err = readLength(r.r)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ toRead := int64(len(p))
+ if toRead > r.remaining {
+ toRead = r.remaining
+ }
+
+ n, err = r.r.Read(p[:int(toRead)])
+ r.remaining -= int64(n)
+ if n < int(toRead) && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// partialLengthWriter writes a stream of data using OpenPGP partial lengths.
+// See RFC 4880, section 4.2.2.4.
+type partialLengthWriter struct {
+ w io.WriteCloser
+ buf bytes.Buffer
+ lengthByte [1]byte
+}
+
+func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
+ bufLen := w.buf.Len()
+ if bufLen > 512 {
+ for power := uint(30); ; power-- {
+ l := 1 << power
+ if bufLen >= l {
+ w.lengthByte[0] = 224 + uint8(power)
+ _, err = w.w.Write(w.lengthByte[:])
+ if err != nil {
+ return
+ }
+ var m int
+ m, err = w.w.Write(w.buf.Next(l))
+ if err != nil {
+ return
+ }
+ if m != l {
+ return 0, io.ErrShortWrite
+ }
+ break
+ }
+ }
+ }
+ return w.buf.Write(p)
+}
+
+func (w *partialLengthWriter) Close() (err error) {
+ len := w.buf.Len()
+ err = serializeLength(w.w, len)
+ if err != nil {
+ return err
+ }
+ _, err = w.buf.WriteTo(w.w)
+ if err != nil {
+ return err
+ }
+ return w.w.Close()
+}
+
+// A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
+// underlying Reader returns EOF before the limit has been reached.
+type spanReader struct {
+ r io.Reader
+ n int64
+}
+
+func (l *spanReader) Read(p []byte) (n int, err error) {
+ if l.n <= 0 {
+ return 0, io.EOF
+ }
+ if int64(len(p)) > l.n {
+ p = p[0:l.n]
+ }
+ n, err = l.r.Read(p)
+ l.n -= int64(n)
+ if l.n > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+// readHeader parses a packet header and returns an io.Reader which will return
+// the contents of the packet. See RFC 4880, section 4.2.
+func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
+ var buf [4]byte
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ if buf[0]&0x80 == 0 {
+ err = errors.StructuralError("tag byte does not have MSB set")
+ return
+ }
+ if buf[0]&0x40 == 0 {
+ // Old format packet
+ tag = packetType((buf[0] & 0x3f) >> 2)
+ lengthType := buf[0] & 3
+ if lengthType == 3 {
+ length = -1
+ contents = r
+ return
+ }
+ lengthBytes := 1 << lengthType
+ _, err = readFull(r, buf[0:lengthBytes])
+ if err != nil {
+ return
+ }
+ for i := 0; i < lengthBytes; i++ {
+ length <<= 8
+ length |= int64(buf[i])
+ }
+ contents = &spanReader{r, length}
+ return
+ }
+
+ // New format packet
+ tag = packetType(buf[0] & 0x3f)
+ length, isPartial, err := readLength(r)
+ if err != nil {
+ return
+ }
+ if isPartial {
+ contents = &partialLengthReader{
+ remaining: length,
+ isPartial: true,
+ r: r,
+ }
+ length = -1
+ } else {
+ contents = &spanReader{r, length}
+ }
+ return
+}
+
+// serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
+// 4.2.
+func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
+ err = serializeType(w, ptype)
+ if err != nil {
+ return
+ }
+ return serializeLength(w, length)
+}
+
+// serializeType writes an OpenPGP packet type to w. See RFC 4880, section
+// 4.2.
+func serializeType(w io.Writer, ptype packetType) (err error) {
+ var buf [1]byte
+ buf[0] = 0x80 | 0x40 | byte(ptype)
+ _, err = w.Write(buf[:])
+ return
+}
+
+// serializeLength writes an OpenPGP packet length to w. See RFC 4880, section
+// 4.2.2.
+func serializeLength(w io.Writer, length int) (err error) {
+ var buf [5]byte
+ var n int
+
+ if length < 192 {
+ buf[0] = byte(length)
+ n = 1
+ } else if length < 8384 {
+ length -= 192
+ buf[0] = 192 + byte(length>>8)
+ buf[1] = byte(length)
+ n = 2
+ } else {
+ buf[0] = 255
+ buf[1] = byte(length >> 24)
+ buf[2] = byte(length >> 16)
+ buf[3] = byte(length >> 8)
+ buf[4] = byte(length)
+ n = 5
+ }
+
+ _, err = w.Write(buf[:n])
+ return
+}
+
+// serializeStreamHeader writes an OpenPGP packet header to w where the
+// length of the packet is unknown. It returns a io.WriteCloser which can be
+// used to write the contents of the packet. See RFC 4880, section 4.2.
+func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
+ err = serializeType(w, ptype)
+ if err != nil {
+ return
+ }
+ out = &partialLengthWriter{w: w}
+ return
+}
+
+// Packet represents an OpenPGP packet. Users are expected to try casting
+// instances of this interface to specific packet types.
+type Packet interface {
+ parse(io.Reader) error
+}
+
+// consumeAll reads from the given Reader until error, returning the number of
+// bytes read.
+func consumeAll(r io.Reader) (n int64, err error) {
+ var m int
+ var buf [1024]byte
+
+ for {
+ m, err = r.Read(buf[:])
+ n += int64(m)
+ if err == io.EOF {
+ err = nil
+ return
+ }
+ if err != nil {
+ return
+ }
+ }
+}
+
+// packetType represents the numeric ids of the different OpenPGP packet types. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
+type packetType uint8
+
+const (
+ packetTypeEncryptedKey packetType = 1
+ packetTypeSignature packetType = 2
+ packetTypeSymmetricKeyEncrypted packetType = 3
+ packetTypeOnePassSignature packetType = 4
+ packetTypePrivateKey packetType = 5
+ packetTypePublicKey packetType = 6
+ packetTypePrivateSubkey packetType = 7
+ packetTypeCompressed packetType = 8
+ packetTypeSymmetricallyEncrypted packetType = 9
+ packetTypeLiteralData packetType = 11
+ packetTypeUserId packetType = 13
+ packetTypePublicSubkey packetType = 14
+ packetTypeUserAttribute packetType = 17
+ packetTypeSymmetricallyEncryptedIntegrityProtected packetType = 18
+ packetTypeAEADEncrypted packetType = 20
+)
+
+// EncryptedDataPacket holds encrypted data. It is currently implemented by
+// SymmetricallyEncrypted and AEADEncrypted.
+type EncryptedDataPacket interface {
+ Decrypt(CipherFunction, []byte) (io.ReadCloser, error)
+}
+
+// Read reads a single OpenPGP packet from the given io.Reader. If there is an
+// error parsing a packet, the whole packet is consumed from the input.
+func Read(r io.Reader) (p Packet, err error) {
+ tag, _, contents, err := readHeader(r)
+ if err != nil {
+ return
+ }
+
+ switch tag {
+ case packetTypeEncryptedKey:
+ p = new(EncryptedKey)
+ case packetTypeSignature:
+ p = new(Signature)
+ case packetTypeSymmetricKeyEncrypted:
+ p = new(SymmetricKeyEncrypted)
+ case packetTypeOnePassSignature:
+ p = new(OnePassSignature)
+ case packetTypePrivateKey, packetTypePrivateSubkey:
+ pk := new(PrivateKey)
+ if tag == packetTypePrivateSubkey {
+ pk.IsSubkey = true
+ }
+ p = pk
+ case packetTypePublicKey, packetTypePublicSubkey:
+ isSubkey := tag == packetTypePublicSubkey
+ p = &PublicKey{IsSubkey: isSubkey}
+ case packetTypeCompressed:
+ p = new(Compressed)
+ case packetTypeSymmetricallyEncrypted:
+ p = new(SymmetricallyEncrypted)
+ case packetTypeLiteralData:
+ p = new(LiteralData)
+ case packetTypeUserId:
+ p = new(UserId)
+ case packetTypeUserAttribute:
+ p = new(UserAttribute)
+ case packetTypeSymmetricallyEncryptedIntegrityProtected:
+ se := new(SymmetricallyEncrypted)
+ se.IntegrityProtected = true
+ p = se
+ case packetTypeAEADEncrypted:
+ p = new(AEADEncrypted)
+ default:
+ err = errors.UnknownPacketTypeError(tag)
+ }
+ if p != nil {
+ err = p.parse(contents)
+ }
+ if err != nil {
+ consumeAll(contents)
+ }
+ return
+}
+
+// SignatureType represents the different semantic meanings of an OpenPGP
+// signature. See RFC 4880, section 5.2.1.
+type SignatureType uint8
+
+const (
+ SigTypeBinary SignatureType = 0x00
+ SigTypeText = 0x01
+ SigTypeGenericCert = 0x10
+ SigTypePersonaCert = 0x11
+ SigTypeCasualCert = 0x12
+ SigTypePositiveCert = 0x13
+ SigTypeSubkeyBinding = 0x18
+ SigTypePrimaryKeyBinding = 0x19
+ SigTypeDirectSignature = 0x1F
+ SigTypeKeyRevocation = 0x20
+ SigTypeSubkeyRevocation = 0x28
+ SigTypeCertificationRevocation = 0x30
+)
+
+// PublicKeyAlgorithm represents the different public key system specified for
+// OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
+type PublicKeyAlgorithm uint8
+
+const (
+ PubKeyAlgoRSA PublicKeyAlgorithm = 1
+ PubKeyAlgoElGamal PublicKeyAlgorithm = 16
+ PubKeyAlgoDSA PublicKeyAlgorithm = 17
+ // RFC 6637, Section 5.
+ PubKeyAlgoECDH PublicKeyAlgorithm = 18
+ PubKeyAlgoECDSA PublicKeyAlgorithm = 19
+ // https://www.ietf.org/archive/id/draft-koch-eddsa-for-openpgp-04.txt
+ PubKeyAlgoEdDSA PublicKeyAlgorithm = 22
+
+ // Deprecated in RFC 4880, Section 13.5. Use key flags instead.
+ PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
+ PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
+)
+
+// CanEncrypt returns true if it's possible to encrypt a message to a public
+// key of the given type.
+func (pka PublicKeyAlgorithm) CanEncrypt() bool {
+ switch pka {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH:
+ return true
+ }
+ return false
+}
+
+// CanSign returns true if it's possible for a public key of the given type to
+// sign a message.
+func (pka PublicKeyAlgorithm) CanSign() bool {
+ switch pka {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA:
+ return true
+ }
+ return false
+}
+
+// CipherFunction represents the different block ciphers specified for OpenPGP. See
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
+type CipherFunction algorithm.CipherFunction
+
+const (
+ Cipher3DES CipherFunction = 2
+ CipherCAST5 CipherFunction = 3
+ CipherAES128 CipherFunction = 7
+ CipherAES192 CipherFunction = 8
+ CipherAES256 CipherFunction = 9
+)
+
+// KeySize returns the key size, in bytes, of cipher.
+func (cipher CipherFunction) KeySize() int {
+ return algorithm.CipherFunction(cipher).KeySize()
+}
+
+// IsSupported returns true if the cipher is supported from the library
+func (cipher CipherFunction) IsSupported() bool {
+ return algorithm.CipherFunction(cipher).KeySize() > 0
+}
+
+// blockSize returns the block size, in bytes, of cipher.
+func (cipher CipherFunction) blockSize() int {
+ return algorithm.CipherFunction(cipher).BlockSize()
+}
+
+// new returns a fresh instance of the given cipher.
+func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
+ return algorithm.CipherFunction(cipher).New(key)
+}
+
+// padToKeySize left-pads a MPI with zeroes to match the length of the
+// specified RSA public.
+func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
+ k := (pub.N.BitLen() + 7) / 8
+ if len(b) >= k {
+ return b
+ }
+ bb := make([]byte, k)
+ copy(bb[len(bb)-len(b):], b)
+ return bb
+}
+
+// CompressionAlgo Represents the different compression algorithms
+// supported by OpenPGP (except for BZIP2, which is not currently
+// supported). See Section 9.3 of RFC 4880.
+type CompressionAlgo uint8
+
+const (
+ CompressionNone CompressionAlgo = 0
+ CompressionZIP CompressionAlgo = 1
+ CompressionZLIB CompressionAlgo = 2
+)
+
+// AEADMode represents the different Authenticated Encryption with Associated
+// Data specified for OpenPGP.
+// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
+type AEADMode algorithm.AEADMode
+
+const (
+ AEADModeEAX AEADMode = 1
+ AEADModeOCB AEADMode = 2
+ AEADModeGCM AEADMode = 3
+)
+
+func (mode AEADMode) IvLength() int {
+ return algorithm.AEADMode(mode).NonceLength()
+}
+
+func (mode AEADMode) TagLength() int {
+ return algorithm.AEADMode(mode).TagLength()
+}
+
+// new returns a fresh instance of the given mode.
+func (mode AEADMode) new(block cipher.Block) cipher.AEAD {
+ return algorithm.AEADMode(mode).New(block)
+}
+
+// ReasonForRevocation represents a revocation reason code as per RFC4880
+// section 5.2.3.23.
+type ReasonForRevocation uint8
+
+const (
+ NoReason ReasonForRevocation = 0
+ KeySuperseded ReasonForRevocation = 1
+ KeyCompromised ReasonForRevocation = 2
+ KeyRetired ReasonForRevocation = 3
+)
+
+// Curve is a mapping to supported ECC curves for key generation.
+// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#name-curve-specific-wire-formats
+type Curve string
+
+const (
+ Curve25519 Curve = "Curve25519"
+ Curve448 Curve = "Curve448"
+ CurveNistP256 Curve = "P256"
+ CurveNistP384 Curve = "P384"
+ CurveNistP521 Curve = "P521"
+ CurveSecP256k1 Curve = "SecP256k1"
+ CurveBrainpoolP256 Curve = "BrainpoolP256"
+ CurveBrainpoolP384 Curve = "BrainpoolP384"
+ CurveBrainpoolP512 Curve = "BrainpoolP512"
+)
+
+// TrustLevel represents a trust level per RFC4880 5.2.3.13
+type TrustLevel uint8
+
+// TrustAmount represents a trust amount per RFC4880 5.2.3.13
+type TrustAmount uint8
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
new file mode 100644
index 0000000..2fc4386
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key.go
@@ -0,0 +1,837 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/cipher"
+ "crypto/dsa"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "io"
+ "io/ioutil"
+ "math/big"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// PrivateKey represents a possibly encrypted private key. See RFC 4880,
+// section 5.5.3.
+type PrivateKey struct {
+ PublicKey
+ Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
+ encryptedData []byte
+ cipher CipherFunction
+ s2k func(out, in []byte)
+ // An *{rsa|dsa|elgamal|ecdh|ecdsa|ed25519}.PrivateKey or
+ // crypto.Signer/crypto.Decrypter (Decryptor RSA only).
+ PrivateKey interface{}
+ sha1Checksum bool
+ iv []byte
+
+ // Type of encryption of the S2K packet
+ // Allowed values are 0 (Not encrypted), 254 (SHA1), or
+ // 255 (2-byte checksum)
+ s2kType S2KType
+ // Full parameters of the S2K packet
+ s2kParams *s2k.Params
+}
+
+// S2KType s2k packet type
+type S2KType uint8
+
+const (
+ // S2KNON unencrypt
+ S2KNON S2KType = 0
+ // S2KSHA1 sha1 sum check
+ S2KSHA1 S2KType = 254
+ // S2KCHECKSUM sum check
+ S2KCHECKSUM S2KType = 255
+)
+
+func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewEdDSAPrivateKey(creationTime time.Time, priv *eddsa.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+func NewECDHPrivateKey(creationTime time.Time, priv *ecdh.PrivateKey) *PrivateKey {
+ pk := new(PrivateKey)
+ pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey)
+ pk.PrivateKey = priv
+ return pk
+}
+
+// NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
+// implements RSA, ECDSA or EdDSA.
+func NewSignerPrivateKey(creationTime time.Time, signer interface{}) *PrivateKey {
+ pk := new(PrivateKey)
+ // In general, the public Keys should be used as pointers. We still
+ // type-switch on the values, for backwards-compatibility.
+ switch pubkey := signer.(type) {
+ case *rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey.PublicKey)
+ case rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey.PublicKey)
+ case *ecdsa.PrivateKey:
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case ecdsa.PrivateKey:
+ pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case *eddsa.PrivateKey:
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey)
+ case eddsa.PrivateKey:
+ pk.PublicKey = *NewEdDSAPublicKey(creationTime, &pubkey.PublicKey)
+ default:
+ panic("openpgp: unknown signer type in NewSignerPrivateKey")
+ }
+ pk.PrivateKey = signer
+ return pk
+}
+
+// NewDecrypterPrivateKey creates a PrivateKey from a *{rsa|elgamal|ecdh}.PrivateKey.
+func NewDecrypterPrivateKey(creationTime time.Time, decrypter interface{}) *PrivateKey {
+ pk := new(PrivateKey)
+ switch priv := decrypter.(type) {
+ case *rsa.PrivateKey:
+ pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
+ case *elgamal.PrivateKey:
+ pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
+ case *ecdh.PrivateKey:
+ pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey)
+ default:
+ panic("openpgp: unknown decrypter type in NewDecrypterPrivateKey")
+ }
+ pk.PrivateKey = decrypter
+ return pk
+}
+
+func (pk *PrivateKey) parse(r io.Reader) (err error) {
+ err = (&pk.PublicKey).parse(r)
+ if err != nil {
+ return
+ }
+ v5 := pk.PublicKey.Version == 5
+
+ var buf [1]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ pk.s2kType = S2KType(buf[0])
+ var optCount [1]byte
+ if v5 {
+ if _, err = readFull(r, optCount[:]); err != nil {
+ return
+ }
+ }
+
+ switch pk.s2kType {
+ case S2KNON:
+ pk.s2k = nil
+ pk.Encrypted = false
+ case S2KSHA1, S2KCHECKSUM:
+ if v5 && pk.s2kType == S2KCHECKSUM {
+ return errors.StructuralError("wrong s2k identifier for version 5")
+ }
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ pk.cipher = CipherFunction(buf[0])
+ if pk.cipher != 0 && !pk.cipher.IsSupported() {
+ return errors.UnsupportedError("unsupported cipher function in private key")
+ }
+ pk.s2kParams, err = s2k.ParseIntoParams(r)
+ if err != nil {
+ return
+ }
+ if pk.s2kParams.Dummy() {
+ return
+ }
+ pk.s2k, err = pk.s2kParams.Function()
+ if err != nil {
+ return
+ }
+ pk.Encrypted = true
+ if pk.s2kType == S2KSHA1 {
+ pk.sha1Checksum = true
+ }
+ default:
+ return errors.UnsupportedError("deprecated s2k function in private key")
+ }
+
+ if pk.Encrypted {
+ blockSize := pk.cipher.blockSize()
+ if blockSize == 0 {
+ return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
+ }
+ pk.iv = make([]byte, blockSize)
+ _, err = readFull(r, pk.iv)
+ if err != nil {
+ return
+ }
+ }
+
+ var privateKeyData []byte
+ if v5 {
+ var n [4]byte /* secret material four octet count */
+ _, err = readFull(r, n[:])
+ if err != nil {
+ return
+ }
+ count := uint32(uint32(n[0])<<24 | uint32(n[1])<<16 | uint32(n[2])<<8 | uint32(n[3]))
+ if !pk.Encrypted {
+ count = count + 2 /* two octet checksum */
+ }
+ privateKeyData = make([]byte, count)
+ _, err = readFull(r, privateKeyData)
+ if err != nil {
+ return
+ }
+ } else {
+ privateKeyData, err = ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ }
+ if !pk.Encrypted {
+ if len(privateKeyData) < 2 {
+ return errors.StructuralError("truncated private key data")
+ }
+ var sum uint16
+ for i := 0; i < len(privateKeyData)-2; i++ {
+ sum += uint16(privateKeyData[i])
+ }
+ if privateKeyData[len(privateKeyData)-2] != uint8(sum>>8) ||
+ privateKeyData[len(privateKeyData)-1] != uint8(sum) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ privateKeyData = privateKeyData[:len(privateKeyData)-2]
+ return pk.parsePrivateKey(privateKeyData)
+ }
+
+ pk.encryptedData = privateKeyData
+ return
+}
+
+// Dummy returns true if the private key is a dummy key. This is a GNU extension.
+func (pk *PrivateKey) Dummy() bool {
+ return pk.s2kParams.Dummy()
+}
+
+func mod64kHash(d []byte) uint16 {
+ var h uint16
+ for _, b := range d {
+ h += uint16(b)
+ }
+ return h
+}
+
+func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
+ contents := bytes.NewBuffer(nil)
+ err = pk.PublicKey.serializeWithoutHeaders(contents)
+ if err != nil {
+ return
+ }
+ if _, err = contents.Write([]byte{uint8(pk.s2kType)}); err != nil {
+ return
+ }
+
+ optional := bytes.NewBuffer(nil)
+ if pk.Encrypted || pk.Dummy() {
+ optional.Write([]byte{uint8(pk.cipher)})
+ if err := pk.s2kParams.Serialize(optional); err != nil {
+ return err
+ }
+ if pk.Encrypted {
+ optional.Write(pk.iv)
+ }
+ }
+ if pk.Version == 5 {
+ contents.Write([]byte{uint8(optional.Len())})
+ }
+ io.Copy(contents, optional)
+
+ if !pk.Dummy() {
+ l := 0
+ var priv []byte
+ if !pk.Encrypted {
+ buf := bytes.NewBuffer(nil)
+ err = pk.serializePrivateKey(buf)
+ if err != nil {
+ return err
+ }
+ l = buf.Len()
+ checksum := mod64kHash(buf.Bytes())
+ buf.Write([]byte{byte(checksum >> 8), byte(checksum)})
+ priv = buf.Bytes()
+ } else {
+ priv, l = pk.encryptedData, len(pk.encryptedData)
+ }
+
+ if pk.Version == 5 {
+ contents.Write([]byte{byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l)})
+ }
+ contents.Write(priv)
+ }
+
+ ptype := packetTypePrivateKey
+ if pk.IsSubkey {
+ ptype = packetTypePrivateSubkey
+ }
+ err = serializeHeader(w, ptype, contents.Len())
+ if err != nil {
+ return
+ }
+ _, err = io.Copy(w, contents)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.D).EncodedBytes()); err != nil {
+ return err
+ }
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.Primes[1]).EncodedBytes()); err != nil {
+ return err
+ }
+ if _, err := w.Write(new(encoding.MPI).SetBig(priv.Primes[0]).EncodedBytes()); err != nil {
+ return err
+ }
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.Precomputed.Qinv).EncodedBytes())
+ return err
+}
+
+func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.X).EncodedBytes())
+ return err
+}
+
+func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
+ _, err := w.Write(new(encoding.MPI).SetBig(priv.X).EncodedBytes())
+ return err
+}
+
+func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalIntegerSecret()).EncodedBytes())
+ return err
+}
+
+func serializeEdDSAPrivateKey(w io.Writer, priv *eddsa.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalByteSecret()).EncodedBytes())
+ return err
+}
+
+func serializeECDHPrivateKey(w io.Writer, priv *ecdh.PrivateKey) error {
+ _, err := w.Write(encoding.NewMPI(priv.MarshalByteSecret()).EncodedBytes())
+ return err
+}
+
+// decrypt decrypts an encrypted private key using a decryption key.
+func (pk *PrivateKey) decrypt(decryptionKey []byte) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ block := pk.cipher.new(decryptionKey)
+ cfb := cipher.NewCFBDecrypter(block, pk.iv)
+
+ data := make([]byte, len(pk.encryptedData))
+ cfb.XORKeyStream(data, pk.encryptedData)
+
+ if pk.sha1Checksum {
+ if len(data) < sha1.Size {
+ return errors.StructuralError("truncated private key data")
+ }
+ h := sha1.New()
+ h.Write(data[:len(data)-sha1.Size])
+ sum := h.Sum(nil)
+ if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ data = data[:len(data)-sha1.Size]
+ } else {
+ if len(data) < 2 {
+ return errors.StructuralError("truncated private key data")
+ }
+ var sum uint16
+ for i := 0; i < len(data)-2; i++ {
+ sum += uint16(data[i])
+ }
+ if data[len(data)-2] != uint8(sum>>8) ||
+ data[len(data)-1] != uint8(sum) {
+ return errors.StructuralError("private key checksum failure")
+ }
+ data = data[:len(data)-2]
+ }
+
+ err := pk.parsePrivateKey(data)
+ if _, ok := err.(errors.KeyInvalidError); ok {
+ return errors.KeyInvalidError("invalid key parameters")
+ }
+ if err != nil {
+ return err
+ }
+
+ // Mark key as unencrypted
+ pk.s2kType = S2KNON
+ pk.s2k = nil
+ pk.Encrypted = false
+ pk.encryptedData = nil
+
+ return nil
+}
+
+func (pk *PrivateKey) decryptWithCache(passphrase []byte, keyCache *s2k.Cache) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ key, err := keyCache.GetOrComputeDerivedKey(passphrase, pk.s2kParams, pk.cipher.KeySize())
+ if err != nil {
+ return err
+ }
+ return pk.decrypt(key)
+}
+
+// Decrypt decrypts an encrypted private key using a passphrase.
+func (pk *PrivateKey) Decrypt(passphrase []byte) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if !pk.Encrypted {
+ return nil
+ }
+
+ key := make([]byte, pk.cipher.KeySize())
+ pk.s2k(key, passphrase)
+ return pk.decrypt(key)
+}
+
+// DecryptPrivateKeys decrypts all encrypted keys with the given config and passphrase.
+// Avoids recomputation of similar s2k key derivations.
+func DecryptPrivateKeys(keys []*PrivateKey, passphrase []byte) error {
+ // Create a cache to avoid recomputation of key derviations for the same passphrase.
+ s2kCache := &s2k.Cache{}
+ for _, key := range keys {
+ if key != nil && !key.Dummy() && key.Encrypted {
+ err := key.decryptWithCache(passphrase, s2kCache)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// encrypt encrypts an unencrypted private key.
+func (pk *PrivateKey) encrypt(key []byte, params *s2k.Params, cipherFunction CipherFunction) error {
+ if pk.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ if pk.Encrypted {
+ return nil
+ }
+ // check if encryptionKey has the correct size
+ if len(key) != cipherFunction.KeySize() {
+ return errors.InvalidArgumentError("supplied encryption key has the wrong size")
+ }
+
+ priv := bytes.NewBuffer(nil)
+ err := pk.serializePrivateKey(priv)
+ if err != nil {
+ return err
+ }
+
+ pk.cipher = cipherFunction
+ pk.s2kParams = params
+ pk.s2k, err = pk.s2kParams.Function()
+ if err != nil {
+ return err
+ }
+
+ privateKeyBytes := priv.Bytes()
+ pk.sha1Checksum = true
+ block := pk.cipher.new(key)
+ pk.iv = make([]byte, pk.cipher.blockSize())
+ _, err = rand.Read(pk.iv)
+ if err != nil {
+ return err
+ }
+ cfb := cipher.NewCFBEncrypter(block, pk.iv)
+
+ if pk.sha1Checksum {
+ pk.s2kType = S2KSHA1
+ h := sha1.New()
+ h.Write(privateKeyBytes)
+ sum := h.Sum(nil)
+ privateKeyBytes = append(privateKeyBytes, sum...)
+ } else {
+ pk.s2kType = S2KCHECKSUM
+ var sum uint16
+ for _, b := range privateKeyBytes {
+ sum += uint16(b)
+ }
+ priv.Write([]byte{uint8(sum >> 8), uint8(sum)})
+ }
+
+ pk.encryptedData = make([]byte, len(privateKeyBytes))
+ cfb.XORKeyStream(pk.encryptedData, privateKeyBytes)
+ pk.Encrypted = true
+ pk.PrivateKey = nil
+ return err
+}
+
+// EncryptWithConfig encrypts an unencrypted private key using the passphrase and the config.
+func (pk *PrivateKey) EncryptWithConfig(passphrase []byte, config *Config) error {
+ params, err := s2k.Generate(config.Random(), config.S2K())
+ if err != nil {
+ return err
+ }
+ // Derive an encryption key with the configured s2k function.
+ key := make([]byte, config.Cipher().KeySize())
+ s2k, err := params.Function()
+ if err != nil {
+ return err
+ }
+ s2k(key, passphrase)
+ // Encrypt the private key with the derived encryption key.
+ return pk.encrypt(key, params, config.Cipher())
+}
+
+// EncryptPrivateKeys encrypts all unencrypted keys with the given config and passphrase.
+// Only derives one key from the passphrase, which is then used to encrypt each key.
+func EncryptPrivateKeys(keys []*PrivateKey, passphrase []byte, config *Config) error {
+ params, err := s2k.Generate(config.Random(), config.S2K())
+ if err != nil {
+ return err
+ }
+ // Derive an encryption key with the configured s2k function.
+ encryptionKey := make([]byte, config.Cipher().KeySize())
+ s2k, err := params.Function()
+ if err != nil {
+ return err
+ }
+ s2k(encryptionKey, passphrase)
+ for _, key := range keys {
+ if key != nil && !key.Dummy() && !key.Encrypted {
+ err = key.encrypt(encryptionKey, params, config.Cipher())
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// Encrypt encrypts an unencrypted private key using a passphrase.
+func (pk *PrivateKey) Encrypt(passphrase []byte) error {
+ // Default config of private key encryption
+ config := &Config{
+ S2KConfig: &s2k.Config{
+ S2KMode: s2k.IteratedSaltedS2K,
+ S2KCount: 65536,
+ Hash: crypto.SHA256,
+ } ,
+ DefaultCipher: CipherAES256,
+ }
+ return pk.EncryptWithConfig(passphrase, config)
+}
+
+func (pk *PrivateKey) serializePrivateKey(w io.Writer) (err error) {
+ switch priv := pk.PrivateKey.(type) {
+ case *rsa.PrivateKey:
+ err = serializeRSAPrivateKey(w, priv)
+ case *dsa.PrivateKey:
+ err = serializeDSAPrivateKey(w, priv)
+ case *elgamal.PrivateKey:
+ err = serializeElGamalPrivateKey(w, priv)
+ case *ecdsa.PrivateKey:
+ err = serializeECDSAPrivateKey(w, priv)
+ case *eddsa.PrivateKey:
+ err = serializeEdDSAPrivateKey(w, priv)
+ case *ecdh.PrivateKey:
+ err = serializeECDHPrivateKey(w, priv)
+ default:
+ err = errors.InvalidArgumentError("unknown private key type")
+ }
+ return
+}
+
+func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
+ switch pk.PublicKey.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
+ return pk.parseRSAPrivateKey(data)
+ case PubKeyAlgoDSA:
+ return pk.parseDSAPrivateKey(data)
+ case PubKeyAlgoElGamal:
+ return pk.parseElGamalPrivateKey(data)
+ case PubKeyAlgoECDSA:
+ return pk.parseECDSAPrivateKey(data)
+ case PubKeyAlgoECDH:
+ return pk.parseECDHPrivateKey(data)
+ case PubKeyAlgoEdDSA:
+ return pk.parseEdDSAPrivateKey(data)
+ }
+ panic("impossible")
+}
+
+func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
+ rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
+ rsaPriv := new(rsa.PrivateKey)
+ rsaPriv.PublicKey = *rsaPub
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ p := new(encoding.MPI)
+ if _, err := p.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ q := new(encoding.MPI)
+ if _, err := q.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ rsaPriv.D = new(big.Int).SetBytes(d.Bytes())
+ rsaPriv.Primes = make([]*big.Int, 2)
+ rsaPriv.Primes[0] = new(big.Int).SetBytes(p.Bytes())
+ rsaPriv.Primes[1] = new(big.Int).SetBytes(q.Bytes())
+ if err := rsaPriv.Validate(); err != nil {
+ return errors.KeyInvalidError(err.Error())
+ }
+ rsaPriv.Precompute()
+ pk.PrivateKey = rsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
+ dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
+ dsaPriv := new(dsa.PrivateKey)
+ dsaPriv.PublicKey = *dsaPub
+
+ buf := bytes.NewBuffer(data)
+ x := new(encoding.MPI)
+ if _, err := x.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ dsaPriv.X = new(big.Int).SetBytes(x.Bytes())
+ if err := validateDSAParameters(dsaPriv); err != nil {
+ return err
+ }
+ pk.PrivateKey = dsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
+ pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
+ priv := new(elgamal.PrivateKey)
+ priv.PublicKey = *pub
+
+ buf := bytes.NewBuffer(data)
+ x := new(encoding.MPI)
+ if _, err := x.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ priv.X = new(big.Int).SetBytes(x.Bytes())
+ if err := validateElGamalParameters(priv); err != nil {
+ return err
+ }
+ pk.PrivateKey = priv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
+ ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
+ ecdsaPriv := ecdsa.NewPrivateKey(*ecdsaPub)
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err := ecdsaPriv.UnmarshalIntegerSecret(d.Bytes()); err != nil {
+ return err
+ }
+ if err := ecdsa.Validate(ecdsaPriv); err != nil {
+ return err
+ }
+ pk.PrivateKey = ecdsaPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseECDHPrivateKey(data []byte) (err error) {
+ ecdhPub := pk.PublicKey.PublicKey.(*ecdh.PublicKey)
+ ecdhPriv := ecdh.NewPrivateKey(*ecdhPub)
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err := ecdhPriv.UnmarshalByteSecret(d.Bytes()); err != nil {
+ return err
+ }
+
+ if err := ecdh.Validate(ecdhPriv); err != nil {
+ return err
+ }
+
+ pk.PrivateKey = ecdhPriv
+
+ return nil
+}
+
+func (pk *PrivateKey) parseEdDSAPrivateKey(data []byte) (err error) {
+ eddsaPub := pk.PublicKey.PublicKey.(*eddsa.PublicKey)
+ eddsaPriv := eddsa.NewPrivateKey(*eddsaPub)
+ eddsaPriv.PublicKey = *eddsaPub
+
+ buf := bytes.NewBuffer(data)
+ d := new(encoding.MPI)
+ if _, err := d.ReadFrom(buf); err != nil {
+ return err
+ }
+
+ if err = eddsaPriv.UnmarshalByteSecret(d.Bytes()); err != nil {
+ return err
+ }
+
+ if err := eddsa.Validate(eddsaPriv); err != nil {
+ return err
+ }
+
+ pk.PrivateKey = eddsaPriv
+
+ return nil
+}
+
+func validateDSAParameters(priv *dsa.PrivateKey) error {
+ p := priv.P // group prime
+ q := priv.Q // subgroup order
+ g := priv.G // g has order q mod p
+ x := priv.X // secret
+ y := priv.Y // y == g**x mod p
+ one := big.NewInt(1)
+ // expect g, y >= 2 and g < p
+ if g.Cmp(one) <= 0 || y.Cmp(one) <= 0 || g.Cmp(p) > 0 {
+ return errors.KeyInvalidError("dsa: invalid group")
+ }
+ // expect p > q
+ if p.Cmp(q) <= 0 {
+ return errors.KeyInvalidError("dsa: invalid group prime")
+ }
+ // q should be large enough and divide p-1
+ pSub1 := new(big.Int).Sub(p, one)
+ if q.BitLen() < 150 || new(big.Int).Mod(pSub1, q).Cmp(big.NewInt(0)) != 0 {
+ return errors.KeyInvalidError("dsa: invalid order")
+ }
+ // confirm that g has order q mod p
+ if !q.ProbablyPrime(32) || new(big.Int).Exp(g, q, p).Cmp(one) != 0 {
+ return errors.KeyInvalidError("dsa: invalid order")
+ }
+ // check y
+ if new(big.Int).Exp(g, x, p).Cmp(y) != 0 {
+ return errors.KeyInvalidError("dsa: mismatching values")
+ }
+
+ return nil
+}
+
+func validateElGamalParameters(priv *elgamal.PrivateKey) error {
+ p := priv.P // group prime
+ g := priv.G // g has order p-1 mod p
+ x := priv.X // secret
+ y := priv.Y // y == g**x mod p
+ one := big.NewInt(1)
+ // Expect g, y >= 2 and g < p
+ if g.Cmp(one) <= 0 || y.Cmp(one) <= 0 || g.Cmp(p) > 0 {
+ return errors.KeyInvalidError("elgamal: invalid group")
+ }
+ if p.BitLen() < 1024 {
+ return errors.KeyInvalidError("elgamal: group order too small")
+ }
+ pSub1 := new(big.Int).Sub(p, one)
+ if new(big.Int).Exp(g, pSub1, p).Cmp(one) != 0 {
+ return errors.KeyInvalidError("elgamal: invalid group")
+ }
+ // Since p-1 is not prime, g might have a smaller order that divides p-1.
+ // We cannot confirm the exact order of g, but we make sure it is not too small.
+ gExpI := new(big.Int).Set(g)
+ i := 1
+ threshold := 2 << 17 // we want order > threshold
+ for i < threshold {
+ i++ // we check every order to make sure key validation is not easily bypassed by guessing y'
+ gExpI.Mod(new(big.Int).Mul(gExpI, g), p)
+ if gExpI.Cmp(one) == 0 {
+ return errors.KeyInvalidError("elgamal: order too small")
+ }
+ }
+ // Check y
+ if new(big.Int).Exp(g, x, p).Cmp(y) != 0 {
+ return errors.KeyInvalidError("elgamal: mismatching values")
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go
new file mode 100644
index 0000000..029b8f1
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/private_key_test_data.go
@@ -0,0 +1,12 @@
+package packet
+
+// Generated with `gpg --export-secret-keys "Test Key 2"`
+const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec"
+
+// Generated by `gpg --export-secret-keys` followed by a manual extraction of
+// the ElGamal subkey from the packets.
+const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc"
+
+// pkcs1PrivKeyHex is a PKCS#1, RSA private key.
+// Generated by `openssl genrsa 1024 | openssl rsa -outform DER | xxd -p`
+const pkcs1PrivKeyHex = "3082025d02010002818100e98edfa1c3b35884a54d0b36a6a603b0290fa85e49e30fa23fc94fef9c6790bc4849928607aa48d809da326fb42a969d06ad756b98b9c1a90f5d4a2b6d0ac05953c97f4da3120164a21a679793ce181c906dc01d235cc085ddcdf6ea06c389b6ab8885dfd685959e693138856a68a7e5db263337ff82a088d583a897cf2d59e9020301000102818100b6d5c9eb70b02d5369b3ee5b520a14490b5bde8a317d36f7e4c74b7460141311d1e5067735f8f01d6f5908b2b96fbd881f7a1ab9a84d82753e39e19e2d36856be960d05ac9ef8e8782ea1b6d65aee28fdfe1d61451e8cff0adfe84322f12cf455028b581cf60eb9e0e140ba5d21aeba6c2634d7c65318b9a665fc01c3191ca21024100fa5e818da3705b0fa33278bb28d4b6f6050388af2d4b75ec9375dd91ccf2e7d7068086a8b82a8f6282e4fbbdb8a7f2622eb97295249d87acea7f5f816f54d347024100eecf9406d7dc49cdfb95ab1eff4064de84c7a30f64b2798936a0d2018ba9eb52e4b636f82e96c49cc63b80b675e91e40d1b2e4017d4b9adaf33ab3d9cf1c214f024100c173704ace742c082323066226a4655226819a85304c542b9dacbeacbf5d1881ee863485fcf6f59f3a604f9b42289282067447f2b13dfeed3eab7851fc81e0550240741fc41f3fc002b382eed8730e33c5d8de40256e4accee846667f536832f711ab1d4590e7db91a8a116ac5bff3be13d3f9243ff2e976662aa9b395d907f8e9c9024046a5696c9ef882363e06c9fa4e2f5b580906452befba03f4a99d0f873697ef1f851d2226ca7934b30b7c3e80cb634a67172bbbf4781735fe3e09263e2dd723e7"
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
new file mode 100644
index 0000000..3402b8c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
@@ -0,0 +1,806 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto"
+ "crypto/dsa"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ _ "crypto/sha512"
+ "encoding/binary"
+ "fmt"
+ "hash"
+ "io"
+ "math/big"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdh"
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/elgamal"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+type kdfHashFunction byte
+type kdfAlgorithm byte
+
+// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
+type PublicKey struct {
+ Version int
+ CreationTime time.Time
+ PubKeyAlgo PublicKeyAlgorithm
+ PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey or *eddsa.PublicKey
+ Fingerprint []byte
+ KeyId uint64
+ IsSubkey bool
+
+ // RFC 4880 fields
+ n, e, p, q, g, y encoding.Field
+
+ // RFC 6637 fields
+ // oid contains the OID byte sequence identifying the elliptic curve used
+ oid encoding.Field
+
+ // kdf stores key derivation function parameters
+ // used for ECDH encryption. See RFC 6637, Section 9.
+ kdf encoding.Field
+}
+
+// UpgradeToV5 updates the version of the key to v5, and updates all necessary
+// fields.
+func (pk *PublicKey) UpgradeToV5() {
+ pk.Version = 5
+ pk.setFingerprintAndKeyId()
+}
+
+// signingKey provides a convenient abstraction over signature verification
+// for v3 and v4 public keys.
+type signingKey interface {
+ SerializeForHash(io.Writer) error
+ SerializeSignaturePrefix(io.Writer)
+ serializeWithoutHeaders(io.Writer) error
+}
+
+// NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
+func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoRSA,
+ PublicKey: pub,
+ n: new(encoding.MPI).SetBig(pub.N),
+ e: new(encoding.MPI).SetBig(big.NewInt(int64(pub.E))),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+// NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
+func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoDSA,
+ PublicKey: pub,
+ p: new(encoding.MPI).SetBig(pub.P),
+ q: new(encoding.MPI).SetBig(pub.Q),
+ g: new(encoding.MPI).SetBig(pub.G),
+ y: new(encoding.MPI).SetBig(pub.Y),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
+func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoElGamal,
+ PublicKey: pub,
+ p: new(encoding.MPI).SetBig(pub.P),
+ g: new(encoding.MPI).SetBig(pub.G),
+ y: new(encoding.MPI).SetBig(pub.Y),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoECDSA,
+ PublicKey: pub,
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ }
+
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+ if curveInfo == nil {
+ panic("unknown elliptic curve")
+ }
+ pk.oid = curveInfo.Oid
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewECDHPublicKey(creationTime time.Time, pub *ecdh.PublicKey) *PublicKey {
+ var pk *PublicKey
+ var kdf = encoding.NewOID([]byte{0x1, pub.Hash.Id(), pub.Cipher.Id()})
+ pk = &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoECDH,
+ PublicKey: pub,
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ kdf: kdf,
+ }
+
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+
+ if curveInfo == nil {
+ panic("unknown elliptic curve")
+ }
+
+ pk.oid = curveInfo.Oid
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func NewEdDSAPublicKey(creationTime time.Time, pub *eddsa.PublicKey) *PublicKey {
+ curveInfo := ecc.FindByCurve(pub.GetCurve())
+ pk := &PublicKey{
+ Version: 4,
+ CreationTime: creationTime,
+ PubKeyAlgo: PubKeyAlgoEdDSA,
+ PublicKey: pub,
+ oid: curveInfo.Oid,
+ // Native point format, see draft-koch-eddsa-for-openpgp-04, Appendix B
+ p: encoding.NewMPI(pub.MarshalPoint()),
+ }
+
+ pk.setFingerprintAndKeyId()
+ return pk
+}
+
+func (pk *PublicKey) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.5.2
+ var buf [6]byte
+ _, err = readFull(r, buf[:])
+ if err != nil {
+ return
+ }
+ if buf[0] != 4 && buf[0] != 5 {
+ return errors.UnsupportedError("public key version " + strconv.Itoa(int(buf[0])))
+ }
+
+ pk.Version = int(buf[0])
+ if pk.Version == 5 {
+ var n [4]byte
+ _, err = readFull(r, n[:])
+ if err != nil {
+ return
+ }
+ }
+ pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
+ pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ err = pk.parseRSA(r)
+ case PubKeyAlgoDSA:
+ err = pk.parseDSA(r)
+ case PubKeyAlgoElGamal:
+ err = pk.parseElGamal(r)
+ case PubKeyAlgoECDSA:
+ err = pk.parseECDSA(r)
+ case PubKeyAlgoECDH:
+ err = pk.parseECDH(r)
+ case PubKeyAlgoEdDSA:
+ err = pk.parseEdDSA(r)
+ default:
+ err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
+ }
+ if err != nil {
+ return
+ }
+
+ pk.setFingerprintAndKeyId()
+ return
+}
+
+func (pk *PublicKey) setFingerprintAndKeyId() {
+ // RFC 4880, section 12.2
+ if pk.Version == 5 {
+ fingerprint := sha256.New()
+ pk.SerializeForHash(fingerprint)
+ pk.Fingerprint = make([]byte, 32)
+ copy(pk.Fingerprint, fingerprint.Sum(nil))
+ pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[:8])
+ } else {
+ fingerprint := sha1.New()
+ pk.SerializeForHash(fingerprint)
+ pk.Fingerprint = make([]byte, 20)
+ copy(pk.Fingerprint, fingerprint.Sum(nil))
+ pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
+ }
+}
+
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
+ pk.n = new(encoding.MPI)
+ if _, err = pk.n.ReadFrom(r); err != nil {
+ return
+ }
+ pk.e = new(encoding.MPI)
+ if _, err = pk.e.ReadFrom(r); err != nil {
+ return
+ }
+
+ if len(pk.e.Bytes()) > 3 {
+ err = errors.UnsupportedError("large public exponent")
+ return
+ }
+ rsa := &rsa.PublicKey{
+ N: new(big.Int).SetBytes(pk.n.Bytes()),
+ E: 0,
+ }
+ for i := 0; i < len(pk.e.Bytes()); i++ {
+ rsa.E <<= 8
+ rsa.E |= int(pk.e.Bytes()[i])
+ }
+ pk.PublicKey = rsa
+ return
+}
+
+// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
+// section 5.5.2.
+func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.q = new(encoding.MPI)
+ if _, err = pk.q.ReadFrom(r); err != nil {
+ return
+ }
+ pk.g = new(encoding.MPI)
+ if _, err = pk.g.ReadFrom(r); err != nil {
+ return
+ }
+ pk.y = new(encoding.MPI)
+ if _, err = pk.y.ReadFrom(r); err != nil {
+ return
+ }
+
+ dsa := new(dsa.PublicKey)
+ dsa.P = new(big.Int).SetBytes(pk.p.Bytes())
+ dsa.Q = new(big.Int).SetBytes(pk.q.Bytes())
+ dsa.G = new(big.Int).SetBytes(pk.g.Bytes())
+ dsa.Y = new(big.Int).SetBytes(pk.y.Bytes())
+ pk.PublicKey = dsa
+ return
+}
+
+// parseElGamal parses ElGamal public key material from the given Reader. See
+// RFC 4880, section 5.5.2.
+func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.g = new(encoding.MPI)
+ if _, err = pk.g.ReadFrom(r); err != nil {
+ return
+ }
+ pk.y = new(encoding.MPI)
+ if _, err = pk.y.ReadFrom(r); err != nil {
+ return
+ }
+
+ elgamal := new(elgamal.PublicKey)
+ elgamal.P = new(big.Int).SetBytes(pk.p.Bytes())
+ elgamal.G = new(big.Int).SetBytes(pk.g.Bytes())
+ elgamal.Y = new(big.Int).SetBytes(pk.y.Bytes())
+ pk.PublicKey = elgamal
+ return
+}
+
+// parseECDSA parses ECDSA public key material from the given Reader. See
+// RFC 6637, Section 9.
+func (pk *PublicKey) parseECDSA(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+
+ curveInfo := ecc.FindByOid(pk.oid)
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.ECDSACurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ ecdsaKey := ecdsa.NewPublicKey(c)
+ err = ecdsaKey.UnmarshalPoint(pk.p.Bytes())
+ pk.PublicKey = ecdsaKey
+
+ return
+}
+
+// parseECDH parses ECDH public key material from the given Reader. See
+// RFC 6637, Section 9.
+func (pk *PublicKey) parseECDH(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+ pk.kdf = new(encoding.OID)
+ if _, err = pk.kdf.ReadFrom(r); err != nil {
+ return
+ }
+
+ curveInfo := ecc.FindByOid(pk.oid)
+
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.ECDHCurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ if kdfLen := len(pk.kdf.Bytes()); kdfLen < 3 {
+ return errors.UnsupportedError("unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
+ }
+ if reserved := pk.kdf.Bytes()[0]; reserved != 0x01 {
+ return errors.UnsupportedError("unsupported KDF reserved field: " + strconv.Itoa(int(reserved)))
+ }
+ kdfHash, ok := algorithm.HashById[pk.kdf.Bytes()[1]]
+ if !ok {
+ return errors.UnsupportedError("unsupported ECDH KDF hash: " + strconv.Itoa(int(pk.kdf.Bytes()[1])))
+ }
+ kdfCipher, ok := algorithm.CipherById[pk.kdf.Bytes()[2]]
+ if !ok {
+ return errors.UnsupportedError("unsupported ECDH KDF cipher: " + strconv.Itoa(int(pk.kdf.Bytes()[2])))
+ }
+
+ ecdhKey := ecdh.NewPublicKey(c, kdfHash, kdfCipher)
+ err = ecdhKey.UnmarshalPoint(pk.p.Bytes())
+ pk.PublicKey = ecdhKey
+
+ return
+}
+
+func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) {
+ pk.oid = new(encoding.OID)
+ if _, err = pk.oid.ReadFrom(r); err != nil {
+ return
+ }
+ curveInfo := ecc.FindByOid(pk.oid)
+ if curveInfo == nil {
+ return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
+ }
+
+ c, ok := curveInfo.Curve.(ecc.EdDSACurve)
+ if !ok {
+ return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
+ }
+
+ pk.p = new(encoding.MPI)
+ if _, err = pk.p.ReadFrom(r); err != nil {
+ return
+ }
+
+ if len(pk.p.Bytes()) == 0 {
+ return errors.StructuralError("empty EdDSA public key")
+ }
+
+ pub := eddsa.NewPublicKey(c)
+
+ switch flag := pk.p.Bytes()[0]; flag {
+ case 0x04:
+ // TODO: see _grcy_ecc_eddsa_ensure_compact in grcypt
+ return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
+ case 0x40:
+ err = pub.UnmarshalPoint(pk.p.Bytes())
+ default:
+ return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
+ }
+
+ pk.PublicKey = pub
+ return
+}
+
+// SerializeForHash serializes the PublicKey to w with the special packet
+// header format needed for hashing.
+func (pk *PublicKey) SerializeForHash(w io.Writer) error {
+ pk.SerializeSignaturePrefix(w)
+ return pk.serializeWithoutHeaders(w)
+}
+
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
+// The prefix is used when calculating a signature over this public key. See
+// RFC 4880, section 5.2.4.
+func (pk *PublicKey) SerializeSignaturePrefix(w io.Writer) {
+ var pLength = pk.algorithmSpecificByteCount()
+ if pk.Version == 5 {
+ pLength += 10 // version, timestamp (4), algorithm, key octet count (4).
+ w.Write([]byte{
+ 0x9A,
+ byte(pLength >> 24),
+ byte(pLength >> 16),
+ byte(pLength >> 8),
+ byte(pLength),
+ })
+ return
+ }
+ pLength += 6
+ w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
+}
+
+func (pk *PublicKey) Serialize(w io.Writer) (err error) {
+ length := 6 // 6 byte header
+ length += pk.algorithmSpecificByteCount()
+ if pk.Version == 5 {
+ length += 4 // octet key count
+ }
+ packetType := packetTypePublicKey
+ if pk.IsSubkey {
+ packetType = packetTypePublicSubkey
+ }
+ err = serializeHeader(w, packetType, length)
+ if err != nil {
+ return
+ }
+ return pk.serializeWithoutHeaders(w)
+}
+
+func (pk *PublicKey) algorithmSpecificByteCount() int {
+ length := 0
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ length += int(pk.n.EncodedLength())
+ length += int(pk.e.EncodedLength())
+ case PubKeyAlgoDSA:
+ length += int(pk.p.EncodedLength())
+ length += int(pk.q.EncodedLength())
+ length += int(pk.g.EncodedLength())
+ length += int(pk.y.EncodedLength())
+ case PubKeyAlgoElGamal:
+ length += int(pk.p.EncodedLength())
+ length += int(pk.g.EncodedLength())
+ length += int(pk.y.EncodedLength())
+ case PubKeyAlgoECDSA:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ case PubKeyAlgoECDH:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ length += int(pk.kdf.EncodedLength())
+ case PubKeyAlgoEdDSA:
+ length += int(pk.oid.EncodedLength())
+ length += int(pk.p.EncodedLength())
+ default:
+ panic("unknown public key algorithm")
+ }
+ return length
+}
+
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
+// OpenPGP public key packet, not including the packet header.
+func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
+ t := uint32(pk.CreationTime.Unix())
+ if _, err = w.Write([]byte{
+ byte(pk.Version),
+ byte(t >> 24), byte(t >> 16), byte(t >> 8), byte(t),
+ byte(pk.PubKeyAlgo),
+ }); err != nil {
+ return
+ }
+
+ if pk.Version == 5 {
+ n := pk.algorithmSpecificByteCount()
+ if _, err = w.Write([]byte{
+ byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
+ }); err != nil {
+ return
+ }
+ }
+
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ if _, err = w.Write(pk.n.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.e.EncodedBytes())
+ return
+ case PubKeyAlgoDSA:
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.q.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.y.EncodedBytes())
+ return
+ case PubKeyAlgoElGamal:
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.y.EncodedBytes())
+ return
+ case PubKeyAlgoECDSA:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.p.EncodedBytes())
+ return
+ case PubKeyAlgoECDH:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.kdf.EncodedBytes())
+ return
+ case PubKeyAlgoEdDSA:
+ if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(pk.p.EncodedBytes())
+ return
+ }
+ return errors.InvalidArgumentError("bad public-key algorithm")
+}
+
+// CanSign returns true iff this public key can generate signatures
+func (pk *PublicKey) CanSign() bool {
+ return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal && pk.PubKeyAlgo != PubKeyAlgoECDH
+}
+
+// VerifySignature returns nil iff sig is a valid signature, made by this
+// public key, of the data hashed into signed. signed is mutated by this call.
+func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
+ if !pk.CanSign() {
+ return errors.InvalidArgumentError("public key cannot generate signatures")
+ }
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.AddMetadataToHashSuffix()
+ }
+ signed.Write(sig.HashSuffix)
+ hashBytes := signed.Sum(nil)
+ if sig.Version == 5 && (hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1]) {
+ return errors.SignatureError("hash tag doesn't match")
+ }
+
+ if pk.PubKeyAlgo != sig.PubKeyAlgo {
+ return errors.InvalidArgumentError("public key and signature use different algorithms")
+ }
+
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
+ err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.Bytes()))
+ if err != nil {
+ return errors.SignatureError("RSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoDSA:
+ dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
+ // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+ subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
+ if len(hashBytes) > subgroupSize {
+ hashBytes = hashBytes[:subgroupSize]
+ }
+ if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.Bytes()), new(big.Int).SetBytes(sig.DSASigS.Bytes())) {
+ return errors.SignatureError("DSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoECDSA:
+ ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
+ if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.Bytes()), new(big.Int).SetBytes(sig.ECDSASigS.Bytes())) {
+ return errors.SignatureError("ECDSA verification failure")
+ }
+ return nil
+ case PubKeyAlgoEdDSA:
+ eddsaPublicKey := pk.PublicKey.(*eddsa.PublicKey)
+ if !eddsa.Verify(eddsaPublicKey, hashBytes, sig.EdDSASigR.Bytes(), sig.EdDSASigS.Bytes()) {
+ return errors.SignatureError("EdDSA verification failure")
+ }
+ return nil
+ default:
+ return errors.SignatureError("Unsupported public key algorithm used in signature")
+ }
+}
+
+// keySignatureHash returns a Hash of the message that needs to be signed for
+// pk to assert a subkey relationship to signed.
+func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ err = pk.SerializeForHash(h)
+ if err != nil {
+ return nil, err
+ }
+
+ err = signed.SerializeForHash(h)
+ return
+}
+
+// VerifyKeySignature returns nil iff sig is a valid signature, made by this
+// public key, of signed.
+func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
+ h, err := keySignatureHash(pk, signed, sig.Hash)
+ if err != nil {
+ return err
+ }
+ if err = pk.VerifySignature(h, sig); err != nil {
+ return err
+ }
+
+ if sig.FlagSign {
+ // Signing subkeys must be cross-signed. See
+ // https://www.gnupg.org/faq/subkey-cross-certify.html.
+ if sig.EmbeddedSignature == nil {
+ return errors.StructuralError("signing subkey is missing cross-signature")
+ }
+ // Verify the cross-signature. This is calculated over the same
+ // data as the main signature, so we cannot just recursively
+ // call signed.VerifyKeySignature(...)
+ if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
+ return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
+ }
+ if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
+ return errors.StructuralError("error while verifying cross-signature: " + err.Error())
+ }
+ }
+
+ return nil
+}
+
+func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ err = pk.SerializeForHash(h)
+
+ return
+}
+
+// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
+// public key.
+func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
+ h, err := keyRevocationHash(pk, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// VerifySubkeyRevocationSignature returns nil iff sig is a valid subkey revocation signature,
+// made by this public key, of signed.
+func (pk *PublicKey) VerifySubkeyRevocationSignature(sig *Signature, signed *PublicKey) (err error) {
+ h, err := keySignatureHash(pk, signed, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// userIdSignatureHash returns a Hash of the message that needs to be signed
+// to assert that pk is a valid key for id.
+func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
+ if !hashFunc.Available() {
+ return nil, errors.UnsupportedError("hash function")
+ }
+ h = hashFunc.New()
+
+ // RFC 4880, section 5.2.4
+ pk.SerializeSignaturePrefix(h)
+ pk.serializeWithoutHeaders(h)
+
+ var buf [5]byte
+ buf[0] = 0xb4
+ buf[1] = byte(len(id) >> 24)
+ buf[2] = byte(len(id) >> 16)
+ buf[3] = byte(len(id) >> 8)
+ buf[4] = byte(len(id))
+ h.Write(buf[:])
+ h.Write([]byte(id))
+
+ return
+}
+
+// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
+// public key, that id is the identity of pub.
+func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
+ h, err := userIdSignatureHash(id, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return pk.VerifySignature(h, sig)
+}
+
+// KeyIdString returns the public key's fingerprint in capital hex
+// (e.g. "6C7EE1B8621CC013").
+func (pk *PublicKey) KeyIdString() string {
+ return fmt.Sprintf("%X", pk.Fingerprint[12:20])
+}
+
+// KeyIdShortString returns the short form of public key's fingerprint
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
+func (pk *PublicKey) KeyIdShortString() string {
+ return fmt.Sprintf("%X", pk.Fingerprint[16:20])
+}
+
+// BitLength returns the bit length for the given public key.
+func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
+ switch pk.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
+ bitLength = pk.n.BitLength()
+ case PubKeyAlgoDSA:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoElGamal:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoECDSA:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoECDH:
+ bitLength = pk.p.BitLength()
+ case PubKeyAlgoEdDSA:
+ bitLength = pk.p.BitLength()
+ default:
+ err = errors.InvalidArgumentError("bad public-key algorithm")
+ }
+ return
+}
+
+// KeyExpired returns whether sig is a self-signature of a key that has
+// expired or is created in the future.
+func (pk *PublicKey) KeyExpired(sig *Signature, currentTime time.Time) bool {
+ if pk.CreationTime.After(currentTime) {
+ return true
+ }
+ if sig.KeyLifetimeSecs == nil || *sig.KeyLifetimeSecs == 0 {
+ return false
+ }
+ expiry := pk.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
+ return currentTime.After(expiry)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go
new file mode 100644
index 0000000..b255f1f
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key_test_data.go
@@ -0,0 +1,24 @@
+package packet
+
+const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb"
+
+const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001"
+
+const dsaFingerprintHex = "eece4c094db002103714c63c8e8fbe54062f19ed"
+
+const dsaPkDataHex = "9901a2044d432f89110400cd581334f0d7a1e1bdc8b9d6d8c0baf68793632735d2bb0903224cbaa1dfbf35a60ee7a13b92643421e1eb41aa8d79bea19a115a677f6b8ba3c7818ce53a6c2a24a1608bd8b8d6e55c5090cbde09dd26e356267465ae25e69ec8bdd57c7bbb2623e4d73336f73a0a9098f7f16da2e25252130fd694c0e8070c55a812a423ae7f00a0ebf50e70c2f19c3520a551bd4b08d30f23530d3d03ff7d0bf4a53a64a09dc5e6e6e35854b7d70c882b0c60293401958b1bd9e40abec3ea05ba87cf64899299d4bd6aa7f459c201d3fbbd6c82004bdc5e8a9eb8082d12054cc90fa9d4ec251a843236a588bf49552441817436c4f43326966fe85447d4e6d0acf8fa1ef0f014730770603ad7634c3088dc52501c237328417c31c89ed70400b2f1a98b0bf42f11fefc430704bebbaa41d9f355600c3facee1e490f64208e0e094ea55e3a598a219a58500bf78ac677b670a14f4e47e9cf8eab4f368cc1ddcaa18cc59309d4cc62dd4f680e73e6cc3e1ce87a84d0925efbcb26c575c093fc42eecf45135fabf6403a25c2016e1774c0484e440a18319072c617cc97ac0a3bb0"
+
+const ecdsaFingerprintHex = "9892270b38b8980b05c8d56d43fe956c542ca00b"
+
+const ecdsaPkDataHex = "9893045071c29413052b8104002304230401f4867769cedfa52c325018896245443968e52e51d0c2df8d939949cb5b330f2921711fbee1c9b9dddb95d15cb0255e99badeddda7cc23d9ddcaacbc290969b9f24019375d61c2e4e3b36953a28d8b2bc95f78c3f1d592fb24499be348656a7b17e3963187b4361afe497bc5f9f81213f04069f8e1fb9e6a6290ae295ca1a92b894396cb4"
+
+const ecdhFingerprintHex = "722354df2475a42164d1d49faa8b938f9a201946"
+
+const ecdhPkDataHex = "b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec91803010909"
+
+const eddsaFingerprintHex = "b2d5e5ec0e6deca6bc8eeeb00907e75e1dd99ad8"
+
+const eddsaPkDataHex = "98330456e2132b16092b06010401da470f01010740bbda39266affa511a8c2d02edf690fb784b0499c4406185811a163539ef11dc1b41d74657374696e67203c74657374696e674074657374696e672e636f6d3e8879041316080021050256e2132b021b03050b09080702061508090a0b020416020301021e01021780000a09100907e75e1dd99ad86d0c00fe39d2008359352782bc9b61ac382584cd8eff3f57a18c2287e3afeeb05d1f04ba00fe2d0bc1ddf3ff8adb9afa3e7d9287244b4ec567f3db4d60b74a9b5465ed528203"
+
+// Source: https://sites.google.com/site/brainhub/pgpecckeys#TOC-ECC-NIST-P-384-key
+const ecc384PubHex = `99006f044d53059213052b81040022030304f6b8c5aced5b84ef9f4a209db2e4a9dfb70d28cb8c10ecd57674a9fa5a67389942b62d5e51367df4c7bfd3f8e500feecf07ed265a621a8ebbbe53e947ec78c677eba143bd1533c2b350e1c29f82313e1e1108eba063be1e64b10e6950e799c2db42465635f6473615f64685f333834203c6f70656e70677040627261696e6875622e6f72673e8900cb04101309005305024d530592301480000000002000077072656665727265642d656d61696c2d656e636f64696e67407067702e636f6d7067706d696d65040b090807021901051b03000000021602051e010000000415090a08000a0910098033880f54719fca2b0180aa37350968bd5f115afd8ce7bc7b103822152dbff06d0afcda835329510905b98cb469ba208faab87c7412b799e7b633017f58364ea480e8a1a3f253a0c5f22c446e8be9a9fce6210136ee30811abbd49139de28b5bdf8dc36d06ae748579e9ff503b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec9180301090989008404181309000c05024d530592051b0c000000000a0910098033880f54719f80970180eee7a6d8fcee41ee4f9289df17f9bcf9d955dca25c583b94336f3a2b2d4986dc5cf417b8d2dc86f741a9e1a6d236c0e3017d1c76575458a0cfb93ae8a2b274fcc65ceecd7a91eec83656ba13219969f06945b48c56bd04152c3a0553c5f2f4bd1267`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go
new file mode 100644
index 0000000..10215fe
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/reader.go
@@ -0,0 +1,86 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// Reader reads packets from an io.Reader and allows packets to be 'unread' so
+// that they result from the next call to Next.
+type Reader struct {
+ q []Packet
+ readers []io.Reader
+}
+
+// New io.Readers are pushed when a compressed or encrypted packet is processed
+// and recursively treated as a new source of packets. However, a carefully
+// crafted packet can trigger an infinite recursive sequence of packets. See
+// http://mumble.net/~campbell/misc/pgp-quine
+// https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402
+// This constant limits the number of recursive packets that may be pushed.
+const maxReaders = 32
+
+// Next returns the most recently unread Packet, or reads another packet from
+// the top-most io.Reader. Unknown packet types are skipped.
+func (r *Reader) Next() (p Packet, err error) {
+ if len(r.q) > 0 {
+ p = r.q[len(r.q)-1]
+ r.q = r.q[:len(r.q)-1]
+ return
+ }
+
+ for len(r.readers) > 0 {
+ p, err = Read(r.readers[len(r.readers)-1])
+ if err == nil {
+ return
+ }
+ if err == io.EOF {
+ r.readers = r.readers[:len(r.readers)-1]
+ continue
+ }
+ // TODO: Add strict mode that rejects unknown packets, instead of ignoring them.
+ if _, ok := err.(errors.UnknownPacketTypeError); ok {
+ continue
+ }
+ if _, ok := err.(errors.UnsupportedError); ok {
+ switch p.(type) {
+ case *SymmetricallyEncrypted, *AEADEncrypted, *Compressed, *LiteralData:
+ return nil, err
+ }
+ continue
+ }
+ return nil, err
+ }
+
+ return nil, io.EOF
+}
+
+// Push causes the Reader to start reading from a new io.Reader. When an EOF
+// error is seen from the new io.Reader, it is popped and the Reader continues
+// to read from the next most recent io.Reader. Push returns a StructuralError
+// if pushing the reader would exceed the maximum recursion level, otherwise it
+// returns nil.
+func (r *Reader) Push(reader io.Reader) (err error) {
+ if len(r.readers) >= maxReaders {
+ return errors.StructuralError("too many layers of packets")
+ }
+ r.readers = append(r.readers, reader)
+ return nil
+}
+
+// Unread causes the given Packet to be returned from the next call to Next.
+func (r *Reader) Unread(p Packet) {
+ r.q = append(r.q, p)
+}
+
+func NewReader(r io.Reader) *Reader {
+ return &Reader{
+ q: nil,
+ readers: []io.Reader{r},
+ }
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
new file mode 100644
index 0000000..80d0bb9
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
@@ -0,0 +1,1084 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/dsa"
+ "encoding/binary"
+ "hash"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
+ "github.com/ProtonMail/go-crypto/openpgp/eddsa"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
+)
+
+const (
+ // See RFC 4880, section 5.2.3.21 for details.
+ KeyFlagCertify = 1 << iota
+ KeyFlagSign
+ KeyFlagEncryptCommunications
+ KeyFlagEncryptStorage
+ KeyFlagSplitKey
+ KeyFlagAuthenticate
+ _
+ KeyFlagGroupKey
+)
+
+// Signature represents a signature. See RFC 4880, section 5.2.
+type Signature struct {
+ Version int
+ SigType SignatureType
+ PubKeyAlgo PublicKeyAlgorithm
+ Hash crypto.Hash
+
+ // HashSuffix is extra data that is hashed in after the signed data.
+ HashSuffix []byte
+ // HashTag contains the first two bytes of the hash for fast rejection
+ // of bad signed data.
+ HashTag [2]byte
+
+ // Metadata includes format, filename and time, and is protected by v5
+ // signatures of type 0x00 or 0x01. This metadata is included into the hash
+ // computation; if nil, six 0x00 bytes are used instead. See section 5.2.4.
+ Metadata *LiteralData
+
+ CreationTime time.Time
+
+ RSASignature encoding.Field
+ DSASigR, DSASigS encoding.Field
+ ECDSASigR, ECDSASigS encoding.Field
+ EdDSASigR, EdDSASigS encoding.Field
+
+ // rawSubpackets contains the unparsed subpackets, in order.
+ rawSubpackets []outputSubpacket
+
+ // The following are optional so are nil when not included in the
+ // signature.
+
+ SigLifetimeSecs, KeyLifetimeSecs *uint32
+ PreferredSymmetric, PreferredHash, PreferredCompression []uint8
+ PreferredCipherSuites [][2]uint8
+ IssuerKeyId *uint64
+ IssuerFingerprint []byte
+ SignerUserId *string
+ IsPrimaryId *bool
+ Notations []*Notation
+
+ // TrustLevel and TrustAmount can be set by the signer to assert that
+ // the key is not only valid but also trustworthy at the specified
+ // level.
+ // See RFC 4880, section 5.2.3.13 for details.
+ TrustLevel TrustLevel
+ TrustAmount TrustAmount
+
+ // TrustRegularExpression can be used in conjunction with trust Signature
+ // packets to limit the scope of the trust that is extended.
+ // See RFC 4880, section 5.2.3.14 for details.
+ TrustRegularExpression *string
+
+ // PolicyURI can be set to the URI of a document that describes the
+ // policy under which the signature was issued. See RFC 4880, section
+ // 5.2.3.20 for details.
+ PolicyURI string
+
+ // FlagsValid is set if any flags were given. See RFC 4880, section
+ // 5.2.3.21 for details.
+ FlagsValid bool
+ FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage, FlagSplitKey, FlagAuthenticate, FlagGroupKey bool
+
+ // RevocationReason is set if this signature has been revoked.
+ // See RFC 4880, section 5.2.3.23 for details.
+ RevocationReason *ReasonForRevocation
+ RevocationReasonText string
+
+ // In a self-signature, these flags are set there is a features subpacket
+ // indicating that the issuer implementation supports these features
+ // see https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#features-subpacket
+ SEIPDv1, SEIPDv2 bool
+
+ // EmbeddedSignature, if non-nil, is a signature of the parent key, by
+ // this key. This prevents an attacker from claiming another's signing
+ // subkey as their own.
+ EmbeddedSignature *Signature
+
+ outSubpackets []outputSubpacket
+}
+
+func (sig *Signature) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.2.3
+ var buf [5]byte
+ _, err = readFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+ if buf[0] != 4 && buf[0] != 5 {
+ err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
+ return
+ }
+ sig.Version = int(buf[0])
+ _, err = readFull(r, buf[:5])
+ if err != nil {
+ return
+ }
+ sig.SigType = SignatureType(buf[0])
+ sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA:
+ default:
+ err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
+ return
+ }
+
+ var ok bool
+
+ if sig.Version < 5 {
+ sig.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
+ } else {
+ sig.Hash, ok = algorithm.HashIdToHash(buf[2])
+ }
+
+ if !ok {
+ return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
+ }
+
+ hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
+ hashedSubpackets := make([]byte, hashedSubpacketsLength)
+ _, err = readFull(r, hashedSubpackets)
+ if err != nil {
+ return
+ }
+ err = sig.buildHashSuffix(hashedSubpackets)
+ if err != nil {
+ return
+ }
+
+ err = parseSignatureSubpackets(sig, hashedSubpackets, true)
+ if err != nil {
+ return
+ }
+
+ _, err = readFull(r, buf[:2])
+ if err != nil {
+ return
+ }
+ unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1])
+ unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
+ _, err = readFull(r, unhashedSubpackets)
+ if err != nil {
+ return
+ }
+ err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
+ if err != nil {
+ return
+ }
+
+ _, err = readFull(r, sig.HashTag[:2])
+ if err != nil {
+ return
+ }
+
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ sig.RSASignature = new(encoding.MPI)
+ _, err = sig.RSASignature.ReadFrom(r)
+ case PubKeyAlgoDSA:
+ sig.DSASigR = new(encoding.MPI)
+ if _, err = sig.DSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.DSASigS = new(encoding.MPI)
+ _, err = sig.DSASigS.ReadFrom(r)
+ case PubKeyAlgoECDSA:
+ sig.ECDSASigR = new(encoding.MPI)
+ if _, err = sig.ECDSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.ECDSASigS = new(encoding.MPI)
+ _, err = sig.ECDSASigS.ReadFrom(r)
+ case PubKeyAlgoEdDSA:
+ sig.EdDSASigR = new(encoding.MPI)
+ if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
+ return
+ }
+
+ sig.EdDSASigS = new(encoding.MPI)
+ if _, err = sig.EdDSASigS.ReadFrom(r); err != nil {
+ return
+ }
+ default:
+ panic("unreachable")
+ }
+ return
+}
+
+// parseSignatureSubpackets parses subpackets of the main signature packet. See
+// RFC 4880, section 5.2.3.1.
+func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
+ for len(subpackets) > 0 {
+ subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
+ if err != nil {
+ return
+ }
+ }
+
+ if sig.CreationTime.IsZero() {
+ err = errors.StructuralError("no creation time in signature")
+ }
+
+ return
+}
+
+type signatureSubpacketType uint8
+
+const (
+ creationTimeSubpacket signatureSubpacketType = 2
+ signatureExpirationSubpacket signatureSubpacketType = 3
+ trustSubpacket signatureSubpacketType = 5
+ regularExpressionSubpacket signatureSubpacketType = 6
+ keyExpirationSubpacket signatureSubpacketType = 9
+ prefSymmetricAlgosSubpacket signatureSubpacketType = 11
+ issuerSubpacket signatureSubpacketType = 16
+ notationDataSubpacket signatureSubpacketType = 20
+ prefHashAlgosSubpacket signatureSubpacketType = 21
+ prefCompressionSubpacket signatureSubpacketType = 22
+ primaryUserIdSubpacket signatureSubpacketType = 25
+ policyUriSubpacket signatureSubpacketType = 26
+ keyFlagsSubpacket signatureSubpacketType = 27
+ signerUserIdSubpacket signatureSubpacketType = 28
+ reasonForRevocationSubpacket signatureSubpacketType = 29
+ featuresSubpacket signatureSubpacketType = 30
+ embeddedSignatureSubpacket signatureSubpacketType = 32
+ issuerFingerprintSubpacket signatureSubpacketType = 33
+ prefCipherSuitesSubpacket signatureSubpacketType = 39
+)
+
+// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
+func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
+ // RFC 4880, section 5.2.3.1
+ var (
+ length uint32
+ packetType signatureSubpacketType
+ isCritical bool
+ )
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("zero length signature subpacket")
+ return
+ }
+ switch {
+ case subpacket[0] < 192:
+ length = uint32(subpacket[0])
+ subpacket = subpacket[1:]
+ case subpacket[0] < 255:
+ if len(subpacket) < 2 {
+ goto Truncated
+ }
+ length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
+ subpacket = subpacket[2:]
+ default:
+ if len(subpacket) < 5 {
+ goto Truncated
+ }
+ length = uint32(subpacket[1])<<24 |
+ uint32(subpacket[2])<<16 |
+ uint32(subpacket[3])<<8 |
+ uint32(subpacket[4])
+ subpacket = subpacket[5:]
+ }
+ if length > uint32(len(subpacket)) {
+ goto Truncated
+ }
+ rest = subpacket[length:]
+ subpacket = subpacket[:length]
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("zero length signature subpacket")
+ return
+ }
+ packetType = signatureSubpacketType(subpacket[0] & 0x7f)
+ isCritical = subpacket[0]&0x80 == 0x80
+ subpacket = subpacket[1:]
+ sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
+ if !isHashed &&
+ packetType != issuerSubpacket &&
+ packetType != issuerFingerprintSubpacket &&
+ packetType != embeddedSignatureSubpacket {
+ return
+ }
+ switch packetType {
+ case creationTimeSubpacket:
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("signature creation time not four bytes")
+ return
+ }
+ t := binary.BigEndian.Uint32(subpacket)
+ sig.CreationTime = time.Unix(int64(t), 0)
+ case signatureExpirationSubpacket:
+ // Signature expiration time, section 5.2.3.10
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("expiration subpacket with bad length")
+ return
+ }
+ sig.SigLifetimeSecs = new(uint32)
+ *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+ case trustSubpacket:
+ if len(subpacket) != 2 {
+ err = errors.StructuralError("trust subpacket with bad length")
+ return
+ }
+ // Trust level and amount, section 5.2.3.13
+ sig.TrustLevel = TrustLevel(subpacket[0])
+ sig.TrustAmount = TrustAmount(subpacket[1])
+ case regularExpressionSubpacket:
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("regexp subpacket with bad length")
+ return
+ }
+ // Trust regular expression, section 5.2.3.14
+ // RFC specifies the string should be null-terminated; remove a null byte from the end
+ if subpacket[len(subpacket)-1] != 0x00 {
+ err = errors.StructuralError("expected regular expression to be null-terminated")
+ return
+ }
+ trustRegularExpression := string(subpacket[:len(subpacket)-1])
+ sig.TrustRegularExpression = &trustRegularExpression
+ case keyExpirationSubpacket:
+ // Key expiration time, section 5.2.3.6
+ if len(subpacket) != 4 {
+ err = errors.StructuralError("key expiration subpacket with bad length")
+ return
+ }
+ sig.KeyLifetimeSecs = new(uint32)
+ *sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
+ case prefSymmetricAlgosSubpacket:
+ // Preferred symmetric algorithms, section 5.2.3.7
+ sig.PreferredSymmetric = make([]byte, len(subpacket))
+ copy(sig.PreferredSymmetric, subpacket)
+ case issuerSubpacket:
+ // Issuer, section 5.2.3.5
+ if sig.Version > 4 {
+ err = errors.StructuralError("issuer subpacket found in v5 key")
+ return
+ }
+ if len(subpacket) != 8 {
+ err = errors.StructuralError("issuer subpacket with bad length")
+ return
+ }
+ sig.IssuerKeyId = new(uint64)
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
+ case notationDataSubpacket:
+ // Notation data, section 5.2.3.16
+ if len(subpacket) < 8 {
+ err = errors.StructuralError("notation data subpacket with bad length")
+ return
+ }
+
+ nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5])
+ valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7])
+ if len(subpacket) != int(nameLength)+int(valueLength)+8 {
+ err = errors.StructuralError("notation data subpacket with bad length")
+ return
+ }
+
+ notation := Notation{
+ IsHumanReadable: (subpacket[0] & 0x80) == 0x80,
+ Name: string(subpacket[8:(nameLength + 8)]),
+ Value: subpacket[(nameLength + 8):(valueLength + nameLength + 8)],
+ IsCritical: isCritical,
+ }
+
+ sig.Notations = append(sig.Notations, ¬ation)
+ case prefHashAlgosSubpacket:
+ // Preferred hash algorithms, section 5.2.3.8
+ sig.PreferredHash = make([]byte, len(subpacket))
+ copy(sig.PreferredHash, subpacket)
+ case prefCompressionSubpacket:
+ // Preferred compression algorithms, section 5.2.3.9
+ sig.PreferredCompression = make([]byte, len(subpacket))
+ copy(sig.PreferredCompression, subpacket)
+ case primaryUserIdSubpacket:
+ // Primary User ID, section 5.2.3.19
+ if len(subpacket) != 1 {
+ err = errors.StructuralError("primary user id subpacket with bad length")
+ return
+ }
+ sig.IsPrimaryId = new(bool)
+ if subpacket[0] > 0 {
+ *sig.IsPrimaryId = true
+ }
+ case keyFlagsSubpacket:
+ // Key flags, section 5.2.3.21
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty key flags subpacket")
+ return
+ }
+ sig.FlagsValid = true
+ if subpacket[0]&KeyFlagCertify != 0 {
+ sig.FlagCertify = true
+ }
+ if subpacket[0]&KeyFlagSign != 0 {
+ sig.FlagSign = true
+ }
+ if subpacket[0]&KeyFlagEncryptCommunications != 0 {
+ sig.FlagEncryptCommunications = true
+ }
+ if subpacket[0]&KeyFlagEncryptStorage != 0 {
+ sig.FlagEncryptStorage = true
+ }
+ if subpacket[0]&KeyFlagSplitKey != 0 {
+ sig.FlagSplitKey = true
+ }
+ if subpacket[0]&KeyFlagAuthenticate != 0 {
+ sig.FlagAuthenticate = true
+ }
+ if subpacket[0]&KeyFlagGroupKey != 0 {
+ sig.FlagGroupKey = true
+ }
+ case signerUserIdSubpacket:
+ userId := string(subpacket)
+ sig.SignerUserId = &userId
+ case reasonForRevocationSubpacket:
+ // Reason For Revocation, section 5.2.3.23
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty revocation reason subpacket")
+ return
+ }
+ sig.RevocationReason = new(ReasonForRevocation)
+ *sig.RevocationReason = ReasonForRevocation(subpacket[0])
+ sig.RevocationReasonText = string(subpacket[1:])
+ case featuresSubpacket:
+ // Features subpacket, section 5.2.3.24 specifies a very general
+ // mechanism for OpenPGP implementations to signal support for new
+ // features.
+ if len(subpacket) > 0 {
+ if subpacket[0]&0x01 != 0 {
+ sig.SEIPDv1 = true
+ }
+ // 0x02 and 0x04 are reserved
+ if subpacket[0]&0x08 != 0 {
+ sig.SEIPDv2 = true
+ }
+ }
+ case embeddedSignatureSubpacket:
+ // Only usage is in signatures that cross-certify
+ // signing subkeys. section 5.2.3.26 describes the
+ // format, with its usage described in section 11.1
+ if sig.EmbeddedSignature != nil {
+ err = errors.StructuralError("Cannot have multiple embedded signatures")
+ return
+ }
+ sig.EmbeddedSignature = new(Signature)
+ // Embedded signatures are required to be v4 signatures see
+ // section 12.1. However, we only parse v4 signatures in this
+ // file anyway.
+ if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
+ return nil, err
+ }
+ if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
+ return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
+ }
+ case policyUriSubpacket:
+ // Policy URI, section 5.2.3.20
+ sig.PolicyURI = string(subpacket)
+ case issuerFingerprintSubpacket:
+ if len(subpacket) == 0 {
+ err = errors.StructuralError("empty issuer fingerprint subpacket")
+ return
+ }
+ v, l := subpacket[0], len(subpacket[1:])
+ if v == 5 && l != 32 || v != 5 && l != 20 {
+ return nil, errors.StructuralError("bad fingerprint length")
+ }
+ sig.IssuerFingerprint = make([]byte, l)
+ copy(sig.IssuerFingerprint, subpacket[1:])
+ sig.IssuerKeyId = new(uint64)
+ if v == 5 {
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9])
+ } else {
+ *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21])
+ }
+ case prefCipherSuitesSubpacket:
+ // Preferred AEAD cipher suites
+ // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-preferred-aead-ciphersuites
+ if len(subpacket)%2 != 0 {
+ err = errors.StructuralError("invalid aead cipher suite length")
+ return
+ }
+
+ sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2)
+
+ for i := 0; i < len(subpacket)/2; i++ {
+ sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]}
+ }
+ default:
+ if isCritical {
+ err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
+ return
+ }
+ }
+ return
+
+Truncated:
+ err = errors.StructuralError("signature subpacket truncated")
+ return
+}
+
+// subpacketLengthLength returns the length, in bytes, of an encoded length value.
+func subpacketLengthLength(length int) int {
+ if length < 192 {
+ return 1
+ }
+ if length < 16320 {
+ return 2
+ }
+ return 5
+}
+
+func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool {
+ if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 {
+ return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint)
+ }
+ return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId
+}
+
+// serializeSubpacketLength marshals the given length into to.
+func serializeSubpacketLength(to []byte, length int) int {
+ // RFC 4880, Section 4.2.2.
+ if length < 192 {
+ to[0] = byte(length)
+ return 1
+ }
+ if length < 16320 {
+ length -= 192
+ to[0] = byte((length >> 8) + 192)
+ to[1] = byte(length)
+ return 2
+ }
+ to[0] = 255
+ to[1] = byte(length >> 24)
+ to[2] = byte(length >> 16)
+ to[3] = byte(length >> 8)
+ to[4] = byte(length)
+ return 5
+}
+
+// subpacketsLength returns the serialized length, in bytes, of the given
+// subpackets.
+func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
+ for _, subpacket := range subpackets {
+ if subpacket.hashed == hashed {
+ length += subpacketLengthLength(len(subpacket.contents) + 1)
+ length += 1 // type byte
+ length += len(subpacket.contents)
+ }
+ }
+ return
+}
+
+// serializeSubpackets marshals the given subpackets into to.
+func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
+ for _, subpacket := range subpackets {
+ if subpacket.hashed == hashed {
+ n := serializeSubpacketLength(to, len(subpacket.contents)+1)
+ to[n] = byte(subpacket.subpacketType)
+ if subpacket.isCritical {
+ to[n] |= 0x80
+ }
+ to = to[1+n:]
+ n = copy(to, subpacket.contents)
+ to = to[n:]
+ }
+ }
+ return
+}
+
+// SigExpired returns whether sig is a signature that has expired or is created
+// in the future.
+func (sig *Signature) SigExpired(currentTime time.Time) bool {
+ if sig.CreationTime.After(currentTime) {
+ return true
+ }
+ if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 {
+ return false
+ }
+ expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second)
+ return currentTime.After(expiry)
+}
+
+// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
+func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) {
+ var hashId byte
+ var ok bool
+
+ if sig.Version < 5 {
+ hashId, ok = algorithm.HashToHashIdWithSha1(sig.Hash)
+ } else {
+ hashId, ok = algorithm.HashToHashId(sig.Hash)
+ }
+
+ if !ok {
+ sig.HashSuffix = nil
+ return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
+ }
+
+ hashedFields := bytes.NewBuffer([]byte{
+ uint8(sig.Version),
+ uint8(sig.SigType),
+ uint8(sig.PubKeyAlgo),
+ uint8(hashId),
+ uint8(len(hashedSubpackets) >> 8),
+ uint8(len(hashedSubpackets)),
+ })
+ hashedFields.Write(hashedSubpackets)
+
+ var l uint64 = uint64(6 + len(hashedSubpackets))
+ if sig.Version == 5 {
+ hashedFields.Write([]byte{0x05, 0xff})
+ hashedFields.Write([]byte{
+ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ } else {
+ hashedFields.Write([]byte{0x04, 0xff})
+ hashedFields.Write([]byte{
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ }
+ sig.HashSuffix = make([]byte, hashedFields.Len())
+ copy(sig.HashSuffix, hashedFields.Bytes())
+ return
+}
+
+func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
+ hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
+ hashedSubpackets := make([]byte, hashedSubpacketsLen)
+ serializeSubpackets(hashedSubpackets, sig.outSubpackets, true)
+ err = sig.buildHashSuffix(hashedSubpackets)
+ if err != nil {
+ return
+ }
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.AddMetadataToHashSuffix()
+ }
+
+ h.Write(sig.HashSuffix)
+ digest = h.Sum(nil)
+ copy(sig.HashTag[:], digest)
+ return
+}
+
+// Sign signs a message with a private key. The hash, h, must contain
+// the hash of the message to be signed and will be mutated by this function.
+// On success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ sig.Version = priv.PublicKey.Version
+ sig.IssuerFingerprint = priv.PublicKey.Fingerprint
+ sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey)
+ if err != nil {
+ return err
+ }
+ digest, err := sig.signPrepareHash(h)
+ if err != nil {
+ return
+ }
+ switch priv.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ // supports both *rsa.PrivateKey and crypto.Signer
+ sigdata, err := priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
+ if err == nil {
+ sig.RSASignature = encoding.NewMPI(sigdata)
+ }
+ case PubKeyAlgoDSA:
+ dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
+
+ // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
+ subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
+ if len(digest) > subgroupSize {
+ digest = digest[:subgroupSize]
+ }
+ r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
+ if err == nil {
+ sig.DSASigR = new(encoding.MPI).SetBig(r)
+ sig.DSASigS = new(encoding.MPI).SetBig(s)
+ }
+ case PubKeyAlgoECDSA:
+ sk := priv.PrivateKey.(*ecdsa.PrivateKey)
+ r, s, err := ecdsa.Sign(config.Random(), sk, digest)
+
+ if err == nil {
+ sig.ECDSASigR = new(encoding.MPI).SetBig(r)
+ sig.ECDSASigS = new(encoding.MPI).SetBig(s)
+ }
+ case PubKeyAlgoEdDSA:
+ sk := priv.PrivateKey.(*eddsa.PrivateKey)
+ r, s, err := eddsa.Sign(sk, digest)
+ if err == nil {
+ sig.EdDSASigR = encoding.NewMPI(r)
+ sig.EdDSASigS = encoding.NewMPI(s)
+ }
+ default:
+ err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
+ }
+
+ return
+}
+
+// SignUserId computes a signature from priv, asserting that pub is a valid
+// key for the identity id. On success, the signature is stored in sig. Call
+// Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ h, err := userIdSignatureHash(id, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// CrossSignKey computes a signature from signingKey on pub hashed using hashKey. On success,
+// the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey,
+ config *Config) error {
+ h, err := keySignatureHash(hashKey, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, signingKey, config)
+}
+
+// SignKey computes a signature from priv, asserting that pub is a subkey. On
+// success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ if priv.Dummy() {
+ return errors.ErrDummyPrivateKey("dummy key found")
+ }
+ h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// RevokeKey computes a revocation signature of pub using priv. On success, the signature is
+// stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ h, err := keyRevocationHash(pub, sig.Hash)
+ if err != nil {
+ return err
+ }
+ return sig.Sign(h, priv, config)
+}
+
+// RevokeSubkey computes a subkey revocation signature of pub using priv.
+// On success, the signature is stored in sig. Call Serialize to write it out.
+// If config is nil, sensible defaults will be used.
+func (sig *Signature) RevokeSubkey(pub *PublicKey, priv *PrivateKey, config *Config) error {
+ // Identical to a subkey binding signature
+ return sig.SignKey(pub, priv, config)
+}
+
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
+// called first.
+func (sig *Signature) Serialize(w io.Writer) (err error) {
+ if len(sig.outSubpackets) == 0 {
+ sig.outSubpackets = sig.rawSubpackets
+ }
+ if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil {
+ return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
+ }
+
+ sigLength := 0
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ sigLength = int(sig.RSASignature.EncodedLength())
+ case PubKeyAlgoDSA:
+ sigLength = int(sig.DSASigR.EncodedLength())
+ sigLength += int(sig.DSASigS.EncodedLength())
+ case PubKeyAlgoECDSA:
+ sigLength = int(sig.ECDSASigR.EncodedLength())
+ sigLength += int(sig.ECDSASigS.EncodedLength())
+ case PubKeyAlgoEdDSA:
+ sigLength = int(sig.EdDSASigR.EncodedLength())
+ sigLength += int(sig.EdDSASigS.EncodedLength())
+ default:
+ panic("impossible")
+ }
+
+ unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
+ length := len(sig.HashSuffix) - 6 /* trailer not included */ +
+ 2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
+ 2 /* hash tag */ + sigLength
+ if sig.Version == 5 {
+ length -= 4 // eight-octet instead of four-octet big endian
+ }
+ err = serializeHeader(w, packetTypeSignature, length)
+ if err != nil {
+ return
+ }
+ err = sig.serializeBody(w)
+ if err != nil {
+ return err
+ }
+ return
+}
+
+func (sig *Signature) serializeBody(w io.Writer) (err error) {
+ hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) | uint16(sig.HashSuffix[5])
+ fields := sig.HashSuffix[:6+hashedSubpacketsLen]
+ _, err = w.Write(fields)
+ if err != nil {
+ return
+ }
+
+ unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
+ unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen)
+ unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
+ unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
+ serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
+
+ _, err = w.Write(unhashedSubpackets)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(sig.HashTag[:])
+ if err != nil {
+ return
+ }
+
+ switch sig.PubKeyAlgo {
+ case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
+ _, err = w.Write(sig.RSASignature.EncodedBytes())
+ case PubKeyAlgoDSA:
+ if _, err = w.Write(sig.DSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.DSASigS.EncodedBytes())
+ case PubKeyAlgoECDSA:
+ if _, err = w.Write(sig.ECDSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.ECDSASigS.EncodedBytes())
+ case PubKeyAlgoEdDSA:
+ if _, err = w.Write(sig.EdDSASigR.EncodedBytes()); err != nil {
+ return
+ }
+ _, err = w.Write(sig.EdDSASigS.EncodedBytes())
+ default:
+ panic("impossible")
+ }
+ return
+}
+
+// outputSubpacket represents a subpacket to be marshaled.
+type outputSubpacket struct {
+ hashed bool // true if this subpacket is in the hashed area.
+ subpacketType signatureSubpacketType
+ isCritical bool
+ contents []byte
+}
+
+func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubpacket, err error) {
+ creationTime := make([]byte, 4)
+ binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
+ subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime})
+
+ if sig.IssuerKeyId != nil && sig.Version == 4 {
+ keyId := make([]byte, 8)
+ binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
+ subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
+ }
+ if sig.IssuerFingerprint != nil {
+ contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...)
+ subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version == 5, contents})
+ }
+ if sig.SignerUserId != nil {
+ subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)})
+ }
+ if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
+ sigLifetime := make([]byte, 4)
+ binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
+ subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
+ }
+
+ // Key flags may only appear in self-signatures or certification signatures.
+
+ if sig.FlagsValid {
+ var flags byte
+ if sig.FlagCertify {
+ flags |= KeyFlagCertify
+ }
+ if sig.FlagSign {
+ flags |= KeyFlagSign
+ }
+ if sig.FlagEncryptCommunications {
+ flags |= KeyFlagEncryptCommunications
+ }
+ if sig.FlagEncryptStorage {
+ flags |= KeyFlagEncryptStorage
+ }
+ if sig.FlagSplitKey {
+ flags |= KeyFlagSplitKey
+ }
+ if sig.FlagAuthenticate {
+ flags |= KeyFlagAuthenticate
+ }
+ if sig.FlagGroupKey {
+ flags |= KeyFlagGroupKey
+ }
+ subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
+ }
+
+ for _, notation := range sig.Notations {
+ subpackets = append(
+ subpackets,
+ outputSubpacket{
+ true,
+ notationDataSubpacket,
+ notation.IsCritical,
+ notation.getData(),
+ })
+ }
+
+ // The following subpackets may only appear in self-signatures.
+
+ var features = byte(0x00)
+ if sig.SEIPDv1 {
+ features |= 0x01
+ }
+ if sig.SEIPDv2 {
+ features |= 0x08
+ }
+
+ if features != 0x00 {
+ subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}})
+ }
+
+ if sig.TrustLevel != 0 {
+ subpackets = append(subpackets, outputSubpacket{true, trustSubpacket, true, []byte{byte(sig.TrustLevel), byte(sig.TrustAmount)}})
+ }
+
+ if sig.TrustRegularExpression != nil {
+ // RFC specifies the string should be null-terminated; add a null byte to the end
+ subpackets = append(subpackets, outputSubpacket{true, regularExpressionSubpacket, true, []byte(*sig.TrustRegularExpression + "\000")})
+ }
+
+ if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
+ keyLifetime := make([]byte, 4)
+ binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
+ subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
+ }
+
+ if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
+ subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
+ }
+
+ if len(sig.PreferredSymmetric) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
+ }
+
+ if len(sig.PreferredHash) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
+ }
+
+ if len(sig.PreferredCompression) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
+ }
+
+ if len(sig.PolicyURI) > 0 {
+ subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)})
+ }
+
+ if len(sig.PreferredCipherSuites) > 0 {
+ serialized := make([]byte, len(sig.PreferredCipherSuites)*2)
+ for i, cipherSuite := range sig.PreferredCipherSuites {
+ serialized[2*i] = cipherSuite[0]
+ serialized[2*i+1] = cipherSuite[1]
+ }
+ subpackets = append(subpackets, outputSubpacket{true, prefCipherSuitesSubpacket, false, serialized})
+ }
+
+ // Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.23.
+ if sig.RevocationReason != nil {
+ subpackets = append(subpackets, outputSubpacket{true, reasonForRevocationSubpacket, true,
+ append([]uint8{uint8(*sig.RevocationReason)}, []uint8(sig.RevocationReasonText)...)})
+ }
+
+ // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.26.
+ if sig.EmbeddedSignature != nil {
+ var buf bytes.Buffer
+ err = sig.EmbeddedSignature.serializeBody(&buf)
+ if err != nil {
+ return
+ }
+ subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()})
+ }
+
+ return
+}
+
+// AddMetadataToHashSuffix modifies the current hash suffix to include metadata
+// (format, filename, and time). Version 5 keys protect this data including it
+// in the hash computation. See section 5.2.4.
+func (sig *Signature) AddMetadataToHashSuffix() {
+ if sig == nil || sig.Version != 5 {
+ return
+ }
+ if sig.SigType != 0x00 && sig.SigType != 0x01 {
+ return
+ }
+ lit := sig.Metadata
+ if lit == nil {
+ // This will translate into six 0x00 bytes.
+ lit = &LiteralData{}
+ }
+
+ // Extract the current byte count
+ n := sig.HashSuffix[len(sig.HashSuffix)-8:]
+ l := uint64(
+ uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 |
+ uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7]))
+
+ suffix := bytes.NewBuffer(nil)
+ suffix.Write(sig.HashSuffix[:l])
+
+ // Add the metadata
+ var buf [4]byte
+ buf[0] = lit.Format
+ fileName := lit.FileName
+ if len(lit.FileName) > 255 {
+ fileName = fileName[:255]
+ }
+ buf[1] = byte(len(fileName))
+ suffix.Write(buf[:2])
+ suffix.Write([]byte(lit.FileName))
+ binary.BigEndian.PutUint32(buf[:], lit.Time)
+ suffix.Write(buf[:])
+
+ // Update the counter and restore trailing bytes
+ l = uint64(suffix.Len())
+ suffix.Write([]byte{0x05, 0xff})
+ suffix.Write([]byte{
+ uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
+ uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
+ })
+ sig.HashSuffix = suffix.Bytes()
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go
new file mode 100644
index 0000000..bac2b13
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go
@@ -0,0 +1,276 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/s2k"
+)
+
+// This is the largest session key that we'll support. Since at most 256-bit cipher
+// is supported in OpenPGP, this is large enough to contain also the auth tag.
+const maxSessionKeySizeInBytes = 64
+
+// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
+// 4880, section 5.3.
+type SymmetricKeyEncrypted struct {
+ Version int
+ CipherFunc CipherFunction
+ Mode AEADMode
+ s2k func(out, in []byte)
+ iv []byte
+ encryptedKey []byte // Contains also the authentication tag for AEAD
+}
+
+// parse parses an SymmetricKeyEncrypted packet as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-symmetric-key-encrypted-ses
+func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error {
+ var buf [1]byte
+
+ // Version
+ if _, err := readFull(r, buf[:]); err != nil {
+ return err
+ }
+ ske.Version = int(buf[0])
+ if ske.Version != 4 && ske.Version != 5 {
+ return errors.UnsupportedError("unknown SymmetricKeyEncrypted version")
+ }
+
+ // Cipher function
+ if _, err := readFull(r, buf[:]); err != nil {
+ return err
+ }
+ ske.CipherFunc = CipherFunction(buf[0])
+ if !ske.CipherFunc.IsSupported() {
+ return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[0])))
+ }
+
+ if ske.Version == 5 {
+ // AEAD mode
+ if _, err := readFull(r, buf[:]); err != nil {
+ return errors.StructuralError("cannot read AEAD octet from packet")
+ }
+ ske.Mode = AEADMode(buf[0])
+ }
+
+ var err error
+ if ske.s2k, err = s2k.Parse(r); err != nil {
+ if _, ok := err.(errors.ErrDummyPrivateKey); ok {
+ return errors.UnsupportedError("missing key GNU extension in session key")
+ }
+ return err
+ }
+
+ if ske.Version == 5 {
+ // AEAD IV
+ iv := make([]byte, ske.Mode.IvLength())
+ _, err := readFull(r, iv)
+ if err != nil {
+ return errors.StructuralError("cannot read AEAD IV")
+ }
+
+ ske.iv = iv
+ }
+
+ encryptedKey := make([]byte, maxSessionKeySizeInBytes)
+ // The session key may follow. We just have to try and read to find
+ // out. If it exists then we limit it to maxSessionKeySizeInBytes.
+ n, err := readFull(r, encryptedKey)
+ if err != nil && err != io.ErrUnexpectedEOF {
+ return err
+ }
+
+ if n != 0 {
+ if n == maxSessionKeySizeInBytes {
+ return errors.UnsupportedError("oversized encrypted session key")
+ }
+ ske.encryptedKey = encryptedKey[:n]
+ }
+ return nil
+}
+
+// Decrypt attempts to decrypt an encrypted session key and returns the key and
+// the cipher to use when decrypting a subsequent Symmetrically Encrypted Data
+// packet.
+func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunction, error) {
+ key := make([]byte, ske.CipherFunc.KeySize())
+ ske.s2k(key, passphrase)
+ if len(ske.encryptedKey) == 0 {
+ return key, ske.CipherFunc, nil
+ }
+ switch ske.Version {
+ case 4:
+ plaintextKey, cipherFunc, err := ske.decryptV4(key)
+ return plaintextKey, cipherFunc, err
+ case 5:
+ plaintextKey, err := ske.decryptV5(key)
+ return plaintextKey, CipherFunction(0), err
+ }
+ err := errors.UnsupportedError("unknown SymmetricKeyEncrypted version")
+ return nil, CipherFunction(0), err
+}
+
+func (ske *SymmetricKeyEncrypted) decryptV4(key []byte) ([]byte, CipherFunction, error) {
+ // the IV is all zeros
+ iv := make([]byte, ske.CipherFunc.blockSize())
+ c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
+ plaintextKey := make([]byte, len(ske.encryptedKey))
+ c.XORKeyStream(plaintextKey, ske.encryptedKey)
+ cipherFunc := CipherFunction(plaintextKey[0])
+ if cipherFunc.blockSize() == 0 {
+ return nil, ske.CipherFunc, errors.UnsupportedError(
+ "unknown cipher: " + strconv.Itoa(int(cipherFunc)))
+ }
+ plaintextKey = plaintextKey[1:]
+ if len(plaintextKey) != cipherFunc.KeySize() {
+ return nil, cipherFunc, errors.StructuralError(
+ "length of decrypted key not equal to cipher keysize")
+ }
+ return plaintextKey, cipherFunc, nil
+}
+
+func (ske *SymmetricKeyEncrypted) decryptV5(key []byte) ([]byte, error) {
+ adata := []byte{0xc3, byte(5), byte(ske.CipherFunc), byte(ske.Mode)}
+ aead := getEncryptedKeyAeadInstance(ske.CipherFunc, ske.Mode, key, adata)
+
+ plaintextKey, err := aead.Open(nil, ske.iv, ske.encryptedKey, adata)
+ if err != nil {
+ return nil, err
+ }
+ return plaintextKey, nil
+}
+
+// SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w.
+// The packet contains a random session key, encrypted by a key derived from
+// the given passphrase. The session key is returned and must be passed to
+// SerializeSymmetricallyEncrypted.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) {
+ cipherFunc := config.Cipher()
+
+ sessionKey := make([]byte, cipherFunc.KeySize())
+ _, err = io.ReadFull(config.Random(), sessionKey)
+ if err != nil {
+ return
+ }
+
+ err = SerializeSymmetricKeyEncryptedReuseKey(w, sessionKey, passphrase, config)
+ if err != nil {
+ return
+ }
+
+ key = sessionKey
+ return
+}
+
+// SerializeSymmetricKeyEncryptedReuseKey serializes a symmetric key packet to w.
+// The packet contains the given session key, encrypted by a key derived from
+// the given passphrase. The returned session key must be passed to
+// SerializeSymmetricallyEncrypted.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, passphrase []byte, config *Config) (err error) {
+ var version int
+ if config.AEAD() != nil {
+ version = 5
+ } else {
+ version = 4
+ }
+ cipherFunc := config.Cipher()
+ // cipherFunc must be AES
+ if !cipherFunc.IsSupported() || cipherFunc < CipherAES128 || cipherFunc > CipherAES256 {
+ return errors.UnsupportedError("unsupported cipher: " + strconv.Itoa(int(cipherFunc)))
+ }
+
+ keySize := cipherFunc.KeySize()
+ s2kBuf := new(bytes.Buffer)
+ keyEncryptingKey := make([]byte, keySize)
+ // s2k.Serialize salts and stretches the passphrase, and writes the
+ // resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf.
+ err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, config.S2K())
+ if err != nil {
+ return
+ }
+ s2kBytes := s2kBuf.Bytes()
+
+ var packetLength int
+ switch version {
+ case 4:
+ packetLength = 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize
+ case 5:
+ ivLen := config.AEAD().Mode().IvLength()
+ tagLen := config.AEAD().Mode().TagLength()
+ packetLength = 3 + len(s2kBytes) + ivLen + keySize + tagLen
+ }
+ err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength)
+ if err != nil {
+ return
+ }
+
+ // Symmetric Key Encrypted Version
+ buf := []byte{byte(version)}
+
+ // Cipher function
+ buf = append(buf, byte(cipherFunc))
+
+ if version == 5 {
+ // AEAD mode
+ buf = append(buf, byte(config.AEAD().Mode()))
+ }
+ _, err = w.Write(buf)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(s2kBytes)
+ if err != nil {
+ return
+ }
+
+ switch version {
+ case 4:
+ iv := make([]byte, cipherFunc.blockSize())
+ c := cipher.NewCFBEncrypter(cipherFunc.new(keyEncryptingKey), iv)
+ encryptedCipherAndKey := make([]byte, keySize+1)
+ c.XORKeyStream(encryptedCipherAndKey, buf[1:])
+ c.XORKeyStream(encryptedCipherAndKey[1:], sessionKey)
+ _, err = w.Write(encryptedCipherAndKey)
+ if err != nil {
+ return
+ }
+ case 5:
+ mode := config.AEAD().Mode()
+ adata := []byte{0xc3, byte(5), byte(cipherFunc), byte(mode)}
+ aead := getEncryptedKeyAeadInstance(cipherFunc, mode, keyEncryptingKey, adata)
+
+ // Sample iv using random reader
+ iv := make([]byte, config.AEAD().Mode().IvLength())
+ _, err = io.ReadFull(config.Random(), iv)
+ if err != nil {
+ return
+ }
+ // Seal and write (encryptedData includes auth. tag)
+
+ encryptedData := aead.Seal(nil, iv, sessionKey, adata)
+ _, err = w.Write(iv)
+ if err != nil {
+ return
+ }
+ _, err = w.Write(encryptedData)
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func getEncryptedKeyAeadInstance(c CipherFunction, mode AEADMode, inputKey, associatedData []byte) (aead cipher.AEAD) {
+ blockCipher := c.new(inputKey)
+ return mode.new(blockCipher)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go
new file mode 100644
index 0000000..e9bbf03
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go
@@ -0,0 +1,90 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+const aeadSaltSize = 32
+
+// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
+// encrypted Contents will consist of more OpenPGP packets. See RFC 4880,
+// sections 5.7 and 5.13.
+type SymmetricallyEncrypted struct {
+ Version int
+ Contents io.Reader // contains tag for version 2
+ IntegrityProtected bool // If true it is type 18 (with MDC or AEAD). False is packet type 9
+
+ // Specific to version 1
+ prefix []byte
+
+ // Specific to version 2
+ Cipher CipherFunction
+ Mode AEADMode
+ ChunkSizeByte byte
+ Salt [aeadSaltSize]byte
+}
+
+const (
+ symmetricallyEncryptedVersionMdc = 1
+ symmetricallyEncryptedVersionAead = 2
+)
+
+func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
+ if se.IntegrityProtected {
+ // See RFC 4880, section 5.13.
+ var buf [1]byte
+ _, err := readFull(r, buf[:])
+ if err != nil {
+ return err
+ }
+
+ switch buf[0] {
+ case symmetricallyEncryptedVersionMdc:
+ se.Version = symmetricallyEncryptedVersionMdc
+ case symmetricallyEncryptedVersionAead:
+ se.Version = symmetricallyEncryptedVersionAead
+ if err := se.parseAead(r); err != nil {
+ return err
+ }
+ default:
+ return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
+ }
+ }
+ se.Contents = r
+ return nil
+}
+
+// Decrypt returns a ReadCloser, from which the decrypted Contents of the
+// packet can be read. An incorrect key will only be detected after trying
+// to decrypt the entire data.
+func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
+ if se.Version == symmetricallyEncryptedVersionAead {
+ return se.decryptAead(key)
+ }
+
+ return se.decryptMdc(c, key)
+}
+
+// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
+// to w and returns a WriteCloser to which the to-be-encrypted packets can be
+// written.
+// If config is nil, sensible defaults will be used.
+func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, aeadSupported bool, cipherSuite CipherSuite, key []byte, config *Config) (Contents io.WriteCloser, err error) {
+ writeCloser := noOpCloser{w}
+ ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedIntegrityProtected)
+ if err != nil {
+ return
+ }
+
+ if aeadSupported {
+ return serializeSymmetricallyEncryptedAead(ciphertext, cipherSuite, config.AEADConfig.ChunkSizeByte(), config.Random(), key)
+ }
+
+ return serializeSymmetricallyEncryptedMdc(ciphertext, c, key, config)
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
new file mode 100644
index 0000000..e96252c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go
@@ -0,0 +1,156 @@
+// Copyright 2023 Proton AG. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto/cipher"
+ "crypto/sha256"
+ "io"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "golang.org/x/crypto/hkdf"
+)
+
+// parseAead parses a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (se *SymmetricallyEncrypted) parseAead(r io.Reader) error {
+ headerData := make([]byte, 3)
+ if n, err := io.ReadFull(r, headerData); n < 3 {
+ return errors.StructuralError("could not read aead header: " + err.Error())
+ }
+
+ // Cipher
+ se.Cipher = CipherFunction(headerData[0])
+ // cipherFunc must have block size 16 to use AEAD
+ if se.Cipher.blockSize() != 16 {
+ return errors.UnsupportedError("invalid aead cipher: " + string(se.Cipher))
+ }
+
+ // Mode
+ se.Mode = AEADMode(headerData[1])
+ if se.Mode.TagLength() == 0 {
+ return errors.UnsupportedError("unknown aead mode: " + string(se.Mode))
+ }
+
+ // Chunk size
+ se.ChunkSizeByte = headerData[2]
+ if se.ChunkSizeByte > 16 {
+ return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.ChunkSizeByte))
+ }
+
+ // Salt
+ if n, err := io.ReadFull(r, se.Salt[:]); n < aeadSaltSize {
+ return errors.StructuralError("could not read aead salt: " + err.Error())
+ }
+
+ return nil
+}
+
+// associatedData for chunks: tag, version, cipher, mode, chunk size byte
+func (se *SymmetricallyEncrypted) associatedData() []byte {
+ return []byte{
+ 0xD2,
+ symmetricallyEncryptedVersionAead,
+ byte(se.Cipher),
+ byte(se.Mode),
+ se.ChunkSizeByte,
+ }
+}
+
+// decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, error) {
+ aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, se.Mode, inputKey, se.Salt[:], se.associatedData())
+
+ // Carry the first tagLen bytes
+ tagLen := se.Mode.TagLength()
+ peekedBytes := make([]byte, tagLen)
+ n, err := io.ReadFull(se.Contents, peekedBytes)
+ if n < tagLen || (err != nil && err != io.EOF) {
+ return nil, errors.StructuralError("not enough data to decrypt:" + err.Error())
+ }
+
+ return &aeadDecrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: decodeAEADChunkSize(se.ChunkSizeByte),
+ initialNonce: nonce,
+ associatedData: se.associatedData(),
+ chunkIndex: make([]byte, 8),
+ packetTag: packetTypeSymmetricallyEncryptedIntegrityProtected,
+ },
+ reader: se.Contents,
+ peekedBytes: peekedBytes,
+ }, nil
+}
+
+// serializeSymmetricallyEncryptedAead encrypts to a writer a V2 SEIPD packet (AEAD) as specified in
+// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
+func serializeSymmetricallyEncryptedAead(ciphertext io.WriteCloser, cipherSuite CipherSuite, chunkSizeByte byte, rand io.Reader, inputKey []byte) (Contents io.WriteCloser, err error) {
+ // cipherFunc must have block size 16 to use AEAD
+ if cipherSuite.Cipher.blockSize() != 16 {
+ return nil, errors.InvalidArgumentError("invalid aead cipher function")
+ }
+
+ if cipherSuite.Cipher.KeySize() != len(inputKey) {
+ return nil, errors.InvalidArgumentError("error in aead serialization: bad key length")
+ }
+
+ // Data for en/decryption: tag, version, cipher, aead mode, chunk size
+ prefix := []byte{
+ 0xD2,
+ symmetricallyEncryptedVersionAead,
+ byte(cipherSuite.Cipher),
+ byte(cipherSuite.Mode),
+ chunkSizeByte,
+ }
+
+ // Write header (that correspond to prefix except first byte)
+ n, err := ciphertext.Write(prefix[1:])
+ if err != nil || n < 4 {
+ return nil, err
+ }
+
+ // Random salt
+ salt := make([]byte, aeadSaltSize)
+ if _, err := rand.Read(salt); err != nil {
+ return nil, err
+ }
+
+ if _, err := ciphertext.Write(salt); err != nil {
+ return nil, err
+ }
+
+ aead, nonce := getSymmetricallyEncryptedAeadInstance(cipherSuite.Cipher, cipherSuite.Mode, inputKey, salt, prefix)
+
+ return &aeadEncrypter{
+ aeadCrypter: aeadCrypter{
+ aead: aead,
+ chunkSize: decodeAEADChunkSize(chunkSizeByte),
+ associatedData: prefix,
+ chunkIndex: make([]byte, 8),
+ initialNonce: nonce,
+ packetTag: packetTypeSymmetricallyEncryptedIntegrityProtected,
+ },
+ writer: ciphertext,
+ }, nil
+}
+
+func getSymmetricallyEncryptedAeadInstance(c CipherFunction, mode AEADMode, inputKey, salt, associatedData []byte) (aead cipher.AEAD, nonce []byte) {
+ hkdfReader := hkdf.New(sha256.New, inputKey, salt, associatedData)
+
+ encryptionKey := make([]byte, c.KeySize())
+ _, _ = readFull(hkdfReader, encryptionKey)
+
+ // Last 64 bits of nonce are the counter
+ nonce = make([]byte, mode.IvLength()-8)
+
+ _, _ = readFull(hkdfReader, nonce)
+
+ blockCipher := c.new(encryptionKey)
+ aead = mode.new(blockCipher)
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go
new file mode 100644
index 0000000..fa26beb
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_mdc.go
@@ -0,0 +1,256 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "crypto/cipher"
+ "crypto/sha1"
+ "crypto/subtle"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+)
+
+// seMdcReader wraps an io.Reader with a no-op Close method.
+type seMdcReader struct {
+ in io.Reader
+}
+
+func (ser seMdcReader) Read(buf []byte) (int, error) {
+ return ser.in.Read(buf)
+}
+
+func (ser seMdcReader) Close() error {
+ return nil
+}
+
+func (se *SymmetricallyEncrypted) decryptMdc(c CipherFunction, key []byte) (io.ReadCloser, error) {
+ if !c.IsSupported() {
+ return nil, errors.UnsupportedError("unsupported cipher: " + strconv.Itoa(int(c)))
+ }
+
+ if len(key) != c.KeySize() {
+ return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
+ }
+
+ if se.prefix == nil {
+ se.prefix = make([]byte, c.blockSize()+2)
+ _, err := readFull(se.Contents, se.prefix)
+ if err != nil {
+ return nil, err
+ }
+ } else if len(se.prefix) != c.blockSize()+2 {
+ return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
+ }
+
+ ocfbResync := OCFBResync
+ if se.IntegrityProtected {
+ // MDC packets use a different form of OCFB mode.
+ ocfbResync = OCFBNoResync
+ }
+
+ s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
+
+ plaintext := cipher.StreamReader{S: s, R: se.Contents}
+
+ if se.IntegrityProtected {
+ // IntegrityProtected packets have an embedded hash that we need to check.
+ h := sha1.New()
+ h.Write(se.prefix)
+ return &seMDCReader{in: plaintext, h: h}, nil
+ }
+
+ // Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
+ return seMdcReader{plaintext}, nil
+}
+
+const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size
+
+// An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold
+// of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an
+// MDC packet containing a hash of the previous Contents which is checked
+// against the running hash. See RFC 4880, section 5.13.
+type seMDCReader struct {
+ in io.Reader
+ h hash.Hash
+ trailer [mdcTrailerSize]byte
+ scratch [mdcTrailerSize]byte
+ trailerUsed int
+ error bool
+ eof bool
+}
+
+func (ser *seMDCReader) Read(buf []byte) (n int, err error) {
+ if ser.error {
+ err = io.ErrUnexpectedEOF
+ return
+ }
+ if ser.eof {
+ err = io.EOF
+ return
+ }
+
+ // If we haven't yet filled the trailer buffer then we must do that
+ // first.
+ for ser.trailerUsed < mdcTrailerSize {
+ n, err = ser.in.Read(ser.trailer[ser.trailerUsed:])
+ ser.trailerUsed += n
+ if err == io.EOF {
+ if ser.trailerUsed != mdcTrailerSize {
+ n = 0
+ err = io.ErrUnexpectedEOF
+ ser.error = true
+ return
+ }
+ ser.eof = true
+ n = 0
+ return
+ }
+
+ if err != nil {
+ n = 0
+ return
+ }
+ }
+
+ // If it's a short read then we read into a temporary buffer and shift
+ // the data into the caller's buffer.
+ if len(buf) <= mdcTrailerSize {
+ n, err = readFull(ser.in, ser.scratch[:len(buf)])
+ copy(buf, ser.trailer[:n])
+ ser.h.Write(buf[:n])
+ copy(ser.trailer[:], ser.trailer[n:])
+ copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:])
+ if n < len(buf) {
+ ser.eof = true
+ err = io.EOF
+ }
+ return
+ }
+
+ n, err = ser.in.Read(buf[mdcTrailerSize:])
+ copy(buf, ser.trailer[:])
+ ser.h.Write(buf[:n])
+ copy(ser.trailer[:], buf[n:])
+
+ if err == io.EOF {
+ ser.eof = true
+ }
+ return
+}
+
+// This is a new-format packet tag byte for a type 19 (Integrity Protected) packet.
+const mdcPacketTagByte = byte(0x80) | 0x40 | 19
+
+func (ser *seMDCReader) Close() error {
+ if ser.error {
+ return errors.ErrMDCMissing
+ }
+
+ for !ser.eof {
+ // We haven't seen EOF so we need to read to the end
+ var buf [1024]byte
+ _, err := ser.Read(buf[:])
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return errors.ErrMDCMissing
+ }
+ }
+
+ ser.h.Write(ser.trailer[:2])
+
+ final := ser.h.Sum(nil)
+ if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 {
+ return errors.ErrMDCHashMismatch
+ }
+ // The hash already includes the MDC header, but we still check its value
+ // to confirm encryption correctness
+ if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
+ return errors.ErrMDCMissing
+ }
+ return nil
+}
+
+// An seMDCWriter writes through to an io.WriteCloser while maintains a running
+// hash of the data written. On close, it emits an MDC packet containing the
+// running hash.
+type seMDCWriter struct {
+ w io.WriteCloser
+ h hash.Hash
+}
+
+func (w *seMDCWriter) Write(buf []byte) (n int, err error) {
+ w.h.Write(buf)
+ return w.w.Write(buf)
+}
+
+func (w *seMDCWriter) Close() (err error) {
+ var buf [mdcTrailerSize]byte
+
+ buf[0] = mdcPacketTagByte
+ buf[1] = sha1.Size
+ w.h.Write(buf[:2])
+ digest := w.h.Sum(nil)
+ copy(buf[2:], digest)
+
+ _, err = w.w.Write(buf[:])
+ if err != nil {
+ return
+ }
+ return w.w.Close()
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+type noOpCloser struct {
+ w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+ return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+ return nil
+}
+
+func serializeSymmetricallyEncryptedMdc(ciphertext io.WriteCloser, c CipherFunction, key []byte, config *Config) (Contents io.WriteCloser, err error) {
+ // Disallow old cipher suites
+ if !c.IsSupported() || c < CipherAES128 {
+ return nil, errors.InvalidArgumentError("invalid mdc cipher function")
+ }
+
+ if c.KeySize() != len(key) {
+ return nil, errors.InvalidArgumentError("error in mdc serialization: bad key length")
+ }
+
+ _, err = ciphertext.Write([]byte{symmetricallyEncryptedVersionMdc})
+ if err != nil {
+ return
+ }
+
+ block := c.new(key)
+ blockSize := block.BlockSize()
+ iv := make([]byte, blockSize)
+ _, err = config.Random().Read(iv)
+ if err != nil {
+ return
+ }
+ s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
+ _, err = ciphertext.Write(prefix)
+ if err != nil {
+ return
+ }
+ plaintext := cipher.StreamWriter{S: s, W: ciphertext}
+
+ h := sha1.New()
+ h.Write(iv)
+ h.Write(iv[blockSize-2:])
+ Contents = &seMDCWriter{w: plaintext, h: h}
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go
new file mode 100644
index 0000000..88ec72c
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userattribute.go
@@ -0,0 +1,101 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "bytes"
+ "image"
+ "image/jpeg"
+ "io"
+ "io/ioutil"
+)
+
+const UserAttrImageSubpacket = 1
+
+// UserAttribute is capable of storing other types of data about a user
+// beyond name, email and a text comment. In practice, user attributes are typically used
+// to store a signed thumbnail photo JPEG image of the user.
+// See RFC 4880, section 5.12.
+type UserAttribute struct {
+ Contents []*OpaqueSubpacket
+}
+
+// NewUserAttributePhoto creates a user attribute packet
+// containing the given images.
+func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) {
+ uat = new(UserAttribute)
+ for _, photo := range photos {
+ var buf bytes.Buffer
+ // RFC 4880, Section 5.12.1.
+ data := []byte{
+ 0x10, 0x00, // Little-endian image header length (16 bytes)
+ 0x01, // Image header version 1
+ 0x01, // JPEG
+ 0, 0, 0, 0, // 12 reserved octets, must be all zero.
+ 0, 0, 0, 0,
+ 0, 0, 0, 0}
+ if _, err = buf.Write(data); err != nil {
+ return
+ }
+ if err = jpeg.Encode(&buf, photo, nil); err != nil {
+ return
+ }
+
+ lengthBuf := make([]byte, 5)
+ n := serializeSubpacketLength(lengthBuf, len(buf.Bytes())+1)
+ lengthBuf = lengthBuf[:n]
+
+ uat.Contents = append(uat.Contents, &OpaqueSubpacket{
+ SubType: UserAttrImageSubpacket,
+ EncodedLength: lengthBuf,
+ Contents: buf.Bytes(),
+ })
+ }
+ return
+}
+
+// NewUserAttribute creates a new user attribute packet containing the given subpackets.
+func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
+ return &UserAttribute{Contents: contents}
+}
+
+func (uat *UserAttribute) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.13
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ uat.Contents, err = OpaqueSubpackets(b)
+ return
+}
+
+// Serialize marshals the user attribute to w in the form of an OpenPGP packet, including
+// header.
+func (uat *UserAttribute) Serialize(w io.Writer) (err error) {
+ var buf bytes.Buffer
+ for _, sp := range uat.Contents {
+ err = sp.Serialize(&buf)
+ if err != nil {
+ return err
+ }
+ }
+ if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil {
+ return err
+ }
+ _, err = w.Write(buf.Bytes())
+ return
+}
+
+// ImageData returns zero or more byte slices, each containing
+// JPEG File Interchange Format (JFIF), for each photo in the
+// user attribute packet.
+func (uat *UserAttribute) ImageData() (imageData [][]byte) {
+ for _, sp := range uat.Contents {
+ if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 {
+ imageData = append(imageData, sp.Contents[16:])
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go
new file mode 100644
index 0000000..614fbaf
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/userid.go
@@ -0,0 +1,167 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packet
+
+import (
+ "io"
+ "io/ioutil"
+ "strings"
+)
+
+// UserId contains text that is intended to represent the name and email
+// address of the key holder. See RFC 4880, section 5.11. By convention, this
+// takes the form "Full Name (Comment) "
+type UserId struct {
+ Id string // By convention, this takes the form "Full Name (Comment) " which is split out in the fields below.
+
+ Name, Comment, Email string
+}
+
+func hasInvalidCharacters(s string) bool {
+ for _, c := range s {
+ switch c {
+ case '(', ')', '<', '>', 0:
+ return true
+ }
+ }
+ return false
+}
+
+// NewUserId returns a UserId or nil if any of the arguments contain invalid
+// characters. The invalid characters are '\x00', '(', ')', '<' and '>'
+func NewUserId(name, comment, email string) *UserId {
+ // RFC 4880 doesn't deal with the structure of userid strings; the
+ // name, comment and email form is just a convention. However, there's
+ // no convention about escaping the metacharacters and GPG just refuses
+ // to create user ids where, say, the name contains a '('. We mirror
+ // this behaviour.
+
+ if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
+ return nil
+ }
+
+ uid := new(UserId)
+ uid.Name, uid.Comment, uid.Email = name, comment, email
+ uid.Id = name
+ if len(comment) > 0 {
+ if len(uid.Id) > 0 {
+ uid.Id += " "
+ }
+ uid.Id += "("
+ uid.Id += comment
+ uid.Id += ")"
+ }
+ if len(email) > 0 {
+ if len(uid.Id) > 0 {
+ uid.Id += " "
+ }
+ uid.Id += "<"
+ uid.Id += email
+ uid.Id += ">"
+ }
+ return uid
+}
+
+func (uid *UserId) parse(r io.Reader) (err error) {
+ // RFC 4880, section 5.11
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ return
+ }
+ uid.Id = string(b)
+ uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
+ return
+}
+
+// Serialize marshals uid to w in the form of an OpenPGP packet, including
+// header.
+func (uid *UserId) Serialize(w io.Writer) error {
+ err := serializeHeader(w, packetTypeUserId, len(uid.Id))
+ if err != nil {
+ return err
+ }
+ _, err = w.Write([]byte(uid.Id))
+ return err
+}
+
+// parseUserId extracts the name, comment and email from a user id string that
+// is formatted as "Full Name (Comment) ".
+func parseUserId(id string) (name, comment, email string) {
+ var n, c, e struct {
+ start, end int
+ }
+ var state int
+
+ for offset, rune := range id {
+ switch state {
+ case 0:
+ // Entering name
+ n.start = offset
+ state = 1
+ fallthrough
+ case 1:
+ // In name
+ if rune == '(' {
+ state = 2
+ n.end = offset
+ } else if rune == '<' {
+ state = 5
+ n.end = offset
+ }
+ case 2:
+ // Entering comment
+ c.start = offset
+ state = 3
+ fallthrough
+ case 3:
+ // In comment
+ if rune == ')' {
+ state = 4
+ c.end = offset
+ }
+ case 4:
+ // Between comment and email
+ if rune == '<' {
+ state = 5
+ }
+ case 5:
+ // Entering email
+ e.start = offset
+ state = 6
+ fallthrough
+ case 6:
+ // In email
+ if rune == '>' {
+ state = 7
+ e.end = offset
+ }
+ default:
+ // After email
+ }
+ }
+ switch state {
+ case 1:
+ // ended in the name
+ n.end = len(id)
+ case 3:
+ // ended in comment
+ c.end = len(id)
+ case 6:
+ // ended in email
+ e.end = len(id)
+ }
+
+ name = strings.TrimSpace(id[n.start:n.end])
+ comment = strings.TrimSpace(id[c.start:c.end])
+ email = strings.TrimSpace(id[e.start:e.end])
+
+ // RFC 2822 3.4: alternate simple form of a mailbox
+ if email == "" && strings.ContainsRune(name, '@') {
+ email = name
+ name = ""
+ }
+
+ return
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
new file mode 100644
index 0000000..8499c73
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
@@ -0,0 +1,592 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package openpgp implements high level operations on OpenPGP messages.
+package openpgp // import "github.com/ProtonMail/go-crypto/openpgp"
+
+import (
+ "crypto"
+ _ "crypto/sha256"
+ _ "crypto/sha512"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+ _ "golang.org/x/crypto/sha3"
+)
+
+// SignatureType is the armor type for a PGP signature.
+var SignatureType = "PGP SIGNATURE"
+
+// readArmored reads an armored block with the given type.
+func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
+ block, err := armor.Decode(r)
+ if err != nil {
+ return
+ }
+
+ if block.Type != expectedType {
+ return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
+ }
+
+ return block.Body, nil
+}
+
+// MessageDetails contains the result of parsing an OpenPGP encrypted and/or
+// signed message.
+type MessageDetails struct {
+ IsEncrypted bool // true if the message was encrypted.
+ EncryptedToKeyIds []uint64 // the list of recipient key ids.
+ IsSymmetricallyEncrypted bool // true if a passphrase could have decrypted the message.
+ DecryptedWith Key // the private key used to decrypt the message, if any.
+ IsSigned bool // true if the message is signed.
+ SignedByKeyId uint64 // the key id of the signer, if any.
+ SignedBy *Key // the key of the signer, if available.
+ LiteralData *packet.LiteralData // the metadata of the contents
+ UnverifiedBody io.Reader // the contents of the message.
+
+ // If IsSigned is true and SignedBy is non-zero then the signature will
+ // be verified as UnverifiedBody is read. The signature cannot be
+ // checked until the whole of UnverifiedBody is read so UnverifiedBody
+ // must be consumed until EOF before the data can be trusted. Even if a
+ // message isn't signed (or the signer is unknown) the data may contain
+ // an authentication code that is only checked once UnverifiedBody has
+ // been consumed. Once EOF has been seen, the following fields are
+ // valid. (An authentication code failure is reported as a
+ // SignatureError error when reading from UnverifiedBody.)
+ Signature *packet.Signature // the signature packet itself.
+ SignatureError error // nil if the signature is good.
+ UnverifiedSignatures []*packet.Signature // all other unverified signature packets.
+
+ decrypted io.ReadCloser
+}
+
+// A PromptFunction is used as a callback by functions that may need to decrypt
+// a private key, or prompt for a passphrase. It is called with a list of
+// acceptable, encrypted private keys and a boolean that indicates whether a
+// passphrase is usable. It should either decrypt a private key or return a
+// passphrase to try. If the decrypted private key or given passphrase isn't
+// correct, the function will be called again, forever. Any error returned will
+// be passed up.
+type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
+
+// A keyEnvelopePair is used to store a private key with the envelope that
+// contains a symmetric key, encrypted with that key.
+type keyEnvelopePair struct {
+ key Key
+ encryptedKey *packet.EncryptedKey
+}
+
+// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
+// The given KeyRing should contain both public keys (for signature
+// verification) and, possibly encrypted, private keys for decrypting.
+// If config is nil, sensible defaults will be used.
+func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
+ var p packet.Packet
+
+ var symKeys []*packet.SymmetricKeyEncrypted
+ var pubKeys []keyEnvelopePair
+ // Integrity protected encrypted packet: SymmetricallyEncrypted or AEADEncrypted
+ var edp packet.EncryptedDataPacket
+
+ packets := packet.NewReader(r)
+ md = new(MessageDetails)
+ md.IsEncrypted = true
+
+ // The message, if encrypted, starts with a number of packets
+ // containing an encrypted decryption key. The decryption key is either
+ // encrypted to a public key, or with a passphrase. This loop
+ // collects these packets.
+ParsePackets:
+ for {
+ p, err = packets.Next()
+ if err != nil {
+ return nil, err
+ }
+ switch p := p.(type) {
+ case *packet.SymmetricKeyEncrypted:
+ // This packet contains the decryption key encrypted with a passphrase.
+ md.IsSymmetricallyEncrypted = true
+ symKeys = append(symKeys, p)
+ case *packet.EncryptedKey:
+ // This packet contains the decryption key encrypted to a public key.
+ md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
+ switch p.Algo {
+ case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH:
+ break
+ default:
+ continue
+ }
+ if keyring != nil {
+ var keys []Key
+ if p.KeyId == 0 {
+ keys = keyring.DecryptionKeys()
+ } else {
+ keys = keyring.KeysById(p.KeyId)
+ }
+ for _, k := range keys {
+ pubKeys = append(pubKeys, keyEnvelopePair{k, p})
+ }
+ }
+ case *packet.SymmetricallyEncrypted:
+ if !p.IntegrityProtected && !config.AllowUnauthenticatedMessages() {
+ return nil, errors.UnsupportedError("message is not integrity protected")
+ }
+ edp = p
+ break ParsePackets
+ case *packet.AEADEncrypted:
+ edp = p
+ break ParsePackets
+ case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
+ // This message isn't encrypted.
+ if len(symKeys) != 0 || len(pubKeys) != 0 {
+ return nil, errors.StructuralError("key material not followed by encrypted message")
+ }
+ packets.Unread(p)
+ return readSignedMessage(packets, nil, keyring, config)
+ }
+ }
+
+ var candidates []Key
+ var decrypted io.ReadCloser
+
+ // Now that we have the list of encrypted keys we need to decrypt at
+ // least one of them or, if we cannot, we need to call the prompt
+ // function so that it can decrypt a key or give us a passphrase.
+FindKey:
+ for {
+ // See if any of the keys already have a private key available
+ candidates = candidates[:0]
+ candidateFingerprints := make(map[string]bool)
+
+ for _, pk := range pubKeys {
+ if pk.key.PrivateKey == nil {
+ continue
+ }
+ if !pk.key.PrivateKey.Encrypted {
+ if len(pk.encryptedKey.Key) == 0 {
+ errDec := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
+ if errDec != nil {
+ continue
+ }
+ }
+ // Try to decrypt symmetrically encrypted
+ decrypted, err = edp.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
+ if err != nil && err != errors.ErrKeyIncorrect {
+ return nil, err
+ }
+ if decrypted != nil {
+ md.DecryptedWith = pk.key
+ break FindKey
+ }
+ } else {
+ fpr := string(pk.key.PublicKey.Fingerprint[:])
+ if v := candidateFingerprints[fpr]; v {
+ continue
+ }
+ candidates = append(candidates, pk.key)
+ candidateFingerprints[fpr] = true
+ }
+ }
+
+ if len(candidates) == 0 && len(symKeys) == 0 {
+ return nil, errors.ErrKeyIncorrect
+ }
+
+ if prompt == nil {
+ return nil, errors.ErrKeyIncorrect
+ }
+
+ passphrase, err := prompt(candidates, len(symKeys) != 0)
+ if err != nil {
+ return nil, err
+ }
+
+ // Try the symmetric passphrase first
+ if len(symKeys) != 0 && passphrase != nil {
+ for _, s := range symKeys {
+ key, cipherFunc, err := s.Decrypt(passphrase)
+ // In v4, on wrong passphrase, session key decryption is very likely to result in an invalid cipherFunc:
+ // only for < 5% of cases we will proceed to decrypt the data
+ if err == nil {
+ decrypted, err = edp.Decrypt(cipherFunc, key)
+ if err != nil {
+ return nil, err
+ }
+ if decrypted != nil {
+ break FindKey
+ }
+ }
+ }
+ }
+ }
+
+ md.decrypted = decrypted
+ if err := packets.Push(decrypted); err != nil {
+ return nil, err
+ }
+ mdFinal, sensitiveParsingErr := readSignedMessage(packets, md, keyring, config)
+ if sensitiveParsingErr != nil {
+ return nil, errors.StructuralError("parsing error")
+ }
+ return mdFinal, nil
+}
+
+// readSignedMessage reads a possibly signed message if mdin is non-zero then
+// that structure is updated and returned. Otherwise a fresh MessageDetails is
+// used.
+func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing, config *packet.Config) (md *MessageDetails, err error) {
+ if mdin == nil {
+ mdin = new(MessageDetails)
+ }
+ md = mdin
+
+ var p packet.Packet
+ var h hash.Hash
+ var wrappedHash hash.Hash
+ var prevLast bool
+FindLiteralData:
+ for {
+ p, err = packets.Next()
+ if err != nil {
+ return nil, err
+ }
+ switch p := p.(type) {
+ case *packet.Compressed:
+ if err := packets.Push(p.Body); err != nil {
+ return nil, err
+ }
+ case *packet.OnePassSignature:
+ if prevLast {
+ return nil, errors.UnsupportedError("nested signature packets")
+ }
+
+ if p.IsLast {
+ prevLast = true
+ }
+
+ h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
+ if err != nil {
+ md.SignatureError = err
+ }
+
+ md.IsSigned = true
+ md.SignedByKeyId = p.KeyId
+ if keyring != nil {
+ keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
+ if len(keys) > 0 {
+ md.SignedBy = &keys[0]
+ }
+ }
+ case *packet.LiteralData:
+ md.LiteralData = p
+ break FindLiteralData
+ }
+ }
+
+ if md.IsSigned && md.SignatureError == nil {
+ md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config}
+ } else if md.decrypted != nil {
+ md.UnverifiedBody = checkReader{md}
+ } else {
+ md.UnverifiedBody = md.LiteralData.Body
+ }
+
+ return md, nil
+}
+
+// hashForSignature returns a pair of hashes that can be used to verify a
+// signature. The signature may specify that the contents of the signed message
+// should be preprocessed (i.e. to normalize line endings). Thus this function
+// returns two hashes. The second should be used to hash the message itself and
+// performs any needed preprocessing.
+func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
+ if _, ok := algorithm.HashToHashIdWithSha1(hashFunc); !ok {
+ return nil, nil, errors.UnsupportedError("unsupported hash function")
+ }
+ if !hashFunc.Available() {
+ return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashFunc)))
+ }
+ h := hashFunc.New()
+
+ switch sigType {
+ case packet.SigTypeBinary:
+ return h, h, nil
+ case packet.SigTypeText:
+ return h, NewCanonicalTextHash(h), nil
+ }
+
+ return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
+}
+
+// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
+// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
+// MDC checks.
+type checkReader struct {
+ md *MessageDetails
+}
+
+func (cr checkReader) Read(buf []byte) (int, error) {
+ n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf)
+ if sensitiveParsingError == io.EOF {
+ mdcErr := cr.md.decrypted.Close()
+ if mdcErr != nil {
+ return n, mdcErr
+ }
+ return n, io.EOF
+ }
+
+ if sensitiveParsingError != nil {
+ return n, errors.StructuralError("parsing error")
+ }
+
+ return n, nil
+}
+
+// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
+// the data as it is read. When it sees an EOF from the underlying io.Reader
+// it parses and checks a trailing Signature packet and triggers any MDC checks.
+type signatureCheckReader struct {
+ packets *packet.Reader
+ h, wrappedHash hash.Hash
+ md *MessageDetails
+ config *packet.Config
+}
+
+func (scr *signatureCheckReader) Read(buf []byte) (int, error) {
+ n, sensitiveParsingError := scr.md.LiteralData.Body.Read(buf)
+
+ // Hash only if required
+ if scr.md.SignedBy != nil {
+ scr.wrappedHash.Write(buf[:n])
+ }
+
+ if sensitiveParsingError == io.EOF {
+ var p packet.Packet
+ var readError error
+ var sig *packet.Signature
+
+ p, readError = scr.packets.Next()
+ for readError == nil {
+ var ok bool
+ if sig, ok = p.(*packet.Signature); ok {
+ if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
+ sig.Metadata = scr.md.LiteralData
+ }
+
+ // If signature KeyID matches
+ if scr.md.SignedBy != nil && *sig.IssuerKeyId == scr.md.SignedByKeyId {
+ key := scr.md.SignedBy
+ signatureError := key.PublicKey.VerifySignature(scr.h, sig)
+ if signatureError == nil {
+ signatureError = checkSignatureDetails(key, sig, scr.config)
+ }
+ scr.md.Signature = sig
+ scr.md.SignatureError = signatureError
+ } else {
+ scr.md.UnverifiedSignatures = append(scr.md.UnverifiedSignatures, sig)
+ }
+ }
+
+ p, readError = scr.packets.Next()
+ }
+
+ if scr.md.SignedBy != nil && scr.md.Signature == nil {
+ if scr.md.UnverifiedSignatures == nil {
+ scr.md.SignatureError = errors.StructuralError("LiteralData not followed by signature")
+ } else {
+ scr.md.SignatureError = errors.StructuralError("No matching signature found")
+ }
+ }
+
+ // The SymmetricallyEncrypted packet, if any, might have an
+ // unsigned hash of its own. In order to check this we need to
+ // close that Reader.
+ if scr.md.decrypted != nil {
+ mdcErr := scr.md.decrypted.Close()
+ if mdcErr != nil {
+ return n, mdcErr
+ }
+ }
+ return n, io.EOF
+ }
+
+ if sensitiveParsingError != nil {
+ return n, errors.StructuralError("parsing error")
+ }
+
+ return n, nil
+}
+
+// VerifyDetachedSignature takes a signed file and a detached signature and
+// returns the signature packet and the entity the signature was signed by,
+// if any, and a possible signature verification error.
+// If the signer isn't known, ErrUnknownIssuer is returned.
+func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ var expectedHashes []crypto.Hash
+ return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+}
+
+// VerifyDetachedSignatureAndHash performs the same actions as
+// VerifyDetachedSignature and checks that the expected hash functions were used.
+func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+}
+
+// CheckDetachedSignature takes a signed file and a detached signature and
+// returns the entity the signature was signed by, if any, and a possible
+// signature verification error. If the signer isn't known,
+// ErrUnknownIssuer is returned.
+func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
+ var expectedHashes []crypto.Hash
+ return CheckDetachedSignatureAndHash(keyring, signed, signature, expectedHashes, config)
+}
+
+// CheckDetachedSignatureAndHash performs the same actions as
+// CheckDetachedSignature and checks that the expected hash functions were used.
+func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) {
+ _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
+ return
+}
+
+func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
+ var issuerKeyId uint64
+ var hashFunc crypto.Hash
+ var sigType packet.SignatureType
+ var keys []Key
+ var p packet.Packet
+
+ expectedHashesLen := len(expectedHashes)
+ packets := packet.NewReader(signature)
+ for {
+ p, err = packets.Next()
+ if err == io.EOF {
+ return nil, nil, errors.ErrUnknownIssuer
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+
+ var ok bool
+ sig, ok = p.(*packet.Signature)
+ if !ok {
+ return nil, nil, errors.StructuralError("non signature packet found")
+ }
+ if sig.IssuerKeyId == nil {
+ return nil, nil, errors.StructuralError("signature doesn't have an issuer")
+ }
+ issuerKeyId = *sig.IssuerKeyId
+ hashFunc = sig.Hash
+ sigType = sig.SigType
+
+ for i, expectedHash := range expectedHashes {
+ if hashFunc == expectedHash {
+ break
+ }
+ if i+1 == expectedHashesLen {
+ return nil, nil, errors.StructuralError("hash algorithm mismatch with cleartext message headers")
+ }
+ }
+
+ keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
+ if len(keys) > 0 {
+ break
+ }
+ }
+
+ if len(keys) == 0 {
+ panic("unreachable")
+ }
+
+ h, wrappedHash, err := hashForSignature(hashFunc, sigType)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
+ return nil, nil, err
+ }
+
+ for _, key := range keys {
+ err = key.PublicKey.VerifySignature(h, sig)
+ if err == nil {
+ return sig, key.Entity, checkSignatureDetails(&key, sig, config)
+ }
+ }
+
+ return nil, nil, err
+}
+
+// CheckArmoredDetachedSignature performs the same actions as
+// CheckDetachedSignature but expects the signature to be armored.
+func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
+ body, err := readArmored(signature, SignatureType)
+ if err != nil {
+ return
+ }
+
+ return CheckDetachedSignature(keyring, signed, body, config)
+}
+
+// checkSignatureDetails returns an error if:
+// - The signature (or one of the binding signatures mentioned below)
+// has a unknown critical notation data subpacket
+// - The primary key of the signing entity is revoked
+// - The primary identity is revoked
+// - The signature is expired
+// - The primary key of the signing entity is expired according to the
+// primary identity binding signature
+//
+// ... or, if the signature was signed by a subkey and:
+// - The signing subkey is revoked
+// - The signing subkey is expired according to the subkey binding signature
+// - The signing subkey binding signature is expired
+// - The signing subkey cross-signature is expired
+//
+// NOTE: The order of these checks is important, as the caller may choose to
+// ignore ErrSignatureExpired or ErrKeyExpired errors, but should never
+// ignore any other errors.
+//
+// TODO: Also return an error if:
+// - The primary key is expired according to a direct-key signature
+// - (For V5 keys only:) The direct-key signature (exists and) is expired
+func checkSignatureDetails(key *Key, signature *packet.Signature, config *packet.Config) error {
+ now := config.Now()
+ primaryIdentity := key.Entity.PrimaryIdentity()
+ signedBySubKey := key.PublicKey != key.Entity.PrimaryKey
+ sigsToCheck := []*packet.Signature{signature, primaryIdentity.SelfSignature}
+ if signedBySubKey {
+ sigsToCheck = append(sigsToCheck, key.SelfSignature, key.SelfSignature.EmbeddedSignature)
+ }
+ for _, sig := range sigsToCheck {
+ for _, notation := range sig.Notations {
+ if notation.IsCritical && !config.KnownNotation(notation.Name) {
+ return errors.SignatureError("unknown critical notation: " + notation.Name)
+ }
+ }
+ }
+ if key.Entity.Revoked(now) || // primary key is revoked
+ (signedBySubKey && key.Revoked(now)) || // subkey is revoked
+ primaryIdentity.Revoked(now) { // primary identity is revoked
+ return errors.ErrKeyRevoked
+ }
+ if key.Entity.PrimaryKey.KeyExpired(primaryIdentity.SelfSignature, now) { // primary key is expired
+ return errors.ErrKeyExpired
+ }
+ if signedBySubKey {
+ if key.PublicKey.KeyExpired(key.SelfSignature, now) { // subkey is expired
+ return errors.ErrKeyExpired
+ }
+ }
+ for _, sig := range sigsToCheck {
+ if sig.SigExpired(now) { // any of the relevant signatures are expired
+ return errors.ErrSignatureExpired
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go
new file mode 100644
index 0000000..db6dad5
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/read_write_test_data.go
@@ -0,0 +1,274 @@
+package openpgp
+
+const testKey1KeyId uint64 = 0xA34D7E18C20C31BB
+const testKey3KeyId uint64 = 0x338934250CCC0360
+const testKeyP256KeyId uint64 = 0xd44a2c495918513e
+
+const signedInput = "Signed message\nline 2\nline 3\n"
+const signedTextInput = "Signed message\r\nline 2\r\nline 3\r\n"
+
+const recipientUnspecifiedHex = "848c0300000000000000000103ff62d4d578d03cf40c3da998dfe216c074fa6ddec5e31c197c9666ba292830d91d18716a80f699f9d897389a90e6d62d0238f5f07a5248073c0f24920e4bc4a30c2d17ee4e0cae7c3d4aaa4e8dced50e3010a80ee692175fa0385f62ecca4b56ee6e9980aa3ec51b61b077096ac9e800edaf161268593eedb6cc7027ff5cb32745d250010d407a6221ae22ef18469b444f2822478c4d190b24d36371a95cb40087cdd42d9399c3d06a53c0673349bfb607927f20d1e122bde1e2bf3aa6cae6edf489629bcaa0689539ae3b718914d88ededc3b"
+
+const detachedSignatureHex = "889c04000102000605024d449cd1000a0910a34d7e18c20c31bb167603ff57718d09f28a519fdc7b5a68b6a3336da04df85e38c5cd5d5bd2092fa4629848a33d85b1729402a2aab39c3ac19f9d573f773cc62c264dc924c067a79dfd8a863ae06c7c8686120760749f5fd9b1e03a64d20a7df3446ddc8f0aeadeaeba7cbaee5c1e366d65b6a0c6cc749bcb912d2f15013f812795c2e29eb7f7b77f39ce77"
+
+const detachedSignatureTextHex = "889c04010102000605024d449d21000a0910a34d7e18c20c31bbc8c60400a24fbef7342603a41cb1165767bd18985d015fb72fe05db42db36cfb2f1d455967f1e491194fbf6cf88146222b23bf6ffbd50d17598d976a0417d3192ff9cc0034fd00f287b02e90418bbefe609484b09231e4e7a5f3562e199bf39909ab5276c4d37382fe088f6b5c3426fc1052865da8b3ab158672d58b6264b10823dc4b39"
+
+const detachedSignatureDSAHex = "884604001102000605024d6c4eac000a0910338934250ccc0360f18d00a087d743d6405ed7b87755476629600b8b694a39e900a0abff8126f46faf1547c1743c37b21b4ea15b8f83"
+
+const detachedSignatureP256Hex = "885e0400130a0006050256e5bb00000a0910d44a2c495918513edef001009841a4f792beb0befccb35c8838a6a87d9b936beaa86db6745ddc7b045eee0cf00fd1ac1f78306b17e965935dd3f8bae4587a76587e4af231efe19cc4011a8434817"
+
+// The plaintext is https://www.gutenberg.org/cache/epub/1080/pg1080.txt
+const modestProposalSha512 = "lbbrB1+WP3T9AaC9OQqBdOcCjgeEQadlulXsNPgVx0tyqPzDHwUugZ2gE7V0ESKAw6kAVfgkcuvfgxAAGaeHtw=="
+
+const testKeys1And2Hex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b0020003b88d044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f0011010001889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab0020003988d044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b0020003b88d044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020003"
+
+const testKeys1And2PrivateHex = "9501d8044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd00110100010003ff4d91393b9a8e3430b14d6209df42f98dc927425b881f1209f319220841273a802a97c7bdb8b3a7740b3ab5866c4d1d308ad0d3a79bd1e883aacf1ac92dfe720285d10d08752a7efe3c609b1d00f17f2805b217be53999a7da7e493bfc3e9618fd17018991b8128aea70a05dbce30e4fbe626aa45775fa255dd9177aabf4df7cf0200c1ded12566e4bc2bb590455e5becfb2e2c9796482270a943343a7835de41080582c2be3caf5981aa838140e97afa40ad652a0b544f83eb1833b0957dce26e47b0200eacd6046741e9ce2ec5beb6fb5e6335457844fb09477f83b050a96be7da043e17f3a9523567ed40e7a521f818813a8b8a72209f1442844843ccc7eb9805442570200bdafe0438d97ac36e773c7162028d65844c4d463e2420aa2228c6e50dc2743c3d6c72d0d782a5173fe7be2169c8a9f4ef8a7cf3e37165e8c61b89c346cdc6c1799d2b41054657374204b6579203120285253412988b804130102002205024d3c5c10021b03060b090807030206150802090a0b0416020301021e01021780000a0910a34d7e18c20c31bbb5b304009cc45fe610b641a2c146331be94dade0a396e73ca725e1b25c21708d9cab46ecca5ccebc23055879df8f99eea39b377962a400f2ebdc36a7c99c333d74aeba346315137c3ff9d0a09b0273299090343048afb8107cf94cbd1400e3026f0ccac7ecebbc4d78588eb3e478fe2754d3ca664bcf3eac96ca4a6b0c8d7df5102f60f6b00200009d01d8044d3c5c10010400b201df61d67487301f11879d514f4248ade90c8f68c7af1284c161098de4c28c2850f1ec7b8e30f959793e571542ffc6532189409cb51c3d30dad78c4ad5165eda18b20d9826d8707d0f742e2ab492103a85bbd9ddf4f5720f6de7064feb0d39ee002219765bb07bcfb8b877f47abe270ddeda4f676108cecb6b9bb2ad484a4f00110100010003fd17a7490c22a79c59281fb7b20f5e6553ec0c1637ae382e8adaea295f50241037f8997cf42c1ce26417e015091451b15424b2c59eb8d4161b0975630408e394d3b00f88d4b4e18e2cc85e8251d4753a27c639c83f5ad4a571c4f19d7cd460b9b73c25ade730c99df09637bd173d8e3e981ac64432078263bb6dc30d3e974150dd0200d0ee05be3d4604d2146fb0457f31ba17c057560785aa804e8ca5530a7cd81d3440d0f4ba6851efcfd3954b7e68908fc0ba47f7ac37bf559c6c168b70d3a7c8cd0200da1c677c4bce06a068070f2b3733b0a714e88d62aa3f9a26c6f5216d48d5c2b5624144f3807c0df30be66b3268eeeca4df1fbded58faf49fc95dc3c35f134f8b01fd1396b6c0fc1b6c4f0eb8f5e44b8eace1e6073e20d0b8bc5385f86f1cf3f050f66af789f3ef1fc107b7f4421e19e0349c730c68f0a226981f4e889054fdb4dc149e8e889f04180102000905024d3c5c10021b0c000a0910a34d7e18c20c31bb1a03040085c8d62e16d05dc4e9dad64953c8a2eed8b6c12f92b1575eeaa6dcf7be9473dd5b24b37b6dffbb4e7c99ed1bd3cb11634be19b3e6e207bed7505c7ca111ccf47cb323bf1f8851eb6360e8034cbff8dd149993c959de89f8f77f38e7e98b8e3076323aa719328e2b408db5ec0d03936efd57422ba04f925cdc7b4c1af7590e40ab00200009501fe044d3c5c33010400b488c3e5f83f4d561f317817538d9d0397981e9aef1321ca68ebfae1cf8b7d388e19f4b5a24a82e2fbbf1c6c26557a6c5845307a03d815756f564ac7325b02bc83e87d5480a8fae848f07cb891f2d51ce7df83dcafdc12324517c86d472cc0ee10d47a68fd1d9ae49a6c19bbd36d82af597a0d88cc9c49de9df4e696fc1f0b5d0011010001fe030302e9030f3c783e14856063f16938530e148bc57a7aa3f3e4f90df9dceccdc779bc0835e1ad3d006e4a8d7b36d08b8e0de5a0d947254ecfbd22037e6572b426bcfdc517796b224b0036ff90bc574b5509bede85512f2eefb520fb4b02aa523ba739bff424a6fe81c5041f253f8d757e69a503d3563a104d0d49e9e890b9d0c26f96b55b743883b472caa7050c4acfd4a21f875bdf1258d88bd61224d303dc9df77f743137d51e6d5246b88c406780528fd9a3e15bab5452e5b93970d9dcc79f48b38651b9f15bfbcf6da452837e9cc70683d1bdca94507870f743e4ad902005812488dd342f836e72869afd00ce1850eea4cfa53ce10e3608e13d3c149394ee3cbd0e23d018fcbcb6e2ec5a1a22972d1d462ca05355d0d290dd2751e550d5efb38c6c89686344df64852bf4ff86638708f644e8ec6bd4af9b50d8541cb91891a431326ab2e332faa7ae86cfb6e0540aa63160c1e5cdd5a4add518b303fff0a20117c6bc77f7cfbaf36b04c865c6c2b42754657374204b6579203220285253412c20656e637279707465642070726976617465206b65792988b804130102002205024d3c5c33021b03060b090807030206150802090a0b0416020301021e01021780000a0910d4984f961e35246b98940400908a73b6a6169f700434f076c6c79015a49bee37130eaf23aaa3cfa9ce60bfe4acaa7bc95f1146ada5867e0079babb38804891f4f0b8ebca57a86b249dee786161a755b7a342e68ccf3f78ed6440a93a6626beb9a37aa66afcd4f888790cb4bb46d94a4ae3eb3d7d3e6b00f6bfec940303e89ec5b32a1eaaacce66497d539328b00200009d01fe044d3c5c33010400a4e913f9442abcc7f1804ccab27d2f787ffa592077ca935a8bb23165bd8d57576acac647cc596b2c3f814518cc8c82953c7a4478f32e0cf645630a5ba38d9618ef2bc3add69d459ae3dece5cab778938d988239f8c5ae437807075e06c828019959c644ff05ef6a5a1dab72227c98e3a040b0cf219026640698d7a13d8538a570011010001fe030302e9030f3c783e148560f936097339ae381d63116efcf802ff8b1c9360767db5219cc987375702a4123fd8657d3e22700f23f95020d1b261eda5257e9a72f9a918e8ef22dd5b3323ae03bbc1923dd224db988cadc16acc04b120a9f8b7e84da9716c53e0334d7b66586ddb9014df604b41be1e960dcfcbc96f4ed150a1a0dd070b9eb14276b9b6be413a769a75b519a53d3ecc0c220e85cd91ca354d57e7344517e64b43b6e29823cbd87eae26e2b2e78e6dedfbb76e3e9f77bcb844f9a8932eb3db2c3f9e44316e6f5d60e9e2a56e46b72abe6b06dc9a31cc63f10023d1f5e12d2a3ee93b675c96f504af0001220991c88db759e231b3320dcedf814dcf723fd9857e3d72d66a0f2af26950b915abdf56c1596f46a325bf17ad4810d3535fb02a259b247ac3dbd4cc3ecf9c51b6c07cebb009c1506fba0a89321ec8683e3fd009a6e551d50243e2d5092fefb3321083a4bad91320dc624bd6b5dddf93553e3d53924c05bfebec1fb4bd47e89a1a889f04180102000905024d3c5c33021b0c000a0910d4984f961e35246b26c703ff7ee29ef53bc1ae1ead533c408fa136db508434e233d6e62be621e031e5940bbd4c08142aed0f82217e7c3e1ec8de574bc06ccf3c36633be41ad78a9eacd209f861cae7b064100758545cc9dd83db71806dc1cfd5fb9ae5c7474bba0c19c44034ae61bae5eca379383339dece94ff56ff7aa44a582f3e5c38f45763af577c0934b0020000"
+
+const dsaElGamalTestKeysHex = "9501e1044dfcb16a110400aa3e5c1a1f43dd28c2ffae8abf5cfce555ee874134d8ba0a0f7b868ce2214beddc74e5e1e21ded354a95d18acdaf69e5e342371a71fbb9093162e0c5f3427de413a7f2c157d83f5cd2f9d791256dc4f6f0e13f13c3302af27f2384075ab3021dff7a050e14854bbde0a1094174855fc02f0bae8e00a340d94a1f22b32e48485700a0cec672ac21258fb95f61de2ce1af74b2c4fa3e6703ff698edc9be22c02ae4d916e4fa223f819d46582c0516235848a77b577ea49018dcd5e9e15cff9dbb4663a1ae6dd7580fa40946d40c05f72814b0f88481207e6c0832c3bded4853ebba0a7e3bd8e8c66df33d5a537cd4acf946d1080e7a3dcea679cb2b11a72a33a2b6a9dc85f466ad2ddf4c3db6283fa645343286971e3dd700703fc0c4e290d45767f370831a90187e74e9972aae5bff488eeff7d620af0362bfb95c1a6c3413ab5d15a2e4139e5d07a54d72583914661ed6a87cce810be28a0aa8879a2dd39e52fb6fe800f4f181ac7e328f740cde3d09a05cecf9483e4cca4253e60d4429ffd679d9996a520012aad119878c941e3cf151459873bdfc2a9563472fe0303027a728f9feb3b864260a1babe83925ce794710cfd642ee4ae0e5b9d74cee49e9c67b6cd0ea5dfbb582132195a121356a1513e1bca73e5b80c58c7ccb4164453412f456c47616d616c2054657374204b65792031886204131102002205024dfcb16a021b03060b090807030206150802090a0b0416020301021e01021780000a091033af447ccd759b09fadd00a0b8fd6f5a790bad7e9f2dbb7632046dc4493588db009c087c6a9ba9f7f49fab221587a74788c00db4889ab00200009d0157044dfcb16a1004008dec3f9291205255ccff8c532318133a6840739dd68b03ba942676f9038612071447bf07d00d559c5c0875724ea16a4c774f80d8338b55fca691a0522e530e604215b467bbc9ccfd483a1da99d7bc2648b4318fdbd27766fc8bfad3fddb37c62b8ae7ccfe9577e9b8d1e77c1d417ed2c2ef02d52f4da11600d85d3229607943700030503ff506c94c87c8cab778e963b76cf63770f0a79bf48fb49d3b4e52234620fc9f7657f9f8d56c96a2b7c7826ae6b57ebb2221a3fe154b03b6637cea7e6d98e3e45d87cf8dc432f723d3d71f89c5192ac8d7290684d2c25ce55846a80c9a7823f6acd9bb29fa6cd71f20bc90eccfca20451d0c976e460e672b000df49466408d527affe0303027a728f9feb3b864260abd761730327bca2aaa4ea0525c175e92bf240682a0e83b226f97ecb2e935b62c9a133858ce31b271fa8eb41f6a1b3cd72a63025ce1a75ee4180dcc284884904181102000905024dfcb16a021b0c000a091033af447ccd759b09dd0b009e3c3e7296092c81bee5a19929462caaf2fff3ae26009e218c437a2340e7ea628149af1ec98ec091a43992b00200009501e1044dfcb1be1104009f61faa61aa43df75d128cbe53de528c4aec49ce9360c992e70c77072ad5623de0a3a6212771b66b39a30dad6781799e92608316900518ec01184a85d872365b7d2ba4bacfb5882ea3c2473d3750dc6178cc1cf82147fb58caa28b28e9f12f6d1efcb0534abed644156c91cca4ab78834268495160b2400bc422beb37d237c2300a0cac94911b6d493bda1e1fbc6feeca7cb7421d34b03fe22cec6ccb39675bb7b94a335c2b7be888fd3906a1125f33301d8aa6ec6ee6878f46f73961c8d57a3e9544d8ef2a2cbfd4d52da665b1266928cfe4cb347a58c412815f3b2d2369dec04b41ac9a71cc9547426d5ab941cccf3b18575637ccfb42df1a802df3cfe0a999f9e7109331170e3a221991bf868543960f8c816c28097e503fe319db10fb98049f3a57d7c80c420da66d56f3644371631fad3f0ff4040a19a4fedc2d07727a1b27576f75a4d28c47d8246f27071e12d7a8de62aad216ddbae6aa02efd6b8a3e2818cda48526549791ab277e447b3a36c57cefe9b592f5eab73959743fcc8e83cbefec03a329b55018b53eec196765ae40ef9e20521a603c551efe0303020950d53a146bf9c66034d00c23130cce95576a2ff78016ca471276e8227fb30b1ffbd92e61804fb0c3eff9e30b1a826ee8f3e4730b4d86273ca977b4164453412f456c47616d616c2054657374204b65792032886204131102002205024dfcb1be021b03060b090807030206150802090a0b0416020301021e01021780000a0910a86bf526325b21b22bd9009e34511620415c974750a20df5cb56b182f3b48e6600a0a9466cb1a1305a84953445f77d461593f1d42bc1b00200009d0157044dfcb1be1004009565a951da1ee87119d600c077198f1c1bceb0f7aa54552489298e41ff788fa8f0d43a69871f0f6f77ebdfb14a4260cf9fbeb65d5844b4272a1904dd95136d06c3da745dc46327dd44a0f16f60135914368c8039a34033862261806bb2c5ce1152e2840254697872c85441ccb7321431d75a747a4bfb1d2c66362b51ce76311700030503fc0ea76601c196768070b7365a200e6ddb09307f262d5f39eec467b5f5784e22abdf1aa49226f59ab37cb49969d8f5230ea65caf56015abda62604544ed526c5c522bf92bed178a078789f6c807b6d34885688024a5bed9e9f8c58d11d4b82487b44c5f470c5606806a0443b79cadb45e0f897a561a53f724e5349b9267c75ca17fe0303020950d53a146bf9c660bc5f4ce8f072465e2d2466434320c1e712272fafc20e342fe7608101580fa1a1a367e60486a7cd1246b7ef5586cf5e10b32762b710a30144f12dd17dd4884904181102000905024dfcb1be021b0c000a0910a86bf526325b21b2904c00a0b2b66b4b39ccffda1d10f3ea8d58f827e30a8b8e009f4255b2d8112a184e40cde43a34e8655ca7809370b0020000"
+
+const signedMessageHex = "a3019bc0cbccc0c4b8d8b74ee2108fe16ec6d3ca490cbe362d3f8333d3f352531472538b8b13d353b97232f352158c20943157c71c16064626063656269052062e4e01987e9b6fccff4b7df3a34c534b23e679cbec3bc0f8f6e64dfb4b55fe3f8efa9ce110ddb5cd79faf1d753c51aecfa669f7e7aa043436596cccc3359cb7dd6bbe9ecaa69e5989d9e57209571edc0b2fa7f57b9b79a64ee6e99ce1371395fee92fec2796f7b15a77c386ff668ee27f6d38f0baa6c438b561657377bf6acff3c5947befd7bf4c196252f1d6e5c524d0300"
+
+const signedTextMessageHex = "a3019bc0cbccc8c4b8d8b74ee2108fe16ec6d36a250cbece0c178233d3f352531472538b8b13d35379b97232f352158ca0b4312f57c71c1646462606365626906a062e4e019811591798ff99bf8afee860b0d8a8c2a85c3387e3bcf0bb3b17987f2bbcfab2aa526d930cbfd3d98757184df3995c9f3e7790e36e3e9779f06089d4c64e9e47dd6202cb6e9bc73c5d11bb59fbaf89d22d8dc7cf199ddf17af96e77c5f65f9bbed56f427bd8db7af37f6c9984bf9385efaf5f184f986fb3e6adb0ecfe35bbf92d16a7aa2a344fb0bc52fb7624f0200"
+
+const signedEncryptedMessageHex = "c18c032a67d68660df41c70103ff5a84c9a72f80e74ef0384c2d6a9ebfe2b09e06a8f298394f6d2abf174e40934ab0ec01fb2d0ddf21211c6fe13eb238563663b017a6b44edca552eb4736c4b7dc6ed907dd9e12a21b51b64b46f902f76fb7aaf805c1db8070574d8d0431a23e324a750f77fb72340a17a42300ee4ca8207301e95a731da229a63ab9c6b44541fbd2c11d016d810b3b3b2b38f15b5b40f0a4910332829c2062f1f7cc61f5b03677d73c54cafa1004ced41f315d46444946faae571d6f426e6dbd45d9780eb466df042005298adabf7ce0ef766dfeb94cd449c7ed0046c880339599c4711af073ce649b1e237c40b50a5536283e03bdbb7afad78bd08707715c67fb43295f905b4c479178809d429a8e167a9a8c6dfd8ab20b4edebdc38d6dec879a3202e1b752690d9bb5b0c07c5a227c79cc200e713a99251a4219d62ad5556900cf69bd384b6c8e726c7be267471d0d23af956da165af4af757246c2ebcc302b39e8ef2fccb4971b234fcda22d759ddb20e27269ee7f7fe67898a9de721bfa02ab0becaa046d00ea16cb1afc4e2eab40d0ac17121c565686e5cbd0cbdfbd9d6db5c70278b9c9db5a83176d04f61fbfbc4471d721340ede2746e5c312ded4f26787985af92b64fae3f253dbdde97f6a5e1996fd4d865599e32ff76325d3e9abe93184c02988ee89a4504356a4ef3b9b7a57cbb9637ca90af34a7676b9ef559325c3cca4e29d69fec1887f5440bb101361d744ad292a8547f22b4f22b419a42aa836169b89190f46d9560824cb2ac6e8771de8223216a5e647e132ab9eebcba89569ab339cb1c3d70fe806b31f4f4c600b4103b8d7583ebff16e43dcda551e6530f975122eb8b29"
+
+const verifiedSignatureEncryptedMessageHex = "c2b304000108000605026048f6d600210910a34d7e18c20c31bb1621045fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb9a3b0400a32ddac1af259c1b0abab0041327ea04970944401978fb647dd1cf9aba4f164e43f0d8a9389501886474bdd4a6e77f6aea945c07dfbf87743835b44cc2c39a1f9aeecfa83135abc92e18e50396f2e6a06c44e0188b0081effbfb4160d28f118d4ff73dd199a102e47cffd8c7ff2bacd83ae72b5820c021a486766dd587b5da61"
+
+const unverifiedSignatureEncryptedMessageHex = "c2b304000108000605026048f6d600210910a34d7e18c20c31bb1621045fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb9a3b0400a32ddac1af259c1b0abab0041327ea04970944401978fb647dd1cf9aba4f164e43f0d8a9389501886474bdd4a6e77f6aea945c07dfbf87743835b44cc2c39a1f9aeecfa83135abc92e18e50396f2e6a06c44e0188b0081effbfb4160d28f118d4ff73dd199a102e47cffd8c7ff2bacd83ae72b5820c021a486766dd587b5da61"
+
+const signedEncryptedMessage2Hex = "85010e03cf6a7abcd43e36731003fb057f5495b79db367e277cdbe4ab90d924ddee0c0381494112ff8c1238fb0184af35d1731573b01bc4c55ecacd2aafbe2003d36310487d1ecc9ac994f3fada7f9f7f5c3a64248ab7782906c82c6ff1303b69a84d9a9529c31ecafbcdb9ba87e05439897d87e8a2a3dec55e14df19bba7f7bd316291c002ae2efd24f83f9e3441203fc081c0c23dc3092a454ca8a082b27f631abf73aca341686982e8fbda7e0e7d863941d68f3de4a755c2964407f4b5e0477b3196b8c93d551dd23c8beef7d0f03fbb1b6066f78907faf4bf1677d8fcec72651124080e0b7feae6b476e72ab207d38d90b958759fdedfc3c6c35717c9dbfc979b3cfbbff0a76d24a5e57056bb88acbd2a901ef64bc6e4db02adc05b6250ff378de81dca18c1910ab257dff1b9771b85bb9bbe0a69f5989e6d1710a35e6dfcceb7d8fb5ccea8db3932b3d9ff3fe0d327597c68b3622aec8e3716c83a6c93f497543b459b58ba504ed6bcaa747d37d2ca746fe49ae0a6ce4a8b694234e941b5159ff8bd34b9023da2814076163b86f40eed7c9472f81b551452d5ab87004a373c0172ec87ea6ce42ccfa7dbdad66b745496c4873d8019e8c28d6b3"
+
+const signatureEncryptedMessage2Hex = "c24604001102000605024dfd0166000a091033af447ccd759b09bae600a096ec5e63ecf0a403085e10f75cc3bab327663282009f51fad9df457ed8d2b70d8a73c76e0443eac0f377"
+
+const symmetricallyEncryptedCompressedHex = "c32e040903085a357c1a7b5614ed00cc0d1d92f428162058b3f558a0fb0980d221ebac6c97d5eda4e0fe32f6e706e94dd263012d6ca1ef8c4bbd324098225e603a10c85ebf09cbf7b5aeeb5ce46381a52edc51038b76a8454483be74e6dcd1e50d5689a8ae7eceaeefed98a0023d49b22eb1f65c2aa1ef1783bb5e1995713b0457102ec3c3075fe871267ffa4b686ad5d52000d857"
+
+const dsaTestKeyHex = "9901a2044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794"
+
+const dsaTestKeyPrivateHex = "9501bb044d6c49de110400cb5ce438cf9250907ac2ba5bf6547931270b89f7c4b53d9d09f4d0213a5ef2ec1f26806d3d259960f872a4a102ef1581ea3f6d6882d15134f21ef6a84de933cc34c47cc9106efe3bd84c6aec12e78523661e29bc1a61f0aab17fa58a627fd5fd33f5149153fbe8cd70edf3d963bc287ef875270ff14b5bfdd1bca4483793923b00a0fe46d76cb6e4cbdc568435cd5480af3266d610d303fe33ae8273f30a96d4d34f42fa28ce1112d425b2e3bf7ea553d526e2db6b9255e9dc7419045ce817214d1a0056dbc8d5289956a4b1b69f20f1105124096e6a438f41f2e2495923b0f34b70642607d45559595c7fe94d7fa85fc41bf7d68c1fd509ebeaa5f315f6059a446b9369c277597e4f474a9591535354c7e7f4fd98a08aa60400b130c24ff20bdfbf683313f5daebf1c9b34b3bdadfc77f2ddd72ee1fb17e56c473664bc21d66467655dd74b9005e3a2bacce446f1920cd7017231ae447b67036c9b431b8179deacd5120262d894c26bc015bffe3d827ba7087ad9b700d2ca1f6d16cc1786581e5dd065f293c31209300f9b0afcc3f7c08dd26d0a22d87580b4d00009f592e0619d823953577d4503061706843317e4fee083db41054657374204b65792033202844534129886204131102002205024d6c49de021b03060b090807030206150802090a0b0416020301021e01021780000a0910338934250ccc03607e0400a0bdb9193e8a6b96fc2dfc108ae848914b504481f100a09c4dc148cb693293a67af24dd40d2b13a9e36794"
+
+const p256TestKeyHex = "98520456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b7754b8560456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b6030108078861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e"
+
+const p256TestKeyPrivateHex = "94a50456e5b83813082a8648ce3d030107020304a2072cd6d21321266c758cc5b83fab0510f751cb8d91897cddb7047d8d6f185546e2107111b0a95cb8ef063c33245502af7a65f004d5919d93ee74eb71a66253fe070302f0c2bfb0b6c30f87ee1599472b8636477eab23ced13b271886a4b50ed34c9d8436af5af5b8f88921f0efba6ef8c37c459bbb88bc1c6a13bbd25c4ce9b1e97679569ee77645d469bf4b43de637f5561b424502d3235362054657374204b6579203c696e76616c6964406578616d706c652e636f6d3e8879041313080021050256e5b838021b03050b09080702061508090a0b020416020301021e01021780000a0910d44a2c495918513e54e50100dfa64f97d9b47766fc1943c6314ba3f2b2a103d71ad286dc5b1efb96a345b0c80100dbc8150b54241f559da6ef4baacea6d31902b4f4b1bdc09b34bf0502334b77549ca90456e5b83812082a8648ce3d030107020304bfe3cea9cee13486f8d518aa487fecab451f25467d2bf08e58f63e5fa525d5482133e6a79299c274b068ef0be448152ad65cf11cf764348588ca4f6a0bcf22b603010807fe0703027510012471a603cfee2968dce19f732721ddf03e966fd133b4e3c7a685b788705cbc46fb026dc94724b830c9edbaecd2fb2c662f23169516cacd1fe423f0475c364ecc10abcabcfd4bbbda1a36a1bd8861041813080009050256e5b838021b0c000a0910d44a2c495918513e4a4800ff49d589fa64024ad30be363a032e3a0e0e6f5db56ba4c73db850518bf0121b8f20100fd78e065f4c70ea5be9df319ea67e493b936fc78da834a71828043d3154af56e"
+
+const armoredPrivateKeyBlock = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.10 (GNU/Linux)
+
+lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp
+idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn
+vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB
+AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X
+0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL
+IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk
+VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn
+gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9
+TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx
+q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz
+dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
+CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1
+ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+
+eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid
+AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV
+bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK
+/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA
+A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX
+TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc
+lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6
+rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN
+oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8
+QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU
+nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC
+AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp
+BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad
+AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
+VrM0m72/jnpKo04=
+=zNCn
+-----END PGP PRIVATE KEY BLOCK-----`
+
+const e2ePublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Charset: UTF-8
+
+xv8AAABSBAAAAAATCCqGSM49AwEHAgME1LRoXSpOxtHXDUdmuvzchyg6005qIBJ4
+sfaSxX7QgH9RV2ONUhC+WiayCNADq+UMzuR/vunSr4aQffXvuGnR383/AAAAFDxk
+Z2lsQHlhaG9vLWluYy5jb20+wv8AAACGBBATCAA4/wAAAAWCVGvAG/8AAAACiwn/
+AAAACZC2VkQCOjdvYf8AAAAFlQgJCgv/AAAAA5YBAv8AAAACngEAAE1BAP0X8veD
+24IjmI5/C6ZAfVNXxgZZFhTAACFX75jUA3oD6AEAzoSwKf1aqH6oq62qhCN/pekX
++WAsVMBhNwzLpqtCRjLO/wAAAFYEAAAAABIIKoZIzj0DAQcCAwT50ain7vXiIRv8
+B1DO3x3cE/aattZ5sHNixJzRCXi2vQIA5QmOxZ6b5jjUekNbdHG3SZi1a2Ak5mfX
+fRxC/5VGAwEIB8L/AAAAZQQYEwgAGP8AAAAFglRrwBz/AAAACZC2VkQCOjdvYQAA
+FJAA9isX3xtGyMLYwp2F3nXm7QEdY5bq5VUcD/RJlj792VwA/1wH0pCzVLl4Q9F9
+ex7En5r7rHR5xwX82Msc+Rq9dSyO
+=7MrZ
+-----END PGP PUBLIC KEY BLOCK-----`
+
+const dsaKeyWithSHA512 = `9901a2044f04b07f110400db244efecc7316553ee08d179972aab87bb1214de7692593fcf5b6feb1c80fba268722dd464748539b85b81d574cd2d7ad0ca2444de4d849b8756bad7768c486c83a824f9bba4af773d11742bdfb4ac3b89ef8cc9452d4aad31a37e4b630d33927bff68e879284a1672659b8b298222fc68f370f3e24dccacc4a862442b9438b00a0ea444a24088dc23e26df7daf8f43cba3bffc4fe703fe3d6cd7fdca199d54ed8ae501c30e3ec7871ea9cdd4cf63cfe6fc82281d70a5b8bb493f922cd99fba5f088935596af087c8d818d5ec4d0b9afa7f070b3d7c1dd32a84fca08d8280b4890c8da1dde334de8e3cad8450eed2a4a4fcc2db7b8e5528b869a74a7f0189e11ef097ef1253582348de072bb07a9fa8ab838e993cef0ee203ff49298723e2d1f549b00559f886cd417a41692ce58d0ac1307dc71d85a8af21b0cf6eaa14baf2922d3a70389bedf17cc514ba0febbd107675a372fe84b90162a9e88b14d4b1c6be855b96b33fb198c46f058568817780435b6936167ebb3724b680f32bf27382ada2e37a879b3d9de2abe0c3f399350afd1ad438883f4791e2e3b4184453412068617368207472756e636174696f6e207465737488620413110a002205024f04b07f021b03060b090807030206150802090a0b0416020301021e01021780000a0910ef20e0cefca131581318009e2bf3bf047a44d75a9bacd00161ee04d435522397009a03a60d51bd8a568c6c021c8d7cf1be8d990d6417b0020003`
+
+const unknownHashFunctionHex = `8a00000040040001990006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const rsaSignatureBadMPIlength = `8a00000040040001030006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const missingHashFunctionHex = `8a00000040040001030006050253863c24000a09103b4fe6acc0b21f32ffff0101010101010101010101010101010101010101010101010101010101010101010101010101`
+
+const campbellQuine = `a0b001000300fcffa0b001000d00f2ff000300fcffa0b001000d00f2ff8270a01c00000500faff8270a01c00000500faff000500faff001400ebff8270a01c00000500faff000500faff001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400001400ebff428821c400000000ffff000000ffff000b00f4ff428821c400000000ffff000000ffff000b00f4ff0233214c40000100feff000233214c40000100feff0000`
+
+const keyV4forVerifyingSignedMessageV3 = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: GPGTools - https://gpgtools.org
+
+mI0EVfxoFQEEAMBIqmbDfYygcvP6Phr1wr1XI41IF7Qixqybs/foBF8qqblD9gIY
+BKpXjnBOtbkcVOJ0nljd3/sQIfH4E0vQwK5/4YRQSI59eKOqd6Fx+fWQOLG+uu6z
+tewpeCj9LLHvibx/Sc7VWRnrznia6ftrXxJ/wHMezSab3tnGC0YPVdGNABEBAAG0
+JEdvY3J5cHRvIFRlc3QgS2V5IDx0aGVtYXhAZ21haWwuY29tPoi5BBMBCgAjBQJV
+/GgVAhsDBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQeXnQmhdGW9PFVAP+
+K7TU0qX5ArvIONIxh/WAweyOk884c5cE8f+3NOPOOCRGyVy0FId5A7MmD5GOQh4H
+JseOZVEVCqlmngEvtHZb3U1VYtVGE5WZ+6rQhGsMcWP5qaT4soYwMBlSYxgYwQcx
+YhN9qOr292f9j2Y//TTIJmZT4Oa+lMxhWdqTfX+qMgG4jQRV/GgVAQQArhFSiij1
+b+hT3dnapbEU+23Z1yTu1DfF6zsxQ4XQWEV3eR8v+8mEDDNcz8oyyF56k6UQ3rXi
+UMTIwRDg4V6SbZmaFbZYCOwp/EmXJ3rfhm7z7yzXj2OFN22luuqbyVhuL7LRdB0M
+pxgmjXb4tTvfgKd26x34S+QqUJ7W6uprY4sAEQEAAYifBBgBCgAJBQJV/GgVAhsM
+AAoJEHl50JoXRlvT7y8D/02ckx4OMkKBZo7viyrBw0MLG92i+DC2bs35PooHR6zz
+786mitjOp5z2QWNLBvxC70S0qVfCIz8jKupO1J6rq6Z8CcbLF3qjm6h1omUBf8Nd
+EfXKD2/2HV6zMKVknnKzIEzauh+eCKS2CeJUSSSryap/QLVAjRnckaES/OsEWhNB
+=RZia
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const signedMessageV3 = `-----BEGIN PGP MESSAGE-----
+Comment: GPGTools - https://gpgtools.org
+
+owGbwMvMwMVYWXlhlrhb9GXG03JJDKF/MtxDMjKLFYAoUaEktbhEITe1uDgxPVWP
+q5NhKjMrWAVcC9evD8z/bF/uWNjqtk/X3y5/38XGRQHm/57rrDRYuGnTw597Xqka
+uM3137/hH3Os+Jf2dc0fXOITKwJvXJvecPVs0ta+Vg7ZO1MLn8w58Xx+6L58mbka
+DGHyU9yTueZE8D+QF/Tz28Y78dqtF56R1VPn9Xw4uJqrWYdd7b3vIZ1V6R4Nh05d
+iT57d/OhWwA=
+=hG7R
+-----END PGP MESSAGE-----
+`
+
+// https://mailarchive.ietf.org/arch/msg/openpgp/9SheW_LENE0Kxf7haNllovPyAdY/
+const v5PrivKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lGEFXJH05BYAAAAtCSsGAQQB2kcPAQEHQFhZlVcVVtwf+21xNQPX+ecMJJBL0MPd
+fj75iux+my8QAAAAAAAiAQCHZ1SnSUmWqxEsoI6facIVZQu6mph3cBFzzTvcm5lA
+Ng5ctBhlbW1hLmdvbGRtYW5AZXhhbXBsZS5uZXSIlgUTFggASCIhBRk0e8mHJGQC
+X5nfPsLgAA7ZiEiS4fez6kyUAJFZVptUBQJckfTkAhsDBQsJCAcCAyICAQYVCgkI
+CwIEFgIDAQIeBwIXgAAA9cAA/jiR3yMsZMeEQ40u6uzEoXa6UXeV/S3wwJAXRJy9
+M8s0AP9vuL/7AyTfFXwwzSjDnYmzS0qAhbLDQ643N+MXGBJ2BZxmBVyR9OQSAAAA
+MgorBgEEAZdVAQUBAQdA+nysrzml2UCweAqtpDuncSPlvrcBWKU0yfU0YvYWWAoD
+AQgHAAAAAAAiAP9OdAPppjU1WwpqjIItkxr+VPQRT8Zm/Riw7U3F6v3OiBFHiHoF
+GBYIACwiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVAUCXJH05AIb
+DAAAOSQBAP4BOOIR/sGLNMOfeb5fPs/02QMieoiSjIBnijhob2U5AQC+RtOHCHx7
+TcIYl5/Uyoi+FOvPLcNw4hOv2nwUzSSVAw==
+=IiS2
+-----END PGP PRIVATE KEY BLOCK-----`
+
+// Generated with the above private key
+const v5PrivKeyMsg = `-----BEGIN PGP MESSAGE-----
+Version: OpenPGP.js v4.10.7
+Comment: https://openpgpjs.org
+
+xA0DAQoWGTR7yYckZAIByxF1B21zZy50eHRfbIGSdGVzdMJ3BQEWCgAGBQJf
+bIGSACMiIQUZNHvJhyRkAl+Z3z7C4AAO2YhIkuH3s+pMlACRWVabVDQvAP9G
+y29VPonFXqi2zKkpZrvyvZxg+n5e8Nt9wNbuxeCd3QD/TtO2s+JvjrE4Siwv
+UQdl5MlBka1QSNbMq2Bz7XwNPg4=
+=6lbM
+-----END PGP MESSAGE-----`
+
+const keyWithExpiredCrossSig = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv
+/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz
+/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/
+5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3
+X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv
+9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0
+qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb
+SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb
+vLIwa3T4CyshfT0AEQEAAc0hQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w
+bGU+wsEABBMBCgATBYJeO2eVAgsJAxUICgKbAQIeAQAhCRD7/MgqAV5zMBYhBNGm
+bhojsYLJmA94jPv8yCoBXnMwKWUMAJ3FKZfJ2mXvh+GFqgymvK4NoKkDRPB0CbUN
+aDdG7ZOizQrWXo7Da2MYIZ6eZUDqBKLdhZ5gZfVnisDfu/yeCgpENaKib1MPHpA8
+nZQjnPejbBDomNqY8HRzr5jvXNlwywBpjWGtegCKUY9xbSynjbfzIlMrWL4S+Rfl
++bOOQKRyYJWXmECmVyqY8cz2VUYmETjNcwC8VCDUxQnhtcCJ7Aej22hfYwVEPb/J
+BsJBPq8WECCiGfJ9Y2y6TF+62KzG9Kfs5hqUeHhQy8V4TSi479ewwL7DH86XmIIK
+chSANBS+7iyMtctjNZfmF9zYdGJFvjI/mbBR/lK66E515Inuf75XnL8hqlXuwqvG
+ni+i03Aet1DzULZEIio4uIU6ioc1lGO9h7K2Xn4S7QQH1QoISNMWqXibUR0RCGjw
+FsEDTt2QwJl8XXxoJCooM7BCcCQo+rMNVUHDjIwrdoQjPld3YZsUQQRcqH6bLuln
+cfn5ufl8zTGWKydoj/iTz8KcjZ7w187AzQRdpZzyAQwA1jC/XGxjK6ddgrRfW9j+
+s/U00++EvIsgTs2kr3Rg0GP7FLWV0YNtR1mpl55/bEl7yAxCDTkOgPUMXcaKlnQh
+6zrlt6H53mF6Bvs3inOHQvOsGtU0dqvb1vkTF0juLiJgPlM7pWv+pNQ6IA39vKoQ
+sTMBv4v5vYNXP9GgKbg8inUNT17BxzZYHfw5+q63ectgDm2on1e8CIRCZ76oBVwz
+dkVxoy3gjh1eENlk2D4P0uJNZzF1Q8GV67yLANGMCDICE/OkWn6daipYDzW4iJQt
+YPUWP4hWhjdm+CK+hg6IQUEn2Vtvi16D2blRP8BpUNNa4fNuylWVuJV76rIHvsLZ
+1pbM3LHpRgE8s6jivS3Rz3WRs0TmWCNnvHPqWizQ3VTy+r3UQVJ5AmhJDrZdZq9i
+aUIuZ01PoE1+CHiJwuxPtWvVAxf2POcm1M/F1fK1J0e+lKlQuyonTXqXR22Y41wr
+fP2aPk3nPSTW2DUAf3vRMZg57ZpRxLEhEMxcM4/LMR+PABEBAAHCwrIEGAEKAAkF
+gl8sAVYCmwIB3QkQ+/zIKgFeczDA+qAEGQEKAAwFgl47Z5UFgwB4TOAAIQkQfC+q
+Tfk8N7IWIQQd3OFfCSF87i87N2B8L6pN+Tw3st58C/0exp0X2U4LqicSHEOSqHZj
+jiysdqIELHGyo5DSPv92UFPp36aqjF9OFgtNNwSa56fmAVCD4+hor/fKARRIeIjF
+qdIC5Y/9a4B10NQFJa5lsvB38x/d39LI2kEoglZnqWgdJskROo3vNQF4KlIcm6FH
+dn4WI8UkC5oUUcrpZVMSKoacIaxLwqnXT42nIVgYYuqrd/ZagZZjG5WlrTOd5+NI
+zi/l0fWProcPHGLjmAh4Thu8i7omtVw1nQaMnq9I77ffg3cPDgXknYrLL+q8xXh/
+0mEJyIhnmPwllWCSZuLv9DrD5pOexFfdlwXhf6cLzNpW6QhXD/Tf5KrqIPr9aOv8
+9xaEEXWh0vEby2kIsI2++ft+vfdIyxYw/wKqx0awTSnuBV1rG3z1dswX4BfoY66x
+Bz3KOVqlz9+mG/FTRQwrgPvR+qgLCHbuotxoGN7fzW+PI75hQG5JQAqhsC9sHjQH
+UrI21/VUNwzfw3v5pYsWuFb5bdQ3ASJetICQiMy7IW8WIQTRpm4aI7GCyZgPeIz7
+/MgqAV5zMG6/C/wLpPl/9e6Hf5wmXIUwpZNQbNZvpiCcyx9sXsHXaycOQVxn3McZ
+nYOUP9/mobl1tIeDQyTNbkxWjU0zzJl8XQsDZerb5098pg+x7oGIL7M1vn5s5JMl
+owROourqF88JEtOBxLMxlAM7X4hB48xKQ3Hu9hS1GdnqLKki4MqRGl4l5FUwyGOM
+GjyS3TzkfiDJNwQxybQiC9n57ij20ieNyLfuWCMLcNNnZUgZtnF6wCctoq/0ZIWu
+a7nvuA/XC2WW9YjEJJiWdy5109pqac+qWiY11HWy/nms4gpMdxVpT0RhrKGWq4o0
+M5q3ZElOoeN70UO3OSbU5EVrG7gB1GuwF9mTHUVlV0veSTw0axkta3FGT//XfSpD
+lRrCkyLzwq0M+UUHQAuYpAfobDlDdnxxOD2jm5GyTzak3GSVFfjW09QFVO6HlGp5
+01/jtzkUiS6nwoHHkfnyn0beZuR8X6KlcrzLB0VFgQFLmkSM9cSOgYhD0PTu9aHb
+hW1Hj9AO8lzggBQ=
+=Nt+N
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+const sigFromKeyWithExpiredCrossSig = `-----BEGIN PGP SIGNATURE-----
+
+wsDzBAABCgAGBYJfLAFsACEJEHwvqk35PDeyFiEEHdzhXwkhfO4vOzdgfC+qTfk8
+N7KiqwwAts4QGB7v9bABCC2qkTxJhmStC0wQMcHRcjL/qAiVnmasQWmvE9KVsdm3
+AaXd8mIx4a37/RRvr9dYrY2eE4uw72cMqPxNja2tvVXkHQvk1oEUqfkvbXs4ypKI
+NyeTWjXNOTZEbg0hbm3nMy+Wv7zgB1CEvAsEboLDJlhGqPcD+X8a6CJGrBGUBUrv
+KVmZr3U6vEzClz3DBLpoddCQseJRhT4YM1nKmBlZ5quh2LFgTSpajv5OsZheqt9y
+EZAPbqmLhDmWRQwGzkWHKceKS7nZ/ox2WK6OS7Ob8ZGZkM64iPo6/EGj5Yc19vQN
+AGiIaPEGszBBWlOpHTPhNm0LB0nMWqqaT87oNYwP8CQuuxDb6rKJ2lffCmZH27Lb
+UbQZcH8J+0UhpeaiadPZxH5ATJAcenmVtVVMLVOFnm+eIlxzov9ntpgGYt8hLdXB
+ITEG9mMgp3TGS9ZzSifMZ8UGtHdp9QdBg8NEVPFzDOMGxpc/Bftav7RRRuPiAER+
+7A5CBid5
+=aQkm
+-----END PGP SIGNATURE-----
+`
+
+const signedMessageWithCriticalNotation = `-----BEGIN PGP MESSAGE-----
+
+owGbwMvMwMH4oOW7S46CznTG09xJDDE3Wl1KUotLuDousDAwcjBYiSmyXL+48d6x
+U1PSGUxcj8IUszKBVMpMaWAAAgEGZpAeh9SKxNyCnFS95PzcytRiBi5OAZjyXXzM
+f8WYLqv7TXP61Sa4rqT12CI3xaN73YS2pt089f96odCKaEPnWJ3iSGmzJaW/ug10
+2Zo8Wj2k4s7t8wt4H3HtTu+y5UZfV3VOO+l//sdE/o+Lsub8FZH7/eOq7OnbNp4n
+vwjE8mqJXetNMfj8r2SCyvkEnlVRYR+/mnge+ib56FdJ8uKtqSxyvgA=
+=fRXs
+-----END PGP MESSAGE-----`
+
+const criticalNotationSigner = `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+
+fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5
+GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0
+JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS
+YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6
+AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki
+Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf
+9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa
+JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag
+Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr
+woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb
+LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA
+SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP
+GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2
+bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X
+W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD
+AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY
+hz3tYjKhoFTKEIq3y3Pp
+=h/aX
+-----END PGP PUBLIC KEY BLOCK-----`
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
new file mode 100644
index 0000000..a436959
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
@@ -0,0 +1,407 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package s2k implements the various OpenPGP string-to-key transforms as
+// specified in RFC 4800 section 3.7.1, and Argon2 specified in
+// draft-ietf-openpgp-crypto-refresh-08 section 3.7.1.4.
+package s2k // import "github.com/ProtonMail/go-crypto/openpgp/s2k"
+
+import (
+ "crypto"
+ "hash"
+ "io"
+ "strconv"
+
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "golang.org/x/crypto/argon2"
+)
+
+type Mode uint8
+
+// Defines the default S2KMode constants
+//
+// 0 (simple), 1(salted), 3(iterated), 4(argon2)
+const (
+ SimpleS2K Mode = 0
+ SaltedS2K Mode = 1
+ IteratedSaltedS2K Mode = 3
+ Argon2S2K Mode = 4
+ GnuS2K Mode = 101
+)
+
+const Argon2SaltSize int = 16
+
+// Params contains all the parameters of the s2k packet
+type Params struct {
+ // mode is the mode of s2k function.
+ // It can be 0 (simple), 1(salted), 3(iterated)
+ // 2(reserved) 100-110(private/experimental).
+ mode Mode
+ // hashId is the ID of the hash function used in any of the modes
+ hashId byte
+ // salt is a byte array to use as a salt in hashing process or argon2
+ saltBytes [Argon2SaltSize]byte
+ // countByte is used to determine how many rounds of hashing are to
+ // be performed in s2k mode 3. See RFC 4880 Section 3.7.1.3.
+ countByte byte
+ // passes is a parameter in Argon2 to determine the number of iterations
+ // See RFC the crypto refresh Section 3.7.1.4.
+ passes byte
+ // parallelism is a parameter in Argon2 to determine the degree of paralellism
+ // See RFC the crypto refresh Section 3.7.1.4.
+ parallelism byte
+ // memoryExp is a parameter in Argon2 to determine the memory usage
+ // i.e., 2 ** memoryExp kibibytes
+ // See RFC the crypto refresh Section 3.7.1.4.
+ memoryExp byte
+}
+
+// encodeCount converts an iterative "count" in the range 1024 to
+// 65011712, inclusive, to an encoded count. The return value is the
+// octet that is actually stored in the GPG file. encodeCount panics
+// if i is not in the above range (encodedCount above takes care to
+// pass i in the correct range). See RFC 4880 Section 3.7.7.1.
+func encodeCount(i int) uint8 {
+ if i < 65536 || i > 65011712 {
+ panic("count arg i outside the required range")
+ }
+
+ for encoded := 96; encoded < 256; encoded++ {
+ count := decodeCount(uint8(encoded))
+ if count >= i {
+ return uint8(encoded)
+ }
+ }
+
+ return 255
+}
+
+// decodeCount returns the s2k mode 3 iterative "count" corresponding to
+// the encoded octet c.
+func decodeCount(c uint8) int {
+ return (16 + int(c&15)) << (uint32(c>>4) + 6)
+}
+
+// encodeMemory converts the Argon2 "memory" in the range parallelism*8 to
+// 2**31, inclusive, to an encoded memory. The return value is the
+// octet that is actually stored in the GPG file. encodeMemory panics
+// if is not in the above range
+// See OpenPGP crypto refresh Section 3.7.1.4.
+func encodeMemory(memory uint32, parallelism uint8) uint8 {
+ if memory < (8 * uint32(parallelism)) || memory > uint32(2147483648) {
+ panic("Memory argument memory is outside the required range")
+ }
+
+ for exp := 3; exp < 31; exp++ {
+ compare := decodeMemory(uint8(exp))
+ if compare >= memory {
+ return uint8(exp)
+ }
+ }
+
+ return 31
+}
+
+// decodeMemory computes the decoded memory in kibibytes as 2**memoryExponent
+func decodeMemory(memoryExponent uint8) uint32 {
+ return uint32(1) << memoryExponent
+}
+
+// Simple writes to out the result of computing the Simple S2K function (RFC
+// 4880, section 3.7.1.1) using the given hash and input passphrase.
+func Simple(out []byte, h hash.Hash, in []byte) {
+ Salted(out, h, in, nil)
+}
+
+var zero [1]byte
+
+// Salted writes to out the result of computing the Salted S2K function (RFC
+// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
+func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
+ done := 0
+ var digest []byte
+
+ for i := 0; done < len(out); i++ {
+ h.Reset()
+ for j := 0; j < i; j++ {
+ h.Write(zero[:])
+ }
+ h.Write(salt)
+ h.Write(in)
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
+ done += n
+ }
+}
+
+// Iterated writes to out the result of computing the Iterated and Salted S2K
+// function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase,
+// salt and iteration count.
+func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
+ combined := make([]byte, len(in)+len(salt))
+ copy(combined, salt)
+ copy(combined[len(salt):], in)
+
+ if count < len(combined) {
+ count = len(combined)
+ }
+
+ done := 0
+ var digest []byte
+ for i := 0; done < len(out); i++ {
+ h.Reset()
+ for j := 0; j < i; j++ {
+ h.Write(zero[:])
+ }
+ written := 0
+ for written < count {
+ if written+len(combined) > count {
+ todo := count - written
+ h.Write(combined[:todo])
+ written = count
+ } else {
+ h.Write(combined)
+ written += len(combined)
+ }
+ }
+ digest = h.Sum(digest[:0])
+ n := copy(out[done:], digest)
+ done += n
+ }
+}
+
+// Argon2 writes to out the key derived from the password (in) with the Argon2
+// function (the crypto refresh, section 3.7.1.4)
+func Argon2(out []byte, in []byte, salt []byte, passes uint8, paralellism uint8, memoryExp uint8) {
+ key := argon2.IDKey(in, salt, uint32(passes), decodeMemory(memoryExp), paralellism, uint32(len(out)))
+ copy(out[:], key)
+}
+
+// Generate generates valid parameters from given configuration.
+// It will enforce the Iterated and Salted or Argon2 S2K method.
+func Generate(rand io.Reader, c *Config) (*Params, error) {
+ var params *Params
+ if c != nil && c.Mode() == Argon2S2K {
+ // handle Argon2 case
+ argonConfig := c.Argon2()
+ params = &Params{
+ mode: Argon2S2K,
+ passes: argonConfig.Passes(),
+ parallelism: argonConfig.Parallelism(),
+ memoryExp: argonConfig.EncodedMemory(),
+ }
+ } else if c != nil && c.PassphraseIsHighEntropy && c.Mode() == SaltedS2K { // Allow SaltedS2K if PassphraseIsHighEntropy
+ hashId, ok := algorithm.HashToHashId(c.hash())
+ if !ok {
+ return nil, errors.UnsupportedError("no such hash")
+ }
+
+ params = &Params{
+ mode: SaltedS2K,
+ hashId: hashId,
+ }
+ } else { // Enforce IteratedSaltedS2K method otherwise
+ hashId, ok := algorithm.HashToHashId(c.hash())
+ if !ok {
+ return nil, errors.UnsupportedError("no such hash")
+ }
+ if c != nil {
+ c.S2KMode = IteratedSaltedS2K
+ }
+ params = &Params{
+ mode: IteratedSaltedS2K,
+ hashId: hashId,
+ countByte: c.EncodedCount(),
+ }
+ }
+ if _, err := io.ReadFull(rand, params.salt()); err != nil {
+ return nil, err
+ }
+ return params, nil
+}
+
+// Parse reads a binary specification for a string-to-key transformation from r
+// and returns a function which performs that transform. If the S2K is a special
+// GNU extension that indicates that the private key is missing, then the error
+// returned is errors.ErrDummyPrivateKey.
+func Parse(r io.Reader) (f func(out, in []byte), err error) {
+ params, err := ParseIntoParams(r)
+ if err != nil {
+ return nil, err
+ }
+
+ return params.Function()
+}
+
+// ParseIntoParams reads a binary specification for a string-to-key
+// transformation from r and returns a struct describing the s2k parameters.
+func ParseIntoParams(r io.Reader) (params *Params, err error) {
+ var buf [Argon2SaltSize + 3]byte
+
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return
+ }
+
+ params = &Params{
+ mode: Mode(buf[0]),
+ }
+
+ switch params.mode {
+ case SimpleS2K:
+ _, err = io.ReadFull(r, buf[:1])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ return params, nil
+ case SaltedS2K:
+ _, err = io.ReadFull(r, buf[:9])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ copy(params.salt(), buf[1:9])
+ return params, nil
+ case IteratedSaltedS2K:
+ _, err = io.ReadFull(r, buf[:10])
+ if err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ copy(params.salt(), buf[1:9])
+ params.countByte = buf[9]
+ return params, nil
+ case Argon2S2K:
+ _, err = io.ReadFull(r, buf[:Argon2SaltSize+3])
+ if err != nil {
+ return nil, err
+ }
+ copy(params.salt(), buf[:Argon2SaltSize])
+ params.passes = buf[Argon2SaltSize]
+ params.parallelism = buf[Argon2SaltSize+1]
+ params.memoryExp = buf[Argon2SaltSize+2]
+ return params, nil
+ case GnuS2K:
+ // This is a GNU extension. See
+ // https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109
+ if _, err = io.ReadFull(r, buf[:5]); err != nil {
+ return nil, err
+ }
+ params.hashId = buf[0]
+ if buf[1] == 'G' && buf[2] == 'N' && buf[3] == 'U' && buf[4] == 1 {
+ return params, nil
+ }
+ return nil, errors.UnsupportedError("GNU S2K extension")
+ }
+
+ return nil, errors.UnsupportedError("S2K function")
+}
+
+func (params *Params) Dummy() bool {
+ return params != nil && params.mode == GnuS2K
+}
+
+func (params *Params) salt() []byte {
+ switch params.mode {
+ case SaltedS2K, IteratedSaltedS2K: return params.saltBytes[:8]
+ case Argon2S2K: return params.saltBytes[:Argon2SaltSize]
+ default: return nil
+ }
+}
+
+func (params *Params) Function() (f func(out, in []byte), err error) {
+ if params.Dummy() {
+ return nil, errors.ErrDummyPrivateKey("dummy key found")
+ }
+ var hashObj crypto.Hash
+ if params.mode != Argon2S2K {
+ var ok bool
+ hashObj, ok = algorithm.HashIdToHashWithSha1(params.hashId)
+ if !ok {
+ return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(params.hashId)))
+ }
+ if !hashObj.Available() {
+ return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashObj)))
+ }
+ }
+
+ switch params.mode {
+ case SimpleS2K:
+ f := func(out, in []byte) {
+ Simple(out, hashObj.New(), in)
+ }
+
+ return f, nil
+ case SaltedS2K:
+ f := func(out, in []byte) {
+ Salted(out, hashObj.New(), in, params.salt())
+ }
+
+ return f, nil
+ case IteratedSaltedS2K:
+ f := func(out, in []byte) {
+ Iterated(out, hashObj.New(), in, params.salt(), decodeCount(params.countByte))
+ }
+
+ return f, nil
+ case Argon2S2K:
+ f := func(out, in []byte) {
+ Argon2(out, in, params.salt(), params.passes, params.parallelism, params.memoryExp)
+ }
+ return f, nil
+ }
+
+ return nil, errors.UnsupportedError("S2K function")
+}
+
+func (params *Params) Serialize(w io.Writer) (err error) {
+ if _, err = w.Write([]byte{uint8(params.mode)}); err != nil {
+ return
+ }
+ if params.mode != Argon2S2K {
+ if _, err = w.Write([]byte{params.hashId}); err != nil {
+ return
+ }
+ }
+ if params.Dummy() {
+ _, err = w.Write(append([]byte("GNU"), 1))
+ return
+ }
+ if params.mode > 0 {
+ if _, err = w.Write(params.salt()); err != nil {
+ return
+ }
+ if params.mode == IteratedSaltedS2K {
+ _, err = w.Write([]byte{params.countByte})
+ }
+ if params.mode == Argon2S2K {
+ _, err = w.Write([]byte{params.passes, params.parallelism, params.memoryExp})
+ }
+ }
+ return
+}
+
+// Serialize salts and stretches the given passphrase and writes the
+// resulting key into key. It also serializes an S2K descriptor to
+// w. The key stretching can be configured with c, which may be
+// nil. In that case, sensible defaults will be used.
+func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error {
+ params, err := Generate(rand, c)
+ if err != nil {
+ return err
+ }
+ err = params.Serialize(w)
+ if err != nil {
+ return err
+ }
+
+ f, err := params.Function()
+ if err != nil {
+ return err
+ }
+ f(key, passphrase)
+ return nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
new file mode 100644
index 0000000..25a4442
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_cache.go
@@ -0,0 +1,26 @@
+package s2k
+
+// Cache stores keys derived with s2k functions from one passphrase
+// to avoid recomputation if multiple items are encrypted with
+// the same parameters.
+type Cache map[Params][]byte
+
+// GetOrComputeDerivedKey tries to retrieve the key
+// for the given s2k parameters from the cache.
+// If there is no hit, it derives the key with the s2k function from the passphrase,
+// updates the cache, and returns the key.
+func (c *Cache) GetOrComputeDerivedKey(passphrase []byte, params *Params, expectedKeySize int) ([]byte, error) {
+ key, found := (*c)[*params]
+ if !found || len(key) != expectedKeySize {
+ var err error
+ derivedKey := make([]byte, expectedKeySize)
+ s2k, err := params.Function()
+ if err != nil {
+ return nil, err
+ }
+ s2k(derivedKey, passphrase)
+ (*c)[*params] = key
+ return derivedKey, nil
+ }
+ return key, nil
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
new file mode 100644
index 0000000..b40be52
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go
@@ -0,0 +1,129 @@
+package s2k
+
+import "crypto"
+
+// Config collects configuration parameters for s2k key-stretching
+// transformations. A nil *Config is valid and results in all default
+// values.
+type Config struct {
+ // S2K (String to Key) mode, used for key derivation in the context of secret key encryption
+ // and passphrase-encrypted data. Either s2k.Argon2S2K or s2k.IteratedSaltedS2K may be used.
+ // If the passphrase is a high-entropy key, indicated by setting PassphraseIsHighEntropy to true,
+ // s2k.SaltedS2K can also be used.
+ // Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it
+ //(pending standardisation).
+ // 0 (simple), 1(salted), 3(iterated), 4(argon2)
+ // 2(reserved) 100-110(private/experimental).
+ S2KMode Mode
+ // Only relevant if S2KMode is not set to s2k.Argon2S2K.
+ // Hash is the default hash function to be used. If
+ // nil, SHA256 is used.
+ Hash crypto.Hash
+ // Argon2 parameters for S2K (String to Key).
+ // Only relevant if S2KMode is set to s2k.Argon2S2K.
+ // If nil, default parameters are used.
+ // For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4.
+ Argon2Config *Argon2Config
+ // Only relevant if S2KMode is set to s2k.IteratedSaltedS2K.
+ // Iteration count for Iterated S2K (String to Key). It
+ // determines the strength of the passphrase stretching when
+ // the said passphrase is hashed to produce a key. S2KCount
+ // should be between 65536 and 65011712, inclusive. If Config
+ // is nil or S2KCount is 0, the value 16777216 used. Not all
+ // values in the above range can be represented. S2KCount will
+ // be rounded up to the next representable value if it cannot
+ // be encoded exactly. When set, it is strongly encrouraged to
+ // use a value that is at least 65536. See RFC 4880 Section
+ // 3.7.1.3.
+ S2KCount int
+ // Indicates whether the passphrase passed by the application is a
+ // high-entropy key (e.g. it's randomly generated or derived from
+ // another passphrase using a strong key derivation function).
+ // When true, allows the S2KMode to be s2k.SaltedS2K.
+ // When the passphrase is not a high-entropy key, using SaltedS2K is
+ // insecure, and not allowed by draft-ietf-openpgp-crypto-refresh-08.
+ PassphraseIsHighEntropy bool
+}
+
+// Argon2Config stores the Argon2 parameters
+// A nil *Argon2Config is valid and results in all default
+type Argon2Config struct {
+ NumberOfPasses uint8
+ DegreeOfParallelism uint8
+ // The memory parameter for Argon2 specifies desired memory usage in kibibytes.
+ // For example memory=64*1024 sets the memory cost to ~64 MB.
+ Memory uint32
+}
+
+func (c *Config) Mode() Mode {
+ if c == nil {
+ return IteratedSaltedS2K
+ }
+ return c.S2KMode
+}
+
+func (c *Config) hash() crypto.Hash {
+ if c == nil || uint(c.Hash) == 0 {
+ return crypto.SHA256
+ }
+
+ return c.Hash
+}
+
+func (c *Config) Argon2() *Argon2Config {
+ if c == nil || c.Argon2Config == nil {
+ return nil
+ }
+ return c.Argon2Config
+}
+
+// EncodedCount get encoded count
+func (c *Config) EncodedCount() uint8 {
+ if c == nil || c.S2KCount == 0 {
+ return 224 // The common case. Corresponding to 16777216
+ }
+
+ i := c.S2KCount
+
+ switch {
+ case i < 65536:
+ i = 65536
+ case i > 65011712:
+ i = 65011712
+ }
+
+ return encodeCount(i)
+}
+
+func (c *Argon2Config) Passes() uint8 {
+ if c == nil || c.NumberOfPasses == 0 {
+ return 3
+ }
+ return c.NumberOfPasses
+}
+
+func (c *Argon2Config) Parallelism() uint8 {
+ if c == nil || c.DegreeOfParallelism == 0 {
+ return 4
+ }
+ return c.DegreeOfParallelism
+}
+
+func (c *Argon2Config) EncodedMemory() uint8 {
+ if c == nil || c.Memory == 0 {
+ return 16 // 64 MiB of RAM
+ }
+
+ memory := c.Memory
+ lowerBound := uint32(c.Parallelism())*8
+ upperBound := uint32(2147483648)
+
+ switch {
+ case memory < lowerBound:
+ memory = lowerBound
+ case memory > upperBound:
+ memory = upperBound
+ }
+
+ return encodeMemory(memory, c.Parallelism())
+}
diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
new file mode 100644
index 0000000..7fdd13a
--- /dev/null
+++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
@@ -0,0 +1,583 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+ "crypto"
+ "hash"
+ "io"
+ "strconv"
+ "time"
+
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/errors"
+ "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
+)
+
+// DetachSign signs message with the private key from signer (which must
+// already have been decrypted) and writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return detachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// ArmoredDetachSign signs message with the private key from signer (which
+// must already have been decrypted) and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
+ return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
+}
+
+// DetachSignText signs message (after canonicalising the line endings) with
+// the private key from signer (which must already have been decrypted) and
+// writes the signature to w.
+// If config is nil, sensible defaults will be used.
+func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return detachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+// ArmoredDetachSignText signs message (after canonicalising the line endings)
+// with the private key from signer (which must already have been decrypted)
+// and writes an armored signature to w.
+// If config is nil, sensible defaults will be used.
+func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
+ return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
+}
+
+func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+ out, err := armor.Encode(w, SignatureType, nil)
+ if err != nil {
+ return
+ }
+ err = detachSign(out, signer, message, sigType, config)
+ if err != nil {
+ return
+ }
+ return out.Close()
+}
+
+func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
+ signingKey, ok := signer.SigningKeyById(config.Now(), config.SigningKey())
+ if !ok {
+ return errors.InvalidArgumentError("no valid signing keys")
+ }
+ if signingKey.PrivateKey == nil {
+ return errors.InvalidArgumentError("signing key doesn't have a private key")
+ }
+ if signingKey.PrivateKey.Encrypted {
+ return errors.InvalidArgumentError("signing key is encrypted")
+ }
+ if _, ok := algorithm.HashToHashId(config.Hash()); !ok {
+ return errors.InvalidArgumentError("invalid hash function")
+ }
+
+ sig := createSignaturePacket(signingKey.PublicKey, sigType, config)
+
+ h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
+ if err != nil {
+ return
+ }
+ if _, err = io.Copy(wrappedHash, message); err != nil {
+ return err
+ }
+
+ err = sig.Sign(h, signingKey.PrivateKey, config)
+ if err != nil {
+ return
+ }
+
+ return sig.Serialize(w)
+}
+
+// FileHints contains metadata about encrypted files. This metadata is, itself,
+// encrypted.
+type FileHints struct {
+ // IsBinary can be set to hint that the contents are binary data.
+ IsBinary bool
+ // FileName hints at the name of the file that should be written. It's
+ // truncated to 255 bytes if longer. It may be empty to suggest that the
+ // file should not be written to disk. It may be equal to "_CONSOLE" to
+ // suggest the data should not be written to disk.
+ FileName string
+ // ModTime contains the modification time of the file, or the zero time if not applicable.
+ ModTime time.Time
+}
+
+// SymmetricallyEncrypt acts like gpg -c: it encrypts a file with a passphrase.
+// The resulting WriteCloser must be closed after the contents of the file have
+// been written.
+// If config is nil, sensible defaults will be used.
+func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ if hints == nil {
+ hints = &FileHints{}
+ }
+
+ key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, passphrase, config)
+ if err != nil {
+ return
+ }
+
+ var w io.WriteCloser
+ cipherSuite := packet.CipherSuite{
+ Cipher: config.Cipher(),
+ Mode: config.AEAD().Mode(),
+ }
+ w, err = packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), config.AEAD() != nil, cipherSuite, key, config)
+ if err != nil {
+ return
+ }
+
+ literalData := w
+ if algo := config.Compression(); algo != packet.CompressionNone {
+ var compConfig *packet.CompressionConfig
+ if config != nil {
+ compConfig = config.CompressionConfig
+ }
+ literalData, err = packet.SerializeCompressed(w, algo, compConfig)
+ if err != nil {
+ return
+ }
+ }
+
+ var epochSeconds uint32
+ if !hints.ModTime.IsZero() {
+ epochSeconds = uint32(hints.ModTime.Unix())
+ }
+ return packet.SerializeLiteral(literalData, hints.IsBinary, hints.FileName, epochSeconds)
+}
+
+// intersectPreferences mutates and returns a prefix of a that contains only
+// the values in the intersection of a and b. The order of a is preserved.
+func intersectPreferences(a []uint8, b []uint8) (intersection []uint8) {
+ var j int
+ for _, v := range a {
+ for _, v2 := range b {
+ if v == v2 {
+ a[j] = v
+ j++
+ break
+ }
+ }
+ }
+
+ return a[:j]
+}
+
+// intersectPreferences mutates and returns a prefix of a that contains only
+// the values in the intersection of a and b. The order of a is preserved.
+func intersectCipherSuites(a [][2]uint8, b [][2]uint8) (intersection [][2]uint8) {
+ var j int
+ for _, v := range a {
+ for _, v2 := range b {
+ if v[0] == v2[0] && v[1] == v2[1] {
+ a[j] = v
+ j++
+ break
+ }
+ }
+ }
+
+ return a[:j]
+}
+
+func hashToHashId(h crypto.Hash) uint8 {
+ v, ok := algorithm.HashToHashId(h)
+ if !ok {
+ panic("tried to convert unknown hash")
+ }
+ return v
+}
+
+// EncryptText encrypts a message to a number of recipients and, optionally,
+// signs it. Optional information is contained in 'hints', also encrypted, that
+// aids the recipients in processing the message. The resulting WriteCloser
+// must be closed after the contents of the file have been written. If config
+// is nil, sensible defaults will be used. The signing is done in text mode.
+func EncryptText(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(ciphertext, ciphertext, to, signed, hints, packet.SigTypeText, config)
+}
+
+// Encrypt encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(ciphertext, ciphertext, to, signed, hints, packet.SigTypeBinary, config)
+}
+
+// EncryptSplit encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func EncryptSplit(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(keyWriter, dataWriter, to, signed, hints, packet.SigTypeBinary, config)
+}
+
+// EncryptTextSplit encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func EncryptTextSplit(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ return encrypt(keyWriter, dataWriter, to, signed, hints, packet.SigTypeText, config)
+}
+
+// writeAndSign writes the data as a payload package and, optionally, signs
+// it. hints contains optional information, that is also encrypted,
+// that aids the recipients in processing the message. The resulting
+// WriteCloser must be closed after the contents of the file have been
+// written. If config is nil, sensible defaults will be used.
+func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entity, hints *FileHints, sigType packet.SignatureType, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ var signer *packet.PrivateKey
+ if signed != nil {
+ signKey, ok := signed.SigningKeyById(config.Now(), config.SigningKey())
+ if !ok {
+ return nil, errors.InvalidArgumentError("no valid signing keys")
+ }
+ signer = signKey.PrivateKey
+ if signer == nil {
+ return nil, errors.InvalidArgumentError("no private key in signing key")
+ }
+ if signer.Encrypted {
+ return nil, errors.InvalidArgumentError("signing key must be decrypted")
+ }
+ }
+
+ var hash crypto.Hash
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
+ hash = h
+ break
+ }
+ }
+
+ // If the hash specified by config is a candidate, we'll use that.
+ if configuredHash := config.Hash(); configuredHash.Available() {
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
+ hash = h
+ break
+ }
+ }
+ }
+
+ if hash == 0 {
+ hashId := candidateHashes[0]
+ name, ok := algorithm.HashIdToString(hashId)
+ if !ok {
+ name = "#" + strconv.Itoa(int(hashId))
+ }
+ return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
+ }
+
+ if signer != nil {
+ ops := &packet.OnePassSignature{
+ SigType: sigType,
+ Hash: hash,
+ PubKeyAlgo: signer.PubKeyAlgo,
+ KeyId: signer.KeyId,
+ IsLast: true,
+ }
+ if err := ops.Serialize(payload); err != nil {
+ return nil, err
+ }
+ }
+
+ if hints == nil {
+ hints = &FileHints{}
+ }
+
+ w := payload
+ if signer != nil {
+ // If we need to write a signature packet after the literal
+ // data then we need to stop literalData from closing
+ // encryptedData.
+ w = noOpCloser{w}
+
+ }
+ var epochSeconds uint32
+ if !hints.ModTime.IsZero() {
+ epochSeconds = uint32(hints.ModTime.Unix())
+ }
+ literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds)
+ if err != nil {
+ return nil, err
+ }
+
+ if signer != nil {
+ h, wrappedHash, err := hashForSignature(hash, sigType)
+ if err != nil {
+ return nil, err
+ }
+ metadata := &packet.LiteralData{
+ Format: 't',
+ FileName: hints.FileName,
+ Time: epochSeconds,
+ }
+ if hints.IsBinary {
+ metadata.Format = 'b'
+ }
+ return signatureWriter{payload, literalData, hash, wrappedHash, h, signer, sigType, config, metadata}, nil
+ }
+ return literalData, nil
+}
+
+// encrypt encrypts a message to a number of recipients and, optionally, signs
+// it. hints contains optional information, that is also encrypted, that aids
+// the recipients in processing the message. The resulting WriteCloser must
+// be closed after the contents of the file have been written.
+// If config is nil, sensible defaults will be used.
+func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *Entity, hints *FileHints, sigType packet.SignatureType, config *packet.Config) (plaintext io.WriteCloser, err error) {
+ if len(to) == 0 {
+ return nil, errors.InvalidArgumentError("no encryption recipient provided")
+ }
+
+ // These are the possible ciphers that we'll use for the message.
+ candidateCiphers := []uint8{
+ uint8(packet.CipherAES256),
+ uint8(packet.CipherAES128),
+ }
+
+ // These are the possible hash functions that we'll use for the signature.
+ candidateHashes := []uint8{
+ hashToHashId(crypto.SHA256),
+ hashToHashId(crypto.SHA384),
+ hashToHashId(crypto.SHA512),
+ hashToHashId(crypto.SHA3_256),
+ hashToHashId(crypto.SHA3_512),
+ }
+
+ // Prefer GCM if everyone supports it
+ candidateCipherSuites := [][2]uint8{
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeGCM)},
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeEAX)},
+ {uint8(packet.CipherAES256), uint8(packet.AEADModeOCB)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeGCM)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeEAX)},
+ {uint8(packet.CipherAES128), uint8(packet.AEADModeOCB)},
+ }
+
+ candidateCompression := []uint8{
+ uint8(packet.CompressionNone),
+ uint8(packet.CompressionZIP),
+ uint8(packet.CompressionZLIB),
+ }
+
+ encryptKeys := make([]Key, len(to))
+
+ // AEAD is used only if config enables it and every key supports it
+ aeadSupported := config.AEAD() != nil
+
+ for i := range to {
+ var ok bool
+ encryptKeys[i], ok = to[i].EncryptionKey(config.Now())
+ if !ok {
+ return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no valid encryption keys")
+ }
+
+ sig := to[i].PrimaryIdentity().SelfSignature
+ if !sig.SEIPDv2 {
+ aeadSupported = false
+ }
+
+ candidateCiphers = intersectPreferences(candidateCiphers, sig.PreferredSymmetric)
+ candidateHashes = intersectPreferences(candidateHashes, sig.PreferredHash)
+ candidateCipherSuites = intersectCipherSuites(candidateCipherSuites, sig.PreferredCipherSuites)
+ candidateCompression = intersectPreferences(candidateCompression, sig.PreferredCompression)
+ }
+
+ // In the event that the intersection of supported algorithms is empty we use the ones
+ // labelled as MUST that every implementation supports.
+ if len(candidateCiphers) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.3
+ candidateCiphers = []uint8{uint8(packet.CipherAES128)}
+ }
+ if len(candidateHashes) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#hash-algos
+ candidateHashes = []uint8{hashToHashId(crypto.SHA256)}
+ }
+ if len(candidateCipherSuites) == 0 {
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
+ candidateCipherSuites = [][2]uint8{{uint8(packet.CipherAES128), uint8(packet.AEADModeOCB)}}
+ }
+
+ cipher := packet.CipherFunction(candidateCiphers[0])
+ aeadCipherSuite := packet.CipherSuite{
+ Cipher: packet.CipherFunction(candidateCipherSuites[0][0]),
+ Mode: packet.AEADMode(candidateCipherSuites[0][1]),
+ }
+
+ // If the cipher specified by config is a candidate, we'll use that.
+ configuredCipher := config.Cipher()
+ for _, c := range candidateCiphers {
+ cipherFunc := packet.CipherFunction(c)
+ if cipherFunc == configuredCipher {
+ cipher = cipherFunc
+ break
+ }
+ }
+
+ symKey := make([]byte, cipher.KeySize())
+ if _, err := io.ReadFull(config.Random(), symKey); err != nil {
+ return nil, err
+ }
+
+ for _, key := range encryptKeys {
+ if err := packet.SerializeEncryptedKey(keyWriter, key.PublicKey, cipher, symKey, config); err != nil {
+ return nil, err
+ }
+ }
+
+ var payload io.WriteCloser
+ payload, err = packet.SerializeSymmetricallyEncrypted(dataWriter, cipher, aeadSupported, aeadCipherSuite, symKey, config)
+ if err != nil {
+ return
+ }
+
+ payload, err = handleCompression(payload, candidateCompression, config)
+ if err != nil {
+ return nil, err
+ }
+
+ return writeAndSign(payload, candidateHashes, signed, hints, sigType, config)
+}
+
+// Sign signs a message. The resulting WriteCloser must be closed after the
+// contents of the file have been written. hints contains optional information
+// that aids the recipients in processing the message.
+// If config is nil, sensible defaults will be used.
+func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Config) (input io.WriteCloser, err error) {
+ if signed == nil {
+ return nil, errors.InvalidArgumentError("no signer provided")
+ }
+
+ // These are the possible hash functions that we'll use for the signature.
+ candidateHashes := []uint8{
+ hashToHashId(crypto.SHA256),
+ hashToHashId(crypto.SHA384),
+ hashToHashId(crypto.SHA512),
+ hashToHashId(crypto.SHA3_256),
+ hashToHashId(crypto.SHA3_512),
+ }
+ defaultHashes := candidateHashes[0:1]
+ preferredHashes := signed.PrimaryIdentity().SelfSignature.PreferredHash
+ if len(preferredHashes) == 0 {
+ preferredHashes = defaultHashes
+ }
+ candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
+ if len(candidateHashes) == 0 {
+ return nil, errors.InvalidArgumentError("cannot sign because signing key shares no common algorithms with candidate hashes")
+ }
+
+ return writeAndSign(noOpCloser{output}, candidateHashes, signed, hints, packet.SigTypeBinary, config)
+}
+
+// signatureWriter hashes the contents of a message while passing it along to
+// literalData. When closed, it closes literalData, writes a signature packet
+// to encryptedData and then also closes encryptedData.
+type signatureWriter struct {
+ encryptedData io.WriteCloser
+ literalData io.WriteCloser
+ hashType crypto.Hash
+ wrappedHash hash.Hash
+ h hash.Hash
+ signer *packet.PrivateKey
+ sigType packet.SignatureType
+ config *packet.Config
+ metadata *packet.LiteralData // V5 signatures protect document metadata
+}
+
+func (s signatureWriter) Write(data []byte) (int, error) {
+ s.wrappedHash.Write(data)
+ switch s.sigType {
+ case packet.SigTypeBinary:
+ return s.literalData.Write(data)
+ case packet.SigTypeText:
+ flag := 0
+ return writeCanonical(s.literalData, data, &flag)
+ }
+ return 0, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(s.sigType)))
+}
+
+func (s signatureWriter) Close() error {
+ sig := createSignaturePacket(&s.signer.PublicKey, s.sigType, s.config)
+ sig.Hash = s.hashType
+ sig.Metadata = s.metadata
+
+ if err := sig.Sign(s.h, s.signer, s.config); err != nil {
+ return err
+ }
+ if err := s.literalData.Close(); err != nil {
+ return err
+ }
+ if err := sig.Serialize(s.encryptedData); err != nil {
+ return err
+ }
+ return s.encryptedData.Close()
+}
+
+func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature {
+ sigLifetimeSecs := config.SigLifetime()
+ return &packet.Signature{
+ Version: signer.Version,
+ SigType: sigType,
+ PubKeyAlgo: signer.PubKeyAlgo,
+ Hash: config.Hash(),
+ CreationTime: config.Now(),
+ IssuerKeyId: &signer.KeyId,
+ IssuerFingerprint: signer.Fingerprint,
+ Notations: config.Notations(),
+ SigLifetimeSecs: &sigLifetimeSecs,
+ }
+}
+
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
+// TODO: we have two of these in OpenPGP packages alone. This probably needs
+// to be promoted somewhere more common.
+type noOpCloser struct {
+ w io.Writer
+}
+
+func (c noOpCloser) Write(data []byte) (n int, err error) {
+ return c.w.Write(data)
+}
+
+func (c noOpCloser) Close() error {
+ return nil
+}
+
+func handleCompression(compressed io.WriteCloser, candidateCompression []uint8, config *packet.Config) (data io.WriteCloser, err error) {
+ data = compressed
+ confAlgo := config.Compression()
+ if confAlgo == packet.CompressionNone {
+ return
+ }
+
+ // Set algorithm labelled as MUST as fallback
+ // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.4
+ finalAlgo := packet.CompressionNone
+ // if compression specified by config available we will use it
+ for _, c := range candidateCompression {
+ if uint8(confAlgo) == c {
+ finalAlgo = confAlgo
+ break
+ }
+ }
+
+ if finalAlgo != packet.CompressionNone {
+ var compConfig *packet.CompressionConfig
+ if config != nil {
+ compConfig = config.CompressionConfig
+ }
+ data, err = packet.SerializeCompressed(compressed, finalAlgo, compConfig)
+ if err != nil {
+ return
+ }
+ }
+ return data, nil
+}
diff --git a/vendor/github.com/avast/retry-go/v4/.gitignore b/vendor/github.com/avast/retry-go/v4/.gitignore
new file mode 100644
index 0000000..c40eb23
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/.gitignore
@@ -0,0 +1,21 @@
+# Binaries for programs and plugins
+*.exe
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
+.glide/
+
+# dep
+vendor/
+Gopkg.lock
+
+# cover
+coverage.txt
diff --git a/vendor/github.com/avast/retry-go/v4/.godocdown.tmpl b/vendor/github.com/avast/retry-go/v4/.godocdown.tmpl
new file mode 100644
index 0000000..e914ca4
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/.godocdown.tmpl
@@ -0,0 +1,38 @@
+# {{ .Name }}
+
+[](https://github.com/avast/retry-go/releases/latest)
+[](LICENSE.md)
+
+[](https://goreportcard.com/report/github.com/avast/retry-go)
+[](http://godoc.org/github.com/avast/retry-go)
+[](https://codecov.io/github/avast/retry-go?branch=master)
+[](https://sourcegraph.com/github.com/avast/retry-go?badge)
+
+{{ .EmitSynopsis }}
+
+{{ .EmitUsage }}
+
+## Contributing
+
+Contributions are very much welcome.
+
+### Makefile
+
+Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc...
+
+Try `make help` for more information.
+
+### Before pull request
+
+> maybe you need `make setup` in order to setup environment
+
+please try:
+* run tests (`make test`)
+* run linter (`make lint`)
+* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`)
+
+### README
+
+README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown).
+
+Never edit README.md direct, because your change will be lost.
diff --git a/vendor/github.com/avast/retry-go/v4/LICENSE b/vendor/github.com/avast/retry-go/v4/LICENSE
new file mode 100644
index 0000000..f63fca8
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Avast
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/avast/retry-go/v4/Makefile b/vendor/github.com/avast/retry-go/v4/Makefile
new file mode 100644
index 0000000..86544d2
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/Makefile
@@ -0,0 +1,59 @@
+SOURCE_FILES?=$$(go list ./... | grep -v /vendor/)
+TEST_PATTERN?=.
+TEST_OPTIONS?=
+VERSION?=$$(cat VERSION)
+LINTER?=$$(which golangci-lint)
+LINTER_VERSION=1.50.0
+
+ifeq ($(OS),Windows_NT)
+ LINTER_FILE=golangci-lint-$(LINTER_VERSION)-windows-amd64.zip
+ LINTER_UNPACK= >| app.zip; unzip -j app.zip -d $$GOPATH/bin; rm app.zip
+else ifeq ($(OS), Darwin)
+ LINTER_FILE=golangci-lint-$(LINTER_VERSION)-darwin-amd64.tar.gz
+ LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint"
+else
+ LINTER_FILE=golangci-lint-$(LINTER_VERSION)-linux-amd64.tar.gz
+ LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint"
+endif
+
+setup:
+ go install github.com/pierrre/gotestcover@latest
+ go install golang.org/x/tools/cmd/cover@latest
+ go install github.com/robertkrimen/godocdown/godocdown@latest
+ go mod download
+
+generate: ## Generate README.md
+ godocdown >| README.md
+
+test: generate test_and_cover_report lint
+
+test_and_cover_report:
+ gotestcover $(TEST_OPTIONS) -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m
+
+cover: test ## Run all the tests and opens the coverage report
+ go tool cover -html=coverage.txt
+
+fmt: ## gofmt and goimports all go files
+ find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done
+
+lint: ## Run all the linters
+ @if [ "$(LINTER)" = "" ]; then\
+ curl -L https://github.com/golangci/golangci-lint/releases/download/v$(LINTER_VERSION)/$(LINTER_FILE) $(LINTER_UNPACK) ;\
+ chmod +x $$GOPATH/bin/golangci-lint;\
+ fi
+
+ golangci-lint run
+
+ci: test_and_cover_report ## Run all the tests but no linters - use https://golangci.com integration instead
+
+build:
+ go build
+
+release: ## Release new version
+ git tag | grep -q $(VERSION) && echo This version was released! Increase VERSION! || git tag $(VERSION) && git push origin $(VERSION) && git tag v$(VERSION) && git push origin v$(VERSION)
+
+# Absolutely awesome: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
+help:
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+.DEFAULT_GOAL := build
diff --git a/vendor/github.com/avast/retry-go/v4/README.md b/vendor/github.com/avast/retry-go/v4/README.md
new file mode 100644
index 0000000..d423e8d
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/README.md
@@ -0,0 +1,494 @@
+# retry
+
+[](https://github.com/avast/retry-go/releases/latest)
+[](LICENSE.md)
+
+[](https://goreportcard.com/report/github.com/avast/retry-go)
+[](http://godoc.org/github.com/avast/retry-go)
+[](https://codecov.io/github/avast/retry-go?branch=master)
+[](https://sourcegraph.com/github.com/avast/retry-go?badge)
+
+Simple library for retry mechanism
+
+Slightly inspired by
+[Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry)
+
+# SYNOPSIS
+
+HTTP GET with retry:
+
+ url := "http://example.com"
+ var body []byte
+
+ err := retry.Do(
+ func() error {
+ resp, err := http.Get(url)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ body, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ return nil
+ },
+ )
+
+ if err != nil {
+ // handle error
+ }
+
+ fmt.Println(string(body))
+
+HTTP GET with retry with data:
+
+ url := "http://example.com"
+
+ body, err := retry.DoWithData(
+ func() ([]byte, error) {
+ resp, err := http.Get(url)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ return body, nil
+ },
+ )
+
+ if err != nil {
+ // handle error
+ }
+
+ fmt.Println(string(body))
+
+[More examples](https://github.com/avast/retry-go/tree/master/examples)
+
+# SEE ALSO
+
+* [giantswarm/retry-go](https://github.com/giantswarm/retry-go) - slightly
+complicated interface.
+
+* [sethgrid/pester](https://github.com/sethgrid/pester) - only http retry for
+http calls with retries and backoff
+
+* [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the
+exponential backoff algorithm from Google's HTTP Client Library for Java. Really
+complicated interface.
+
+* [rafaeljesus/retry-go](https://github.com/rafaeljesus/retry-go) - looks good,
+slightly similar as this package, don't have 'simple' `Retry` method
+
+* [matryer/try](https://github.com/matryer/try) - very popular package,
+nonintuitive interface (for me)
+
+# BREAKING CHANGES
+
+* 4.0.0
+
+ - infinity retry is possible by set `Attempts(0)` by PR [#49](https://github.com/avast/retry-go/pull/49)
+
+* 3.0.0
+
+ - `DelayTypeFunc` accepts a new parameter `err` - this breaking change affects only your custom Delay Functions. This change allow [make delay functions based on error](examples/delay_based_on_error_test.go).
+
+* 1.0.2 -> 2.0.0
+
+ - argument of `retry.Delay` is final delay (no multiplication by `retry.Units` anymore)
+ - function `retry.Units` are removed
+ - [more about this breaking change](https://github.com/avast/retry-go/issues/7)
+
+* 0.3.0 -> 1.0.0
+
+ - `retry.Retry` function are changed to `retry.Do` function
+ - `retry.RetryCustom` (OnRetry) and `retry.RetryCustomWithOpts` functions are now implement via functions produces Options (aka `retry.OnRetry`)
+
+## Usage
+
+#### func BackOffDelay
+
+```go
+func BackOffDelay(n uint, _ error, config *Config) time.Duration
+```
+BackOffDelay is a DelayType which increases delay between consecutive retries
+
+#### func Do
+
+```go
+func Do(retryableFunc RetryableFunc, opts ...Option) error
+```
+
+#### func DoWithData
+
+```go
+func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (T, error)
+```
+
+#### func FixedDelay
+
+```go
+func FixedDelay(_ uint, _ error, config *Config) time.Duration
+```
+FixedDelay is a DelayType which keeps delay the same through all iterations
+
+#### func IsRecoverable
+
+```go
+func IsRecoverable(err error) bool
+```
+IsRecoverable checks if error is an instance of `unrecoverableError`
+
+#### func RandomDelay
+
+```go
+func RandomDelay(_ uint, _ error, config *Config) time.Duration
+```
+RandomDelay is a DelayType which picks a random delay up to config.maxJitter
+
+#### func Unrecoverable
+
+```go
+func Unrecoverable(err error) error
+```
+Unrecoverable wraps an error in `unrecoverableError` struct
+
+#### type Config
+
+```go
+type Config struct {
+}
+```
+
+
+#### type DelayTypeFunc
+
+```go
+type DelayTypeFunc func(n uint, err error, config *Config) time.Duration
+```
+
+DelayTypeFunc is called to return the next delay to wait after the retriable
+function fails on `err` after `n` attempts.
+
+#### func CombineDelay
+
+```go
+func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc
+```
+CombineDelay is a DelayType the combines all of the specified delays into a new
+DelayTypeFunc
+
+#### type Error
+
+```go
+type Error []error
+```
+
+Error type represents list of errors in retry
+
+#### func (Error) As
+
+```go
+func (e Error) As(target interface{}) bool
+```
+
+#### func (Error) Error
+
+```go
+func (e Error) Error() string
+```
+Error method return string representation of Error It is an implementation of
+error interface
+
+#### func (Error) Is
+
+```go
+func (e Error) Is(target error) bool
+```
+
+#### func (Error) Unwrap
+
+```go
+func (e Error) Unwrap() error
+```
+Unwrap the last error for compatibility with `errors.Unwrap()`. When you need to
+unwrap all errors, you should use `WrappedErrors()` instead.
+
+ err := Do(
+ func() error {
+ return errors.New("original error")
+ },
+ Attempts(1),
+ )
+
+ fmt.Println(errors.Unwrap(err)) # "original error" is printed
+
+Added in version 4.2.0.
+
+#### func (Error) WrappedErrors
+
+```go
+func (e Error) WrappedErrors() []error
+```
+WrappedErrors returns the list of errors that this Error is wrapping. It is an
+implementation of the `errwrap.Wrapper` interface in package
+[errwrap](https://github.com/hashicorp/errwrap) so that `retry.Error` can be
+used with that library.
+
+#### type OnRetryFunc
+
+```go
+type OnRetryFunc func(attempt uint, err error)
+```
+
+Function signature of OnRetry function
+
+#### type Option
+
+```go
+type Option func(*Config)
+```
+
+Option represents an option for retry.
+
+#### func Attempts
+
+```go
+func Attempts(attempts uint) Option
+```
+Attempts set count of retry. Setting to 0 will retry until the retried function
+succeeds. default is 10
+
+#### func AttemptsForError
+
+```go
+func AttemptsForError(attempts uint, err error) Option
+```
+AttemptsForError sets count of retry in case execution results in given `err`
+Retries for the given `err` are also counted against total retries. The retry
+will stop if any of given retries is exhausted.
+
+added in 4.3.0
+
+#### func Context
+
+```go
+func Context(ctx context.Context) Option
+```
+Context allow to set context of retry default are Background context
+
+example of immediately cancellation (maybe it isn't the best example, but it
+describes behavior enough; I hope)
+
+ ctx, cancel := context.WithCancel(context.Background())
+ cancel()
+
+ retry.Do(
+ func() error {
+ ...
+ },
+ retry.Context(ctx),
+ )
+
+#### func Delay
+
+```go
+func Delay(delay time.Duration) Option
+```
+Delay set delay between retry default is 100ms
+
+#### func DelayType
+
+```go
+func DelayType(delayType DelayTypeFunc) Option
+```
+DelayType set type of the delay between retries default is BackOff
+
+#### func LastErrorOnly
+
+```go
+func LastErrorOnly(lastErrorOnly bool) Option
+```
+return the direct last error that came from the retried function default is
+false (return wrapped errors with everything)
+
+#### func MaxDelay
+
+```go
+func MaxDelay(maxDelay time.Duration) Option
+```
+MaxDelay set maximum delay between retry does not apply by default
+
+#### func MaxJitter
+
+```go
+func MaxJitter(maxJitter time.Duration) Option
+```
+MaxJitter sets the maximum random Jitter between retries for RandomDelay
+
+#### func OnRetry
+
+```go
+func OnRetry(onRetry OnRetryFunc) Option
+```
+OnRetry function callback are called each retry
+
+log each retry example:
+
+ retry.Do(
+ func() error {
+ return errors.New("some error")
+ },
+ retry.OnRetry(func(n uint, err error) {
+ log.Printf("#%d: %s\n", n, err)
+ }),
+ )
+
+#### func RetryIf
+
+```go
+func RetryIf(retryIf RetryIfFunc) Option
+```
+RetryIf controls whether a retry should be attempted after an error (assuming
+there are any retry attempts remaining)
+
+skip retry if special error example:
+
+ retry.Do(
+ func() error {
+ return errors.New("special error")
+ },
+ retry.RetryIf(func(err error) bool {
+ if err.Error() == "special error" {
+ return false
+ }
+ return true
+ })
+ )
+
+By default RetryIf stops execution if the error is wrapped using
+`retry.Unrecoverable`, so above example may also be shortened to:
+
+ retry.Do(
+ func() error {
+ return retry.Unrecoverable(errors.New("special error"))
+ }
+ )
+
+#### func UntilSucceeded
+
+```go
+func UntilSucceeded() Option
+```
+UntilSucceeded will retry until the retried function succeeds. Equivalent to
+setting Attempts(0).
+
+#### func WithTimer
+
+```go
+func WithTimer(t Timer) Option
+```
+WithTimer provides a way to swap out timer module implementations. This
+primarily is useful for mocking/testing, where you may not want to explicitly
+wait for a set duration for retries.
+
+example of augmenting time.After with a print statement
+
+ type struct MyTimer {}
+
+ func (t *MyTimer) After(d time.Duration) <- chan time.Time {
+ fmt.Print("Timer called!")
+ return time.After(d)
+ }
+
+ retry.Do(
+ func() error { ... },
+ retry.WithTimer(&MyTimer{})
+ )
+
+#### func WrapContextErrorWithLastError
+
+```go
+func WrapContextErrorWithLastError(wrapContextErrorWithLastError bool) Option
+```
+WrapContextErrorWithLastError allows the context error to be returned wrapped
+with the last error that the retried function returned. This is only applicable
+when Attempts is set to 0 to retry indefinitly and when using a context to
+cancel / timeout
+
+default is false
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ retry.Do(
+ func() error {
+ ...
+ },
+ retry.Context(ctx),
+ retry.Attempts(0),
+ retry.WrapContextErrorWithLastError(true),
+ )
+
+#### type RetryIfFunc
+
+```go
+type RetryIfFunc func(error) bool
+```
+
+Function signature of retry if function
+
+#### type RetryableFunc
+
+```go
+type RetryableFunc func() error
+```
+
+Function signature of retryable function
+
+#### type RetryableFuncWithData
+
+```go
+type RetryableFuncWithData[T any] func() (T, error)
+```
+
+Function signature of retryable function with data
+
+#### type Timer
+
+```go
+type Timer interface {
+ After(time.Duration) <-chan time.Time
+}
+```
+
+Timer represents the timer used to track time for a retry.
+
+## Contributing
+
+Contributions are very much welcome.
+
+### Makefile
+
+Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc...
+
+Try `make help` for more information.
+
+### Before pull request
+
+> maybe you need `make setup` in order to setup environment
+
+please try:
+* run tests (`make test`)
+* run linter (`make lint`)
+* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`)
+
+### README
+
+README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown).
+
+Never edit README.md direct, because your change will be lost.
diff --git a/vendor/github.com/avast/retry-go/v4/VERSION b/vendor/github.com/avast/retry-go/v4/VERSION
new file mode 100644
index 0000000..4404a17
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/VERSION
@@ -0,0 +1 @@
+4.5.1
diff --git a/vendor/github.com/avast/retry-go/v4/options.go b/vendor/github.com/avast/retry-go/v4/options.go
new file mode 100644
index 0000000..5577ee7
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/options.go
@@ -0,0 +1,280 @@
+package retry
+
+import (
+ "context"
+ "math"
+ "math/rand"
+ "time"
+)
+
+// Function signature of retry if function
+type RetryIfFunc func(error) bool
+
+// Function signature of OnRetry function
+type OnRetryFunc func(attempt uint, err error)
+
+// DelayTypeFunc is called to return the next delay to wait after the retriable function fails on `err` after `n` attempts.
+type DelayTypeFunc func(n uint, err error, config *Config) time.Duration
+
+// Timer represents the timer used to track time for a retry.
+type Timer interface {
+ After(time.Duration) <-chan time.Time
+}
+
+type Config struct {
+ attempts uint
+ attemptsForError map[error]uint
+ delay time.Duration
+ maxDelay time.Duration
+ maxJitter time.Duration
+ onRetry OnRetryFunc
+ retryIf RetryIfFunc
+ delayType DelayTypeFunc
+ lastErrorOnly bool
+ context context.Context
+ timer Timer
+ wrapContextErrorWithLastError bool
+
+ maxBackOffN uint
+}
+
+// Option represents an option for retry.
+type Option func(*Config)
+
+func emptyOption(c *Config) {}
+
+// return the direct last error that came from the retried function
+// default is false (return wrapped errors with everything)
+func LastErrorOnly(lastErrorOnly bool) Option {
+ return func(c *Config) {
+ c.lastErrorOnly = lastErrorOnly
+ }
+}
+
+// Attempts set count of retry. Setting to 0 will retry until the retried function succeeds.
+// default is 10
+func Attempts(attempts uint) Option {
+ return func(c *Config) {
+ c.attempts = attempts
+ }
+}
+
+// UntilSucceeded will retry until the retried function succeeds. Equivalent to setting Attempts(0).
+func UntilSucceeded() Option {
+ return func(c *Config) {
+ c.attempts = 0
+ }
+}
+
+// AttemptsForError sets count of retry in case execution results in given `err`
+// Retries for the given `err` are also counted against total retries.
+// The retry will stop if any of given retries is exhausted.
+//
+// added in 4.3.0
+func AttemptsForError(attempts uint, err error) Option {
+ return func(c *Config) {
+ c.attemptsForError[err] = attempts
+ }
+}
+
+// Delay set delay between retry
+// default is 100ms
+func Delay(delay time.Duration) Option {
+ return func(c *Config) {
+ c.delay = delay
+ }
+}
+
+// MaxDelay set maximum delay between retry
+// does not apply by default
+func MaxDelay(maxDelay time.Duration) Option {
+ return func(c *Config) {
+ c.maxDelay = maxDelay
+ }
+}
+
+// MaxJitter sets the maximum random Jitter between retries for RandomDelay
+func MaxJitter(maxJitter time.Duration) Option {
+ return func(c *Config) {
+ c.maxJitter = maxJitter
+ }
+}
+
+// DelayType set type of the delay between retries
+// default is BackOff
+func DelayType(delayType DelayTypeFunc) Option {
+ if delayType == nil {
+ return emptyOption
+ }
+ return func(c *Config) {
+ c.delayType = delayType
+ }
+}
+
+// BackOffDelay is a DelayType which increases delay between consecutive retries
+func BackOffDelay(n uint, _ error, config *Config) time.Duration {
+ // 1 << 63 would overflow signed int64 (time.Duration), thus 62.
+ const max uint = 62
+
+ if config.maxBackOffN == 0 {
+ if config.delay <= 0 {
+ config.delay = 1
+ }
+
+ config.maxBackOffN = max - uint(math.Floor(math.Log2(float64(config.delay))))
+ }
+
+ if n > config.maxBackOffN {
+ n = config.maxBackOffN
+ }
+
+ return config.delay << n
+}
+
+// FixedDelay is a DelayType which keeps delay the same through all iterations
+func FixedDelay(_ uint, _ error, config *Config) time.Duration {
+ return config.delay
+}
+
+// RandomDelay is a DelayType which picks a random delay up to config.maxJitter
+func RandomDelay(_ uint, _ error, config *Config) time.Duration {
+ return time.Duration(rand.Int63n(int64(config.maxJitter)))
+}
+
+// CombineDelay is a DelayType the combines all of the specified delays into a new DelayTypeFunc
+func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc {
+ const maxInt64 = uint64(math.MaxInt64)
+
+ return func(n uint, err error, config *Config) time.Duration {
+ var total uint64
+ for _, delay := range delays {
+ total += uint64(delay(n, err, config))
+ if total > maxInt64 {
+ total = maxInt64
+ }
+ }
+
+ return time.Duration(total)
+ }
+}
+
+// OnRetry function callback are called each retry
+//
+// log each retry example:
+//
+// retry.Do(
+// func() error {
+// return errors.New("some error")
+// },
+// retry.OnRetry(func(n uint, err error) {
+// log.Printf("#%d: %s\n", n, err)
+// }),
+// )
+func OnRetry(onRetry OnRetryFunc) Option {
+ if onRetry == nil {
+ return emptyOption
+ }
+ return func(c *Config) {
+ c.onRetry = onRetry
+ }
+}
+
+// RetryIf controls whether a retry should be attempted after an error
+// (assuming there are any retry attempts remaining)
+//
+// skip retry if special error example:
+//
+// retry.Do(
+// func() error {
+// return errors.New("special error")
+// },
+// retry.RetryIf(func(err error) bool {
+// if err.Error() == "special error" {
+// return false
+// }
+// return true
+// })
+// )
+//
+// By default RetryIf stops execution if the error is wrapped using `retry.Unrecoverable`,
+// so above example may also be shortened to:
+//
+// retry.Do(
+// func() error {
+// return retry.Unrecoverable(errors.New("special error"))
+// }
+// )
+func RetryIf(retryIf RetryIfFunc) Option {
+ if retryIf == nil {
+ return emptyOption
+ }
+ return func(c *Config) {
+ c.retryIf = retryIf
+ }
+}
+
+// Context allow to set context of retry
+// default are Background context
+//
+// example of immediately cancellation (maybe it isn't the best example, but it describes behavior enough; I hope)
+//
+// ctx, cancel := context.WithCancel(context.Background())
+// cancel()
+//
+// retry.Do(
+// func() error {
+// ...
+// },
+// retry.Context(ctx),
+// )
+func Context(ctx context.Context) Option {
+ return func(c *Config) {
+ c.context = ctx
+ }
+}
+
+// WithTimer provides a way to swap out timer module implementations.
+// This primarily is useful for mocking/testing, where you may not want to explicitly wait for a set duration
+// for retries.
+//
+// example of augmenting time.After with a print statement
+//
+// type struct MyTimer {}
+//
+// func (t *MyTimer) After(d time.Duration) <- chan time.Time {
+// fmt.Print("Timer called!")
+// return time.After(d)
+// }
+//
+// retry.Do(
+// func() error { ... },
+// retry.WithTimer(&MyTimer{})
+// )
+func WithTimer(t Timer) Option {
+ return func(c *Config) {
+ c.timer = t
+ }
+}
+
+// WrapContextErrorWithLastError allows the context error to be returned wrapped with the last error that the
+// retried function returned. This is only applicable when Attempts is set to 0 to retry indefinitly and when
+// using a context to cancel / timeout
+//
+// default is false
+//
+// ctx, cancel := context.WithCancel(context.Background())
+// defer cancel()
+//
+// retry.Do(
+// func() error {
+// ...
+// },
+// retry.Context(ctx),
+// retry.Attempts(0),
+// retry.WrapContextErrorWithLastError(true),
+// )
+func WrapContextErrorWithLastError(wrapContextErrorWithLastError bool) Option {
+ return func(c *Config) {
+ c.wrapContextErrorWithLastError = wrapContextErrorWithLastError
+ }
+}
diff --git a/vendor/github.com/avast/retry-go/v4/retry.go b/vendor/github.com/avast/retry-go/v4/retry.go
new file mode 100644
index 0000000..f739915
--- /dev/null
+++ b/vendor/github.com/avast/retry-go/v4/retry.go
@@ -0,0 +1,348 @@
+/*
+Simple library for retry mechanism
+
+Slightly inspired by [Try::Tiny::Retry](https://metacpan.org/pod/Try::Tiny::Retry)
+
+# SYNOPSIS
+
+HTTP GET with retry:
+
+ url := "http://example.com"
+ var body []byte
+
+ err := retry.Do(
+ func() error {
+ resp, err := http.Get(url)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ body, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ return nil
+ },
+ )
+
+ if err != nil {
+ // handle error
+ }
+
+ fmt.Println(string(body))
+
+HTTP GET with retry with data:
+
+ url := "http://example.com"
+
+ body, err := retry.DoWithData(
+ func() ([]byte, error) {
+ resp, err := http.Get(url)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ return body, nil
+ },
+ )
+
+ if err != nil {
+ // handle error
+ }
+
+ fmt.Println(string(body))
+
+[More examples](https://github.com/avast/retry-go/tree/master/examples)
+
+# SEE ALSO
+
+* [giantswarm/retry-go](https://github.com/giantswarm/retry-go) - slightly complicated interface.
+
+* [sethgrid/pester](https://github.com/sethgrid/pester) - only http retry for http calls with retries and backoff
+
+* [cenkalti/backoff](https://github.com/cenkalti/backoff) - Go port of the exponential backoff algorithm from Google's HTTP Client Library for Java. Really complicated interface.
+
+* [rafaeljesus/retry-go](https://github.com/rafaeljesus/retry-go) - looks good, slightly similar as this package, don't have 'simple' `Retry` method
+
+* [matryer/try](https://github.com/matryer/try) - very popular package, nonintuitive interface (for me)
+
+# BREAKING CHANGES
+
+* 4.0.0
+ - infinity retry is possible by set `Attempts(0)` by PR [#49](https://github.com/avast/retry-go/pull/49)
+
+* 3.0.0
+ - `DelayTypeFunc` accepts a new parameter `err` - this breaking change affects only your custom Delay Functions. This change allow [make delay functions based on error](examples/delay_based_on_error_test.go).
+
+* 1.0.2 -> 2.0.0
+ - argument of `retry.Delay` is final delay (no multiplication by `retry.Units` anymore)
+ - function `retry.Units` are removed
+ - [more about this breaking change](https://github.com/avast/retry-go/issues/7)
+
+* 0.3.0 -> 1.0.0
+ - `retry.Retry` function are changed to `retry.Do` function
+ - `retry.RetryCustom` (OnRetry) and `retry.RetryCustomWithOpts` functions are now implement via functions produces Options (aka `retry.OnRetry`)
+*/
+package retry
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+)
+
+// Function signature of retryable function
+type RetryableFunc func() error
+
+// Function signature of retryable function with data
+type RetryableFuncWithData[T any] func() (T, error)
+
+// Default timer is a wrapper around time.After
+type timerImpl struct{}
+
+func (t *timerImpl) After(d time.Duration) <-chan time.Time {
+ return time.After(d)
+}
+
+func Do(retryableFunc RetryableFunc, opts ...Option) error {
+ retryableFuncWithData := func() (any, error) {
+ return nil, retryableFunc()
+ }
+
+ _, err := DoWithData(retryableFuncWithData, opts...)
+ return err
+}
+
+func DoWithData[T any](retryableFunc RetryableFuncWithData[T], opts ...Option) (T, error) {
+ var n uint
+ var emptyT T
+
+ // default
+ config := newDefaultRetryConfig()
+
+ // apply opts
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if err := config.context.Err(); err != nil {
+ return emptyT, err
+ }
+
+ // Setting attempts to 0 means we'll retry until we succeed
+ var lastErr error
+ if config.attempts == 0 {
+ for {
+ t, err := retryableFunc()
+ if err == nil {
+ return t, nil
+ }
+
+ if !IsRecoverable(err) {
+ return emptyT, err
+ }
+
+ if !config.retryIf(err) {
+ return emptyT, err
+ }
+
+ lastErr = err
+
+ config.onRetry(n, err)
+ n++
+ select {
+ case <-config.timer.After(delay(config, n, err)):
+ case <-config.context.Done():
+ if config.wrapContextErrorWithLastError {
+ return emptyT, Error{config.context.Err(), lastErr}
+ }
+ return emptyT, config.context.Err()
+ }
+ }
+ }
+
+ errorLog := Error{}
+
+ attemptsForError := make(map[error]uint, len(config.attemptsForError))
+ for err, attempts := range config.attemptsForError {
+ attemptsForError[err] = attempts
+ }
+
+ shouldRetry := true
+ for shouldRetry {
+ t, err := retryableFunc()
+ if err == nil {
+ return t, nil
+ }
+
+ errorLog = append(errorLog, unpackUnrecoverable(err))
+
+ if !config.retryIf(err) {
+ break
+ }
+
+ config.onRetry(n, err)
+
+ for errToCheck, attempts := range attemptsForError {
+ if errors.Is(err, errToCheck) {
+ attempts--
+ attemptsForError[errToCheck] = attempts
+ shouldRetry = shouldRetry && attempts > 0
+ }
+ }
+
+ // if this is last attempt - don't wait
+ if n == config.attempts-1 {
+ break
+ }
+
+ select {
+ case <-config.timer.After(delay(config, n, err)):
+ case <-config.context.Done():
+ if config.lastErrorOnly {
+ return emptyT, config.context.Err()
+ }
+
+ return emptyT, append(errorLog, config.context.Err())
+ }
+
+ n++
+ shouldRetry = shouldRetry && n < config.attempts
+ }
+
+ if config.lastErrorOnly {
+ return emptyT, errorLog.Unwrap()
+ }
+ return emptyT, errorLog
+}
+
+func newDefaultRetryConfig() *Config {
+ return &Config{
+ attempts: uint(10),
+ attemptsForError: make(map[error]uint),
+ delay: 100 * time.Millisecond,
+ maxJitter: 100 * time.Millisecond,
+ onRetry: func(n uint, err error) {},
+ retryIf: IsRecoverable,
+ delayType: CombineDelay(BackOffDelay, RandomDelay),
+ lastErrorOnly: false,
+ context: context.Background(),
+ timer: &timerImpl{},
+ }
+}
+
+// Error type represents list of errors in retry
+type Error []error
+
+// Error method return string representation of Error
+// It is an implementation of error interface
+func (e Error) Error() string {
+ logWithNumber := make([]string, len(e))
+ for i, l := range e {
+ if l != nil {
+ logWithNumber[i] = fmt.Sprintf("#%d: %s", i+1, l.Error())
+ }
+ }
+
+ return fmt.Sprintf("All attempts fail:\n%s", strings.Join(logWithNumber, "\n"))
+}
+
+func (e Error) Is(target error) bool {
+ for _, v := range e {
+ if errors.Is(v, target) {
+ return true
+ }
+ }
+ return false
+}
+
+func (e Error) As(target interface{}) bool {
+ for _, v := range e {
+ if errors.As(v, target) {
+ return true
+ }
+ }
+ return false
+}
+
+/*
+Unwrap the last error for compatibility with `errors.Unwrap()`.
+When you need to unwrap all errors, you should use `WrappedErrors()` instead.
+
+ err := Do(
+ func() error {
+ return errors.New("original error")
+ },
+ Attempts(1),
+ )
+
+ fmt.Println(errors.Unwrap(err)) # "original error" is printed
+
+Added in version 4.2.0.
+*/
+func (e Error) Unwrap() error {
+ return e[len(e)-1]
+}
+
+// WrappedErrors returns the list of errors that this Error is wrapping.
+// It is an implementation of the `errwrap.Wrapper` interface
+// in package [errwrap](https://github.com/hashicorp/errwrap) so that
+// `retry.Error` can be used with that library.
+func (e Error) WrappedErrors() []error {
+ return e
+}
+
+type unrecoverableError struct {
+ error
+}
+
+func (e unrecoverableError) Error() string {
+ if e.error == nil {
+ return "unrecoverable error"
+ }
+ return e.error.Error()
+}
+
+func (e unrecoverableError) Unwrap() error {
+ return e.error
+}
+
+// Unrecoverable wraps an error in `unrecoverableError` struct
+func Unrecoverable(err error) error {
+ return unrecoverableError{err}
+}
+
+// IsRecoverable checks if error is an instance of `unrecoverableError`
+func IsRecoverable(err error) bool {
+ return !errors.Is(err, unrecoverableError{})
+}
+
+// Adds support for errors.Is usage on unrecoverableError
+func (unrecoverableError) Is(err error) bool {
+ _, isUnrecoverable := err.(unrecoverableError)
+ return isUnrecoverable
+}
+
+func unpackUnrecoverable(err error) error {
+ if unrecoverable, isUnrecoverable := err.(unrecoverableError); isUnrecoverable {
+ return unrecoverable.error
+ }
+
+ return err
+}
+
+func delay(config *Config, n uint, err error) time.Duration {
+ delayTime := config.delayType(n, err, config)
+ if config.maxDelay > 0 && delayTime > config.maxDelay {
+ delayTime = config.maxDelay
+ }
+
+ return delayTime
+}
diff --git a/vendor/github.com/cloudflare/circl/LICENSE b/vendor/github.com/cloudflare/circl/LICENSE
new file mode 100644
index 0000000..67edaa9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/LICENSE
@@ -0,0 +1,57 @@
+Copyright (c) 2019 Cloudflare. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Cloudflare nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================
+
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve.go
new file mode 100644
index 0000000..f9057c2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve.go
@@ -0,0 +1,96 @@
+package x25519
+
+import (
+ fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+// ladderJoye calculates a fixed-point multiplication with the generator point.
+// The algorithm is the right-to-left Joye's ladder as described
+// in "How to precompute a ladder" in SAC'2017.
+func ladderJoye(k *Key) {
+ w := [5]fp.Elt{} // [mu,x1,z1,x2,z2] order must be preserved.
+ fp.SetOne(&w[1]) // x1 = 1
+ fp.SetOne(&w[2]) // z1 = 1
+ w[3] = fp.Elt{ // x2 = G-S
+ 0xbd, 0xaa, 0x2f, 0xc8, 0xfe, 0xe1, 0x94, 0x7e,
+ 0xf8, 0xed, 0xb2, 0x14, 0xae, 0x95, 0xf0, 0xbb,
+ 0xe2, 0x48, 0x5d, 0x23, 0xb9, 0xa0, 0xc7, 0xad,
+ 0x34, 0xab, 0x7c, 0xe2, 0xee, 0xcd, 0xae, 0x1e,
+ }
+ fp.SetOne(&w[4]) // z2 = 1
+
+ const n = 255
+ const h = 3
+ swap := uint(1)
+ for s := 0; s < n-h; s++ {
+ i := (s + h) / 8
+ j := (s + h) % 8
+ bit := uint((k[i] >> uint(j)) & 1)
+ copy(w[0][:], tableGenerator[s*Size:(s+1)*Size])
+ diffAdd(&w, swap^bit)
+ swap = bit
+ }
+ for s := 0; s < h; s++ {
+ double(&w[1], &w[2])
+ }
+ toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+// ladderMontgomery calculates a generic scalar point multiplication
+// The algorithm implemented is the left-to-right Montgomery's ladder.
+func ladderMontgomery(k, xP *Key) {
+ w := [5]fp.Elt{} // [x1, x2, z2, x3, z3] order must be preserved.
+ w[0] = *(*fp.Elt)(xP) // x1 = xP
+ fp.SetOne(&w[1]) // x2 = 1
+ w[3] = *(*fp.Elt)(xP) // x3 = xP
+ fp.SetOne(&w[4]) // z3 = 1
+
+ move := uint(0)
+ for s := 255 - 1; s >= 0; s-- {
+ i := s / 8
+ j := s % 8
+ bit := uint((k[i] >> uint(j)) & 1)
+ ladderStep(&w, move^bit)
+ move = bit
+ }
+ toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+func toAffine(k *[fp.Size]byte, x, z *fp.Elt) {
+ fp.Inv(z, z)
+ fp.Mul(x, x, z)
+ _ = fp.ToBytes(k[:], x)
+}
+
+var lowOrderPoints = [5]fp.Elt{
+ { /* (0,_,1) point of order 2 on Curve25519 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* (1,_,1) point of order 4 on Curve25519 */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* (x,_,1) first point of order 8 on Curve25519 */
+ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
+ 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
+ 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
+ 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00,
+ },
+ { /* (x,_,1) second point of order 8 on Curve25519 */
+ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
+ 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
+ 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
+ 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57,
+ },
+ { /* (-1,_,1) a point of order 4 on the twist of Curve25519 */
+ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ },
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go
new file mode 100644
index 0000000..8a3d54c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go
@@ -0,0 +1,30 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package x25519
+
+import (
+ fp "github.com/cloudflare/circl/math/fp25519"
+ "golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func double(x, z *fp.Elt) { doubleAmd64(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint) { diffAddAmd64(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepAmd64(w, b) }
+func mulA24(z, x *fp.Elt) { mulA24Amd64(z, x) }
+
+//go:noescape
+func ladderStepAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func diffAddAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func doubleAmd64(x, z *fp.Elt)
+
+//go:noescape
+func mulA24Amd64(z, x *fp.Elt)
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h
new file mode 100644
index 0000000..8c1ae4d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h
@@ -0,0 +1,111 @@
+#define ladderStepLeg \
+ addSub(x2,z2) \
+ addSub(x3,z3) \
+ integerMulLeg(b0,x2,z3) \
+ integerMulLeg(b1,x3,z2) \
+ reduceFromDoubleLeg(t0,b0) \
+ reduceFromDoubleLeg(t1,b1) \
+ addSub(t0,t1) \
+ cselect(x2,x3,regMove) \
+ cselect(z2,z3,regMove) \
+ integerSqrLeg(b0,t0) \
+ integerSqrLeg(b1,t1) \
+ reduceFromDoubleLeg(x3,b0) \
+ reduceFromDoubleLeg(z3,b1) \
+ integerMulLeg(b0,x1,z3) \
+ reduceFromDoubleLeg(z3,b0) \
+ integerSqrLeg(b0,x2) \
+ integerSqrLeg(b1,z2) \
+ reduceFromDoubleLeg(x2,b0) \
+ reduceFromDoubleLeg(z2,b1) \
+ subtraction(t0,x2,z2) \
+ multiplyA24Leg(t1,t0) \
+ additionLeg(t1,t1,z2) \
+ integerMulLeg(b0,x2,z2) \
+ integerMulLeg(b1,t0,t1) \
+ reduceFromDoubleLeg(x2,b0) \
+ reduceFromDoubleLeg(z2,b1)
+
+#define ladderStepBmi2Adx \
+ addSub(x2,z2) \
+ addSub(x3,z3) \
+ integerMulAdx(b0,x2,z3) \
+ integerMulAdx(b1,x3,z2) \
+ reduceFromDoubleAdx(t0,b0) \
+ reduceFromDoubleAdx(t1,b1) \
+ addSub(t0,t1) \
+ cselect(x2,x3,regMove) \
+ cselect(z2,z3,regMove) \
+ integerSqrAdx(b0,t0) \
+ integerSqrAdx(b1,t1) \
+ reduceFromDoubleAdx(x3,b0) \
+ reduceFromDoubleAdx(z3,b1) \
+ integerMulAdx(b0,x1,z3) \
+ reduceFromDoubleAdx(z3,b0) \
+ integerSqrAdx(b0,x2) \
+ integerSqrAdx(b1,z2) \
+ reduceFromDoubleAdx(x2,b0) \
+ reduceFromDoubleAdx(z2,b1) \
+ subtraction(t0,x2,z2) \
+ multiplyA24Adx(t1,t0) \
+ additionAdx(t1,t1,z2) \
+ integerMulAdx(b0,x2,z2) \
+ integerMulAdx(b1,t0,t1) \
+ reduceFromDoubleAdx(x2,b0) \
+ reduceFromDoubleAdx(z2,b1)
+
+#define difAddLeg \
+ addSub(x1,z1) \
+ integerMulLeg(b0,z1,ui) \
+ reduceFromDoubleLeg(z1,b0) \
+ addSub(x1,z1) \
+ integerSqrLeg(b0,x1) \
+ integerSqrLeg(b1,z1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1) \
+ integerMulLeg(b0,x1,z2) \
+ integerMulLeg(b1,z1,x2) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1)
+
+#define difAddBmi2Adx \
+ addSub(x1,z1) \
+ integerMulAdx(b0,z1,ui) \
+ reduceFromDoubleAdx(z1,b0) \
+ addSub(x1,z1) \
+ integerSqrAdx(b0,x1) \
+ integerSqrAdx(b1,z1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1) \
+ integerMulAdx(b0,x1,z2) \
+ integerMulAdx(b1,z1,x2) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1)
+
+#define doubleLeg \
+ addSub(x1,z1) \
+ integerSqrLeg(b0,x1) \
+ integerSqrLeg(b1,z1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1) \
+ subtraction(t0,x1,z1) \
+ multiplyA24Leg(t1,t0) \
+ additionLeg(t1,t1,z1) \
+ integerMulLeg(b0,x1,z1) \
+ integerMulLeg(b1,t0,t1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1)
+
+#define doubleBmi2Adx \
+ addSub(x1,z1) \
+ integerSqrAdx(b0,x1) \
+ integerSqrAdx(b1,z1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1) \
+ subtraction(t0,x1,z1) \
+ multiplyA24Adx(t1,t0) \
+ additionAdx(t1,t1,z1) \
+ integerMulAdx(b0,x1,z1) \
+ integerMulAdx(b1,t0,t1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1)
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
new file mode 100644
index 0000000..ce9f062
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
@@ -0,0 +1,157 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+
+// Depends on circl/math/fp25519 package
+#include "../../math/fp25519/fp_amd64.h"
+#include "curve_amd64.h"
+
+// CTE_A24 is (A+2)/4 from Curve25519
+#define CTE_A24 121666
+
+#define Size 32
+
+// multiplyA24Leg multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R13, FLAGS
+// Instr: x86_64, cmov
+#define multiplyA24Leg(z,x) \
+ MOVL $CTE_A24, AX; MULQ 0+x; MOVQ AX, R8; MOVQ DX, R9; \
+ MOVL $CTE_A24, AX; MULQ 8+x; MOVQ AX, R12; MOVQ DX, R10; \
+ MOVL $CTE_A24, AX; MULQ 16+x; MOVQ AX, R13; MOVQ DX, R11; \
+ MOVL $CTE_A24, AX; MULQ 24+x; \
+ ADDQ R12, R9; \
+ ADCQ R13, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, DX; \
+ MOVL $38, AX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
+ IMULQ AX, DX; \
+ ADDQ DX, R8; \
+ ADCQ $0, R9; MOVQ R9, 8+z; \
+ ADCQ $0, R10; MOVQ R10, 16+z; \
+ ADCQ $0, R11; MOVQ R11, 24+z; \
+ MOVQ $0, DX; \
+ CMOVQCS AX, DX; \
+ ADDQ DX, R8; MOVQ R8, 0+z;
+
+// multiplyA24Adx multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R12, FLAGS
+// Instr: x86_64, cmov, bmi2
+#define multiplyA24Adx(z,x) \
+ MOVQ $CTE_A24, DX; \
+ MULXQ 0+x, R8, R10; \
+ MULXQ 8+x, R9, R11; ADDQ R10, R9; \
+ MULXQ 16+x, R10, AX; ADCQ R11, R10; \
+ MULXQ 24+x, R11, R12; ADCQ AX, R11; \
+ ;;;;;;;;;;;;;;;;;;;;; ADCQ $0, R12; \
+ MOVL $38, DX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
+ IMULQ DX, R12; \
+ ADDQ R12, R8; \
+ ADCQ $0, R9; MOVQ R9, 8+z; \
+ ADCQ $0, R10; MOVQ R10, 16+z; \
+ ADCQ $0, R11; MOVQ R11, 24+z; \
+ MOVQ $0, R12; \
+ CMOVQCS DX, R12; \
+ ADDQ R12, R8; MOVQ R8, 0+z;
+
+#define mulA24Legacy \
+ multiplyA24Leg(0(DI),0(SI))
+#define mulA24Bmi2Adx \
+ multiplyA24Adx(0(DI),0(SI))
+
+// func mulA24Amd64(z, x *fp255.Elt)
+TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
+
+
+// func ladderStepAmd64(w *[5]fp255.Elt, b uint)
+// ladderStepAmd64 calculates a point addition and doubling as follows:
+// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
+// work = (x1,x2,z2,x3,z3) are five fp255.Elt of 32 bytes.
+// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·ladderStepAmd64(SB),NOSPLIT,$192-16
+ // Parameters
+ #define regWork DI
+ #define regMove SI
+ #define x1 0*Size(regWork)
+ #define x2 1*Size(regWork)
+ #define z2 2*Size(regWork)
+ #define x3 3*Size(regWork)
+ #define z3 4*Size(regWork)
+ // Local variables
+ #define t0 0*Size(SP)
+ #define t1 1*Size(SP)
+ #define b0 2*Size(SP)
+ #define b1 4*Size(SP)
+ MOVQ w+0(FP), regWork
+ MOVQ b+8(FP), regMove
+ CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
+ #undef regWork
+ #undef regMove
+ #undef x1
+ #undef x2
+ #undef z2
+ #undef x3
+ #undef z3
+ #undef t0
+ #undef t1
+ #undef b0
+ #undef b1
+
+// func diffAddAmd64(w *[5]fp255.Elt, b uint)
+// diffAddAmd64 calculates a differential point addition using a precomputed point.
+// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
+// w = (mu,x1,z1,x2,z2) are five fp.Elt, and
+// stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·diffAddAmd64(SB),NOSPLIT,$128-16
+ // Parameters
+ #define regWork DI
+ #define regSwap SI
+ #define ui 0*Size(regWork)
+ #define x1 1*Size(regWork)
+ #define z1 2*Size(regWork)
+ #define x2 3*Size(regWork)
+ #define z2 4*Size(regWork)
+ // Local variables
+ #define b0 0*Size(SP)
+ #define b1 2*Size(SP)
+ MOVQ w+0(FP), regWork
+ MOVQ b+8(FP), regSwap
+ cswap(x1,x2,regSwap)
+ cswap(z1,z2,regSwap)
+ CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
+ #undef regWork
+ #undef regSwap
+ #undef ui
+ #undef x1
+ #undef z1
+ #undef x2
+ #undef z2
+ #undef b0
+ #undef b1
+
+// func doubleAmd64(x, z *fp255.Elt)
+// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
+// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·doubleAmd64(SB),NOSPLIT,$192-16
+ // Parameters
+ #define x1 0(DI)
+ #define z1 0(SI)
+ // Local variables
+ #define t0 0*Size(SP)
+ #define t1 1*Size(SP)
+ #define b0 2*Size(SP)
+ #define b1 4*Size(SP)
+ MOVQ x+0(FP), DI
+ MOVQ z+8(FP), SI
+ CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
+ #undef x1
+ #undef z1
+ #undef t0
+ #undef t1
+ #undef b0
+ #undef b1
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go
new file mode 100644
index 0000000..dae67ea
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go
@@ -0,0 +1,85 @@
+package x25519
+
+import (
+ "encoding/binary"
+ "math/bits"
+
+ fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+func doubleGeneric(x, z *fp.Elt) {
+ t0, t1 := &fp.Elt{}, &fp.Elt{}
+ fp.AddSub(x, z)
+ fp.Sqr(x, x)
+ fp.Sqr(z, z)
+ fp.Sub(t0, x, z)
+ mulA24Generic(t1, t0)
+ fp.Add(t1, t1, z)
+ fp.Mul(x, x, z)
+ fp.Mul(z, t0, t1)
+}
+
+func diffAddGeneric(w *[5]fp.Elt, b uint) {
+ mu, x1, z1, x2, z2 := &w[0], &w[1], &w[2], &w[3], &w[4]
+ fp.Cswap(x1, x2, b)
+ fp.Cswap(z1, z2, b)
+ fp.AddSub(x1, z1)
+ fp.Mul(z1, z1, mu)
+ fp.AddSub(x1, z1)
+ fp.Sqr(x1, x1)
+ fp.Sqr(z1, z1)
+ fp.Mul(x1, x1, z2)
+ fp.Mul(z1, z1, x2)
+}
+
+func ladderStepGeneric(w *[5]fp.Elt, b uint) {
+ x1, x2, z2, x3, z3 := &w[0], &w[1], &w[2], &w[3], &w[4]
+ t0 := &fp.Elt{}
+ t1 := &fp.Elt{}
+ fp.AddSub(x2, z2)
+ fp.AddSub(x3, z3)
+ fp.Mul(t0, x2, z3)
+ fp.Mul(t1, x3, z2)
+ fp.AddSub(t0, t1)
+ fp.Cmov(x2, x3, b)
+ fp.Cmov(z2, z3, b)
+ fp.Sqr(x3, t0)
+ fp.Sqr(z3, t1)
+ fp.Mul(z3, x1, z3)
+ fp.Sqr(x2, x2)
+ fp.Sqr(z2, z2)
+ fp.Sub(t0, x2, z2)
+ mulA24Generic(t1, t0)
+ fp.Add(t1, t1, z2)
+ fp.Mul(x2, x2, z2)
+ fp.Mul(z2, t0, t1)
+}
+
+func mulA24Generic(z, x *fp.Elt) {
+ const A24 = 121666
+ const n = 8
+ var xx [4]uint64
+ for i := range xx {
+ xx[i] = binary.LittleEndian.Uint64(x[i*n : (i+1)*n])
+ }
+
+ h0, l0 := bits.Mul64(xx[0], A24)
+ h1, l1 := bits.Mul64(xx[1], A24)
+ h2, l2 := bits.Mul64(xx[2], A24)
+ h3, l3 := bits.Mul64(xx[3], A24)
+
+ var c3 uint64
+ l1, c0 := bits.Add64(h0, l1, 0)
+ l2, c1 := bits.Add64(h1, l2, c0)
+ l3, c2 := bits.Add64(h2, l3, c1)
+ l4, _ := bits.Add64(h3, 0, c2)
+ _, l4 = bits.Mul64(l4, 38)
+ l0, c0 = bits.Add64(l0, l4, 0)
+ xx[1], c1 = bits.Add64(l1, 0, c0)
+ xx[2], c2 = bits.Add64(l2, 0, c1)
+ xx[3], c3 = bits.Add64(l3, 0, c2)
+ xx[0], _ = bits.Add64(l0, (-c3)&38, 0)
+ for i := range xx {
+ binary.LittleEndian.PutUint64(z[i*n:(i+1)*n], xx[i])
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go
new file mode 100644
index 0000000..07fab97
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go
@@ -0,0 +1,11 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package x25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+func double(x, z *fp.Elt) { doubleGeneric(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint) { diffAddGeneric(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepGeneric(w, b) }
+func mulA24(z, x *fp.Elt) { mulA24Generic(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/doc.go b/vendor/github.com/cloudflare/circl/dh/x25519/doc.go
new file mode 100644
index 0000000..3ce102d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/doc.go
@@ -0,0 +1,19 @@
+/*
+Package x25519 provides Diffie-Hellman functions as specified in RFC-7748.
+
+Validation of public keys.
+
+The Diffie-Hellman function, as described in RFC-7748 [1], works for any
+public key. However, if a different protocol requires contributory
+behaviour [2,3], then the public keys must be validated against low-order
+points [3,4]. To do that, the Shared function performs this validation
+internally and returns false when the public key is invalid (i.e., it
+is a low-order point).
+
+References:
+ - [1] RFC7748 by Langley, Hamburg, Turner (https://rfc-editor.org/rfc/rfc7748.txt)
+ - [2] Curve25519 by Bernstein (https://cr.yp.to/ecdh.html)
+ - [3] Bernstein (https://cr.yp.to/ecdh.html#validate)
+ - [4] Cremers&Jackson (https://eprint.iacr.org/2019/526)
+*/
+package x25519
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/key.go b/vendor/github.com/cloudflare/circl/dh/x25519/key.go
new file mode 100644
index 0000000..c76f72a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/key.go
@@ -0,0 +1,47 @@
+package x25519
+
+import (
+ "crypto/subtle"
+
+ fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+// Size is the length in bytes of a X25519 key.
+const Size = 32
+
+// Key represents a X25519 key.
+type Key [Size]byte
+
+func (k *Key) clamp(in *Key) *Key {
+ *k = *in
+ k[0] &= 248
+ k[31] = (k[31] & 127) | 64
+ return k
+}
+
+// isValidPubKey verifies if the public key is not a low-order point.
+func (k *Key) isValidPubKey() bool {
+ fp.Modp((*fp.Elt)(k))
+ var isLowOrder int
+ for _, P := range lowOrderPoints {
+ isLowOrder |= subtle.ConstantTimeCompare(P[:], k[:])
+ }
+ return isLowOrder == 0
+}
+
+// KeyGen obtains a public key given a secret key.
+func KeyGen(public, secret *Key) {
+ ladderJoye(public.clamp(secret))
+}
+
+// Shared calculates Alice's shared key from Alice's secret key and Bob's
+// public key returning true on success. A failure case happens when the public
+// key is a low-order point, thus the shared key is all-zeros and the function
+// returns false.
+func Shared(shared, secret, public *Key) bool {
+ validPk := *public
+ validPk[31] &= (1 << (255 % 8)) - 1
+ ok := validPk.isValidPubKey()
+ ladderMontgomery(shared.clamp(secret), &validPk)
+ return ok
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/table.go b/vendor/github.com/cloudflare/circl/dh/x25519/table.go
new file mode 100644
index 0000000..28c8c4a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/table.go
@@ -0,0 +1,268 @@
+package x25519
+
+import "github.com/cloudflare/circl/math/fp25519"
+
+// tableGenerator contains the set of points:
+//
+// t[i] = (xi+1)/(xi-1),
+//
+// where (xi,yi) = 2^iG and G is the generator point
+// Size = (256)*(256/8) = 8192 bytes.
+var tableGenerator = [256 * fp25519.Size]byte{
+ /* (2^ 0)P */ 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f,
+ /* (2^ 1)P */ 0x96, 0xfe, 0xaa, 0x16, 0xf4, 0x20, 0x82, 0x6b, 0x34, 0x6a, 0x56, 0x4f, 0x2b, 0xeb, 0xeb, 0x82, 0x0f, 0x95, 0xa5, 0x75, 0xb0, 0xa5, 0xa9, 0xd5, 0xf4, 0x88, 0x24, 0x4b, 0xcf, 0xb2, 0x42, 0x51,
+ /* (2^ 2)P */ 0x0c, 0x68, 0x69, 0x00, 0x75, 0xbc, 0xae, 0x6a, 0x41, 0x9c, 0xf9, 0xa0, 0x20, 0x78, 0xcf, 0x89, 0xf4, 0xd0, 0x56, 0x3b, 0x18, 0xd9, 0x58, 0x2a, 0xa4, 0x11, 0x60, 0xe3, 0x80, 0xca, 0x5a, 0x4b,
+ /* (2^ 3)P */ 0x5d, 0x74, 0x29, 0x8c, 0x34, 0x32, 0x91, 0x32, 0xd7, 0x2f, 0x64, 0xe1, 0x16, 0xe6, 0xa2, 0xf4, 0x34, 0xbc, 0x67, 0xff, 0x03, 0xbb, 0x45, 0x1e, 0x4a, 0x9b, 0x2a, 0xf4, 0xd0, 0x12, 0x69, 0x30,
+ /* (2^ 4)P */ 0x54, 0x71, 0xaf, 0xe6, 0x07, 0x65, 0x88, 0xff, 0x2f, 0xc8, 0xee, 0xdf, 0x13, 0x0e, 0xf5, 0x04, 0xce, 0xb5, 0xba, 0x2a, 0xe8, 0x2f, 0x51, 0xaa, 0x22, 0xf2, 0xd5, 0x68, 0x1a, 0x25, 0x4e, 0x17,
+ /* (2^ 5)P */ 0x98, 0x88, 0x02, 0x82, 0x0d, 0x70, 0x96, 0xcf, 0xc5, 0x02, 0x2c, 0x0a, 0x37, 0xe3, 0x43, 0x17, 0xaa, 0x6e, 0xe8, 0xb4, 0x98, 0xec, 0x9e, 0x37, 0x2e, 0x48, 0xe0, 0x51, 0x8a, 0x88, 0x59, 0x0c,
+ /* (2^ 6)P */ 0x89, 0xd1, 0xb5, 0x99, 0xd6, 0xf1, 0xcb, 0xfb, 0x84, 0xdc, 0x9f, 0x8e, 0xd5, 0xf0, 0xae, 0xac, 0x14, 0x76, 0x1f, 0x23, 0x06, 0x0d, 0xc2, 0xc1, 0x72, 0xf9, 0x74, 0xa2, 0x8d, 0x21, 0x38, 0x29,
+ /* (2^ 7)P */ 0x18, 0x7f, 0x1d, 0xff, 0xbe, 0x49, 0xaf, 0xf6, 0xc2, 0xc9, 0x7a, 0x38, 0x22, 0x1c, 0x54, 0xcc, 0x6b, 0xc5, 0x15, 0x40, 0xef, 0xc9, 0xfc, 0x96, 0xa9, 0x13, 0x09, 0x69, 0x7c, 0x62, 0xc1, 0x69,
+ /* (2^ 8)P */ 0x0e, 0xdb, 0x33, 0x47, 0x2f, 0xfd, 0x86, 0x7a, 0xe9, 0x7d, 0x08, 0x9e, 0xf2, 0xc4, 0xb8, 0xfd, 0x29, 0xa2, 0xa2, 0x8e, 0x1a, 0x4b, 0x5e, 0x09, 0x79, 0x7a, 0xb3, 0x29, 0xc8, 0xa7, 0xd7, 0x1a,
+ /* (2^ 9)P */ 0xc0, 0xa0, 0x7e, 0xd1, 0xca, 0x89, 0x2d, 0x34, 0x51, 0x20, 0xed, 0xcc, 0xa6, 0xdd, 0xbe, 0x67, 0x74, 0x2f, 0xb4, 0x2b, 0xbf, 0x31, 0xca, 0x19, 0xbb, 0xac, 0x80, 0x49, 0xc8, 0xb4, 0xf7, 0x3d,
+ /* (2^ 10)P */ 0x83, 0xd8, 0x0a, 0xc8, 0x4d, 0x44, 0xc6, 0xa8, 0x85, 0xab, 0xe3, 0x66, 0x03, 0x44, 0x1e, 0xb9, 0xd8, 0xf6, 0x64, 0x01, 0xa0, 0xcd, 0x15, 0xc2, 0x68, 0xe6, 0x47, 0xf2, 0x6e, 0x7c, 0x86, 0x3d,
+ /* (2^ 11)P */ 0x8c, 0x65, 0x3e, 0xcc, 0x2b, 0x58, 0xdd, 0xc7, 0x28, 0x55, 0x0e, 0xee, 0x48, 0x47, 0x2c, 0xfd, 0x71, 0x4f, 0x9f, 0xcc, 0x95, 0x9b, 0xfd, 0xa0, 0xdf, 0x5d, 0x67, 0xb0, 0x71, 0xd8, 0x29, 0x75,
+ /* (2^ 12)P */ 0x78, 0xbd, 0x3c, 0x2d, 0xb4, 0x68, 0xf5, 0xb8, 0x82, 0xda, 0xf3, 0x91, 0x1b, 0x01, 0x33, 0x12, 0x62, 0x3b, 0x7c, 0x4a, 0xcd, 0x6c, 0xce, 0x2d, 0x03, 0x86, 0x49, 0x9e, 0x8e, 0xfc, 0xe7, 0x75,
+ /* (2^ 13)P */ 0xec, 0xb6, 0xd0, 0xfc, 0xf1, 0x13, 0x4f, 0x2f, 0x45, 0x7a, 0xff, 0x29, 0x1f, 0xca, 0xa8, 0xf1, 0x9b, 0xe2, 0x81, 0x29, 0xa7, 0xc1, 0x49, 0xc2, 0x6a, 0xb5, 0x83, 0x8c, 0xbb, 0x0d, 0xbe, 0x6e,
+ /* (2^ 14)P */ 0x22, 0xb2, 0x0b, 0x17, 0x8d, 0xfa, 0x14, 0x71, 0x5f, 0x93, 0x93, 0xbf, 0xd5, 0xdc, 0xa2, 0x65, 0x9a, 0x97, 0x9c, 0xb5, 0x68, 0x1f, 0xc4, 0xbd, 0x89, 0x92, 0xce, 0xa2, 0x79, 0xef, 0x0e, 0x2f,
+ /* (2^ 15)P */ 0xce, 0x37, 0x3c, 0x08, 0x0c, 0xbf, 0xec, 0x42, 0x22, 0x63, 0x49, 0xec, 0x09, 0xbc, 0x30, 0x29, 0x0d, 0xac, 0xfe, 0x9c, 0xc1, 0xb0, 0x94, 0xf2, 0x80, 0xbb, 0xfa, 0xed, 0x4b, 0xaa, 0x80, 0x37,
+ /* (2^ 16)P */ 0x29, 0xd9, 0xea, 0x7c, 0x3e, 0x7d, 0xc1, 0x56, 0xc5, 0x22, 0x57, 0x2e, 0xeb, 0x4b, 0xcb, 0xe7, 0x5a, 0xe1, 0xbf, 0x2d, 0x73, 0x31, 0xe9, 0x0c, 0xf8, 0x52, 0x10, 0x62, 0xc7, 0x83, 0xb8, 0x41,
+ /* (2^ 17)P */ 0x50, 0x53, 0xd2, 0xc3, 0xa0, 0x5c, 0xf7, 0xdb, 0x51, 0xe3, 0xb1, 0x6e, 0x08, 0xbe, 0x36, 0x29, 0x12, 0xb2, 0xa9, 0xb4, 0x3c, 0xe0, 0x36, 0xc9, 0xaa, 0x25, 0x22, 0x32, 0x82, 0xbf, 0x45, 0x1d,
+ /* (2^ 18)P */ 0xc5, 0x4c, 0x02, 0x6a, 0x03, 0xb1, 0x1a, 0xe8, 0x72, 0x9a, 0x4c, 0x30, 0x1c, 0x20, 0x12, 0xe2, 0xfc, 0xb1, 0x32, 0x68, 0xba, 0x3f, 0xd7, 0xc5, 0x81, 0x95, 0x83, 0x4d, 0x5a, 0xdb, 0xff, 0x20,
+ /* (2^ 19)P */ 0xad, 0x0f, 0x5d, 0xbe, 0x67, 0xd3, 0x83, 0xa2, 0x75, 0x44, 0x16, 0x8b, 0xca, 0x25, 0x2b, 0x6c, 0x2e, 0xf2, 0xaa, 0x7c, 0x46, 0x35, 0x49, 0x9d, 0x49, 0xff, 0x85, 0xee, 0x8e, 0x40, 0x66, 0x51,
+ /* (2^ 20)P */ 0x61, 0xe3, 0xb4, 0xfa, 0xa2, 0xba, 0x67, 0x3c, 0xef, 0x5c, 0xf3, 0x7e, 0xc6, 0x33, 0xe4, 0xb3, 0x1c, 0x9b, 0x15, 0x41, 0x92, 0x72, 0x59, 0x52, 0x33, 0xab, 0xb0, 0xd5, 0x92, 0x18, 0x62, 0x6a,
+ /* (2^ 21)P */ 0xcb, 0xcd, 0x55, 0x75, 0x38, 0x4a, 0xb7, 0x20, 0x3f, 0x92, 0x08, 0x12, 0x0e, 0xa1, 0x2a, 0x53, 0xd1, 0x1d, 0x28, 0x62, 0x77, 0x7b, 0xa1, 0xea, 0xbf, 0x44, 0x5c, 0xf0, 0x43, 0x34, 0xab, 0x61,
+ /* (2^ 22)P */ 0xf8, 0xde, 0x24, 0x23, 0x42, 0x6c, 0x7a, 0x25, 0x7f, 0xcf, 0xe3, 0x17, 0x10, 0x6c, 0x1c, 0x13, 0x57, 0xa2, 0x30, 0xf6, 0x39, 0x87, 0x75, 0x23, 0x80, 0x85, 0xa7, 0x01, 0x7a, 0x40, 0x5a, 0x29,
+ /* (2^ 23)P */ 0xd9, 0xa8, 0x5d, 0x6d, 0x24, 0x43, 0xc4, 0xf8, 0x5d, 0xfa, 0x52, 0x0c, 0x45, 0x75, 0xd7, 0x19, 0x3d, 0xf8, 0x1b, 0x73, 0x92, 0xfc, 0xfc, 0x2a, 0x00, 0x47, 0x2b, 0x1b, 0xe8, 0xc8, 0x10, 0x7d,
+ /* (2^ 24)P */ 0x0b, 0xa2, 0xba, 0x70, 0x1f, 0x27, 0xe0, 0xc8, 0x57, 0x39, 0xa6, 0x7c, 0x86, 0x48, 0x37, 0x99, 0xbb, 0xd4, 0x7e, 0xcb, 0xb3, 0xef, 0x12, 0x54, 0x75, 0x29, 0xe6, 0x73, 0x61, 0xd3, 0x96, 0x31,
+ /* (2^ 25)P */ 0xfc, 0xdf, 0xc7, 0x41, 0xd1, 0xca, 0x5b, 0xde, 0x48, 0xc8, 0x95, 0xb3, 0xd2, 0x8c, 0xcc, 0x47, 0xcb, 0xf3, 0x1a, 0xe1, 0x42, 0xd9, 0x4c, 0xa3, 0xc2, 0xce, 0x4e, 0xd0, 0xf2, 0xdb, 0x56, 0x02,
+ /* (2^ 26)P */ 0x7f, 0x66, 0x0e, 0x4b, 0xe9, 0xb7, 0x5a, 0x87, 0x10, 0x0d, 0x85, 0xc0, 0x83, 0xdd, 0xd4, 0xca, 0x9f, 0xc7, 0x72, 0x4e, 0x8f, 0x2e, 0xf1, 0x47, 0x9b, 0xb1, 0x85, 0x8c, 0xbb, 0x87, 0x1a, 0x5f,
+ /* (2^ 27)P */ 0xb8, 0x51, 0x7f, 0x43, 0xb6, 0xd0, 0xe9, 0x7a, 0x65, 0x90, 0x87, 0x18, 0x55, 0xce, 0xc7, 0x12, 0xee, 0x7a, 0xf7, 0x5c, 0xfe, 0x09, 0xde, 0x2a, 0x27, 0x56, 0x2c, 0x7d, 0x2f, 0x5a, 0xa0, 0x23,
+ /* (2^ 28)P */ 0x9a, 0x16, 0x7c, 0xf1, 0x28, 0xe1, 0x08, 0x59, 0x2d, 0x85, 0xd0, 0x8a, 0xdd, 0x98, 0x74, 0xf7, 0x64, 0x2f, 0x10, 0xab, 0xce, 0xc4, 0xb4, 0x74, 0x45, 0x98, 0x13, 0x10, 0xdd, 0xba, 0x3a, 0x18,
+ /* (2^ 29)P */ 0xac, 0xaa, 0x92, 0xaa, 0x8d, 0xba, 0x65, 0xb1, 0x05, 0x67, 0x38, 0x99, 0x95, 0xef, 0xc5, 0xd5, 0xd1, 0x40, 0xfc, 0xf8, 0x0c, 0x8f, 0x2f, 0xbe, 0x14, 0x45, 0x20, 0xee, 0x35, 0xe6, 0x01, 0x27,
+ /* (2^ 30)P */ 0x14, 0x65, 0x15, 0x20, 0x00, 0xa8, 0x9f, 0x62, 0xce, 0xc1, 0xa8, 0x64, 0x87, 0x86, 0x23, 0xf2, 0x0e, 0x06, 0x3f, 0x0b, 0xff, 0x4f, 0x89, 0x5b, 0xfa, 0xa3, 0x08, 0xf7, 0x4c, 0x94, 0xd9, 0x60,
+ /* (2^ 31)P */ 0x1f, 0x20, 0x7a, 0x1c, 0x1a, 0x00, 0xea, 0xae, 0x63, 0xce, 0xe2, 0x3e, 0x63, 0x6a, 0xf1, 0xeb, 0xe1, 0x07, 0x7a, 0x4c, 0x59, 0x09, 0x77, 0x6f, 0xcb, 0x08, 0x02, 0x0d, 0x15, 0x58, 0xb9, 0x79,
+ /* (2^ 32)P */ 0xe7, 0x10, 0xd4, 0x01, 0x53, 0x5e, 0xb5, 0x24, 0x4d, 0xc8, 0xfd, 0xf3, 0xdf, 0x4e, 0xa3, 0xe3, 0xd8, 0x32, 0x40, 0x90, 0xe4, 0x68, 0x87, 0xd8, 0xec, 0xae, 0x3a, 0x7b, 0x42, 0x84, 0x13, 0x13,
+ /* (2^ 33)P */ 0x14, 0x4f, 0x23, 0x86, 0x12, 0xe5, 0x05, 0x84, 0x29, 0xc5, 0xb4, 0xad, 0x39, 0x47, 0xdc, 0x14, 0xfd, 0x4f, 0x63, 0x50, 0xb2, 0xb5, 0xa2, 0xb8, 0x93, 0xff, 0xa7, 0xd8, 0x4a, 0xa9, 0xe2, 0x2f,
+ /* (2^ 34)P */ 0xdd, 0xfa, 0x43, 0xe8, 0xef, 0x57, 0x5c, 0xec, 0x18, 0x99, 0xbb, 0xf0, 0x40, 0xce, 0x43, 0x28, 0x05, 0x63, 0x3d, 0xcf, 0xd6, 0x61, 0xb5, 0xa4, 0x7e, 0x77, 0xfb, 0xe8, 0xbd, 0x29, 0x36, 0x74,
+ /* (2^ 35)P */ 0x8f, 0x73, 0xaf, 0xbb, 0x46, 0xdd, 0x3e, 0x34, 0x51, 0xa6, 0x01, 0xb1, 0x28, 0x18, 0x98, 0xed, 0x7a, 0x79, 0x2c, 0x88, 0x0b, 0x76, 0x01, 0xa4, 0x30, 0x87, 0xc8, 0x8d, 0xe2, 0x23, 0xc2, 0x1f,
+ /* (2^ 36)P */ 0x0e, 0xba, 0x0f, 0xfc, 0x91, 0x4e, 0x60, 0x48, 0xa4, 0x6f, 0x2c, 0x05, 0x8f, 0xf7, 0x37, 0xb6, 0x9c, 0x23, 0xe9, 0x09, 0x3d, 0xac, 0xcc, 0x91, 0x7c, 0x68, 0x7a, 0x43, 0xd4, 0xee, 0xf7, 0x23,
+ /* (2^ 37)P */ 0x00, 0xd8, 0x9b, 0x8d, 0x11, 0xb1, 0x73, 0x51, 0xa7, 0xd4, 0x89, 0x31, 0xb6, 0x41, 0xd6, 0x29, 0x86, 0xc5, 0xbb, 0x88, 0x79, 0x17, 0xbf, 0xfd, 0xf5, 0x1d, 0xd8, 0xca, 0x4f, 0x89, 0x59, 0x29,
+ /* (2^ 38)P */ 0x99, 0xc8, 0xbb, 0xb4, 0xf3, 0x8e, 0xbc, 0xae, 0xb9, 0x92, 0x69, 0xb2, 0x5a, 0x99, 0x48, 0x41, 0xfb, 0x2c, 0xf9, 0x34, 0x01, 0x0b, 0xe2, 0x24, 0xe8, 0xde, 0x05, 0x4a, 0x89, 0x58, 0xd1, 0x40,
+ /* (2^ 39)P */ 0xf6, 0x76, 0xaf, 0x85, 0x11, 0x0b, 0xb0, 0x46, 0x79, 0x7a, 0x18, 0x73, 0x78, 0xc7, 0xba, 0x26, 0x5f, 0xff, 0x8f, 0xab, 0x95, 0xbf, 0xc0, 0x3d, 0xd7, 0x24, 0x55, 0x94, 0xd8, 0x8b, 0x60, 0x2a,
+ /* (2^ 40)P */ 0x02, 0x63, 0x44, 0xbd, 0x88, 0x95, 0x44, 0x26, 0x9c, 0x43, 0x88, 0x03, 0x1c, 0xc2, 0x4b, 0x7c, 0xb2, 0x11, 0xbd, 0x83, 0xf3, 0xa4, 0x98, 0x8e, 0xb9, 0x76, 0xd8, 0xc9, 0x7b, 0x8d, 0x21, 0x26,
+ /* (2^ 41)P */ 0x8a, 0x17, 0x7c, 0x99, 0x42, 0x15, 0x08, 0xe3, 0x6f, 0x60, 0xb6, 0x6f, 0xa8, 0x29, 0x2d, 0x3c, 0x74, 0x93, 0x27, 0xfa, 0x36, 0x77, 0x21, 0x5c, 0xfa, 0xb1, 0xfe, 0x4a, 0x73, 0x05, 0xde, 0x7d,
+ /* (2^ 42)P */ 0xab, 0x2b, 0xd4, 0x06, 0x39, 0x0e, 0xf1, 0x3b, 0x9c, 0x64, 0x80, 0x19, 0x3e, 0x80, 0xf7, 0xe4, 0x7a, 0xbf, 0x95, 0x95, 0xf8, 0x3b, 0x05, 0xe6, 0x30, 0x55, 0x24, 0xda, 0x38, 0xaf, 0x4f, 0x39,
+ /* (2^ 43)P */ 0xf4, 0x28, 0x69, 0x89, 0x58, 0xfb, 0x8e, 0x7a, 0x3c, 0x11, 0x6a, 0xcc, 0xe9, 0x78, 0xc7, 0xfb, 0x6f, 0x59, 0xaf, 0x30, 0xe3, 0x0c, 0x67, 0x72, 0xf7, 0x6c, 0x3d, 0x1d, 0xa8, 0x22, 0xf2, 0x48,
+ /* (2^ 44)P */ 0xa7, 0xca, 0x72, 0x0d, 0x41, 0xce, 0x1f, 0xf0, 0x95, 0x55, 0x3b, 0x21, 0xc7, 0xec, 0x20, 0x5a, 0x83, 0x14, 0xfa, 0xc1, 0x65, 0x11, 0xc2, 0x7b, 0x41, 0xa7, 0xa8, 0x1d, 0xe3, 0x9a, 0xf8, 0x07,
+ /* (2^ 45)P */ 0xf9, 0x0f, 0x83, 0xc6, 0xb4, 0xc2, 0xd2, 0x05, 0x93, 0x62, 0x31, 0xc6, 0x0f, 0x33, 0x3e, 0xd4, 0x04, 0xa9, 0xd3, 0x96, 0x0a, 0x59, 0xa5, 0xa5, 0xb6, 0x33, 0x53, 0xa6, 0x91, 0xdb, 0x5e, 0x70,
+ /* (2^ 46)P */ 0xf7, 0xa5, 0xb9, 0x0b, 0x5e, 0xe1, 0x8e, 0x04, 0x5d, 0xaf, 0x0a, 0x9e, 0xca, 0xcf, 0x40, 0x32, 0x0b, 0xa4, 0xc4, 0xed, 0xce, 0x71, 0x4b, 0x8f, 0x6d, 0x4a, 0x54, 0xde, 0xa3, 0x0d, 0x1c, 0x62,
+ /* (2^ 47)P */ 0x91, 0x40, 0x8c, 0xa0, 0x36, 0x28, 0x87, 0x92, 0x45, 0x14, 0xc9, 0x10, 0xb0, 0x75, 0x83, 0xce, 0x94, 0x63, 0x27, 0x4f, 0x52, 0xeb, 0x72, 0x8a, 0x35, 0x36, 0xc8, 0x7e, 0xfa, 0xfc, 0x67, 0x26,
+ /* (2^ 48)P */ 0x2a, 0x75, 0xe8, 0x45, 0x33, 0x17, 0x4c, 0x7f, 0xa5, 0x79, 0x70, 0xee, 0xfe, 0x47, 0x1b, 0x06, 0x34, 0xff, 0x86, 0x9f, 0xfa, 0x9a, 0xdd, 0x25, 0x9c, 0xc8, 0x5d, 0x42, 0xf5, 0xce, 0x80, 0x37,
+ /* (2^ 49)P */ 0xe9, 0xb4, 0x3b, 0x51, 0x5a, 0x03, 0x46, 0x1a, 0xda, 0x5a, 0x57, 0xac, 0x79, 0xf3, 0x1e, 0x3e, 0x50, 0x4b, 0xa2, 0x5f, 0x1c, 0x5f, 0x8c, 0xc7, 0x22, 0x9f, 0xfd, 0x34, 0x76, 0x96, 0x1a, 0x32,
+ /* (2^ 50)P */ 0xfa, 0x27, 0x6e, 0x82, 0xb8, 0x07, 0x67, 0x94, 0xd0, 0x6f, 0x50, 0x4c, 0xd6, 0x84, 0xca, 0x3d, 0x36, 0x14, 0xe9, 0x75, 0x80, 0x21, 0x89, 0xc1, 0x84, 0x84, 0x3b, 0x9b, 0x16, 0x84, 0x92, 0x6d,
+ /* (2^ 51)P */ 0xdf, 0x2d, 0x3f, 0x38, 0x40, 0xe8, 0x67, 0x3a, 0x75, 0x9b, 0x4f, 0x0c, 0xa3, 0xc9, 0xee, 0x33, 0x47, 0xef, 0x83, 0xa7, 0x6f, 0xc8, 0xc7, 0x3e, 0xc4, 0xfb, 0xc9, 0xba, 0x9f, 0x44, 0xec, 0x26,
+ /* (2^ 52)P */ 0x7d, 0x9e, 0x9b, 0xa0, 0xcb, 0x38, 0x0f, 0x5c, 0x8c, 0x47, 0xa3, 0x62, 0xc7, 0x8c, 0x16, 0x81, 0x1c, 0x12, 0xfc, 0x06, 0xd3, 0xb0, 0x23, 0x3e, 0xdd, 0xdc, 0xef, 0xa5, 0xa0, 0x8a, 0x23, 0x5a,
+ /* (2^ 53)P */ 0xff, 0x43, 0xea, 0xc4, 0x21, 0x61, 0xa2, 0x1b, 0xb5, 0x32, 0x88, 0x7c, 0x7f, 0xc7, 0xf8, 0x36, 0x9a, 0xf9, 0xdc, 0x0a, 0x0b, 0xea, 0xfb, 0x88, 0xf9, 0xeb, 0x5b, 0xc2, 0x8e, 0x93, 0xa9, 0x5c,
+ /* (2^ 54)P */ 0xa0, 0xcd, 0xfc, 0x51, 0x5e, 0x6a, 0x43, 0xd5, 0x3b, 0x89, 0xcd, 0xc2, 0x97, 0x47, 0xbc, 0x1d, 0x08, 0x4a, 0x22, 0xd3, 0x65, 0x6a, 0x34, 0x19, 0x66, 0xf4, 0x9a, 0x9b, 0xe4, 0x34, 0x50, 0x0f,
+ /* (2^ 55)P */ 0x6e, 0xb9, 0xe0, 0xa1, 0x67, 0x39, 0x3c, 0xf2, 0x88, 0x4d, 0x7a, 0x86, 0xfa, 0x08, 0x8b, 0xe5, 0x79, 0x16, 0x34, 0xa7, 0xc6, 0xab, 0x2f, 0xfb, 0x46, 0x69, 0x02, 0xb6, 0x1e, 0x38, 0x75, 0x2a,
+ /* (2^ 56)P */ 0xac, 0x20, 0x94, 0xc1, 0xe4, 0x3b, 0x0a, 0xc8, 0xdc, 0xb6, 0xf2, 0x81, 0xc6, 0xf6, 0xb1, 0x66, 0x88, 0x33, 0xe9, 0x61, 0x67, 0x03, 0xf7, 0x7c, 0xc4, 0xa4, 0x60, 0xa6, 0xd8, 0xbb, 0xab, 0x25,
+ /* (2^ 57)P */ 0x98, 0x51, 0xfd, 0x14, 0xba, 0x12, 0xea, 0x91, 0xa9, 0xff, 0x3c, 0x4a, 0xfc, 0x50, 0x49, 0x68, 0x28, 0xad, 0xf5, 0x30, 0x21, 0x84, 0x26, 0xf8, 0x41, 0xa4, 0x01, 0x53, 0xf7, 0x88, 0xa9, 0x3e,
+ /* (2^ 58)P */ 0x6f, 0x8c, 0x5f, 0x69, 0x9a, 0x10, 0x78, 0xc9, 0xf3, 0xc3, 0x30, 0x05, 0x4a, 0xeb, 0x46, 0x17, 0x95, 0x99, 0x45, 0xb4, 0x77, 0x6d, 0x4d, 0x44, 0xc7, 0x5c, 0x4e, 0x05, 0x8c, 0x2b, 0x95, 0x75,
+ /* (2^ 59)P */ 0xaa, 0xd6, 0xf4, 0x15, 0x79, 0x3f, 0x70, 0xa3, 0xd8, 0x47, 0x26, 0x2f, 0x20, 0x46, 0xc3, 0x66, 0x4b, 0x64, 0x1d, 0x81, 0xdf, 0x69, 0x14, 0xd0, 0x1f, 0xd7, 0xa5, 0x81, 0x7d, 0xa4, 0xfe, 0x77,
+ /* (2^ 60)P */ 0x81, 0xa3, 0x7c, 0xf5, 0x9e, 0x52, 0xe9, 0xc5, 0x1a, 0x88, 0x2f, 0xce, 0xb9, 0xb4, 0xee, 0x6e, 0xd6, 0x9b, 0x00, 0xe8, 0x28, 0x1a, 0xe9, 0xb6, 0xec, 0x3f, 0xfc, 0x9a, 0x3e, 0xbe, 0x80, 0x4b,
+ /* (2^ 61)P */ 0xc5, 0xd2, 0xae, 0x26, 0xc5, 0x73, 0x37, 0x7e, 0x9d, 0xa4, 0xc9, 0x53, 0xb4, 0xfc, 0x4a, 0x1b, 0x4d, 0xb2, 0xff, 0xba, 0xd7, 0xbd, 0x20, 0xa9, 0x0e, 0x40, 0x2d, 0x12, 0x9f, 0x69, 0x54, 0x7c,
+ /* (2^ 62)P */ 0xc8, 0x4b, 0xa9, 0x4f, 0xe1, 0xc8, 0x46, 0xef, 0x5e, 0xed, 0x52, 0x29, 0xce, 0x74, 0xb0, 0xe0, 0xd5, 0x85, 0xd8, 0xdb, 0xe1, 0x50, 0xa4, 0xbe, 0x2c, 0x71, 0x0f, 0x32, 0x49, 0x86, 0xb6, 0x61,
+ /* (2^ 63)P */ 0xd1, 0xbd, 0xcc, 0x09, 0x73, 0x5f, 0x48, 0x8a, 0x2d, 0x1a, 0x4d, 0x7d, 0x0d, 0x32, 0x06, 0xbd, 0xf4, 0xbe, 0x2d, 0x32, 0x73, 0x29, 0x23, 0x25, 0x70, 0xf7, 0x17, 0x8c, 0x75, 0xc4, 0x5d, 0x44,
+ /* (2^ 64)P */ 0x3c, 0x93, 0xc8, 0x7c, 0x17, 0x34, 0x04, 0xdb, 0x9f, 0x05, 0xea, 0x75, 0x21, 0xe8, 0x6f, 0xed, 0x34, 0xdb, 0x53, 0xc0, 0xfd, 0xbe, 0xfe, 0x1e, 0x99, 0xaf, 0x5d, 0xc6, 0x67, 0xe8, 0xdb, 0x4a,
+ /* (2^ 65)P */ 0xdf, 0x09, 0x06, 0xa9, 0xa2, 0x71, 0xcd, 0x3a, 0x50, 0x40, 0xd0, 0x6d, 0x85, 0x91, 0xe9, 0xe5, 0x3c, 0xc2, 0x57, 0x81, 0x68, 0x9b, 0xc6, 0x1e, 0x4d, 0xfe, 0x5c, 0x88, 0xf6, 0x27, 0x74, 0x69,
+ /* (2^ 66)P */ 0x51, 0xa8, 0xe1, 0x65, 0x9b, 0x7b, 0xbe, 0xd7, 0xdd, 0x36, 0xc5, 0x22, 0xd5, 0x28, 0x3d, 0xa0, 0x45, 0xb6, 0xd2, 0x8f, 0x65, 0x9d, 0x39, 0x28, 0xe1, 0x41, 0x26, 0x7c, 0xe1, 0xb7, 0xe5, 0x49,
+ /* (2^ 67)P */ 0xa4, 0x57, 0x04, 0x70, 0x98, 0x3a, 0x8c, 0x6f, 0x78, 0x67, 0xbb, 0x5e, 0xa2, 0xf0, 0x78, 0x50, 0x0f, 0x96, 0x82, 0xc3, 0xcb, 0x3c, 0x3c, 0xd1, 0xb1, 0x84, 0xdf, 0xa7, 0x58, 0x32, 0x00, 0x2e,
+ /* (2^ 68)P */ 0x1c, 0x6a, 0x29, 0xe6, 0x9b, 0xf3, 0xd1, 0x8a, 0xb2, 0xbf, 0x5f, 0x2a, 0x65, 0xaa, 0xee, 0xc1, 0xcb, 0xf3, 0x26, 0xfd, 0x73, 0x06, 0xee, 0x33, 0xcc, 0x2c, 0x9d, 0xa6, 0x73, 0x61, 0x25, 0x59,
+ /* (2^ 69)P */ 0x41, 0xfc, 0x18, 0x4e, 0xaa, 0x07, 0xea, 0x41, 0x1e, 0xa5, 0x87, 0x7c, 0x52, 0x19, 0xfc, 0xd9, 0x6f, 0xca, 0x31, 0x58, 0x80, 0xcb, 0xaa, 0xbd, 0x4f, 0x69, 0x16, 0xc9, 0x2d, 0x65, 0x5b, 0x44,
+ /* (2^ 70)P */ 0x15, 0x23, 0x17, 0xf2, 0xa7, 0xa3, 0x92, 0xce, 0x64, 0x99, 0x1b, 0xe1, 0x2d, 0x28, 0xdc, 0x1e, 0x4a, 0x31, 0x4c, 0xe0, 0xaf, 0x3a, 0x82, 0xa1, 0x86, 0xf5, 0x7c, 0x43, 0x94, 0x2d, 0x0a, 0x79,
+ /* (2^ 71)P */ 0x09, 0xe0, 0xf6, 0x93, 0xfb, 0x47, 0xc4, 0x71, 0x76, 0x52, 0x84, 0x22, 0x67, 0xa5, 0x22, 0x89, 0x69, 0x51, 0x4f, 0x20, 0x3b, 0x90, 0x70, 0xbf, 0xfe, 0x19, 0xa3, 0x1b, 0x89, 0x89, 0x7a, 0x2f,
+ /* (2^ 72)P */ 0x0c, 0x14, 0xe2, 0x77, 0xb5, 0x8e, 0xa0, 0x02, 0xf4, 0xdc, 0x7b, 0x42, 0xd4, 0x4e, 0x9a, 0xed, 0xd1, 0x3c, 0x32, 0xe4, 0x44, 0xec, 0x53, 0x52, 0x5b, 0x35, 0xe9, 0x14, 0x3c, 0x36, 0x88, 0x3e,
+ /* (2^ 73)P */ 0x8c, 0x0b, 0x11, 0x77, 0x42, 0xc1, 0x66, 0xaa, 0x90, 0x33, 0xa2, 0x10, 0x16, 0x39, 0xe0, 0x1a, 0xa2, 0xc2, 0x3f, 0xc9, 0x12, 0xbd, 0x30, 0x20, 0xab, 0xc7, 0x55, 0x95, 0x57, 0x41, 0xe1, 0x3e,
+ /* (2^ 74)P */ 0x41, 0x7d, 0x6e, 0x6d, 0x3a, 0xde, 0x14, 0x92, 0xfe, 0x7e, 0xf1, 0x07, 0x86, 0xd8, 0xcd, 0x3c, 0x17, 0x12, 0xe1, 0xf8, 0x88, 0x12, 0x4f, 0x67, 0xd0, 0x93, 0x9f, 0x32, 0x0f, 0x25, 0x82, 0x56,
+ /* (2^ 75)P */ 0x6e, 0x39, 0x2e, 0x6d, 0x13, 0x0b, 0xf0, 0x6c, 0xbf, 0xde, 0x14, 0x10, 0x6f, 0xf8, 0x4c, 0x6e, 0x83, 0x4e, 0xcc, 0xbf, 0xb5, 0xb1, 0x30, 0x59, 0xb6, 0x16, 0xba, 0x8a, 0xb4, 0x69, 0x70, 0x04,
+ /* (2^ 76)P */ 0x93, 0x07, 0xb2, 0x69, 0xab, 0xe4, 0x4c, 0x0d, 0x9e, 0xfb, 0xd0, 0x97, 0x1a, 0xb9, 0x4d, 0xb2, 0x1d, 0xd0, 0x00, 0x4e, 0xf5, 0x50, 0xfa, 0xcd, 0xb5, 0xdd, 0x8b, 0x36, 0x85, 0x10, 0x1b, 0x22,
+ /* (2^ 77)P */ 0xd2, 0xd8, 0xe3, 0xb1, 0x68, 0x94, 0xe5, 0xe7, 0x93, 0x2f, 0x12, 0xbd, 0x63, 0x65, 0xc5, 0x53, 0x09, 0x3f, 0x66, 0xe0, 0x03, 0xa9, 0xe8, 0xee, 0x42, 0x3d, 0xbe, 0xcb, 0x62, 0xa6, 0xef, 0x61,
+ /* (2^ 78)P */ 0x2a, 0xab, 0x6e, 0xde, 0xdd, 0xdd, 0xf8, 0x2c, 0x31, 0xf2, 0x35, 0x14, 0xd5, 0x0a, 0xf8, 0x9b, 0x73, 0x49, 0xf0, 0xc9, 0xce, 0xda, 0xea, 0x5d, 0x27, 0x9b, 0xd2, 0x41, 0x5d, 0x5b, 0x27, 0x29,
+ /* (2^ 79)P */ 0x4f, 0xf1, 0xeb, 0x95, 0x08, 0x0f, 0xde, 0xcf, 0xa7, 0x05, 0x49, 0x05, 0x6b, 0xb9, 0xaa, 0xb9, 0xfd, 0x20, 0xc4, 0xa1, 0xd9, 0x0d, 0xe8, 0xca, 0xc7, 0xbb, 0x73, 0x16, 0x2f, 0xbf, 0x63, 0x0a,
+ /* (2^ 80)P */ 0x8c, 0xbc, 0x8f, 0x95, 0x11, 0x6e, 0x2f, 0x09, 0xad, 0x2f, 0x82, 0x04, 0xe8, 0x81, 0x2a, 0x67, 0x17, 0x25, 0xd5, 0x60, 0x15, 0x35, 0xc8, 0xca, 0xf8, 0x92, 0xf1, 0xc8, 0x22, 0x77, 0x3f, 0x6f,
+ /* (2^ 81)P */ 0xb7, 0x94, 0xe8, 0xc2, 0xcc, 0x90, 0xba, 0xf8, 0x0d, 0x9f, 0xff, 0x38, 0xa4, 0x57, 0x75, 0x2c, 0x59, 0x23, 0xe5, 0x5a, 0x85, 0x1d, 0x4d, 0x89, 0x69, 0x3d, 0x74, 0x7b, 0x15, 0x22, 0xe1, 0x68,
+ /* (2^ 82)P */ 0xf3, 0x19, 0xb9, 0xcf, 0x70, 0x55, 0x7e, 0xd8, 0xb9, 0x8d, 0x79, 0x95, 0xcd, 0xde, 0x2c, 0x3f, 0xce, 0xa2, 0xc0, 0x10, 0x47, 0x15, 0x21, 0x21, 0xb2, 0xc5, 0x6d, 0x24, 0x15, 0xa1, 0x66, 0x3c,
+ /* (2^ 83)P */ 0x72, 0xcb, 0x4e, 0x29, 0x62, 0xc5, 0xed, 0xcb, 0x16, 0x0b, 0x28, 0x6a, 0xc3, 0x43, 0x71, 0xba, 0x67, 0x8b, 0x07, 0xd4, 0xef, 0xc2, 0x10, 0x96, 0x1e, 0x4b, 0x6a, 0x94, 0x5d, 0x73, 0x44, 0x61,
+ /* (2^ 84)P */ 0x50, 0x33, 0x5b, 0xd7, 0x1e, 0x11, 0x6f, 0x53, 0x1b, 0xd8, 0x41, 0x20, 0x8c, 0xdb, 0x11, 0x02, 0x3c, 0x41, 0x10, 0x0e, 0x00, 0xb1, 0x3c, 0xf9, 0x76, 0x88, 0x9e, 0x03, 0x3c, 0xfd, 0x9d, 0x14,
+ /* (2^ 85)P */ 0x5b, 0x15, 0x63, 0x6b, 0xe4, 0xdd, 0x79, 0xd4, 0x76, 0x79, 0x83, 0x3c, 0xe9, 0x15, 0x6e, 0xb6, 0x38, 0xe0, 0x13, 0x1f, 0x3b, 0xe4, 0xfd, 0xda, 0x35, 0x0b, 0x4b, 0x2e, 0x1a, 0xda, 0xaf, 0x5f,
+ /* (2^ 86)P */ 0x81, 0x75, 0x19, 0x17, 0xdf, 0xbb, 0x00, 0x36, 0xc2, 0xd2, 0x3c, 0xbe, 0x0b, 0x05, 0x72, 0x39, 0x86, 0xbe, 0xd5, 0xbd, 0x6d, 0x90, 0x38, 0x59, 0x0f, 0x86, 0x9b, 0x3f, 0xe4, 0xe5, 0xfc, 0x34,
+ /* (2^ 87)P */ 0x02, 0x4d, 0xd1, 0x42, 0xcd, 0xa4, 0xa8, 0x75, 0x65, 0xdf, 0x41, 0x34, 0xc5, 0xab, 0x8d, 0x82, 0xd3, 0x31, 0xe1, 0xd2, 0xed, 0xab, 0xdc, 0x33, 0x5f, 0xd2, 0x14, 0xb8, 0x6f, 0xd7, 0xba, 0x3e,
+ /* (2^ 88)P */ 0x0f, 0xe1, 0x70, 0x6f, 0x56, 0x6f, 0x90, 0xd4, 0x5a, 0x0f, 0x69, 0x51, 0xaa, 0xf7, 0x12, 0x5d, 0xf2, 0xfc, 0xce, 0x76, 0x6e, 0xb1, 0xad, 0x45, 0x99, 0x29, 0x23, 0xad, 0xae, 0x68, 0xf7, 0x01,
+ /* (2^ 89)P */ 0xbd, 0xfe, 0x48, 0x62, 0x7b, 0xc7, 0x6c, 0x2b, 0xfd, 0xaf, 0x3a, 0xec, 0x28, 0x06, 0xd3, 0x3c, 0x6a, 0x48, 0xef, 0xd4, 0x80, 0x0b, 0x1c, 0xce, 0x23, 0x6c, 0xf6, 0xa6, 0x2e, 0xff, 0x3b, 0x4c,
+ /* (2^ 90)P */ 0x5f, 0xeb, 0xea, 0x4a, 0x09, 0xc4, 0x2e, 0x3f, 0xa7, 0x2c, 0x37, 0x6e, 0x28, 0x9b, 0xb1, 0x61, 0x1d, 0x70, 0x2a, 0xde, 0x66, 0xa9, 0xef, 0x5e, 0xef, 0xe3, 0x55, 0xde, 0x65, 0x05, 0xb2, 0x23,
+ /* (2^ 91)P */ 0x57, 0x85, 0xd5, 0x79, 0x52, 0xca, 0x01, 0xe3, 0x4f, 0x87, 0xc2, 0x27, 0xce, 0xd4, 0xb2, 0x07, 0x67, 0x1d, 0xcf, 0x9d, 0x8a, 0xcd, 0x32, 0xa5, 0x56, 0xff, 0x2b, 0x3f, 0xe2, 0xfe, 0x52, 0x2a,
+ /* (2^ 92)P */ 0x3d, 0x66, 0xd8, 0x7c, 0xb3, 0xef, 0x24, 0x86, 0x94, 0x75, 0xbd, 0xff, 0x20, 0xac, 0xc7, 0xbb, 0x45, 0x74, 0xd3, 0x82, 0x9c, 0x5e, 0xb8, 0x57, 0x66, 0xec, 0xa6, 0x86, 0xcb, 0x52, 0x30, 0x7b,
+ /* (2^ 93)P */ 0x1e, 0xe9, 0x25, 0x25, 0xad, 0xf0, 0x82, 0x34, 0xa0, 0xdc, 0x8e, 0xd2, 0x43, 0x80, 0xb6, 0x2c, 0x3a, 0x00, 0x1b, 0x2e, 0x05, 0x6d, 0x4f, 0xaf, 0x0a, 0x1b, 0x78, 0x29, 0x25, 0x8c, 0x5f, 0x18,
+ /* (2^ 94)P */ 0xd6, 0xe0, 0x0c, 0xd8, 0x5b, 0xde, 0x41, 0xaa, 0xd6, 0xe9, 0x53, 0x68, 0x41, 0xb2, 0x07, 0x94, 0x3a, 0x4c, 0x7f, 0x35, 0x6e, 0xc3, 0x3e, 0x56, 0xce, 0x7b, 0x29, 0x0e, 0xdd, 0xb8, 0xc4, 0x4c,
+ /* (2^ 95)P */ 0x0e, 0x73, 0xb8, 0xff, 0x52, 0x1a, 0xfc, 0xa2, 0x37, 0x8e, 0x05, 0x67, 0x6e, 0xf1, 0x11, 0x18, 0xe1, 0x4e, 0xdf, 0xcd, 0x66, 0xa3, 0xf9, 0x10, 0x99, 0xf0, 0xb9, 0xa0, 0xc4, 0xa0, 0xf4, 0x72,
+ /* (2^ 96)P */ 0xa7, 0x4e, 0x3f, 0x66, 0x6f, 0xc0, 0x16, 0x8c, 0xba, 0x0f, 0x97, 0x4e, 0xf7, 0x3a, 0x3b, 0x69, 0x45, 0xc3, 0x9e, 0xd6, 0xf1, 0xe7, 0x02, 0x21, 0x89, 0x80, 0x8a, 0x96, 0xbc, 0x3c, 0xa5, 0x0b,
+ /* (2^ 97)P */ 0x37, 0x55, 0xa1, 0xfe, 0xc7, 0x9d, 0x3d, 0xca, 0x93, 0x64, 0x53, 0x51, 0xbb, 0x24, 0x68, 0x4c, 0xb1, 0x06, 0x40, 0x84, 0x14, 0x63, 0x88, 0xb9, 0x60, 0xcc, 0x54, 0xb4, 0x2a, 0xa7, 0xd2, 0x40,
+ /* (2^ 98)P */ 0x75, 0x09, 0x57, 0x12, 0xb7, 0xa1, 0x36, 0x59, 0x57, 0xa6, 0xbd, 0xde, 0x48, 0xd6, 0xb9, 0x91, 0xea, 0x30, 0x43, 0xb6, 0x4b, 0x09, 0x44, 0x33, 0xd0, 0x51, 0xee, 0x12, 0x0d, 0xa1, 0x6b, 0x00,
+ /* (2^ 99)P */ 0x58, 0x5d, 0xde, 0xf5, 0x68, 0x84, 0x22, 0x19, 0xb0, 0x05, 0xcc, 0x38, 0x4c, 0x2f, 0xb1, 0x0e, 0x90, 0x19, 0x60, 0xd5, 0x9d, 0x9f, 0x03, 0xa1, 0x0b, 0x0e, 0xff, 0x4f, 0xce, 0xd4, 0x02, 0x45,
+ /* (2^100)P */ 0x89, 0xc1, 0x37, 0x68, 0x10, 0x54, 0x20, 0xeb, 0x3c, 0xb9, 0xd3, 0x6d, 0x4c, 0x54, 0xf6, 0xd0, 0x4f, 0xd7, 0x16, 0xc4, 0x64, 0x70, 0x72, 0x40, 0xf0, 0x2e, 0x50, 0x4b, 0x11, 0xc6, 0x15, 0x6e,
+ /* (2^101)P */ 0x6b, 0xa7, 0xb1, 0xcf, 0x98, 0xa3, 0xf2, 0x4d, 0xb1, 0xf6, 0xf2, 0x19, 0x74, 0x6c, 0x25, 0x11, 0x43, 0x60, 0x6e, 0x06, 0x62, 0x79, 0x49, 0x4a, 0x44, 0x5b, 0x35, 0x41, 0xab, 0x3a, 0x5b, 0x70,
+ /* (2^102)P */ 0xd8, 0xb1, 0x97, 0xd7, 0x36, 0xf5, 0x5e, 0x36, 0xdb, 0xf0, 0xdd, 0x22, 0xd6, 0x6b, 0x07, 0x00, 0x88, 0x5a, 0x57, 0xe0, 0xb0, 0x33, 0xbf, 0x3b, 0x4d, 0xca, 0xe4, 0xc8, 0x05, 0xaa, 0x77, 0x37,
+ /* (2^103)P */ 0x5f, 0xdb, 0x78, 0x55, 0xc8, 0x45, 0x27, 0x39, 0xe2, 0x5a, 0xae, 0xdb, 0x49, 0x41, 0xda, 0x6f, 0x67, 0x98, 0xdc, 0x8a, 0x0b, 0xb0, 0xf0, 0xb1, 0xa3, 0x1d, 0x6f, 0xd3, 0x37, 0x34, 0x96, 0x09,
+ /* (2^104)P */ 0x53, 0x38, 0xdc, 0xa5, 0x90, 0x4e, 0x82, 0x7e, 0xbd, 0x5c, 0x13, 0x1f, 0x64, 0xf6, 0xb5, 0xcc, 0xcc, 0x8f, 0xce, 0x87, 0x6c, 0xd8, 0x36, 0x67, 0x9f, 0x24, 0x04, 0x66, 0xe2, 0x3c, 0x5f, 0x62,
+ /* (2^105)P */ 0x3f, 0xf6, 0x02, 0x95, 0x05, 0xc8, 0x8a, 0xaf, 0x69, 0x14, 0x35, 0x2e, 0x0a, 0xe7, 0x05, 0x0c, 0x05, 0x63, 0x4b, 0x76, 0x9c, 0x2e, 0x29, 0x35, 0xc3, 0x3a, 0xe2, 0xc7, 0x60, 0x43, 0x39, 0x1a,
+ /* (2^106)P */ 0x64, 0x32, 0x18, 0x51, 0x32, 0xd5, 0xc6, 0xd5, 0x4f, 0xb7, 0xc2, 0x43, 0xbd, 0x5a, 0x06, 0x62, 0x9b, 0x3f, 0x97, 0x3b, 0xd0, 0xf5, 0xfb, 0xb5, 0x5e, 0x6e, 0x20, 0x61, 0x36, 0xda, 0xa3, 0x13,
+ /* (2^107)P */ 0xe5, 0x94, 0x5d, 0x72, 0x37, 0x58, 0xbd, 0xc6, 0xc5, 0x16, 0x50, 0x20, 0x12, 0x09, 0xe3, 0x18, 0x68, 0x3c, 0x03, 0x70, 0x15, 0xce, 0x88, 0x20, 0x87, 0x79, 0x83, 0x5c, 0x49, 0x1f, 0xba, 0x7f,
+ /* (2^108)P */ 0x9d, 0x07, 0xf9, 0xf2, 0x23, 0x74, 0x8c, 0x5a, 0xc5, 0x3f, 0x02, 0x34, 0x7b, 0x15, 0x35, 0x17, 0x51, 0xb3, 0xfa, 0xd2, 0x9a, 0xb4, 0xf9, 0xe4, 0x3c, 0xe3, 0x78, 0xc8, 0x72, 0xff, 0x91, 0x66,
+ /* (2^109)P */ 0x3e, 0xff, 0x5e, 0xdc, 0xde, 0x2a, 0x2c, 0x12, 0xf4, 0x6c, 0x95, 0xd8, 0xf1, 0x4b, 0xdd, 0xf8, 0xda, 0x5b, 0x9e, 0x9e, 0x5d, 0x20, 0x86, 0xeb, 0x43, 0xc7, 0x75, 0xd9, 0xb9, 0x92, 0x9b, 0x04,
+ /* (2^110)P */ 0x5a, 0xc0, 0xf6, 0xb0, 0x30, 0x97, 0x37, 0xa5, 0x53, 0xa5, 0xf3, 0xc6, 0xac, 0xff, 0xa0, 0x72, 0x6d, 0xcd, 0x0d, 0xb2, 0x34, 0x2c, 0x03, 0xb0, 0x4a, 0x16, 0xd5, 0x88, 0xbc, 0x9d, 0x0e, 0x47,
+ /* (2^111)P */ 0x47, 0xc0, 0x37, 0xa2, 0x0c, 0xf1, 0x9c, 0xb1, 0xa2, 0x81, 0x6c, 0x1f, 0x71, 0x66, 0x54, 0xb6, 0x43, 0x0b, 0xd8, 0x6d, 0xd1, 0x1b, 0x32, 0xb3, 0x8e, 0xbe, 0x5f, 0x0c, 0x60, 0x4f, 0xc1, 0x48,
+ /* (2^112)P */ 0x03, 0xc8, 0xa6, 0x4a, 0x26, 0x1c, 0x45, 0x66, 0xa6, 0x7d, 0xfa, 0xa4, 0x04, 0x39, 0x6e, 0xb6, 0x95, 0x83, 0x12, 0xb3, 0xb0, 0x19, 0x5f, 0xd4, 0x10, 0xbc, 0xc9, 0xc3, 0x27, 0x26, 0x60, 0x31,
+ /* (2^113)P */ 0x0d, 0xe1, 0xe4, 0x32, 0x48, 0xdc, 0x20, 0x31, 0xf7, 0x17, 0xc7, 0x56, 0x67, 0xc4, 0x20, 0xeb, 0x94, 0x02, 0x28, 0x67, 0x3f, 0x2e, 0xf5, 0x00, 0x09, 0xc5, 0x30, 0x47, 0xc1, 0x4f, 0x6d, 0x56,
+ /* (2^114)P */ 0x06, 0x72, 0x83, 0xfd, 0x40, 0x5d, 0x3a, 0x7e, 0x7a, 0x54, 0x59, 0x71, 0xdc, 0x26, 0xe9, 0xc1, 0x95, 0x60, 0x8d, 0xa6, 0xfb, 0x30, 0x67, 0x21, 0xa7, 0xce, 0x69, 0x3f, 0x84, 0xc3, 0xe8, 0x22,
+ /* (2^115)P */ 0x2b, 0x4b, 0x0e, 0x93, 0xe8, 0x74, 0xd0, 0x33, 0x16, 0x58, 0xd1, 0x84, 0x0e, 0x35, 0xe4, 0xb6, 0x65, 0x23, 0xba, 0xd6, 0x6a, 0xc2, 0x34, 0x55, 0xf3, 0xf3, 0xf1, 0x89, 0x2f, 0xc1, 0x73, 0x77,
+ /* (2^116)P */ 0xaa, 0x62, 0x79, 0xa5, 0x4d, 0x40, 0xba, 0x8c, 0x56, 0xce, 0x99, 0x19, 0xa8, 0x97, 0x98, 0x5b, 0xfc, 0x92, 0x16, 0x12, 0x2f, 0x86, 0x8e, 0x50, 0x91, 0xc2, 0x93, 0xa0, 0x7f, 0x90, 0x81, 0x3a,
+ /* (2^117)P */ 0x10, 0xa5, 0x25, 0x47, 0xff, 0xd0, 0xde, 0x0d, 0x03, 0xc5, 0x3f, 0x67, 0x10, 0xcc, 0xd8, 0x10, 0x89, 0x4e, 0x1f, 0x9f, 0x1c, 0x15, 0x9d, 0x5b, 0x4c, 0xa4, 0x09, 0xcb, 0xd5, 0xc1, 0xa5, 0x32,
+ /* (2^118)P */ 0xfb, 0x41, 0x05, 0xb9, 0x42, 0xa4, 0x0a, 0x1e, 0xdb, 0x85, 0xb4, 0xc1, 0x7c, 0xeb, 0x85, 0x5f, 0xe5, 0xf2, 0x9d, 0x8a, 0xce, 0x95, 0xe5, 0xbe, 0x36, 0x22, 0x42, 0x22, 0xc7, 0x96, 0xe4, 0x25,
+ /* (2^119)P */ 0xb9, 0xe5, 0x0f, 0xcd, 0x46, 0x3c, 0xdf, 0x5e, 0x88, 0x33, 0xa4, 0xd2, 0x7e, 0x5a, 0xe7, 0x34, 0x52, 0xe3, 0x61, 0xd7, 0x11, 0xde, 0x88, 0xe4, 0x5c, 0x54, 0x85, 0xa0, 0x01, 0x8a, 0x87, 0x0e,
+ /* (2^120)P */ 0x04, 0xbb, 0x21, 0xe0, 0x77, 0x3c, 0x49, 0xba, 0x9a, 0x89, 0xdf, 0xc7, 0x43, 0x18, 0x4d, 0x2b, 0x67, 0x0d, 0xe8, 0x7a, 0x48, 0x7a, 0xa3, 0x9e, 0x94, 0x17, 0xe4, 0x11, 0x80, 0x95, 0xa9, 0x67,
+ /* (2^121)P */ 0x65, 0xb0, 0x97, 0x66, 0x1a, 0x05, 0x58, 0x4b, 0xd4, 0xa6, 0x6b, 0x8d, 0x7d, 0x3f, 0xe3, 0x47, 0xc1, 0x46, 0xca, 0x83, 0xd4, 0xa8, 0x4d, 0xbb, 0x0d, 0xdb, 0xc2, 0x81, 0xa1, 0xca, 0xbe, 0x68,
+ /* (2^122)P */ 0xa5, 0x9a, 0x98, 0x0b, 0xe9, 0x80, 0x89, 0x8d, 0x9b, 0xc9, 0x93, 0x2c, 0x4a, 0xb1, 0x5e, 0xf9, 0xa2, 0x73, 0x6e, 0x79, 0xc4, 0xc7, 0xc6, 0x51, 0x69, 0xb5, 0xef, 0xb5, 0x63, 0x83, 0x22, 0x6e,
+ /* (2^123)P */ 0xc8, 0x24, 0xd6, 0x2d, 0xb0, 0xc0, 0xbb, 0xc6, 0xee, 0x70, 0x81, 0xec, 0x7d, 0xb4, 0x7e, 0x77, 0xa9, 0xaf, 0xcf, 0x04, 0xa0, 0x15, 0xde, 0x3c, 0x9b, 0xbf, 0x60, 0x71, 0x08, 0xbc, 0xc6, 0x1d,
+ /* (2^124)P */ 0x02, 0x40, 0xc3, 0xee, 0x43, 0xe0, 0x07, 0x2e, 0x7f, 0xdc, 0x68, 0x7a, 0x67, 0xfc, 0xe9, 0x18, 0x9a, 0x5b, 0xd1, 0x8b, 0x18, 0x03, 0xda, 0xd8, 0x53, 0x82, 0x56, 0x00, 0xbb, 0xc3, 0xfb, 0x48,
+ /* (2^125)P */ 0xe1, 0x4c, 0x65, 0xfb, 0x4c, 0x7d, 0x54, 0x57, 0xad, 0xe2, 0x58, 0xa0, 0x82, 0x5b, 0x56, 0xd3, 0x78, 0x44, 0x15, 0xbf, 0x0b, 0xaf, 0x3e, 0xf6, 0x18, 0xbb, 0xdf, 0x14, 0xf1, 0x1e, 0x53, 0x47,
+ /* (2^126)P */ 0x87, 0xc5, 0x78, 0x42, 0x0a, 0x63, 0xec, 0xe1, 0xf3, 0x83, 0x8e, 0xca, 0x46, 0xd5, 0x07, 0x55, 0x2b, 0x0c, 0xdc, 0x3a, 0xc6, 0x35, 0xe1, 0x85, 0x4e, 0x84, 0x82, 0x56, 0xa8, 0xef, 0xa7, 0x0a,
+ /* (2^127)P */ 0x15, 0xf6, 0xe1, 0xb3, 0xa8, 0x1b, 0x69, 0x72, 0xfa, 0x3f, 0xbe, 0x1f, 0x70, 0xe9, 0xb4, 0x32, 0x68, 0x78, 0xbb, 0x39, 0x2e, 0xd9, 0xb6, 0x97, 0xe8, 0x39, 0x2e, 0xa0, 0xde, 0x53, 0xfe, 0x2c,
+ /* (2^128)P */ 0xb0, 0x52, 0xcd, 0x85, 0xcd, 0x92, 0x73, 0x68, 0x31, 0x98, 0xe2, 0x10, 0xc9, 0x66, 0xff, 0x27, 0x06, 0x2d, 0x83, 0xa9, 0x56, 0x45, 0x13, 0x97, 0xa0, 0xf8, 0x84, 0x0a, 0x36, 0xb0, 0x9b, 0x26,
+ /* (2^129)P */ 0x5c, 0xf8, 0x43, 0x76, 0x45, 0x55, 0x6e, 0x70, 0x1b, 0x7d, 0x59, 0x9b, 0x8c, 0xa4, 0x34, 0x37, 0x72, 0xa4, 0xef, 0xc6, 0xe8, 0x91, 0xee, 0x7a, 0xe0, 0xd9, 0xa9, 0x98, 0xc1, 0xab, 0xd6, 0x5c,
+ /* (2^130)P */ 0x1a, 0xe4, 0x3c, 0xcb, 0x06, 0xde, 0x04, 0x0e, 0x38, 0xe1, 0x02, 0x34, 0x89, 0xeb, 0xc6, 0xd8, 0x72, 0x37, 0x6e, 0x68, 0xbb, 0x59, 0x46, 0x90, 0xc8, 0xa8, 0x6b, 0x74, 0x71, 0xc3, 0x15, 0x72,
+ /* (2^131)P */ 0xd9, 0xa2, 0xe4, 0xea, 0x7e, 0xa9, 0x12, 0xfd, 0xc5, 0xf2, 0x94, 0x63, 0x51, 0xb7, 0x14, 0x95, 0x94, 0xf2, 0x08, 0x92, 0x80, 0xd5, 0x6f, 0x26, 0xb9, 0x26, 0x9a, 0x61, 0x85, 0x70, 0x84, 0x5c,
+ /* (2^132)P */ 0xea, 0x94, 0xd6, 0xfe, 0x10, 0x54, 0x98, 0x52, 0x54, 0xd2, 0x2e, 0x4a, 0x93, 0x5b, 0x90, 0x3c, 0x67, 0xe4, 0x3b, 0x2d, 0x69, 0x47, 0xbb, 0x10, 0xe1, 0xe9, 0xe5, 0x69, 0x2d, 0x3d, 0x3b, 0x06,
+ /* (2^133)P */ 0xeb, 0x7d, 0xa5, 0xdd, 0xee, 0x26, 0x27, 0x47, 0x91, 0x18, 0xf4, 0x10, 0xae, 0xc4, 0xb6, 0xef, 0x14, 0x76, 0x30, 0x7b, 0x91, 0x41, 0x16, 0x2b, 0x7c, 0x5b, 0xf4, 0xc4, 0x4f, 0x55, 0x7c, 0x11,
+ /* (2^134)P */ 0x12, 0x88, 0x9d, 0x8f, 0x11, 0xf3, 0x7c, 0xc0, 0x39, 0x79, 0x01, 0x50, 0x20, 0xd8, 0xdb, 0x01, 0x27, 0x28, 0x1b, 0x17, 0xf4, 0x03, 0xe8, 0xd7, 0xea, 0x25, 0xd2, 0x87, 0x74, 0xe8, 0x15, 0x10,
+ /* (2^135)P */ 0x4d, 0xcc, 0x3a, 0xd2, 0xfe, 0xe3, 0x8d, 0xc5, 0x2d, 0xbe, 0xa7, 0x94, 0xc2, 0x91, 0xdb, 0x50, 0x57, 0xf4, 0x9c, 0x1c, 0x3d, 0xd4, 0x94, 0x0b, 0x4a, 0x52, 0x37, 0x6e, 0xfa, 0x40, 0x16, 0x6b,
+ /* (2^136)P */ 0x09, 0x0d, 0xda, 0x5f, 0x6c, 0x34, 0x2f, 0x69, 0x51, 0x31, 0x4d, 0xfa, 0x59, 0x1c, 0x0b, 0x20, 0x96, 0xa2, 0x77, 0x07, 0x76, 0x6f, 0xc4, 0xb8, 0xcf, 0xfb, 0xfd, 0x3f, 0x5f, 0x39, 0x38, 0x4b,
+ /* (2^137)P */ 0x71, 0xd6, 0x54, 0xbe, 0x00, 0x5e, 0xd2, 0x18, 0xa6, 0xab, 0xc8, 0xbe, 0x82, 0x05, 0xd5, 0x60, 0x82, 0xb9, 0x78, 0x3b, 0x26, 0x8f, 0xad, 0x87, 0x32, 0x04, 0xda, 0x9c, 0x4e, 0xf6, 0xfd, 0x50,
+ /* (2^138)P */ 0xf0, 0xdc, 0x78, 0xc5, 0xaa, 0x67, 0xf5, 0x90, 0x3b, 0x13, 0xa3, 0xf2, 0x0e, 0x9b, 0x1e, 0xef, 0x71, 0xde, 0xd9, 0x42, 0x92, 0xba, 0xeb, 0x0e, 0xc7, 0x01, 0x31, 0xf0, 0x9b, 0x3c, 0x47, 0x15,
+ /* (2^139)P */ 0x95, 0x80, 0xb7, 0x56, 0xae, 0xe8, 0x77, 0x7c, 0x8e, 0x07, 0x6f, 0x6e, 0x66, 0xe7, 0x78, 0xb6, 0x1f, 0xba, 0x48, 0x53, 0x61, 0xb9, 0xa0, 0x2d, 0x0b, 0x3f, 0x73, 0xff, 0xc1, 0x31, 0xf9, 0x7c,
+ /* (2^140)P */ 0x6c, 0x36, 0x0a, 0x0a, 0xf5, 0x57, 0xb3, 0x26, 0x32, 0xd7, 0x87, 0x2b, 0xf4, 0x8c, 0x70, 0xe9, 0xc0, 0xb2, 0x1c, 0xf9, 0xa5, 0xee, 0x3a, 0xc1, 0x4c, 0xbb, 0x43, 0x11, 0x99, 0x0c, 0xd9, 0x35,
+ /* (2^141)P */ 0xdc, 0xd9, 0xa0, 0xa9, 0x04, 0xc4, 0xc1, 0x47, 0x51, 0xd2, 0x72, 0x19, 0x45, 0x58, 0x9e, 0x65, 0x31, 0x8c, 0xb3, 0x73, 0xc4, 0xa8, 0x75, 0x38, 0x24, 0x1f, 0x56, 0x79, 0xd3, 0x9e, 0xbd, 0x1f,
+ /* (2^142)P */ 0x8d, 0xc2, 0x1e, 0xd4, 0x6f, 0xbc, 0xfa, 0x11, 0xca, 0x2d, 0x2a, 0xcd, 0xe3, 0xdf, 0xf8, 0x7e, 0x95, 0x45, 0x40, 0x8c, 0x5d, 0x3b, 0xe7, 0x72, 0x27, 0x2f, 0xb7, 0x54, 0x49, 0xfa, 0x35, 0x61,
+ /* (2^143)P */ 0x9c, 0xb6, 0x24, 0xde, 0xa2, 0x32, 0xfc, 0xcc, 0x88, 0x5d, 0x09, 0x1f, 0x8c, 0x69, 0x55, 0x3f, 0x29, 0xf9, 0xc3, 0x5a, 0xed, 0x50, 0x33, 0xbe, 0xeb, 0x7e, 0x47, 0xca, 0x06, 0xf8, 0x9b, 0x5e,
+ /* (2^144)P */ 0x68, 0x9f, 0x30, 0x3c, 0xb6, 0x8f, 0xce, 0xe9, 0xf4, 0xf9, 0xe1, 0x65, 0x35, 0xf6, 0x76, 0x53, 0xf1, 0x93, 0x63, 0x5a, 0xb3, 0xcf, 0xaf, 0xd1, 0x06, 0x35, 0x62, 0xe5, 0xed, 0xa1, 0x32, 0x66,
+ /* (2^145)P */ 0x4c, 0xed, 0x2d, 0x0c, 0x39, 0x6c, 0x7d, 0x0b, 0x1f, 0xcb, 0x04, 0xdf, 0x81, 0x32, 0xcb, 0x56, 0xc7, 0xc3, 0xec, 0x49, 0x12, 0x5a, 0x30, 0x66, 0x2a, 0xa7, 0x8c, 0xa3, 0x60, 0x8b, 0x58, 0x5d,
+ /* (2^146)P */ 0x2d, 0xf4, 0xe5, 0xe8, 0x78, 0xbf, 0xec, 0xa6, 0xec, 0x3e, 0x8a, 0x3c, 0x4b, 0xb4, 0xee, 0x86, 0x04, 0x16, 0xd2, 0xfb, 0x48, 0x9c, 0x21, 0xec, 0x31, 0x67, 0xc3, 0x17, 0xf5, 0x1a, 0xaf, 0x1a,
+ /* (2^147)P */ 0xe7, 0xbd, 0x69, 0x67, 0x83, 0xa2, 0x06, 0xc3, 0xdb, 0x2a, 0x1e, 0x2b, 0x62, 0x80, 0x82, 0x20, 0xa6, 0x94, 0xff, 0xfb, 0x1f, 0xf5, 0x27, 0x80, 0x6b, 0xf2, 0x24, 0x11, 0xce, 0xa1, 0xcf, 0x76,
+ /* (2^148)P */ 0xb6, 0xab, 0x22, 0x24, 0x56, 0x00, 0xeb, 0x18, 0xc3, 0x29, 0x8c, 0x8f, 0xd5, 0xc4, 0x77, 0xf3, 0x1a, 0x56, 0x31, 0xf5, 0x07, 0xc2, 0xbb, 0x4d, 0x27, 0x8a, 0x12, 0x82, 0xf0, 0xb7, 0x53, 0x02,
+ /* (2^149)P */ 0xe0, 0x17, 0x2c, 0xb6, 0x1c, 0x09, 0x1f, 0x3d, 0xa9, 0x28, 0x46, 0xd6, 0xab, 0xe1, 0x60, 0x48, 0x53, 0x42, 0x9d, 0x30, 0x36, 0x74, 0xd1, 0x52, 0x76, 0xe5, 0xfa, 0x3e, 0xe1, 0x97, 0x6f, 0x35,
+ /* (2^150)P */ 0x5b, 0x53, 0x50, 0xa1, 0x1a, 0xe1, 0x51, 0xd3, 0xcc, 0x78, 0xd8, 0x1d, 0xbb, 0x45, 0x6b, 0x3e, 0x98, 0x2c, 0xd9, 0xbe, 0x28, 0x61, 0x77, 0x0c, 0xb8, 0x85, 0x28, 0x03, 0x93, 0xae, 0x34, 0x1d,
+ /* (2^151)P */ 0xc3, 0xa4, 0x5b, 0xa8, 0x8c, 0x48, 0xa0, 0x4b, 0xce, 0xe6, 0x9c, 0x3c, 0xc3, 0x48, 0x53, 0x98, 0x70, 0xa7, 0xbd, 0x97, 0x6f, 0x4c, 0x12, 0x66, 0x4a, 0x12, 0x54, 0x06, 0x29, 0xa0, 0x81, 0x0f,
+ /* (2^152)P */ 0xfd, 0x86, 0x9b, 0x56, 0xa6, 0x9c, 0xd0, 0x9e, 0x2d, 0x9a, 0xaf, 0x18, 0xfd, 0x09, 0x10, 0x81, 0x0a, 0xc2, 0xd8, 0x93, 0x3f, 0xd0, 0x08, 0xff, 0x6b, 0xf2, 0xae, 0x9f, 0x19, 0x48, 0xa1, 0x52,
+ /* (2^153)P */ 0x73, 0x1b, 0x8d, 0x2d, 0xdc, 0xf9, 0x03, 0x3e, 0x70, 0x1a, 0x96, 0x73, 0x18, 0x80, 0x05, 0x42, 0x70, 0x59, 0xa3, 0x41, 0xf0, 0x87, 0xd9, 0xc0, 0x49, 0xd5, 0xc0, 0xa1, 0x15, 0x1f, 0xaa, 0x07,
+ /* (2^154)P */ 0x24, 0x72, 0xd2, 0x8c, 0xe0, 0x6c, 0xd4, 0xdf, 0x39, 0x42, 0x4e, 0x93, 0x4f, 0x02, 0x0a, 0x6d, 0x59, 0x7b, 0x89, 0x99, 0x63, 0x7a, 0x8a, 0x80, 0xa2, 0x95, 0x3d, 0xe1, 0xe9, 0x56, 0x45, 0x0a,
+ /* (2^155)P */ 0x45, 0x30, 0xc1, 0xe9, 0x1f, 0x99, 0x1a, 0xd2, 0xb8, 0x51, 0x77, 0xfe, 0x48, 0x85, 0x0e, 0x9b, 0x35, 0x00, 0xf3, 0x4b, 0xcb, 0x43, 0xa6, 0x5d, 0x21, 0xf7, 0x40, 0x39, 0xd6, 0x28, 0xdb, 0x77,
+ /* (2^156)P */ 0x11, 0x90, 0xdc, 0x4a, 0x61, 0xeb, 0x5e, 0xfc, 0xeb, 0x11, 0xc4, 0xe8, 0x9a, 0x41, 0x29, 0x52, 0x74, 0xcf, 0x1d, 0x7d, 0x78, 0xe7, 0xc3, 0x9e, 0xb5, 0x4c, 0x6e, 0x21, 0x3e, 0x05, 0x0d, 0x34,
+ /* (2^157)P */ 0xb4, 0xf2, 0x8d, 0xb4, 0x39, 0xaf, 0xc7, 0xca, 0x94, 0x0a, 0xa1, 0x71, 0x28, 0xec, 0xfa, 0xc0, 0xed, 0x75, 0xa5, 0x5c, 0x24, 0x69, 0x0a, 0x14, 0x4c, 0x3a, 0x27, 0x34, 0x71, 0xc3, 0xf1, 0x0c,
+ /* (2^158)P */ 0xa5, 0xb8, 0x24, 0xc2, 0x6a, 0x30, 0xee, 0xc8, 0xb0, 0x30, 0x49, 0xcb, 0x7c, 0xee, 0xea, 0x57, 0x4f, 0xe7, 0xcb, 0xaa, 0xbd, 0x06, 0xe8, 0xa1, 0x7d, 0x65, 0xeb, 0x2e, 0x74, 0x62, 0x9a, 0x7d,
+ /* (2^159)P */ 0x30, 0x48, 0x6c, 0x54, 0xef, 0xb6, 0xb6, 0x9e, 0x2e, 0x6e, 0xb3, 0xdd, 0x1f, 0xca, 0x5c, 0x88, 0x05, 0x71, 0x0d, 0xef, 0x83, 0xf3, 0xb9, 0xe6, 0x12, 0x04, 0x2e, 0x9d, 0xef, 0x4f, 0x65, 0x58,
+ /* (2^160)P */ 0x26, 0x8e, 0x0e, 0xbe, 0xff, 0xc4, 0x05, 0xa9, 0x6e, 0x81, 0x31, 0x9b, 0xdf, 0xe5, 0x2d, 0x94, 0xe1, 0x88, 0x2e, 0x80, 0x3f, 0x72, 0x7d, 0x49, 0x8d, 0x40, 0x2f, 0x60, 0xea, 0x4d, 0x68, 0x30,
+ /* (2^161)P */ 0x34, 0xcb, 0xe6, 0xa3, 0x78, 0xa2, 0xe5, 0x21, 0xc4, 0x1d, 0x15, 0x5b, 0x6f, 0x6e, 0xfb, 0xae, 0x15, 0xca, 0x77, 0x9d, 0x04, 0x8e, 0x0b, 0xb3, 0x81, 0x89, 0xb9, 0x53, 0xcf, 0xc9, 0xc3, 0x28,
+ /* (2^162)P */ 0x2a, 0xdd, 0x6c, 0x55, 0x21, 0xb7, 0x7f, 0x28, 0x74, 0x22, 0x02, 0x97, 0xa8, 0x7c, 0x31, 0x0d, 0x58, 0x32, 0x54, 0x3a, 0x42, 0xc7, 0x68, 0x74, 0x2f, 0x64, 0xb5, 0x4e, 0x46, 0x11, 0x7f, 0x4a,
+ /* (2^163)P */ 0xa6, 0x3a, 0x19, 0x4d, 0x77, 0xa4, 0x37, 0xa2, 0xa1, 0x29, 0x21, 0xa9, 0x6e, 0x98, 0x65, 0xd8, 0x88, 0x1a, 0x7c, 0xf8, 0xec, 0x15, 0xc5, 0x24, 0xeb, 0xf5, 0x39, 0x5f, 0x57, 0x03, 0x40, 0x60,
+ /* (2^164)P */ 0x27, 0x9b, 0x0a, 0x57, 0x89, 0xf1, 0xb9, 0x47, 0x78, 0x4b, 0x5e, 0x46, 0xde, 0xce, 0x98, 0x2b, 0x20, 0x5c, 0xb8, 0xdb, 0x51, 0xf5, 0x6d, 0x02, 0x01, 0x19, 0xe2, 0x47, 0x10, 0xd9, 0xfc, 0x74,
+ /* (2^165)P */ 0xa3, 0xbf, 0xc1, 0x23, 0x0a, 0xa9, 0xe2, 0x13, 0xf6, 0x19, 0x85, 0x47, 0x4e, 0x07, 0xb0, 0x0c, 0x44, 0xcf, 0xf6, 0x3a, 0xbe, 0xcb, 0xf1, 0x5f, 0xbe, 0x2d, 0x81, 0xbe, 0x38, 0x54, 0xfe, 0x67,
+ /* (2^166)P */ 0xb0, 0x05, 0x0f, 0xa4, 0x4f, 0xf6, 0x3c, 0xd1, 0x87, 0x37, 0x28, 0x32, 0x2f, 0xfb, 0x4d, 0x05, 0xea, 0x2a, 0x0d, 0x7f, 0x5b, 0x91, 0x73, 0x41, 0x4e, 0x0d, 0x61, 0x1f, 0x4f, 0x14, 0x2f, 0x48,
+ /* (2^167)P */ 0x34, 0x82, 0x7f, 0xb4, 0x01, 0x02, 0x21, 0xf6, 0x90, 0xb9, 0x70, 0x9e, 0x92, 0xe1, 0x0a, 0x5d, 0x7c, 0x56, 0x49, 0xb0, 0x55, 0xf4, 0xd7, 0xdc, 0x01, 0x6f, 0x91, 0xf0, 0xf1, 0xd0, 0x93, 0x7e,
+ /* (2^168)P */ 0xfa, 0xb4, 0x7d, 0x8a, 0xf1, 0xcb, 0x79, 0xdd, 0x2f, 0xc6, 0x74, 0x6f, 0xbf, 0x91, 0x83, 0xbe, 0xbd, 0x91, 0x82, 0x4b, 0xd1, 0x45, 0x71, 0x02, 0x05, 0x17, 0xbf, 0x2c, 0xea, 0x73, 0x5a, 0x58,
+ /* (2^169)P */ 0xb2, 0x0d, 0x8a, 0x92, 0x3e, 0xa0, 0x5c, 0x48, 0xe7, 0x57, 0x28, 0x74, 0xa5, 0x01, 0xfc, 0x10, 0xa7, 0x51, 0xd5, 0xd6, 0xdb, 0x2e, 0x48, 0x2f, 0x8a, 0xdb, 0x8f, 0x04, 0xb5, 0x33, 0x04, 0x0f,
+ /* (2^170)P */ 0x47, 0x62, 0xdc, 0xd7, 0x8d, 0x2e, 0xda, 0x60, 0x9a, 0x81, 0xd4, 0x8c, 0xd3, 0xc9, 0xb4, 0x88, 0x97, 0x66, 0xf6, 0x01, 0xc0, 0x3a, 0x03, 0x13, 0x75, 0x7d, 0x36, 0x3b, 0xfe, 0x24, 0x3b, 0x27,
+ /* (2^171)P */ 0xd4, 0xb9, 0xb3, 0x31, 0x6a, 0xf6, 0xe8, 0xc6, 0xd5, 0x49, 0xdf, 0x94, 0xa4, 0x14, 0x15, 0x28, 0xa7, 0x3d, 0xb2, 0xc8, 0xdf, 0x6f, 0x72, 0xd1, 0x48, 0xe5, 0xde, 0x03, 0xd1, 0xe7, 0x3a, 0x4b,
+ /* (2^172)P */ 0x7e, 0x9d, 0x4b, 0xce, 0x19, 0x6e, 0x25, 0xc6, 0x1c, 0xc6, 0xe3, 0x86, 0xf1, 0x5c, 0x5c, 0xff, 0x45, 0xc1, 0x8e, 0x4b, 0xa3, 0x3c, 0xc6, 0xac, 0x74, 0x65, 0xe6, 0xfe, 0x88, 0x18, 0x62, 0x74,
+ /* (2^173)P */ 0x1e, 0x0a, 0x29, 0x45, 0x96, 0x40, 0x6f, 0x95, 0x2e, 0x96, 0x3a, 0x26, 0xe3, 0xf8, 0x0b, 0xef, 0x7b, 0x64, 0xc2, 0x5e, 0xeb, 0x50, 0x6a, 0xed, 0x02, 0x75, 0xca, 0x9d, 0x3a, 0x28, 0x94, 0x06,
+ /* (2^174)P */ 0xd1, 0xdc, 0xa2, 0x43, 0x36, 0x96, 0x9b, 0x76, 0x53, 0x53, 0xfc, 0x09, 0xea, 0xc8, 0xb7, 0x42, 0xab, 0x7e, 0x39, 0x13, 0xee, 0x2a, 0x00, 0x4f, 0x3a, 0xd6, 0xb7, 0x19, 0x2c, 0x5e, 0x00, 0x63,
+ /* (2^175)P */ 0xea, 0x3b, 0x02, 0x63, 0xda, 0x36, 0x67, 0xca, 0xb7, 0x99, 0x2a, 0xb1, 0x6d, 0x7f, 0x6c, 0x96, 0xe1, 0xc5, 0x37, 0xc5, 0x90, 0x93, 0xe0, 0xac, 0xee, 0x89, 0xaa, 0xa1, 0x63, 0x60, 0x69, 0x0b,
+ /* (2^176)P */ 0xe5, 0x56, 0x8c, 0x28, 0x97, 0x3e, 0xb0, 0xeb, 0xe8, 0x8b, 0x8c, 0x93, 0x9f, 0x9f, 0x2a, 0x43, 0x71, 0x7f, 0x71, 0x5b, 0x3d, 0xa9, 0xa5, 0xa6, 0x97, 0x9d, 0x8f, 0xe1, 0xc3, 0xb4, 0x5f, 0x1a,
+ /* (2^177)P */ 0xce, 0xcd, 0x60, 0x1c, 0xad, 0xe7, 0x94, 0x1c, 0xa0, 0xc4, 0x02, 0xfc, 0x43, 0x2a, 0x20, 0xee, 0x20, 0x6a, 0xc4, 0x67, 0xd8, 0xe4, 0xaf, 0x8d, 0x58, 0x7b, 0xc2, 0x8a, 0x3c, 0x26, 0x10, 0x0a,
+ /* (2^178)P */ 0x4a, 0x2a, 0x43, 0xe4, 0xdf, 0xa9, 0xde, 0xd0, 0xc5, 0x77, 0x92, 0xbe, 0x7b, 0xf8, 0x6a, 0x85, 0x1a, 0xc7, 0x12, 0xc2, 0xac, 0x72, 0x84, 0xce, 0x91, 0x1e, 0xbb, 0x9b, 0x6d, 0x1b, 0x15, 0x6f,
+ /* (2^179)P */ 0x6a, 0xd5, 0xee, 0x7c, 0x52, 0x6c, 0x77, 0x26, 0xec, 0xfa, 0xf8, 0xfb, 0xb7, 0x1c, 0x21, 0x7d, 0xcc, 0x09, 0x46, 0xfd, 0xa6, 0x66, 0xae, 0x37, 0x42, 0x0c, 0x77, 0xd2, 0x02, 0xb7, 0x81, 0x1f,
+ /* (2^180)P */ 0x92, 0x83, 0xc5, 0xea, 0x57, 0xb0, 0xb0, 0x2f, 0x9d, 0x4e, 0x74, 0x29, 0xfe, 0x89, 0xdd, 0xe1, 0xf8, 0xb4, 0xbe, 0x17, 0xeb, 0xf8, 0x64, 0xc9, 0x1e, 0xd4, 0xa2, 0xc9, 0x73, 0x10, 0x57, 0x29,
+ /* (2^181)P */ 0x54, 0xe2, 0xc0, 0x81, 0x89, 0xa1, 0x48, 0xa9, 0x30, 0x28, 0xb2, 0x65, 0x9b, 0x36, 0xf6, 0x2d, 0xc6, 0xd3, 0xcf, 0x5f, 0xd7, 0xb2, 0x3e, 0xa3, 0x1f, 0xa0, 0x99, 0x41, 0xec, 0xd6, 0x8c, 0x07,
+ /* (2^182)P */ 0x2f, 0x0d, 0x90, 0xad, 0x41, 0x4a, 0x58, 0x4a, 0x52, 0x4c, 0xc7, 0xe2, 0x78, 0x2b, 0x14, 0x32, 0x78, 0xc9, 0x31, 0x84, 0x33, 0xe8, 0xc4, 0x68, 0xc2, 0x9f, 0x68, 0x08, 0x90, 0xea, 0x69, 0x7f,
+ /* (2^183)P */ 0x65, 0x82, 0xa3, 0x46, 0x1e, 0xc8, 0xf2, 0x52, 0xfd, 0x32, 0xa8, 0x04, 0x2d, 0x07, 0x78, 0xfd, 0x94, 0x9e, 0x35, 0x25, 0xfa, 0xd5, 0xd7, 0x8c, 0xd2, 0x29, 0xcc, 0x54, 0x74, 0x1b, 0xe7, 0x4d,
+ /* (2^184)P */ 0xc9, 0x6a, 0xda, 0x1e, 0xad, 0x60, 0xeb, 0x42, 0x3a, 0x9c, 0xc0, 0xdb, 0xdf, 0x37, 0xad, 0x0a, 0x91, 0xc1, 0x3c, 0xe3, 0x71, 0x4b, 0x00, 0x81, 0x3c, 0x80, 0x22, 0x51, 0x34, 0xbe, 0xe6, 0x44,
+ /* (2^185)P */ 0xdb, 0x20, 0x19, 0xba, 0x88, 0x83, 0xfe, 0x03, 0x08, 0xb0, 0x0d, 0x15, 0x32, 0x7c, 0xd5, 0xf5, 0x29, 0x0c, 0xf6, 0x1a, 0x28, 0xc4, 0xc8, 0x49, 0xee, 0x1a, 0x70, 0xde, 0x18, 0xb5, 0xed, 0x21,
+ /* (2^186)P */ 0x99, 0xdc, 0x06, 0x8f, 0x41, 0x3e, 0xb6, 0x7f, 0xb8, 0xd7, 0x66, 0xc1, 0x99, 0x0d, 0x46, 0xa4, 0x83, 0x0a, 0x52, 0xce, 0x48, 0x52, 0xdd, 0x24, 0x58, 0x83, 0x92, 0x2b, 0x71, 0xad, 0xc3, 0x5e,
+ /* (2^187)P */ 0x0f, 0x93, 0x17, 0xbd, 0x5f, 0x2a, 0x02, 0x15, 0xe3, 0x70, 0x25, 0xd8, 0x77, 0x4a, 0xf6, 0xa4, 0x12, 0x37, 0x78, 0x15, 0x69, 0x8d, 0xbc, 0x12, 0xbb, 0x0a, 0x62, 0xfc, 0xc0, 0x94, 0x81, 0x49,
+ /* (2^188)P */ 0x82, 0x6c, 0x68, 0x55, 0xd2, 0xd9, 0xa2, 0x38, 0xf0, 0x21, 0x3e, 0x19, 0xd9, 0x6b, 0x5c, 0x78, 0x84, 0x54, 0x4a, 0xb2, 0x1a, 0xc8, 0xd5, 0xe4, 0x89, 0x09, 0xe2, 0xb2, 0x60, 0x78, 0x30, 0x56,
+ /* (2^189)P */ 0xc4, 0x74, 0x4d, 0x8b, 0xf7, 0x55, 0x9d, 0x42, 0x31, 0x01, 0x35, 0x43, 0x46, 0x83, 0xf1, 0x22, 0xff, 0x1f, 0xc7, 0x98, 0x45, 0xc2, 0x60, 0x1e, 0xef, 0x83, 0x99, 0x97, 0x14, 0xf0, 0xf2, 0x59,
+ /* (2^190)P */ 0x44, 0x4a, 0x49, 0xeb, 0x56, 0x7d, 0xa4, 0x46, 0x8e, 0xa1, 0x36, 0xd6, 0x54, 0xa8, 0x22, 0x3e, 0x3b, 0x1c, 0x49, 0x74, 0x52, 0xe1, 0x46, 0xb3, 0xe7, 0xcd, 0x90, 0x53, 0x4e, 0xfd, 0xea, 0x2c,
+ /* (2^191)P */ 0x75, 0x66, 0x0d, 0xbe, 0x38, 0x85, 0x8a, 0xba, 0x23, 0x8e, 0x81, 0x50, 0xbb, 0x74, 0x90, 0x4b, 0xc3, 0x04, 0xd3, 0x85, 0x90, 0xb8, 0xda, 0xcb, 0xc4, 0x92, 0x61, 0xe5, 0xe0, 0x4f, 0xa2, 0x61,
+ /* (2^192)P */ 0xcb, 0x5b, 0x52, 0xdb, 0xe6, 0x15, 0x76, 0xcb, 0xca, 0xe4, 0x67, 0xa5, 0x35, 0x8c, 0x7d, 0xdd, 0x69, 0xdd, 0xfc, 0xca, 0x3a, 0x15, 0xb4, 0xe6, 0x66, 0x97, 0x3c, 0x7f, 0x09, 0x8e, 0x66, 0x2d,
+ /* (2^193)P */ 0xf0, 0x5e, 0xe5, 0x5c, 0x26, 0x7e, 0x7e, 0xa5, 0x67, 0xb9, 0xd4, 0x7c, 0x52, 0x4e, 0x9f, 0x5d, 0xe5, 0xd1, 0x2f, 0x49, 0x06, 0x36, 0xc8, 0xfb, 0xae, 0xf7, 0xc3, 0xb7, 0xbe, 0x52, 0x0d, 0x09,
+ /* (2^194)P */ 0x7c, 0x4d, 0x7b, 0x1e, 0x5a, 0x51, 0xb9, 0x09, 0xc0, 0x44, 0xda, 0x99, 0x25, 0x6a, 0x26, 0x1f, 0x04, 0x55, 0xc5, 0xe2, 0x48, 0x95, 0xc4, 0xa1, 0xcc, 0x15, 0x6f, 0x12, 0x87, 0x42, 0xf0, 0x7e,
+ /* (2^195)P */ 0x15, 0xef, 0x30, 0xbd, 0x9d, 0x65, 0xd1, 0xfe, 0x7b, 0x27, 0xe0, 0xc4, 0xee, 0xb9, 0x4a, 0x8b, 0x91, 0x32, 0xdf, 0xa5, 0x36, 0x62, 0x4d, 0x88, 0x88, 0xf7, 0x5c, 0xbf, 0xa6, 0x6e, 0xd9, 0x1f,
+ /* (2^196)P */ 0x9a, 0x0d, 0x19, 0x1f, 0x98, 0x61, 0xa1, 0x42, 0xc1, 0x52, 0x60, 0x7e, 0x50, 0x49, 0xd8, 0x61, 0xd5, 0x2c, 0x5a, 0x28, 0xbf, 0x13, 0xe1, 0x9f, 0xd8, 0x85, 0xad, 0xdb, 0x76, 0xd6, 0x22, 0x7c,
+ /* (2^197)P */ 0x7d, 0xd2, 0xfb, 0x2b, 0xed, 0x70, 0xe7, 0x82, 0xa5, 0xf5, 0x96, 0xe9, 0xec, 0xb2, 0x05, 0x4c, 0x50, 0x01, 0x90, 0xb0, 0xc2, 0xa9, 0x40, 0xcd, 0x64, 0xbf, 0xd9, 0x13, 0x92, 0x31, 0x95, 0x58,
+ /* (2^198)P */ 0x08, 0x2e, 0xea, 0x3f, 0x70, 0x5d, 0xcc, 0xe7, 0x8c, 0x18, 0xe2, 0x58, 0x12, 0x49, 0x0c, 0xb5, 0xf0, 0x5b, 0x20, 0x48, 0xaa, 0x0b, 0xe3, 0xcc, 0x62, 0x2d, 0xa3, 0xcf, 0x9c, 0x65, 0x7c, 0x53,
+ /* (2^199)P */ 0x88, 0xc0, 0xcf, 0x98, 0x3a, 0x62, 0xb6, 0x37, 0xa4, 0xac, 0xd6, 0xa4, 0x1f, 0xed, 0x9b, 0xfe, 0xb0, 0xd1, 0xa8, 0x56, 0x8e, 0x9b, 0xd2, 0x04, 0x75, 0x95, 0x51, 0x0b, 0xc4, 0x71, 0x5f, 0x72,
+ /* (2^200)P */ 0xe6, 0x9c, 0x33, 0xd0, 0x9c, 0xf8, 0xc7, 0x28, 0x8b, 0xc1, 0xdd, 0x69, 0x44, 0xb1, 0x67, 0x83, 0x2c, 0x65, 0xa1, 0xa6, 0x83, 0xda, 0x3a, 0x88, 0x17, 0x6c, 0x4d, 0x03, 0x74, 0x19, 0x5f, 0x58,
+ /* (2^201)P */ 0x88, 0x91, 0xb1, 0xf1, 0x66, 0xb2, 0xcf, 0x89, 0x17, 0x52, 0xc3, 0xe7, 0x63, 0x48, 0x3b, 0xe6, 0x6a, 0x52, 0xc0, 0xb4, 0xa6, 0x9d, 0x8c, 0xd8, 0x35, 0x46, 0x95, 0xf0, 0x9d, 0x5c, 0x03, 0x3e,
+ /* (2^202)P */ 0x9d, 0xde, 0x45, 0xfb, 0x12, 0x54, 0x9d, 0xdd, 0x0d, 0xf4, 0xcf, 0xe4, 0x32, 0x45, 0x68, 0xdd, 0x1c, 0x67, 0x1d, 0x15, 0x9b, 0x99, 0x5c, 0x4b, 0x90, 0xf6, 0xe7, 0x11, 0xc8, 0x2c, 0x8c, 0x2d,
+ /* (2^203)P */ 0x40, 0x5d, 0x05, 0x90, 0x1d, 0xbe, 0x54, 0x7f, 0x40, 0xaf, 0x4a, 0x46, 0xdf, 0xc5, 0x64, 0xa4, 0xbe, 0x17, 0xe9, 0xf0, 0x24, 0x96, 0x97, 0x33, 0x30, 0x6b, 0x35, 0x27, 0xc5, 0x8d, 0x01, 0x2c,
+ /* (2^204)P */ 0xd4, 0xb3, 0x30, 0xe3, 0x24, 0x50, 0x41, 0xa5, 0xd3, 0x52, 0x16, 0x69, 0x96, 0x3d, 0xff, 0x73, 0xf1, 0x59, 0x9b, 0xef, 0xc4, 0x42, 0xec, 0x94, 0x5a, 0x8e, 0xd0, 0x18, 0x16, 0x20, 0x47, 0x07,
+ /* (2^205)P */ 0x53, 0x1c, 0x41, 0xca, 0x8a, 0xa4, 0x6c, 0x4d, 0x19, 0x61, 0xa6, 0xcf, 0x2f, 0x5f, 0x41, 0x66, 0xff, 0x27, 0xe2, 0x51, 0x00, 0xd4, 0x4d, 0x9c, 0xeb, 0xf7, 0x02, 0x9a, 0xc0, 0x0b, 0x81, 0x59,
+ /* (2^206)P */ 0x1d, 0x10, 0xdc, 0xb3, 0x71, 0xb1, 0x7e, 0x2a, 0x8e, 0xf6, 0xfe, 0x9f, 0xb9, 0x5a, 0x1c, 0x44, 0xea, 0x59, 0xb3, 0x93, 0x9b, 0x5c, 0x02, 0x32, 0x2f, 0x11, 0x9d, 0x1e, 0xa7, 0xe0, 0x8c, 0x5e,
+ /* (2^207)P */ 0xfd, 0x03, 0x95, 0x42, 0x92, 0xcb, 0xcc, 0xbf, 0x55, 0x5d, 0x09, 0x2f, 0x75, 0xba, 0x71, 0xd2, 0x1e, 0x09, 0x2d, 0x97, 0x5e, 0xad, 0x5e, 0x34, 0xba, 0x03, 0x31, 0xa8, 0x11, 0xdf, 0xc8, 0x18,
+ /* (2^208)P */ 0x4c, 0x0f, 0xed, 0x9a, 0x9a, 0x94, 0xcd, 0x90, 0x7e, 0xe3, 0x60, 0x66, 0xcb, 0xf4, 0xd1, 0xc5, 0x0b, 0x2e, 0xc5, 0x56, 0x2d, 0xc5, 0xca, 0xb8, 0x0d, 0x8e, 0x80, 0xc5, 0x00, 0xe4, 0x42, 0x6e,
+ /* (2^209)P */ 0x23, 0xfd, 0xae, 0xee, 0x66, 0x69, 0xb4, 0xa3, 0xca, 0xcd, 0x9e, 0xe3, 0x0b, 0x1f, 0x4f, 0x0c, 0x1d, 0xa5, 0x83, 0xd6, 0xc9, 0xc8, 0x9d, 0x18, 0x1b, 0x35, 0x09, 0x4c, 0x05, 0x7f, 0xf2, 0x51,
+ /* (2^210)P */ 0x82, 0x06, 0x32, 0x2a, 0xcd, 0x7c, 0x48, 0x4c, 0x96, 0x1c, 0xdf, 0xb3, 0x5b, 0xa9, 0x7e, 0x58, 0xe8, 0xb8, 0x5c, 0x55, 0x9e, 0xf7, 0xcc, 0xc8, 0x3d, 0xd7, 0x06, 0xa2, 0x29, 0xc8, 0x7d, 0x54,
+ /* (2^211)P */ 0x06, 0x9b, 0xc3, 0x80, 0xcd, 0xa6, 0x22, 0xb8, 0xc6, 0xd4, 0x00, 0x20, 0x73, 0x54, 0x6d, 0xe9, 0x4d, 0x3b, 0x46, 0x91, 0x6f, 0x5b, 0x53, 0x28, 0x1d, 0x6e, 0x48, 0xe2, 0x60, 0x46, 0x8f, 0x22,
+ /* (2^212)P */ 0xbf, 0x3a, 0x8d, 0xde, 0x38, 0x95, 0x79, 0x98, 0x6e, 0xca, 0xeb, 0x45, 0x00, 0x33, 0xd8, 0x8c, 0x38, 0xe7, 0x21, 0x82, 0x00, 0x2a, 0x95, 0x79, 0xbb, 0xd2, 0x5c, 0x53, 0xa7, 0xe1, 0x22, 0x43,
+ /* (2^213)P */ 0x1c, 0x80, 0xd1, 0x19, 0x18, 0xc1, 0x14, 0xb1, 0xc7, 0x5e, 0x3f, 0x4f, 0xd8, 0xe4, 0x16, 0x20, 0x4c, 0x0f, 0x26, 0x09, 0xf4, 0x2d, 0x0e, 0xdd, 0x66, 0x72, 0x5f, 0xae, 0xc0, 0x62, 0xc3, 0x5e,
+ /* (2^214)P */ 0xee, 0xb4, 0xb2, 0xb8, 0x18, 0x2b, 0x46, 0xc0, 0xfb, 0x1a, 0x4d, 0x27, 0x50, 0xd9, 0xc8, 0x7c, 0xd2, 0x02, 0x6b, 0x43, 0x05, 0x71, 0x5f, 0xf2, 0xd3, 0xcc, 0xf9, 0xbf, 0xdc, 0xf8, 0xbb, 0x43,
+ /* (2^215)P */ 0xdf, 0xe9, 0x39, 0xa0, 0x67, 0x17, 0xad, 0xb6, 0x83, 0x35, 0x9d, 0xf6, 0xa8, 0x4d, 0x71, 0xb0, 0xf5, 0x31, 0x29, 0xb4, 0x18, 0xfa, 0x55, 0x5e, 0x61, 0x09, 0xc6, 0x33, 0x8f, 0x55, 0xd5, 0x4e,
+ /* (2^216)P */ 0xdd, 0xa5, 0x47, 0xc6, 0x01, 0x79, 0xe3, 0x1f, 0x57, 0xd3, 0x81, 0x80, 0x1f, 0xdf, 0x3d, 0x59, 0xa6, 0xd7, 0x3f, 0x81, 0xfd, 0xa4, 0x49, 0x02, 0x61, 0xaf, 0x9c, 0x4e, 0x27, 0xca, 0xac, 0x69,
+ /* (2^217)P */ 0xc9, 0x21, 0x07, 0x33, 0xea, 0xa3, 0x7b, 0x04, 0xa0, 0x1e, 0x7e, 0x0e, 0xc2, 0x3f, 0x42, 0x83, 0x60, 0x4a, 0x31, 0x01, 0xaf, 0xc0, 0xf4, 0x1d, 0x27, 0x95, 0x28, 0x89, 0xab, 0x2d, 0xa6, 0x09,
+ /* (2^218)P */ 0x00, 0xcb, 0xc6, 0x9c, 0xa4, 0x25, 0xb3, 0xa5, 0xb6, 0x6c, 0xb5, 0x54, 0xc6, 0x5d, 0x4b, 0xe9, 0xa0, 0x94, 0xc9, 0xad, 0x79, 0x87, 0xe2, 0x3b, 0xad, 0x4a, 0x3a, 0xba, 0xf8, 0xe8, 0x96, 0x42,
+ /* (2^219)P */ 0xab, 0x1e, 0x45, 0x1e, 0x76, 0x89, 0x86, 0x32, 0x4a, 0x59, 0x59, 0xff, 0x8b, 0x59, 0x4d, 0x2e, 0x4a, 0x08, 0xa7, 0xd7, 0x53, 0x68, 0xb9, 0x49, 0xa8, 0x20, 0x14, 0x60, 0x19, 0xa3, 0x80, 0x49,
+ /* (2^220)P */ 0x42, 0x2c, 0x55, 0x2f, 0xe1, 0xb9, 0x65, 0x95, 0x96, 0xfe, 0x00, 0x71, 0xdb, 0x18, 0x53, 0x8a, 0xd7, 0xd0, 0xad, 0x43, 0x4d, 0x0b, 0xc9, 0x05, 0xda, 0x4e, 0x5d, 0x6a, 0xd6, 0x4c, 0x8b, 0x53,
+ /* (2^221)P */ 0x9f, 0x03, 0x9f, 0xe8, 0xc3, 0x4f, 0xe9, 0xf4, 0x45, 0x80, 0x61, 0x6f, 0xf2, 0x9a, 0x2c, 0x59, 0x50, 0x95, 0x4b, 0xfd, 0xb5, 0x6e, 0xa3, 0x08, 0x19, 0x14, 0xed, 0xc2, 0xf6, 0xfa, 0xff, 0x25,
+ /* (2^222)P */ 0x54, 0xd3, 0x79, 0xcc, 0x59, 0x44, 0x43, 0x34, 0x6b, 0x47, 0xd5, 0xb1, 0xb4, 0xbf, 0xec, 0xee, 0x99, 0x5d, 0x61, 0x61, 0xa0, 0x34, 0xeb, 0xdd, 0x73, 0xb7, 0x64, 0xeb, 0xcc, 0xce, 0x29, 0x51,
+ /* (2^223)P */ 0x20, 0x35, 0x99, 0x94, 0x58, 0x21, 0x43, 0xee, 0x3b, 0x0b, 0x4c, 0xf1, 0x7c, 0x9c, 0x2f, 0x77, 0xd5, 0xda, 0xbe, 0x06, 0xe3, 0xfc, 0xe2, 0xd2, 0x97, 0x6a, 0xf0, 0x46, 0xb5, 0x42, 0x5f, 0x71,
+ /* (2^224)P */ 0x1a, 0x5f, 0x5b, 0xda, 0xce, 0xcd, 0x4e, 0x43, 0xa9, 0x41, 0x97, 0xa4, 0x15, 0x71, 0xa1, 0x0d, 0x2e, 0xad, 0xed, 0x73, 0x7c, 0xd7, 0x0b, 0x68, 0x41, 0x90, 0xdd, 0x4e, 0x35, 0x02, 0x7c, 0x48,
+ /* (2^225)P */ 0xc4, 0xd9, 0x0e, 0xa7, 0xf3, 0xef, 0xef, 0xb8, 0x02, 0xe3, 0x57, 0xe8, 0xa3, 0x2a, 0xa3, 0x56, 0xa0, 0xa5, 0xa2, 0x48, 0xbd, 0x68, 0x3a, 0xdf, 0x44, 0xc4, 0x76, 0x31, 0xb7, 0x50, 0xf6, 0x07,
+ /* (2^226)P */ 0xb1, 0xcc, 0xe0, 0x26, 0x16, 0x9b, 0x8b, 0xe3, 0x36, 0xfb, 0x09, 0x8b, 0xc1, 0x53, 0xe0, 0x79, 0x64, 0x49, 0xf9, 0xc9, 0x19, 0x03, 0xd9, 0x56, 0xc4, 0xf5, 0x9f, 0xac, 0xe7, 0x41, 0xa9, 0x1c,
+ /* (2^227)P */ 0xbb, 0xa0, 0x2f, 0x16, 0x29, 0xdf, 0xc4, 0x49, 0x05, 0x33, 0xb3, 0x82, 0x32, 0xcf, 0x88, 0x84, 0x7d, 0x43, 0xbb, 0xca, 0x14, 0xda, 0xdf, 0x95, 0x86, 0xad, 0xd5, 0x64, 0x82, 0xf7, 0x91, 0x33,
+ /* (2^228)P */ 0x5d, 0x09, 0xb5, 0xe2, 0x6a, 0xe0, 0x9a, 0x72, 0x46, 0xa9, 0x59, 0x32, 0xd7, 0x58, 0x8a, 0xd5, 0xed, 0x21, 0x39, 0xd1, 0x62, 0x42, 0x83, 0xe9, 0x92, 0xb5, 0x4b, 0xa5, 0xfa, 0xda, 0xfe, 0x27,
+ /* (2^229)P */ 0xbb, 0x48, 0xad, 0x29, 0xb8, 0xc5, 0x9d, 0xa9, 0x60, 0xe2, 0x9e, 0x49, 0x42, 0x57, 0x02, 0x5f, 0xfd, 0x13, 0x75, 0x5d, 0xcd, 0x8e, 0x2c, 0x80, 0x38, 0xd9, 0x6d, 0x3f, 0xef, 0xb3, 0xce, 0x78,
+ /* (2^230)P */ 0x94, 0x5d, 0x13, 0x8a, 0x4f, 0xf4, 0x42, 0xc3, 0xa3, 0xdd, 0x8c, 0x82, 0x44, 0xdb, 0x9e, 0x7b, 0xe7, 0xcf, 0x37, 0x05, 0x1a, 0xd1, 0x36, 0x94, 0xc8, 0xb4, 0x1a, 0xec, 0x64, 0xb1, 0x64, 0x50,
+ /* (2^231)P */ 0xfc, 0xb2, 0x7e, 0xd3, 0xcf, 0xec, 0x20, 0x70, 0xfc, 0x25, 0x0d, 0xd9, 0x3e, 0xea, 0x31, 0x1f, 0x34, 0xbb, 0xa1, 0xdf, 0x7b, 0x0d, 0x93, 0x1b, 0x44, 0x30, 0x11, 0x48, 0x7a, 0x46, 0x44, 0x53,
+ /* (2^232)P */ 0xfb, 0x6d, 0x5e, 0xf2, 0x70, 0x31, 0x07, 0x70, 0xc8, 0x4c, 0x11, 0x50, 0x1a, 0xdc, 0x85, 0xe3, 0x00, 0x4f, 0xfc, 0xc8, 0x8a, 0x69, 0x48, 0x23, 0xd8, 0x40, 0xdd, 0x84, 0x52, 0xa5, 0x77, 0x2a,
+ /* (2^233)P */ 0xe4, 0x6c, 0x8c, 0xc9, 0xe0, 0xaf, 0x06, 0xfe, 0xe4, 0xd6, 0xdf, 0xdd, 0x96, 0xdf, 0x35, 0xc2, 0xd3, 0x1e, 0xbf, 0x33, 0x1e, 0xd0, 0x28, 0x14, 0xaf, 0xbd, 0x00, 0x93, 0xec, 0x68, 0x57, 0x78,
+ /* (2^234)P */ 0x3b, 0xb6, 0xde, 0x91, 0x7a, 0xe5, 0x02, 0x97, 0x80, 0x8b, 0xce, 0xe5, 0xbf, 0xb8, 0xbd, 0x61, 0xac, 0x58, 0x1d, 0x3d, 0x6f, 0x42, 0x5b, 0x64, 0xbc, 0x57, 0xa5, 0x27, 0x22, 0xa8, 0x04, 0x48,
+ /* (2^235)P */ 0x01, 0x26, 0x4d, 0xb4, 0x8a, 0x04, 0x57, 0x8e, 0x35, 0x69, 0x3a, 0x4b, 0x1a, 0x50, 0xd6, 0x68, 0x93, 0xc2, 0xe1, 0xf9, 0xc3, 0x9e, 0x9c, 0xc3, 0xe2, 0x63, 0xde, 0xd4, 0x57, 0xf2, 0x72, 0x41,
+ /* (2^236)P */ 0x01, 0x64, 0x0c, 0x33, 0x50, 0xb4, 0x68, 0xd3, 0x91, 0x23, 0x8f, 0x41, 0x17, 0x30, 0x0d, 0x04, 0x0d, 0xd9, 0xb7, 0x90, 0x60, 0xbb, 0x34, 0x2c, 0x1f, 0xd5, 0xdf, 0x8f, 0x22, 0x49, 0xf6, 0x16,
+ /* (2^237)P */ 0xf5, 0x8e, 0x92, 0x2b, 0x8e, 0x81, 0xa6, 0xbe, 0x72, 0x1e, 0xc1, 0xcd, 0x91, 0xcf, 0x8c, 0xe2, 0xcd, 0x36, 0x7a, 0xe7, 0x68, 0xaa, 0x4a, 0x59, 0x0f, 0xfd, 0x7f, 0x6c, 0x80, 0x34, 0x30, 0x31,
+ /* (2^238)P */ 0x65, 0xbd, 0x49, 0x22, 0xac, 0x27, 0x9d, 0x8a, 0x12, 0x95, 0x8e, 0x01, 0x64, 0xb4, 0xa3, 0x19, 0xc7, 0x7e, 0xb3, 0x52, 0xf3, 0xcf, 0x6c, 0xc2, 0x21, 0x7b, 0x79, 0x1d, 0x34, 0x68, 0x6f, 0x05,
+ /* (2^239)P */ 0x27, 0x23, 0xfd, 0x7e, 0x75, 0xd6, 0x79, 0x5e, 0x15, 0xfe, 0x3a, 0x55, 0xb6, 0xbc, 0xbd, 0xfa, 0x60, 0x5a, 0xaf, 0x6e, 0x2c, 0x22, 0xe7, 0xd3, 0x3b, 0x74, 0xae, 0x4d, 0x6d, 0xc7, 0x46, 0x70,
+ /* (2^240)P */ 0x55, 0x4a, 0x8d, 0xb1, 0x72, 0xe8, 0x0b, 0x66, 0x96, 0x14, 0x4e, 0x57, 0x18, 0x25, 0x99, 0x19, 0xbb, 0xdc, 0x2b, 0x30, 0x3a, 0x05, 0x03, 0xc1, 0x8e, 0x8e, 0x21, 0x0b, 0x80, 0xe9, 0xd8, 0x3e,
+ /* (2^241)P */ 0x3e, 0xe0, 0x75, 0xfa, 0x39, 0x92, 0x0b, 0x7b, 0x83, 0xc0, 0x33, 0x46, 0x68, 0xfb, 0xe9, 0xef, 0x93, 0x77, 0x1a, 0x39, 0xbe, 0x5f, 0xa3, 0x98, 0x34, 0xfe, 0xd0, 0xe2, 0x0f, 0x51, 0x65, 0x60,
+ /* (2^242)P */ 0x0c, 0xad, 0xab, 0x48, 0x85, 0x66, 0xcb, 0x55, 0x27, 0xe5, 0x87, 0xda, 0x48, 0x45, 0x58, 0xb4, 0xdd, 0xc1, 0x07, 0x01, 0xea, 0xec, 0x43, 0x2c, 0x35, 0xde, 0x72, 0x93, 0x80, 0x28, 0x60, 0x52,
+ /* (2^243)P */ 0x1f, 0x3b, 0x21, 0xf9, 0x6a, 0xc5, 0x15, 0x34, 0xdb, 0x98, 0x7e, 0x01, 0x4d, 0x1a, 0xee, 0x5b, 0x9b, 0x70, 0xcf, 0xb5, 0x05, 0xb1, 0xf6, 0x13, 0xb6, 0x9a, 0xb2, 0x82, 0x34, 0x0e, 0xf2, 0x5f,
+ /* (2^244)P */ 0x90, 0x6c, 0x2e, 0xcc, 0x75, 0x9c, 0xa2, 0x0a, 0x06, 0xe2, 0x70, 0x3a, 0xca, 0x73, 0x7d, 0xfc, 0x15, 0xc5, 0xb5, 0xc4, 0x8f, 0xc3, 0x9f, 0x89, 0x07, 0xc2, 0xff, 0x24, 0xb1, 0x86, 0x03, 0x25,
+ /* (2^245)P */ 0x56, 0x2b, 0x3d, 0xae, 0xd5, 0x28, 0xea, 0x54, 0xce, 0x60, 0xde, 0xd6, 0x9d, 0x14, 0x13, 0x99, 0xc1, 0xd6, 0x06, 0x8f, 0xc5, 0x4f, 0x69, 0x16, 0xc7, 0x8f, 0x01, 0xeb, 0x75, 0x39, 0xb2, 0x46,
+ /* (2^246)P */ 0xe2, 0xb4, 0xb7, 0xb4, 0x0f, 0x6a, 0x0a, 0x47, 0xde, 0x53, 0x72, 0x8f, 0x5a, 0x47, 0x92, 0x5d, 0xdb, 0x3a, 0xbd, 0x2f, 0xb5, 0xe5, 0xee, 0xab, 0x68, 0x69, 0x80, 0xa0, 0x01, 0x08, 0xa2, 0x7f,
+ /* (2^247)P */ 0xd2, 0x14, 0x77, 0x9f, 0xf1, 0xfa, 0xf3, 0x76, 0xc3, 0x60, 0x46, 0x2f, 0xc1, 0x40, 0xe8, 0xb3, 0x4e, 0x74, 0x12, 0xf2, 0x8d, 0xcd, 0xb4, 0x0f, 0xd2, 0x2d, 0x3a, 0x1d, 0x25, 0x5a, 0x06, 0x4b,
+ /* (2^248)P */ 0x4a, 0xcd, 0x77, 0x3d, 0x38, 0xde, 0xeb, 0x5c, 0xb1, 0x9c, 0x2c, 0x88, 0xdf, 0x39, 0xdf, 0x6a, 0x59, 0xf7, 0x9a, 0xb0, 0x2e, 0x24, 0xdd, 0xa2, 0x22, 0x64, 0x5f, 0x0e, 0xe5, 0xc0, 0x47, 0x31,
+ /* (2^249)P */ 0xdb, 0x50, 0x13, 0x1d, 0x10, 0xa5, 0x4c, 0x16, 0x62, 0xc9, 0x3f, 0xc3, 0x79, 0x34, 0xd1, 0xf8, 0x08, 0xda, 0xe5, 0x13, 0x4d, 0xce, 0x40, 0xe6, 0xba, 0xf8, 0x61, 0x50, 0xc4, 0xe0, 0xde, 0x4b,
+ /* (2^250)P */ 0xc9, 0xb1, 0xed, 0xa4, 0xc1, 0x6d, 0xc4, 0xd7, 0x8a, 0xd9, 0x7f, 0x43, 0xb6, 0xd7, 0x14, 0x55, 0x0b, 0xc0, 0xa1, 0xb2, 0x6b, 0x2f, 0x94, 0x58, 0x0e, 0x71, 0x70, 0x1d, 0xab, 0xb2, 0xff, 0x2d,
+ /* (2^251)P */ 0x68, 0x6d, 0x8b, 0xc1, 0x2f, 0xcf, 0xdf, 0xcc, 0x67, 0x61, 0x80, 0xb7, 0xa8, 0xcb, 0xeb, 0xa8, 0xe3, 0x37, 0x29, 0x5e, 0xf9, 0x97, 0x06, 0x98, 0x8c, 0x6e, 0x12, 0xd0, 0x1c, 0xba, 0xfb, 0x02,
+ /* (2^252)P */ 0x65, 0x45, 0xff, 0xad, 0x60, 0xc3, 0x98, 0xcb, 0x19, 0x15, 0xdb, 0x4b, 0xd2, 0x01, 0x71, 0x44, 0xd5, 0x15, 0xfb, 0x75, 0x74, 0xc8, 0xc4, 0x98, 0x7d, 0xa2, 0x22, 0x6e, 0x6d, 0xc7, 0xf8, 0x05,
+ /* (2^253)P */ 0x94, 0xf4, 0xb9, 0xfe, 0xdf, 0xe5, 0x69, 0xab, 0x75, 0x6b, 0x40, 0x18, 0x9d, 0xc7, 0x09, 0xae, 0x1d, 0x2d, 0xa4, 0x94, 0xfb, 0x45, 0x9b, 0x19, 0x84, 0xfa, 0x2a, 0xae, 0xeb, 0x0a, 0x71, 0x79,
+ /* (2^254)P */ 0xdf, 0xd2, 0x34, 0xf3, 0xa7, 0xed, 0xad, 0xa6, 0xb4, 0x57, 0x2a, 0xaf, 0x51, 0x9c, 0xde, 0x7b, 0xa8, 0xea, 0xdc, 0x86, 0x4f, 0xc6, 0x8f, 0xa9, 0x7b, 0xd0, 0x0e, 0xc2, 0x35, 0x03, 0xbe, 0x6b,
+ /* (2^255)P */ 0x44, 0x43, 0x98, 0x53, 0xbe, 0xdc, 0x7f, 0x66, 0xa8, 0x49, 0x59, 0x00, 0x1c, 0xbc, 0x72, 0x07, 0x8e, 0xd6, 0xbe, 0x4e, 0x9f, 0xa4, 0x07, 0xba, 0xbf, 0x30, 0xdf, 0xba, 0x85, 0xb0, 0xa7, 0x1f,
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve.go b/vendor/github.com/cloudflare/circl/dh/x448/curve.go
new file mode 100644
index 0000000..d59564e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve.go
@@ -0,0 +1,104 @@
+package x448
+
+import (
+ fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// ladderJoye calculates a fixed-point multiplication with the generator point.
+// The algorithm is the right-to-left Joye's ladder as described
+// in "How to precompute a ladder" in SAC'2017.
+func ladderJoye(k *Key) {
+ w := [5]fp.Elt{} // [mu,x1,z1,x2,z2] order must be preserved.
+ w[1] = fp.Elt{ // x1 = S
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ }
+ fp.SetOne(&w[2]) // z1 = 1
+ w[3] = fp.Elt{ // x2 = G-S
+ 0x20, 0x27, 0x9d, 0xc9, 0x7d, 0x19, 0xb1, 0xac,
+ 0xf8, 0xba, 0x69, 0x1c, 0xff, 0x33, 0xac, 0x23,
+ 0x51, 0x1b, 0xce, 0x3a, 0x64, 0x65, 0xbd, 0xf1,
+ 0x23, 0xf8, 0xc1, 0x84, 0x9d, 0x45, 0x54, 0x29,
+ 0x67, 0xb9, 0x81, 0x1c, 0x03, 0xd1, 0xcd, 0xda,
+ 0x7b, 0xeb, 0xff, 0x1a, 0x88, 0x03, 0xcf, 0x3a,
+ 0x42, 0x44, 0x32, 0x01, 0x25, 0xb7, 0xfa, 0xf0,
+ }
+ fp.SetOne(&w[4]) // z2 = 1
+
+ const n = 448
+ const h = 2
+ swap := uint(1)
+ for s := 0; s < n-h; s++ {
+ i := (s + h) / 8
+ j := (s + h) % 8
+ bit := uint((k[i] >> uint(j)) & 1)
+ copy(w[0][:], tableGenerator[s*Size:(s+1)*Size])
+ diffAdd(&w, swap^bit)
+ swap = bit
+ }
+ for s := 0; s < h; s++ {
+ double(&w[1], &w[2])
+ }
+ toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+// ladderMontgomery calculates a generic scalar point multiplication
+// The algorithm implemented is the left-to-right Montgomery's ladder.
+func ladderMontgomery(k, xP *Key) {
+ w := [5]fp.Elt{} // [x1, x2, z2, x3, z3] order must be preserved.
+ w[0] = *(*fp.Elt)(xP) // x1 = xP
+ fp.SetOne(&w[1]) // x2 = 1
+ w[3] = *(*fp.Elt)(xP) // x3 = xP
+ fp.SetOne(&w[4]) // z3 = 1
+
+ move := uint(0)
+ for s := 448 - 1; s >= 0; s-- {
+ i := s / 8
+ j := s % 8
+ bit := uint((k[i] >> uint(j)) & 1)
+ ladderStep(&w, move^bit)
+ move = bit
+ }
+ toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+func toAffine(k *[fp.Size]byte, x, z *fp.Elt) {
+ fp.Inv(z, z)
+ fp.Mul(x, x, z)
+ _ = fp.ToBytes(k[:], x)
+}
+
+var lowOrderPoints = [3]fp.Elt{
+ { /* (0,_,1) point of order 2 on Curve448 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* (1,_,1) a point of order 4 on the twist of Curve448 */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* (-1,_,1) point of order 4 on Curve448 */
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ },
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go
new file mode 100644
index 0000000..a062266
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go
@@ -0,0 +1,30 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package x448
+
+import (
+ fp "github.com/cloudflare/circl/math/fp448"
+ "golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func double(x, z *fp.Elt) { doubleAmd64(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint) { diffAddAmd64(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepAmd64(w, b) }
+func mulA24(z, x *fp.Elt) { mulA24Amd64(z, x) }
+
+//go:noescape
+func doubleAmd64(x, z *fp.Elt)
+
+//go:noescape
+func diffAddAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func ladderStepAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func mulA24Amd64(z, x *fp.Elt)
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h
new file mode 100644
index 0000000..8c1ae4d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h
@@ -0,0 +1,111 @@
+#define ladderStepLeg \
+ addSub(x2,z2) \
+ addSub(x3,z3) \
+ integerMulLeg(b0,x2,z3) \
+ integerMulLeg(b1,x3,z2) \
+ reduceFromDoubleLeg(t0,b0) \
+ reduceFromDoubleLeg(t1,b1) \
+ addSub(t0,t1) \
+ cselect(x2,x3,regMove) \
+ cselect(z2,z3,regMove) \
+ integerSqrLeg(b0,t0) \
+ integerSqrLeg(b1,t1) \
+ reduceFromDoubleLeg(x3,b0) \
+ reduceFromDoubleLeg(z3,b1) \
+ integerMulLeg(b0,x1,z3) \
+ reduceFromDoubleLeg(z3,b0) \
+ integerSqrLeg(b0,x2) \
+ integerSqrLeg(b1,z2) \
+ reduceFromDoubleLeg(x2,b0) \
+ reduceFromDoubleLeg(z2,b1) \
+ subtraction(t0,x2,z2) \
+ multiplyA24Leg(t1,t0) \
+ additionLeg(t1,t1,z2) \
+ integerMulLeg(b0,x2,z2) \
+ integerMulLeg(b1,t0,t1) \
+ reduceFromDoubleLeg(x2,b0) \
+ reduceFromDoubleLeg(z2,b1)
+
+#define ladderStepBmi2Adx \
+ addSub(x2,z2) \
+ addSub(x3,z3) \
+ integerMulAdx(b0,x2,z3) \
+ integerMulAdx(b1,x3,z2) \
+ reduceFromDoubleAdx(t0,b0) \
+ reduceFromDoubleAdx(t1,b1) \
+ addSub(t0,t1) \
+ cselect(x2,x3,regMove) \
+ cselect(z2,z3,regMove) \
+ integerSqrAdx(b0,t0) \
+ integerSqrAdx(b1,t1) \
+ reduceFromDoubleAdx(x3,b0) \
+ reduceFromDoubleAdx(z3,b1) \
+ integerMulAdx(b0,x1,z3) \
+ reduceFromDoubleAdx(z3,b0) \
+ integerSqrAdx(b0,x2) \
+ integerSqrAdx(b1,z2) \
+ reduceFromDoubleAdx(x2,b0) \
+ reduceFromDoubleAdx(z2,b1) \
+ subtraction(t0,x2,z2) \
+ multiplyA24Adx(t1,t0) \
+ additionAdx(t1,t1,z2) \
+ integerMulAdx(b0,x2,z2) \
+ integerMulAdx(b1,t0,t1) \
+ reduceFromDoubleAdx(x2,b0) \
+ reduceFromDoubleAdx(z2,b1)
+
+#define difAddLeg \
+ addSub(x1,z1) \
+ integerMulLeg(b0,z1,ui) \
+ reduceFromDoubleLeg(z1,b0) \
+ addSub(x1,z1) \
+ integerSqrLeg(b0,x1) \
+ integerSqrLeg(b1,z1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1) \
+ integerMulLeg(b0,x1,z2) \
+ integerMulLeg(b1,z1,x2) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1)
+
+#define difAddBmi2Adx \
+ addSub(x1,z1) \
+ integerMulAdx(b0,z1,ui) \
+ reduceFromDoubleAdx(z1,b0) \
+ addSub(x1,z1) \
+ integerSqrAdx(b0,x1) \
+ integerSqrAdx(b1,z1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1) \
+ integerMulAdx(b0,x1,z2) \
+ integerMulAdx(b1,z1,x2) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1)
+
+#define doubleLeg \
+ addSub(x1,z1) \
+ integerSqrLeg(b0,x1) \
+ integerSqrLeg(b1,z1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1) \
+ subtraction(t0,x1,z1) \
+ multiplyA24Leg(t1,t0) \
+ additionLeg(t1,t1,z1) \
+ integerMulLeg(b0,x1,z1) \
+ integerMulLeg(b1,t0,t1) \
+ reduceFromDoubleLeg(x1,b0) \
+ reduceFromDoubleLeg(z1,b1)
+
+#define doubleBmi2Adx \
+ addSub(x1,z1) \
+ integerSqrAdx(b0,x1) \
+ integerSqrAdx(b1,z1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1) \
+ subtraction(t0,x1,z1) \
+ multiplyA24Adx(t1,t0) \
+ additionAdx(t1,t1,z1) \
+ integerMulAdx(b0,x1,z1) \
+ integerMulAdx(b1,t0,t1) \
+ reduceFromDoubleAdx(x1,b0) \
+ reduceFromDoubleAdx(z1,b1)
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
new file mode 100644
index 0000000..ed33ba3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
@@ -0,0 +1,194 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+
+// Depends on circl/math/fp448 package
+#include "../../math/fp448/fp_amd64.h"
+#include "curve_amd64.h"
+
+// CTE_A24 is (A+2)/4 from Curve448
+#define CTE_A24 39082
+
+#define Size 56
+
+// multiplyA24Leg multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, cmov, adx
+#define multiplyA24Leg(z,x) \
+ MOVQ $CTE_A24, R15; \
+ MOVQ 0+x, AX; MULQ R15; MOVQ AX, R8; ;;;;;;;;;;;; MOVQ DX, R9; \
+ MOVQ 8+x, AX; MULQ R15; ADDQ AX, R9; ADCQ $0, DX; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
+ MOVQ 32+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
+ MOVQ 40+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
+ MOVQ 48+x, AX; MULQ R15; ADDQ AX, R14; ADCQ $0, DX; \
+ MOVQ DX, AX; \
+ SHLQ $32, AX; \
+ ADDQ DX, R8; MOVQ $0, DX; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ ADCQ $0, DX; \
+ MOVQ DX, AX; \
+ SHLQ $32, AX; \
+ ADDQ DX, R8; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ MOVQ R8, 0+z; \
+ MOVQ R9, 8+z; \
+ MOVQ R10, 16+z; \
+ MOVQ R11, 24+z; \
+ MOVQ R12, 32+z; \
+ MOVQ R13, 40+z; \
+ MOVQ R14, 48+z;
+
+// multiplyA24Adx multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64, bmi2
+#define multiplyA24Adx(z,x) \
+ MOVQ $CTE_A24, DX; \
+ MULXQ 0+x, R8, R9; \
+ MULXQ 8+x, AX, R10; ADDQ AX, R9; \
+ MULXQ 16+x, AX, R11; ADCQ AX, R10; \
+ MULXQ 24+x, AX, R12; ADCQ AX, R11; \
+ MULXQ 32+x, AX, R13; ADCQ AX, R12; \
+ MULXQ 40+x, AX, R14; ADCQ AX, R13; \
+ MULXQ 48+x, AX, DX; ADCQ AX, R14; \
+ ;;;;;;;;;;;;;;;;;;;; ADCQ $0, DX; \
+ MOVQ DX, AX; \
+ SHLQ $32, AX; \
+ ADDQ DX, R8; MOVQ $0, DX; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ ADCQ $0, DX; \
+ MOVQ DX, AX; \
+ SHLQ $32, AX; \
+ ADDQ DX, R8; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ MOVQ R8, 0+z; \
+ MOVQ R9, 8+z; \
+ MOVQ R10, 16+z; \
+ MOVQ R11, 24+z; \
+ MOVQ R12, 32+z; \
+ MOVQ R13, 40+z; \
+ MOVQ R14, 48+z;
+
+#define mulA24Legacy \
+ multiplyA24Leg(0(DI),0(SI))
+#define mulA24Bmi2Adx \
+ multiplyA24Adx(0(DI),0(SI))
+
+// func mulA24Amd64(z, x *fp448.Elt)
+TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
+
+// func ladderStepAmd64(w *[5]fp448.Elt, b uint)
+// ladderStepAmd64 calculates a point addition and doubling as follows:
+// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
+// w = {x1,x2,z2,x3,z4} are five fp255.Elt of 56 bytes.
+// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·ladderStepAmd64(SB),NOSPLIT,$336-16
+ // Parameters
+ #define regWork DI
+ #define regMove SI
+ #define x1 0*Size(regWork)
+ #define x2 1*Size(regWork)
+ #define z2 2*Size(regWork)
+ #define x3 3*Size(regWork)
+ #define z3 4*Size(regWork)
+ // Local variables
+ #define t0 0*Size(SP)
+ #define t1 1*Size(SP)
+ #define b0 2*Size(SP)
+ #define b1 4*Size(SP)
+ MOVQ w+0(FP), regWork
+ MOVQ b+8(FP), regMove
+ CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
+ #undef regWork
+ #undef regMove
+ #undef x1
+ #undef x2
+ #undef z2
+ #undef x3
+ #undef z3
+ #undef t0
+ #undef t1
+ #undef b0
+ #undef b1
+
+// func diffAddAmd64(work *[5]fp.Elt, swap uint)
+// diffAddAmd64 calculates a differential point addition using a precomputed point.
+// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
+// work = {mu,x1,z1,x2,z2} are five fp448.Elt of 56 bytes, and
+// stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+// This is Equation 7 at https://eprint.iacr.org/2017/264.
+TEXT ·diffAddAmd64(SB),NOSPLIT,$224-16
+ // Parameters
+ #define regWork DI
+ #define regSwap SI
+ #define ui 0*Size(regWork)
+ #define x1 1*Size(regWork)
+ #define z1 2*Size(regWork)
+ #define x2 3*Size(regWork)
+ #define z2 4*Size(regWork)
+ // Local variables
+ #define b0 0*Size(SP)
+ #define b1 2*Size(SP)
+ MOVQ w+0(FP), regWork
+ MOVQ b+8(FP), regSwap
+ cswap(x1,x2,regSwap)
+ cswap(z1,z2,regSwap)
+ CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
+ #undef regWork
+ #undef regSwap
+ #undef ui
+ #undef x1
+ #undef z1
+ #undef x2
+ #undef z2
+ #undef b0
+ #undef b1
+
+// func doubleAmd64(x, z *fp448.Elt)
+// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
+// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·doubleAmd64(SB),NOSPLIT,$336-16
+ // Parameters
+ #define x1 0(DI)
+ #define z1 0(SI)
+ // Local variables
+ #define t0 0*Size(SP)
+ #define t1 1*Size(SP)
+ #define b0 2*Size(SP)
+ #define b1 4*Size(SP)
+ MOVQ x+0(FP), DI
+ MOVQ z+8(FP), SI
+ CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
+ #undef x1
+ #undef z1
+ #undef t0
+ #undef t1
+ #undef b0
+ #undef b1
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go
new file mode 100644
index 0000000..b0b65cc
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go
@@ -0,0 +1,100 @@
+package x448
+
+import (
+ "encoding/binary"
+ "math/bits"
+
+ "github.com/cloudflare/circl/math/fp448"
+)
+
+func doubleGeneric(x, z *fp448.Elt) {
+ t0, t1 := &fp448.Elt{}, &fp448.Elt{}
+ fp448.AddSub(x, z)
+ fp448.Sqr(x, x)
+ fp448.Sqr(z, z)
+ fp448.Sub(t0, x, z)
+ mulA24Generic(t1, t0)
+ fp448.Add(t1, t1, z)
+ fp448.Mul(x, x, z)
+ fp448.Mul(z, t0, t1)
+}
+
+func diffAddGeneric(w *[5]fp448.Elt, b uint) {
+ mu, x1, z1, x2, z2 := &w[0], &w[1], &w[2], &w[3], &w[4]
+ fp448.Cswap(x1, x2, b)
+ fp448.Cswap(z1, z2, b)
+ fp448.AddSub(x1, z1)
+ fp448.Mul(z1, z1, mu)
+ fp448.AddSub(x1, z1)
+ fp448.Sqr(x1, x1)
+ fp448.Sqr(z1, z1)
+ fp448.Mul(x1, x1, z2)
+ fp448.Mul(z1, z1, x2)
+}
+
+func ladderStepGeneric(w *[5]fp448.Elt, b uint) {
+ x1, x2, z2, x3, z3 := &w[0], &w[1], &w[2], &w[3], &w[4]
+ t0 := &fp448.Elt{}
+ t1 := &fp448.Elt{}
+ fp448.AddSub(x2, z2)
+ fp448.AddSub(x3, z3)
+ fp448.Mul(t0, x2, z3)
+ fp448.Mul(t1, x3, z2)
+ fp448.AddSub(t0, t1)
+ fp448.Cmov(x2, x3, b)
+ fp448.Cmov(z2, z3, b)
+ fp448.Sqr(x3, t0)
+ fp448.Sqr(z3, t1)
+ fp448.Mul(z3, x1, z3)
+ fp448.Sqr(x2, x2)
+ fp448.Sqr(z2, z2)
+ fp448.Sub(t0, x2, z2)
+ mulA24Generic(t1, t0)
+ fp448.Add(t1, t1, z2)
+ fp448.Mul(x2, x2, z2)
+ fp448.Mul(z2, t0, t1)
+}
+
+func mulA24Generic(z, x *fp448.Elt) {
+ const A24 = 39082
+ const n = 8
+ var xx [7]uint64
+ for i := range xx {
+ xx[i] = binary.LittleEndian.Uint64(x[i*n : (i+1)*n])
+ }
+ h0, l0 := bits.Mul64(xx[0], A24)
+ h1, l1 := bits.Mul64(xx[1], A24)
+ h2, l2 := bits.Mul64(xx[2], A24)
+ h3, l3 := bits.Mul64(xx[3], A24)
+ h4, l4 := bits.Mul64(xx[4], A24)
+ h5, l5 := bits.Mul64(xx[5], A24)
+ h6, l6 := bits.Mul64(xx[6], A24)
+
+ l1, c0 := bits.Add64(h0, l1, 0)
+ l2, c1 := bits.Add64(h1, l2, c0)
+ l3, c2 := bits.Add64(h2, l3, c1)
+ l4, c3 := bits.Add64(h3, l4, c2)
+ l5, c4 := bits.Add64(h4, l5, c3)
+ l6, c5 := bits.Add64(h5, l6, c4)
+ l7, _ := bits.Add64(h6, 0, c5)
+
+ l0, c0 = bits.Add64(l0, l7, 0)
+ l1, c1 = bits.Add64(l1, 0, c0)
+ l2, c2 = bits.Add64(l2, 0, c1)
+ l3, c3 = bits.Add64(l3, l7<<32, c2)
+ l4, c4 = bits.Add64(l4, 0, c3)
+ l5, c5 = bits.Add64(l5, 0, c4)
+ l6, l7 = bits.Add64(l6, 0, c5)
+
+ xx[0], c0 = bits.Add64(l0, l7, 0)
+ xx[1], c1 = bits.Add64(l1, 0, c0)
+ xx[2], c2 = bits.Add64(l2, 0, c1)
+ xx[3], c3 = bits.Add64(l3, l7<<32, c2)
+ xx[4], c4 = bits.Add64(l4, 0, c3)
+ xx[5], c5 = bits.Add64(l5, 0, c4)
+ xx[6], _ = bits.Add64(l6, 0, c5)
+
+ for i := range xx {
+ binary.LittleEndian.PutUint64(z[i*n:(i+1)*n], xx[i])
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go
new file mode 100644
index 0000000..3755b7c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go
@@ -0,0 +1,11 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package x448
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+func double(x, z *fp.Elt) { doubleGeneric(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint) { diffAddGeneric(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepGeneric(w, b) }
+func mulA24(z, x *fp.Elt) { mulA24Generic(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/doc.go b/vendor/github.com/cloudflare/circl/dh/x448/doc.go
new file mode 100644
index 0000000..c02904f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/doc.go
@@ -0,0 +1,19 @@
+/*
+Package x448 provides Diffie-Hellman functions as specified in RFC-7748.
+
+Validation of public keys.
+
+The Diffie-Hellman function, as described in RFC-7748 [1], works for any
+public key. However, if a different protocol requires contributory
+behaviour [2,3], then the public keys must be validated against low-order
+points [3,4]. To do that, the Shared function performs this validation
+internally and returns false when the public key is invalid (i.e., it
+is a low-order point).
+
+References:
+ - [1] RFC7748 by Langley, Hamburg, Turner (https://rfc-editor.org/rfc/rfc7748.txt)
+ - [2] Curve25519 by Bernstein (https://cr.yp.to/ecdh.html)
+ - [3] Bernstein (https://cr.yp.to/ecdh.html#validate)
+ - [4] Cremers&Jackson (https://eprint.iacr.org/2019/526)
+*/
+package x448
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/key.go b/vendor/github.com/cloudflare/circl/dh/x448/key.go
new file mode 100644
index 0000000..2fdde51
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/key.go
@@ -0,0 +1,46 @@
+package x448
+
+import (
+ "crypto/subtle"
+
+ fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// Size is the length in bytes of a X448 key.
+const Size = 56
+
+// Key represents a X448 key.
+type Key [Size]byte
+
+func (k *Key) clamp(in *Key) *Key {
+ *k = *in
+ k[0] &= 252
+ k[55] |= 128
+ return k
+}
+
+// isValidPubKey verifies if the public key is not a low-order point.
+func (k *Key) isValidPubKey() bool {
+ fp.Modp((*fp.Elt)(k))
+ var isLowOrder int
+ for _, P := range lowOrderPoints {
+ isLowOrder |= subtle.ConstantTimeCompare(P[:], k[:])
+ }
+ return isLowOrder == 0
+}
+
+// KeyGen obtains a public key given a secret key.
+func KeyGen(public, secret *Key) {
+ ladderJoye(public.clamp(secret))
+}
+
+// Shared calculates Alice's shared key from Alice's secret key and Bob's
+// public key returning true on success. A failure case happens when the public
+// key is a low-order point, thus the shared key is all-zeros and the function
+// returns false.
+func Shared(shared, secret, public *Key) bool {
+ validPk := *public
+ ok := validPk.isValidPubKey()
+ ladderMontgomery(shared.clamp(secret), &validPk)
+ return ok
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/table.go b/vendor/github.com/cloudflare/circl/dh/x448/table.go
new file mode 100644
index 0000000..eef53c3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/table.go
@@ -0,0 +1,460 @@
+package x448
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+// tableGenerator contains the set of points:
+//
+// t[i] = (xi+1)/(xi-1),
+//
+// where (xi,yi) = 2^iG and G is the generator point
+// Size = (448)*(448/8) = 25088 bytes.
+var tableGenerator = [448 * fp.Size]byte{
+ /* (2^ 0)P */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ /* (2^ 1)P */ 0x37, 0xfa, 0xaa, 0x0d, 0x86, 0xa6, 0x24, 0xe9, 0x6c, 0x95, 0x08, 0x34, 0xba, 0x1a, 0x81, 0x3a, 0xae, 0x01, 0xa5, 0xa7, 0x05, 0x85, 0x96, 0x00, 0x06, 0x5a, 0xd7, 0xff, 0xee, 0x8e, 0x8f, 0x94, 0xd2, 0xdc, 0xd7, 0xfc, 0xe7, 0xe5, 0x99, 0x1d, 0x05, 0x46, 0x43, 0xe8, 0xbc, 0x12, 0xb7, 0xeb, 0x30, 0x5e, 0x7a, 0x85, 0x68, 0xed, 0x9d, 0x28,
+ /* (2^ 2)P */ 0xf1, 0x7d, 0x08, 0x2b, 0x32, 0x4a, 0x62, 0x80, 0x36, 0xe7, 0xa4, 0x76, 0x5a, 0x2a, 0x1e, 0xf7, 0x9e, 0x3c, 0x40, 0x46, 0x9a, 0x1b, 0x61, 0xc1, 0xbf, 0x1a, 0x1b, 0xae, 0x91, 0x80, 0xa3, 0x76, 0x6c, 0xd4, 0x8f, 0xa4, 0xee, 0x26, 0x39, 0x23, 0xa4, 0x80, 0xf4, 0x66, 0x92, 0xe4, 0xe1, 0x18, 0x76, 0xc5, 0xe2, 0x19, 0x87, 0xd5, 0xc3, 0xe8,
+ /* (2^ 3)P */ 0xfb, 0xc9, 0xf0, 0x07, 0xf2, 0x93, 0xd8, 0x50, 0x36, 0xed, 0xfb, 0xbd, 0xb2, 0xd3, 0xfc, 0xdf, 0xd5, 0x2a, 0x6e, 0x26, 0x09, 0xce, 0xd4, 0x07, 0x64, 0x9f, 0x40, 0x74, 0xad, 0x98, 0x2f, 0x1c, 0xb6, 0xdc, 0x2d, 0x42, 0xff, 0xbf, 0x97, 0xd8, 0xdb, 0xef, 0x99, 0xca, 0x73, 0x99, 0x1a, 0x04, 0x3b, 0x56, 0x2c, 0x1f, 0x87, 0x9d, 0x9f, 0x03,
+ /* (2^ 4)P */ 0x4c, 0x35, 0x97, 0xf7, 0x81, 0x2c, 0x84, 0xa6, 0xe0, 0xcb, 0xce, 0x37, 0x4c, 0x21, 0x1c, 0x67, 0xfa, 0xab, 0x18, 0x4d, 0xef, 0xd0, 0xf0, 0x44, 0xa9, 0xfb, 0xc0, 0x8e, 0xda, 0x57, 0xa1, 0xd8, 0xeb, 0x87, 0xf4, 0x17, 0xea, 0x66, 0x0f, 0x16, 0xea, 0xcd, 0x5f, 0x3e, 0x88, 0xea, 0x09, 0x68, 0x40, 0xdf, 0x43, 0xcc, 0x54, 0x61, 0x58, 0xaa,
+ /* (2^ 5)P */ 0x8d, 0xe7, 0x59, 0xd7, 0x5e, 0x63, 0x37, 0xa7, 0x3f, 0xd1, 0x49, 0x85, 0x01, 0xdd, 0x5e, 0xb3, 0xe6, 0x29, 0xcb, 0x25, 0x93, 0xdd, 0x08, 0x96, 0x83, 0x52, 0x76, 0x85, 0xf5, 0x5d, 0x02, 0xbf, 0xe9, 0x6d, 0x15, 0x27, 0xc1, 0x09, 0xd1, 0x14, 0x4d, 0x6e, 0xe8, 0xaf, 0x59, 0x58, 0x34, 0x9d, 0x2a, 0x99, 0x85, 0x26, 0xbe, 0x4b, 0x1e, 0xb9,
+ /* (2^ 6)P */ 0x8d, 0xce, 0x94, 0xe2, 0x18, 0x56, 0x0d, 0x82, 0x8e, 0xdf, 0x85, 0x01, 0x8f, 0x93, 0x3c, 0xc6, 0xbd, 0x61, 0xfb, 0xf4, 0x22, 0xc5, 0x16, 0x87, 0xd1, 0xb1, 0x9e, 0x09, 0xc5, 0x83, 0x2e, 0x4a, 0x07, 0x88, 0xee, 0xe0, 0x29, 0x8d, 0x2e, 0x1f, 0x88, 0xad, 0xfd, 0x18, 0x93, 0xb7, 0xed, 0x42, 0x86, 0x78, 0xf0, 0xb8, 0x70, 0xbe, 0x01, 0x67,
+ /* (2^ 7)P */ 0xdf, 0x62, 0x2d, 0x94, 0xc7, 0x35, 0x23, 0xda, 0x27, 0xbb, 0x2b, 0xdb, 0x30, 0x80, 0x68, 0x16, 0xa3, 0xae, 0xd7, 0xd2, 0xa7, 0x7c, 0xbf, 0x6a, 0x1d, 0x83, 0xde, 0x96, 0x0a, 0x43, 0xb6, 0x30, 0x37, 0xd6, 0xee, 0x63, 0x59, 0x9a, 0xbf, 0xa3, 0x30, 0x6c, 0xaf, 0x0c, 0xee, 0x3d, 0xcb, 0x35, 0x4b, 0x55, 0x5f, 0x84, 0x85, 0xcb, 0x4f, 0x1e,
+ /* (2^ 8)P */ 0x9d, 0x04, 0x68, 0x89, 0xa4, 0xa9, 0x0d, 0x87, 0xc1, 0x70, 0xf1, 0xeb, 0xfb, 0x47, 0x0a, 0xf0, 0xde, 0x67, 0xb7, 0x94, 0xcd, 0x36, 0x43, 0xa5, 0x49, 0x43, 0x67, 0xc3, 0xee, 0x3c, 0x6b, 0xec, 0xd0, 0x1a, 0xf4, 0xad, 0xef, 0x06, 0x4a, 0xe8, 0x46, 0x24, 0xd7, 0x93, 0xbf, 0xf0, 0xe3, 0x81, 0x61, 0xec, 0xea, 0x64, 0xfe, 0x67, 0xeb, 0xc7,
+ /* (2^ 9)P */ 0x95, 0x45, 0x79, 0xcf, 0x2c, 0xfd, 0x9b, 0xfe, 0x84, 0x46, 0x4b, 0x8f, 0xa1, 0xcf, 0xc3, 0x04, 0x94, 0x78, 0xdb, 0xc9, 0xa6, 0x01, 0x75, 0xa4, 0xb4, 0x93, 0x72, 0x43, 0xa7, 0x7d, 0xda, 0x31, 0x38, 0x54, 0xab, 0x4e, 0x3f, 0x89, 0xa6, 0xab, 0x57, 0xc0, 0x16, 0x65, 0xdb, 0x92, 0x96, 0xe4, 0xc8, 0xae, 0xe7, 0x4c, 0x7a, 0xeb, 0xbb, 0x5a,
+ /* (2^ 10)P */ 0xbe, 0xfe, 0x86, 0xc3, 0x97, 0xe0, 0x6a, 0x18, 0x20, 0x21, 0xca, 0x22, 0x55, 0xa1, 0xeb, 0xf5, 0x74, 0xe5, 0xc9, 0x59, 0xa7, 0x92, 0x65, 0x15, 0x08, 0x71, 0xd1, 0x09, 0x7e, 0x83, 0xfc, 0xbc, 0x5a, 0x93, 0x38, 0x0d, 0x43, 0x42, 0xfd, 0x76, 0x30, 0xe8, 0x63, 0x60, 0x09, 0x8d, 0x6c, 0xd3, 0xf8, 0x56, 0x3d, 0x68, 0x47, 0xab, 0xa0, 0x1d,
+ /* (2^ 11)P */ 0x38, 0x50, 0x1c, 0xb1, 0xac, 0x88, 0x8f, 0x38, 0xe3, 0x69, 0xe6, 0xfc, 0x4f, 0x8f, 0xe1, 0x9b, 0xb1, 0x1a, 0x09, 0x39, 0x19, 0xdf, 0xcd, 0x98, 0x7b, 0x64, 0x42, 0xf6, 0x11, 0xea, 0xc7, 0xe8, 0x92, 0x65, 0x00, 0x2c, 0x75, 0xb5, 0x94, 0x1e, 0x5b, 0xa6, 0x66, 0x81, 0x77, 0xf3, 0x39, 0x94, 0xac, 0xbd, 0xe4, 0x2a, 0x66, 0x84, 0x9c, 0x60,
+ /* (2^ 12)P */ 0xb5, 0xb6, 0xd9, 0x03, 0x67, 0xa4, 0xa8, 0x0a, 0x4a, 0x2b, 0x9d, 0xfa, 0x13, 0xe1, 0x99, 0x25, 0x4a, 0x5c, 0x67, 0xb9, 0xb2, 0xb7, 0xdd, 0x1e, 0xaf, 0xeb, 0x63, 0x41, 0xb6, 0xb9, 0xa0, 0x87, 0x0a, 0xe0, 0x06, 0x07, 0xaa, 0x97, 0xf8, 0xf9, 0x38, 0x4f, 0xdf, 0x0c, 0x40, 0x7c, 0xc3, 0x98, 0xa9, 0x74, 0xf1, 0x5d, 0xda, 0xd1, 0xc0, 0x0a,
+ /* (2^ 13)P */ 0xf2, 0x0a, 0xab, 0xab, 0x94, 0x50, 0xf0, 0xa3, 0x6f, 0xc6, 0x66, 0xba, 0xa6, 0xdc, 0x44, 0xdd, 0xd6, 0x08, 0xf4, 0xd3, 0xed, 0xb1, 0x40, 0x93, 0xee, 0xf6, 0xb8, 0x8e, 0xb4, 0x7c, 0xb9, 0x82, 0xc9, 0x9d, 0x45, 0x3b, 0x8e, 0x10, 0xcb, 0x70, 0x1e, 0xba, 0x3c, 0x62, 0x50, 0xda, 0xa9, 0x93, 0xb5, 0xd7, 0xd0, 0x6f, 0x29, 0x52, 0x95, 0xae,
+ /* (2^ 14)P */ 0x14, 0x68, 0x69, 0x23, 0xa8, 0x44, 0x87, 0x9e, 0x22, 0x91, 0xe8, 0x92, 0xdf, 0xf7, 0xae, 0xba, 0x1c, 0x96, 0xe1, 0xc3, 0x94, 0xed, 0x6c, 0x95, 0xae, 0x96, 0xa7, 0x15, 0x9f, 0xf1, 0x17, 0x11, 0x92, 0x42, 0xd5, 0xcd, 0x18, 0xe7, 0xa9, 0xb5, 0x2f, 0xcd, 0xde, 0x6c, 0xc9, 0x7d, 0xfc, 0x7e, 0xbd, 0x7f, 0x10, 0x3d, 0x01, 0x00, 0x8d, 0x95,
+ /* (2^ 15)P */ 0x3b, 0x76, 0x72, 0xae, 0xaf, 0x84, 0xf2, 0xf7, 0xd1, 0x6d, 0x13, 0x9c, 0x47, 0xe1, 0xb7, 0xa3, 0x19, 0x16, 0xee, 0x75, 0x45, 0xf6, 0x1a, 0x7b, 0x78, 0x49, 0x79, 0x05, 0x86, 0xf0, 0x7f, 0x9f, 0xfc, 0xc4, 0xbd, 0x86, 0xf3, 0x41, 0xa7, 0xfe, 0x01, 0xd5, 0x67, 0x16, 0x10, 0x5b, 0xa5, 0x16, 0xf3, 0x7f, 0x60, 0xce, 0xd2, 0x0c, 0x8e, 0x4b,
+ /* (2^ 16)P */ 0x4a, 0x07, 0x99, 0x4a, 0x0f, 0x74, 0x91, 0x14, 0x68, 0xb9, 0x48, 0xb7, 0x44, 0x77, 0x9b, 0x4a, 0xe0, 0x68, 0x0e, 0x43, 0x4d, 0x98, 0x98, 0xbf, 0xa8, 0x3a, 0xb7, 0x6d, 0x2a, 0x9a, 0x77, 0x5f, 0x62, 0xf5, 0x6b, 0x4a, 0xb7, 0x7d, 0xe5, 0x09, 0x6b, 0xc0, 0x8b, 0x9c, 0x88, 0x37, 0x33, 0xf2, 0x41, 0xac, 0x22, 0x1f, 0xcf, 0x3b, 0x82, 0x34,
+ /* (2^ 17)P */ 0x00, 0xc3, 0x78, 0x42, 0x32, 0x2e, 0xdc, 0xda, 0xb1, 0x96, 0x21, 0xa4, 0xe4, 0xbb, 0xe9, 0x9d, 0xbb, 0x0f, 0x93, 0xed, 0x26, 0x3d, 0xb5, 0xdb, 0x94, 0x31, 0x37, 0x07, 0xa2, 0xb2, 0xd5, 0x99, 0x0d, 0x93, 0xe1, 0xce, 0x3f, 0x0b, 0x96, 0x82, 0x47, 0xfe, 0x60, 0x6f, 0x8f, 0x61, 0x88, 0xd7, 0x05, 0x95, 0x0b, 0x46, 0x06, 0xb7, 0x32, 0x06,
+ /* (2^ 18)P */ 0x44, 0xf5, 0x34, 0xdf, 0x2f, 0x9c, 0x5d, 0x9f, 0x53, 0x5c, 0x42, 0x8f, 0xc9, 0xdc, 0xd8, 0x40, 0xa2, 0xe7, 0x6a, 0x4a, 0x05, 0xf7, 0x86, 0x77, 0x2b, 0xae, 0x37, 0xed, 0x48, 0xfb, 0xf7, 0x62, 0x7c, 0x17, 0x59, 0x92, 0x41, 0x61, 0x93, 0x38, 0x30, 0xd1, 0xef, 0x54, 0x54, 0x03, 0x17, 0x57, 0x91, 0x15, 0x11, 0x33, 0xb5, 0xfa, 0xfb, 0x17,
+ /* (2^ 19)P */ 0x29, 0xbb, 0xd4, 0xb4, 0x9c, 0xf1, 0x72, 0x94, 0xce, 0x6a, 0x29, 0xa8, 0x89, 0x18, 0x19, 0xf7, 0xb7, 0xcc, 0xee, 0x9a, 0x02, 0xe3, 0xc0, 0xb1, 0xe0, 0xee, 0x83, 0x78, 0xb4, 0x9e, 0x07, 0x87, 0xdf, 0xb0, 0x82, 0x26, 0x4e, 0xa4, 0x0c, 0x33, 0xaf, 0x40, 0x59, 0xb6, 0xdd, 0x52, 0x45, 0xf0, 0xb4, 0xf6, 0xe8, 0x4e, 0x4e, 0x79, 0x1a, 0x5d,
+ /* (2^ 20)P */ 0x27, 0x33, 0x4d, 0x4c, 0x6b, 0x4f, 0x75, 0xb1, 0xbc, 0x1f, 0xab, 0x5b, 0x2b, 0xf0, 0x1c, 0x57, 0x86, 0xdd, 0xfd, 0x60, 0xb0, 0x8c, 0xe7, 0x9a, 0xe5, 0x5c, 0xeb, 0x11, 0x3a, 0xda, 0x22, 0x25, 0x99, 0x06, 0x8d, 0xf4, 0xaf, 0x29, 0x7a, 0xc9, 0xe5, 0xd2, 0x16, 0x9e, 0xd4, 0x63, 0x1d, 0x64, 0xa6, 0x47, 0x96, 0x37, 0x6f, 0x93, 0x2c, 0xcc,
+ /* (2^ 21)P */ 0xc1, 0x94, 0x74, 0x86, 0x75, 0xf2, 0x91, 0x58, 0x23, 0x85, 0x63, 0x76, 0x54, 0xc7, 0xb4, 0x8c, 0xbc, 0x4e, 0xc4, 0xa7, 0xba, 0xa0, 0x55, 0x26, 0x71, 0xd5, 0x33, 0x72, 0xc9, 0xad, 0x1e, 0xf9, 0x5d, 0x78, 0x70, 0x93, 0x4e, 0x85, 0xfc, 0x39, 0x06, 0x73, 0x76, 0xff, 0xe8, 0x64, 0x69, 0x42, 0x45, 0xb2, 0x69, 0xb5, 0x32, 0xe7, 0x2c, 0xde,
+ /* (2^ 22)P */ 0xde, 0x16, 0xd8, 0x33, 0x49, 0x32, 0xe9, 0x0e, 0x3a, 0x60, 0xee, 0x2e, 0x24, 0x75, 0xe3, 0x9c, 0x92, 0x07, 0xdb, 0xad, 0x92, 0xf5, 0x11, 0xdf, 0xdb, 0xb0, 0x17, 0x5c, 0xd6, 0x1a, 0x70, 0x00, 0xb7, 0xe2, 0x18, 0xec, 0xdc, 0xc2, 0x02, 0x93, 0xb3, 0xc8, 0x3f, 0x4f, 0x1b, 0x96, 0xe6, 0x33, 0x8c, 0xfb, 0xcc, 0xa5, 0x4e, 0xe8, 0xe7, 0x11,
+ /* (2^ 23)P */ 0x05, 0x7a, 0x74, 0x52, 0xf8, 0xdf, 0x0d, 0x7c, 0x6a, 0x1a, 0x4e, 0x9a, 0x02, 0x1d, 0xae, 0x77, 0xf8, 0x8e, 0xf9, 0xa2, 0x38, 0x54, 0x50, 0xb2, 0x2c, 0x08, 0x9d, 0x9b, 0x9f, 0xfb, 0x2b, 0x06, 0xde, 0x9d, 0xc2, 0x03, 0x0b, 0x22, 0x2b, 0x10, 0x5b, 0x3a, 0x73, 0x29, 0x8e, 0x3e, 0x37, 0x08, 0x2c, 0x3b, 0xf8, 0x80, 0xc1, 0x66, 0x1e, 0x98,
+ /* (2^ 24)P */ 0xd8, 0xd6, 0x3e, 0xcd, 0x63, 0x8c, 0x2b, 0x41, 0x81, 0xc0, 0x0c, 0x06, 0x87, 0xd6, 0xe7, 0x92, 0xfe, 0xf1, 0x0c, 0x4a, 0x84, 0x5b, 0xaf, 0x40, 0x53, 0x6f, 0x60, 0xd6, 0x6b, 0x76, 0x4b, 0xc2, 0xad, 0xc9, 0xb6, 0xb6, 0x6a, 0xa2, 0xb3, 0xf5, 0xf5, 0xc2, 0x55, 0x83, 0xb2, 0xd3, 0xe9, 0x41, 0x6c, 0x63, 0x51, 0xb8, 0x81, 0x74, 0xc8, 0x2c,
+ /* (2^ 25)P */ 0xb2, 0xaf, 0x1c, 0xee, 0x07, 0xb0, 0x58, 0xa8, 0x2c, 0x6a, 0xc9, 0x2d, 0x62, 0x28, 0x75, 0x0c, 0x40, 0xb6, 0x11, 0x33, 0x96, 0x80, 0x28, 0x6d, 0xd5, 0x9e, 0x87, 0x90, 0x01, 0x66, 0x1d, 0x1c, 0xf8, 0xb4, 0x92, 0xac, 0x38, 0x18, 0x05, 0xc2, 0x4c, 0x4b, 0x54, 0x7d, 0x80, 0x46, 0x87, 0x2d, 0x99, 0x8e, 0x70, 0x80, 0x69, 0x71, 0x8b, 0xed,
+ /* (2^ 26)P */ 0x37, 0xa7, 0x6b, 0x71, 0x36, 0x75, 0x8e, 0xff, 0x0f, 0x42, 0xda, 0x5a, 0x46, 0xa6, 0x97, 0x79, 0x7e, 0x30, 0xb3, 0x8f, 0xc7, 0x3a, 0xa0, 0xcb, 0x1d, 0x9c, 0x78, 0x77, 0x36, 0xc2, 0xe7, 0xf4, 0x2f, 0x29, 0x07, 0xb1, 0x07, 0xfd, 0xed, 0x1b, 0x39, 0x77, 0x06, 0x38, 0x77, 0x0f, 0x50, 0x31, 0x12, 0xbf, 0x92, 0xbf, 0x72, 0x79, 0x54, 0xa9,
+ /* (2^ 27)P */ 0xbd, 0x4d, 0x46, 0x6b, 0x1a, 0x80, 0x46, 0x2d, 0xed, 0xfd, 0x64, 0x6d, 0x94, 0xbc, 0x4a, 0x6e, 0x0c, 0x12, 0xf6, 0x12, 0xab, 0x54, 0x88, 0xd3, 0x85, 0xac, 0x51, 0xae, 0x6f, 0xca, 0xc4, 0xb7, 0xec, 0x22, 0x54, 0x6d, 0x80, 0xb2, 0x1c, 0x63, 0x33, 0x76, 0x6b, 0x8e, 0x6d, 0x59, 0xcd, 0x73, 0x92, 0x5f, 0xff, 0xad, 0x10, 0x35, 0x70, 0x5f,
+ /* (2^ 28)P */ 0xb3, 0x84, 0xde, 0xc8, 0x04, 0x43, 0x63, 0xfa, 0x29, 0xd9, 0xf0, 0x69, 0x65, 0x5a, 0x0c, 0xe8, 0x2e, 0x0b, 0xfe, 0xb0, 0x7a, 0x42, 0xb3, 0xc3, 0xfc, 0xe6, 0xb8, 0x92, 0x29, 0xae, 0xed, 0xec, 0xd5, 0xe8, 0x4a, 0xa1, 0xbd, 0x3b, 0xd3, 0xc0, 0x07, 0xab, 0x65, 0x65, 0x35, 0x9a, 0xa6, 0x5e, 0x78, 0x18, 0x76, 0x1c, 0x15, 0x49, 0xe6, 0x75,
+ /* (2^ 29)P */ 0x45, 0xb3, 0x92, 0xa9, 0xc3, 0xb8, 0x11, 0x68, 0x64, 0x3a, 0x83, 0x5d, 0xa8, 0x94, 0x6a, 0x9d, 0xaa, 0x27, 0x9f, 0x98, 0x5d, 0xc0, 0x29, 0xf0, 0xc0, 0x4b, 0x14, 0x3c, 0x05, 0xe7, 0xf8, 0xbd, 0x38, 0x22, 0x96, 0x75, 0x65, 0x5e, 0x0d, 0x3f, 0xbb, 0x6f, 0xe8, 0x3f, 0x96, 0x76, 0x9f, 0xba, 0xd9, 0x44, 0x92, 0x96, 0x22, 0xe7, 0x52, 0xe7,
+ /* (2^ 30)P */ 0xf4, 0xa3, 0x95, 0x90, 0x47, 0xdf, 0x7d, 0xdc, 0xf4, 0x13, 0x87, 0x67, 0x7d, 0x4f, 0x9d, 0xa0, 0x00, 0x46, 0x72, 0x08, 0xc3, 0xa2, 0x7a, 0x3e, 0xe7, 0x6d, 0x52, 0x7c, 0x11, 0x36, 0x50, 0x83, 0x89, 0x64, 0xcb, 0x1f, 0x08, 0x83, 0x46, 0xcb, 0xac, 0xa6, 0xd8, 0x9c, 0x1b, 0xe8, 0x05, 0x47, 0xc7, 0x26, 0x06, 0x83, 0x39, 0xe9, 0xb1, 0x1c,
+ /* (2^ 31)P */ 0x11, 0xe8, 0xc8, 0x42, 0xbf, 0x30, 0x9c, 0xa3, 0xf1, 0x85, 0x96, 0x95, 0x4f, 0x4f, 0x52, 0xa2, 0xf5, 0x8b, 0x68, 0x24, 0x16, 0xac, 0x9b, 0xa9, 0x27, 0x28, 0x0e, 0x84, 0x03, 0x46, 0x22, 0x5f, 0xf7, 0x0d, 0xa6, 0x85, 0x88, 0xc1, 0x45, 0x4b, 0x85, 0x1a, 0x10, 0x7f, 0xc9, 0x94, 0x20, 0xb0, 0x04, 0x28, 0x12, 0x30, 0xb9, 0xe6, 0x40, 0x6b,
+ /* (2^ 32)P */ 0xac, 0x1b, 0x57, 0xb6, 0x42, 0xdb, 0x81, 0x8d, 0x76, 0xfd, 0x9b, 0x1c, 0x29, 0x30, 0xd5, 0x3a, 0xcc, 0x53, 0xd9, 0x26, 0x7a, 0x0f, 0x9c, 0x2e, 0x79, 0xf5, 0x62, 0xeb, 0x61, 0x9d, 0x9b, 0x80, 0x39, 0xcd, 0x60, 0x2e, 0x1f, 0x08, 0x22, 0xbc, 0x19, 0xb3, 0x2a, 0x43, 0x44, 0xf2, 0x4e, 0x66, 0xf4, 0x36, 0xa6, 0xa7, 0xbc, 0xa4, 0x15, 0x7e,
+ /* (2^ 33)P */ 0xc1, 0x90, 0x8a, 0xde, 0xff, 0x78, 0xc3, 0x73, 0x16, 0xee, 0x76, 0xa0, 0x84, 0x60, 0x8d, 0xe6, 0x82, 0x0f, 0xde, 0x4e, 0xc5, 0x99, 0x34, 0x06, 0x90, 0x44, 0x55, 0xf8, 0x91, 0xd8, 0xe1, 0xe4, 0x2c, 0x8a, 0xde, 0x94, 0x1e, 0x78, 0x25, 0x3d, 0xfd, 0xd8, 0x59, 0x7d, 0xaf, 0x6e, 0xbe, 0x96, 0xbe, 0x3c, 0x16, 0x23, 0x0f, 0x4c, 0xa4, 0x28,
+ /* (2^ 34)P */ 0xba, 0x11, 0x35, 0x57, 0x03, 0xb6, 0xf4, 0x24, 0x89, 0xb8, 0x5a, 0x0d, 0x50, 0x9c, 0xaa, 0x51, 0x7f, 0xa4, 0x0e, 0xfc, 0x71, 0xb3, 0x3b, 0xf1, 0x96, 0x50, 0x23, 0x15, 0xf5, 0xf5, 0xd4, 0x23, 0xdc, 0x8b, 0x26, 0x9e, 0xae, 0xb7, 0x50, 0xcd, 0xc4, 0x25, 0xf6, 0x75, 0x40, 0x9c, 0x37, 0x79, 0x33, 0x60, 0xd4, 0x4b, 0x13, 0x32, 0xee, 0xe2,
+ /* (2^ 35)P */ 0x43, 0xb8, 0x56, 0x59, 0xf0, 0x68, 0x23, 0xb3, 0xea, 0x70, 0x58, 0x4c, 0x1e, 0x5a, 0x16, 0x54, 0x03, 0xb2, 0xf4, 0x73, 0xb6, 0xd9, 0x5c, 0x9c, 0x6f, 0xcf, 0x82, 0x2e, 0x54, 0x15, 0x46, 0x2c, 0xa3, 0xda, 0x4e, 0x87, 0xf5, 0x2b, 0xba, 0x91, 0xa3, 0xa0, 0x89, 0xba, 0x48, 0x2b, 0xfa, 0x64, 0x02, 0x7f, 0x78, 0x03, 0xd1, 0xe8, 0x3b, 0xe9,
+ /* (2^ 36)P */ 0x15, 0xa4, 0x71, 0xd4, 0x0c, 0x24, 0xe9, 0x07, 0xa1, 0x43, 0xf4, 0x7f, 0xbb, 0xa2, 0xa6, 0x6b, 0xfa, 0xb7, 0xea, 0x58, 0xd1, 0x96, 0xb0, 0x24, 0x5c, 0xc7, 0x37, 0x4e, 0x60, 0x0f, 0x40, 0xf2, 0x2f, 0x44, 0x70, 0xea, 0x80, 0x63, 0xfe, 0xfc, 0x46, 0x59, 0x12, 0x27, 0xb5, 0x27, 0xfd, 0xb7, 0x73, 0x0b, 0xca, 0x8b, 0xc2, 0xd3, 0x71, 0x08,
+ /* (2^ 37)P */ 0x26, 0x0e, 0xd7, 0x52, 0x6f, 0xf1, 0xf2, 0x9d, 0xb8, 0x3d, 0xbd, 0xd4, 0x75, 0x97, 0xd8, 0xbf, 0xa8, 0x86, 0x96, 0xa5, 0x80, 0xa0, 0x45, 0x75, 0xf6, 0x77, 0x71, 0xdb, 0x77, 0x96, 0x55, 0x99, 0x31, 0xd0, 0x4f, 0x34, 0xf4, 0x35, 0x39, 0x41, 0xd3, 0x7d, 0xf7, 0xe2, 0x74, 0xde, 0xbe, 0x5b, 0x1f, 0x39, 0x10, 0x21, 0xa3, 0x4d, 0x3b, 0xc8,
+ /* (2^ 38)P */ 0x04, 0x00, 0x2a, 0x45, 0xb2, 0xaf, 0x9b, 0x18, 0x6a, 0xeb, 0x96, 0x28, 0xa4, 0x77, 0xd0, 0x13, 0xcf, 0x17, 0x65, 0xe8, 0xc5, 0x81, 0x28, 0xad, 0x39, 0x7a, 0x0b, 0xaa, 0x55, 0x2b, 0xf3, 0xfc, 0x86, 0x40, 0xad, 0x0d, 0x1e, 0x28, 0xa2, 0x2d, 0xc5, 0xd6, 0x04, 0x15, 0xa2, 0x30, 0x3d, 0x12, 0x8e, 0xd6, 0xb5, 0xf7, 0x69, 0xbb, 0x84, 0x20,
+ /* (2^ 39)P */ 0xd7, 0x7a, 0x77, 0x2c, 0xfb, 0x81, 0x80, 0xe9, 0x1e, 0xc6, 0x36, 0x31, 0x79, 0xc3, 0x7c, 0xa9, 0x57, 0x6b, 0xb5, 0x70, 0xfb, 0xe4, 0xa1, 0xff, 0xfd, 0x21, 0xa5, 0x7c, 0xfa, 0x44, 0xba, 0x0d, 0x96, 0x3d, 0xc4, 0x5c, 0x39, 0x52, 0x87, 0xd7, 0x22, 0x0f, 0x52, 0x88, 0x91, 0x87, 0x96, 0xac, 0xfa, 0x3b, 0xdf, 0xdc, 0x83, 0x8c, 0x99, 0x29,
+ /* (2^ 40)P */ 0x98, 0x6b, 0x3a, 0x8d, 0x83, 0x17, 0xe1, 0x62, 0xd8, 0x80, 0x4c, 0x97, 0xce, 0x6b, 0xaa, 0x10, 0xa7, 0xc4, 0xe9, 0xeb, 0xa5, 0xfb, 0xc9, 0xdd, 0x2d, 0xeb, 0xfc, 0x9a, 0x71, 0xcd, 0x68, 0x6e, 0xc0, 0x35, 0x64, 0x62, 0x1b, 0x95, 0x12, 0xe8, 0x53, 0xec, 0xf0, 0xf4, 0x86, 0x86, 0x78, 0x18, 0xc4, 0xc6, 0xbc, 0x5a, 0x59, 0x8f, 0x7c, 0x7e,
+ /* (2^ 41)P */ 0x7f, 0xd7, 0x1e, 0xc5, 0x83, 0xdc, 0x1f, 0xbe, 0x0b, 0xcf, 0x2e, 0x01, 0x01, 0xed, 0xac, 0x17, 0x3b, 0xed, 0xa4, 0x30, 0x96, 0x0e, 0x14, 0x7e, 0x19, 0x2b, 0xa5, 0x67, 0x1e, 0xb3, 0x34, 0x03, 0xa8, 0xbb, 0x0a, 0x7d, 0x08, 0x2d, 0xd5, 0x53, 0x19, 0x6f, 0x13, 0xd5, 0xc0, 0x90, 0x8a, 0xcc, 0xc9, 0x5c, 0xab, 0x24, 0xd7, 0x03, 0xf6, 0x57,
+ /* (2^ 42)P */ 0x49, 0xcb, 0xb4, 0x96, 0x5f, 0xa6, 0xf8, 0x71, 0x6f, 0x59, 0xad, 0x05, 0x24, 0x2d, 0xaf, 0x67, 0xa8, 0xbe, 0x95, 0xdf, 0x0d, 0x28, 0x5a, 0x7f, 0x6e, 0x87, 0x8c, 0x6e, 0x67, 0x0c, 0xf4, 0xe0, 0x1c, 0x30, 0xc2, 0x66, 0xae, 0x20, 0xa1, 0x34, 0xec, 0x9c, 0xbc, 0xae, 0x3d, 0xa1, 0x28, 0x28, 0x95, 0x1d, 0xc9, 0x3a, 0xa8, 0xfd, 0xfc, 0xa1,
+ /* (2^ 43)P */ 0xe2, 0x2b, 0x9d, 0xed, 0x02, 0x99, 0x67, 0xbb, 0x2e, 0x16, 0x62, 0x05, 0x70, 0xc7, 0x27, 0xb9, 0x1c, 0x3f, 0xf2, 0x11, 0x01, 0xd8, 0x51, 0xa4, 0x18, 0x92, 0xa9, 0x5d, 0xfb, 0xa9, 0xe4, 0x42, 0xba, 0x38, 0x34, 0x1a, 0x4a, 0xc5, 0x6a, 0x37, 0xde, 0xa7, 0x0c, 0xb4, 0x7e, 0x7f, 0xde, 0xa6, 0xee, 0xcd, 0x55, 0x57, 0x05, 0x06, 0xfd, 0x5d,
+ /* (2^ 44)P */ 0x2f, 0x32, 0xcf, 0x2e, 0x2c, 0x7b, 0xbe, 0x9a, 0x0c, 0x57, 0x35, 0xf8, 0x87, 0xda, 0x9c, 0xec, 0x48, 0xf2, 0xbb, 0xe2, 0xda, 0x10, 0x58, 0x20, 0xc6, 0xd3, 0x87, 0xe9, 0xc7, 0x26, 0xd1, 0x9a, 0x46, 0x87, 0x90, 0xda, 0xdc, 0xde, 0xc3, 0xb3, 0xf2, 0xe8, 0x6f, 0x4a, 0xe6, 0xe8, 0x9d, 0x98, 0x36, 0x20, 0x03, 0x47, 0x15, 0x3f, 0x64, 0x59,
+ /* (2^ 45)P */ 0xd4, 0x71, 0x49, 0x0a, 0x67, 0x97, 0xaa, 0x3f, 0xf4, 0x1b, 0x3a, 0x6e, 0x5e, 0x17, 0xcc, 0x0a, 0x8f, 0x81, 0x6a, 0x41, 0x38, 0x77, 0x40, 0x8a, 0x11, 0x42, 0x62, 0xd2, 0x50, 0x32, 0x79, 0x78, 0x28, 0xc2, 0x2e, 0x10, 0x01, 0x94, 0x30, 0x4f, 0x7f, 0x18, 0x17, 0x56, 0x85, 0x4e, 0xad, 0xf7, 0xcb, 0x87, 0x3c, 0x3f, 0x50, 0x2c, 0xc0, 0xba,
+ /* (2^ 46)P */ 0xbc, 0x30, 0x8e, 0x65, 0x8e, 0x57, 0x5b, 0x38, 0x7a, 0xd4, 0x95, 0x52, 0x7a, 0x32, 0x59, 0x69, 0xcd, 0x9d, 0x47, 0x34, 0x5b, 0x55, 0xa5, 0x24, 0x60, 0xdd, 0xc0, 0xc1, 0x62, 0x73, 0x44, 0xae, 0x4c, 0x9c, 0x65, 0x55, 0x1b, 0x9d, 0x8a, 0x29, 0xb0, 0x1a, 0x52, 0xa8, 0xf1, 0xe6, 0x9a, 0xb3, 0xf6, 0xa3, 0xc9, 0x0a, 0x70, 0x7d, 0x0f, 0xee,
+ /* (2^ 47)P */ 0x77, 0xd3, 0xe5, 0x8e, 0xfa, 0x00, 0xeb, 0x1b, 0x7f, 0xdc, 0x68, 0x3f, 0x92, 0xbd, 0xb7, 0x0b, 0xb7, 0xb5, 0x24, 0xdf, 0xc5, 0x67, 0x53, 0xd4, 0x36, 0x79, 0xc4, 0x7b, 0x57, 0xbc, 0x99, 0x97, 0x60, 0xef, 0xe4, 0x01, 0xa1, 0xa7, 0xaa, 0x12, 0x36, 0x29, 0xb1, 0x03, 0xc2, 0x83, 0x1c, 0x2b, 0x83, 0xef, 0x2e, 0x2c, 0x23, 0x92, 0xfd, 0xd1,
+ /* (2^ 48)P */ 0x94, 0xef, 0x03, 0x59, 0xfa, 0x8a, 0x18, 0x76, 0xee, 0x58, 0x08, 0x4d, 0x44, 0xce, 0xf1, 0x52, 0x33, 0x49, 0xf6, 0x69, 0x71, 0xe3, 0xa9, 0xbc, 0x86, 0xe3, 0x43, 0xde, 0x33, 0x7b, 0x90, 0x8b, 0x3e, 0x7d, 0xd5, 0x4a, 0xf0, 0x23, 0x99, 0xa6, 0xea, 0x5f, 0x08, 0xe5, 0xb9, 0x49, 0x8b, 0x0d, 0x6a, 0x21, 0xab, 0x07, 0x62, 0xcd, 0xc4, 0xbe,
+ /* (2^ 49)P */ 0x61, 0xbf, 0x70, 0x14, 0xfa, 0x4e, 0x9e, 0x7c, 0x0c, 0xf8, 0xb2, 0x48, 0x71, 0x62, 0x83, 0xd6, 0xd1, 0xdc, 0x9c, 0x29, 0x66, 0xb1, 0x34, 0x9c, 0x8d, 0xe6, 0x88, 0xaf, 0xbe, 0xdc, 0x4d, 0xeb, 0xb0, 0xe7, 0x28, 0xae, 0xb2, 0x05, 0x56, 0xc6, 0x0e, 0x10, 0x26, 0xab, 0x2c, 0x59, 0x72, 0x03, 0x66, 0xfe, 0x8f, 0x2c, 0x51, 0x2d, 0xdc, 0xae,
+ /* (2^ 50)P */ 0xdc, 0x63, 0xf1, 0x8b, 0x5c, 0x65, 0x0b, 0xf1, 0xa6, 0x22, 0xe2, 0xd9, 0xdb, 0x49, 0xb1, 0x3c, 0x47, 0xc2, 0xfe, 0xac, 0x86, 0x07, 0x52, 0xec, 0xb0, 0x08, 0x69, 0xfb, 0xd1, 0x06, 0xdc, 0x48, 0x5c, 0x3d, 0xb2, 0x4d, 0xb8, 0x1a, 0x4e, 0xda, 0xb9, 0xc1, 0x2b, 0xab, 0x4b, 0x62, 0x81, 0x21, 0x9a, 0xfc, 0x3d, 0x39, 0x83, 0x11, 0x36, 0xeb,
+ /* (2^ 51)P */ 0x94, 0xf3, 0x17, 0xef, 0xf9, 0x60, 0x54, 0xc3, 0xd7, 0x27, 0x35, 0xc5, 0x98, 0x5e, 0xf6, 0x63, 0x6c, 0xa0, 0x4a, 0xd3, 0xa3, 0x98, 0xd9, 0x42, 0xe3, 0xf1, 0xf8, 0x81, 0x96, 0xa9, 0xea, 0x6d, 0x4b, 0x8e, 0x33, 0xca, 0x94, 0x0d, 0xa0, 0xf7, 0xbb, 0x64, 0xa3, 0x36, 0x6f, 0xdc, 0x5a, 0x94, 0x42, 0xca, 0x06, 0xb2, 0x2b, 0x9a, 0x9f, 0x71,
+ /* (2^ 52)P */ 0xec, 0xdb, 0xa6, 0x1f, 0xdf, 0x15, 0x36, 0xa3, 0xda, 0x8a, 0x7a, 0xb6, 0xa7, 0xe3, 0xaf, 0x52, 0xe0, 0x8d, 0xe8, 0xf2, 0x44, 0x20, 0xeb, 0xa1, 0x20, 0xc4, 0x65, 0x3c, 0x7c, 0x6c, 0x49, 0xed, 0x2f, 0x66, 0x23, 0x68, 0x61, 0x91, 0x40, 0x9f, 0x50, 0x19, 0xd1, 0x84, 0xa7, 0xe2, 0xed, 0x34, 0x37, 0xe3, 0xe4, 0x11, 0x7f, 0x87, 0x55, 0x0f,
+ /* (2^ 53)P */ 0xb3, 0xa1, 0x0f, 0xb0, 0x48, 0xc0, 0x4d, 0x96, 0xa7, 0xcf, 0x5a, 0x81, 0xb8, 0x4a, 0x46, 0xef, 0x0a, 0xd3, 0x40, 0x7e, 0x02, 0xe3, 0x63, 0xaa, 0x50, 0xd1, 0x2a, 0x37, 0x22, 0x4a, 0x7f, 0x4f, 0xb6, 0xf9, 0x01, 0x82, 0x78, 0x3d, 0x93, 0x14, 0x11, 0x8a, 0x90, 0x60, 0xcd, 0x45, 0x4e, 0x7b, 0x42, 0xb9, 0x3e, 0x6e, 0x68, 0x1f, 0x36, 0x41,
+ /* (2^ 54)P */ 0x13, 0x73, 0x0e, 0x4f, 0x79, 0x93, 0x9e, 0x29, 0x70, 0x7b, 0x4a, 0x59, 0x1a, 0x9a, 0xf4, 0x55, 0x08, 0xf0, 0xdb, 0x17, 0x58, 0xec, 0x64, 0xad, 0x7f, 0x29, 0xeb, 0x3f, 0x85, 0x4e, 0x60, 0x28, 0x98, 0x1f, 0x73, 0x4e, 0xe6, 0xa8, 0xab, 0xd5, 0xd6, 0xfc, 0xa1, 0x36, 0x6d, 0x15, 0xc6, 0x13, 0x83, 0xa0, 0xc2, 0x6e, 0xd9, 0xdb, 0xc9, 0xcc,
+ /* (2^ 55)P */ 0xff, 0xd8, 0x52, 0xa3, 0xdc, 0x99, 0xcf, 0x3e, 0x19, 0xb3, 0x68, 0xd0, 0xb5, 0x0d, 0xb8, 0xee, 0x3f, 0xef, 0x6e, 0xc0, 0x38, 0x28, 0x44, 0x92, 0x78, 0x91, 0x1a, 0x08, 0x78, 0x6c, 0x65, 0x24, 0xf3, 0xa2, 0x3d, 0xf2, 0xe5, 0x79, 0x62, 0x69, 0x29, 0xf4, 0x22, 0xc5, 0xdb, 0x6a, 0xae, 0xf4, 0x44, 0xa3, 0x6f, 0xc7, 0x86, 0xab, 0xef, 0xef,
+ /* (2^ 56)P */ 0xbf, 0x54, 0x9a, 0x09, 0x5d, 0x17, 0xd0, 0xde, 0xfb, 0xf5, 0xca, 0xff, 0x13, 0x20, 0x88, 0x82, 0x3a, 0xe2, 0xd0, 0x3b, 0xfb, 0x05, 0x76, 0xd1, 0xc0, 0x02, 0x71, 0x3b, 0x94, 0xe8, 0xc9, 0x84, 0xcf, 0xa4, 0xe9, 0x28, 0x7b, 0xf5, 0x09, 0xc3, 0x2b, 0x22, 0x40, 0xf1, 0x68, 0x24, 0x24, 0x7d, 0x9f, 0x6e, 0xcd, 0xfe, 0xb0, 0x19, 0x61, 0xf5,
+ /* (2^ 57)P */ 0xe8, 0x63, 0x51, 0xb3, 0x95, 0x6b, 0x7b, 0x74, 0x92, 0x52, 0x45, 0xa4, 0xed, 0xea, 0x0e, 0x0d, 0x2b, 0x01, 0x1e, 0x2c, 0xbc, 0x91, 0x06, 0x69, 0xdb, 0x1f, 0xb5, 0x77, 0x1d, 0x56, 0xf5, 0xb4, 0x02, 0x80, 0x49, 0x56, 0x12, 0xce, 0x86, 0x05, 0xc9, 0xd9, 0xae, 0xf3, 0x6d, 0xe6, 0x3f, 0x40, 0x52, 0xe9, 0x49, 0x2b, 0x31, 0x06, 0x86, 0x14,
+ /* (2^ 58)P */ 0xf5, 0x09, 0x3b, 0xd2, 0xff, 0xdf, 0x11, 0xa5, 0x1c, 0x99, 0xe8, 0x1b, 0xa4, 0x2c, 0x7d, 0x8e, 0xc8, 0xf7, 0x03, 0x46, 0xfa, 0xb6, 0xde, 0x73, 0x91, 0x7e, 0x5a, 0x7a, 0xd7, 0x9a, 0x5b, 0x80, 0x24, 0x62, 0x5e, 0x92, 0xf1, 0xa3, 0x45, 0xa3, 0x43, 0x92, 0x8a, 0x2a, 0x5b, 0x0c, 0xb4, 0xc8, 0xad, 0x1c, 0xb6, 0x6c, 0x5e, 0x81, 0x18, 0x91,
+ /* (2^ 59)P */ 0x96, 0xb3, 0xca, 0x2b, 0xe3, 0x7a, 0x59, 0x72, 0x17, 0x74, 0x29, 0x21, 0xe7, 0x78, 0x07, 0xad, 0xda, 0xb6, 0xcd, 0xf9, 0x27, 0x4d, 0xc8, 0xf2, 0x98, 0x22, 0xca, 0xf2, 0x33, 0x74, 0x7a, 0xdd, 0x1e, 0x71, 0xec, 0xe3, 0x3f, 0xe2, 0xa2, 0xd2, 0x38, 0x75, 0xb0, 0xd0, 0x0a, 0xcf, 0x7d, 0x36, 0xdc, 0x49, 0x38, 0x25, 0x34, 0x4f, 0x20, 0x9a,
+ /* (2^ 60)P */ 0x2b, 0x6e, 0x04, 0x0d, 0x4f, 0x3d, 0x3b, 0x24, 0xf6, 0x4e, 0x5e, 0x0a, 0xbd, 0x48, 0x96, 0xba, 0x81, 0x8f, 0x39, 0x82, 0x13, 0xe6, 0x72, 0xf3, 0x0f, 0xb6, 0x94, 0xf4, 0xc5, 0x90, 0x74, 0x91, 0xa8, 0xf2, 0xc9, 0xca, 0x9a, 0x4d, 0x98, 0xf2, 0xdf, 0x52, 0x4e, 0x97, 0x2f, 0xeb, 0x84, 0xd3, 0xaf, 0xc2, 0xcc, 0xfb, 0x4c, 0x26, 0x4b, 0xe4,
+ /* (2^ 61)P */ 0x12, 0x9e, 0xfb, 0x9d, 0x78, 0x79, 0x99, 0xdd, 0xb3, 0x0b, 0x2e, 0x56, 0x41, 0x8e, 0x3f, 0x39, 0xb8, 0x97, 0x89, 0x53, 0x9b, 0x8a, 0x3c, 0x40, 0x9d, 0xa4, 0x6c, 0x2e, 0x31, 0x71, 0xc6, 0x0a, 0x41, 0xd4, 0x95, 0x06, 0x5e, 0xc1, 0xab, 0xc2, 0x14, 0xc4, 0xc7, 0x15, 0x08, 0x3a, 0xad, 0x7a, 0xb4, 0x62, 0xa3, 0x0c, 0x90, 0xf4, 0x47, 0x08,
+ /* (2^ 62)P */ 0x7f, 0xec, 0x09, 0x82, 0xf5, 0x94, 0x09, 0x93, 0x32, 0xd3, 0xdc, 0x56, 0x80, 0x7b, 0x5b, 0x22, 0x80, 0x6a, 0x96, 0x72, 0xb1, 0xc2, 0xd9, 0xa1, 0x8b, 0x66, 0x42, 0x16, 0xe2, 0x07, 0xb3, 0x2d, 0xf1, 0x75, 0x35, 0x72, 0xc7, 0x98, 0xbe, 0x63, 0x3b, 0x20, 0x75, 0x05, 0xc1, 0x3e, 0x31, 0x5a, 0xf7, 0xaa, 0xae, 0x4b, 0xdb, 0x1d, 0xd0, 0x74,
+ /* (2^ 63)P */ 0x36, 0x5c, 0x74, 0xe6, 0x5d, 0x59, 0x3f, 0x15, 0x4b, 0x4d, 0x4e, 0x67, 0x41, 0xfe, 0x98, 0x1f, 0x49, 0x76, 0x91, 0x0f, 0x9b, 0xf4, 0xaf, 0x86, 0xaf, 0x66, 0x19, 0xed, 0x46, 0xf1, 0x05, 0x9a, 0xcc, 0xd1, 0x14, 0x1f, 0x82, 0x12, 0x8e, 0xe6, 0xf4, 0xc3, 0x42, 0x5c, 0x4e, 0x33, 0x93, 0xbe, 0x30, 0xe7, 0x64, 0xa9, 0x35, 0x00, 0x4d, 0xf9,
+ /* (2^ 64)P */ 0x1f, 0xc1, 0x1e, 0xb7, 0xe3, 0x7c, 0xfa, 0xa3, 0x6b, 0x76, 0xaf, 0x9c, 0x05, 0x85, 0x4a, 0xa9, 0xfb, 0xe3, 0x7e, 0xf2, 0x49, 0x56, 0xdc, 0x2f, 0x57, 0x10, 0xba, 0x37, 0xb2, 0x62, 0xf5, 0x6b, 0xe5, 0x8f, 0x0a, 0x87, 0xd1, 0x6a, 0xcb, 0x9d, 0x07, 0xd0, 0xf6, 0x38, 0x99, 0x2c, 0x61, 0x4a, 0x4e, 0xd8, 0xd2, 0x88, 0x29, 0x99, 0x11, 0x95,
+ /* (2^ 65)P */ 0x6f, 0xdc, 0xd5, 0xd6, 0xd6, 0xa7, 0x4c, 0x46, 0x93, 0x65, 0x62, 0x23, 0x95, 0x32, 0x9c, 0xde, 0x40, 0x41, 0x68, 0x2c, 0x18, 0x4e, 0x5a, 0x8c, 0xc0, 0xc5, 0xc5, 0xea, 0x5c, 0x45, 0x0f, 0x60, 0x78, 0x39, 0xb6, 0x36, 0x23, 0x12, 0xbc, 0x21, 0x9a, 0xf8, 0x91, 0xac, 0xc4, 0x70, 0xdf, 0x85, 0x8e, 0x3c, 0xec, 0x22, 0x04, 0x98, 0xa8, 0xaa,
+ /* (2^ 66)P */ 0xcc, 0x52, 0x10, 0x5b, 0x4b, 0x6c, 0xc5, 0xfa, 0x3e, 0xd4, 0xf8, 0x1c, 0x04, 0x14, 0x48, 0x33, 0xd9, 0xfc, 0x5f, 0xb0, 0xa5, 0x48, 0x8c, 0x45, 0x8a, 0xee, 0x3e, 0xa7, 0xc1, 0x2e, 0x34, 0xca, 0xf6, 0xc9, 0xeb, 0x10, 0xbb, 0xe1, 0x59, 0x84, 0x25, 0xe8, 0x81, 0x70, 0xc0, 0x09, 0x42, 0xa7, 0x3b, 0x0d, 0x33, 0x00, 0xb5, 0x77, 0xbe, 0x25,
+ /* (2^ 67)P */ 0xcd, 0x1f, 0xbc, 0x7d, 0xef, 0xe5, 0xca, 0x91, 0xaf, 0xa9, 0x59, 0x6a, 0x09, 0xca, 0xd6, 0x1b, 0x3d, 0x55, 0xde, 0xa2, 0x6a, 0x80, 0xd6, 0x95, 0x47, 0xe4, 0x5f, 0x68, 0x54, 0x08, 0xdf, 0x29, 0xba, 0x2a, 0x02, 0x84, 0xe8, 0xe9, 0x00, 0x77, 0x99, 0x36, 0x03, 0xf6, 0x4a, 0x3e, 0x21, 0x81, 0x7d, 0xb8, 0xa4, 0x8a, 0xa2, 0x05, 0xef, 0xbc,
+ /* (2^ 68)P */ 0x7c, 0x59, 0x5f, 0x66, 0xd9, 0xb7, 0x83, 0x43, 0x8a, 0xa1, 0x8d, 0x51, 0x70, 0xba, 0xf2, 0x9b, 0x95, 0xc0, 0x4b, 0x4c, 0xa0, 0x14, 0xd3, 0xa4, 0x5d, 0x4a, 0x37, 0x36, 0x97, 0x31, 0x1e, 0x12, 0xe7, 0xbb, 0x08, 0x67, 0xa5, 0x23, 0xd7, 0xfb, 0x97, 0xd8, 0x6a, 0x03, 0xb1, 0xf8, 0x7f, 0xda, 0x58, 0xd9, 0x3f, 0x73, 0x4a, 0x53, 0xe1, 0x7b,
+ /* (2^ 69)P */ 0x55, 0x83, 0x98, 0x78, 0x6c, 0x56, 0x5e, 0xed, 0xf7, 0x23, 0x3e, 0x4c, 0x7d, 0x09, 0x2d, 0x09, 0x9c, 0x58, 0x8b, 0x32, 0xca, 0xfe, 0xbf, 0x47, 0x03, 0xeb, 0x4d, 0xe7, 0xeb, 0x9c, 0x83, 0x05, 0x68, 0xaa, 0x80, 0x89, 0x44, 0xf9, 0xd4, 0xdc, 0xdb, 0xb1, 0xdb, 0x77, 0xac, 0xf9, 0x2a, 0xae, 0x35, 0xac, 0x74, 0xb5, 0x95, 0x62, 0x18, 0x85,
+ /* (2^ 70)P */ 0xab, 0x82, 0x7e, 0x10, 0xd7, 0xe6, 0x57, 0xd1, 0x66, 0x12, 0x31, 0x9c, 0x9c, 0xa6, 0x27, 0x59, 0x71, 0x2e, 0xeb, 0xa0, 0x68, 0xc5, 0x87, 0x51, 0xf4, 0xca, 0x3f, 0x98, 0x56, 0xb0, 0x89, 0xb1, 0xc7, 0x7b, 0x46, 0xb3, 0xae, 0x36, 0xf2, 0xee, 0x15, 0x1a, 0x60, 0xf4, 0x50, 0x76, 0x4f, 0xc4, 0x53, 0x0d, 0x36, 0x4d, 0x31, 0xb1, 0x20, 0x51,
+ /* (2^ 71)P */ 0xf7, 0x1d, 0x8c, 0x1b, 0x5e, 0xe5, 0x02, 0x6f, 0xc5, 0xa5, 0xe0, 0x5f, 0xc6, 0xb6, 0x63, 0x43, 0xaf, 0x3c, 0x19, 0x6c, 0xf4, 0xaf, 0xa4, 0x33, 0xb1, 0x0a, 0x37, 0x3d, 0xd9, 0x4d, 0xe2, 0x29, 0x24, 0x26, 0x94, 0x7c, 0x02, 0xe4, 0xe2, 0xf2, 0xbe, 0xbd, 0xac, 0x1b, 0x48, 0xb8, 0xdd, 0xe9, 0x0d, 0x9a, 0x50, 0x1a, 0x98, 0x71, 0x6e, 0xdc,
+ /* (2^ 72)P */ 0x9f, 0x40, 0xb1, 0xb3, 0x66, 0x28, 0x6c, 0xfe, 0xa6, 0x7d, 0xf8, 0x3e, 0xb8, 0xf3, 0xde, 0x52, 0x76, 0x52, 0xa3, 0x92, 0x98, 0x23, 0xab, 0x4f, 0x88, 0x97, 0xfc, 0x22, 0xe1, 0x6b, 0x67, 0xcd, 0x13, 0x95, 0xda, 0x65, 0xdd, 0x3b, 0x67, 0x3f, 0x5f, 0x4c, 0xf2, 0x8a, 0xad, 0x98, 0xa7, 0x94, 0x24, 0x45, 0x87, 0x11, 0x7c, 0x75, 0x79, 0x85,
+ /* (2^ 73)P */ 0x70, 0xbf, 0xf9, 0x3b, 0xa9, 0x44, 0x57, 0x72, 0x96, 0xc9, 0xa4, 0x98, 0x65, 0xbf, 0x87, 0xb3, 0x3a, 0x39, 0x12, 0xde, 0xe5, 0x39, 0x01, 0x4f, 0xf7, 0xc0, 0x71, 0x52, 0x36, 0x85, 0xb3, 0x18, 0xf8, 0x14, 0xc0, 0x6d, 0xae, 0x9e, 0x4f, 0xb0, 0x72, 0x87, 0xac, 0x5c, 0xd1, 0x6c, 0x41, 0x6c, 0x90, 0x9d, 0x22, 0x81, 0xe4, 0x2b, 0xea, 0xe5,
+ /* (2^ 74)P */ 0xfc, 0xea, 0x1a, 0x65, 0xd9, 0x49, 0x6a, 0x39, 0xb5, 0x96, 0x72, 0x7b, 0x32, 0xf1, 0xd0, 0xe9, 0x45, 0xd9, 0x31, 0x55, 0xc7, 0x34, 0xe9, 0x5a, 0xec, 0x73, 0x0b, 0x03, 0xc4, 0xb3, 0xe6, 0xc9, 0x5e, 0x0a, 0x17, 0xfe, 0x53, 0x66, 0x7f, 0x21, 0x18, 0x74, 0x54, 0x1b, 0xc9, 0x49, 0x16, 0xd2, 0x48, 0xaf, 0x5b, 0x47, 0x7b, 0xeb, 0xaa, 0xc9,
+ /* (2^ 75)P */ 0x47, 0x04, 0xf5, 0x5a, 0x87, 0x77, 0x9e, 0x21, 0x34, 0x4e, 0x83, 0x88, 0xaf, 0x02, 0x1d, 0xb0, 0x5a, 0x1d, 0x1d, 0x7d, 0x8d, 0x2c, 0xd3, 0x8d, 0x63, 0xa9, 0x45, 0xfb, 0x15, 0x6d, 0x86, 0x45, 0xcd, 0x38, 0x0e, 0xf7, 0x37, 0x79, 0xed, 0x6d, 0x5a, 0xbc, 0x32, 0xcc, 0x66, 0xf1, 0x3a, 0xb2, 0x87, 0x6f, 0x70, 0x71, 0xd9, 0xf2, 0xfa, 0x7b,
+ /* (2^ 76)P */ 0x68, 0x07, 0xdc, 0x61, 0x40, 0xe4, 0xec, 0x32, 0xc8, 0xbe, 0x66, 0x30, 0x54, 0x80, 0xfd, 0x13, 0x7a, 0xef, 0xae, 0xed, 0x2e, 0x00, 0x6d, 0x3f, 0xbd, 0xfc, 0x91, 0x24, 0x53, 0x7f, 0x63, 0x9d, 0x2e, 0xe3, 0x76, 0xe0, 0xf3, 0xe1, 0x8f, 0x7a, 0xc4, 0x77, 0x0c, 0x91, 0xc0, 0xc2, 0x18, 0x6b, 0x04, 0xad, 0xb6, 0x70, 0x9a, 0x64, 0xc5, 0x82,
+ /* (2^ 77)P */ 0x7f, 0xea, 0x13, 0xd8, 0x9e, 0xfc, 0x5b, 0x06, 0xb5, 0x4f, 0xda, 0x38, 0xe0, 0x9c, 0xd2, 0x3a, 0xc1, 0x1c, 0x62, 0x70, 0x7f, 0xc6, 0x24, 0x0a, 0x47, 0x04, 0x01, 0xc4, 0x55, 0x09, 0xd1, 0x7a, 0x07, 0xba, 0xa3, 0x80, 0x4f, 0xc1, 0x65, 0x36, 0x6d, 0xc0, 0x10, 0xcf, 0x94, 0xa9, 0xa2, 0x01, 0x44, 0xd1, 0xf9, 0x1c, 0x4c, 0xfb, 0xf8, 0x99,
+ /* (2^ 78)P */ 0x6c, 0xb9, 0x6b, 0xee, 0x43, 0x5b, 0xb9, 0xbb, 0xee, 0x2e, 0x52, 0xc1, 0xc6, 0xb9, 0x61, 0xd2, 0x93, 0xa5, 0xaf, 0x52, 0xf4, 0xa4, 0x1a, 0x51, 0x61, 0xa7, 0xcb, 0x9e, 0xbb, 0x56, 0x65, 0xe2, 0xbf, 0x75, 0xb9, 0x9c, 0x50, 0x96, 0x60, 0x81, 0x74, 0x47, 0xc0, 0x04, 0x88, 0x71, 0x76, 0x39, 0x9a, 0xa7, 0xb1, 0x4e, 0x43, 0x15, 0xe0, 0xbb,
+ /* (2^ 79)P */ 0xbb, 0xce, 0xe2, 0xbb, 0xf9, 0x17, 0x0f, 0x82, 0x40, 0xad, 0x73, 0xe3, 0xeb, 0x3b, 0x06, 0x1a, 0xcf, 0x8e, 0x6e, 0x28, 0xb8, 0x26, 0xd9, 0x5b, 0xb7, 0xb3, 0xcf, 0xb4, 0x6a, 0x1c, 0xbf, 0x7f, 0xb8, 0xb5, 0x79, 0xcf, 0x45, 0x68, 0x7d, 0xc5, 0xeb, 0xf3, 0xbe, 0x39, 0x40, 0xfc, 0x07, 0x90, 0x7a, 0x62, 0xad, 0x86, 0x08, 0x71, 0x25, 0xe1,
+ /* (2^ 80)P */ 0x9b, 0x46, 0xac, 0xef, 0xc1, 0x4e, 0xa1, 0x97, 0x95, 0x76, 0xf9, 0x1b, 0xc2, 0xb2, 0x6a, 0x41, 0xea, 0x80, 0x3d, 0xe9, 0x08, 0x52, 0x5a, 0xe3, 0xf2, 0x08, 0xc5, 0xea, 0x39, 0x3f, 0x44, 0x71, 0x4d, 0xea, 0x0d, 0x05, 0x23, 0xe4, 0x2e, 0x3c, 0x89, 0xfe, 0x12, 0x8a, 0x95, 0x42, 0x0a, 0x68, 0xea, 0x5a, 0x28, 0x06, 0x9e, 0xe3, 0x5f, 0xe0,
+ /* (2^ 81)P */ 0x00, 0x61, 0x6c, 0x98, 0x9b, 0xe7, 0xb9, 0x06, 0x1c, 0xc5, 0x1b, 0xed, 0xbe, 0xc8, 0xb3, 0xea, 0x87, 0xf0, 0xc4, 0x24, 0x7d, 0xbb, 0x5d, 0xa4, 0x1d, 0x7a, 0x16, 0x00, 0x55, 0x94, 0x67, 0x78, 0xbd, 0x58, 0x02, 0x82, 0x90, 0x53, 0x76, 0xd4, 0x72, 0x99, 0x51, 0x6f, 0x7b, 0xcf, 0x80, 0x30, 0x31, 0x3b, 0x01, 0xc7, 0xc1, 0xef, 0xe6, 0x42,
+ /* (2^ 82)P */ 0xe2, 0x35, 0xaf, 0x4b, 0x79, 0xc6, 0x12, 0x24, 0x99, 0xc0, 0x68, 0xb0, 0x43, 0x3e, 0xe5, 0xef, 0xe2, 0x29, 0xea, 0xb8, 0xb3, 0xbc, 0x6a, 0x53, 0x2c, 0x69, 0x18, 0x5a, 0xf9, 0x15, 0xae, 0x66, 0x58, 0x18, 0xd3, 0x2d, 0x4b, 0x00, 0xfd, 0x84, 0xab, 0x4f, 0xae, 0x70, 0x6b, 0x9e, 0x9a, 0xdf, 0x83, 0xfd, 0x2e, 0x3c, 0xcf, 0xf8, 0x88, 0x5b,
+ /* (2^ 83)P */ 0xa4, 0x90, 0x31, 0x85, 0x13, 0xcd, 0xdf, 0x64, 0xc9, 0xa1, 0x0b, 0xe7, 0xb6, 0x73, 0x8a, 0x1b, 0x22, 0x78, 0x4c, 0xd4, 0xae, 0x48, 0x18, 0x00, 0x00, 0xa8, 0x9f, 0x06, 0xf9, 0xfb, 0x2d, 0xc3, 0xb1, 0x2a, 0xbc, 0x13, 0x99, 0x57, 0xaf, 0xf0, 0x8d, 0x61, 0x54, 0x29, 0xd5, 0xf2, 0x72, 0x00, 0x96, 0xd1, 0x85, 0x12, 0x8a, 0xf0, 0x23, 0xfb,
+ /* (2^ 84)P */ 0x69, 0xc7, 0xdb, 0xd9, 0x92, 0x75, 0x08, 0x9b, 0xeb, 0xa5, 0x93, 0xd1, 0x1a, 0xf4, 0xf5, 0xaf, 0xe6, 0xc4, 0x4a, 0x0d, 0x35, 0x26, 0x39, 0x9d, 0xd3, 0x17, 0x3e, 0xae, 0x2d, 0xbf, 0x73, 0x9f, 0xb7, 0x74, 0x91, 0xd1, 0xd8, 0x5c, 0x14, 0xf9, 0x75, 0xdf, 0xeb, 0xc2, 0x22, 0xd8, 0x14, 0x8d, 0x86, 0x23, 0x4d, 0xd1, 0x2d, 0xdb, 0x6b, 0x42,
+ /* (2^ 85)P */ 0x8c, 0xda, 0xc6, 0xf8, 0x71, 0xba, 0x2b, 0x06, 0x78, 0xae, 0xcc, 0x3a, 0xe3, 0xe3, 0xa1, 0x8b, 0xe2, 0x34, 0x6d, 0x28, 0x9e, 0x46, 0x13, 0x4d, 0x9e, 0xa6, 0x73, 0x49, 0x65, 0x79, 0x88, 0xb9, 0x3a, 0xd1, 0x6d, 0x2f, 0x48, 0x2b, 0x0a, 0x7f, 0x58, 0x20, 0x37, 0xf4, 0x0e, 0xbb, 0x4a, 0x95, 0x58, 0x0c, 0x88, 0x30, 0xc4, 0x74, 0xdd, 0xfd,
+ /* (2^ 86)P */ 0x6d, 0x13, 0x4e, 0x89, 0x2d, 0xa9, 0xa3, 0xed, 0x09, 0xe3, 0x0e, 0x71, 0x3e, 0x4a, 0xab, 0x90, 0xde, 0x03, 0xeb, 0x56, 0x46, 0x60, 0x06, 0xf5, 0x71, 0xe5, 0xee, 0x9b, 0xef, 0xff, 0xc4, 0x2c, 0x9f, 0x37, 0x48, 0x45, 0x94, 0x12, 0x41, 0x81, 0x15, 0x70, 0x91, 0x99, 0x5e, 0x56, 0x6b, 0xf4, 0xa6, 0xc9, 0xf5, 0x69, 0x9d, 0x78, 0x37, 0x57,
+ /* (2^ 87)P */ 0xf3, 0x51, 0x57, 0x7e, 0x43, 0x6f, 0xc6, 0x67, 0x59, 0x0c, 0xcf, 0x94, 0xe6, 0x3d, 0xb5, 0x07, 0xc9, 0x77, 0x48, 0xc9, 0x68, 0x0d, 0x98, 0x36, 0x62, 0x35, 0x38, 0x1c, 0xf5, 0xc5, 0xec, 0x66, 0x78, 0xfe, 0x47, 0xab, 0x26, 0xd6, 0x44, 0xb6, 0x06, 0x0f, 0x89, 0xe3, 0x19, 0x40, 0x1a, 0xe7, 0xd8, 0x65, 0x55, 0xf7, 0x1a, 0xfc, 0xa3, 0x0e,
+ /* (2^ 88)P */ 0x0e, 0x30, 0xa6, 0xb7, 0x58, 0x60, 0x62, 0x2a, 0x6c, 0x13, 0xa8, 0x14, 0x9b, 0xb8, 0xf2, 0x70, 0xd8, 0xb1, 0x71, 0x88, 0x8c, 0x18, 0x31, 0x25, 0x93, 0x90, 0xb4, 0xc7, 0x49, 0xd8, 0xd4, 0xdb, 0x1e, 0x1e, 0x7f, 0xaa, 0xba, 0xc9, 0xf2, 0x5d, 0xa9, 0x3a, 0x43, 0xb4, 0x5c, 0xee, 0x7b, 0xc7, 0x97, 0xb7, 0x66, 0xd7, 0x23, 0xd9, 0x22, 0x59,
+ /* (2^ 89)P */ 0x28, 0x19, 0xa6, 0xf9, 0x89, 0x20, 0x78, 0xd4, 0x6d, 0xcb, 0x79, 0x8f, 0x61, 0x6f, 0xb2, 0x5c, 0x4f, 0xa6, 0x54, 0x84, 0x95, 0x24, 0x36, 0x64, 0xcb, 0x39, 0xe7, 0x8f, 0x97, 0x9c, 0x5c, 0x3c, 0xfb, 0x51, 0x11, 0x01, 0x17, 0xdb, 0xc9, 0x9b, 0x51, 0x03, 0x9a, 0xe9, 0xe5, 0x24, 0x1e, 0xf5, 0xda, 0xe0, 0x48, 0x02, 0x23, 0xd0, 0x2c, 0x81,
+ /* (2^ 90)P */ 0x42, 0x1b, 0xe4, 0x91, 0x85, 0x2a, 0x0c, 0xd2, 0x28, 0x66, 0x57, 0x9e, 0x33, 0x8d, 0x25, 0x71, 0x10, 0x65, 0x76, 0xa2, 0x8c, 0x21, 0x86, 0x81, 0x15, 0xc2, 0x27, 0xeb, 0x54, 0x2d, 0x4f, 0x6c, 0xe6, 0xd6, 0x24, 0x9c, 0x1a, 0x12, 0xb8, 0x81, 0xe2, 0x0a, 0xf3, 0xd3, 0xf0, 0xd3, 0xe1, 0x74, 0x1f, 0x9b, 0x11, 0x47, 0xd0, 0xcf, 0xb6, 0x54,
+ /* (2^ 91)P */ 0x26, 0x45, 0xa2, 0x10, 0xd4, 0x2d, 0xae, 0xc0, 0xb0, 0xe8, 0x86, 0xb3, 0xc7, 0xea, 0x70, 0x87, 0x61, 0xb5, 0xa5, 0x55, 0xbe, 0x88, 0x1d, 0x7a, 0xd9, 0x6f, 0xeb, 0x83, 0xe2, 0x44, 0x7f, 0x98, 0x04, 0xd6, 0x50, 0x9d, 0xa7, 0x86, 0x66, 0x09, 0x63, 0xe1, 0xed, 0x72, 0xb1, 0xe4, 0x1d, 0x3a, 0xfd, 0x47, 0xce, 0x1c, 0xaa, 0x3b, 0x8f, 0x1b,
+ /* (2^ 92)P */ 0xf4, 0x3c, 0x4a, 0xb6, 0xc2, 0x9c, 0xe0, 0x2e, 0xb7, 0x38, 0xea, 0x61, 0x35, 0x97, 0x10, 0x90, 0xae, 0x22, 0x48, 0xb3, 0xa9, 0xc6, 0x7a, 0xbb, 0x23, 0xf2, 0xf8, 0x1b, 0xa7, 0xa1, 0x79, 0xcc, 0xc4, 0xf8, 0x08, 0x76, 0x8a, 0x5a, 0x1c, 0x1b, 0xc5, 0x33, 0x91, 0xa9, 0xb8, 0xb9, 0xd3, 0xf8, 0x49, 0xcd, 0xe5, 0x82, 0x43, 0xf7, 0xca, 0x68,
+ /* (2^ 93)P */ 0x38, 0xba, 0xae, 0x44, 0xfe, 0x57, 0x64, 0x56, 0x7c, 0x0e, 0x9c, 0xca, 0xff, 0xa9, 0x82, 0xbb, 0x38, 0x4a, 0xa7, 0xf7, 0x47, 0xab, 0xbe, 0x6d, 0x23, 0x0b, 0x8a, 0xed, 0xc2, 0xb9, 0x8f, 0xf1, 0xec, 0x91, 0x44, 0x73, 0x64, 0xba, 0xd5, 0x8f, 0x37, 0x38, 0x0d, 0xd5, 0xf8, 0x73, 0x57, 0xb6, 0xc2, 0x45, 0xdc, 0x25, 0xb2, 0xb6, 0xea, 0xd9,
+ /* (2^ 94)P */ 0xbf, 0xe9, 0x1a, 0x40, 0x4d, 0xcc, 0xe6, 0x1d, 0x70, 0x1a, 0x65, 0xcc, 0x34, 0x2c, 0x37, 0x2c, 0x2d, 0x6b, 0x6d, 0xe5, 0x2f, 0x19, 0x9e, 0xe4, 0xe1, 0xaa, 0xd4, 0xab, 0x54, 0xf4, 0xa8, 0xe4, 0x69, 0x2d, 0x8e, 0x4d, 0xd7, 0xac, 0xb0, 0x5b, 0xfe, 0xe3, 0x26, 0x07, 0xc3, 0xf8, 0x1b, 0x43, 0xa8, 0x1d, 0x64, 0xa5, 0x25, 0x88, 0xbb, 0x77,
+ /* (2^ 95)P */ 0x92, 0xcd, 0x6e, 0xa0, 0x79, 0x04, 0x18, 0xf4, 0x11, 0x58, 0x48, 0xb5, 0x3c, 0x7b, 0xd1, 0xcc, 0xd3, 0x14, 0x2c, 0xa0, 0xdd, 0x04, 0x44, 0x11, 0xb3, 0x6d, 0x2f, 0x0d, 0xf5, 0x2a, 0x75, 0x5d, 0x1d, 0xda, 0x86, 0x8d, 0x7d, 0x6b, 0x32, 0x68, 0xb6, 0x6c, 0x64, 0x9e, 0xde, 0x80, 0x88, 0xce, 0x08, 0xbf, 0x0b, 0xe5, 0x8e, 0x4f, 0x1d, 0xfb,
+ /* (2^ 96)P */ 0xaf, 0xe8, 0x85, 0xbf, 0x7f, 0x37, 0x8d, 0x66, 0x7c, 0xd5, 0xd3, 0x96, 0xa5, 0x81, 0x67, 0x95, 0xff, 0x48, 0xde, 0xde, 0xd7, 0x7a, 0x46, 0x34, 0xb1, 0x13, 0x70, 0x29, 0xed, 0x87, 0x90, 0xb0, 0x40, 0x2c, 0xa6, 0x43, 0x6e, 0xb6, 0xbc, 0x48, 0x8a, 0xc1, 0xae, 0xb8, 0xd4, 0xe2, 0xc0, 0x32, 0xb2, 0xa6, 0x2a, 0x8f, 0xb5, 0x16, 0x9e, 0xc3,
+ /* (2^ 97)P */ 0xff, 0x4d, 0xd2, 0xd6, 0x74, 0xef, 0x2c, 0x96, 0xc1, 0x11, 0xa8, 0xb8, 0xfe, 0x94, 0x87, 0x3e, 0xa0, 0xfb, 0x57, 0xa3, 0xfc, 0x7a, 0x7e, 0x6a, 0x59, 0x6c, 0x54, 0xbb, 0xbb, 0xa2, 0x25, 0x38, 0x1b, 0xdf, 0x5d, 0x7b, 0x94, 0x14, 0xde, 0x07, 0x6e, 0xd3, 0xab, 0x02, 0x26, 0x74, 0x16, 0x12, 0xdf, 0x2e, 0x2a, 0xa7, 0xb0, 0xe8, 0x29, 0xc0,
+ /* (2^ 98)P */ 0x6a, 0x38, 0x0b, 0xd3, 0xba, 0x45, 0x23, 0xe0, 0x04, 0x3b, 0x83, 0x39, 0xc5, 0x11, 0xe6, 0xcf, 0x39, 0x0a, 0xb3, 0xb0, 0x3b, 0x27, 0x29, 0x63, 0x1c, 0xf3, 0x00, 0xe6, 0xd2, 0x55, 0x21, 0x1f, 0x84, 0x97, 0x9f, 0x01, 0x49, 0x43, 0x30, 0x5f, 0xe0, 0x1d, 0x24, 0xc4, 0x4e, 0xa0, 0x2b, 0x0b, 0x12, 0x55, 0xc3, 0x27, 0xae, 0x08, 0x83, 0x7c,
+ /* (2^ 99)P */ 0x5d, 0x1a, 0xb7, 0xa9, 0xf5, 0xfd, 0xec, 0xad, 0xb7, 0x87, 0x02, 0x5f, 0x0d, 0x30, 0x4d, 0xe2, 0x65, 0x87, 0xa4, 0x41, 0x45, 0x1d, 0x67, 0xe0, 0x30, 0x5c, 0x13, 0x87, 0xf6, 0x2e, 0x08, 0xc1, 0xc7, 0x12, 0x45, 0xc8, 0x9b, 0xad, 0xb8, 0xd5, 0x57, 0xbb, 0x5c, 0x48, 0x3a, 0xe1, 0x91, 0x5e, 0xf6, 0x4d, 0x8a, 0x63, 0x75, 0x69, 0x0c, 0x01,
+ /* (2^100)P */ 0x8f, 0x53, 0x2d, 0xa0, 0x71, 0x3d, 0xfc, 0x45, 0x10, 0x96, 0xcf, 0x56, 0xf9, 0xbb, 0x40, 0x3c, 0x86, 0x52, 0x76, 0xbe, 0x84, 0xf9, 0xa6, 0x9d, 0x3d, 0x27, 0xbe, 0xb4, 0x00, 0x49, 0x94, 0xf5, 0x5d, 0xe1, 0x62, 0x85, 0x66, 0xe5, 0xb8, 0x20, 0x2c, 0x09, 0x7d, 0x9d, 0x3d, 0x6e, 0x74, 0x39, 0xab, 0xad, 0xa0, 0x90, 0x97, 0x5f, 0xbb, 0xa7,
+ /* (2^101)P */ 0xdb, 0x2d, 0x99, 0x08, 0x16, 0x46, 0x83, 0x7a, 0xa8, 0xea, 0x3d, 0x28, 0x5b, 0x49, 0xfc, 0xb9, 0x6d, 0x00, 0x9e, 0x54, 0x4f, 0x47, 0x64, 0x9b, 0x58, 0x4d, 0x07, 0x0c, 0x6f, 0x29, 0x56, 0x0b, 0x00, 0x14, 0x85, 0x96, 0x41, 0x04, 0xb9, 0x5c, 0xa4, 0xf6, 0x16, 0x73, 0x6a, 0xc7, 0x62, 0x0c, 0x65, 0x2f, 0x93, 0xbf, 0xf7, 0xb9, 0xb7, 0xf1,
+ /* (2^102)P */ 0xeb, 0x6d, 0xb3, 0x46, 0x32, 0xd2, 0xcb, 0x08, 0x94, 0x14, 0xbf, 0x3f, 0xc5, 0xcb, 0x5f, 0x9f, 0x8a, 0x89, 0x0c, 0x1b, 0x45, 0xad, 0x4c, 0x50, 0xb4, 0xe1, 0xa0, 0x6b, 0x11, 0x92, 0xaf, 0x1f, 0x00, 0xcc, 0xe5, 0x13, 0x7e, 0xe4, 0x2e, 0xa0, 0x57, 0xf3, 0xa7, 0x84, 0x79, 0x7a, 0xc2, 0xb7, 0xb7, 0xfc, 0x5d, 0xa5, 0xa9, 0x64, 0xcc, 0xd8,
+ /* (2^103)P */ 0xa9, 0xc4, 0x12, 0x8b, 0x34, 0x78, 0x3e, 0x38, 0xfd, 0x3f, 0x87, 0xfa, 0x88, 0x94, 0xd5, 0xd9, 0x7f, 0xeb, 0x58, 0xff, 0xb9, 0x45, 0xdb, 0xa1, 0xed, 0x22, 0x28, 0x1d, 0x00, 0x6d, 0x79, 0x85, 0x7a, 0x75, 0x5d, 0xf0, 0xb1, 0x9e, 0x47, 0x28, 0x8c, 0x62, 0xdf, 0xfb, 0x4c, 0x7b, 0xc5, 0x1a, 0x42, 0x95, 0xef, 0x9a, 0xb7, 0x27, 0x7e, 0xda,
+ /* (2^104)P */ 0xca, 0xd5, 0xc0, 0x17, 0xa1, 0x66, 0x79, 0x9c, 0x2a, 0xb7, 0x0a, 0xfe, 0x62, 0xe4, 0x26, 0x78, 0x90, 0xa7, 0xcb, 0xb0, 0x4f, 0x6d, 0xf9, 0x8f, 0xf7, 0x7d, 0xac, 0xb8, 0x78, 0x1f, 0x41, 0xea, 0x97, 0x1e, 0x62, 0x97, 0x43, 0x80, 0x58, 0x80, 0xb6, 0x69, 0x7d, 0xee, 0x16, 0xd2, 0xa1, 0x81, 0xd7, 0xb1, 0x27, 0x03, 0x48, 0xda, 0xab, 0xec,
+ /* (2^105)P */ 0x5b, 0xed, 0x40, 0x8e, 0x8c, 0xc1, 0x66, 0x90, 0x7f, 0x0c, 0xb2, 0xfc, 0xbd, 0x16, 0xac, 0x7d, 0x4c, 0x6a, 0xf9, 0xae, 0xe7, 0x4e, 0x11, 0x12, 0xe9, 0xbe, 0x17, 0x09, 0xc6, 0xc1, 0x5e, 0xb5, 0x7b, 0x50, 0x5c, 0x27, 0xfb, 0x80, 0xab, 0x01, 0xfa, 0x5b, 0x9b, 0x75, 0x16, 0x6e, 0xb2, 0x5c, 0x8c, 0x2f, 0xa5, 0x6a, 0x1a, 0x68, 0xa6, 0x90,
+ /* (2^106)P */ 0x75, 0xfe, 0xb6, 0x96, 0x96, 0x87, 0x4c, 0x12, 0xa9, 0xd1, 0xd8, 0x03, 0xa3, 0xc1, 0x15, 0x96, 0xe8, 0xa0, 0x75, 0x82, 0xa0, 0x6d, 0xea, 0x54, 0xdc, 0x5f, 0x0d, 0x7e, 0xf6, 0x70, 0xb5, 0xdc, 0x7a, 0xf6, 0xc4, 0xd4, 0x21, 0x49, 0xf5, 0xd4, 0x14, 0x6d, 0x48, 0x1d, 0x7c, 0x99, 0x42, 0xdf, 0x78, 0x6b, 0x9d, 0xb9, 0x30, 0x3c, 0xd0, 0x29,
+ /* (2^107)P */ 0x85, 0xd6, 0xd8, 0xf3, 0x91, 0x74, 0xdd, 0xbd, 0x72, 0x96, 0x10, 0xe4, 0x76, 0x02, 0x5a, 0x72, 0x67, 0xd3, 0x17, 0x72, 0x14, 0x9a, 0x20, 0x5b, 0x0f, 0x8d, 0xed, 0x6d, 0x4e, 0xe3, 0xd9, 0x82, 0xc2, 0x99, 0xee, 0x39, 0x61, 0x69, 0x8a, 0x24, 0x01, 0x92, 0x15, 0xe7, 0xfc, 0xf9, 0x4d, 0xac, 0xf1, 0x30, 0x49, 0x01, 0x0b, 0x6e, 0x0f, 0x20,
+ /* (2^108)P */ 0xd8, 0x25, 0x94, 0x5e, 0x43, 0x29, 0xf5, 0xcc, 0xe8, 0xe3, 0x55, 0x41, 0x3c, 0x9f, 0x58, 0x5b, 0x00, 0xeb, 0xc5, 0xdf, 0xcf, 0xfb, 0xfd, 0x6e, 0x92, 0xec, 0x99, 0x30, 0xd6, 0x05, 0xdd, 0x80, 0x7a, 0x5d, 0x6d, 0x16, 0x85, 0xd8, 0x9d, 0x43, 0x65, 0xd8, 0x2c, 0x33, 0x2f, 0x5c, 0x41, 0xea, 0xb7, 0x95, 0x77, 0xf2, 0x9e, 0x59, 0x09, 0xe8,
+ /* (2^109)P */ 0x00, 0xa0, 0x03, 0x80, 0xcd, 0x60, 0xe5, 0x17, 0xd4, 0x15, 0x99, 0xdd, 0x4f, 0xbf, 0x66, 0xb8, 0xc0, 0xf5, 0xf9, 0xfc, 0x6d, 0x42, 0x18, 0x34, 0x1c, 0x7d, 0x5b, 0xb5, 0x09, 0xd0, 0x99, 0x57, 0x81, 0x0b, 0x62, 0xb3, 0xa2, 0xf9, 0x0b, 0xae, 0x95, 0xb8, 0xc2, 0x3b, 0x0d, 0x5b, 0x00, 0xf1, 0xed, 0xbc, 0x05, 0x9d, 0x61, 0xbc, 0x73, 0x9d,
+ /* (2^110)P */ 0xd4, 0xdb, 0x29, 0xe5, 0x85, 0xe9, 0xc6, 0x89, 0x2a, 0xa8, 0x54, 0xab, 0xb3, 0x7f, 0x88, 0xc0, 0x4d, 0xe0, 0xd1, 0x74, 0x6e, 0xa3, 0xa7, 0x39, 0xd5, 0xcc, 0xa1, 0x8a, 0xcb, 0x5b, 0x34, 0xad, 0x92, 0xb4, 0xd8, 0xd5, 0x17, 0xf6, 0x77, 0x18, 0x9e, 0xaf, 0x45, 0x3b, 0x03, 0xe2, 0xf8, 0x52, 0x60, 0xdc, 0x15, 0x20, 0x9e, 0xdf, 0xd8, 0x5d,
+ /* (2^111)P */ 0x02, 0xc1, 0xac, 0x1a, 0x15, 0x8e, 0x6c, 0xf5, 0x1e, 0x1e, 0xba, 0x7e, 0xc2, 0xda, 0x7d, 0x02, 0xda, 0x43, 0xae, 0x04, 0x70, 0x28, 0x54, 0x78, 0x94, 0xf5, 0x4f, 0x07, 0x84, 0x8f, 0xed, 0xaa, 0xc0, 0xb8, 0xcd, 0x7f, 0x7e, 0x33, 0xa3, 0xbe, 0x21, 0x29, 0xc8, 0x56, 0x34, 0xc0, 0x76, 0x87, 0x8f, 0xc7, 0x73, 0x58, 0x90, 0x16, 0xfc, 0xd6,
+ /* (2^112)P */ 0xb8, 0x3f, 0xe1, 0xdf, 0x3a, 0x91, 0x25, 0x0c, 0xf6, 0x47, 0xa8, 0x89, 0xc4, 0xc6, 0x61, 0xec, 0x86, 0x2c, 0xfd, 0xbe, 0xa4, 0x6f, 0xc2, 0xd4, 0x46, 0x19, 0x70, 0x5d, 0x09, 0x02, 0x86, 0xd3, 0x4b, 0xe9, 0x16, 0x7b, 0xf0, 0x0d, 0x6c, 0xff, 0x91, 0x05, 0xbf, 0x55, 0xb4, 0x00, 0x8d, 0xe5, 0x6d, 0x68, 0x20, 0x90, 0x12, 0xb5, 0x5c, 0x32,
+ /* (2^113)P */ 0x80, 0x45, 0xc8, 0x51, 0x87, 0xba, 0x1c, 0x5c, 0xcf, 0x5f, 0x4b, 0x3c, 0x9e, 0x3b, 0x36, 0xd2, 0x26, 0xa2, 0x7f, 0xab, 0xb7, 0xbf, 0xda, 0x68, 0x23, 0x8f, 0xc3, 0xa0, 0xfd, 0xad, 0xf1, 0x56, 0x3b, 0xd0, 0x75, 0x2b, 0x44, 0x61, 0xd8, 0xf4, 0xf1, 0x05, 0x49, 0x53, 0x07, 0xee, 0x47, 0xef, 0xc0, 0x7c, 0x9d, 0xe4, 0x15, 0x88, 0xc5, 0x47,
+ /* (2^114)P */ 0x2d, 0xb5, 0x09, 0x80, 0xb9, 0xd3, 0xd8, 0xfe, 0x4c, 0xd2, 0xa6, 0x6e, 0xd3, 0x75, 0xcf, 0xb0, 0x99, 0xcb, 0x50, 0x8d, 0xe9, 0x67, 0x9b, 0x20, 0xe8, 0x57, 0xd8, 0x14, 0x85, 0x73, 0x6a, 0x74, 0xe0, 0x99, 0xf0, 0x6b, 0x6e, 0x59, 0x30, 0x31, 0x33, 0x96, 0x5f, 0xa1, 0x0c, 0x1b, 0xf4, 0xca, 0x09, 0xe1, 0x9b, 0xb5, 0xcf, 0x6d, 0x0b, 0xeb,
+ /* (2^115)P */ 0x1a, 0xde, 0x50, 0xa9, 0xac, 0x3e, 0x10, 0x43, 0x4f, 0x82, 0x4f, 0xc0, 0xfe, 0x3f, 0x33, 0xd2, 0x64, 0x86, 0x50, 0xa9, 0x51, 0x76, 0x5e, 0x50, 0x97, 0x6c, 0x73, 0x8d, 0x77, 0xa3, 0x75, 0x03, 0xbc, 0xc9, 0xfb, 0x50, 0xd9, 0x6d, 0x16, 0xad, 0x5d, 0x32, 0x3d, 0xac, 0x44, 0xdf, 0x51, 0xf7, 0x19, 0xd4, 0x0b, 0x57, 0x78, 0x0b, 0x81, 0x4e,
+ /* (2^116)P */ 0x32, 0x24, 0xf1, 0x6c, 0x55, 0x62, 0x1d, 0xb3, 0x1f, 0xda, 0xfa, 0x6a, 0x8f, 0x98, 0x01, 0x16, 0xde, 0x44, 0x50, 0x0d, 0x2e, 0x6c, 0x0b, 0xa2, 0xd3, 0x74, 0x0e, 0xa9, 0xbf, 0x8d, 0xa9, 0xc8, 0xc8, 0x2f, 0x62, 0xc1, 0x35, 0x5e, 0xfd, 0x3a, 0xb3, 0x83, 0x2d, 0xee, 0x4e, 0xfd, 0x5c, 0x5e, 0xad, 0x85, 0xa5, 0x10, 0xb5, 0x4f, 0x34, 0xa7,
+ /* (2^117)P */ 0xd1, 0x58, 0x6f, 0xe6, 0x54, 0x2c, 0xc2, 0xcd, 0xcf, 0x83, 0xdc, 0x88, 0x0c, 0xb9, 0xb4, 0x62, 0x18, 0x89, 0x65, 0x28, 0xe9, 0x72, 0x4b, 0x65, 0xcf, 0xd6, 0x90, 0x88, 0xd7, 0x76, 0x17, 0x4f, 0x74, 0x64, 0x1e, 0xcb, 0xd3, 0xf5, 0x4b, 0xaa, 0x2e, 0x4d, 0x2d, 0x7c, 0x13, 0x1f, 0xfd, 0xd9, 0x60, 0x83, 0x7e, 0xda, 0x64, 0x1c, 0xdc, 0x9f,
+ /* (2^118)P */ 0xad, 0xef, 0xac, 0x1b, 0xc1, 0x30, 0x5a, 0x15, 0xc9, 0x1f, 0xac, 0xf1, 0xca, 0x44, 0x95, 0x95, 0xea, 0xf2, 0x22, 0xe7, 0x8d, 0x25, 0xf0, 0xff, 0xd8, 0x71, 0xf7, 0xf8, 0x8f, 0x8f, 0xcd, 0xf4, 0x1e, 0xfe, 0x6c, 0x68, 0x04, 0xb8, 0x78, 0xa1, 0x5f, 0xa6, 0x5d, 0x5e, 0xf9, 0x8d, 0xea, 0x80, 0xcb, 0xf3, 0x17, 0xa6, 0x03, 0xc9, 0x38, 0xd5,
+ /* (2^119)P */ 0x79, 0x14, 0x31, 0xc3, 0x38, 0xe5, 0xaa, 0xbf, 0x17, 0xa3, 0x04, 0x4e, 0x80, 0x59, 0x9c, 0x9f, 0x19, 0x39, 0xe4, 0x2d, 0x23, 0x54, 0x4a, 0x7f, 0x3e, 0xf3, 0xd9, 0xc7, 0xba, 0x6c, 0x8f, 0x6b, 0xfa, 0x34, 0xb5, 0x23, 0x17, 0x1d, 0xff, 0x1d, 0xea, 0x1f, 0xd7, 0xba, 0x61, 0xb2, 0xe0, 0x38, 0x6a, 0xe9, 0xcf, 0x48, 0x5d, 0x6a, 0x10, 0x9c,
+ /* (2^120)P */ 0xc8, 0xbb, 0x13, 0x1c, 0x3f, 0x3c, 0x34, 0xfd, 0xac, 0x37, 0x52, 0x44, 0x25, 0xa8, 0xde, 0x1d, 0x63, 0xf4, 0x81, 0x9a, 0xbe, 0x0b, 0x74, 0x2e, 0xc8, 0x51, 0x16, 0xd3, 0xac, 0x4a, 0xaf, 0xe2, 0x5f, 0x3a, 0x89, 0x32, 0xd1, 0x9b, 0x7c, 0x90, 0x0d, 0xac, 0xdc, 0x8b, 0x73, 0x45, 0x45, 0x97, 0xb1, 0x90, 0x2c, 0x1b, 0x31, 0xca, 0xb1, 0x94,
+ /* (2^121)P */ 0x07, 0x28, 0xdd, 0x10, 0x14, 0xa5, 0x95, 0x7e, 0xf3, 0xe4, 0xd4, 0x14, 0xb4, 0x7e, 0x76, 0xdb, 0x42, 0xd6, 0x94, 0x3e, 0xeb, 0x44, 0x64, 0x88, 0x0d, 0xec, 0xc1, 0x21, 0xf0, 0x79, 0xe0, 0x83, 0x67, 0x55, 0x53, 0xc2, 0xf6, 0xc5, 0xc5, 0x89, 0x39, 0xe8, 0x42, 0xd0, 0x17, 0xbd, 0xff, 0x35, 0x59, 0x0e, 0xc3, 0x06, 0x86, 0xd4, 0x64, 0xcf,
+ /* (2^122)P */ 0x91, 0xa8, 0xdb, 0x57, 0x9b, 0xe2, 0x96, 0x31, 0x10, 0x6e, 0xd7, 0x9a, 0x97, 0xb3, 0xab, 0xb5, 0x15, 0x66, 0xbe, 0xcc, 0x6d, 0x9a, 0xac, 0x06, 0xb3, 0x0d, 0xaa, 0x4b, 0x9c, 0x96, 0x79, 0x6c, 0x34, 0xee, 0x9e, 0x53, 0x4d, 0x6e, 0xbd, 0x88, 0x02, 0xbf, 0x50, 0x54, 0x12, 0x5d, 0x01, 0x02, 0x46, 0xc6, 0x74, 0x02, 0x8c, 0x24, 0xae, 0xb1,
+ /* (2^123)P */ 0xf5, 0x22, 0xea, 0xac, 0x7d, 0x9c, 0x33, 0x8a, 0xa5, 0x36, 0x79, 0x6a, 0x4f, 0xa4, 0xdc, 0xa5, 0x73, 0x64, 0xc4, 0x6f, 0x43, 0x02, 0x3b, 0x94, 0x66, 0xd2, 0x4b, 0x4f, 0xf6, 0x45, 0x33, 0x5d, 0x10, 0x33, 0x18, 0x1e, 0xa3, 0xfc, 0xf7, 0xd2, 0xb8, 0xc8, 0xa7, 0xe0, 0x76, 0x8a, 0xcd, 0xff, 0x4f, 0x99, 0x34, 0x47, 0x84, 0x91, 0x96, 0x9f,
+ /* (2^124)P */ 0x8a, 0x48, 0x3b, 0x48, 0x4a, 0xbc, 0xac, 0xe2, 0x80, 0xd6, 0xd2, 0x35, 0xde, 0xd0, 0x56, 0x42, 0x33, 0xb3, 0x56, 0x5a, 0xcd, 0xb8, 0x3d, 0xb5, 0x25, 0xc1, 0xed, 0xff, 0x87, 0x0b, 0x79, 0xff, 0xf2, 0x62, 0xe1, 0x76, 0xc6, 0xa2, 0x0f, 0xa8, 0x9b, 0x0d, 0xcc, 0x3f, 0x3d, 0x35, 0x27, 0x8d, 0x0b, 0x74, 0xb0, 0xc3, 0x78, 0x8c, 0xcc, 0xc8,
+ /* (2^125)P */ 0xfc, 0x9a, 0x0c, 0xa8, 0x49, 0x42, 0xb8, 0xdf, 0xcf, 0xb3, 0x19, 0xa6, 0x64, 0x57, 0xfe, 0xe8, 0xf8, 0xa6, 0x4b, 0x86, 0xa1, 0xd5, 0x83, 0x7f, 0x14, 0x99, 0x18, 0x0c, 0x7d, 0x5b, 0xf7, 0x3d, 0xf9, 0x4b, 0x79, 0xb1, 0x86, 0x30, 0xb4, 0x5e, 0x6a, 0xe8, 0x9d, 0xfa, 0x8a, 0x41, 0xc4, 0x30, 0xfc, 0x56, 0x74, 0x14, 0x42, 0xc8, 0x96, 0x0e,
+ /* (2^126)P */ 0xdf, 0x66, 0xec, 0xbc, 0x44, 0xdb, 0x19, 0xce, 0xd4, 0xb5, 0x49, 0x40, 0x07, 0x49, 0xe0, 0x3a, 0x61, 0x10, 0xfb, 0x7d, 0xba, 0xb1, 0xe0, 0x28, 0x5b, 0x99, 0x59, 0x96, 0xa2, 0xee, 0xe0, 0x23, 0x37, 0x39, 0x1f, 0xe6, 0x57, 0x9f, 0xf8, 0xf8, 0xdc, 0x74, 0xf6, 0x8f, 0x4f, 0x5e, 0x51, 0xa4, 0x12, 0xac, 0xbe, 0xe4, 0xf3, 0xd1, 0xf0, 0x24,
+ /* (2^127)P */ 0x1e, 0x3e, 0x9a, 0x5f, 0xdf, 0x9f, 0xd6, 0x4e, 0x8a, 0x28, 0xc3, 0xcd, 0x96, 0x9d, 0x57, 0xc7, 0x61, 0x81, 0x90, 0xff, 0xae, 0xb1, 0x4f, 0xc2, 0x96, 0x8b, 0x1a, 0x18, 0xf4, 0x50, 0xcb, 0x31, 0xe1, 0x57, 0xf4, 0x90, 0xa8, 0xea, 0xac, 0xe7, 0x61, 0x98, 0xb6, 0x15, 0xc1, 0x7b, 0x29, 0xa4, 0xc3, 0x18, 0xef, 0xb9, 0xd8, 0xdf, 0xf6, 0xac,
+ /* (2^128)P */ 0xca, 0xa8, 0x6c, 0xf1, 0xb4, 0xca, 0xfe, 0x31, 0xee, 0x48, 0x38, 0x8b, 0x0e, 0xbb, 0x7a, 0x30, 0xaa, 0xf9, 0xee, 0x27, 0x53, 0x24, 0xdc, 0x2e, 0x15, 0xa6, 0x48, 0x8f, 0xa0, 0x7e, 0xf1, 0xdc, 0x93, 0x87, 0x39, 0xeb, 0x7f, 0x38, 0x92, 0x92, 0x4c, 0x29, 0xe9, 0x57, 0xd8, 0x59, 0xfc, 0xe9, 0x9c, 0x44, 0xc0, 0x65, 0xcf, 0xac, 0x4b, 0xdc,
+ /* (2^129)P */ 0xa3, 0xd0, 0x37, 0x8f, 0x86, 0x2f, 0xc6, 0x47, 0x55, 0x46, 0x65, 0x26, 0x4b, 0x91, 0xe2, 0x18, 0x5c, 0x4f, 0x23, 0xc1, 0x37, 0x29, 0xb9, 0xc1, 0x27, 0xc5, 0x3c, 0xbf, 0x7e, 0x23, 0xdb, 0x73, 0x99, 0xbd, 0x1b, 0xb2, 0x31, 0x68, 0x3a, 0xad, 0xb7, 0xb0, 0x10, 0xc5, 0xe5, 0x11, 0x51, 0xba, 0xa7, 0x60, 0x66, 0x54, 0xf0, 0x08, 0xd7, 0x69,
+ /* (2^130)P */ 0x89, 0x41, 0x79, 0xcc, 0xeb, 0x0a, 0xf5, 0x4b, 0xa3, 0x4c, 0xce, 0x52, 0xb0, 0xa7, 0xe4, 0x41, 0x75, 0x7d, 0x04, 0xbb, 0x09, 0x4c, 0x50, 0x9f, 0xdf, 0xea, 0x74, 0x61, 0x02, 0xad, 0xb4, 0x9d, 0xb7, 0x05, 0xb9, 0xea, 0xeb, 0x91, 0x35, 0xe7, 0x49, 0xea, 0xd3, 0x4f, 0x3c, 0x60, 0x21, 0x7a, 0xde, 0xc7, 0xe2, 0x5a, 0xee, 0x8e, 0x93, 0xc7,
+ /* (2^131)P */ 0x00, 0xe8, 0xed, 0xd0, 0xb3, 0x0d, 0xaf, 0xb2, 0xde, 0x2c, 0xf6, 0x00, 0xe2, 0xea, 0x6d, 0xf8, 0x0e, 0xd9, 0x67, 0x59, 0xa9, 0x50, 0xbb, 0x17, 0x8f, 0xff, 0xb1, 0x9f, 0x17, 0xb6, 0xf2, 0xb5, 0xba, 0x80, 0xf7, 0x0f, 0xba, 0xd5, 0x09, 0x43, 0xaa, 0x4e, 0x3a, 0x67, 0x6a, 0x89, 0x9b, 0x18, 0x65, 0x35, 0xf8, 0x3a, 0x49, 0x91, 0x30, 0x51,
+ /* (2^132)P */ 0x8d, 0x25, 0xe9, 0x0e, 0x7d, 0x50, 0x76, 0xe4, 0x58, 0x7e, 0xb9, 0x33, 0xe6, 0x65, 0x90, 0xc2, 0x50, 0x9d, 0x50, 0x2e, 0x11, 0xad, 0xd5, 0x43, 0x52, 0x32, 0x41, 0x4f, 0x7b, 0xb6, 0xa0, 0xec, 0x81, 0x75, 0x36, 0x7c, 0x77, 0x85, 0x59, 0x70, 0xe4, 0xf9, 0xef, 0x66, 0x8d, 0x35, 0xc8, 0x2a, 0x6e, 0x5b, 0xc6, 0x0d, 0x0b, 0x29, 0x60, 0x68,
+ /* (2^133)P */ 0xf8, 0xce, 0xb0, 0x3a, 0x56, 0x7d, 0x51, 0x9a, 0x25, 0x73, 0xea, 0xdd, 0xe4, 0xe0, 0x0e, 0xf0, 0x07, 0xc0, 0x31, 0x00, 0x73, 0x35, 0xd0, 0x39, 0xc4, 0x9b, 0xb7, 0x95, 0xe0, 0x62, 0x70, 0x36, 0x0b, 0xcb, 0xa0, 0x42, 0xde, 0x51, 0xcf, 0x41, 0xe0, 0xb8, 0xb4, 0xc0, 0xe5, 0x46, 0x99, 0x9f, 0x02, 0x7f, 0x14, 0x8c, 0xc1, 0x4e, 0xef, 0xe8,
+ /* (2^134)P */ 0x10, 0x01, 0x57, 0x0a, 0xbe, 0x8b, 0x18, 0xc8, 0xca, 0x00, 0x28, 0x77, 0x4a, 0x9a, 0xc7, 0x55, 0x2a, 0xcc, 0x0c, 0x7b, 0xb9, 0xe9, 0xc8, 0x97, 0x7c, 0x02, 0xe3, 0x09, 0x2f, 0x62, 0x30, 0xb8, 0x40, 0x09, 0x65, 0xe9, 0x55, 0x63, 0xb5, 0x07, 0xca, 0x9f, 0x00, 0xdf, 0x9d, 0x5c, 0xc7, 0xee, 0x57, 0xa5, 0x90, 0x15, 0x1e, 0x22, 0xa0, 0x12,
+ /* (2^135)P */ 0x71, 0x2d, 0xc9, 0xef, 0x27, 0xb9, 0xd8, 0x12, 0x43, 0x6b, 0xa8, 0xce, 0x3b, 0x6d, 0x6e, 0x91, 0x43, 0x23, 0xbc, 0x32, 0xb3, 0xbf, 0xe1, 0xc7, 0x39, 0xcf, 0x7c, 0x42, 0x4c, 0xb1, 0x30, 0xe2, 0xdd, 0x69, 0x06, 0xe5, 0xea, 0xf0, 0x2a, 0x16, 0x50, 0x71, 0xca, 0x92, 0xdf, 0xc1, 0xcc, 0xec, 0xe6, 0x54, 0x07, 0xf3, 0x18, 0x8d, 0xd8, 0x29,
+ /* (2^136)P */ 0x98, 0x51, 0x48, 0x8f, 0xfa, 0x2e, 0x5e, 0x67, 0xb0, 0xc6, 0x17, 0x12, 0xb6, 0x7d, 0xc9, 0xad, 0x81, 0x11, 0xad, 0x0c, 0x1c, 0x2d, 0x45, 0xdf, 0xac, 0x66, 0xbd, 0x08, 0x6f, 0x7c, 0xc7, 0x06, 0x6e, 0x19, 0x08, 0x39, 0x64, 0xd7, 0xe4, 0xd1, 0x11, 0x5f, 0x1c, 0xf4, 0x67, 0xc3, 0x88, 0x6a, 0xe6, 0x07, 0xa3, 0x83, 0xd7, 0xfd, 0x2a, 0xf9,
+ /* (2^137)P */ 0x87, 0xed, 0xeb, 0xd9, 0xdf, 0xff, 0x43, 0x8b, 0xaa, 0x20, 0x58, 0xb0, 0xb4, 0x6b, 0x14, 0xb8, 0x02, 0xc5, 0x40, 0x20, 0x22, 0xbb, 0xf7, 0xb4, 0xf3, 0x05, 0x1e, 0x4d, 0x94, 0xff, 0xe3, 0xc5, 0x22, 0x82, 0xfe, 0xaf, 0x90, 0x42, 0x98, 0x6b, 0x76, 0x8b, 0x3e, 0x89, 0x3f, 0x42, 0x2a, 0xa7, 0x26, 0x00, 0xda, 0x5c, 0xa2, 0x2b, 0xec, 0xdd,
+ /* (2^138)P */ 0x5c, 0x21, 0x16, 0x0d, 0x46, 0xb8, 0xd0, 0xa7, 0x88, 0xe7, 0x25, 0xcb, 0x3e, 0x50, 0x73, 0x61, 0xe7, 0xaf, 0x5a, 0x3f, 0x47, 0x8b, 0x3d, 0x97, 0x79, 0x2c, 0xe6, 0x6d, 0x95, 0x74, 0x65, 0x70, 0x36, 0xfd, 0xd1, 0x9e, 0x13, 0x18, 0x63, 0xb1, 0x2d, 0x0b, 0xb5, 0x36, 0x3e, 0xe7, 0x35, 0x42, 0x3b, 0xe6, 0x1f, 0x4d, 0x9d, 0x59, 0xa2, 0x43,
+ /* (2^139)P */ 0x8c, 0x0c, 0x7c, 0x24, 0x9e, 0xe0, 0xf8, 0x05, 0x1c, 0x9e, 0x1f, 0x31, 0xc0, 0x70, 0xb3, 0xfb, 0x4e, 0xf8, 0x0a, 0x57, 0xb7, 0x49, 0xb5, 0x73, 0xa1, 0x5f, 0x9b, 0x6a, 0x07, 0x6c, 0x87, 0x71, 0x87, 0xd4, 0xbe, 0x98, 0x1e, 0x98, 0xee, 0x52, 0xc1, 0x7b, 0x95, 0x0f, 0x28, 0x32, 0x36, 0x28, 0xd0, 0x3a, 0x0f, 0x7d, 0x2a, 0xa9, 0x62, 0xb9,
+ /* (2^140)P */ 0x97, 0xe6, 0x18, 0x77, 0xf9, 0x34, 0xac, 0xbc, 0xe0, 0x62, 0x9f, 0x42, 0xde, 0xbd, 0x2f, 0xf7, 0x1f, 0xb7, 0x14, 0x52, 0x8a, 0x79, 0xb2, 0x3f, 0xd2, 0x95, 0x71, 0x01, 0xe8, 0xaf, 0x8c, 0xa4, 0xa4, 0xa7, 0x27, 0xf3, 0x5c, 0xdf, 0x3e, 0x57, 0x7a, 0xf1, 0x76, 0x49, 0xe6, 0x42, 0x3f, 0x8f, 0x1e, 0x63, 0x4a, 0x65, 0xb5, 0x41, 0xf5, 0x02,
+ /* (2^141)P */ 0x72, 0x85, 0xc5, 0x0b, 0xe1, 0x47, 0x64, 0x02, 0xc5, 0x4d, 0x81, 0x69, 0xb2, 0xcf, 0x0f, 0x6c, 0xd4, 0x6d, 0xd0, 0xc7, 0xb4, 0x1c, 0xd0, 0x32, 0x59, 0x89, 0xe2, 0xe0, 0x96, 0x8b, 0x12, 0x98, 0xbf, 0x63, 0x7a, 0x4c, 0x76, 0x7e, 0x58, 0x17, 0x8f, 0x5b, 0x0a, 0x59, 0x65, 0x75, 0xbc, 0x61, 0x1f, 0xbe, 0xc5, 0x6e, 0x0a, 0x57, 0x52, 0x70,
+ /* (2^142)P */ 0x92, 0x1c, 0x77, 0xbb, 0x62, 0x02, 0x6c, 0x25, 0x9c, 0x66, 0x07, 0x83, 0xab, 0xcc, 0x80, 0x5d, 0xd2, 0x76, 0x0c, 0xa4, 0xc5, 0xb4, 0x8a, 0x68, 0x23, 0x31, 0x32, 0x29, 0x8a, 0x47, 0x92, 0x12, 0x80, 0xb3, 0xfa, 0x18, 0xe4, 0x8d, 0xc0, 0x4d, 0xfe, 0x97, 0x5f, 0x72, 0x41, 0xb5, 0x5c, 0x7a, 0xbd, 0xf0, 0xcf, 0x5e, 0x97, 0xaa, 0x64, 0x32,
+ /* (2^143)P */ 0x35, 0x3f, 0x75, 0xc1, 0x7a, 0x75, 0x7e, 0xa9, 0xc6, 0x0b, 0x4e, 0x32, 0x62, 0xec, 0xe3, 0x5c, 0xfb, 0x01, 0x43, 0xb6, 0xd4, 0x5b, 0x75, 0xd2, 0xee, 0x7f, 0x5d, 0x23, 0x2b, 0xb3, 0x54, 0x34, 0x4c, 0xd3, 0xb4, 0x32, 0x84, 0x81, 0xb5, 0x09, 0x76, 0x19, 0xda, 0x58, 0xda, 0x7c, 0xdb, 0x2e, 0xdd, 0x4c, 0x8e, 0xdd, 0x5d, 0x89, 0x10, 0x10,
+ /* (2^144)P */ 0x57, 0x25, 0x6a, 0x08, 0x37, 0x92, 0xa8, 0xdf, 0x24, 0xef, 0x8f, 0x33, 0x34, 0x52, 0xa4, 0x4c, 0xf0, 0x77, 0x9f, 0x69, 0x77, 0xd5, 0x8f, 0xd2, 0x9a, 0xb3, 0xb6, 0x1d, 0x2d, 0xa6, 0xf7, 0x1f, 0xda, 0xd7, 0xcb, 0x75, 0x11, 0xc3, 0x6b, 0xc0, 0x38, 0xb1, 0xd5, 0x2d, 0x96, 0x84, 0x16, 0xfa, 0x26, 0xb9, 0xcc, 0x3f, 0x16, 0x47, 0x23, 0x74,
+ /* (2^145)P */ 0x9b, 0x61, 0x2a, 0x1c, 0xdd, 0x39, 0xa5, 0xfa, 0x1c, 0x7d, 0x63, 0x50, 0xca, 0xe6, 0x9d, 0xfa, 0xb7, 0xc4, 0x4c, 0x6a, 0x97, 0x5f, 0x36, 0x4e, 0x47, 0xdd, 0x17, 0xf7, 0xf9, 0x19, 0xce, 0x75, 0x17, 0xad, 0xce, 0x2a, 0xf3, 0xfe, 0x27, 0x8f, 0x3e, 0x48, 0xc0, 0x60, 0x87, 0x24, 0x19, 0xae, 0x59, 0xe4, 0x5a, 0x00, 0x2a, 0xba, 0xa2, 0x1f,
+ /* (2^146)P */ 0x26, 0x88, 0x42, 0x60, 0x9f, 0x6e, 0x2c, 0x7c, 0x39, 0x0f, 0x47, 0x6a, 0x0e, 0x02, 0xbb, 0x4b, 0x34, 0x29, 0x55, 0x18, 0x36, 0xcf, 0x3b, 0x47, 0xf1, 0x2e, 0xfc, 0x6e, 0x94, 0xff, 0xe8, 0x6b, 0x06, 0xd2, 0xba, 0x77, 0x5e, 0x60, 0xd7, 0x19, 0xef, 0x02, 0x9d, 0x3a, 0xc2, 0xb7, 0xa9, 0xd8, 0x57, 0xee, 0x7e, 0x2b, 0xf2, 0x6d, 0x28, 0xda,
+ /* (2^147)P */ 0xdf, 0xd9, 0x92, 0x11, 0x98, 0x23, 0xe2, 0x45, 0x2f, 0x74, 0x70, 0xee, 0x0e, 0x55, 0x65, 0x79, 0x86, 0x38, 0x17, 0x92, 0x85, 0x87, 0x99, 0x50, 0xd9, 0x7c, 0xdb, 0xa1, 0x10, 0xec, 0x30, 0xb7, 0x40, 0xa3, 0x23, 0x9b, 0x0e, 0x27, 0x49, 0x29, 0x03, 0x94, 0xff, 0x53, 0xdc, 0xd7, 0xed, 0x49, 0xa9, 0x5a, 0x3b, 0xee, 0xd7, 0xc7, 0x65, 0xaf,
+ /* (2^148)P */ 0xa0, 0xbd, 0xbe, 0x03, 0xee, 0x0c, 0xbe, 0x32, 0x00, 0x7b, 0x52, 0xcb, 0x92, 0x29, 0xbf, 0xa0, 0xc6, 0xd9, 0xd2, 0xd6, 0x15, 0xe8, 0x3a, 0x75, 0x61, 0x65, 0x56, 0xae, 0xad, 0x3c, 0x2a, 0x64, 0x14, 0x3f, 0x8e, 0xc1, 0x2d, 0x0c, 0x8d, 0x20, 0xdb, 0x58, 0x4b, 0xe5, 0x40, 0x15, 0x4b, 0xdc, 0xa8, 0xbd, 0xef, 0x08, 0xa7, 0xd1, 0xf4, 0xb0,
+ /* (2^149)P */ 0xa9, 0x0f, 0x05, 0x94, 0x66, 0xac, 0x1f, 0x65, 0x3f, 0xe1, 0xb8, 0xe1, 0x34, 0x5e, 0x1d, 0x8f, 0xe3, 0x93, 0x03, 0x15, 0xff, 0xb6, 0x65, 0xb6, 0x6e, 0xc0, 0x2f, 0xd4, 0x2e, 0xb9, 0x2c, 0x13, 0x3c, 0x99, 0x1c, 0xb5, 0x87, 0xba, 0x79, 0xcb, 0xf0, 0x18, 0x06, 0x86, 0x04, 0x14, 0x25, 0x09, 0xcd, 0x1c, 0x14, 0xda, 0x35, 0xd0, 0x38, 0x3b,
+ /* (2^150)P */ 0x1b, 0x04, 0xa3, 0x27, 0xb4, 0xd3, 0x37, 0x48, 0x1e, 0x8f, 0x69, 0xd3, 0x5a, 0x2f, 0x20, 0x02, 0x36, 0xbe, 0x06, 0x7b, 0x6b, 0x6c, 0x12, 0x5b, 0x80, 0x74, 0x44, 0xe6, 0xf8, 0xf5, 0x95, 0x59, 0x29, 0xab, 0x51, 0x47, 0x83, 0x28, 0xe0, 0xad, 0xde, 0xaa, 0xd3, 0xb1, 0x1a, 0xcb, 0xa3, 0xcd, 0x8b, 0x6a, 0xb1, 0xa7, 0x0a, 0xd1, 0xf9, 0xbe,
+ /* (2^151)P */ 0xce, 0x2f, 0x85, 0xca, 0x74, 0x6d, 0x49, 0xb8, 0xce, 0x80, 0x44, 0xe0, 0xda, 0x5b, 0xcf, 0x2f, 0x79, 0x74, 0xfe, 0xb4, 0x2c, 0x99, 0x20, 0x6e, 0x09, 0x04, 0xfb, 0x6d, 0x57, 0x5b, 0x95, 0x0c, 0x45, 0xda, 0x4f, 0x7f, 0x63, 0xcc, 0x85, 0x5a, 0x67, 0x50, 0x68, 0x71, 0xb4, 0x67, 0xb1, 0x2e, 0xc1, 0x1c, 0xdc, 0xff, 0x2a, 0x7c, 0x10, 0x5e,
+ /* (2^152)P */ 0xa6, 0xde, 0xf3, 0xd4, 0x22, 0x30, 0x24, 0x9e, 0x0b, 0x30, 0x54, 0x59, 0x7e, 0xa2, 0xeb, 0x89, 0x54, 0x65, 0x3e, 0x40, 0xd1, 0xde, 0xe6, 0xee, 0x4d, 0xbf, 0x5e, 0x40, 0x1d, 0xee, 0x4f, 0x68, 0xd9, 0xa7, 0x2f, 0xb3, 0x64, 0xb3, 0xf5, 0xc8, 0xd3, 0xaa, 0x70, 0x70, 0x3d, 0xef, 0xd3, 0x95, 0x54, 0xdb, 0x3e, 0x94, 0x95, 0x92, 0x1f, 0x45,
+ /* (2^153)P */ 0x22, 0x80, 0x1d, 0x9d, 0x96, 0xa5, 0x78, 0x6f, 0xe0, 0x1e, 0x1b, 0x66, 0x42, 0xc8, 0xae, 0x9e, 0x46, 0x45, 0x08, 0x41, 0xdf, 0x80, 0xae, 0x6f, 0xdb, 0x15, 0x5a, 0x21, 0x31, 0x7a, 0xd0, 0xf2, 0x54, 0x15, 0x88, 0xd3, 0x0f, 0x7f, 0x14, 0x5a, 0x14, 0x97, 0xab, 0xf4, 0x58, 0x6a, 0x9f, 0xea, 0x74, 0xe5, 0x6b, 0x90, 0x59, 0x2b, 0x48, 0xd9,
+ /* (2^154)P */ 0x12, 0x24, 0x04, 0xf5, 0x50, 0xc2, 0x8c, 0xb0, 0x7c, 0x46, 0x98, 0xd5, 0x24, 0xad, 0xf6, 0x72, 0xdc, 0x82, 0x1a, 0x60, 0xc1, 0xeb, 0x48, 0xef, 0x7f, 0x6e, 0xe6, 0xcc, 0xdb, 0x7b, 0xae, 0xbe, 0x5e, 0x1e, 0x5c, 0xe6, 0x0a, 0x70, 0xdf, 0xa4, 0xa3, 0x85, 0x1b, 0x1b, 0x7f, 0x72, 0xb9, 0x96, 0x6f, 0xdc, 0x03, 0x76, 0x66, 0xfb, 0xa0, 0x33,
+ /* (2^155)P */ 0x37, 0x40, 0xbb, 0xbc, 0x68, 0x58, 0x86, 0xca, 0xbb, 0xa5, 0x24, 0x76, 0x3d, 0x48, 0xd1, 0xad, 0xb4, 0xa8, 0xcf, 0xc3, 0xb6, 0xa8, 0xba, 0x1a, 0x3a, 0xbe, 0x33, 0x75, 0x04, 0x5c, 0x13, 0x8c, 0x0d, 0x70, 0x8d, 0xa6, 0x4e, 0x2a, 0xeb, 0x17, 0x3c, 0x22, 0xdd, 0x3e, 0x96, 0x40, 0x11, 0x9e, 0x4e, 0xae, 0x3d, 0xf8, 0x91, 0xd7, 0x50, 0xc8,
+ /* (2^156)P */ 0xd8, 0xca, 0xde, 0x19, 0xcf, 0x00, 0xe4, 0x73, 0x18, 0x7f, 0x9b, 0x9f, 0xf4, 0x5b, 0x49, 0x49, 0x99, 0xdc, 0xa4, 0x46, 0x21, 0xb5, 0xd7, 0x3e, 0xb7, 0x47, 0x1b, 0xa9, 0x9f, 0x4c, 0x69, 0x7d, 0xec, 0x33, 0xd6, 0x1c, 0x51, 0x7f, 0x47, 0x74, 0x7a, 0x6c, 0xf3, 0xd2, 0x2e, 0xbf, 0xdf, 0x6c, 0x9e, 0x77, 0x3b, 0x34, 0xf6, 0x73, 0x80, 0xed,
+ /* (2^157)P */ 0x16, 0xfb, 0x16, 0xc3, 0xc2, 0x83, 0xe4, 0xf4, 0x03, 0x7f, 0x52, 0xb0, 0x67, 0x51, 0x7b, 0x24, 0x5a, 0x51, 0xd3, 0xb6, 0x4e, 0x59, 0x76, 0xcd, 0x08, 0x7b, 0x1d, 0x7a, 0x9c, 0x65, 0xae, 0xce, 0xaa, 0xd2, 0x1c, 0x85, 0x66, 0x68, 0x06, 0x15, 0xa8, 0x06, 0xe6, 0x16, 0x37, 0xf4, 0x49, 0x9e, 0x0f, 0x50, 0x37, 0xb1, 0xb2, 0x93, 0x70, 0x43,
+ /* (2^158)P */ 0x18, 0x3a, 0x16, 0xe5, 0x8d, 0xc8, 0x35, 0xd6, 0x7b, 0x09, 0xec, 0x61, 0x5f, 0x5c, 0x2a, 0x19, 0x96, 0x2e, 0xc3, 0xfd, 0xab, 0xe6, 0x23, 0xae, 0xab, 0xc5, 0xcb, 0xb9, 0x7b, 0x2d, 0x34, 0x51, 0xb9, 0x41, 0x9e, 0x7d, 0xca, 0xda, 0x25, 0x45, 0x14, 0xb0, 0xc7, 0x4d, 0x26, 0x2b, 0xfe, 0x43, 0xb0, 0x21, 0x5e, 0xfa, 0xdc, 0x7c, 0xf9, 0x5a,
+ /* (2^159)P */ 0x94, 0xad, 0x42, 0x17, 0xf5, 0xcd, 0x1c, 0x0d, 0xf6, 0x41, 0xd2, 0x55, 0xbb, 0x50, 0xf1, 0xc6, 0xbc, 0xa6, 0xc5, 0x3a, 0xfd, 0x9b, 0x75, 0x3e, 0xf6, 0x1a, 0xa7, 0xb2, 0x6e, 0x64, 0x12, 0xdc, 0x3c, 0xe5, 0xf6, 0xfc, 0x3b, 0xfa, 0x43, 0x81, 0xd4, 0xa5, 0xee, 0xf5, 0x9c, 0x47, 0x2f, 0xd0, 0x9c, 0xde, 0xa1, 0x48, 0x91, 0x9a, 0x34, 0xc1,
+ /* (2^160)P */ 0x37, 0x1b, 0xb3, 0x88, 0xc9, 0x98, 0x4e, 0xfb, 0x84, 0x4f, 0x2b, 0x0a, 0xb6, 0x8f, 0x35, 0x15, 0xcd, 0x61, 0x7a, 0x5f, 0x5c, 0xa0, 0xca, 0x23, 0xa0, 0x93, 0x1f, 0xcc, 0x3c, 0x39, 0x3a, 0x24, 0xa7, 0x49, 0xad, 0x8d, 0x59, 0xcc, 0x94, 0x5a, 0x16, 0xf5, 0x70, 0xe8, 0x52, 0x1e, 0xee, 0x20, 0x30, 0x17, 0x7e, 0xf0, 0x4c, 0x93, 0x06, 0x5a,
+ /* (2^161)P */ 0x81, 0xba, 0x3b, 0xd7, 0x3e, 0xb4, 0x32, 0x3a, 0x22, 0x39, 0x2a, 0xfc, 0x19, 0xd9, 0xd2, 0xf6, 0xc5, 0x79, 0x6c, 0x0e, 0xde, 0xda, 0x01, 0xff, 0x52, 0xfb, 0xb6, 0x95, 0x4e, 0x7a, 0x10, 0xb8, 0x06, 0x86, 0x3c, 0xcd, 0x56, 0xd6, 0x15, 0xbf, 0x6e, 0x3e, 0x4f, 0x35, 0x5e, 0xca, 0xbc, 0xa5, 0x95, 0xa2, 0xdf, 0x2d, 0x1d, 0xaf, 0x59, 0xf9,
+ /* (2^162)P */ 0x69, 0xe5, 0xe2, 0xfa, 0xc9, 0x7f, 0xdd, 0x09, 0xf5, 0x6b, 0x4e, 0x2e, 0xbe, 0xb4, 0xbf, 0x3e, 0xb2, 0xf2, 0x81, 0x30, 0xe1, 0x07, 0xa8, 0x0d, 0x2b, 0xd2, 0x5a, 0x55, 0xbe, 0x4b, 0x86, 0x5d, 0xb0, 0x5e, 0x7c, 0x8f, 0xc1, 0x3c, 0x81, 0x4c, 0xf7, 0x6d, 0x7d, 0xe6, 0x4f, 0x8a, 0x85, 0xc2, 0x2f, 0x28, 0xef, 0x8c, 0x69, 0xc2, 0xc2, 0x1a,
+ /* (2^163)P */ 0xd9, 0xe4, 0x0e, 0x1e, 0xc2, 0xf7, 0x2f, 0x9f, 0xa1, 0x40, 0xfe, 0x46, 0x16, 0xaf, 0x2e, 0xd1, 0xec, 0x15, 0x9b, 0x61, 0x92, 0xce, 0xfc, 0x10, 0x43, 0x1d, 0x00, 0xf6, 0xbe, 0x20, 0x80, 0x80, 0x6f, 0x3c, 0x16, 0x94, 0x59, 0xba, 0x03, 0x53, 0x6e, 0xb6, 0xdd, 0x25, 0x7b, 0x86, 0xbf, 0x96, 0xf4, 0x2f, 0xa1, 0x96, 0x8d, 0xf9, 0xb3, 0x29,
+ /* (2^164)P */ 0x3b, 0x04, 0x60, 0x6e, 0xce, 0xab, 0xd2, 0x63, 0x18, 0x53, 0x88, 0x16, 0x4a, 0x6a, 0xab, 0x72, 0x03, 0x68, 0xa5, 0xd4, 0x0d, 0xb2, 0x82, 0x81, 0x1f, 0x2b, 0x5c, 0x75, 0xe8, 0xd2, 0x1d, 0x7f, 0xe7, 0x1b, 0x35, 0x02, 0xde, 0xec, 0xbd, 0xcb, 0xc7, 0x01, 0xd3, 0x95, 0x61, 0xfe, 0xb2, 0x7a, 0x66, 0x09, 0x4c, 0x6d, 0xfd, 0x39, 0xf7, 0x52,
+ /* (2^165)P */ 0x42, 0xc1, 0x5f, 0xf8, 0x35, 0x52, 0xc1, 0xfe, 0xc5, 0x11, 0x80, 0x1c, 0x11, 0x46, 0x31, 0x11, 0xbe, 0xd0, 0xc4, 0xb6, 0x07, 0x13, 0x38, 0xa0, 0x8d, 0x65, 0xf0, 0x56, 0x9e, 0x16, 0xbf, 0x9d, 0xcd, 0x51, 0x34, 0xf9, 0x08, 0x48, 0x7b, 0x76, 0x0c, 0x7b, 0x30, 0x07, 0xa8, 0x76, 0xaf, 0xa3, 0x29, 0x38, 0xb0, 0x58, 0xde, 0x72, 0x4b, 0x45,
+ /* (2^166)P */ 0xd4, 0x16, 0xa7, 0xc0, 0xb4, 0x9f, 0xdf, 0x1a, 0x37, 0xc8, 0x35, 0xed, 0xc5, 0x85, 0x74, 0x64, 0x09, 0x22, 0xef, 0xe9, 0x0c, 0xaf, 0x12, 0x4c, 0x9e, 0xf8, 0x47, 0x56, 0xe0, 0x7f, 0x4e, 0x24, 0x6b, 0x0c, 0xe7, 0xad, 0xc6, 0x47, 0x1d, 0xa4, 0x0d, 0x86, 0x89, 0x65, 0xe8, 0x5f, 0x71, 0xc7, 0xe9, 0xcd, 0xec, 0x6c, 0x62, 0xc7, 0xe3, 0xb3,
+ /* (2^167)P */ 0xb5, 0xea, 0x86, 0xe3, 0x15, 0x18, 0x3f, 0x6d, 0x7b, 0x05, 0x95, 0x15, 0x53, 0x26, 0x1c, 0xeb, 0xbe, 0x7e, 0x16, 0x42, 0x4b, 0xa2, 0x3d, 0xdd, 0x0e, 0xff, 0xba, 0x67, 0xb5, 0xae, 0x7a, 0x17, 0xde, 0x23, 0xad, 0x14, 0xcc, 0xd7, 0xaf, 0x57, 0x01, 0xe0, 0xdd, 0x48, 0xdd, 0xd7, 0xe3, 0xdf, 0xe9, 0x2d, 0xda, 0x67, 0xa4, 0x9f, 0x29, 0x04,
+ /* (2^168)P */ 0x16, 0x53, 0xe6, 0x9c, 0x4e, 0xe5, 0x1e, 0x70, 0x81, 0x25, 0x02, 0x9b, 0x47, 0x6d, 0xd2, 0x08, 0x73, 0xbe, 0x0a, 0xf1, 0x7b, 0xeb, 0x24, 0xeb, 0x38, 0x23, 0x5c, 0xb6, 0x3e, 0xce, 0x1e, 0xe3, 0xbc, 0x82, 0x35, 0x1f, 0xaf, 0x3a, 0x3a, 0xe5, 0x4e, 0xc1, 0xca, 0xbf, 0x47, 0xb4, 0xbb, 0xbc, 0x5f, 0xea, 0xc6, 0xca, 0xf3, 0xa0, 0xa2, 0x73,
+ /* (2^169)P */ 0xef, 0xa4, 0x7a, 0x4e, 0xe4, 0xc7, 0xb6, 0x43, 0x2e, 0xa5, 0xe4, 0xa5, 0xba, 0x1e, 0xa5, 0xfe, 0x9e, 0xce, 0xa9, 0x80, 0x04, 0xcb, 0x4f, 0xd8, 0x74, 0x05, 0x48, 0xfa, 0x99, 0x11, 0x5d, 0x97, 0x3b, 0x07, 0x0d, 0xdd, 0xe6, 0xb1, 0x74, 0x87, 0x1a, 0xd3, 0x26, 0xb7, 0x8f, 0xe1, 0x63, 0x3d, 0xec, 0x53, 0x93, 0xb0, 0x81, 0x78, 0x34, 0xa4,
+ /* (2^170)P */ 0xe1, 0xe7, 0xd4, 0x58, 0x9d, 0x0e, 0x8b, 0x65, 0x66, 0x37, 0x16, 0x48, 0x6f, 0xaa, 0x42, 0x37, 0x77, 0xad, 0xb1, 0x56, 0x48, 0xdf, 0x65, 0x36, 0x30, 0xb8, 0x00, 0x12, 0xd8, 0x32, 0x28, 0x7f, 0xc1, 0x71, 0xeb, 0x93, 0x0f, 0x48, 0x04, 0xe1, 0x5a, 0x6a, 0x96, 0xc1, 0xca, 0x89, 0x6d, 0x1b, 0x82, 0x4c, 0x18, 0x6d, 0x55, 0x4b, 0xea, 0xfd,
+ /* (2^171)P */ 0x62, 0x1a, 0x53, 0xb4, 0xb1, 0xbe, 0x6f, 0x15, 0x18, 0x88, 0xd4, 0x66, 0x61, 0xc7, 0x12, 0x69, 0x02, 0xbd, 0x03, 0x23, 0x2b, 0xef, 0xf9, 0x54, 0xa4, 0x85, 0xa8, 0xe3, 0xb7, 0xbd, 0xa9, 0xa3, 0xf3, 0x2a, 0xdd, 0xf1, 0xd4, 0x03, 0x0f, 0xa9, 0xa1, 0xd8, 0xa3, 0xcd, 0xb2, 0x71, 0x90, 0x4b, 0x35, 0x62, 0xf2, 0x2f, 0xce, 0x67, 0x1f, 0xaa,
+ /* (2^172)P */ 0x9e, 0x1e, 0xcd, 0x43, 0x7e, 0x87, 0x37, 0x94, 0x3a, 0x97, 0x4c, 0x7e, 0xee, 0xc9, 0x37, 0x85, 0xf1, 0xd9, 0x4f, 0xbf, 0xf9, 0x6f, 0x39, 0x9a, 0x39, 0x87, 0x2e, 0x25, 0x84, 0x42, 0xc3, 0x80, 0xcb, 0x07, 0x22, 0xae, 0x30, 0xd5, 0x50, 0xa1, 0x23, 0xcc, 0x31, 0x81, 0x9d, 0xf1, 0x30, 0xd9, 0x2b, 0x73, 0x41, 0x16, 0x50, 0xab, 0x2d, 0xa2,
+ /* (2^173)P */ 0xa4, 0x69, 0x4f, 0xa1, 0x4e, 0xb9, 0xbf, 0x14, 0xe8, 0x2b, 0x04, 0x93, 0xb7, 0x6e, 0x9f, 0x7d, 0x73, 0x0a, 0xc5, 0x14, 0xb8, 0xde, 0x8c, 0xc1, 0xfe, 0xc0, 0xa7, 0xa4, 0xcc, 0x42, 0x42, 0x81, 0x15, 0x65, 0x8a, 0x80, 0xb9, 0xde, 0x1f, 0x60, 0x33, 0x0e, 0xcb, 0xfc, 0xe0, 0xdb, 0x83, 0xa1, 0xe5, 0xd0, 0x16, 0x86, 0x2c, 0xe2, 0x87, 0xed,
+ /* (2^174)P */ 0x7a, 0xc0, 0xeb, 0x6b, 0xf6, 0x0d, 0x4c, 0x6d, 0x1e, 0xdb, 0xab, 0xe7, 0x19, 0x45, 0xc6, 0xe3, 0xb2, 0x06, 0xbb, 0xbc, 0x70, 0x99, 0x83, 0x33, 0xeb, 0x28, 0xc8, 0x77, 0xf6, 0x4d, 0x01, 0xb7, 0x59, 0xa0, 0xd2, 0xb3, 0x2a, 0x72, 0x30, 0xe7, 0x11, 0x39, 0xb6, 0x41, 0x29, 0x65, 0x5a, 0x14, 0xb9, 0x86, 0x08, 0xe0, 0x7d, 0x32, 0x8c, 0xf0,
+ /* (2^175)P */ 0x5c, 0x11, 0x30, 0x9e, 0x05, 0x27, 0xf5, 0x45, 0x0f, 0xb3, 0xc9, 0x75, 0xc3, 0xd7, 0xe1, 0x82, 0x3b, 0x8e, 0x87, 0x23, 0x00, 0x15, 0x19, 0x07, 0xd9, 0x21, 0x53, 0xc7, 0xf1, 0xa3, 0xbf, 0x70, 0x64, 0x15, 0x18, 0xca, 0x23, 0x9e, 0xd3, 0x08, 0xc3, 0x2a, 0x8b, 0xe5, 0x83, 0x04, 0x89, 0x14, 0xfd, 0x28, 0x25, 0x1c, 0xe3, 0x26, 0xa7, 0x22,
+ /* (2^176)P */ 0xdc, 0xd4, 0x75, 0x60, 0x99, 0x94, 0xea, 0x09, 0x8e, 0x8a, 0x3c, 0x1b, 0xf9, 0xbd, 0x33, 0x0d, 0x51, 0x3d, 0x12, 0x6f, 0x4e, 0x72, 0xe0, 0x17, 0x20, 0xe9, 0x75, 0xe6, 0x3a, 0xb2, 0x13, 0x83, 0x4e, 0x7a, 0x08, 0x9e, 0xd1, 0x04, 0x5f, 0x6b, 0x42, 0x0b, 0x76, 0x2a, 0x2d, 0x77, 0x53, 0x6c, 0x65, 0x6d, 0x8e, 0x25, 0x3c, 0xb6, 0x8b, 0x69,
+ /* (2^177)P */ 0xb9, 0x49, 0x28, 0xd0, 0xdc, 0x6c, 0x8f, 0x4c, 0xc9, 0x14, 0x8a, 0x38, 0xa3, 0xcb, 0xc4, 0x9d, 0x53, 0xcf, 0xe9, 0xe3, 0xcf, 0xe0, 0xb1, 0xf2, 0x1b, 0x4c, 0x7f, 0x83, 0x2a, 0x7a, 0xe9, 0x8b, 0x3b, 0x86, 0x61, 0x30, 0xe9, 0x99, 0xbd, 0xba, 0x19, 0x6e, 0x65, 0x2a, 0x12, 0x3e, 0x9c, 0xa8, 0xaf, 0xc3, 0xcf, 0xf8, 0x1f, 0x77, 0x86, 0xea,
+ /* (2^178)P */ 0x30, 0xde, 0xe7, 0xff, 0x54, 0xf7, 0xa2, 0x59, 0xf6, 0x0b, 0xfb, 0x7a, 0xf2, 0x39, 0xf0, 0xdb, 0x39, 0xbc, 0xf0, 0xfa, 0x60, 0xeb, 0x6b, 0x4f, 0x47, 0x17, 0xc8, 0x00, 0x65, 0x6d, 0x25, 0x1c, 0xd0, 0x48, 0x56, 0x53, 0x45, 0x11, 0x30, 0x02, 0x49, 0x20, 0x27, 0xac, 0xf2, 0x4c, 0xac, 0x64, 0x3d, 0x52, 0xb8, 0x89, 0xe0, 0x93, 0x16, 0x0f,
+ /* (2^179)P */ 0x84, 0x09, 0xba, 0x40, 0xb2, 0x2f, 0xa3, 0xa8, 0xc2, 0xba, 0x46, 0x33, 0x05, 0x9d, 0x62, 0xad, 0xa1, 0x3c, 0x33, 0xef, 0x0d, 0xeb, 0xf0, 0x77, 0x11, 0x5a, 0xb0, 0x21, 0x9c, 0xdf, 0x55, 0x24, 0x25, 0x35, 0x51, 0x61, 0x92, 0xf0, 0xb1, 0xce, 0xf5, 0xd4, 0x7b, 0x6c, 0x21, 0x9d, 0x56, 0x52, 0xf8, 0xa1, 0x4c, 0xe9, 0x27, 0x55, 0xac, 0x91,
+ /* (2^180)P */ 0x03, 0x3e, 0x30, 0xd2, 0x0a, 0xfa, 0x7d, 0x82, 0x3d, 0x1f, 0x8b, 0xcb, 0xb6, 0x04, 0x5c, 0xcc, 0x8b, 0xda, 0xe2, 0x68, 0x74, 0x08, 0x8c, 0x44, 0x83, 0x57, 0x6d, 0x6f, 0x80, 0xb0, 0x7e, 0xa9, 0x82, 0x91, 0x7b, 0x4c, 0x37, 0x97, 0xd1, 0x63, 0xd1, 0xbd, 0x45, 0xe6, 0x8a, 0x86, 0xd6, 0x89, 0x54, 0xfd, 0xd2, 0xb1, 0xd7, 0x54, 0xad, 0xaf,
+ /* (2^181)P */ 0x8b, 0x33, 0x62, 0x49, 0x9f, 0x63, 0xf9, 0x87, 0x42, 0x58, 0xbf, 0xb3, 0xe6, 0x68, 0x02, 0x60, 0x5c, 0x76, 0x62, 0xf7, 0x61, 0xd7, 0x36, 0x31, 0xf7, 0x9c, 0xb5, 0xe5, 0x13, 0x6c, 0xea, 0x78, 0xae, 0xcf, 0xde, 0xbf, 0xb6, 0xeb, 0x4f, 0xc8, 0x2a, 0xb4, 0x9a, 0x9f, 0xf3, 0xd1, 0x6a, 0xec, 0x0c, 0xbd, 0x85, 0x98, 0x40, 0x06, 0x1c, 0x2a,
+ /* (2^182)P */ 0x74, 0x3b, 0xe7, 0x81, 0xd5, 0xae, 0x54, 0x56, 0x03, 0xe8, 0x97, 0x16, 0x76, 0xcf, 0x24, 0x96, 0x96, 0x5b, 0xcc, 0x09, 0xab, 0x23, 0x6f, 0x54, 0xae, 0x8f, 0xe4, 0x12, 0xcb, 0xfd, 0xbc, 0xac, 0x93, 0x45, 0x3d, 0x68, 0x08, 0x22, 0x59, 0xc6, 0xf0, 0x47, 0x19, 0x8c, 0x79, 0x93, 0x1e, 0x0e, 0x30, 0xb0, 0x94, 0xfb, 0x17, 0x1d, 0x5a, 0x12,
+ /* (2^183)P */ 0x85, 0xff, 0x40, 0x18, 0x85, 0xff, 0x44, 0x37, 0x69, 0x23, 0x4d, 0x34, 0xe1, 0xeb, 0xa3, 0x1b, 0x55, 0x40, 0xc1, 0x64, 0xf4, 0xd4, 0x13, 0x0a, 0x9f, 0xb9, 0x19, 0xfc, 0x88, 0x7d, 0xc0, 0x72, 0xcf, 0x69, 0x2f, 0xd2, 0x0c, 0x82, 0x0f, 0xda, 0x08, 0xba, 0x0f, 0xaa, 0x3b, 0xe9, 0xe5, 0x83, 0x7a, 0x06, 0xe8, 0x1b, 0x38, 0x43, 0xc3, 0x54,
+ /* (2^184)P */ 0x14, 0xaa, 0xb3, 0x6e, 0xe6, 0x28, 0xee, 0xc5, 0x22, 0x6c, 0x7c, 0xf9, 0xa8, 0x71, 0xcc, 0xfe, 0x68, 0x7e, 0xd3, 0xb8, 0x37, 0x96, 0xca, 0x0b, 0xd9, 0xb6, 0x06, 0xa9, 0xf6, 0x71, 0xe8, 0x31, 0xf7, 0xd8, 0xf1, 0x5d, 0xab, 0xb9, 0xf0, 0x5c, 0x98, 0xcf, 0x22, 0xa2, 0x2a, 0xf6, 0xd0, 0x59, 0xf0, 0x9d, 0xd9, 0x6a, 0x4f, 0x59, 0x57, 0xad,
+ /* (2^185)P */ 0xd7, 0x2b, 0x3d, 0x38, 0x4c, 0x2e, 0x23, 0x4d, 0x49, 0xa2, 0x62, 0x62, 0xf9, 0x0f, 0xde, 0x08, 0xf3, 0x86, 0x71, 0xb6, 0xc7, 0xf9, 0x85, 0x9c, 0x33, 0xa1, 0xcf, 0x16, 0xaa, 0x60, 0xb9, 0xb7, 0xea, 0xed, 0x01, 0x1c, 0x59, 0xdb, 0x3f, 0x3f, 0x97, 0x2e, 0xf0, 0x09, 0x9f, 0x10, 0x85, 0x5f, 0x53, 0x39, 0xf3, 0x13, 0x40, 0x56, 0x95, 0xf9,
+ /* (2^186)P */ 0xb4, 0xe3, 0xda, 0xc6, 0x1f, 0x78, 0x8e, 0xac, 0xd4, 0x20, 0x1d, 0xa0, 0xbf, 0x4c, 0x09, 0x16, 0xa7, 0x30, 0xb5, 0x8d, 0x9e, 0xa1, 0x5f, 0x6d, 0x52, 0xf4, 0x71, 0xb6, 0x32, 0x2d, 0x21, 0x51, 0xc6, 0xfc, 0x2f, 0x08, 0xf4, 0x13, 0x6c, 0x55, 0xba, 0x72, 0x81, 0x24, 0x49, 0x0e, 0x4f, 0x06, 0x36, 0x39, 0x6a, 0xc5, 0x81, 0xfc, 0xeb, 0xb2,
+ /* (2^187)P */ 0x7d, 0x8d, 0xc8, 0x6c, 0xea, 0xb4, 0xb9, 0xe8, 0x40, 0xc9, 0x69, 0xc9, 0x30, 0x05, 0xfd, 0x34, 0x46, 0xfd, 0x94, 0x05, 0x16, 0xf5, 0x4b, 0x13, 0x3d, 0x24, 0x1a, 0xd6, 0x64, 0x2b, 0x9c, 0xe2, 0xa5, 0xd9, 0x98, 0xe0, 0xe8, 0xf4, 0xbc, 0x2c, 0xbd, 0xa2, 0x56, 0xe3, 0x9e, 0x14, 0xdb, 0xbf, 0x05, 0xbf, 0x9a, 0x13, 0x5d, 0xf7, 0x91, 0xa3,
+ /* (2^188)P */ 0x8b, 0xcb, 0x27, 0xf3, 0x15, 0x26, 0x05, 0x40, 0x0f, 0xa6, 0x15, 0x13, 0x71, 0x95, 0xa2, 0xc6, 0x38, 0x04, 0x67, 0xf8, 0x9a, 0x83, 0x06, 0xaa, 0x25, 0x36, 0x72, 0x01, 0x6f, 0x74, 0x5f, 0xe5, 0x6e, 0x44, 0x99, 0xce, 0x13, 0xbc, 0x82, 0xc2, 0x0d, 0xa4, 0x98, 0x50, 0x38, 0xf3, 0xa2, 0xc5, 0xe5, 0x24, 0x1f, 0x6f, 0x56, 0x3e, 0x07, 0xb2,
+ /* (2^189)P */ 0xbd, 0x0f, 0x32, 0x60, 0x07, 0xb1, 0xd7, 0x0b, 0x11, 0x07, 0x57, 0x02, 0x89, 0xe8, 0x8b, 0xe8, 0x5a, 0x1f, 0xee, 0x54, 0x6b, 0xff, 0xb3, 0x04, 0x07, 0x57, 0x13, 0x0b, 0x94, 0xa8, 0x4d, 0x81, 0xe2, 0x17, 0x16, 0x45, 0xd4, 0x4b, 0xf7, 0x7e, 0x64, 0x66, 0x20, 0xe8, 0x0b, 0x26, 0xfd, 0xa9, 0x8a, 0x47, 0x52, 0x89, 0x14, 0xd0, 0xd1, 0xa1,
+ /* (2^190)P */ 0xdc, 0x03, 0xe6, 0x20, 0x44, 0x47, 0x8f, 0x04, 0x16, 0x24, 0x22, 0xc1, 0x55, 0x5c, 0xbe, 0x43, 0xc3, 0x92, 0xc5, 0x54, 0x3d, 0x5d, 0xd1, 0x05, 0x9c, 0xc6, 0x7c, 0xbf, 0x23, 0x84, 0x1a, 0xba, 0x4f, 0x1f, 0xfc, 0xa1, 0xae, 0x1a, 0x64, 0x02, 0x51, 0xf1, 0xcb, 0x7a, 0x20, 0xce, 0xb2, 0x34, 0x3c, 0xca, 0xe0, 0xe4, 0xba, 0x22, 0xd4, 0x7b,
+ /* (2^191)P */ 0xca, 0xfd, 0xca, 0xd7, 0xde, 0x61, 0xae, 0xf0, 0x79, 0x0c, 0x20, 0xab, 0xbc, 0x6f, 0x4d, 0x61, 0xf0, 0xc7, 0x9c, 0x8d, 0x4b, 0x52, 0xf3, 0xb9, 0x48, 0x63, 0x0b, 0xb6, 0xd2, 0x25, 0x9a, 0x96, 0x72, 0xc1, 0x6b, 0x0c, 0xb5, 0xfb, 0x71, 0xaa, 0xad, 0x47, 0x5b, 0xe7, 0xc0, 0x0a, 0x55, 0xb2, 0xd4, 0x16, 0x2f, 0xb1, 0x01, 0xfd, 0xce, 0x27,
+ /* (2^192)P */ 0x64, 0x11, 0x4b, 0xab, 0x57, 0x09, 0xc6, 0x49, 0x4a, 0x37, 0xc3, 0x36, 0xc4, 0x7b, 0x81, 0x1f, 0x42, 0xed, 0xbb, 0xe0, 0xa0, 0x8d, 0x51, 0xe6, 0xca, 0x8b, 0xb9, 0xcd, 0x99, 0x2d, 0x91, 0x53, 0xa9, 0x47, 0xcb, 0x32, 0xc7, 0xa4, 0x92, 0xec, 0x46, 0x74, 0x44, 0x6d, 0x71, 0x9f, 0x6d, 0x0c, 0x69, 0xa4, 0xf8, 0xbe, 0x9f, 0x7f, 0xa0, 0xd7,
+ /* (2^193)P */ 0x5f, 0x33, 0xb6, 0x91, 0xc8, 0xa5, 0x3f, 0x5d, 0x7f, 0x38, 0x6e, 0x74, 0x20, 0x4a, 0xd6, 0x2b, 0x98, 0x2a, 0x41, 0x4b, 0x83, 0x64, 0x0b, 0x92, 0x7a, 0x06, 0x1e, 0xc6, 0x2c, 0xf6, 0xe4, 0x91, 0xe5, 0xb1, 0x2e, 0x6e, 0x4e, 0xa8, 0xc8, 0x14, 0x32, 0x57, 0x44, 0x1c, 0xe4, 0xb9, 0x7f, 0x54, 0x51, 0x08, 0x81, 0xaa, 0x4e, 0xce, 0xa1, 0x5d,
+ /* (2^194)P */ 0x5c, 0xd5, 0x9b, 0x5e, 0x7c, 0xb5, 0xb1, 0x52, 0x73, 0x00, 0x41, 0x56, 0x79, 0x08, 0x7e, 0x07, 0x28, 0x06, 0xa6, 0xfb, 0x7f, 0x69, 0xbd, 0x7a, 0x3c, 0xae, 0x9f, 0x39, 0xbb, 0x54, 0xa2, 0x79, 0xb9, 0x0e, 0x7f, 0xbb, 0xe0, 0xe6, 0xb7, 0x27, 0x64, 0x38, 0x45, 0xdb, 0x84, 0xe4, 0x61, 0x72, 0x3f, 0xe2, 0x24, 0xfe, 0x7a, 0x31, 0x9a, 0xc9,
+ /* (2^195)P */ 0xa1, 0xd2, 0xa4, 0xee, 0x24, 0x96, 0xe5, 0x5b, 0x79, 0x78, 0x3c, 0x7b, 0x82, 0x3b, 0x8b, 0x58, 0x0b, 0xa3, 0x63, 0x2d, 0xbc, 0x75, 0x46, 0xe8, 0x83, 0x1a, 0xc0, 0x2a, 0x92, 0x61, 0xa8, 0x75, 0x37, 0x3c, 0xbf, 0x0f, 0xef, 0x8f, 0x6c, 0x97, 0x75, 0x10, 0x05, 0x7a, 0xde, 0x23, 0xe8, 0x2a, 0x35, 0xeb, 0x41, 0x64, 0x7d, 0xcf, 0xe0, 0x52,
+ /* (2^196)P */ 0x4a, 0xd0, 0x49, 0x93, 0xae, 0xf3, 0x24, 0x8c, 0xe1, 0x09, 0x98, 0x45, 0xd8, 0xb9, 0xfe, 0x8e, 0x8c, 0xa8, 0x2c, 0xc9, 0x9f, 0xce, 0x01, 0xdc, 0x38, 0x11, 0xab, 0x85, 0xb9, 0xe8, 0x00, 0x51, 0xfd, 0x82, 0xe1, 0x9b, 0x4e, 0xfc, 0xb5, 0x2a, 0x0f, 0x8b, 0xda, 0x4e, 0x02, 0xca, 0xcc, 0xe3, 0x91, 0xc4, 0xe0, 0xcf, 0x7b, 0xd6, 0xe6, 0x6a,
+ /* (2^197)P */ 0xfe, 0x11, 0xd7, 0xaa, 0xe3, 0x0c, 0x52, 0x2e, 0x04, 0xe0, 0xe0, 0x61, 0xc8, 0x05, 0xd7, 0x31, 0x4c, 0xc3, 0x9b, 0x2d, 0xce, 0x59, 0xbe, 0x12, 0xb7, 0x30, 0x21, 0xfc, 0x81, 0xb8, 0x5e, 0x57, 0x73, 0xd0, 0xad, 0x8e, 0x9e, 0xe4, 0xeb, 0xcd, 0xcf, 0xd2, 0x0f, 0x01, 0x35, 0x16, 0xed, 0x7a, 0x43, 0x8e, 0x42, 0xdc, 0xea, 0x4c, 0xa8, 0x7c,
+ /* (2^198)P */ 0x37, 0x26, 0xcc, 0x76, 0x0b, 0xe5, 0x76, 0xdd, 0x3e, 0x19, 0x3c, 0xc4, 0x6c, 0x7f, 0xd0, 0x03, 0xc1, 0xb8, 0x59, 0x82, 0xca, 0x36, 0xc1, 0xe4, 0xc8, 0xb2, 0x83, 0x69, 0x9c, 0xc5, 0x9d, 0x12, 0x82, 0x1c, 0xea, 0xb2, 0x84, 0x9f, 0xf3, 0x52, 0x6b, 0xbb, 0xd8, 0x81, 0x56, 0x83, 0x04, 0x66, 0x05, 0x22, 0x49, 0x37, 0x93, 0xb1, 0xfd, 0xd5,
+ /* (2^199)P */ 0xaf, 0x96, 0xbf, 0x03, 0xbe, 0xe6, 0x5d, 0x78, 0x19, 0xba, 0x37, 0x46, 0x0a, 0x2b, 0x52, 0x7c, 0xd8, 0x51, 0x9e, 0x3d, 0x29, 0x42, 0xdb, 0x0e, 0x31, 0x20, 0x94, 0xf8, 0x43, 0x9a, 0x2d, 0x22, 0xd3, 0xe3, 0xa1, 0x79, 0x68, 0xfb, 0x2d, 0x7e, 0xd6, 0x79, 0xda, 0x0b, 0xc6, 0x5b, 0x76, 0x68, 0xf0, 0xfe, 0x72, 0x59, 0xbb, 0xa1, 0x9c, 0x74,
+ /* (2^200)P */ 0x0a, 0xd9, 0xec, 0xc5, 0xbd, 0xf0, 0xda, 0xcf, 0x82, 0xab, 0x46, 0xc5, 0x32, 0x13, 0xdc, 0x5b, 0xac, 0xc3, 0x53, 0x9a, 0x7f, 0xef, 0xa5, 0x40, 0x5a, 0x1f, 0xc1, 0x12, 0x91, 0x54, 0x83, 0x6a, 0xb0, 0x9a, 0x85, 0x4d, 0xbf, 0x36, 0x8e, 0xd3, 0xa2, 0x2b, 0xe5, 0xd6, 0xc6, 0xe1, 0x58, 0x5b, 0x82, 0x9b, 0xc8, 0xf2, 0x03, 0xba, 0xf5, 0x92,
+ /* (2^201)P */ 0xfb, 0x21, 0x7e, 0xde, 0xe7, 0xb4, 0xc0, 0x56, 0x86, 0x3a, 0x5b, 0x78, 0xf8, 0xf0, 0xf4, 0xe7, 0x5c, 0x00, 0xd2, 0xd7, 0xd6, 0xf8, 0x75, 0x5e, 0x0f, 0x3e, 0xd1, 0x4b, 0x77, 0xd8, 0xad, 0xb0, 0xc9, 0x8b, 0x59, 0x7d, 0x30, 0x76, 0x64, 0x7a, 0x76, 0xd9, 0x51, 0x69, 0xfc, 0xbd, 0x8e, 0xb5, 0x55, 0xe0, 0xd2, 0x07, 0x15, 0xa9, 0xf7, 0xa4,
+ /* (2^202)P */ 0xaa, 0x2d, 0x2f, 0x2b, 0x3c, 0x15, 0xdd, 0xcd, 0xe9, 0x28, 0x82, 0x4f, 0xa2, 0xaa, 0x31, 0x48, 0xcc, 0xfa, 0x07, 0x73, 0x8a, 0x34, 0x74, 0x0d, 0xab, 0x1a, 0xca, 0xd2, 0xbf, 0x3a, 0xdb, 0x1a, 0x5f, 0x50, 0x62, 0xf4, 0x6b, 0x83, 0x38, 0x43, 0x96, 0xee, 0x6b, 0x39, 0x1e, 0xf0, 0x17, 0x80, 0x1e, 0x9b, 0xed, 0x2b, 0x2f, 0xcc, 0x65, 0xf7,
+ /* (2^203)P */ 0x03, 0xb3, 0x23, 0x9c, 0x0d, 0xd1, 0xeb, 0x7e, 0x34, 0x17, 0x8a, 0x4c, 0xde, 0x54, 0x39, 0xc4, 0x11, 0x82, 0xd3, 0xa4, 0x00, 0x32, 0x95, 0x9c, 0xa6, 0x64, 0x76, 0x6e, 0xd6, 0x53, 0x27, 0xb4, 0x6a, 0x14, 0x8c, 0x54, 0xf6, 0x58, 0x9e, 0x22, 0x4a, 0x55, 0x18, 0x77, 0xd0, 0x08, 0x6b, 0x19, 0x8a, 0xb5, 0xe7, 0x19, 0xb8, 0x60, 0x92, 0xb1,
+ /* (2^204)P */ 0x66, 0xec, 0xf3, 0x12, 0xde, 0x67, 0x7f, 0xd4, 0x5b, 0xf6, 0x70, 0x64, 0x0a, 0xb5, 0xc2, 0xf9, 0xb3, 0x64, 0xab, 0x56, 0x46, 0xc7, 0x93, 0xc2, 0x8b, 0x2d, 0xd0, 0xd6, 0x39, 0x3b, 0x1f, 0xcd, 0xb3, 0xac, 0xcc, 0x2c, 0x27, 0x6a, 0xbc, 0xb3, 0x4b, 0xa8, 0x3c, 0x69, 0x20, 0xe2, 0x18, 0x35, 0x17, 0xe1, 0x8a, 0xd3, 0x11, 0x74, 0xaa, 0x4d,
+ /* (2^205)P */ 0x96, 0xc4, 0x16, 0x7e, 0xfd, 0xf5, 0xd0, 0x7d, 0x1f, 0x32, 0x1b, 0xdb, 0xa6, 0xfd, 0x51, 0x75, 0x4d, 0xd7, 0x00, 0xe5, 0x7f, 0x58, 0x5b, 0xeb, 0x4b, 0x6a, 0x78, 0xfe, 0xe5, 0xd6, 0x8f, 0x99, 0x17, 0xca, 0x96, 0x45, 0xf7, 0x52, 0xdf, 0x84, 0x06, 0x77, 0xb9, 0x05, 0x63, 0x5d, 0xe9, 0x91, 0xb1, 0x4b, 0x82, 0x5a, 0xdb, 0xd7, 0xca, 0x69,
+ /* (2^206)P */ 0x02, 0xd3, 0x38, 0x38, 0x87, 0xea, 0xbd, 0x9f, 0x11, 0xca, 0xf3, 0x21, 0xf1, 0x9b, 0x35, 0x97, 0x98, 0xff, 0x8e, 0x6d, 0x3d, 0xd6, 0xb2, 0xfa, 0x68, 0xcb, 0x7e, 0x62, 0x85, 0xbb, 0xc7, 0x5d, 0xee, 0x32, 0x30, 0x2e, 0x71, 0x96, 0x63, 0x43, 0x98, 0xc4, 0xa7, 0xde, 0x60, 0xb2, 0xd9, 0x43, 0x4a, 0xfa, 0x97, 0x2d, 0x5f, 0x21, 0xd4, 0xfe,
+ /* (2^207)P */ 0x3b, 0x20, 0x29, 0x07, 0x07, 0xb5, 0x78, 0xc3, 0xc7, 0xab, 0x56, 0xba, 0x40, 0xde, 0x1d, 0xcf, 0xc3, 0x00, 0x56, 0x21, 0x0c, 0xc8, 0x42, 0xd9, 0x0e, 0xcd, 0x02, 0x7c, 0x07, 0xb9, 0x11, 0xd7, 0x96, 0xaf, 0xff, 0xad, 0xc5, 0xba, 0x30, 0x6d, 0x82, 0x3a, 0xbf, 0xef, 0x7b, 0xf7, 0x0a, 0x74, 0xbd, 0x31, 0x0c, 0xe4, 0xec, 0x1a, 0xe5, 0xc5,
+ /* (2^208)P */ 0xcc, 0xf2, 0x28, 0x16, 0x12, 0xbf, 0xef, 0x85, 0xbc, 0xf7, 0xcb, 0x9f, 0xdb, 0xa8, 0xb2, 0x49, 0x53, 0x48, 0xa8, 0x24, 0xa8, 0x68, 0x8d, 0xbb, 0x21, 0x0a, 0x5a, 0xbd, 0xb2, 0x91, 0x61, 0x47, 0xc4, 0x43, 0x08, 0xa6, 0x19, 0xef, 0x8e, 0x88, 0x39, 0xc6, 0x33, 0x30, 0xf3, 0x0e, 0xc5, 0x92, 0x66, 0xd6, 0xfe, 0xc5, 0x12, 0xd9, 0x4c, 0x2d,
+ /* (2^209)P */ 0x30, 0x34, 0x07, 0xbf, 0x9c, 0x5a, 0x4e, 0x65, 0xf1, 0x39, 0x35, 0x38, 0xae, 0x7b, 0x55, 0xac, 0x6a, 0x92, 0x24, 0x7e, 0x50, 0xd3, 0xba, 0x78, 0x51, 0xfe, 0x4d, 0x32, 0x05, 0x11, 0xf5, 0x52, 0xf1, 0x31, 0x45, 0x39, 0x98, 0x7b, 0x28, 0x56, 0xc3, 0x5d, 0x4f, 0x07, 0x6f, 0x84, 0xb8, 0x1a, 0x58, 0x0b, 0xc4, 0x7c, 0xc4, 0x8d, 0x32, 0x8e,
+ /* (2^210)P */ 0x7e, 0xaf, 0x98, 0xce, 0xc5, 0x2b, 0x9d, 0xf6, 0xfa, 0x2c, 0xb6, 0x2a, 0x5a, 0x1d, 0xc0, 0x24, 0x8d, 0xa4, 0xce, 0xb1, 0x12, 0x01, 0xf9, 0x79, 0xc6, 0x79, 0x38, 0x0c, 0xd4, 0x07, 0xc9, 0xf7, 0x37, 0xa1, 0x0b, 0xfe, 0x72, 0xec, 0x5d, 0xd6, 0xb0, 0x1c, 0x70, 0xbe, 0x70, 0x01, 0x13, 0xe0, 0x86, 0x95, 0xc7, 0x2e, 0x12, 0x3b, 0xe6, 0xa6,
+ /* (2^211)P */ 0x24, 0x82, 0x67, 0xe0, 0x14, 0x7b, 0x56, 0x08, 0x38, 0x44, 0xdb, 0xa0, 0x3a, 0x05, 0x47, 0xb2, 0xc0, 0xac, 0xd1, 0xcc, 0x3f, 0x82, 0xb8, 0x8a, 0x88, 0xbc, 0xf5, 0x33, 0xa1, 0x35, 0x0f, 0xf6, 0xe2, 0xef, 0x6c, 0xf7, 0x37, 0x9e, 0xe8, 0x10, 0xca, 0xb0, 0x8e, 0x80, 0x86, 0x00, 0x23, 0xd0, 0x4a, 0x76, 0x9f, 0xf7, 0x2c, 0x52, 0x15, 0x0e,
+ /* (2^212)P */ 0x5e, 0x49, 0xe1, 0x2c, 0x9a, 0x01, 0x76, 0xa6, 0xb3, 0x07, 0x5b, 0xa4, 0x07, 0xef, 0x1d, 0xc3, 0x6a, 0xbb, 0x64, 0xbe, 0x71, 0x15, 0x6e, 0x32, 0x31, 0x46, 0x9a, 0x9e, 0x8f, 0x45, 0x73, 0xce, 0x0b, 0x94, 0x1a, 0x52, 0x07, 0xf4, 0x50, 0x30, 0x49, 0x53, 0x50, 0xfb, 0x71, 0x1f, 0x5a, 0x03, 0xa9, 0x76, 0xf2, 0x8f, 0x42, 0xff, 0xed, 0xed,
+ /* (2^213)P */ 0xed, 0x08, 0xdb, 0x91, 0x1c, 0xee, 0xa2, 0xb4, 0x47, 0xa2, 0xfa, 0xcb, 0x03, 0xd1, 0xff, 0x8c, 0xad, 0x64, 0x50, 0x61, 0xcd, 0xfc, 0x88, 0xa0, 0x31, 0x95, 0x30, 0xb9, 0x58, 0xdd, 0xd7, 0x43, 0xe4, 0x46, 0xc2, 0x16, 0xd9, 0x72, 0x4a, 0x56, 0x51, 0x70, 0x85, 0xf1, 0xa1, 0x80, 0x40, 0xd5, 0xba, 0x67, 0x81, 0xda, 0xcd, 0x03, 0xea, 0x51,
+ /* (2^214)P */ 0x42, 0x50, 0xf0, 0xef, 0x37, 0x61, 0x72, 0x85, 0xe1, 0xf1, 0xff, 0x6f, 0x3d, 0xe8, 0x7b, 0x21, 0x5c, 0xe5, 0x50, 0x03, 0xde, 0x00, 0xc1, 0xf7, 0x3a, 0x55, 0x12, 0x1c, 0x9e, 0x1e, 0xce, 0xd1, 0x2f, 0xaf, 0x05, 0x70, 0x5b, 0x47, 0xf2, 0x04, 0x7a, 0x89, 0xbc, 0x78, 0xa6, 0x65, 0x6c, 0xaa, 0x3c, 0xa2, 0x3c, 0x8b, 0x5c, 0xa9, 0x22, 0x48,
+ /* (2^215)P */ 0x7e, 0x8c, 0x8f, 0x2f, 0x60, 0xe3, 0x5a, 0x94, 0xd4, 0xce, 0xdd, 0x9d, 0x83, 0x3b, 0x77, 0x78, 0x43, 0x1d, 0xfd, 0x8f, 0xc8, 0xe8, 0x02, 0x90, 0xab, 0xf6, 0xc9, 0xfc, 0xf1, 0x63, 0xaa, 0x5f, 0x42, 0xf1, 0x78, 0x34, 0x64, 0x16, 0x75, 0x9c, 0x7d, 0xd0, 0xe4, 0x74, 0x5a, 0xa8, 0xfb, 0xcb, 0xac, 0x20, 0xa3, 0xc2, 0xa6, 0x20, 0xf8, 0x1b,
+ /* (2^216)P */ 0x00, 0x4f, 0x1e, 0x56, 0xb5, 0x34, 0xb2, 0x87, 0x31, 0xe5, 0xee, 0x8d, 0xf1, 0x41, 0x67, 0xb7, 0x67, 0x3a, 0x54, 0x86, 0x5c, 0xf0, 0x0b, 0x37, 0x2f, 0x1b, 0x92, 0x5d, 0x58, 0x93, 0xdc, 0xd8, 0x58, 0xcc, 0x9e, 0x67, 0xd0, 0x97, 0x3a, 0xaf, 0x49, 0x39, 0x2d, 0x3b, 0xd8, 0x98, 0xfb, 0x76, 0x6b, 0xe7, 0xaf, 0xc3, 0x45, 0x44, 0x53, 0x94,
+ /* (2^217)P */ 0x30, 0xbd, 0x90, 0x75, 0xd3, 0xbd, 0x3b, 0x58, 0x27, 0x14, 0x9f, 0x6b, 0xd4, 0x31, 0x99, 0xcd, 0xde, 0x3a, 0x21, 0x1e, 0xb4, 0x02, 0xe4, 0x33, 0x04, 0x02, 0xb0, 0x50, 0x66, 0x68, 0x90, 0xdd, 0x7b, 0x69, 0x31, 0xd9, 0xcf, 0x68, 0x73, 0xf1, 0x60, 0xdd, 0xc8, 0x1d, 0x5d, 0xe3, 0xd6, 0x5b, 0x2a, 0xa4, 0xea, 0xc4, 0x3f, 0x08, 0xcd, 0x9c,
+ /* (2^218)P */ 0x6b, 0x1a, 0xbf, 0x55, 0xc1, 0x1b, 0x0c, 0x05, 0x09, 0xdf, 0xf5, 0x5e, 0xa3, 0x77, 0x95, 0xe9, 0xdf, 0x19, 0xdd, 0xc7, 0x94, 0xcb, 0x06, 0x73, 0xd0, 0x88, 0x02, 0x33, 0x94, 0xca, 0x7a, 0x2f, 0x8e, 0x3d, 0x72, 0x61, 0x2d, 0x4d, 0xa6, 0x61, 0x1f, 0x32, 0x5e, 0x87, 0x53, 0x36, 0x11, 0x15, 0x20, 0xb3, 0x5a, 0x57, 0x51, 0x93, 0x20, 0xd8,
+ /* (2^219)P */ 0xb7, 0x56, 0xf4, 0xab, 0x7d, 0x0c, 0xfb, 0x99, 0x1a, 0x30, 0x29, 0xb0, 0x75, 0x2a, 0xf8, 0x53, 0x71, 0x23, 0xbd, 0xa7, 0xd8, 0x0a, 0xe2, 0x27, 0x65, 0xe9, 0x74, 0x26, 0x98, 0x4a, 0x69, 0x19, 0xb2, 0x4d, 0x0a, 0x17, 0x98, 0xb2, 0xa9, 0x57, 0x4e, 0xf6, 0x86, 0xc8, 0x01, 0xa4, 0xc6, 0x98, 0xad, 0x5a, 0x90, 0x2c, 0x05, 0x46, 0x64, 0xb7,
+ /* (2^220)P */ 0x7b, 0x91, 0xdf, 0xfc, 0xf8, 0x1c, 0x8c, 0x15, 0x9e, 0xf7, 0xd5, 0xa8, 0xe8, 0xe7, 0xe3, 0xa3, 0xb0, 0x04, 0x74, 0xfa, 0x78, 0xfb, 0x26, 0xbf, 0x67, 0x42, 0xf9, 0x8c, 0x9b, 0xb4, 0x69, 0x5b, 0x02, 0x13, 0x6d, 0x09, 0x6c, 0xd6, 0x99, 0x61, 0x7b, 0x89, 0x4a, 0x67, 0x75, 0xa3, 0x98, 0x13, 0x23, 0x1d, 0x18, 0x24, 0x0e, 0xef, 0x41, 0x79,
+ /* (2^221)P */ 0x86, 0x33, 0xab, 0x08, 0xcb, 0xbf, 0x1e, 0x76, 0x3c, 0x0b, 0xbd, 0x30, 0xdb, 0xe9, 0xa3, 0x35, 0x87, 0x1b, 0xe9, 0x07, 0x00, 0x66, 0x7f, 0x3b, 0x35, 0x0c, 0x8a, 0x3f, 0x61, 0xbc, 0xe0, 0xae, 0xf6, 0xcc, 0x54, 0xe1, 0x72, 0x36, 0x2d, 0xee, 0x93, 0x24, 0xf8, 0xd7, 0xc5, 0xf9, 0xcb, 0xb0, 0xe5, 0x88, 0x0d, 0x23, 0x4b, 0x76, 0x15, 0xa2,
+ /* (2^222)P */ 0x37, 0xdb, 0x83, 0xd5, 0x6d, 0x06, 0x24, 0x37, 0x1b, 0x15, 0x85, 0x15, 0xe2, 0xc0, 0x4e, 0x02, 0xa9, 0x6d, 0x0a, 0x3a, 0x94, 0x4a, 0x6f, 0x49, 0x00, 0x01, 0x72, 0xbb, 0x60, 0x14, 0x35, 0xae, 0xb4, 0xc6, 0x01, 0x0a, 0x00, 0x9e, 0xc3, 0x58, 0xc5, 0xd1, 0x5e, 0x30, 0x73, 0x96, 0x24, 0x85, 0x9d, 0xf0, 0xf9, 0xec, 0x09, 0xd3, 0xe7, 0x70,
+ /* (2^223)P */ 0xf3, 0xbd, 0x96, 0x87, 0xe9, 0x71, 0xbd, 0xd6, 0xa2, 0x45, 0xeb, 0x0a, 0xcd, 0x2c, 0xf1, 0x72, 0xa6, 0x31, 0xa9, 0x6f, 0x09, 0xa1, 0x5e, 0xdd, 0xc8, 0x8d, 0x0d, 0xbc, 0x5a, 0x8d, 0xb1, 0x2c, 0x9a, 0xcc, 0x37, 0x74, 0xc2, 0xa9, 0x4e, 0xd6, 0xc0, 0x3c, 0xa0, 0x23, 0xb0, 0xa0, 0x77, 0x14, 0x80, 0x45, 0x71, 0x6a, 0x2d, 0x41, 0xc3, 0x82,
+ /* (2^224)P */ 0x37, 0x44, 0xec, 0x8a, 0x3e, 0xc1, 0x0c, 0xa9, 0x12, 0x9c, 0x08, 0x88, 0xcb, 0xd9, 0xf8, 0xba, 0x00, 0xd6, 0xc3, 0xdf, 0xef, 0x7a, 0x44, 0x7e, 0x25, 0x69, 0xc9, 0xc1, 0x46, 0xe5, 0x20, 0x9e, 0xcc, 0x0b, 0x05, 0x3e, 0xf4, 0x78, 0x43, 0x0c, 0xa6, 0x2f, 0xc1, 0xfa, 0x70, 0xb2, 0x3c, 0x31, 0x7a, 0x63, 0x58, 0xab, 0x17, 0xcf, 0x4c, 0x4f,
+ /* (2^225)P */ 0x2b, 0x08, 0x31, 0x59, 0x75, 0x8b, 0xec, 0x0a, 0xa9, 0x79, 0x70, 0xdd, 0xf1, 0x11, 0xc3, 0x11, 0x1f, 0xab, 0x37, 0xaa, 0x26, 0xea, 0x53, 0xc4, 0x79, 0xa7, 0x91, 0x00, 0xaa, 0x08, 0x42, 0xeb, 0x8b, 0x8b, 0xe8, 0xc3, 0x2f, 0xb8, 0x78, 0x90, 0x38, 0x0e, 0x8a, 0x42, 0x0c, 0x0f, 0xbf, 0x3e, 0xf8, 0xd8, 0x07, 0xcf, 0x6a, 0x34, 0xc9, 0xfa,
+ /* (2^226)P */ 0x11, 0xe0, 0x76, 0x4d, 0x23, 0xc5, 0xa6, 0xcc, 0x9f, 0x9a, 0x2a, 0xde, 0x3a, 0xb5, 0x92, 0x39, 0x19, 0x8a, 0xf1, 0x8d, 0xf9, 0x4d, 0xc9, 0xb4, 0x39, 0x9f, 0x57, 0xd8, 0x72, 0xab, 0x1d, 0x61, 0x6a, 0xb2, 0xff, 0x52, 0xba, 0x54, 0x0e, 0xfb, 0x83, 0x30, 0x8a, 0xf7, 0x3b, 0xf4, 0xd8, 0xae, 0x1a, 0x94, 0x3a, 0xec, 0x63, 0xfe, 0x6e, 0x7c,
+ /* (2^227)P */ 0xdc, 0x70, 0x8e, 0x55, 0x44, 0xbf, 0xd2, 0x6a, 0xa0, 0x14, 0x61, 0x89, 0xd5, 0x55, 0x45, 0x3c, 0xf6, 0x40, 0x0d, 0x83, 0x85, 0x44, 0xb4, 0x62, 0x56, 0xfe, 0x60, 0xd7, 0x07, 0x1d, 0x47, 0x30, 0x3b, 0x73, 0xa4, 0xb5, 0xb7, 0xea, 0xac, 0xda, 0xf1, 0x17, 0xaa, 0x60, 0xdf, 0xe9, 0x84, 0xda, 0x31, 0x32, 0x61, 0xbf, 0xd0, 0x7e, 0x8a, 0x02,
+ /* (2^228)P */ 0xb9, 0x51, 0xb3, 0x89, 0x21, 0x5d, 0xa2, 0xfe, 0x79, 0x2a, 0xb3, 0x2a, 0x3b, 0xe6, 0x6f, 0x2b, 0x22, 0x03, 0xea, 0x7b, 0x1f, 0xaf, 0x85, 0xc3, 0x38, 0x55, 0x5b, 0x8e, 0xb4, 0xaa, 0x77, 0xfe, 0x03, 0x6e, 0xda, 0x91, 0x24, 0x0c, 0x48, 0x39, 0x27, 0x43, 0x16, 0xd2, 0x0a, 0x0d, 0x43, 0xa3, 0x0e, 0xca, 0x45, 0xd1, 0x7f, 0xf5, 0xd3, 0x16,
+ /* (2^229)P */ 0x3d, 0x32, 0x9b, 0x38, 0xf8, 0x06, 0x93, 0x78, 0x5b, 0x50, 0x2b, 0x06, 0xd8, 0x66, 0xfe, 0xab, 0x9b, 0x58, 0xc7, 0xd1, 0x4d, 0xd5, 0xf8, 0x3b, 0x10, 0x7e, 0x85, 0xde, 0x58, 0x4e, 0xdf, 0x53, 0xd9, 0x58, 0xe0, 0x15, 0x81, 0x9f, 0x1a, 0x78, 0xfc, 0x9f, 0x10, 0xc2, 0x23, 0xd6, 0x78, 0xd1, 0x9d, 0xd2, 0xd5, 0x1c, 0x53, 0xe2, 0xc9, 0x76,
+ /* (2^230)P */ 0x98, 0x1e, 0x38, 0x7b, 0x71, 0x18, 0x4b, 0x15, 0xaf, 0xa1, 0xa6, 0x98, 0xcb, 0x26, 0xa3, 0xc8, 0x07, 0x46, 0xda, 0x3b, 0x70, 0x65, 0xec, 0x7a, 0x2b, 0x34, 0x94, 0xa8, 0xb6, 0x14, 0xf8, 0x1a, 0xce, 0xf7, 0xc8, 0x60, 0xf3, 0x88, 0xf4, 0x33, 0x60, 0x7b, 0xd1, 0x02, 0xe7, 0xda, 0x00, 0x4a, 0xea, 0xd2, 0xfd, 0x88, 0xd2, 0x99, 0x28, 0xf3,
+ /* (2^231)P */ 0x28, 0x24, 0x1d, 0x26, 0xc2, 0xeb, 0x8b, 0x3b, 0xb4, 0x6b, 0xbe, 0x6b, 0x77, 0xff, 0xf3, 0x21, 0x3b, 0x26, 0x6a, 0x8c, 0x8e, 0x2a, 0x44, 0xa8, 0x01, 0x2b, 0x71, 0xea, 0x64, 0x30, 0xfd, 0xfd, 0x95, 0xcb, 0x39, 0x38, 0x48, 0xfa, 0x96, 0x97, 0x8c, 0x2f, 0x33, 0xca, 0x03, 0xe6, 0xd7, 0x94, 0x55, 0x6c, 0xc3, 0xb3, 0xa8, 0xf7, 0xae, 0x8c,
+ /* (2^232)P */ 0xea, 0x62, 0x8a, 0xb4, 0xeb, 0x74, 0xf7, 0xb8, 0xae, 0xc5, 0x20, 0x71, 0x06, 0xd6, 0x7c, 0x62, 0x9b, 0x69, 0x74, 0xef, 0xa7, 0x6d, 0xd6, 0x8c, 0x37, 0xb9, 0xbf, 0xcf, 0xeb, 0xe4, 0x2f, 0x04, 0x02, 0x21, 0x7d, 0x75, 0x6b, 0x92, 0x48, 0xf8, 0x70, 0xad, 0x69, 0xe2, 0xea, 0x0e, 0x88, 0x67, 0x72, 0xcc, 0x2d, 0x10, 0xce, 0x2d, 0xcf, 0x65,
+ /* (2^233)P */ 0x49, 0xf3, 0x57, 0x64, 0xe5, 0x5c, 0xc5, 0x65, 0x49, 0x97, 0xc4, 0x8a, 0xcc, 0xa9, 0xca, 0x94, 0x7b, 0x86, 0x88, 0xb6, 0x51, 0x27, 0x69, 0xa5, 0x0f, 0x8b, 0x06, 0x59, 0xa0, 0x94, 0xef, 0x63, 0x1a, 0x01, 0x9e, 0x4f, 0xd2, 0x5a, 0x93, 0xc0, 0x7c, 0xe6, 0x61, 0x77, 0xb6, 0xf5, 0x40, 0xd9, 0x98, 0x43, 0x5b, 0x56, 0x68, 0xe9, 0x37, 0x8f,
+ /* (2^234)P */ 0xee, 0x87, 0xd2, 0x05, 0x1b, 0x39, 0x89, 0x10, 0x07, 0x6d, 0xe8, 0xfd, 0x8b, 0x4d, 0xb2, 0xa7, 0x7b, 0x1e, 0xa0, 0x6c, 0x0d, 0x3d, 0x3d, 0x49, 0xba, 0x61, 0x36, 0x1f, 0xc2, 0x84, 0x4a, 0xcc, 0x87, 0xa9, 0x1b, 0x23, 0x04, 0xe2, 0x3e, 0x97, 0xe1, 0xdb, 0xd5, 0x5a, 0xe8, 0x41, 0x6b, 0xe5, 0x5a, 0xa1, 0x99, 0xe5, 0x7b, 0xa7, 0xe0, 0x3b,
+ /* (2^235)P */ 0xea, 0xa3, 0x6a, 0xdd, 0x77, 0x7f, 0x77, 0x41, 0xc5, 0x6a, 0xe4, 0xaf, 0x11, 0x5f, 0x88, 0xa5, 0x10, 0xee, 0xd0, 0x8c, 0x0c, 0xb4, 0xa5, 0x2a, 0xd0, 0xd8, 0x1d, 0x47, 0x06, 0xc0, 0xd5, 0xce, 0x51, 0x54, 0x9b, 0x2b, 0xe6, 0x2f, 0xe7, 0xe7, 0x31, 0x5f, 0x5c, 0x23, 0x81, 0x3e, 0x03, 0x93, 0xaa, 0x2d, 0x71, 0x84, 0xa0, 0x89, 0x32, 0xa6,
+ /* (2^236)P */ 0x55, 0xa3, 0x13, 0x92, 0x4e, 0x93, 0x7d, 0xec, 0xca, 0x57, 0xfb, 0x37, 0xae, 0xd2, 0x18, 0x2e, 0x54, 0x05, 0x6c, 0xd1, 0x28, 0xca, 0x90, 0x40, 0x82, 0x2e, 0x79, 0xc6, 0x5a, 0xc7, 0xdd, 0x84, 0x93, 0xdf, 0x15, 0xb8, 0x1f, 0xb1, 0xf9, 0xaf, 0x2c, 0xe5, 0x32, 0xcd, 0xc2, 0x99, 0x6d, 0xac, 0x85, 0x5c, 0x63, 0xd3, 0xe2, 0xff, 0x24, 0xda,
+ /* (2^237)P */ 0x2d, 0x8d, 0xfd, 0x65, 0xcc, 0xe5, 0x02, 0xa0, 0xe5, 0xb9, 0xec, 0x59, 0x09, 0x50, 0x27, 0xb7, 0x3d, 0x2a, 0x79, 0xb2, 0x76, 0x5d, 0x64, 0x95, 0xf8, 0xc5, 0xaf, 0x8a, 0x62, 0x11, 0x5c, 0x56, 0x1c, 0x05, 0x64, 0x9e, 0x5e, 0xbd, 0x54, 0x04, 0xe6, 0x9e, 0xab, 0xe6, 0x22, 0x7e, 0x42, 0x54, 0xb5, 0xa5, 0xd0, 0x8d, 0x28, 0x6b, 0x0f, 0x0b,
+ /* (2^238)P */ 0x2d, 0xb2, 0x8c, 0x59, 0x10, 0x37, 0x84, 0x3b, 0x9b, 0x65, 0x1b, 0x0f, 0x10, 0xf9, 0xea, 0x60, 0x1b, 0x02, 0xf5, 0xee, 0x8b, 0xe6, 0x32, 0x7d, 0x10, 0x7f, 0x5f, 0x8c, 0x72, 0x09, 0x4e, 0x1f, 0x29, 0xff, 0x65, 0xcb, 0x3e, 0x3a, 0xd2, 0x96, 0x50, 0x1e, 0xea, 0x64, 0x99, 0xb5, 0x4c, 0x7a, 0x69, 0xb8, 0x95, 0xae, 0x48, 0xc0, 0x7c, 0xb1,
+ /* (2^239)P */ 0xcd, 0x7c, 0x4f, 0x3e, 0xea, 0xf3, 0x90, 0xcb, 0x12, 0x76, 0xd1, 0x17, 0xdc, 0x0d, 0x13, 0x0f, 0xfd, 0x4d, 0xb5, 0x1f, 0xe4, 0xdd, 0xf2, 0x4d, 0x58, 0xea, 0xa5, 0x66, 0x92, 0xcf, 0xe5, 0x54, 0xea, 0x9b, 0x35, 0x83, 0x1a, 0x44, 0x8e, 0x62, 0x73, 0x45, 0x98, 0xa3, 0x89, 0x95, 0x52, 0x93, 0x1a, 0x8d, 0x63, 0x0f, 0xc2, 0x57, 0x3c, 0xb1,
+ /* (2^240)P */ 0x72, 0xb4, 0xdf, 0x51, 0xb7, 0xf6, 0x52, 0xa2, 0x14, 0x56, 0xe5, 0x0a, 0x2e, 0x75, 0x81, 0x02, 0xee, 0x93, 0x48, 0x0a, 0x92, 0x4e, 0x0c, 0x0f, 0xdf, 0x09, 0x89, 0x99, 0xf6, 0xf9, 0x22, 0xa2, 0x32, 0xf8, 0xb0, 0x76, 0x0c, 0xb2, 0x4d, 0x6e, 0xbe, 0x83, 0x35, 0x61, 0x44, 0xd2, 0x58, 0xc7, 0xdd, 0x14, 0xcf, 0xc3, 0x4b, 0x7c, 0x07, 0xee,
+ /* (2^241)P */ 0x8b, 0x03, 0xee, 0xcb, 0xa7, 0x2e, 0x28, 0xbd, 0x97, 0xd1, 0x4c, 0x2b, 0xd1, 0x92, 0x67, 0x5b, 0x5a, 0x12, 0xbf, 0x29, 0x17, 0xfc, 0x50, 0x09, 0x74, 0x76, 0xa2, 0xd4, 0x82, 0xfd, 0x2c, 0x0c, 0x90, 0xf7, 0xe7, 0xe5, 0x9a, 0x2c, 0x16, 0x40, 0xb9, 0x6c, 0xd9, 0xe0, 0x22, 0x9e, 0xf8, 0xdd, 0x73, 0xe4, 0x7b, 0x9e, 0xbe, 0x4f, 0x66, 0x22,
+ /* (2^242)P */ 0xa4, 0x10, 0xbe, 0xb8, 0x83, 0x3a, 0x77, 0x8e, 0xea, 0x0a, 0xc4, 0x97, 0x3e, 0xb6, 0x6c, 0x81, 0xd7, 0x65, 0xd9, 0xf7, 0xae, 0xe6, 0xbe, 0xab, 0x59, 0x81, 0x29, 0x4b, 0xff, 0xe1, 0x0f, 0xc3, 0x2b, 0xad, 0x4b, 0xef, 0xc4, 0x50, 0x9f, 0x88, 0x31, 0xf2, 0xde, 0x80, 0xd6, 0xf4, 0x20, 0x9c, 0x77, 0x9b, 0xbe, 0xbe, 0x08, 0xf5, 0xf0, 0x95,
+ /* (2^243)P */ 0x0e, 0x7c, 0x7b, 0x7c, 0xb3, 0xd8, 0x83, 0xfc, 0x8c, 0x75, 0x51, 0x74, 0x1b, 0xe1, 0x6d, 0x11, 0x05, 0x46, 0x24, 0x0d, 0xa4, 0x2b, 0x32, 0xfd, 0x2c, 0x4e, 0x21, 0xdf, 0x39, 0x6b, 0x96, 0xfc, 0xff, 0x92, 0xfc, 0x35, 0x0d, 0x9a, 0x4b, 0xc0, 0x70, 0x46, 0x32, 0x7d, 0xc0, 0xc4, 0x04, 0xe0, 0x2d, 0x83, 0xa7, 0x00, 0xc7, 0xcb, 0xb4, 0x8f,
+ /* (2^244)P */ 0xa9, 0x5a, 0x7f, 0x0e, 0xdd, 0x2c, 0x85, 0xaa, 0x4d, 0xac, 0xde, 0xb3, 0xb6, 0xaf, 0xe6, 0xd1, 0x06, 0x7b, 0x2c, 0xa4, 0x01, 0x19, 0x22, 0x7d, 0x78, 0xf0, 0x3a, 0xea, 0x89, 0xfe, 0x21, 0x61, 0x6d, 0xb8, 0xfe, 0xa5, 0x2a, 0xab, 0x0d, 0x7b, 0x51, 0x39, 0xb6, 0xde, 0xbc, 0xf0, 0xc5, 0x48, 0xd7, 0x09, 0x82, 0x6e, 0x66, 0x75, 0xc5, 0xcd,
+ /* (2^245)P */ 0xee, 0xdf, 0x2b, 0x6c, 0xa8, 0xde, 0x61, 0xe1, 0x27, 0xfa, 0x2a, 0x0f, 0x68, 0xe7, 0x7a, 0x9b, 0x13, 0xe9, 0x56, 0xd2, 0x1c, 0x3d, 0x2f, 0x3c, 0x7a, 0xf6, 0x6f, 0x45, 0xee, 0xe8, 0xf4, 0xa0, 0xa6, 0xe8, 0xa5, 0x27, 0xee, 0xf2, 0x85, 0xa9, 0xd5, 0x0e, 0xa9, 0x26, 0x60, 0xfe, 0xee, 0xc7, 0x59, 0x99, 0x5e, 0xa3, 0xdf, 0x23, 0x36, 0xd5,
+ /* (2^246)P */ 0x15, 0x66, 0x6f, 0xd5, 0x78, 0xa4, 0x0a, 0xf7, 0xb1, 0xe8, 0x75, 0x6b, 0x48, 0x7d, 0xa6, 0x4d, 0x3d, 0x36, 0x9b, 0xc7, 0xcc, 0x68, 0x9a, 0xfe, 0x2f, 0x39, 0x2a, 0x51, 0x31, 0x39, 0x7d, 0x73, 0x6f, 0xc8, 0x74, 0x72, 0x6f, 0x6e, 0xda, 0x5f, 0xad, 0x48, 0xc8, 0x40, 0xe1, 0x06, 0x01, 0x36, 0xa1, 0x88, 0xc8, 0x99, 0x9c, 0xd1, 0x11, 0x8f,
+ /* (2^247)P */ 0xab, 0xc5, 0xcb, 0xcf, 0xbd, 0x73, 0x21, 0xd0, 0x82, 0xb1, 0x2e, 0x2d, 0xd4, 0x36, 0x1b, 0xed, 0xa9, 0x8a, 0x26, 0x79, 0xc4, 0x17, 0xae, 0xe5, 0x09, 0x0a, 0x0c, 0xa4, 0x21, 0xa0, 0x6e, 0xdd, 0x62, 0x8e, 0x44, 0x62, 0xcc, 0x50, 0xff, 0x93, 0xb3, 0x9a, 0x72, 0x8c, 0x3f, 0xa1, 0xa6, 0x4d, 0x87, 0xd5, 0x1c, 0x5a, 0xc0, 0x0b, 0x1a, 0xd6,
+ /* (2^248)P */ 0x67, 0x36, 0x6a, 0x1f, 0x96, 0xe5, 0x80, 0x20, 0xa9, 0xe8, 0x0b, 0x0e, 0x21, 0x29, 0x3f, 0xc8, 0x0a, 0x6d, 0x27, 0x47, 0xca, 0xd9, 0x05, 0x55, 0xbf, 0x11, 0xcf, 0x31, 0x7a, 0x37, 0xc7, 0x90, 0xa9, 0xf4, 0x07, 0x5e, 0xd5, 0xc3, 0x92, 0xaa, 0x95, 0xc8, 0x23, 0x2a, 0x53, 0x45, 0xe3, 0x3a, 0x24, 0xe9, 0x67, 0x97, 0x3a, 0x82, 0xf9, 0xa6,
+ /* (2^249)P */ 0x92, 0x9e, 0x6d, 0x82, 0x67, 0xe9, 0xf9, 0x17, 0x96, 0x2c, 0xa7, 0xd3, 0x89, 0xf9, 0xdb, 0xd8, 0x20, 0xc6, 0x2e, 0xec, 0x4a, 0x76, 0x64, 0xbf, 0x27, 0x40, 0xe2, 0xb4, 0xdf, 0x1f, 0xa0, 0xef, 0x07, 0x80, 0xfb, 0x8e, 0x12, 0xf8, 0xb8, 0xe1, 0xc6, 0xdf, 0x7c, 0x69, 0x35, 0x5a, 0xe1, 0x8e, 0x5d, 0x69, 0x84, 0x56, 0xb6, 0x31, 0x1c, 0x0b,
+ /* (2^250)P */ 0xd6, 0x94, 0x5c, 0xef, 0xbb, 0x46, 0x45, 0x44, 0x5b, 0xa1, 0xae, 0x03, 0x65, 0xdd, 0xb5, 0x66, 0x88, 0x35, 0x29, 0x95, 0x16, 0x54, 0xa6, 0xf5, 0xc9, 0x78, 0x34, 0xe6, 0x0f, 0xc4, 0x2b, 0x5b, 0x79, 0x51, 0x68, 0x48, 0x3a, 0x26, 0x87, 0x05, 0x70, 0xaf, 0x8b, 0xa6, 0xc7, 0x2e, 0xb3, 0xa9, 0x10, 0x01, 0xb0, 0xb9, 0x31, 0xfd, 0xdc, 0x80,
+ /* (2^251)P */ 0x25, 0xf2, 0xad, 0xd6, 0x75, 0xa3, 0x04, 0x05, 0x64, 0x8a, 0x97, 0x60, 0x27, 0x2a, 0xe5, 0x6d, 0xb0, 0x73, 0xf4, 0x07, 0x2a, 0x9d, 0xe9, 0x46, 0xb4, 0x1c, 0x51, 0xf8, 0x63, 0x98, 0x7e, 0xe5, 0x13, 0x51, 0xed, 0x98, 0x65, 0x98, 0x4f, 0x8f, 0xe7, 0x7e, 0x72, 0xd7, 0x64, 0x11, 0x2f, 0xcd, 0x12, 0xf8, 0xc4, 0x63, 0x52, 0x0f, 0x7f, 0xc4,
+ /* (2^252)P */ 0x5c, 0xd9, 0x85, 0x63, 0xc7, 0x8a, 0x65, 0x9a, 0x25, 0x83, 0x31, 0x73, 0x49, 0xf0, 0x93, 0x96, 0x70, 0x67, 0x6d, 0xb1, 0xff, 0x95, 0x54, 0xe4, 0xf8, 0x15, 0x6c, 0x5f, 0xbd, 0xf6, 0x0f, 0x38, 0x7b, 0x68, 0x7d, 0xd9, 0x3d, 0xf0, 0xa9, 0xa0, 0xe4, 0xd1, 0xb6, 0x34, 0x6d, 0x14, 0x16, 0xc2, 0x4c, 0x30, 0x0e, 0x67, 0xd3, 0xbe, 0x2e, 0xc0,
+ /* (2^253)P */ 0x06, 0x6b, 0x52, 0xc8, 0x14, 0xcd, 0xae, 0x03, 0x93, 0xea, 0xc1, 0xf2, 0xf6, 0x8b, 0xc5, 0xb6, 0xdc, 0x82, 0x42, 0x29, 0x94, 0xe0, 0x25, 0x6c, 0x3f, 0x9f, 0x5d, 0xe4, 0x96, 0xf6, 0x8e, 0x3f, 0xf9, 0x72, 0xc4, 0x77, 0x60, 0x8b, 0xa4, 0xf9, 0xa8, 0xc3, 0x0a, 0x81, 0xb1, 0x97, 0x70, 0x18, 0xab, 0xea, 0x37, 0x8a, 0x08, 0xc7, 0xe2, 0x95,
+ /* (2^254)P */ 0x94, 0x49, 0xd9, 0x5f, 0x76, 0x72, 0x82, 0xad, 0x2d, 0x50, 0x1a, 0x7a, 0x5b, 0xe6, 0x95, 0x1e, 0x95, 0x65, 0x87, 0x1c, 0x52, 0xd7, 0x44, 0xe6, 0x9b, 0x56, 0xcd, 0x6f, 0x05, 0xff, 0x67, 0xc5, 0xdb, 0xa2, 0xac, 0xe4, 0xa2, 0x28, 0x63, 0x5f, 0xfb, 0x0c, 0x3b, 0xf1, 0x87, 0xc3, 0x36, 0x78, 0x3f, 0x77, 0xfa, 0x50, 0x85, 0xf9, 0xd7, 0x82,
+ /* (2^255)P */ 0x64, 0xc0, 0xe0, 0xd8, 0x2d, 0xed, 0xcb, 0x6a, 0xfd, 0xcd, 0xbc, 0x7e, 0x9f, 0xc8, 0x85, 0xe9, 0xc1, 0x7c, 0x0f, 0xe5, 0x18, 0xea, 0xd4, 0x51, 0xad, 0x59, 0x13, 0x75, 0xd9, 0x3d, 0xd4, 0x8a, 0xb2, 0xbe, 0x78, 0x52, 0x2b, 0x52, 0x94, 0x37, 0x41, 0xd6, 0xb4, 0xb6, 0x45, 0x20, 0x76, 0xe0, 0x1f, 0x31, 0xdb, 0xb1, 0xa1, 0x43, 0xf0, 0x18,
+ /* (2^256)P */ 0x74, 0xa9, 0xa4, 0xa9, 0xdd, 0x6e, 0x3e, 0x68, 0xe5, 0xc3, 0x2e, 0x92, 0x17, 0xa4, 0xcb, 0x80, 0xb1, 0xf0, 0x06, 0x93, 0xef, 0xe6, 0x00, 0xe6, 0x3b, 0xb1, 0x32, 0x65, 0x7b, 0x83, 0xb6, 0x8a, 0x49, 0x1b, 0x14, 0x89, 0xee, 0xba, 0xf5, 0x6a, 0x8d, 0x36, 0xef, 0xb0, 0xd8, 0xb2, 0x16, 0x99, 0x17, 0x35, 0x02, 0x16, 0x55, 0x58, 0xdd, 0x82,
+ /* (2^257)P */ 0x36, 0x95, 0xe8, 0xf4, 0x36, 0x42, 0xbb, 0xc5, 0x3e, 0xfa, 0x30, 0x84, 0x9e, 0x59, 0xfd, 0xd2, 0x95, 0x42, 0xf8, 0x64, 0xd9, 0xb9, 0x0e, 0x9f, 0xfa, 0xd0, 0x7b, 0x20, 0x31, 0x77, 0x48, 0x29, 0x4d, 0xd0, 0x32, 0x57, 0x56, 0x30, 0xa6, 0x17, 0x53, 0x04, 0xbf, 0x08, 0x28, 0xec, 0xb8, 0x46, 0xc1, 0x03, 0x89, 0xdc, 0xed, 0xa0, 0x35, 0x53,
+ /* (2^258)P */ 0xc5, 0x7f, 0x9e, 0xd8, 0xc5, 0xba, 0x5f, 0x68, 0xc8, 0x23, 0x75, 0xea, 0x0d, 0xd9, 0x5a, 0xfd, 0x61, 0x1a, 0xa3, 0x2e, 0x45, 0x63, 0x14, 0x55, 0x86, 0x21, 0x29, 0xbe, 0xef, 0x5e, 0x50, 0xe5, 0x18, 0x59, 0xe7, 0xe3, 0xce, 0x4d, 0x8c, 0x15, 0x8f, 0x89, 0x66, 0x44, 0x52, 0x3d, 0xfa, 0xc7, 0x9a, 0x59, 0x90, 0x8e, 0xc0, 0x06, 0x3f, 0xc9,
+ /* (2^259)P */ 0x8e, 0x04, 0xd9, 0x16, 0x50, 0x1d, 0x8c, 0x9f, 0xd5, 0xe3, 0xce, 0xfd, 0x47, 0x04, 0x27, 0x4d, 0xc2, 0xfa, 0x71, 0xd9, 0x0b, 0xb8, 0x65, 0xf4, 0x11, 0xf3, 0x08, 0xee, 0x81, 0xc8, 0x67, 0x99, 0x0b, 0x8d, 0x77, 0xa3, 0x4f, 0xb5, 0x9b, 0xdb, 0x26, 0xf1, 0x97, 0xeb, 0x04, 0x54, 0xeb, 0x80, 0x08, 0x1d, 0x1d, 0xf6, 0x3d, 0x1f, 0x5a, 0xb8,
+ /* (2^260)P */ 0xb7, 0x9c, 0x9d, 0xee, 0xb9, 0x5c, 0xad, 0x0d, 0x9e, 0xfd, 0x60, 0x3c, 0x27, 0x4e, 0xa2, 0x95, 0xfb, 0x64, 0x7e, 0x79, 0x64, 0x87, 0x10, 0xb4, 0x73, 0xe0, 0x9d, 0x46, 0x4d, 0x3d, 0xee, 0x83, 0xe4, 0x16, 0x88, 0x97, 0xe6, 0x4d, 0xba, 0x70, 0xb6, 0x96, 0x7b, 0xff, 0x4b, 0xc8, 0xcf, 0x72, 0x83, 0x3e, 0x5b, 0x24, 0x2e, 0x57, 0xf1, 0x82,
+ /* (2^261)P */ 0x30, 0x71, 0x40, 0x51, 0x4f, 0x44, 0xbb, 0xc7, 0xf0, 0x54, 0x6e, 0x9d, 0xeb, 0x15, 0xad, 0xf8, 0x61, 0x43, 0x5a, 0xef, 0xc0, 0xb1, 0x57, 0xae, 0x03, 0x40, 0xe8, 0x68, 0x6f, 0x03, 0x20, 0x4f, 0x8a, 0x51, 0x2a, 0x9e, 0xd2, 0x45, 0xaf, 0xb4, 0xf5, 0xd4, 0x95, 0x7f, 0x3d, 0x3d, 0xb7, 0xb6, 0x28, 0xc5, 0x08, 0x8b, 0x44, 0xd6, 0x3f, 0xe7,
+ /* (2^262)P */ 0xa9, 0x52, 0x04, 0x67, 0xcb, 0x20, 0x63, 0xf8, 0x18, 0x01, 0x44, 0x21, 0x6a, 0x8a, 0x83, 0x48, 0xd4, 0xaf, 0x23, 0x0f, 0x35, 0x8d, 0xe5, 0x5a, 0xc4, 0x7c, 0x55, 0x46, 0x19, 0x5f, 0x35, 0xe0, 0x5d, 0x97, 0x4c, 0x2d, 0x04, 0xed, 0x59, 0xd4, 0xb0, 0xb2, 0xc6, 0xe3, 0x51, 0xe1, 0x38, 0xc6, 0x30, 0x49, 0x8f, 0xae, 0x61, 0x64, 0xce, 0xa8,
+ /* (2^263)P */ 0x9b, 0x64, 0x83, 0x3c, 0xd3, 0xdf, 0xb9, 0x27, 0xe7, 0x5b, 0x7f, 0xeb, 0xf3, 0x26, 0xcf, 0xb1, 0x8f, 0xaf, 0x26, 0xc8, 0x48, 0xce, 0xa1, 0xac, 0x7d, 0x10, 0x34, 0x28, 0xe1, 0x1f, 0x69, 0x03, 0x64, 0x77, 0x61, 0xdd, 0x4a, 0x9b, 0x18, 0x47, 0xf8, 0xca, 0x63, 0xc9, 0x03, 0x2d, 0x20, 0x2a, 0x69, 0x6e, 0x42, 0xd0, 0xe7, 0xaa, 0xb5, 0xf3,
+ /* (2^264)P */ 0xea, 0x31, 0x0c, 0x57, 0x0f, 0x3e, 0xe3, 0x35, 0xd8, 0x30, 0xa5, 0x6f, 0xdd, 0x95, 0x43, 0xc6, 0x66, 0x07, 0x4f, 0x34, 0xc3, 0x7e, 0x04, 0x10, 0x2d, 0xc4, 0x1c, 0x94, 0x52, 0x2e, 0x5b, 0x9a, 0x65, 0x2f, 0x91, 0xaa, 0x4f, 0x3c, 0xdc, 0x23, 0x18, 0xe1, 0x4f, 0x85, 0xcd, 0xf4, 0x8c, 0x51, 0xf7, 0xab, 0x4f, 0xdc, 0x15, 0x5c, 0x9e, 0xc5,
+ /* (2^265)P */ 0x54, 0x57, 0x23, 0x17, 0xe7, 0x82, 0x2f, 0x04, 0x7d, 0xfe, 0xe7, 0x1f, 0xa2, 0x57, 0x79, 0xe9, 0x58, 0x9b, 0xbe, 0xc6, 0x16, 0x4a, 0x17, 0x50, 0x90, 0x4a, 0x34, 0x70, 0x87, 0x37, 0x01, 0x26, 0xd8, 0xa3, 0x5f, 0x07, 0x7c, 0xd0, 0x7d, 0x05, 0x8a, 0x93, 0x51, 0x2f, 0x99, 0xea, 0xcf, 0x00, 0xd8, 0xc7, 0xe6, 0x9b, 0x8c, 0x62, 0x45, 0x87,
+ /* (2^266)P */ 0xc3, 0xfd, 0x29, 0x66, 0xe7, 0x30, 0x29, 0x77, 0xe0, 0x0d, 0x63, 0x5b, 0xe6, 0x90, 0x1a, 0x1e, 0x99, 0xc2, 0xa7, 0xab, 0xff, 0xa7, 0xbd, 0x79, 0x01, 0x97, 0xfd, 0x27, 0x1b, 0x43, 0x2b, 0xe6, 0xfe, 0x5e, 0xf1, 0xb9, 0x35, 0x38, 0x08, 0x25, 0x55, 0x90, 0x68, 0x2e, 0xc3, 0x67, 0x39, 0x9f, 0x2b, 0x2c, 0x70, 0x48, 0x8c, 0x47, 0xee, 0x56,
+ /* (2^267)P */ 0xf7, 0x32, 0x70, 0xb5, 0xe6, 0x42, 0xfd, 0x0a, 0x39, 0x9b, 0x07, 0xfe, 0x0e, 0xf4, 0x47, 0xba, 0x6a, 0x3f, 0xf5, 0x2c, 0x15, 0xf3, 0x60, 0x3f, 0xb1, 0x83, 0x7b, 0x2e, 0x34, 0x58, 0x1a, 0x6e, 0x4a, 0x49, 0x05, 0x45, 0xca, 0xdb, 0x00, 0x01, 0x0c, 0x42, 0x5e, 0x60, 0x40, 0x5f, 0xd9, 0xc7, 0x3a, 0x9e, 0x1c, 0x8d, 0xab, 0x11, 0x55, 0x65,
+ /* (2^268)P */ 0x87, 0x40, 0xb7, 0x0d, 0xaa, 0x34, 0x89, 0x90, 0x75, 0x6d, 0xa2, 0xfe, 0x3b, 0x6d, 0x5c, 0x39, 0x98, 0x10, 0x9e, 0x15, 0xc5, 0x35, 0xa2, 0x27, 0x23, 0x0a, 0x2d, 0x60, 0xe2, 0xa8, 0x7f, 0x3e, 0x77, 0x8f, 0xcc, 0x44, 0xcc, 0x30, 0x28, 0xe2, 0xf0, 0x04, 0x8c, 0xee, 0xe4, 0x5f, 0x68, 0x8c, 0xdf, 0x70, 0xbf, 0x31, 0xee, 0x2a, 0xfc, 0xce,
+ /* (2^269)P */ 0x92, 0xf2, 0xa0, 0xd9, 0x58, 0x3b, 0x7c, 0x1a, 0x99, 0x46, 0x59, 0x54, 0x60, 0x06, 0x8d, 0x5e, 0xf0, 0x22, 0xa1, 0xed, 0x92, 0x8a, 0x4d, 0x76, 0x95, 0x05, 0x0b, 0xff, 0xfc, 0x9a, 0xd1, 0xcc, 0x05, 0xb9, 0x5e, 0x99, 0xe8, 0x2a, 0x76, 0x7b, 0xfd, 0xa6, 0xe2, 0xd1, 0x1a, 0xd6, 0x76, 0x9f, 0x2f, 0x0e, 0xd1, 0xa8, 0x77, 0x5a, 0x40, 0x5a,
+ /* (2^270)P */ 0xff, 0xf9, 0x3f, 0xa9, 0xa6, 0x6c, 0x6d, 0x03, 0x8b, 0xa7, 0x10, 0x5d, 0x3f, 0xec, 0x3e, 0x1c, 0x0b, 0x6b, 0xa2, 0x6a, 0x22, 0xa9, 0x28, 0xd0, 0x66, 0xc9, 0xc2, 0x3d, 0x47, 0x20, 0x7d, 0xa6, 0x1d, 0xd8, 0x25, 0xb5, 0xf2, 0xf9, 0x70, 0x19, 0x6b, 0xf8, 0x43, 0x36, 0xc5, 0x1f, 0xe4, 0x5a, 0x4c, 0x13, 0xe4, 0x6d, 0x08, 0x0b, 0x1d, 0xb1,
+ /* (2^271)P */ 0x3f, 0x20, 0x9b, 0xfb, 0xec, 0x7d, 0x31, 0xc5, 0xfc, 0x88, 0x0b, 0x30, 0xed, 0x36, 0xc0, 0x63, 0xb1, 0x7d, 0x10, 0xda, 0xb6, 0x2e, 0xad, 0xf3, 0xec, 0x94, 0xe7, 0xec, 0xb5, 0x9c, 0xfe, 0xf5, 0x35, 0xf0, 0xa2, 0x2d, 0x7f, 0xca, 0x6b, 0x67, 0x1a, 0xf6, 0xb3, 0xda, 0x09, 0x2a, 0xaa, 0xdf, 0xb1, 0xca, 0x9b, 0xfb, 0xeb, 0xb3, 0xcd, 0xc0,
+ /* (2^272)P */ 0xcd, 0x4d, 0x89, 0x00, 0xa4, 0x3b, 0x48, 0xf0, 0x76, 0x91, 0x35, 0xa5, 0xf8, 0xc9, 0xb6, 0x46, 0xbc, 0xf6, 0x9a, 0x45, 0x47, 0x17, 0x96, 0x80, 0x5b, 0x3a, 0x28, 0x33, 0xf9, 0x5a, 0xef, 0x43, 0x07, 0xfe, 0x3b, 0xf4, 0x8e, 0x19, 0xce, 0xd2, 0x94, 0x4b, 0x6d, 0x8e, 0x67, 0x20, 0xc7, 0x4f, 0x2f, 0x59, 0x8e, 0xe1, 0xa1, 0xa9, 0xf9, 0x0e,
+ /* (2^273)P */ 0xdc, 0x7b, 0xb5, 0x50, 0x2e, 0xe9, 0x7e, 0x8b, 0x78, 0xa1, 0x38, 0x96, 0x22, 0xc3, 0x61, 0x67, 0x6d, 0xc8, 0x58, 0xed, 0x41, 0x1d, 0x5d, 0x86, 0x98, 0x7f, 0x2f, 0x1b, 0x8d, 0x3e, 0xaa, 0xc1, 0xd2, 0x0a, 0xf3, 0xbf, 0x95, 0x04, 0xf3, 0x10, 0x3c, 0x2b, 0x7f, 0x90, 0x46, 0x04, 0xaa, 0x6a, 0xa9, 0x35, 0x76, 0xac, 0x49, 0xb5, 0x00, 0x45,
+ /* (2^274)P */ 0xb1, 0x93, 0x79, 0x84, 0x4a, 0x2a, 0x30, 0x78, 0x16, 0xaa, 0xc5, 0x74, 0x06, 0xce, 0xa5, 0xa7, 0x32, 0x86, 0xe0, 0xf9, 0x10, 0xd2, 0x58, 0x76, 0xfb, 0x66, 0x49, 0x76, 0x3a, 0x90, 0xba, 0xb5, 0xcc, 0x99, 0xcd, 0x09, 0xc1, 0x9a, 0x74, 0x23, 0xdf, 0x0c, 0xfe, 0x99, 0x52, 0x80, 0xa3, 0x7c, 0x1c, 0x71, 0x5f, 0x2c, 0x49, 0x57, 0xf4, 0xf9,
+ /* (2^275)P */ 0x6d, 0xbf, 0x52, 0xe6, 0x25, 0x98, 0xed, 0xcf, 0xe3, 0xbc, 0x08, 0xa2, 0x1a, 0x90, 0xae, 0xa0, 0xbf, 0x07, 0x15, 0xad, 0x0a, 0x9f, 0x3e, 0x47, 0x44, 0xc2, 0x10, 0x46, 0xa6, 0x7a, 0x9e, 0x2f, 0x57, 0xbc, 0xe2, 0xf0, 0x1d, 0xd6, 0x9a, 0x06, 0xed, 0xfc, 0x54, 0x95, 0x92, 0x15, 0xa2, 0xf7, 0x8d, 0x6b, 0xef, 0xb2, 0x05, 0xed, 0x5c, 0x63,
+ /* (2^276)P */ 0xbc, 0x0b, 0x27, 0x3a, 0x3a, 0xf8, 0xe1, 0x48, 0x02, 0x7e, 0x27, 0xe6, 0x81, 0x62, 0x07, 0x73, 0x74, 0xe5, 0x52, 0xd7, 0xf8, 0x26, 0xca, 0x93, 0x4d, 0x3e, 0x9b, 0x55, 0x09, 0x8e, 0xe3, 0xd7, 0xa6, 0xe3, 0xb6, 0x2a, 0xa9, 0xb3, 0xb0, 0xa0, 0x8c, 0x01, 0xbb, 0x07, 0x90, 0x78, 0x6d, 0x6d, 0xe9, 0xf0, 0x7a, 0x90, 0xbd, 0xdc, 0x0c, 0x36,
+ /* (2^277)P */ 0x7f, 0x20, 0x12, 0x0f, 0x40, 0x00, 0x53, 0xd8, 0x0c, 0x27, 0x47, 0x47, 0x22, 0x80, 0xfb, 0x62, 0xe4, 0xa7, 0xf7, 0xbd, 0x42, 0xa5, 0xc3, 0x2b, 0xb2, 0x7f, 0x50, 0xcc, 0xe2, 0xfb, 0xd5, 0xc0, 0x63, 0xdd, 0x24, 0x5f, 0x7c, 0x08, 0x91, 0xbf, 0x6e, 0x47, 0x44, 0xd4, 0x6a, 0xc0, 0xc3, 0x09, 0x39, 0x27, 0xdd, 0xc7, 0xca, 0x06, 0x29, 0x55,
+ /* (2^278)P */ 0x76, 0x28, 0x58, 0xb0, 0xd2, 0xf3, 0x0f, 0x04, 0xe9, 0xc9, 0xab, 0x66, 0x5b, 0x75, 0x51, 0xdc, 0xe5, 0x8f, 0xe8, 0x1f, 0xdb, 0x03, 0x0f, 0xb0, 0x7d, 0xf9, 0x20, 0x64, 0x89, 0xe9, 0xdc, 0xe6, 0x24, 0xc3, 0xd5, 0xd2, 0x41, 0xa6, 0xe4, 0xe3, 0xc4, 0x79, 0x7c, 0x0f, 0xa1, 0x61, 0x2f, 0xda, 0xa4, 0xc9, 0xfd, 0xad, 0x5c, 0x65, 0x6a, 0xf3,
+ /* (2^279)P */ 0xd5, 0xab, 0x72, 0x7a, 0x3b, 0x59, 0xea, 0xcf, 0xd5, 0x17, 0xd2, 0xb2, 0x5f, 0x2d, 0xab, 0xad, 0x9e, 0x88, 0x64, 0x55, 0x96, 0x6e, 0xf3, 0x44, 0xa9, 0x11, 0xf5, 0xf8, 0x3a, 0xf1, 0xcd, 0x79, 0x4c, 0x99, 0x6d, 0x23, 0x6a, 0xa0, 0xc2, 0x1a, 0x19, 0x45, 0xb5, 0xd8, 0x95, 0x2f, 0x49, 0xe9, 0x46, 0x39, 0x26, 0x60, 0x04, 0x15, 0x8b, 0xcc,
+ /* (2^280)P */ 0x66, 0x0c, 0xf0, 0x54, 0x41, 0x02, 0x91, 0xab, 0xe5, 0x85, 0x8a, 0x44, 0xa6, 0x34, 0x96, 0x32, 0xc0, 0xdf, 0x6c, 0x41, 0x39, 0xd4, 0xc6, 0xe1, 0xe3, 0x81, 0xb0, 0x4c, 0x34, 0x4f, 0xe5, 0xf4, 0x35, 0x46, 0x1f, 0xeb, 0x75, 0xfd, 0x43, 0x37, 0x50, 0x99, 0xab, 0xad, 0xb7, 0x8c, 0xa1, 0x57, 0xcb, 0xe6, 0xce, 0x16, 0x2e, 0x85, 0xcc, 0xf9,
+ /* (2^281)P */ 0x63, 0xd1, 0x3f, 0x9e, 0xa2, 0x17, 0x2e, 0x1d, 0x3e, 0xce, 0x48, 0x2d, 0xbb, 0x8f, 0x69, 0xc9, 0xa6, 0x3d, 0x4e, 0xfe, 0x09, 0x56, 0xb3, 0x02, 0x5f, 0x99, 0x97, 0x0c, 0x54, 0xda, 0x32, 0x97, 0x9b, 0xf4, 0x95, 0xf1, 0xad, 0xe3, 0x2b, 0x04, 0xa7, 0x9b, 0x3f, 0xbb, 0xe7, 0x87, 0x2e, 0x1f, 0x8b, 0x4b, 0x7a, 0xa4, 0x43, 0x0c, 0x0f, 0x35,
+ /* (2^282)P */ 0x05, 0xdc, 0xe0, 0x2c, 0xa1, 0xc1, 0xd0, 0xf1, 0x1f, 0x4e, 0xc0, 0x6c, 0x35, 0x7b, 0xca, 0x8f, 0x8b, 0x02, 0xb1, 0xf7, 0xd6, 0x2e, 0xe7, 0x93, 0x80, 0x85, 0x18, 0x88, 0x19, 0xb9, 0xb4, 0x4a, 0xbc, 0xeb, 0x5a, 0x78, 0x38, 0xed, 0xc6, 0x27, 0x2a, 0x74, 0x76, 0xf0, 0x1b, 0x79, 0x92, 0x2f, 0xd2, 0x81, 0x98, 0xdf, 0xa9, 0x50, 0x19, 0xeb,
+ /* (2^283)P */ 0xb5, 0xe7, 0xb4, 0x11, 0x3a, 0x81, 0xb6, 0xb4, 0xf8, 0xa2, 0xb3, 0x6c, 0xfc, 0x9d, 0xe0, 0xc0, 0xe0, 0x59, 0x7f, 0x05, 0x37, 0xef, 0x2c, 0xa9, 0x3a, 0x24, 0xac, 0x7b, 0x25, 0xa0, 0x55, 0xd2, 0x44, 0x82, 0x82, 0x6e, 0x64, 0xa3, 0x58, 0xc8, 0x67, 0xae, 0x26, 0xa7, 0x0f, 0x42, 0x63, 0xe1, 0x93, 0x01, 0x52, 0x19, 0xaf, 0x49, 0x3e, 0x33,
+ /* (2^284)P */ 0x05, 0x85, 0xe6, 0x66, 0xaf, 0x5f, 0xdf, 0xbf, 0x9d, 0x24, 0x62, 0x60, 0x90, 0xe2, 0x4c, 0x7d, 0x4e, 0xc3, 0x74, 0x5d, 0x4f, 0x53, 0xf3, 0x63, 0x13, 0xf4, 0x74, 0x28, 0x6b, 0x7d, 0x57, 0x0c, 0x9d, 0x84, 0xa7, 0x1a, 0xff, 0xa0, 0x79, 0xdf, 0xfc, 0x65, 0x98, 0x8e, 0x22, 0x0d, 0x62, 0x7e, 0xf2, 0x34, 0x60, 0x83, 0x05, 0x14, 0xb1, 0xc1,
+ /* (2^285)P */ 0x64, 0x22, 0xcc, 0xdf, 0x5c, 0xbc, 0x88, 0x68, 0x4c, 0xd9, 0xbc, 0x0e, 0xc9, 0x8b, 0xb4, 0x23, 0x52, 0xad, 0xb0, 0xb3, 0xf1, 0x17, 0xd8, 0x15, 0x04, 0x6b, 0x99, 0xf0, 0xc4, 0x7d, 0x48, 0x22, 0x4a, 0xf8, 0x6f, 0xaa, 0x88, 0x0d, 0xc5, 0x5e, 0xa9, 0x1c, 0x61, 0x3d, 0x95, 0xa9, 0x7b, 0x6a, 0x79, 0x33, 0x0a, 0x2b, 0x99, 0xe3, 0x4e, 0x48,
+ /* (2^286)P */ 0x6b, 0x9b, 0x6a, 0x2a, 0xf1, 0x60, 0x31, 0xb4, 0x73, 0xd1, 0x87, 0x45, 0x9c, 0x15, 0x58, 0x4b, 0x91, 0x6d, 0x94, 0x1c, 0x41, 0x11, 0x4a, 0x83, 0xec, 0xaf, 0x65, 0xbc, 0x34, 0xaa, 0x26, 0xe2, 0xaf, 0xed, 0x46, 0x05, 0x4e, 0xdb, 0xc6, 0x4e, 0x10, 0x28, 0x4e, 0x72, 0xe5, 0x31, 0xa3, 0x20, 0xd7, 0xb1, 0x96, 0x64, 0xf6, 0xce, 0x08, 0x08,
+ /* (2^287)P */ 0x16, 0xa9, 0x5c, 0x9f, 0x9a, 0xb4, 0xb8, 0xc8, 0x32, 0x78, 0xc0, 0x3a, 0xd9, 0x5f, 0x94, 0xac, 0x3a, 0x42, 0x1f, 0x43, 0xd6, 0x80, 0x47, 0x2c, 0xdc, 0x76, 0x27, 0xfa, 0x50, 0xe5, 0xa1, 0xe4, 0xc3, 0xcb, 0x61, 0x31, 0xe1, 0x2e, 0xde, 0x81, 0x3b, 0x77, 0x1c, 0x39, 0x3c, 0xdb, 0xda, 0x87, 0x4b, 0x84, 0x12, 0xeb, 0xdd, 0x54, 0xbf, 0xe7,
+ /* (2^288)P */ 0xbf, 0xcb, 0x73, 0x21, 0x3d, 0x7e, 0x13, 0x8c, 0xa6, 0x34, 0x21, 0x2b, 0xa5, 0xe4, 0x9f, 0x8e, 0x9c, 0x01, 0x9c, 0x43, 0xd9, 0xc7, 0xb9, 0xf1, 0xbe, 0x7f, 0x45, 0x51, 0x97, 0xa1, 0x8e, 0x01, 0xf8, 0xbd, 0xd2, 0xbf, 0x81, 0x3a, 0x8b, 0xab, 0xe4, 0x89, 0xb7, 0xbd, 0xf2, 0xcd, 0xa9, 0x8a, 0x8a, 0xde, 0xfb, 0x8a, 0x55, 0x12, 0x7b, 0x17,
+ /* (2^289)P */ 0x1b, 0x95, 0x58, 0x4d, 0xe6, 0x51, 0x31, 0x52, 0x1c, 0xd8, 0x15, 0x84, 0xb1, 0x0d, 0x36, 0x25, 0x88, 0x91, 0x46, 0x71, 0x42, 0x56, 0xe2, 0x90, 0x08, 0x9e, 0x77, 0x1b, 0xee, 0x22, 0x3f, 0xec, 0xee, 0x8c, 0x7b, 0x2e, 0x79, 0xc4, 0x6c, 0x07, 0xa1, 0x7e, 0x52, 0xf5, 0x26, 0x5c, 0x84, 0x2a, 0x50, 0x6e, 0x82, 0xb3, 0x76, 0xda, 0x35, 0x16,
+ /* (2^290)P */ 0x0a, 0x6f, 0x99, 0x87, 0xc0, 0x7d, 0x8a, 0xb2, 0xca, 0xae, 0xe8, 0x65, 0x98, 0x0f, 0xb3, 0x44, 0xe1, 0xdc, 0x52, 0x79, 0x75, 0xec, 0x8f, 0x95, 0x87, 0x45, 0xd1, 0x32, 0x18, 0x55, 0x15, 0xce, 0x64, 0x9b, 0x08, 0x4f, 0x2c, 0xea, 0xba, 0x1c, 0x57, 0x06, 0x63, 0xc8, 0xb1, 0xfd, 0xc5, 0x67, 0xe7, 0x1f, 0x87, 0x9e, 0xde, 0x72, 0x7d, 0xec,
+ /* (2^291)P */ 0x36, 0x8b, 0x4d, 0x2c, 0xc2, 0x46, 0xe8, 0x96, 0xac, 0x0b, 0x8c, 0xc5, 0x09, 0x10, 0xfc, 0xf2, 0xda, 0xea, 0x22, 0xb2, 0xd3, 0x89, 0xeb, 0xb2, 0x85, 0x0f, 0xff, 0x59, 0x50, 0x2c, 0x99, 0x5a, 0x1f, 0xec, 0x2a, 0x6f, 0xec, 0xcf, 0xe9, 0xce, 0x12, 0x6b, 0x19, 0xd8, 0xde, 0x9b, 0xce, 0x0e, 0x6a, 0xaa, 0xe1, 0x32, 0xea, 0x4c, 0xfe, 0x92,
+ /* (2^292)P */ 0x5f, 0x17, 0x70, 0x53, 0x26, 0x03, 0x0b, 0xab, 0xd1, 0xc1, 0x42, 0x0b, 0xab, 0x2b, 0x3d, 0x31, 0xa4, 0xd5, 0x2b, 0x5e, 0x00, 0xd5, 0x9a, 0x22, 0x34, 0xe0, 0x53, 0x3f, 0x59, 0x7f, 0x2c, 0x6d, 0x72, 0x9a, 0xa4, 0xbe, 0x3d, 0x42, 0x05, 0x1b, 0xf2, 0x7f, 0x88, 0x56, 0xd1, 0x7c, 0x7d, 0x6b, 0x9f, 0x43, 0xfe, 0x65, 0x19, 0xae, 0x9c, 0x4c,
+ /* (2^293)P */ 0xf3, 0x7c, 0x20, 0xa9, 0xfc, 0xf2, 0xf2, 0x3b, 0x3c, 0x57, 0x41, 0x94, 0xe5, 0xcc, 0x6a, 0x37, 0x5d, 0x09, 0xf2, 0xab, 0xc2, 0xca, 0x60, 0x38, 0x6b, 0x7a, 0xe1, 0x78, 0x2b, 0xc1, 0x1d, 0xe8, 0xfd, 0xbc, 0x3d, 0x5c, 0xa2, 0xdb, 0x49, 0x20, 0x79, 0xe6, 0x1b, 0x9b, 0x65, 0xd9, 0x6d, 0xec, 0x57, 0x1d, 0xd2, 0xe9, 0x90, 0xeb, 0x43, 0x7b,
+ /* (2^294)P */ 0x2a, 0x8b, 0x2e, 0x19, 0x18, 0x10, 0xb8, 0x83, 0xe7, 0x7d, 0x2d, 0x9a, 0x3a, 0xe5, 0xd1, 0xe4, 0x7c, 0x38, 0xe5, 0x59, 0x2a, 0x6e, 0xd9, 0x01, 0x29, 0x3d, 0x23, 0xf7, 0x52, 0xba, 0x61, 0x04, 0x9a, 0xde, 0xc4, 0x31, 0x50, 0xeb, 0x1b, 0xaa, 0xde, 0x39, 0x58, 0xd8, 0x1b, 0x1e, 0xfc, 0x57, 0x9a, 0x28, 0x43, 0x9e, 0x97, 0x5e, 0xaa, 0xa3,
+ /* (2^295)P */ 0x97, 0x0a, 0x74, 0xc4, 0x39, 0x99, 0x6b, 0x40, 0xc7, 0x3e, 0x8c, 0xa7, 0xb1, 0x4e, 0x9a, 0x59, 0x6e, 0x1c, 0xfe, 0xfc, 0x2a, 0x5e, 0x73, 0x2b, 0x8c, 0xa9, 0x71, 0xf5, 0xda, 0x6b, 0x15, 0xab, 0xf7, 0xbe, 0x2a, 0x44, 0x5f, 0xba, 0xae, 0x67, 0x93, 0xc5, 0x86, 0xc1, 0xb8, 0xdf, 0xdc, 0xcb, 0xd7, 0xff, 0xb1, 0x71, 0x7c, 0x6f, 0x88, 0xf8,
+ /* (2^296)P */ 0x3f, 0x89, 0xb1, 0xbf, 0x24, 0x16, 0xac, 0x56, 0xfe, 0xdf, 0x94, 0x71, 0xbf, 0xd6, 0x57, 0x0c, 0xb4, 0x77, 0x37, 0xaa, 0x2a, 0x70, 0x76, 0x49, 0xaf, 0x0c, 0x97, 0x8e, 0x78, 0x2a, 0x67, 0xc9, 0x3b, 0x3d, 0x5b, 0x01, 0x2f, 0xda, 0xd5, 0xa8, 0xde, 0x02, 0xa9, 0xac, 0x76, 0x00, 0x0b, 0x46, 0xc6, 0x2d, 0xdc, 0x08, 0xf4, 0x10, 0x2c, 0xbe,
+ /* (2^297)P */ 0xcb, 0x07, 0xf9, 0x91, 0xc6, 0xd5, 0x3e, 0x54, 0x63, 0xae, 0xfc, 0x10, 0xbe, 0x3a, 0x20, 0x73, 0x4e, 0x65, 0x0e, 0x2d, 0x86, 0x77, 0x83, 0x9d, 0xe2, 0x0a, 0xe9, 0xac, 0x22, 0x52, 0x76, 0xd4, 0x6e, 0xfa, 0xe0, 0x09, 0xef, 0x78, 0x82, 0x9f, 0x26, 0xf9, 0x06, 0xb5, 0xe7, 0x05, 0x0e, 0xf2, 0x46, 0x72, 0x93, 0xd3, 0x24, 0xbd, 0x87, 0x60,
+ /* (2^298)P */ 0x14, 0x55, 0x84, 0x7b, 0x6c, 0x60, 0x80, 0x73, 0x8c, 0xbe, 0x2d, 0xd6, 0x69, 0xd6, 0x17, 0x26, 0x44, 0x9f, 0x88, 0xa2, 0x39, 0x7c, 0x89, 0xbc, 0x6d, 0x9e, 0x46, 0xb6, 0x68, 0x66, 0xea, 0xdc, 0x31, 0xd6, 0x21, 0x51, 0x9f, 0x28, 0x28, 0xaf, 0x9e, 0x47, 0x2c, 0x4c, 0x8f, 0xf3, 0xaf, 0x1f, 0xe4, 0xab, 0xac, 0xe9, 0x0c, 0x91, 0x3a, 0x61,
+ /* (2^299)P */ 0xb0, 0x37, 0x55, 0x4b, 0xe9, 0xc3, 0xb1, 0xce, 0x42, 0xe6, 0xc5, 0x11, 0x7f, 0x2c, 0x11, 0xfc, 0x4e, 0x71, 0x17, 0x00, 0x74, 0x7f, 0xbf, 0x07, 0x4d, 0xfd, 0x40, 0xb2, 0x87, 0xb0, 0xef, 0x1f, 0x35, 0x2c, 0x2d, 0xd7, 0xe1, 0xe4, 0xad, 0x0e, 0x7f, 0x63, 0x66, 0x62, 0x23, 0x41, 0xf6, 0xc1, 0x14, 0xa6, 0xd7, 0xa9, 0x11, 0x56, 0x9d, 0x1b,
+ /* (2^300)P */ 0x02, 0x82, 0x42, 0x18, 0x4f, 0x1b, 0xc9, 0x5d, 0x78, 0x5f, 0xee, 0xed, 0x01, 0x49, 0x8f, 0xf2, 0xa0, 0xe2, 0x6e, 0xbb, 0x6b, 0x04, 0x8d, 0xb2, 0x41, 0xae, 0xc8, 0x1b, 0x59, 0x34, 0xb8, 0x2a, 0xdb, 0x1f, 0xd2, 0x52, 0xdf, 0x3f, 0x35, 0x00, 0x8b, 0x61, 0xbc, 0x97, 0xa0, 0xc4, 0x77, 0xd1, 0xe4, 0x2c, 0x59, 0x68, 0xff, 0x30, 0xf2, 0xe2,
+ /* (2^301)P */ 0x79, 0x08, 0xb1, 0xdb, 0x55, 0xae, 0xd0, 0xed, 0xda, 0xa0, 0xec, 0x6c, 0xae, 0x68, 0xf2, 0x0b, 0x61, 0xb3, 0xf5, 0x21, 0x69, 0x87, 0x0b, 0x03, 0xea, 0x8a, 0x15, 0xd9, 0x7e, 0xca, 0xf7, 0xcd, 0xf3, 0x33, 0xb3, 0x4c, 0x5b, 0x23, 0x4e, 0x6f, 0x90, 0xad, 0x91, 0x4b, 0x4f, 0x46, 0x37, 0xe5, 0xe8, 0xb7, 0xeb, 0xd5, 0xca, 0x34, 0x4e, 0x23,
+ /* (2^302)P */ 0x09, 0x02, 0xdd, 0xfd, 0x70, 0xac, 0x56, 0x80, 0x36, 0x5e, 0x49, 0xd0, 0x3f, 0xc2, 0xe0, 0xba, 0x46, 0x7f, 0x5c, 0xf7, 0xc5, 0xbd, 0xd5, 0x55, 0x7d, 0x3f, 0xd5, 0x7d, 0x06, 0xdf, 0x27, 0x20, 0x4f, 0xe9, 0x30, 0xec, 0x1b, 0xa0, 0x0c, 0xd4, 0x2c, 0xe1, 0x2b, 0x65, 0x73, 0xea, 0x75, 0x35, 0xe8, 0xe6, 0x56, 0xd6, 0x07, 0x15, 0x99, 0xdf,
+ /* (2^303)P */ 0x4e, 0x10, 0xb7, 0xd0, 0x63, 0x8c, 0xcf, 0x16, 0x00, 0x7c, 0x58, 0xdf, 0x86, 0xdc, 0x4e, 0xca, 0x9c, 0x40, 0x5a, 0x42, 0xfd, 0xec, 0x98, 0xa4, 0x42, 0x53, 0xae, 0x16, 0x9d, 0xfd, 0x75, 0x5a, 0x12, 0x56, 0x1e, 0xc6, 0x57, 0xcc, 0x79, 0x27, 0x96, 0x00, 0xcf, 0x80, 0x4f, 0x8a, 0x36, 0x5c, 0xbb, 0xe9, 0x12, 0xdb, 0xb6, 0x2b, 0xad, 0x96,
+ /* (2^304)P */ 0x92, 0x32, 0x1f, 0xfd, 0xc6, 0x02, 0x94, 0x08, 0x1b, 0x60, 0x6a, 0x9f, 0x8b, 0xd6, 0xc8, 0xad, 0xd5, 0x1b, 0x27, 0x4e, 0xa4, 0x4d, 0x4a, 0x00, 0x10, 0x5f, 0x86, 0x11, 0xf5, 0xe3, 0x14, 0x32, 0x43, 0xee, 0xb9, 0xc7, 0xab, 0xf4, 0x6f, 0xe5, 0x66, 0x0c, 0x06, 0x0d, 0x96, 0x79, 0x28, 0xaf, 0x45, 0x2b, 0x56, 0xbe, 0xe4, 0x4a, 0x52, 0xd6,
+ /* (2^305)P */ 0x15, 0x16, 0x69, 0xef, 0x60, 0xca, 0x82, 0x25, 0x0f, 0xc6, 0x30, 0xa0, 0x0a, 0xd1, 0x83, 0x29, 0xcd, 0xb6, 0x89, 0x6c, 0xf5, 0xb2, 0x08, 0x38, 0xe6, 0xca, 0x6b, 0x19, 0x93, 0xc6, 0x5f, 0x75, 0x8e, 0x60, 0x34, 0x23, 0xc4, 0x13, 0x17, 0x69, 0x55, 0xcc, 0x72, 0x9c, 0x2b, 0x6c, 0x80, 0xf4, 0x4b, 0x8b, 0xb6, 0x97, 0x65, 0x07, 0xb6, 0xfb,
+ /* (2^306)P */ 0x01, 0x99, 0x74, 0x28, 0xa6, 0x67, 0xa3, 0xe5, 0x25, 0xfb, 0xdf, 0x82, 0x93, 0xe7, 0x35, 0x74, 0xce, 0xe3, 0x15, 0x1c, 0x1d, 0x79, 0x52, 0x84, 0x08, 0x04, 0x2f, 0x5c, 0xb8, 0xcd, 0x7f, 0x89, 0xb0, 0x39, 0x93, 0x63, 0xc9, 0x5d, 0x06, 0x01, 0x59, 0xf7, 0x7e, 0xf1, 0x4c, 0x3d, 0x12, 0x8d, 0x69, 0x1d, 0xb7, 0x21, 0x5e, 0x88, 0x82, 0xa2,
+ /* (2^307)P */ 0x8e, 0x69, 0xaf, 0x9a, 0x41, 0x0d, 0x9d, 0xcf, 0x8e, 0x8d, 0x5c, 0x51, 0x6e, 0xde, 0x0e, 0x48, 0x23, 0x89, 0xe5, 0x37, 0x80, 0xd6, 0x9d, 0x72, 0x32, 0x26, 0x38, 0x2d, 0x63, 0xa0, 0xfa, 0xd3, 0x40, 0xc0, 0x8c, 0x68, 0x6f, 0x2b, 0x1e, 0x9a, 0x39, 0x51, 0x78, 0x74, 0x9a, 0x7b, 0x4a, 0x8f, 0x0c, 0xa0, 0x88, 0x60, 0xa5, 0x21, 0xcd, 0xc7,
+ /* (2^308)P */ 0x3a, 0x7f, 0x73, 0x14, 0xbf, 0x89, 0x6a, 0x4c, 0x09, 0x5d, 0xf2, 0x93, 0x20, 0x2d, 0xc4, 0x29, 0x86, 0x06, 0x95, 0xab, 0x22, 0x76, 0x4c, 0x54, 0xe1, 0x7e, 0x80, 0x6d, 0xab, 0x29, 0x61, 0x87, 0x77, 0xf6, 0xc0, 0x3e, 0xda, 0xab, 0x65, 0x7e, 0x39, 0x12, 0xa1, 0x6b, 0x42, 0xf7, 0xc5, 0x97, 0x77, 0xec, 0x6f, 0x22, 0xbe, 0x44, 0xc7, 0x03,
+ /* (2^309)P */ 0xa5, 0x23, 0x90, 0x41, 0xa3, 0xc5, 0x3e, 0xe0, 0xa5, 0x32, 0x49, 0x1f, 0x39, 0x78, 0xb1, 0xd8, 0x24, 0xea, 0xd4, 0x87, 0x53, 0x42, 0x51, 0xf4, 0xd9, 0x46, 0x25, 0x2f, 0x62, 0xa9, 0x90, 0x9a, 0x4a, 0x25, 0x8a, 0xd2, 0x10, 0xe7, 0x3c, 0xbc, 0x58, 0x8d, 0x16, 0x14, 0x96, 0xa4, 0x6f, 0xf8, 0x12, 0x69, 0x91, 0x73, 0xe2, 0xfa, 0xf4, 0x57,
+ /* (2^310)P */ 0x51, 0x45, 0x3f, 0x96, 0xdc, 0x97, 0x38, 0xa6, 0x01, 0x63, 0x09, 0xea, 0xc2, 0x13, 0x30, 0xb0, 0x00, 0xb8, 0x0a, 0xce, 0xd1, 0x8f, 0x3e, 0x69, 0x62, 0x46, 0x33, 0x9c, 0xbf, 0x4b, 0xcb, 0x0c, 0x90, 0x1c, 0x45, 0xcf, 0x37, 0x5b, 0xf7, 0x4b, 0x5e, 0x95, 0xc3, 0x28, 0x9f, 0x08, 0x83, 0x53, 0x74, 0xab, 0x0c, 0xb4, 0xc0, 0xa1, 0xbc, 0x89,
+ /* (2^311)P */ 0x06, 0xb1, 0x51, 0x15, 0x65, 0x60, 0x21, 0x17, 0x7a, 0x20, 0x65, 0xee, 0x12, 0x35, 0x4d, 0x46, 0xf4, 0xf8, 0xd0, 0xb1, 0xca, 0x09, 0x30, 0x08, 0x89, 0x23, 0x3b, 0xe7, 0xab, 0x8b, 0x77, 0xa6, 0xad, 0x25, 0xdd, 0xea, 0x3c, 0x7d, 0xa5, 0x24, 0xb3, 0xe8, 0xfa, 0xfb, 0xc9, 0xf2, 0x71, 0xe9, 0xfa, 0xf2, 0xdc, 0x54, 0xdd, 0x55, 0x2e, 0x2f,
+ /* (2^312)P */ 0x7f, 0x96, 0x96, 0xfb, 0x52, 0x86, 0xcf, 0xea, 0x62, 0x18, 0xf1, 0x53, 0x1f, 0x61, 0x2a, 0x9f, 0x8c, 0x51, 0xca, 0x2c, 0xde, 0x6d, 0xce, 0xab, 0x58, 0x32, 0x0b, 0x33, 0x9b, 0x99, 0xb4, 0x5c, 0x88, 0x2a, 0x76, 0xcc, 0x3e, 0x54, 0x1e, 0x9d, 0xa2, 0x89, 0xe4, 0x19, 0xba, 0x80, 0xc8, 0x39, 0x32, 0x7f, 0x0f, 0xc7, 0x84, 0xbb, 0x43, 0x56,
+ /* (2^313)P */ 0x9b, 0x07, 0xb4, 0x42, 0xa9, 0xa0, 0x78, 0x4f, 0x28, 0x70, 0x2b, 0x7e, 0x61, 0xe0, 0xdd, 0x02, 0x98, 0xfc, 0xed, 0x31, 0x80, 0xf1, 0x15, 0x52, 0x89, 0x23, 0xcd, 0x5d, 0x2b, 0xc5, 0x19, 0x32, 0xfb, 0x70, 0x50, 0x7a, 0x97, 0x6b, 0x42, 0xdb, 0xca, 0xdb, 0xc4, 0x59, 0x99, 0xe0, 0x12, 0x1f, 0x17, 0xba, 0x8b, 0xf0, 0xc4, 0x38, 0x5d, 0x27,
+ /* (2^314)P */ 0x29, 0x1d, 0xdc, 0x2b, 0xf6, 0x5b, 0x04, 0x61, 0x36, 0x76, 0xa0, 0x56, 0x36, 0x6e, 0xd7, 0x24, 0x4d, 0xe7, 0xef, 0x44, 0xd2, 0xd5, 0x07, 0xcd, 0xc4, 0x9d, 0x80, 0x48, 0xc3, 0x38, 0xcf, 0xd8, 0xa3, 0xdd, 0xb2, 0x5e, 0xb5, 0x70, 0x15, 0xbb, 0x36, 0x85, 0x8a, 0xd7, 0xfb, 0x56, 0x94, 0x73, 0x9c, 0x81, 0xbe, 0xb1, 0x44, 0x28, 0xf1, 0x37,
+ /* (2^315)P */ 0xbf, 0xcf, 0x5c, 0xd2, 0xe2, 0xea, 0xc2, 0xcd, 0x70, 0x7a, 0x9d, 0xcb, 0x81, 0xc1, 0xe9, 0xf1, 0x56, 0x71, 0x52, 0xf7, 0x1b, 0x87, 0xc6, 0xd8, 0xcc, 0xb2, 0x69, 0xf3, 0xb0, 0xbd, 0xba, 0x83, 0x12, 0x26, 0xc4, 0xce, 0x72, 0xde, 0x3b, 0x21, 0x28, 0x9e, 0x5a, 0x94, 0xf5, 0x04, 0xa3, 0xc8, 0x0f, 0x5e, 0xbc, 0x71, 0xf9, 0x0d, 0xce, 0xf5,
+ /* (2^316)P */ 0x93, 0x97, 0x00, 0x85, 0xf4, 0xb4, 0x40, 0xec, 0xd9, 0x2b, 0x6c, 0xd6, 0x63, 0x9e, 0x93, 0x0a, 0x5a, 0xf4, 0xa7, 0x9a, 0xe3, 0x3c, 0xf0, 0x55, 0xd1, 0x96, 0x6c, 0xf5, 0x2a, 0xce, 0xd7, 0x95, 0x72, 0xbf, 0xc5, 0x0c, 0xce, 0x79, 0xa2, 0x0a, 0x78, 0xe0, 0x72, 0xd0, 0x66, 0x28, 0x05, 0x75, 0xd3, 0x23, 0x09, 0x91, 0xed, 0x7e, 0xc4, 0xbc,
+ /* (2^317)P */ 0x77, 0xc2, 0x9a, 0xf7, 0xa6, 0xe6, 0x18, 0xb4, 0xe7, 0xf6, 0xda, 0xec, 0x44, 0x6d, 0xfb, 0x08, 0xee, 0x65, 0xa8, 0x92, 0x85, 0x1f, 0xba, 0x38, 0x93, 0x20, 0x5c, 0x4d, 0xd2, 0x18, 0x0f, 0x24, 0xbe, 0x1a, 0x96, 0x44, 0x7d, 0xeb, 0xb3, 0xda, 0x95, 0xf4, 0xaf, 0x6c, 0x06, 0x0f, 0x47, 0x37, 0xc8, 0x77, 0x63, 0xe1, 0x29, 0xef, 0xff, 0xa5,
+ /* (2^318)P */ 0x16, 0x12, 0xd9, 0x47, 0x90, 0x22, 0x9b, 0x05, 0xf2, 0xa5, 0x9a, 0xae, 0x83, 0x98, 0xb5, 0xac, 0xab, 0x29, 0xaa, 0xdc, 0x5f, 0xde, 0xcd, 0xf7, 0x42, 0xad, 0x3b, 0x96, 0xd6, 0x3e, 0x6e, 0x52, 0x47, 0xb1, 0xab, 0x51, 0xde, 0x49, 0x7c, 0x87, 0x8d, 0x86, 0xe2, 0x70, 0x13, 0x21, 0x51, 0x1c, 0x0c, 0x25, 0xc1, 0xb0, 0xe6, 0x19, 0xcf, 0x12,
+ /* (2^319)P */ 0xf0, 0xbc, 0x97, 0x8f, 0x4b, 0x2f, 0xd1, 0x1f, 0x8c, 0x57, 0xed, 0x3c, 0xf4, 0x26, 0x19, 0xbb, 0x60, 0xca, 0x24, 0xc5, 0xd9, 0x97, 0xe2, 0x5f, 0x76, 0x49, 0x39, 0x7e, 0x2d, 0x12, 0x21, 0x98, 0xda, 0xe6, 0xdb, 0xd2, 0xd8, 0x9f, 0x18, 0xd8, 0x83, 0x6c, 0xba, 0x89, 0x8d, 0x29, 0xfa, 0x46, 0x33, 0x8c, 0x28, 0xdf, 0x6a, 0xb3, 0x69, 0x28,
+ /* (2^320)P */ 0x86, 0x17, 0xbc, 0xd6, 0x7c, 0xba, 0x1e, 0x83, 0xbb, 0x84, 0xb5, 0x8c, 0xad, 0xdf, 0xa1, 0x24, 0x81, 0x70, 0x40, 0x0f, 0xad, 0xad, 0x3b, 0x23, 0xd0, 0x93, 0xa0, 0x49, 0x5c, 0x4b, 0x51, 0xbe, 0x20, 0x49, 0x4e, 0xda, 0x2d, 0xd3, 0xad, 0x1b, 0x74, 0x08, 0x41, 0xf0, 0xef, 0x19, 0xe9, 0x45, 0x5d, 0x02, 0xae, 0x26, 0x25, 0xd9, 0xd1, 0xc2,
+ /* (2^321)P */ 0x48, 0x81, 0x3e, 0xb2, 0x83, 0xf8, 0x4d, 0xb3, 0xd0, 0x4c, 0x75, 0xb3, 0xa0, 0x52, 0x26, 0xf2, 0xaf, 0x5d, 0x36, 0x70, 0x72, 0xd6, 0xb7, 0x88, 0x08, 0x69, 0xbd, 0x15, 0x25, 0xb1, 0x45, 0x1b, 0xb7, 0x0b, 0x5f, 0x71, 0x5d, 0x83, 0x49, 0xb9, 0x84, 0x3b, 0x7c, 0xc1, 0x50, 0x93, 0x05, 0x53, 0xe0, 0x61, 0xea, 0xc1, 0xef, 0xdb, 0x82, 0x97,
+ /* (2^322)P */ 0x00, 0xd5, 0xc3, 0x3a, 0x4d, 0x8a, 0x23, 0x7a, 0xef, 0xff, 0x37, 0xef, 0xf3, 0xbc, 0xa9, 0xb6, 0xae, 0xd7, 0x3a, 0x7b, 0xfd, 0x3e, 0x8e, 0x9b, 0xab, 0x44, 0x54, 0x60, 0x28, 0x6c, 0xbf, 0x15, 0x24, 0x4a, 0x56, 0x60, 0x7f, 0xa9, 0x7a, 0x28, 0x59, 0x2c, 0x8a, 0xd1, 0x7d, 0x6b, 0x00, 0xfd, 0xa5, 0xad, 0xbc, 0x19, 0x3f, 0xcb, 0x73, 0xe0,
+ /* (2^323)P */ 0xcf, 0x9e, 0x66, 0x06, 0x4d, 0x2b, 0xf5, 0x9c, 0xc2, 0x9d, 0x9e, 0xed, 0x5a, 0x5c, 0x2d, 0x00, 0xbf, 0x29, 0x90, 0x88, 0xe4, 0x5d, 0xfd, 0xe2, 0xf0, 0x38, 0xec, 0x4d, 0x26, 0xea, 0x54, 0xf0, 0x3c, 0x84, 0x10, 0x6a, 0xf9, 0x66, 0x9c, 0xe7, 0x21, 0xfd, 0x0f, 0xc7, 0x13, 0x50, 0x81, 0xb6, 0x50, 0xf9, 0x04, 0x7f, 0xa4, 0x37, 0x85, 0x14,
+ /* (2^324)P */ 0xdb, 0x87, 0x49, 0xc7, 0xa8, 0x39, 0x0c, 0x32, 0x98, 0x0c, 0xb9, 0x1a, 0x1b, 0x4d, 0xe0, 0x8a, 0x9a, 0x8e, 0x8f, 0xab, 0x5a, 0x17, 0x3d, 0x04, 0x21, 0xce, 0x3e, 0x2c, 0xf9, 0xa3, 0x97, 0xe4, 0x77, 0x95, 0x0e, 0xb6, 0xa5, 0x15, 0xad, 0x3a, 0x1e, 0x46, 0x53, 0x17, 0x09, 0x83, 0x71, 0x4e, 0x86, 0x38, 0xd5, 0x23, 0x44, 0x16, 0x8d, 0xc8,
+ /* (2^325)P */ 0x05, 0x5e, 0x99, 0x08, 0xbb, 0xc3, 0xc0, 0xb7, 0x6c, 0x12, 0xf2, 0xf3, 0xf4, 0x7c, 0x6a, 0x4d, 0x9e, 0xeb, 0x3d, 0xb9, 0x63, 0x94, 0xce, 0x81, 0xd8, 0x11, 0xcb, 0x55, 0x69, 0x4a, 0x20, 0x0b, 0x4c, 0x2e, 0x14, 0xb8, 0xd4, 0x6a, 0x7c, 0xf0, 0xed, 0xfc, 0x8f, 0xef, 0xa0, 0xeb, 0x6c, 0x01, 0xe2, 0xdc, 0x10, 0x22, 0xa2, 0x01, 0x85, 0x64,
+ /* (2^326)P */ 0x58, 0xe1, 0x9c, 0x27, 0x55, 0xc6, 0x25, 0xa6, 0x7d, 0x67, 0x88, 0x65, 0x99, 0x6c, 0xcb, 0xdb, 0x27, 0x4f, 0x44, 0x29, 0xf5, 0x4a, 0x23, 0x10, 0xbc, 0x03, 0x3f, 0x36, 0x1e, 0xef, 0xb0, 0xba, 0x75, 0xe8, 0x74, 0x5f, 0x69, 0x3e, 0x26, 0x40, 0xb4, 0x2f, 0xdc, 0x43, 0xbf, 0xa1, 0x8b, 0xbd, 0xca, 0x6e, 0xc1, 0x6e, 0x21, 0x79, 0xa0, 0xd0,
+ /* (2^327)P */ 0x78, 0x93, 0x4a, 0x2d, 0x22, 0x6e, 0x6e, 0x7d, 0x74, 0xd2, 0x66, 0x58, 0xce, 0x7b, 0x1d, 0x97, 0xb1, 0xf2, 0xda, 0x1c, 0x79, 0xfb, 0xba, 0xd1, 0xc0, 0xc5, 0x6e, 0xc9, 0x11, 0x89, 0xd2, 0x41, 0x8d, 0x70, 0xb9, 0xcc, 0xea, 0x6a, 0xb3, 0x45, 0xb6, 0x05, 0x2e, 0xf2, 0x17, 0xf1, 0x27, 0xb8, 0xed, 0x06, 0x1f, 0xdb, 0x9d, 0x1f, 0x69, 0x28,
+ /* (2^328)P */ 0x93, 0x12, 0xa8, 0x11, 0xe1, 0x92, 0x30, 0x8d, 0xac, 0xe1, 0x1c, 0x60, 0x7c, 0xed, 0x2d, 0x2e, 0xd3, 0x03, 0x5c, 0x9c, 0xc5, 0xbd, 0x64, 0x4a, 0x8c, 0xba, 0x76, 0xfe, 0xc6, 0xc1, 0xea, 0xc2, 0x4f, 0xbe, 0x70, 0x3d, 0x64, 0xcf, 0x8e, 0x18, 0xcb, 0xcd, 0x57, 0xa7, 0xf7, 0x36, 0xa9, 0x6b, 0x3e, 0xb8, 0x69, 0xee, 0x47, 0xa2, 0x7e, 0xb2,
+ /* (2^329)P */ 0x96, 0xaf, 0x3a, 0xf5, 0xed, 0xcd, 0xaf, 0xf7, 0x82, 0xaf, 0x59, 0x62, 0x0b, 0x36, 0x85, 0xf9, 0xaf, 0xd6, 0x38, 0xff, 0x87, 0x2e, 0x1d, 0x6c, 0x8b, 0xaf, 0x3b, 0xdf, 0x28, 0xa2, 0xd6, 0x4d, 0x80, 0x92, 0xc3, 0x0f, 0x34, 0xa8, 0xae, 0x69, 0x5d, 0x7b, 0x9d, 0xbc, 0xf5, 0xfd, 0x1d, 0xb1, 0x96, 0x55, 0x86, 0xe1, 0x5c, 0xb6, 0xac, 0xb9,
+ /* (2^330)P */ 0x50, 0x9e, 0x37, 0x28, 0x7d, 0xa8, 0x33, 0x63, 0xda, 0x3f, 0x20, 0x98, 0x0e, 0x09, 0xa8, 0x77, 0x3b, 0x7a, 0xfc, 0x16, 0x85, 0x44, 0x64, 0x77, 0x65, 0x68, 0x92, 0x41, 0xc6, 0x1f, 0xdf, 0x27, 0xf9, 0xec, 0xa0, 0x61, 0x22, 0xea, 0x19, 0xe7, 0x75, 0x8b, 0x4e, 0xe5, 0x0f, 0xb7, 0xf7, 0xd2, 0x53, 0xf4, 0xdd, 0x4a, 0xaa, 0x78, 0x40, 0xb7,
+ /* (2^331)P */ 0xd4, 0x89, 0xe3, 0x79, 0xba, 0xb6, 0xc3, 0xda, 0xe6, 0x78, 0x65, 0x7d, 0x6e, 0x22, 0x62, 0xb1, 0x3d, 0xea, 0x90, 0x84, 0x30, 0x5e, 0xd4, 0x39, 0x84, 0x78, 0xd9, 0x75, 0xd6, 0xce, 0x2a, 0x11, 0x29, 0x69, 0xa4, 0x5e, 0xaa, 0x2a, 0x98, 0x5a, 0xe5, 0x91, 0x8f, 0xb2, 0xfb, 0xda, 0x97, 0xe8, 0x83, 0x6f, 0x04, 0xb9, 0x5d, 0xaf, 0xe1, 0x9b,
+ /* (2^332)P */ 0x8b, 0xe4, 0xe1, 0x48, 0x9c, 0xc4, 0x83, 0x89, 0xdf, 0x65, 0xd3, 0x35, 0x55, 0x13, 0xf4, 0x1f, 0x36, 0x92, 0x33, 0x38, 0xcb, 0xed, 0x15, 0xe6, 0x60, 0x2d, 0x25, 0xf5, 0x36, 0x60, 0x3a, 0x37, 0x9b, 0x71, 0x9d, 0x42, 0xb0, 0x14, 0xc8, 0xba, 0x62, 0xa3, 0x49, 0xb0, 0x88, 0xc1, 0x72, 0x73, 0xdd, 0x62, 0x40, 0xa9, 0x62, 0x88, 0x99, 0xca,
+ /* (2^333)P */ 0x47, 0x7b, 0xea, 0xda, 0x46, 0x2f, 0x45, 0xc6, 0xe3, 0xb4, 0x4d, 0x8d, 0xac, 0x0b, 0x54, 0x22, 0x06, 0x31, 0x16, 0x66, 0x3e, 0xe4, 0x38, 0x12, 0xcd, 0xf3, 0xe7, 0x99, 0x37, 0xd9, 0x62, 0x24, 0x4b, 0x05, 0xf2, 0x58, 0xe6, 0x29, 0x4b, 0x0d, 0xf6, 0xc1, 0xba, 0xa0, 0x1e, 0x0f, 0xcb, 0x1f, 0xc6, 0x2b, 0x19, 0xfc, 0x82, 0x01, 0xd0, 0x86,
+ /* (2^334)P */ 0xa2, 0xae, 0x77, 0x20, 0xfb, 0xa8, 0x18, 0xb4, 0x61, 0xef, 0xe8, 0x52, 0x79, 0xbb, 0x86, 0x90, 0x5d, 0x2e, 0x76, 0xed, 0x66, 0x60, 0x5d, 0x00, 0xb5, 0xa4, 0x00, 0x40, 0x89, 0xec, 0xd1, 0xd2, 0x0d, 0x26, 0xb9, 0x30, 0xb2, 0xd2, 0xb8, 0xe8, 0x0e, 0x56, 0xf9, 0x67, 0x94, 0x2e, 0x62, 0xe1, 0x79, 0x48, 0x2b, 0xa9, 0xfa, 0xea, 0xdb, 0x28,
+ /* (2^335)P */ 0x35, 0xf1, 0xb0, 0x43, 0xbd, 0x27, 0xef, 0x18, 0x44, 0xa2, 0x04, 0xb4, 0x69, 0xa1, 0x97, 0x1f, 0x8c, 0x04, 0x82, 0x9b, 0x00, 0x6d, 0xf8, 0xbf, 0x7d, 0xc1, 0x5b, 0xab, 0xe8, 0xb2, 0x34, 0xbd, 0xaf, 0x7f, 0xb2, 0x0d, 0xf3, 0xed, 0xfc, 0x5b, 0x50, 0xee, 0xe7, 0x4a, 0x20, 0xd9, 0xf5, 0xc6, 0x9a, 0x97, 0x6d, 0x07, 0x2f, 0xb9, 0x31, 0x02,
+ /* (2^336)P */ 0xf9, 0x54, 0x4a, 0xc5, 0x61, 0x7e, 0x1d, 0xa6, 0x0e, 0x1a, 0xa8, 0xd3, 0x8c, 0x36, 0x7d, 0xf1, 0x06, 0xb1, 0xac, 0x93, 0xcd, 0xe9, 0x8f, 0x61, 0x6c, 0x5d, 0x03, 0x23, 0xdf, 0x85, 0x53, 0x39, 0x63, 0x5e, 0xeb, 0xf3, 0xd3, 0xd3, 0x75, 0x97, 0x9b, 0x62, 0x9b, 0x01, 0xb3, 0x19, 0xd8, 0x2b, 0x36, 0xf2, 0x2c, 0x2c, 0x6f, 0x36, 0xc6, 0x3c,
+ /* (2^337)P */ 0x05, 0x74, 0x43, 0x10, 0xb6, 0xb0, 0xf8, 0xbf, 0x02, 0x46, 0x9a, 0xee, 0xc1, 0xaf, 0xc1, 0xe5, 0x5a, 0x2e, 0xbb, 0xe1, 0xdc, 0xc6, 0xce, 0x51, 0x29, 0x50, 0xbf, 0x1b, 0xde, 0xff, 0xba, 0x4d, 0x8d, 0x8b, 0x7e, 0xe7, 0xbd, 0x5b, 0x8f, 0xbe, 0xe3, 0x75, 0x71, 0xff, 0x37, 0x05, 0x5a, 0x10, 0xeb, 0x54, 0x7e, 0x44, 0x72, 0x2c, 0xd4, 0xfc,
+ /* (2^338)P */ 0x03, 0x12, 0x1c, 0xb2, 0x08, 0x90, 0xa1, 0x2d, 0x50, 0xa0, 0xad, 0x7f, 0x8d, 0xa6, 0x97, 0xc1, 0xbd, 0xdc, 0xc3, 0xa7, 0xad, 0x31, 0xdf, 0xb8, 0x03, 0x84, 0xc3, 0xb9, 0x29, 0x3d, 0x92, 0x2e, 0xc3, 0x90, 0x07, 0xe8, 0xa7, 0xc7, 0xbc, 0x61, 0xe9, 0x3e, 0xa0, 0x35, 0xda, 0x1d, 0xab, 0x48, 0xfe, 0x50, 0xc9, 0x25, 0x59, 0x23, 0x69, 0x3f,
+ /* (2^339)P */ 0x8e, 0x91, 0xab, 0x6b, 0x91, 0x4f, 0x89, 0x76, 0x67, 0xad, 0xb2, 0x65, 0x9d, 0xad, 0x02, 0x36, 0xdc, 0xac, 0x96, 0x93, 0x97, 0x21, 0x14, 0xd0, 0xe8, 0x11, 0x60, 0x1e, 0xeb, 0x96, 0x06, 0xf2, 0x53, 0xf2, 0x6d, 0xb7, 0x93, 0x6f, 0x26, 0x91, 0x23, 0xe3, 0x34, 0x04, 0x92, 0x91, 0x37, 0x08, 0x50, 0xd6, 0x28, 0x09, 0x27, 0xa1, 0x0c, 0x00,
+ /* (2^340)P */ 0x1f, 0xbb, 0x21, 0x26, 0x33, 0xcb, 0xa4, 0xd1, 0xee, 0x85, 0xf9, 0xd9, 0x3c, 0x90, 0xc3, 0xd1, 0x26, 0xa2, 0x25, 0x93, 0x43, 0x61, 0xed, 0x91, 0x6e, 0x54, 0x03, 0x2e, 0x42, 0x9d, 0xf7, 0xa6, 0x02, 0x0f, 0x2f, 0x9c, 0x7a, 0x8d, 0x12, 0xc2, 0x18, 0xfc, 0x41, 0xff, 0x85, 0x26, 0x1a, 0x44, 0x55, 0x0b, 0x89, 0xab, 0x6f, 0x62, 0x33, 0x8c,
+ /* (2^341)P */ 0xe0, 0x3c, 0x5d, 0x70, 0x64, 0x87, 0x81, 0x35, 0xf2, 0x37, 0xa6, 0x24, 0x3e, 0xe0, 0x62, 0xd5, 0x71, 0xe7, 0x93, 0xfb, 0xac, 0xc3, 0xe7, 0xc7, 0x04, 0xe2, 0x70, 0xd3, 0x29, 0x5b, 0x21, 0xbf, 0xf4, 0x26, 0x5d, 0xf3, 0x95, 0xb4, 0x2a, 0x6a, 0x07, 0x55, 0xa6, 0x4b, 0x3b, 0x15, 0xf2, 0x25, 0x8a, 0x95, 0x3f, 0x63, 0x2f, 0x7a, 0x23, 0x96,
+ /* (2^342)P */ 0x0d, 0x3d, 0xd9, 0x13, 0xa7, 0xb3, 0x5e, 0x67, 0xf7, 0x02, 0x23, 0xee, 0x84, 0xff, 0x99, 0xda, 0xb9, 0x53, 0xf8, 0xf0, 0x0e, 0x39, 0x2f, 0x3c, 0x64, 0x34, 0xe3, 0x09, 0xfd, 0x2b, 0x33, 0xc7, 0xfe, 0x62, 0x2b, 0x84, 0xdf, 0x2b, 0xd2, 0x7c, 0x26, 0x01, 0x70, 0x66, 0x5b, 0x85, 0xc2, 0xbe, 0x88, 0x37, 0xf1, 0x30, 0xac, 0xb8, 0x76, 0xa3,
+ /* (2^343)P */ 0x6e, 0x01, 0xf0, 0x55, 0x35, 0xe4, 0xbd, 0x43, 0x62, 0x9d, 0xd6, 0x11, 0xef, 0x6f, 0xb8, 0x8c, 0xaa, 0x98, 0x87, 0xc6, 0x6d, 0xc4, 0xcc, 0x74, 0x92, 0x53, 0x4a, 0xdf, 0xe4, 0x08, 0x89, 0x17, 0xd0, 0x0f, 0xf4, 0x00, 0x60, 0x78, 0x08, 0x44, 0xb5, 0xda, 0x18, 0xed, 0x98, 0xc8, 0x61, 0x3d, 0x39, 0xdb, 0xcf, 0x1d, 0x49, 0x40, 0x65, 0x75,
+ /* (2^344)P */ 0x8e, 0x10, 0xae, 0x5f, 0x06, 0xd2, 0x95, 0xfd, 0x20, 0x16, 0x49, 0x5b, 0x57, 0xbe, 0x22, 0x8b, 0x43, 0xfb, 0xe6, 0xcc, 0x26, 0xa5, 0x5d, 0xd3, 0x68, 0xc5, 0xf9, 0x5a, 0x86, 0x24, 0x87, 0x27, 0x05, 0xfd, 0xe2, 0xff, 0xb3, 0xa3, 0x7b, 0x37, 0x59, 0xc5, 0x4e, 0x14, 0x94, 0xf9, 0x3b, 0xcb, 0x7c, 0xed, 0xca, 0x1d, 0xb2, 0xac, 0x05, 0x4a,
+ /* (2^345)P */ 0xf4, 0xd1, 0x81, 0xeb, 0x89, 0xbf, 0xfe, 0x1e, 0x41, 0x92, 0x29, 0xee, 0xe1, 0x43, 0xf5, 0x86, 0x1d, 0x2f, 0xbb, 0x1e, 0x84, 0x5d, 0x7b, 0x8d, 0xd5, 0xda, 0xee, 0x1e, 0x8a, 0xd0, 0x27, 0xf2, 0x60, 0x51, 0x59, 0x82, 0xf4, 0x84, 0x2b, 0x5b, 0x14, 0x2d, 0x81, 0x82, 0x3e, 0x2b, 0xb4, 0x6d, 0x51, 0x4f, 0xc5, 0xcb, 0xbf, 0x74, 0xe3, 0xb4,
+ /* (2^346)P */ 0x19, 0x2f, 0x22, 0xb3, 0x04, 0x5f, 0x81, 0xca, 0x05, 0x60, 0xb9, 0xaa, 0xee, 0x0e, 0x2f, 0x48, 0x38, 0xf9, 0x91, 0xb4, 0x66, 0xe4, 0x57, 0x28, 0x54, 0x10, 0xe9, 0x61, 0x9d, 0xd4, 0x90, 0x75, 0xb1, 0x39, 0x23, 0xb6, 0xfc, 0x82, 0xe0, 0xfa, 0xbb, 0x5c, 0x6e, 0xc3, 0x44, 0x13, 0x00, 0x83, 0x55, 0x9e, 0x8e, 0x10, 0x61, 0x81, 0x91, 0x04,
+ /* (2^347)P */ 0x5f, 0x2a, 0xd7, 0x81, 0xd9, 0x9c, 0xbb, 0x79, 0xbc, 0x62, 0x56, 0x98, 0x03, 0x5a, 0x18, 0x85, 0x2a, 0x9c, 0xd0, 0xfb, 0xd2, 0xb1, 0xaf, 0xef, 0x0d, 0x24, 0xc5, 0xfa, 0x39, 0xbb, 0x6b, 0xed, 0xa4, 0xdf, 0xe4, 0x87, 0xcd, 0x41, 0xd3, 0x72, 0x32, 0xc6, 0x28, 0x21, 0xb1, 0xba, 0x8b, 0xa3, 0x91, 0x79, 0x76, 0x22, 0x25, 0x10, 0x61, 0xd1,
+ /* (2^348)P */ 0x73, 0xb5, 0x32, 0x97, 0xdd, 0xeb, 0xdd, 0x22, 0x22, 0xf1, 0x33, 0x3c, 0x77, 0x56, 0x7d, 0x6b, 0x48, 0x2b, 0x05, 0x81, 0x03, 0x03, 0x91, 0x9a, 0xe3, 0x5e, 0xd4, 0xee, 0x3f, 0xf8, 0xbb, 0x50, 0x21, 0x32, 0x4c, 0x4a, 0x58, 0x49, 0xde, 0x0c, 0xde, 0x30, 0x82, 0x3d, 0x92, 0xf0, 0x6c, 0xcc, 0x32, 0x3e, 0xd2, 0x78, 0x8a, 0x6e, 0x2c, 0xd0,
+ /* (2^349)P */ 0xf0, 0xf7, 0xa1, 0x0b, 0xc1, 0x74, 0x85, 0xa8, 0xe9, 0xdd, 0x48, 0xa1, 0xc0, 0x16, 0xd8, 0x2b, 0x61, 0x08, 0xc2, 0x2b, 0x30, 0x26, 0x79, 0xce, 0x9e, 0xfd, 0x39, 0xd7, 0x81, 0xa4, 0x63, 0x8c, 0xd5, 0x74, 0xa0, 0x88, 0xfa, 0x03, 0x30, 0xe9, 0x7f, 0x2b, 0xc6, 0x02, 0xc9, 0x5e, 0xe4, 0xd5, 0x4d, 0x92, 0xd0, 0xf6, 0xf2, 0x5b, 0x79, 0x08,
+ /* (2^350)P */ 0x34, 0x89, 0x81, 0x43, 0xd1, 0x94, 0x2c, 0x10, 0x54, 0x9b, 0xa0, 0xe5, 0x44, 0xe8, 0xc2, 0x2f, 0x3e, 0x0e, 0x74, 0xae, 0xba, 0xe2, 0xac, 0x85, 0x6b, 0xd3, 0x5c, 0x97, 0xf7, 0x90, 0xf1, 0x12, 0xc0, 0x03, 0xc8, 0x1f, 0x37, 0x72, 0x8c, 0x9b, 0x9c, 0x17, 0x96, 0x9d, 0xc7, 0xbf, 0xa3, 0x3f, 0x44, 0x3d, 0x87, 0x81, 0xbd, 0x81, 0xa6, 0x5f,
+ /* (2^351)P */ 0xe4, 0xff, 0x78, 0x62, 0x82, 0x5b, 0x76, 0x58, 0xf5, 0x5b, 0xa6, 0xc4, 0x53, 0x11, 0x3b, 0x7b, 0xaa, 0x67, 0xf8, 0xea, 0x3b, 0x5d, 0x9a, 0x2e, 0x04, 0xeb, 0x4a, 0x24, 0xfb, 0x56, 0xf0, 0xa8, 0xd4, 0x14, 0xed, 0x0f, 0xfd, 0xc5, 0x26, 0x17, 0x2a, 0xf0, 0xb9, 0x13, 0x8c, 0xbd, 0x65, 0x14, 0x24, 0x95, 0x27, 0x12, 0x63, 0x2a, 0x09, 0x18,
+ /* (2^352)P */ 0xe1, 0x5c, 0xe7, 0xe0, 0x00, 0x6a, 0x96, 0xf2, 0x49, 0x6a, 0x39, 0xa5, 0xe0, 0x17, 0x79, 0x4a, 0x63, 0x07, 0x62, 0x09, 0x61, 0x1b, 0x6e, 0xa9, 0xb5, 0x62, 0xb7, 0xde, 0xdf, 0x80, 0x4c, 0x5a, 0x99, 0x73, 0x59, 0x9d, 0xfb, 0xb1, 0x5e, 0xbe, 0xb8, 0xb7, 0x63, 0x93, 0xe8, 0xad, 0x5e, 0x1f, 0xae, 0x59, 0x1c, 0xcd, 0xb4, 0xc2, 0xb3, 0x8a,
+ /* (2^353)P */ 0x78, 0x53, 0xa1, 0x4c, 0x70, 0x9c, 0x63, 0x7e, 0xb3, 0x12, 0x40, 0x5f, 0xbb, 0x23, 0xa7, 0xf7, 0x77, 0x96, 0x5b, 0x4d, 0x91, 0x10, 0x52, 0x85, 0x9e, 0xa5, 0x38, 0x0b, 0xfd, 0x25, 0x01, 0x4b, 0xfa, 0x4d, 0xd3, 0x3f, 0x78, 0x74, 0x42, 0xff, 0x62, 0x2d, 0x27, 0xdc, 0x9d, 0xd1, 0x29, 0x76, 0x2e, 0x78, 0xb3, 0x35, 0xfa, 0x15, 0xd5, 0x38,
+ /* (2^354)P */ 0x8b, 0xc7, 0x43, 0xce, 0xf0, 0x5e, 0xf1, 0x0d, 0x02, 0x38, 0xe8, 0x82, 0xc9, 0x25, 0xad, 0x2d, 0x27, 0xa4, 0x54, 0x18, 0xb2, 0x30, 0x73, 0xa4, 0x41, 0x08, 0xe4, 0x86, 0xe6, 0x8c, 0xe9, 0x2a, 0x34, 0xb3, 0xd6, 0x61, 0x8f, 0x66, 0x26, 0x08, 0xb6, 0x06, 0x33, 0xaa, 0x12, 0xac, 0x72, 0xec, 0x2e, 0x52, 0xa3, 0x25, 0x3e, 0xd7, 0x62, 0xe8,
+ /* (2^355)P */ 0xc4, 0xbb, 0x89, 0xc8, 0x40, 0xcc, 0x84, 0xec, 0x4a, 0xd9, 0xc4, 0x55, 0x78, 0x00, 0xcf, 0xd8, 0xe9, 0x24, 0x59, 0xdc, 0x5e, 0xf0, 0x66, 0xa1, 0x83, 0xae, 0x97, 0x18, 0xc5, 0x54, 0x27, 0xa2, 0x21, 0x52, 0x03, 0x31, 0x5b, 0x11, 0x67, 0xf6, 0x12, 0x00, 0x87, 0x2f, 0xff, 0x59, 0x70, 0x8f, 0x6d, 0x71, 0xab, 0xab, 0x24, 0xb8, 0xba, 0x35,
+ /* (2^356)P */ 0x69, 0x43, 0xa7, 0x14, 0x06, 0x96, 0xe9, 0xc2, 0xe3, 0x2b, 0x45, 0x22, 0xc0, 0xd0, 0x2f, 0x34, 0xd1, 0x01, 0x99, 0xfc, 0x99, 0x38, 0xa1, 0x25, 0x2e, 0x59, 0x6c, 0x27, 0xc9, 0xeb, 0x7b, 0xdc, 0x4e, 0x26, 0x68, 0xba, 0xfa, 0xec, 0x02, 0x05, 0x64, 0x80, 0x30, 0x20, 0x5c, 0x26, 0x7f, 0xaf, 0x95, 0x17, 0x3d, 0x5c, 0x9e, 0x96, 0x96, 0xaf,
+ /* (2^357)P */ 0xa6, 0xba, 0x21, 0x29, 0x32, 0xe2, 0x98, 0xde, 0x9b, 0x6d, 0x0b, 0x44, 0x91, 0xa8, 0x3e, 0xd4, 0xb8, 0x04, 0x6c, 0xf6, 0x04, 0x39, 0xbd, 0x52, 0x05, 0x15, 0x27, 0x78, 0x8e, 0x55, 0xac, 0x79, 0xc5, 0xe6, 0x00, 0x7f, 0x90, 0xa2, 0xdd, 0x07, 0x13, 0xe0, 0x24, 0x70, 0x5c, 0x0f, 0x4d, 0xa9, 0xf9, 0xae, 0xcb, 0x34, 0x10, 0x9d, 0x89, 0x9d,
+ /* (2^358)P */ 0x12, 0xe0, 0xb3, 0x9f, 0xc4, 0x96, 0x1d, 0xcf, 0xed, 0x99, 0x64, 0x28, 0x8d, 0xc7, 0x31, 0x82, 0xee, 0x5e, 0x75, 0x48, 0xff, 0x3a, 0xf2, 0x09, 0x34, 0x03, 0x93, 0x52, 0x19, 0xb2, 0xc5, 0x81, 0x93, 0x45, 0x5e, 0x59, 0x21, 0x2b, 0xec, 0x89, 0xba, 0x36, 0x6e, 0xf9, 0x82, 0x75, 0x7e, 0x82, 0x3f, 0xaa, 0xe2, 0xe3, 0x3b, 0x94, 0xfd, 0x98,
+ /* (2^359)P */ 0x7c, 0xdb, 0x75, 0x31, 0x61, 0xfb, 0x15, 0x28, 0x94, 0xd7, 0xc3, 0x5a, 0xa9, 0xa1, 0x0a, 0x66, 0x0f, 0x2b, 0x13, 0x3e, 0x42, 0xb5, 0x28, 0x3a, 0xca, 0x83, 0xf3, 0x61, 0x22, 0xf4, 0x40, 0xc5, 0xdf, 0xe7, 0x31, 0x9f, 0x7e, 0x51, 0x75, 0x06, 0x9d, 0x51, 0xc8, 0xe7, 0x9f, 0xc3, 0x71, 0x4f, 0x3d, 0x5b, 0xfb, 0xe9, 0x8e, 0x08, 0x40, 0x8e,
+ /* (2^360)P */ 0xf7, 0x31, 0xad, 0x50, 0x5d, 0x25, 0x93, 0x73, 0x68, 0xf6, 0x7c, 0x89, 0x5a, 0x3d, 0x9f, 0x9b, 0x05, 0x82, 0xe7, 0x70, 0x4b, 0x19, 0xaa, 0xcf, 0xff, 0xde, 0x50, 0x8f, 0x2f, 0x69, 0xd3, 0xf0, 0x99, 0x51, 0x6b, 0x9d, 0xb6, 0x56, 0x6f, 0xf8, 0x4c, 0x74, 0x8b, 0x4c, 0x91, 0xf9, 0xa9, 0xb1, 0x3e, 0x07, 0xdf, 0x0b, 0x27, 0x8a, 0xb1, 0xed,
+ /* (2^361)P */ 0xfb, 0x67, 0xd9, 0x48, 0xd2, 0xe4, 0x44, 0x9b, 0x43, 0x15, 0x8a, 0xeb, 0x00, 0x53, 0xad, 0x25, 0xc7, 0x7e, 0x19, 0x30, 0x87, 0xb7, 0xd5, 0x5f, 0x04, 0xf8, 0xaa, 0xdd, 0x57, 0xae, 0x34, 0x75, 0xe2, 0x84, 0x4b, 0x54, 0x60, 0x37, 0x95, 0xe4, 0xd3, 0xec, 0xac, 0xef, 0x47, 0x31, 0xa3, 0xc8, 0x31, 0x22, 0xdb, 0x26, 0xe7, 0x6a, 0xb5, 0xad,
+ /* (2^362)P */ 0x44, 0x09, 0x5c, 0x95, 0xe4, 0x72, 0x3c, 0x1a, 0xd1, 0xac, 0x42, 0x51, 0x99, 0x6f, 0xfa, 0x1f, 0xf2, 0x22, 0xbe, 0xff, 0x7b, 0x66, 0xf5, 0x6c, 0xb3, 0x66, 0xc7, 0x4d, 0x78, 0x31, 0x83, 0x80, 0xf5, 0x41, 0xe9, 0x7f, 0xbe, 0xf7, 0x23, 0x49, 0x6b, 0x84, 0x4e, 0x7e, 0x47, 0x07, 0x6e, 0x74, 0xdf, 0xe5, 0x9d, 0x9e, 0x56, 0x2a, 0xc0, 0xbc,
+ /* (2^363)P */ 0xac, 0x10, 0x80, 0x8c, 0x7c, 0xfa, 0x83, 0xdf, 0xb3, 0xd0, 0xc4, 0xbe, 0xfb, 0x9f, 0xac, 0xc9, 0xc3, 0x40, 0x95, 0x0b, 0x09, 0x23, 0xda, 0x63, 0x67, 0xcf, 0xe7, 0x9f, 0x7d, 0x7b, 0x6b, 0xe2, 0xe6, 0x6d, 0xdb, 0x87, 0x9e, 0xa6, 0xff, 0x6d, 0xab, 0xbd, 0xfb, 0x54, 0x84, 0x68, 0xcf, 0x89, 0xf1, 0xd0, 0xe2, 0x85, 0x61, 0xdc, 0x22, 0xd1,
+ /* (2^364)P */ 0xa8, 0x48, 0xfb, 0x8c, 0x6a, 0x63, 0x01, 0x72, 0x43, 0x43, 0xeb, 0x21, 0xa3, 0x00, 0x8a, 0xc0, 0x87, 0x51, 0x9e, 0x86, 0x75, 0x16, 0x79, 0xf9, 0x6b, 0x11, 0x80, 0x62, 0xc2, 0x9d, 0xb8, 0x8c, 0x30, 0x8e, 0x8d, 0x03, 0x52, 0x7e, 0x31, 0x59, 0x38, 0xf9, 0x25, 0xc7, 0x0f, 0xc7, 0xa8, 0x2b, 0x5c, 0x80, 0xfa, 0x90, 0xa2, 0x63, 0xca, 0xe7,
+ /* (2^365)P */ 0xf1, 0x5d, 0xb5, 0xd9, 0x20, 0x10, 0x7d, 0x0f, 0xc5, 0x50, 0x46, 0x07, 0xff, 0x02, 0x75, 0x2b, 0x4a, 0xf3, 0x39, 0x91, 0x72, 0xb7, 0xd5, 0xcc, 0x38, 0xb8, 0xe7, 0x36, 0x26, 0x5e, 0x11, 0x97, 0x25, 0xfb, 0x49, 0x68, 0xdc, 0xb4, 0x46, 0x87, 0x5c, 0xc2, 0x7f, 0xaa, 0x7d, 0x36, 0x23, 0xa6, 0xc6, 0x53, 0xec, 0xbc, 0x57, 0x47, 0xc1, 0x2b,
+ /* (2^366)P */ 0x25, 0x5d, 0x7d, 0x95, 0xda, 0x0b, 0x8f, 0x78, 0x1e, 0x19, 0x09, 0xfa, 0x67, 0xe0, 0xa0, 0x17, 0x24, 0x76, 0x6c, 0x30, 0x1f, 0x62, 0x3d, 0xbe, 0x45, 0x70, 0xcc, 0xb6, 0x1e, 0x68, 0x06, 0x25, 0x68, 0x16, 0x1a, 0x33, 0x3f, 0x90, 0xc7, 0x78, 0x2d, 0x98, 0x3c, 0x2f, 0xb9, 0x2d, 0x94, 0x0b, 0xfb, 0x49, 0x56, 0x30, 0xd7, 0xc1, 0xe6, 0x48,
+ /* (2^367)P */ 0x7a, 0xd1, 0xe0, 0x8e, 0x67, 0xfc, 0x0b, 0x50, 0x1f, 0x84, 0x98, 0xfa, 0xaf, 0xae, 0x2e, 0x31, 0x27, 0xcf, 0x3f, 0xf2, 0x6e, 0x8d, 0x81, 0x8f, 0xd2, 0x5f, 0xde, 0xd3, 0x5e, 0xe9, 0xe7, 0x13, 0x48, 0x83, 0x5a, 0x4e, 0x84, 0xd1, 0x58, 0xcf, 0x6b, 0x84, 0xdf, 0x13, 0x1d, 0x91, 0x85, 0xe8, 0xcb, 0x29, 0x79, 0xd2, 0xca, 0xac, 0x6a, 0x93,
+ /* (2^368)P */ 0x53, 0x82, 0xce, 0x61, 0x96, 0x88, 0x6f, 0xe1, 0x4a, 0x4c, 0x1e, 0x30, 0x73, 0xe8, 0x74, 0xde, 0x40, 0x2b, 0xe0, 0xc4, 0xb5, 0xd8, 0x7c, 0x15, 0xe7, 0xe1, 0xb1, 0xe0, 0xd6, 0x88, 0xb1, 0x6a, 0x57, 0x19, 0x6a, 0x22, 0x66, 0x57, 0xf6, 0x8d, 0xfd, 0xc0, 0xf2, 0xa3, 0x03, 0x56, 0xfb, 0x2e, 0x75, 0x5e, 0xc7, 0x8e, 0x22, 0x96, 0x5c, 0x06,
+ /* (2^369)P */ 0x98, 0x7e, 0xbf, 0x3e, 0xbf, 0x24, 0x9d, 0x15, 0xd3, 0xf6, 0xd3, 0xd2, 0xf0, 0x11, 0xf2, 0xdb, 0x36, 0x23, 0x38, 0xf7, 0x1d, 0x71, 0x20, 0xd2, 0x54, 0x7f, 0x1e, 0x24, 0x8f, 0xe2, 0xaa, 0xf7, 0x3f, 0x6b, 0x41, 0x4e, 0xdc, 0x0e, 0xec, 0xe8, 0x35, 0x0a, 0x08, 0x6d, 0x89, 0x5b, 0x32, 0x91, 0x01, 0xb6, 0xe0, 0x2c, 0xc6, 0xa1, 0xbe, 0xb4,
+ /* (2^370)P */ 0x29, 0xf2, 0x1e, 0x1c, 0xdc, 0x68, 0x8a, 0x43, 0x87, 0x2c, 0x48, 0xb3, 0x9e, 0xed, 0xd2, 0x82, 0x46, 0xac, 0x2f, 0xef, 0x93, 0x34, 0x37, 0xca, 0x64, 0x8d, 0xc9, 0x06, 0x90, 0xbb, 0x78, 0x0a, 0x3c, 0x4c, 0xcf, 0x35, 0x7a, 0x0f, 0xf7, 0xa7, 0xf4, 0x2f, 0x45, 0x69, 0x3f, 0xa9, 0x5d, 0xce, 0x7b, 0x8a, 0x84, 0xc3, 0xae, 0xf4, 0xda, 0xd5,
+ /* (2^371)P */ 0xca, 0xba, 0x95, 0x43, 0x05, 0x7b, 0x06, 0xd9, 0x5c, 0x0a, 0x18, 0x5f, 0x6a, 0x6a, 0xce, 0xc0, 0x3d, 0x95, 0x51, 0x0e, 0x1a, 0xbe, 0x85, 0x7a, 0xf2, 0x69, 0xec, 0xc0, 0x8c, 0xca, 0xa3, 0x32, 0x0a, 0x76, 0x50, 0xc6, 0x76, 0x61, 0x00, 0x89, 0xbf, 0x6e, 0x0f, 0x48, 0x90, 0x31, 0x93, 0xec, 0x34, 0x70, 0xf0, 0xc3, 0x8d, 0xf0, 0x0f, 0xb5,
+ /* (2^372)P */ 0xbe, 0x23, 0xe2, 0x18, 0x99, 0xf1, 0xed, 0x8a, 0xf6, 0xc9, 0xac, 0xb8, 0x1e, 0x9a, 0x3c, 0x15, 0xae, 0xd7, 0x6d, 0xb3, 0x04, 0xee, 0x5b, 0x0d, 0x1e, 0x79, 0xb7, 0xf9, 0xf9, 0x8d, 0xad, 0xf9, 0x8f, 0x5a, 0x6a, 0x7b, 0xd7, 0x9b, 0xca, 0x62, 0xfe, 0x9c, 0xc0, 0x6f, 0x6d, 0x9d, 0x76, 0xa3, 0x69, 0xb9, 0x4c, 0xa1, 0xc4, 0x0c, 0x76, 0xaa,
+ /* (2^373)P */ 0x1c, 0x06, 0xfe, 0x3f, 0x45, 0x70, 0xcd, 0x97, 0xa9, 0xa2, 0xb1, 0xd3, 0xf2, 0xa5, 0x0c, 0x49, 0x2c, 0x75, 0x73, 0x1f, 0xcf, 0x00, 0xaf, 0xd5, 0x2e, 0xde, 0x0d, 0x8f, 0x8f, 0x7c, 0xc4, 0x58, 0xce, 0xd4, 0xf6, 0x24, 0x19, 0x2e, 0xd8, 0xc5, 0x1d, 0x1a, 0x3f, 0xb8, 0x4f, 0xbc, 0x7d, 0xbd, 0x68, 0xe3, 0x81, 0x98, 0x1b, 0xa8, 0xc9, 0xd9,
+ /* (2^374)P */ 0x39, 0x95, 0x78, 0x24, 0x6c, 0x38, 0xe4, 0xe7, 0xd0, 0x8d, 0xb9, 0x38, 0x71, 0x5e, 0xc1, 0x62, 0x80, 0xcc, 0xcb, 0x8c, 0x97, 0xca, 0xf8, 0xb9, 0xd9, 0x9c, 0xce, 0x72, 0x7b, 0x70, 0xee, 0x5f, 0xea, 0xa2, 0xdf, 0xa9, 0x14, 0x10, 0xf9, 0x6e, 0x59, 0x9f, 0x9c, 0xe0, 0x0c, 0xb2, 0x07, 0x97, 0xcd, 0xd2, 0x89, 0x16, 0xfd, 0x9c, 0xa8, 0xa5,
+ /* (2^375)P */ 0x5a, 0x61, 0xf1, 0x59, 0x7c, 0x38, 0xda, 0xe2, 0x85, 0x99, 0x68, 0xe9, 0xc9, 0xf7, 0x32, 0x7e, 0xc4, 0xca, 0xb7, 0x11, 0x08, 0x69, 0x2b, 0x66, 0x02, 0xf7, 0x2e, 0x18, 0xc3, 0x8e, 0xe1, 0xf9, 0xc5, 0x19, 0x9a, 0x0a, 0x9c, 0x07, 0xba, 0xc7, 0x9c, 0x03, 0x34, 0x89, 0x99, 0x67, 0x0b, 0x16, 0x4b, 0x07, 0x36, 0x16, 0x36, 0x2c, 0xe2, 0xa1,
+ /* (2^376)P */ 0x70, 0x10, 0x91, 0x27, 0xa8, 0x24, 0x8e, 0x29, 0x04, 0x6f, 0x79, 0x1f, 0xd3, 0xa5, 0x68, 0xd3, 0x0b, 0x7d, 0x56, 0x4d, 0x14, 0x57, 0x7b, 0x2e, 0x00, 0x9f, 0x9a, 0xfd, 0x6c, 0x63, 0x18, 0x81, 0xdb, 0x9d, 0xb7, 0xd7, 0xa4, 0x1e, 0xe8, 0x40, 0xf1, 0x4c, 0xa3, 0x01, 0xd5, 0x4b, 0x75, 0xea, 0xdd, 0x97, 0xfd, 0x5b, 0xb2, 0x66, 0x6a, 0x24,
+ /* (2^377)P */ 0x72, 0x11, 0xfe, 0x73, 0x1b, 0xd3, 0xea, 0x7f, 0x93, 0x15, 0x15, 0x05, 0xfe, 0x40, 0xe8, 0x28, 0xd8, 0x50, 0x47, 0x66, 0xfa, 0xb7, 0xb5, 0x04, 0xba, 0x35, 0x1e, 0x32, 0x9f, 0x5f, 0x32, 0xba, 0x3d, 0xd1, 0xed, 0x9a, 0x76, 0xca, 0xa3, 0x3e, 0x77, 0xd8, 0xd8, 0x7c, 0x5f, 0x68, 0x42, 0xb5, 0x86, 0x7f, 0x3b, 0xc9, 0xc1, 0x89, 0x64, 0xda,
+ /* (2^378)P */ 0xd5, 0xd4, 0x17, 0x31, 0xfc, 0x6a, 0xfd, 0xb8, 0xe8, 0xe5, 0x3e, 0x39, 0x06, 0xe4, 0xd1, 0x90, 0x2a, 0xca, 0xf6, 0x54, 0x6c, 0x1b, 0x2f, 0x49, 0x97, 0xb1, 0x2a, 0x82, 0x43, 0x3d, 0x1f, 0x8b, 0xe2, 0x47, 0xc5, 0x24, 0xa8, 0xd5, 0x53, 0x29, 0x7d, 0xc6, 0x87, 0xa6, 0x25, 0x3a, 0x64, 0xdd, 0x71, 0x08, 0x9e, 0xcd, 0xe9, 0x45, 0xc7, 0xba,
+ /* (2^379)P */ 0x37, 0x72, 0x6d, 0x13, 0x7a, 0x8d, 0x04, 0x31, 0xe6, 0xe3, 0x9e, 0x36, 0x71, 0x3e, 0xc0, 0x1e, 0xe3, 0x71, 0xd3, 0x49, 0x4e, 0x4a, 0x36, 0x42, 0x68, 0x68, 0x61, 0xc7, 0x3c, 0xdb, 0x81, 0x49, 0xf7, 0x91, 0x4d, 0xea, 0x4c, 0x4f, 0x98, 0xc6, 0x7e, 0x60, 0x84, 0x4b, 0x6a, 0x37, 0xbb, 0x52, 0xf7, 0xce, 0x02, 0xe4, 0xad, 0xd1, 0x3c, 0xa7,
+ /* (2^380)P */ 0x51, 0x06, 0x2d, 0xf8, 0x08, 0xe8, 0xf1, 0x0c, 0xe5, 0xa9, 0xac, 0x29, 0x73, 0x3b, 0xed, 0x98, 0x5f, 0x55, 0x08, 0x38, 0x51, 0x44, 0x36, 0x5d, 0xea, 0xc3, 0xb8, 0x0e, 0xa0, 0x4f, 0xd2, 0x79, 0xe9, 0x98, 0xc3, 0xf5, 0x00, 0xb9, 0x26, 0x27, 0x42, 0xa8, 0x07, 0xc1, 0x12, 0x31, 0xc1, 0xc3, 0x3c, 0x3b, 0x7a, 0x72, 0x97, 0xc2, 0x70, 0x3a,
+ /* (2^381)P */ 0xf4, 0xb2, 0xba, 0x32, 0xbc, 0xa9, 0x2f, 0x87, 0xc7, 0x3c, 0x45, 0xcd, 0xae, 0xe2, 0x13, 0x6d, 0x3a, 0xf2, 0xf5, 0x66, 0x97, 0x29, 0xaf, 0x53, 0x9f, 0xda, 0xea, 0x14, 0xdf, 0x04, 0x98, 0x19, 0x95, 0x9e, 0x2a, 0x00, 0x5c, 0x9d, 0x1d, 0xf0, 0x39, 0x23, 0xff, 0xfc, 0xca, 0x36, 0xb7, 0xde, 0xdf, 0x37, 0x78, 0x52, 0x21, 0xfa, 0x19, 0x10,
+ /* (2^382)P */ 0x50, 0x20, 0x73, 0x74, 0x62, 0x21, 0xf2, 0xf7, 0x9b, 0x66, 0x85, 0x34, 0x74, 0xd4, 0x9d, 0x60, 0xd7, 0xbc, 0xc8, 0x46, 0x3b, 0xb8, 0x80, 0x42, 0x15, 0x0a, 0x6c, 0x35, 0x1a, 0x69, 0xf0, 0x1d, 0x4b, 0x29, 0x54, 0x5a, 0x9a, 0x48, 0xec, 0x9f, 0x37, 0x74, 0x91, 0xd0, 0xd1, 0x9e, 0x00, 0xc2, 0x76, 0x56, 0xd6, 0xa0, 0x15, 0x14, 0x83, 0x59,
+ /* (2^383)P */ 0xc2, 0xf8, 0x22, 0x20, 0x23, 0x07, 0xbd, 0x1d, 0x6f, 0x1e, 0x8c, 0x56, 0x06, 0x6a, 0x4b, 0x9f, 0xe2, 0xa9, 0x92, 0x46, 0x4b, 0x46, 0x59, 0xd7, 0xe1, 0xda, 0x14, 0x98, 0x07, 0x65, 0x7e, 0x28, 0x20, 0xf2, 0x9d, 0x4f, 0x36, 0x5c, 0x92, 0xe0, 0x9d, 0xfe, 0x3e, 0xda, 0xe4, 0x47, 0x19, 0x3c, 0x00, 0x7f, 0x22, 0xf2, 0x9e, 0x51, 0xae, 0x4d,
+ /* (2^384)P */ 0xbe, 0x8c, 0x1b, 0x10, 0xb6, 0xad, 0xcc, 0xcc, 0xd8, 0x5e, 0x21, 0xa6, 0xfb, 0xf1, 0xf6, 0xbd, 0x0a, 0x24, 0x67, 0xb4, 0x57, 0x7a, 0xbc, 0xe8, 0xe9, 0xff, 0xee, 0x0a, 0x1f, 0xee, 0xbd, 0xc8, 0x44, 0xed, 0x2b, 0xbb, 0x55, 0x1f, 0xdd, 0x7c, 0xb3, 0xeb, 0x3f, 0x63, 0xa1, 0x28, 0x91, 0x21, 0xab, 0x71, 0xc6, 0x4c, 0xd0, 0xe9, 0xb0, 0x21,
+ /* (2^385)P */ 0xad, 0xc9, 0x77, 0x2b, 0xee, 0x89, 0xa4, 0x7b, 0xfd, 0xf9, 0xf6, 0x14, 0xe4, 0xed, 0x1a, 0x16, 0x9b, 0x78, 0x41, 0x43, 0xa8, 0x83, 0x72, 0x06, 0x2e, 0x7c, 0xdf, 0xeb, 0x7e, 0xdd, 0xd7, 0x8b, 0xea, 0x9a, 0x2b, 0x03, 0xba, 0x57, 0xf3, 0xf1, 0xd9, 0xe5, 0x09, 0xc5, 0x98, 0x61, 0x1c, 0x51, 0x6d, 0x5d, 0x6e, 0xfb, 0x5e, 0x95, 0x9f, 0xb5,
+ /* (2^386)P */ 0x23, 0xe2, 0x1e, 0x95, 0xa3, 0x5e, 0x42, 0x10, 0xc7, 0xc3, 0x70, 0xbf, 0x4b, 0x6b, 0x83, 0x36, 0x93, 0xb7, 0x68, 0x47, 0x88, 0x3a, 0x10, 0x88, 0x48, 0x7f, 0x8c, 0xae, 0x54, 0x10, 0x02, 0xa4, 0x52, 0x8f, 0x8d, 0xf7, 0x26, 0x4f, 0x50, 0xc3, 0x6a, 0xe2, 0x4e, 0x3b, 0x4c, 0xb9, 0x8a, 0x14, 0x15, 0x6d, 0x21, 0x29, 0xb3, 0x6e, 0x4e, 0xd0,
+ /* (2^387)P */ 0x4c, 0x8a, 0x18, 0x3f, 0xb7, 0x20, 0xfd, 0x3e, 0x54, 0xca, 0x68, 0x3c, 0xea, 0x6f, 0xf4, 0x6b, 0xa2, 0xbd, 0x01, 0xbd, 0xfe, 0x08, 0xa8, 0xd8, 0xc2, 0x20, 0x36, 0x05, 0xcd, 0xe9, 0xf3, 0x9e, 0xfa, 0x85, 0x66, 0x8f, 0x4b, 0x1d, 0x8c, 0x64, 0x4f, 0xb8, 0xc6, 0x0f, 0x5b, 0x57, 0xd8, 0x24, 0x19, 0x5a, 0x14, 0x4b, 0x92, 0xd3, 0x96, 0xbc,
+ /* (2^388)P */ 0xa9, 0x3f, 0xc9, 0x6c, 0xca, 0x64, 0x1e, 0x6f, 0xdf, 0x65, 0x7f, 0x9a, 0x47, 0x6b, 0x8a, 0x60, 0x31, 0xa6, 0x06, 0xac, 0x69, 0x30, 0xe6, 0xea, 0x63, 0x42, 0x26, 0x5f, 0xdb, 0xd0, 0xf2, 0x8e, 0x34, 0x0a, 0x3a, 0xeb, 0xf3, 0x79, 0xc8, 0xb7, 0x60, 0x56, 0x5c, 0x37, 0x95, 0x71, 0xf8, 0x7f, 0x49, 0x3e, 0x9e, 0x01, 0x26, 0x1e, 0x80, 0x9f,
+ /* (2^389)P */ 0xf8, 0x16, 0x9a, 0xaa, 0xb0, 0x28, 0xb5, 0x8e, 0xd0, 0x60, 0xe5, 0x26, 0xa9, 0x47, 0xc4, 0x5c, 0xa9, 0x39, 0xfe, 0x0a, 0xd8, 0x07, 0x2b, 0xb3, 0xce, 0xf1, 0xea, 0x1a, 0xf4, 0x7b, 0x98, 0x31, 0x3d, 0x13, 0x29, 0x80, 0xe8, 0x0d, 0xcf, 0x56, 0x39, 0x86, 0x50, 0x0c, 0xb3, 0x18, 0xf4, 0xc5, 0xca, 0xf2, 0x6f, 0xcd, 0x8d, 0xd5, 0x02, 0xb0,
+ /* (2^390)P */ 0xbf, 0x39, 0x3f, 0xac, 0x6d, 0x1a, 0x6a, 0xe4, 0x42, 0x24, 0xd6, 0x41, 0x9d, 0xb9, 0x5b, 0x46, 0x73, 0x93, 0x76, 0xaa, 0xb7, 0x37, 0x36, 0xa6, 0x09, 0xe5, 0x04, 0x3b, 0x66, 0xc4, 0x29, 0x3e, 0x41, 0xc2, 0xcb, 0xe5, 0x17, 0xd7, 0x34, 0x67, 0x1d, 0x2c, 0x12, 0xec, 0x24, 0x7a, 0x40, 0xa2, 0x45, 0x41, 0xf0, 0x75, 0xed, 0x43, 0x30, 0xc9,
+ /* (2^391)P */ 0x80, 0xf6, 0x47, 0x5b, 0xad, 0x54, 0x02, 0xbc, 0xdd, 0xa4, 0xb2, 0xd7, 0x42, 0x95, 0xf2, 0x0d, 0x1b, 0xef, 0x37, 0xa7, 0xb4, 0x34, 0x04, 0x08, 0x71, 0x1b, 0xd3, 0xdf, 0xa1, 0xf0, 0x2b, 0xfa, 0xc0, 0x1f, 0xf3, 0x44, 0xb5, 0xc6, 0x47, 0x3d, 0x65, 0x67, 0x45, 0x4d, 0x2f, 0xde, 0x52, 0x73, 0xfc, 0x30, 0x01, 0x6b, 0xc1, 0x03, 0xd8, 0xd7,
+ /* (2^392)P */ 0x1c, 0x67, 0x55, 0x3e, 0x01, 0x17, 0x0f, 0x3e, 0xe5, 0x34, 0x58, 0xfc, 0xcb, 0x71, 0x24, 0x74, 0x5d, 0x36, 0x1e, 0x89, 0x2a, 0x63, 0xf8, 0xf8, 0x9f, 0x50, 0x9f, 0x32, 0x92, 0x29, 0xd8, 0x1a, 0xec, 0x76, 0x57, 0x6c, 0x67, 0x12, 0x6a, 0x6e, 0xef, 0x97, 0x1f, 0xc3, 0x77, 0x60, 0x3c, 0x22, 0xcb, 0xc7, 0x04, 0x1a, 0x89, 0x2d, 0x10, 0xa6,
+ /* (2^393)P */ 0x12, 0xf5, 0xa9, 0x26, 0x16, 0xd9, 0x3c, 0x65, 0x5d, 0x83, 0xab, 0xd1, 0x70, 0x6b, 0x1c, 0xdb, 0xe7, 0x86, 0x0d, 0xfb, 0xe7, 0xf8, 0x2a, 0x58, 0x6e, 0x7a, 0x66, 0x13, 0x53, 0x3a, 0x6f, 0x8d, 0x43, 0x5f, 0x14, 0x23, 0x14, 0xff, 0x3d, 0x52, 0x7f, 0xee, 0xbd, 0x7a, 0x34, 0x8b, 0x35, 0x24, 0xc3, 0x7a, 0xdb, 0xcf, 0x22, 0x74, 0x9a, 0x8f,
+ /* (2^394)P */ 0xdb, 0x20, 0xfc, 0xe5, 0x39, 0x4e, 0x7d, 0x78, 0xee, 0x0b, 0xbf, 0x1d, 0x80, 0xd4, 0x05, 0x4f, 0xb9, 0xd7, 0x4e, 0x94, 0x88, 0x9a, 0x50, 0x78, 0x1a, 0x70, 0x8c, 0xcc, 0x25, 0xb6, 0x61, 0x09, 0xdc, 0x7b, 0xea, 0x3f, 0x7f, 0xea, 0x2a, 0x0d, 0x47, 0x1c, 0x8e, 0xa6, 0x5b, 0xd2, 0xa3, 0x61, 0x93, 0x3c, 0x68, 0x9f, 0x8b, 0xea, 0xb0, 0xcb,
+ /* (2^395)P */ 0xff, 0x54, 0x02, 0x19, 0xae, 0x8b, 0x4c, 0x2c, 0x3a, 0xe0, 0xe4, 0xac, 0x87, 0xf7, 0x51, 0x45, 0x41, 0x43, 0xdc, 0xaa, 0xcd, 0xcb, 0xdc, 0x40, 0xe3, 0x44, 0x3b, 0x1d, 0x9e, 0x3d, 0xb9, 0x82, 0xcc, 0x7a, 0xc5, 0x12, 0xf8, 0x1e, 0xdd, 0xdb, 0x8d, 0xb0, 0x2a, 0xe8, 0xe6, 0x6c, 0x94, 0x3b, 0xb7, 0x2d, 0xba, 0x79, 0x3b, 0xb5, 0x86, 0xfb,
+ /* (2^396)P */ 0x82, 0x88, 0x13, 0xdd, 0x6c, 0xcd, 0x85, 0x2b, 0x90, 0x86, 0xb7, 0xac, 0x16, 0xa6, 0x6e, 0x6a, 0x94, 0xd8, 0x1e, 0x4e, 0x41, 0x0f, 0xce, 0x81, 0x6a, 0xa8, 0x26, 0x56, 0x43, 0x52, 0x52, 0xe6, 0xff, 0x88, 0xcf, 0x47, 0x05, 0x1d, 0xff, 0xf3, 0xa0, 0x10, 0xb2, 0x97, 0x87, 0xeb, 0x47, 0xbb, 0xfa, 0x1f, 0xe8, 0x4c, 0xce, 0xc4, 0xcd, 0x93,
+ /* (2^397)P */ 0xf4, 0x11, 0xf5, 0x8d, 0x89, 0x29, 0x79, 0xb3, 0x59, 0x0b, 0x29, 0x7d, 0x9c, 0x12, 0x4a, 0x65, 0x72, 0x3a, 0xf9, 0xec, 0x37, 0x18, 0x86, 0xef, 0x44, 0x07, 0x25, 0x74, 0x76, 0x53, 0xed, 0x51, 0x01, 0xc6, 0x28, 0xc5, 0xc3, 0x4a, 0x0f, 0x99, 0xec, 0xc8, 0x40, 0x5a, 0x83, 0x30, 0x79, 0xa2, 0x3e, 0x63, 0x09, 0x2d, 0x6f, 0x23, 0x54, 0x1c,
+ /* (2^398)P */ 0x5c, 0x6f, 0x3b, 0x1c, 0x30, 0x77, 0x7e, 0x87, 0x66, 0x83, 0x2e, 0x7e, 0x85, 0x50, 0xfd, 0xa0, 0x7a, 0xc2, 0xf5, 0x0f, 0xc1, 0x64, 0xe7, 0x0b, 0xbd, 0x59, 0xa7, 0xe7, 0x65, 0x53, 0xc3, 0xf5, 0x55, 0x5b, 0xe1, 0x82, 0x30, 0x5a, 0x61, 0xcd, 0xa0, 0x89, 0x32, 0xdb, 0x87, 0xfc, 0x21, 0x8a, 0xab, 0x6d, 0x82, 0xa8, 0x42, 0x81, 0x4f, 0xf2,
+ /* (2^399)P */ 0xb3, 0xeb, 0x88, 0x18, 0xf6, 0x56, 0x96, 0xbf, 0xba, 0x5d, 0x71, 0xa1, 0x5a, 0xd1, 0x04, 0x7b, 0xd5, 0x46, 0x01, 0x74, 0xfe, 0x15, 0x25, 0xb7, 0xff, 0x0c, 0x24, 0x47, 0xac, 0xfd, 0xab, 0x47, 0x32, 0xe1, 0x6a, 0x4e, 0xca, 0xcf, 0x7f, 0xdd, 0xf8, 0xd2, 0x4b, 0x3b, 0xf5, 0x17, 0xba, 0xba, 0x8b, 0xa1, 0xec, 0x28, 0x3f, 0x97, 0xab, 0x2a,
+ /* (2^400)P */ 0x51, 0x38, 0xc9, 0x5e, 0xc6, 0xb3, 0x64, 0xf2, 0x24, 0x4d, 0x04, 0x7d, 0xc8, 0x39, 0x0c, 0x4a, 0xc9, 0x73, 0x74, 0x1b, 0x5c, 0xb2, 0xc5, 0x41, 0x62, 0xa0, 0x4c, 0x6d, 0x8d, 0x91, 0x9a, 0x7b, 0x88, 0xab, 0x9c, 0x7e, 0x23, 0xdb, 0x6f, 0xb5, 0x72, 0xd6, 0x47, 0x40, 0xef, 0x22, 0x58, 0x62, 0x19, 0x6c, 0x38, 0xba, 0x5b, 0x00, 0x30, 0x9f,
+ /* (2^401)P */ 0x65, 0xbb, 0x3b, 0x9b, 0xe9, 0xae, 0xbf, 0xbe, 0xe4, 0x13, 0x95, 0xf3, 0xe3, 0x77, 0xcb, 0xe4, 0x9a, 0x22, 0xb5, 0x4a, 0x08, 0x9d, 0xb3, 0x9e, 0x27, 0xe0, 0x15, 0x6c, 0x9f, 0x7e, 0x9a, 0x5e, 0x15, 0x45, 0x25, 0x8d, 0x01, 0x0a, 0xd2, 0x2b, 0xbd, 0x48, 0x06, 0x0d, 0x18, 0x97, 0x4b, 0xdc, 0xbc, 0xf0, 0xcd, 0xb2, 0x52, 0x3c, 0xac, 0xf5,
+ /* (2^402)P */ 0x3e, 0xed, 0x47, 0x6b, 0x5c, 0xf6, 0x76, 0xd0, 0xe9, 0x15, 0xa3, 0xcb, 0x36, 0x00, 0x21, 0xa3, 0x79, 0x20, 0xa5, 0x3e, 0x88, 0x03, 0xcb, 0x7e, 0x63, 0xbb, 0xed, 0xa9, 0x13, 0x35, 0x16, 0xaf, 0x2e, 0xb4, 0x70, 0x14, 0x93, 0xfb, 0xc4, 0x9b, 0xd8, 0xb1, 0xbe, 0x43, 0xd1, 0x85, 0xb8, 0x97, 0xef, 0xea, 0x88, 0xa1, 0x25, 0x52, 0x62, 0x75,
+ /* (2^403)P */ 0x8e, 0x4f, 0xaa, 0x23, 0x62, 0x7e, 0x2b, 0x37, 0x89, 0x00, 0x11, 0x30, 0xc5, 0x33, 0x4a, 0x89, 0x8a, 0xe2, 0xfc, 0x5c, 0x6a, 0x75, 0xe5, 0xf7, 0x02, 0x4a, 0x9b, 0xf7, 0xb5, 0x6a, 0x85, 0x31, 0xd3, 0x5a, 0xcf, 0xc3, 0xf8, 0xde, 0x2f, 0xcf, 0xb5, 0x24, 0xf4, 0xe3, 0xa1, 0xad, 0x42, 0xae, 0x09, 0xb9, 0x2e, 0x04, 0x2d, 0x01, 0x22, 0x3f,
+ /* (2^404)P */ 0x41, 0x16, 0xfb, 0x7d, 0x50, 0xfd, 0xb5, 0xba, 0x88, 0x24, 0xba, 0xfd, 0x3d, 0xb2, 0x90, 0x15, 0xb7, 0xfa, 0xa2, 0xe1, 0x4c, 0x7d, 0xb9, 0xc6, 0xff, 0x81, 0x57, 0xb6, 0xc2, 0x9e, 0xcb, 0xc4, 0x35, 0xbd, 0x01, 0xb7, 0xaa, 0xce, 0xd0, 0xe9, 0xb5, 0xd6, 0x72, 0xbf, 0xd2, 0xee, 0xc7, 0xac, 0x94, 0xff, 0x29, 0x57, 0x02, 0x49, 0x09, 0xad,
+ /* (2^405)P */ 0x27, 0xa5, 0x78, 0x1b, 0xbf, 0x6b, 0xaf, 0x0b, 0x8c, 0xd9, 0xa8, 0x37, 0xb0, 0x67, 0x18, 0xb6, 0xc7, 0x05, 0x8a, 0x67, 0x03, 0x30, 0x62, 0x6e, 0x56, 0x82, 0xa9, 0x54, 0x3e, 0x0c, 0x4e, 0x07, 0xe1, 0x5a, 0x38, 0xed, 0xfa, 0xc8, 0x55, 0x6b, 0x08, 0xa3, 0x6b, 0x64, 0x2a, 0x15, 0xd6, 0x39, 0x6f, 0x47, 0x99, 0x42, 0x3f, 0x33, 0x84, 0x8f,
+ /* (2^406)P */ 0xbc, 0x45, 0x29, 0x81, 0x0e, 0xa4, 0xc5, 0x72, 0x3a, 0x10, 0xe1, 0xc4, 0x1e, 0xda, 0xc3, 0xfe, 0xb0, 0xce, 0xd2, 0x13, 0x34, 0x67, 0x21, 0xc6, 0x7e, 0xf9, 0x8c, 0xff, 0x39, 0x50, 0xae, 0x92, 0x60, 0x35, 0x2f, 0x8b, 0x6e, 0xc9, 0xc1, 0x27, 0x3a, 0x94, 0x66, 0x3e, 0x26, 0x84, 0x93, 0xc8, 0x6c, 0xcf, 0xd2, 0x03, 0xa1, 0x10, 0xcf, 0xb7,
+ /* (2^407)P */ 0x64, 0xda, 0x19, 0xf6, 0xc5, 0x73, 0x17, 0x44, 0x88, 0x81, 0x07, 0x0d, 0x34, 0xb2, 0x75, 0xf9, 0xd9, 0xe2, 0xe0, 0x8b, 0x71, 0xcf, 0x72, 0x34, 0x83, 0xb4, 0xce, 0xfc, 0xd7, 0x29, 0x09, 0x5a, 0x98, 0xbf, 0x14, 0xac, 0x77, 0x55, 0x38, 0x47, 0x5b, 0x0f, 0x40, 0x24, 0xe5, 0xa5, 0xa6, 0xac, 0x2d, 0xa6, 0xff, 0x9c, 0x73, 0xfe, 0x5c, 0x7e,
+ /* (2^408)P */ 0x1e, 0x33, 0xcc, 0x68, 0xb2, 0xbc, 0x8c, 0x93, 0xaf, 0xcc, 0x38, 0xf8, 0xd9, 0x16, 0x72, 0x50, 0xac, 0xd9, 0xb5, 0x0b, 0x9a, 0xbe, 0x46, 0x7a, 0xf1, 0xee, 0xf1, 0xad, 0xec, 0x5b, 0x59, 0x27, 0x9c, 0x05, 0xa3, 0x87, 0xe0, 0x37, 0x2c, 0x83, 0xce, 0xb3, 0x65, 0x09, 0x8e, 0xc3, 0x9c, 0xbf, 0x6a, 0xa2, 0x00, 0xcc, 0x12, 0x36, 0xc5, 0x95,
+ /* (2^409)P */ 0x36, 0x11, 0x02, 0x14, 0x9c, 0x3c, 0xeb, 0x2f, 0x23, 0x5b, 0x6b, 0x2b, 0x08, 0x54, 0x53, 0xac, 0xb2, 0xa3, 0xe0, 0x26, 0x62, 0x3c, 0xe4, 0xe1, 0x81, 0xee, 0x13, 0x3e, 0xa4, 0x97, 0xef, 0xf9, 0x92, 0x27, 0x01, 0xce, 0x54, 0x8b, 0x3e, 0x31, 0xbe, 0xa7, 0x88, 0xcf, 0x47, 0x99, 0x3c, 0x10, 0x6f, 0x60, 0xb3, 0x06, 0x4e, 0xee, 0x1b, 0xf0,
+ /* (2^410)P */ 0x59, 0x49, 0x66, 0xcf, 0x22, 0xe6, 0xf6, 0x73, 0xfe, 0xa3, 0x1c, 0x09, 0xfa, 0x5f, 0x65, 0xa8, 0xf0, 0x82, 0xc2, 0xef, 0x16, 0x63, 0x6e, 0x79, 0x69, 0x51, 0x39, 0x07, 0x65, 0xc4, 0x81, 0xec, 0x73, 0x0f, 0x15, 0x93, 0xe1, 0x30, 0x33, 0xe9, 0x37, 0x86, 0x42, 0x4c, 0x1f, 0x9b, 0xad, 0xee, 0x3f, 0xf1, 0x2a, 0x8e, 0x6a, 0xa3, 0xc8, 0x35,
+ /* (2^411)P */ 0x1e, 0x49, 0xf1, 0xdd, 0xd2, 0x9c, 0x8e, 0x78, 0xb2, 0x06, 0xe4, 0x6a, 0xab, 0x3a, 0xdc, 0xcd, 0xf4, 0xeb, 0xe1, 0xe7, 0x2f, 0xaa, 0xeb, 0x40, 0x31, 0x9f, 0xb9, 0xab, 0x13, 0xa9, 0x78, 0xbf, 0x38, 0x89, 0x0e, 0x85, 0x14, 0x8b, 0x46, 0x76, 0x14, 0xda, 0xcf, 0x33, 0xc8, 0x79, 0xd3, 0xd5, 0xa3, 0x6a, 0x69, 0x45, 0x70, 0x34, 0xc3, 0xe9,
+ /* (2^412)P */ 0x5e, 0xe7, 0x78, 0xe9, 0x24, 0xcc, 0xe9, 0xf4, 0xc8, 0x6b, 0xe0, 0xfb, 0x3a, 0xbe, 0xcc, 0x42, 0x4a, 0x00, 0x22, 0xf8, 0xe6, 0x32, 0xbe, 0x6d, 0x18, 0x55, 0x60, 0xe9, 0x72, 0x69, 0x50, 0x56, 0xca, 0x04, 0x18, 0x38, 0xa1, 0xee, 0xd8, 0x38, 0x3c, 0xa7, 0x70, 0xe2, 0xb9, 0x4c, 0xa0, 0xc8, 0x89, 0x72, 0xcf, 0x49, 0x7f, 0xdf, 0xbc, 0x67,
+ /* (2^413)P */ 0x1d, 0x17, 0xcb, 0x0b, 0xbd, 0xb2, 0x36, 0xe3, 0xa8, 0x99, 0x31, 0xb6, 0x26, 0x9c, 0x0c, 0x74, 0xaf, 0x4d, 0x24, 0x61, 0xcf, 0x31, 0x7b, 0xed, 0xdd, 0xc3, 0xf6, 0x32, 0x70, 0xfe, 0x17, 0xf6, 0x51, 0x37, 0x65, 0xce, 0x5d, 0xaf, 0xa5, 0x2f, 0x2a, 0xfe, 0x00, 0x71, 0x7c, 0x50, 0xbe, 0x21, 0xc7, 0xed, 0xc6, 0xfc, 0x67, 0xcf, 0x9c, 0xdd,
+ /* (2^414)P */ 0x26, 0x3e, 0xf8, 0xbb, 0xd0, 0xb1, 0x01, 0xd8, 0xeb, 0x0b, 0x62, 0x87, 0x35, 0x4c, 0xde, 0xca, 0x99, 0x9c, 0x6d, 0xf7, 0xb6, 0xf0, 0x57, 0x0a, 0x52, 0x29, 0x6a, 0x3f, 0x26, 0x31, 0x04, 0x07, 0x2a, 0xc9, 0xfa, 0x9b, 0x0e, 0x62, 0x8e, 0x72, 0xf2, 0xad, 0xce, 0xb6, 0x35, 0x7a, 0xc1, 0xae, 0x35, 0xc7, 0xa3, 0x14, 0xcf, 0x0c, 0x28, 0xb7,
+ /* (2^415)P */ 0xa6, 0xf1, 0x32, 0x3a, 0x20, 0xd2, 0x24, 0x97, 0xcf, 0x5d, 0x37, 0x99, 0xaf, 0x33, 0x7a, 0x5b, 0x7a, 0xcc, 0x4e, 0x41, 0x38, 0xb1, 0x4e, 0xad, 0xc9, 0xd9, 0x71, 0x7e, 0xb2, 0xf5, 0xd5, 0x01, 0x6c, 0x4d, 0xfd, 0xa1, 0xda, 0x03, 0x38, 0x9b, 0x3d, 0x92, 0x92, 0xf2, 0xca, 0xbf, 0x1f, 0x24, 0xa4, 0xbb, 0x30, 0x6a, 0x74, 0x56, 0xc8, 0xce,
+ /* (2^416)P */ 0x27, 0xf4, 0xed, 0xc9, 0xc3, 0xb1, 0x79, 0x85, 0xbe, 0xf6, 0xeb, 0xf3, 0x55, 0xc7, 0xaa, 0xa6, 0xe9, 0x07, 0x5d, 0xf4, 0xeb, 0xa6, 0x81, 0xe3, 0x0e, 0xcf, 0xa3, 0xc1, 0xef, 0xe7, 0x34, 0xb2, 0x03, 0x73, 0x8a, 0x91, 0xf1, 0xad, 0x05, 0xc7, 0x0b, 0x43, 0x99, 0x12, 0x31, 0xc8, 0xc7, 0xc5, 0xa4, 0x3d, 0xcd, 0xe5, 0x4e, 0x6d, 0x24, 0xdd,
+ /* (2^417)P */ 0x61, 0x54, 0xd0, 0x95, 0x2c, 0x45, 0x75, 0xac, 0xb5, 0x1a, 0x9d, 0x11, 0xeb, 0xed, 0x6b, 0x57, 0xa3, 0xe6, 0xcd, 0x77, 0xd4, 0x83, 0x8e, 0x39, 0xf1, 0x0f, 0x98, 0xcb, 0x40, 0x02, 0x6e, 0x10, 0x82, 0x9e, 0xb4, 0x93, 0x76, 0xd7, 0x97, 0xa3, 0x53, 0x12, 0x86, 0xc6, 0x15, 0x78, 0x73, 0x93, 0xe7, 0x7f, 0xcf, 0x1f, 0xbf, 0xcd, 0xd2, 0x7a,
+ /* (2^418)P */ 0xc2, 0x21, 0xdc, 0xd5, 0x69, 0xff, 0xca, 0x49, 0x3a, 0xe1, 0xc3, 0x69, 0x41, 0x56, 0xc1, 0x76, 0x63, 0x24, 0xbd, 0x64, 0x1b, 0x3d, 0x92, 0xf9, 0x13, 0x04, 0x25, 0xeb, 0x27, 0xa6, 0xef, 0x39, 0x3a, 0x80, 0xe0, 0xf8, 0x27, 0xee, 0xc9, 0x49, 0x77, 0xef, 0x3f, 0x29, 0x3d, 0x5e, 0xe6, 0x66, 0x83, 0xd1, 0xf6, 0xfe, 0x9d, 0xbc, 0xf1, 0x96,
+ /* (2^419)P */ 0x6b, 0xc6, 0x99, 0x26, 0x3c, 0xf3, 0x63, 0xf9, 0xc7, 0x29, 0x8c, 0x52, 0x62, 0x2d, 0xdc, 0x8a, 0x66, 0xce, 0x2c, 0xa7, 0xe4, 0xf0, 0xd7, 0x37, 0x17, 0x1e, 0xe4, 0xa3, 0x53, 0x7b, 0x29, 0x8e, 0x60, 0x99, 0xf9, 0x0c, 0x7c, 0x6f, 0xa2, 0xcc, 0x9f, 0x80, 0xdd, 0x5e, 0x46, 0xaa, 0x0d, 0x6c, 0xc9, 0x6c, 0xf7, 0x78, 0x5b, 0x38, 0xe3, 0x24,
+ /* (2^420)P */ 0x4b, 0x75, 0x6a, 0x2f, 0x08, 0xe1, 0x72, 0x76, 0xab, 0x82, 0x96, 0xdf, 0x3b, 0x1f, 0x9b, 0xd8, 0xed, 0xdb, 0xcd, 0x15, 0x09, 0x5a, 0x1e, 0xb7, 0xc5, 0x26, 0x72, 0x07, 0x0c, 0x50, 0xcd, 0x3b, 0x4d, 0x3f, 0xa2, 0x67, 0xc2, 0x02, 0x61, 0x2e, 0x68, 0xe9, 0x6f, 0xf0, 0x21, 0x2a, 0xa7, 0x3b, 0x88, 0x04, 0x11, 0x64, 0x49, 0x0d, 0xb4, 0x46,
+ /* (2^421)P */ 0x63, 0x85, 0xf3, 0xc5, 0x2b, 0x5a, 0x9f, 0xf0, 0x17, 0xcb, 0x45, 0x0a, 0xf3, 0x6e, 0x7e, 0xb0, 0x7c, 0xbc, 0xf0, 0x4f, 0x3a, 0xb0, 0xbc, 0x36, 0x36, 0x52, 0x51, 0xcb, 0xfe, 0x9a, 0xcb, 0xe8, 0x7e, 0x4b, 0x06, 0x7f, 0xaa, 0x35, 0xc8, 0x0e, 0x7a, 0x30, 0xa3, 0xb1, 0x09, 0xbb, 0x86, 0x4c, 0xbe, 0xb8, 0xbd, 0xe0, 0x32, 0xa5, 0xd4, 0xf7,
+ /* (2^422)P */ 0x7d, 0x50, 0x37, 0x68, 0x4e, 0x22, 0xb2, 0x2c, 0xd5, 0x0f, 0x2b, 0x6d, 0xb1, 0x51, 0xf2, 0x82, 0xe9, 0x98, 0x7c, 0x50, 0xc7, 0x96, 0x7e, 0x0e, 0xdc, 0xb1, 0x0e, 0xb2, 0x63, 0x8c, 0x30, 0x37, 0x72, 0x21, 0x9c, 0x61, 0xc2, 0xa7, 0x33, 0xd9, 0xb2, 0x63, 0x93, 0xd1, 0x6b, 0x6a, 0x73, 0xa5, 0x58, 0x80, 0xff, 0x04, 0xc7, 0x83, 0x21, 0x29,
+ /* (2^423)P */ 0x29, 0x04, 0xbc, 0x99, 0x39, 0xc9, 0x58, 0xc9, 0x6b, 0x17, 0xe8, 0x90, 0xb3, 0xe6, 0xa9, 0xb6, 0x28, 0x9b, 0xcb, 0x3b, 0x28, 0x90, 0x68, 0x71, 0xff, 0xcf, 0x08, 0x78, 0xc9, 0x8d, 0xa8, 0x4e, 0x43, 0xd1, 0x1c, 0x9e, 0xa4, 0xe3, 0xdf, 0xbf, 0x92, 0xf4, 0xf9, 0x41, 0xba, 0x4d, 0x1c, 0xf9, 0xdd, 0x74, 0x76, 0x1c, 0x6e, 0x3e, 0x94, 0x87,
+ /* (2^424)P */ 0xe4, 0xda, 0xc5, 0xd7, 0xfb, 0x87, 0xc5, 0x4d, 0x6b, 0x19, 0xaa, 0xb9, 0xbc, 0x8c, 0xf2, 0x8a, 0xd8, 0x5d, 0xdb, 0x4d, 0xef, 0xa6, 0xf2, 0x65, 0xf1, 0x22, 0x9c, 0xf1, 0x46, 0x30, 0x71, 0x7c, 0xe4, 0x53, 0x8e, 0x55, 0x2e, 0x9c, 0x9a, 0x31, 0x2a, 0xc3, 0xab, 0x0f, 0xde, 0xe4, 0xbe, 0xd8, 0x96, 0x50, 0x6e, 0x0c, 0x54, 0x49, 0xe6, 0xec,
+ /* (2^425)P */ 0x3c, 0x1d, 0x5a, 0xa5, 0xda, 0xad, 0xdd, 0xc2, 0xae, 0xac, 0x6f, 0x86, 0x75, 0x31, 0x91, 0x64, 0x45, 0x9d, 0xa4, 0xf0, 0x81, 0xf1, 0x0e, 0xba, 0x74, 0xaf, 0x7b, 0xcd, 0x6f, 0xfe, 0xac, 0x4e, 0xdb, 0x4e, 0x45, 0x35, 0x36, 0xc5, 0xc0, 0x6c, 0x3d, 0x64, 0xf4, 0xd8, 0x07, 0x62, 0xd1, 0xec, 0xf3, 0xfc, 0x93, 0xc9, 0x28, 0x0c, 0x2c, 0xf3,
+ /* (2^426)P */ 0x0c, 0x69, 0x2b, 0x5c, 0xb6, 0x41, 0x69, 0xf1, 0xa4, 0xf1, 0x5b, 0x75, 0x4c, 0x42, 0x8b, 0x47, 0xeb, 0x69, 0xfb, 0xa8, 0xe6, 0xf9, 0x7b, 0x48, 0x50, 0xaf, 0xd3, 0xda, 0xb2, 0x35, 0x10, 0xb5, 0x5b, 0x40, 0x90, 0x39, 0xc9, 0x07, 0x06, 0x73, 0x26, 0x20, 0x95, 0x01, 0xa4, 0x2d, 0xf0, 0xe7, 0x2e, 0x00, 0x7d, 0x41, 0x09, 0x68, 0x13, 0xc4,
+ /* (2^427)P */ 0xbe, 0x38, 0x78, 0xcf, 0xc9, 0x4f, 0x36, 0xca, 0x09, 0x61, 0x31, 0x3c, 0x57, 0x2e, 0xec, 0x17, 0xa4, 0x7d, 0x19, 0x2b, 0x9b, 0x5b, 0xbe, 0x8f, 0xd6, 0xc5, 0x2f, 0x86, 0xf2, 0x64, 0x76, 0x17, 0x00, 0x6e, 0x1a, 0x8c, 0x67, 0x1b, 0x68, 0xeb, 0x15, 0xa2, 0xd6, 0x09, 0x91, 0xdd, 0x23, 0x0d, 0x98, 0xb2, 0x10, 0x19, 0x55, 0x9b, 0x63, 0xf2,
+ /* (2^428)P */ 0x51, 0x1f, 0x93, 0xea, 0x2a, 0x3a, 0xfa, 0x41, 0xc0, 0x57, 0xfb, 0x74, 0xa6, 0x65, 0x09, 0x56, 0x14, 0xb6, 0x12, 0xaa, 0xb3, 0x1a, 0x8d, 0x3b, 0x76, 0x91, 0x7a, 0x23, 0x56, 0x9c, 0x6a, 0xc0, 0xe0, 0x3c, 0x3f, 0xb5, 0x1a, 0xf4, 0x57, 0x71, 0x93, 0x2b, 0xb1, 0xa7, 0x70, 0x57, 0x22, 0x80, 0xf5, 0xb8, 0x07, 0x77, 0x87, 0x0c, 0xbe, 0x83,
+ /* (2^429)P */ 0x07, 0x9b, 0x0e, 0x52, 0x38, 0x63, 0x13, 0x86, 0x6a, 0xa6, 0xb4, 0xd2, 0x60, 0x68, 0x9a, 0x99, 0x82, 0x0a, 0x04, 0x5f, 0x89, 0x7a, 0x1a, 0x2a, 0xae, 0x2d, 0x35, 0x0c, 0x1e, 0xad, 0xef, 0x4f, 0x9a, 0xfc, 0xc8, 0xd9, 0xcf, 0x9d, 0x48, 0x71, 0xa5, 0x55, 0x79, 0x73, 0x39, 0x1b, 0xd8, 0x73, 0xec, 0x9b, 0x03, 0x16, 0xd8, 0x82, 0xf7, 0x67,
+ /* (2^430)P */ 0x52, 0x67, 0x42, 0x21, 0xc9, 0x40, 0x78, 0x82, 0x2b, 0x95, 0x2d, 0x20, 0x92, 0xd1, 0xe2, 0x61, 0x25, 0xb0, 0xc6, 0x9c, 0x20, 0x59, 0x8e, 0x28, 0x6f, 0xf3, 0xfd, 0xd3, 0xc1, 0x32, 0x43, 0xc9, 0xa6, 0x08, 0x7a, 0x77, 0x9c, 0x4c, 0x8c, 0x33, 0x71, 0x13, 0x69, 0xe3, 0x52, 0x30, 0xa7, 0xf5, 0x07, 0x67, 0xac, 0xad, 0x46, 0x8a, 0x26, 0x25,
+ /* (2^431)P */ 0xda, 0x86, 0xc4, 0xa2, 0x71, 0x56, 0xdd, 0xd2, 0x48, 0xd3, 0xde, 0x42, 0x63, 0x01, 0xa7, 0x2c, 0x92, 0x83, 0x6f, 0x2e, 0xd8, 0x1e, 0x3f, 0xc1, 0xc5, 0x42, 0x4e, 0x34, 0x19, 0x54, 0x6e, 0x35, 0x2c, 0x51, 0x2e, 0xfd, 0x0f, 0x9a, 0x45, 0x66, 0x5e, 0x4a, 0x83, 0xda, 0x0a, 0x53, 0x68, 0x63, 0xfa, 0xce, 0x47, 0x20, 0xd3, 0x34, 0xba, 0x0d,
+ /* (2^432)P */ 0xd0, 0xe9, 0x64, 0xa4, 0x61, 0x4b, 0x86, 0xe5, 0x93, 0x6f, 0xda, 0x0e, 0x31, 0x7e, 0x6e, 0xe3, 0xc6, 0x73, 0xd8, 0xa3, 0x08, 0x57, 0x52, 0xcd, 0x51, 0x63, 0x1d, 0x9f, 0x93, 0x00, 0x62, 0x91, 0x26, 0x21, 0xa7, 0xdd, 0x25, 0x0f, 0x09, 0x0d, 0x35, 0xad, 0xcf, 0x11, 0x8e, 0x6e, 0xe8, 0xae, 0x1d, 0x95, 0xcb, 0x88, 0xf8, 0x70, 0x7b, 0x91,
+ /* (2^433)P */ 0x0c, 0x19, 0x5c, 0xd9, 0x8d, 0xda, 0x9d, 0x2c, 0x90, 0x54, 0x65, 0xe8, 0xb6, 0x35, 0x50, 0xae, 0xea, 0xae, 0x43, 0xb7, 0x1e, 0x99, 0x8b, 0x4c, 0x36, 0x4e, 0xe4, 0x1e, 0xc4, 0x64, 0x43, 0xb6, 0xeb, 0xd4, 0xe9, 0x60, 0x22, 0xee, 0xcf, 0xb8, 0x52, 0x1b, 0xf0, 0x04, 0xce, 0xbc, 0x2b, 0xf0, 0xbe, 0xcd, 0x44, 0x74, 0x1e, 0x1f, 0x63, 0xf9,
+ /* (2^434)P */ 0xe1, 0x3f, 0x95, 0x94, 0xb2, 0xb6, 0x31, 0xa9, 0x1b, 0xdb, 0xfd, 0x0e, 0xdb, 0xdd, 0x1a, 0x22, 0x78, 0x60, 0x9f, 0x75, 0x5f, 0x93, 0x06, 0x0c, 0xd8, 0xbb, 0xa2, 0x85, 0x2b, 0x5e, 0xc0, 0x9b, 0xa8, 0x5d, 0xaf, 0x93, 0x91, 0x91, 0x47, 0x41, 0x1a, 0xfc, 0xb4, 0x51, 0x85, 0xad, 0x69, 0x4d, 0x73, 0x69, 0xd5, 0x4e, 0x82, 0xfb, 0x66, 0xcb,
+ /* (2^435)P */ 0x7c, 0xbe, 0xc7, 0x51, 0xc4, 0x74, 0x6e, 0xab, 0xfd, 0x41, 0x4f, 0x76, 0x4f, 0x24, 0x03, 0xd6, 0x2a, 0xb7, 0x42, 0xb4, 0xda, 0x41, 0x2c, 0x82, 0x48, 0x4c, 0x7f, 0x6f, 0x25, 0x5d, 0x36, 0xd4, 0x69, 0xf5, 0xef, 0x02, 0x81, 0xea, 0x6f, 0x19, 0x69, 0xe8, 0x6f, 0x5b, 0x2f, 0x14, 0x0e, 0x6f, 0x89, 0xb4, 0xb5, 0xd8, 0xae, 0xef, 0x7b, 0x87,
+ /* (2^436)P */ 0xe9, 0x91, 0xa0, 0x8b, 0xc9, 0xe0, 0x01, 0x90, 0x37, 0xc1, 0x6f, 0xdc, 0x5e, 0xf7, 0xbf, 0x43, 0x00, 0xaa, 0x10, 0x76, 0x76, 0x18, 0x6e, 0x19, 0x1e, 0x94, 0x50, 0x11, 0x0a, 0xd1, 0xe2, 0xdb, 0x08, 0x21, 0xa0, 0x1f, 0xdb, 0x54, 0xfe, 0xea, 0x6e, 0xa3, 0x68, 0x56, 0x87, 0x0b, 0x22, 0x4e, 0x66, 0xf3, 0x82, 0x82, 0x00, 0xcd, 0xd4, 0x12,
+ /* (2^437)P */ 0x25, 0x8e, 0x24, 0x77, 0x64, 0x4c, 0xe0, 0xf8, 0x18, 0xc0, 0xdc, 0xc7, 0x1b, 0x35, 0x65, 0xde, 0x67, 0x41, 0x5e, 0x6f, 0x90, 0x82, 0xa7, 0x2e, 0x6d, 0xf1, 0x47, 0xb4, 0x92, 0x9c, 0xfd, 0x6a, 0x9a, 0x41, 0x36, 0x20, 0x24, 0x58, 0xc3, 0x59, 0x07, 0x9a, 0xfa, 0x9f, 0x03, 0xcb, 0xc7, 0x69, 0x37, 0x60, 0xe1, 0xab, 0x13, 0x72, 0xee, 0xa2,
+ /* (2^438)P */ 0x74, 0x78, 0xfb, 0x13, 0xcb, 0x8e, 0x37, 0x1a, 0xf6, 0x1d, 0x17, 0x83, 0x06, 0xd4, 0x27, 0x06, 0x21, 0xe8, 0xda, 0xdf, 0x6b, 0xf3, 0x83, 0x6b, 0x34, 0x8a, 0x8c, 0xee, 0x01, 0x05, 0x5b, 0xed, 0xd3, 0x1b, 0xc9, 0x64, 0x83, 0xc9, 0x49, 0xc2, 0x57, 0x1b, 0xdd, 0xcf, 0xf1, 0x9d, 0x63, 0xee, 0x1c, 0x0d, 0xa0, 0x0a, 0x73, 0x1f, 0x5b, 0x32,
+ /* (2^439)P */ 0x29, 0xce, 0x1e, 0xc0, 0x6a, 0xf5, 0xeb, 0x99, 0x5a, 0x39, 0x23, 0xe9, 0xdd, 0xac, 0x44, 0x88, 0xbc, 0x80, 0x22, 0xde, 0x2c, 0xcb, 0xa8, 0x3b, 0xff, 0xf7, 0x6f, 0xc7, 0x71, 0x72, 0xa8, 0xa3, 0xf6, 0x4d, 0xc6, 0x75, 0xda, 0x80, 0xdc, 0xd9, 0x30, 0xd9, 0x07, 0x50, 0x5a, 0x54, 0x7d, 0xda, 0x39, 0x6f, 0x78, 0x94, 0xbf, 0x25, 0x98, 0xdc,
+ /* (2^440)P */ 0x01, 0x26, 0x62, 0x44, 0xfb, 0x0f, 0x11, 0x72, 0x73, 0x0a, 0x16, 0xc7, 0x16, 0x9c, 0x9b, 0x37, 0xd8, 0xff, 0x4f, 0xfe, 0x57, 0xdb, 0xae, 0xef, 0x7d, 0x94, 0x30, 0x04, 0x70, 0x83, 0xde, 0x3c, 0xd4, 0xb5, 0x70, 0xda, 0xa7, 0x55, 0xc8, 0x19, 0xe1, 0x36, 0x15, 0x61, 0xe7, 0x3b, 0x7d, 0x85, 0xbb, 0xf3, 0x42, 0x5a, 0x94, 0xf4, 0x53, 0x2a,
+ /* (2^441)P */ 0x14, 0x60, 0xa6, 0x0b, 0x83, 0xe1, 0x23, 0x77, 0xc0, 0xce, 0x50, 0xed, 0x35, 0x8d, 0x98, 0x99, 0x7d, 0xf5, 0x8d, 0xce, 0x94, 0x25, 0xc8, 0x0f, 0x6d, 0xfa, 0x4a, 0xa4, 0x3a, 0x1f, 0x66, 0xfb, 0x5a, 0x64, 0xaf, 0x8b, 0x54, 0x54, 0x44, 0x3f, 0x5b, 0x88, 0x61, 0xe4, 0x48, 0x45, 0x26, 0x20, 0xbe, 0x0d, 0x06, 0xbb, 0x65, 0x59, 0xe1, 0x36,
+ /* (2^442)P */ 0xb7, 0x98, 0xce, 0xa3, 0xe3, 0xee, 0x11, 0x1b, 0x9e, 0x24, 0x59, 0x75, 0x31, 0x37, 0x44, 0x6f, 0x6b, 0x9e, 0xec, 0xb7, 0x44, 0x01, 0x7e, 0xab, 0xbb, 0x69, 0x5d, 0x11, 0xb0, 0x30, 0x64, 0xea, 0x91, 0xb4, 0x7a, 0x8c, 0x02, 0x4c, 0xb9, 0x10, 0xa7, 0xc7, 0x79, 0xe6, 0xdc, 0x77, 0xe3, 0xc8, 0xef, 0x3e, 0xf9, 0x38, 0x81, 0xce, 0x9a, 0xb2,
+ /* (2^443)P */ 0x91, 0x12, 0x76, 0xd0, 0x10, 0xb4, 0xaf, 0xe1, 0x89, 0x3a, 0x93, 0x6b, 0x5c, 0x19, 0x5f, 0x24, 0xed, 0x04, 0x92, 0xc7, 0xf0, 0x00, 0x08, 0xc1, 0x92, 0xff, 0x90, 0xdb, 0xb2, 0xbf, 0xdf, 0x49, 0xcd, 0xbd, 0x5c, 0x6e, 0xbf, 0x16, 0xbb, 0x61, 0xf9, 0x20, 0x33, 0x35, 0x93, 0x11, 0xbc, 0x59, 0x69, 0xce, 0x18, 0x9f, 0xf8, 0x7b, 0xa1, 0x6e,
+ /* (2^444)P */ 0xa1, 0xf4, 0xaf, 0xad, 0xf8, 0xe6, 0x99, 0xd2, 0xa1, 0x4d, 0xde, 0x56, 0xc9, 0x7b, 0x0b, 0x11, 0x3e, 0xbf, 0x89, 0x1a, 0x9a, 0x90, 0xe5, 0xe2, 0xa6, 0x37, 0x88, 0xa1, 0x68, 0x59, 0xae, 0x8c, 0xec, 0x02, 0x14, 0x8d, 0xb7, 0x2e, 0x25, 0x75, 0x7f, 0x76, 0x1a, 0xd3, 0x4d, 0xad, 0x8a, 0x00, 0x6c, 0x96, 0x49, 0xa4, 0xc3, 0x2e, 0x5c, 0x7b,
+ /* (2^445)P */ 0x26, 0x53, 0xf7, 0xda, 0xa8, 0x01, 0x14, 0xb1, 0x63, 0xe3, 0xc3, 0x89, 0x88, 0xb0, 0x85, 0x40, 0x2b, 0x26, 0x9a, 0x10, 0x1a, 0x70, 0x33, 0xf4, 0x50, 0x9d, 0x4d, 0xd8, 0x64, 0xc6, 0x0f, 0xe1, 0x17, 0xc8, 0x10, 0x4b, 0xfc, 0xa0, 0xc9, 0xba, 0x2c, 0x98, 0x09, 0xf5, 0x84, 0xb6, 0x7c, 0x4e, 0xa3, 0xe3, 0x81, 0x1b, 0x32, 0x60, 0x02, 0xdd,
+ /* (2^446)P */ 0xa3, 0xe5, 0x86, 0xd4, 0x43, 0xa8, 0xd1, 0x98, 0x9d, 0x9d, 0xdb, 0x04, 0xcf, 0x6e, 0x35, 0x05, 0x30, 0x53, 0x3b, 0xbc, 0x90, 0x00, 0x4a, 0xc5, 0x40, 0x2a, 0x0f, 0xde, 0x1a, 0xd7, 0x36, 0x27, 0x44, 0x62, 0xa6, 0xac, 0x9d, 0xd2, 0x70, 0x69, 0x14, 0x39, 0x9b, 0xd1, 0xc3, 0x0a, 0x3a, 0x82, 0x0e, 0xf1, 0x94, 0xd7, 0x42, 0x94, 0xd5, 0x7d,
+ /* (2^447)P */ 0x04, 0xc0, 0x6e, 0x12, 0x90, 0x70, 0xf9, 0xdf, 0xf7, 0xc9, 0x86, 0xc0, 0xe6, 0x92, 0x8b, 0x0a, 0xa1, 0xc1, 0x3b, 0xcc, 0x33, 0xb7, 0xf0, 0xeb, 0x51, 0x50, 0x80, 0x20, 0x69, 0x1c, 0x4f, 0x89, 0x05, 0x1e, 0xe4, 0x7a, 0x0a, 0xc2, 0xf0, 0xf5, 0x78, 0x91, 0x76, 0x34, 0x45, 0xdc, 0x24, 0x53, 0x24, 0x98, 0xe2, 0x73, 0x6f, 0xe6, 0x46, 0x67,
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go
new file mode 100644
index 0000000..b6b236e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go
@@ -0,0 +1,71 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+var (
+ // genX is the x-coordinate of the generator of Goldilocks curve.
+ genX = fp.Elt{
+ 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26,
+ 0x8e, 0x93, 0x00, 0x8b, 0xe1, 0x80, 0x3b, 0x43,
+ 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
+ 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea,
+ 0x67, 0x17, 0x0f, 0x47, 0x70, 0x65, 0x14, 0x9e,
+ 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
+ 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f,
+ }
+ // genY is the y-coordinate of the generator of Goldilocks curve.
+ genY = fp.Elt{
+ 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98,
+ 0xad, 0xc8, 0xd7, 0x4e, 0x2c, 0x13, 0xbd, 0xfd,
+ 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
+ 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87,
+ 0x40, 0x98, 0xa3, 0x6c, 0x73, 0x73, 0xea, 0x4b,
+ 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
+ 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69,
+ }
+ // paramD is -39081 in Fp.
+ paramD = fp.Elt{
+ 0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ }
+ // order is 2^446-0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d,
+ // which is the number of points in the prime subgroup.
+ order = Scalar{
+ 0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23,
+ 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21,
+ 0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4,
+ 0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
+ }
+ // residue448 is 2^448 mod order.
+ residue448 = [4]uint64{
+ 0x721cf5b5529eec34, 0x7a4cf635c8e9c2ab, 0xeec492d944a725bf, 0x20cd77058,
+ }
+ // invFour is 1/4 mod order.
+ invFour = Scalar{
+ 0x3d, 0x11, 0xd6, 0xaa, 0xa4, 0x30, 0xde, 0x48,
+ 0xd5, 0x63, 0x71, 0xa3, 0x9c, 0x30, 0x5b, 0x08,
+ 0xa4, 0x8d, 0xb5, 0x6b, 0xd2, 0xb6, 0x13, 0x71,
+ 0xfa, 0x88, 0x32, 0xdf, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+ }
+ // paramDTwist is -39082 in Fp. The D parameter of the twist curve.
+ paramDTwist = fp.Elt{
+ 0x55, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ }
+)
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
new file mode 100644
index 0000000..5a93910
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
@@ -0,0 +1,80 @@
+// Package goldilocks provides elliptic curve operations over the goldilocks curve.
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+// Curve is the Goldilocks curve x^2+y^2=z^2-39081x^2y^2.
+type Curve struct{}
+
+// Identity returns the identity point.
+func (Curve) Identity() *Point {
+ return &Point{
+ y: fp.One(),
+ z: fp.One(),
+ }
+}
+
+// IsOnCurve returns true if the point lies on the curve.
+func (Curve) IsOnCurve(P *Point) bool {
+ x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+ rhs, lhs := &fp.Elt{}, &fp.Elt{}
+ fp.Mul(t, &P.ta, &P.tb) // t = ta*tb
+ fp.Sqr(x2, &P.x) // x^2
+ fp.Sqr(y2, &P.y) // y^2
+ fp.Sqr(z2, &P.z) // z^2
+ fp.Sqr(t2, t) // t^2
+ fp.Add(lhs, x2, y2) // x^2 + y^2
+ fp.Mul(rhs, t2, ¶mD) // dt^2
+ fp.Add(rhs, rhs, z2) // z^2 + dt^2
+ fp.Sub(lhs, lhs, rhs) // x^2 + y^2 - (z^2 + dt^2)
+ eq0 := fp.IsZero(lhs)
+
+ fp.Mul(lhs, &P.x, &P.y) // xy
+ fp.Mul(rhs, t, &P.z) // tz
+ fp.Sub(lhs, lhs, rhs) // xy - tz
+ eq1 := fp.IsZero(lhs)
+ return eq0 && eq1
+}
+
+// Generator returns the generator point.
+func (Curve) Generator() *Point {
+ return &Point{
+ x: genX,
+ y: genY,
+ z: fp.One(),
+ ta: genX,
+ tb: genY,
+ }
+}
+
+// Order returns the number of points in the prime subgroup.
+func (Curve) Order() Scalar { return order }
+
+// Double returns 2P.
+func (Curve) Double(P *Point) *Point { R := *P; R.Double(); return &R }
+
+// Add returns P+Q.
+func (Curve) Add(P, Q *Point) *Point { R := *P; R.Add(Q); return &R }
+
+// ScalarMult returns kP. This function runs in constant time.
+func (e Curve) ScalarMult(k *Scalar, P *Point) *Point {
+ k4 := &Scalar{}
+ k4.divBy4(k)
+ return e.pull(twistCurve{}.ScalarMult(k4, e.push(P)))
+}
+
+// ScalarBaseMult returns kG where G is the generator point. This function runs in constant time.
+func (e Curve) ScalarBaseMult(k *Scalar) *Point {
+ k4 := &Scalar{}
+ k4.divBy4(k)
+ return e.pull(twistCurve{}.ScalarBaseMult(k4))
+}
+
+// CombinedMult returns mG+nP, where G is the generator point. This function is non-constant time.
+func (e Curve) CombinedMult(m, n *Scalar, P *Point) *Point {
+ m4 := &Scalar{}
+ n4 := &Scalar{}
+ m4.divBy4(m)
+ n4.divBy4(n)
+ return e.pull(twistCurve{}.CombinedMult(m4, n4, twistCurve{}.pull(P)))
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go
new file mode 100644
index 0000000..b1daab8
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go
@@ -0,0 +1,52 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+func (Curve) pull(P *twistPoint) *Point { return twistCurve{}.push(P) }
+func (twistCurve) pull(P *Point) *twistPoint { return Curve{}.push(P) }
+
+// push sends a point on the Goldilocks curve to a point on the twist curve.
+func (Curve) push(P *Point) *twistPoint {
+ Q := &twistPoint{}
+ Px, Py, Pz := &P.x, &P.y, &P.z
+ a, b, c, d, e, f, g, h := &Q.x, &Q.y, &Q.z, &fp.Elt{}, &Q.ta, &Q.x, &Q.y, &Q.tb
+ fp.Add(e, Px, Py) // x+y
+ fp.Sqr(a, Px) // A = x^2
+ fp.Sqr(b, Py) // B = y^2
+ fp.Sqr(c, Pz) // z^2
+ fp.Add(c, c, c) // C = 2*z^2
+ *d = *a // D = A
+ fp.Sqr(e, e) // (x+y)^2
+ fp.Sub(e, e, a) // (x+y)^2-A
+ fp.Sub(e, e, b) // E = (x+y)^2-A-B
+ fp.Add(h, b, d) // H = B+D
+ fp.Sub(g, b, d) // G = B-D
+ fp.Sub(f, c, h) // F = C-H
+ fp.Mul(&Q.z, f, g) // Z = F * G
+ fp.Mul(&Q.x, e, f) // X = E * F
+ fp.Mul(&Q.y, g, h) // Y = G * H, // T = E * H
+ return Q
+}
+
+// push sends a point on the twist curve to a point on the Goldilocks curve.
+func (twistCurve) push(P *twistPoint) *Point {
+ Q := &Point{}
+ Px, Py, Pz := &P.x, &P.y, &P.z
+ a, b, c, d, e, f, g, h := &Q.x, &Q.y, &Q.z, &fp.Elt{}, &Q.ta, &Q.x, &Q.y, &Q.tb
+ fp.Add(e, Px, Py) // x+y
+ fp.Sqr(a, Px) // A = x^2
+ fp.Sqr(b, Py) // B = y^2
+ fp.Sqr(c, Pz) // z^2
+ fp.Add(c, c, c) // C = 2*z^2
+ fp.Neg(d, a) // D = -A
+ fp.Sqr(e, e) // (x+y)^2
+ fp.Sub(e, e, a) // (x+y)^2-A
+ fp.Sub(e, e, b) // E = (x+y)^2-A-B
+ fp.Add(h, b, d) // H = B+D
+ fp.Sub(g, b, d) // G = B-D
+ fp.Sub(f, c, h) // F = C-H
+ fp.Mul(&Q.z, f, g) // Z = F * G
+ fp.Mul(&Q.x, e, f) // X = E * F
+ fp.Mul(&Q.y, g, h) // Y = G * H, // T = E * H
+ return Q
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go
new file mode 100644
index 0000000..11f73de
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go
@@ -0,0 +1,171 @@
+package goldilocks
+
+import (
+ "errors"
+ "fmt"
+
+ fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// Point is a point on the Goldilocks Curve.
+type Point struct{ x, y, z, ta, tb fp.Elt }
+
+func (P Point) String() string {
+ return fmt.Sprintf("x: %v\ny: %v\nz: %v\nta: %v\ntb: %v", P.x, P.y, P.z, P.ta, P.tb)
+}
+
+// FromAffine creates a point from affine coordinates.
+func FromAffine(x, y *fp.Elt) (*Point, error) {
+ P := &Point{
+ x: *x,
+ y: *y,
+ z: fp.One(),
+ ta: *x,
+ tb: *y,
+ }
+ if !(Curve{}).IsOnCurve(P) {
+ return P, errors.New("point not on curve")
+ }
+ return P, nil
+}
+
+// isLessThan returns true if 0 <= x < y, and assumes that slices are of the
+// same length and are interpreted in little-endian order.
+func isLessThan(x, y []byte) bool {
+ i := len(x) - 1
+ for i > 0 && x[i] == y[i] {
+ i--
+ }
+ return x[i] < y[i]
+}
+
+// FromBytes returns a point from the input buffer.
+func FromBytes(in []byte) (*Point, error) {
+ if len(in) < fp.Size+1 {
+ return nil, errors.New("wrong input length")
+ }
+ err := errors.New("invalid decoding")
+ P := &Point{}
+ signX := in[fp.Size] >> 7
+ copy(P.y[:], in[:fp.Size])
+ p := fp.P()
+ if !isLessThan(P.y[:], p[:]) {
+ return nil, err
+ }
+
+ u, v := &fp.Elt{}, &fp.Elt{}
+ one := fp.One()
+ fp.Sqr(u, &P.y) // u = y^2
+ fp.Mul(v, u, ¶mD) // v = dy^2
+ fp.Sub(u, u, &one) // u = y^2-1
+ fp.Sub(v, v, &one) // v = dy^2-1
+ isQR := fp.InvSqrt(&P.x, u, v) // x = sqrt(u/v)
+ if !isQR {
+ return nil, err
+ }
+ fp.Modp(&P.x) // x = x mod p
+ if fp.IsZero(&P.x) && signX == 1 {
+ return nil, err
+ }
+ if signX != (P.x[0] & 1) {
+ fp.Neg(&P.x, &P.x)
+ }
+ P.ta = P.x
+ P.tb = P.y
+ P.z = fp.One()
+ return P, nil
+}
+
+// IsIdentity returns true is P is the identity Point.
+func (P *Point) IsIdentity() bool {
+ return fp.IsZero(&P.x) && !fp.IsZero(&P.y) && !fp.IsZero(&P.z) && P.y == P.z
+}
+
+// IsEqual returns true if P is equivalent to Q.
+func (P *Point) IsEqual(Q *Point) bool {
+ l, r := &fp.Elt{}, &fp.Elt{}
+ fp.Mul(l, &P.x, &Q.z)
+ fp.Mul(r, &Q.x, &P.z)
+ fp.Sub(l, l, r)
+ b := fp.IsZero(l)
+ fp.Mul(l, &P.y, &Q.z)
+ fp.Mul(r, &Q.y, &P.z)
+ fp.Sub(l, l, r)
+ b = b && fp.IsZero(l)
+ fp.Mul(l, &P.ta, &P.tb)
+ fp.Mul(l, l, &Q.z)
+ fp.Mul(r, &Q.ta, &Q.tb)
+ fp.Mul(r, r, &P.z)
+ fp.Sub(l, l, r)
+ b = b && fp.IsZero(l)
+ return b
+}
+
+// Neg obtains the inverse of the Point.
+func (P *Point) Neg() { fp.Neg(&P.x, &P.x); fp.Neg(&P.ta, &P.ta) }
+
+// ToAffine returns the x,y affine coordinates of P.
+func (P *Point) ToAffine() (x, y fp.Elt) {
+ fp.Inv(&P.z, &P.z) // 1/z
+ fp.Mul(&P.x, &P.x, &P.z) // x/z
+ fp.Mul(&P.y, &P.y, &P.z) // y/z
+ fp.Modp(&P.x)
+ fp.Modp(&P.y)
+ fp.SetOne(&P.z)
+ P.ta = P.x
+ P.tb = P.y
+ return P.x, P.y
+}
+
+// ToBytes stores P into a slice of bytes.
+func (P *Point) ToBytes(out []byte) error {
+ if len(out) < fp.Size+1 {
+ return errors.New("invalid decoding")
+ }
+ x, y := P.ToAffine()
+ out[fp.Size] = (x[0] & 1) << 7
+ return fp.ToBytes(out[:fp.Size], &y)
+}
+
+// MarshalBinary encodes the receiver into a binary form and returns the result.
+func (P *Point) MarshalBinary() (data []byte, err error) {
+ data = make([]byte, fp.Size+1)
+ err = P.ToBytes(data[:fp.Size+1])
+ return data, err
+}
+
+// UnmarshalBinary must be able to decode the form generated by MarshalBinary.
+func (P *Point) UnmarshalBinary(data []byte) error { Q, err := FromBytes(data); *P = *Q; return err }
+
+// Double sets P = 2Q.
+func (P *Point) Double() { P.Add(P) }
+
+// Add sets P =P+Q..
+func (P *Point) Add(Q *Point) {
+ // This is formula (5) from "Twisted Edwards Curves Revisited" by
+ // Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+ // https://doi.org/10.1007/978-3-540-89255-7_20
+ x1, y1, z1, ta1, tb1 := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ x2, y2, z2, ta2, tb2 := &Q.x, &Q.y, &Q.z, &Q.ta, &Q.tb
+ x3, y3, z3, E, H := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ A, B, C, D := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+ t1, t2, F, G := C, D, &fp.Elt{}, &fp.Elt{}
+ fp.Mul(t1, ta1, tb1) // t1 = ta1*tb1
+ fp.Mul(t2, ta2, tb2) // t2 = ta2*tb2
+ fp.Mul(A, x1, x2) // A = x1*x2
+ fp.Mul(B, y1, y2) // B = y1*y2
+ fp.Mul(C, t1, t2) // t1*t2
+ fp.Mul(C, C, ¶mD) // C = d*t1*t2
+ fp.Mul(D, z1, z2) // D = z1*z2
+ fp.Add(F, x1, y1) // x1+y1
+ fp.Add(E, x2, y2) // x2+y2
+ fp.Mul(E, E, F) // (x1+y1)*(x2+y2)
+ fp.Sub(E, E, A) // (x1+y1)*(x2+y2)-A
+ fp.Sub(E, E, B) // E = (x1+y1)*(x2+y2)-A-B
+ fp.Sub(F, D, C) // F = D-C
+ fp.Add(G, D, C) // G = D+C
+ fp.Sub(H, B, A) // H = B-A
+ fp.Mul(z3, F, G) // Z = F * G
+ fp.Mul(x3, E, F) // X = E * F
+ fp.Mul(y3, G, H) // Y = G * H, T = E * H
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go
new file mode 100644
index 0000000..f98117b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go
@@ -0,0 +1,203 @@
+package goldilocks
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+// ScalarSize is the size (in bytes) of scalars.
+const ScalarSize = 56 // 448 / 8
+
+// _N is the number of 64-bit words to store scalars.
+const _N = 7 // 448 / 64
+
+// Scalar represents a positive integer stored in little-endian order.
+type Scalar [ScalarSize]byte
+
+type scalar64 [_N]uint64
+
+func (z *scalar64) fromScalar(x *Scalar) {
+ z[0] = binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ z[1] = binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ z[2] = binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ z[3] = binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ z[4] = binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ z[5] = binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ z[6] = binary.LittleEndian.Uint64(x[6*8 : 7*8])
+}
+
+func (z *scalar64) toScalar(x *Scalar) {
+ binary.LittleEndian.PutUint64(x[0*8:1*8], z[0])
+ binary.LittleEndian.PutUint64(x[1*8:2*8], z[1])
+ binary.LittleEndian.PutUint64(x[2*8:3*8], z[2])
+ binary.LittleEndian.PutUint64(x[3*8:4*8], z[3])
+ binary.LittleEndian.PutUint64(x[4*8:5*8], z[4])
+ binary.LittleEndian.PutUint64(x[5*8:6*8], z[5])
+ binary.LittleEndian.PutUint64(x[6*8:7*8], z[6])
+}
+
+// add calculates z = x + y. Assumes len(z) > max(len(x),len(y)).
+func add(z, x, y []uint64) uint64 {
+ l, L, zz := len(x), len(y), y
+ if l > L {
+ l, L, zz = L, l, x
+ }
+ c := uint64(0)
+ for i := 0; i < l; i++ {
+ z[i], c = bits.Add64(x[i], y[i], c)
+ }
+ for i := l; i < L; i++ {
+ z[i], c = bits.Add64(zz[i], 0, c)
+ }
+ return c
+}
+
+// sub calculates z = x - y. Assumes len(z) > max(len(x),len(y)).
+func sub(z, x, y []uint64) uint64 {
+ l, L, zz := len(x), len(y), y
+ if l > L {
+ l, L, zz = L, l, x
+ }
+ c := uint64(0)
+ for i := 0; i < l; i++ {
+ z[i], c = bits.Sub64(x[i], y[i], c)
+ }
+ for i := l; i < L; i++ {
+ z[i], c = bits.Sub64(zz[i], 0, c)
+ }
+ return c
+}
+
+// mulWord calculates z = x * y. Assumes len(z) >= len(x)+1.
+func mulWord(z, x []uint64, y uint64) {
+ for i := range z {
+ z[i] = 0
+ }
+ carry := uint64(0)
+ for i := range x {
+ hi, lo := bits.Mul64(x[i], y)
+ lo, cc := bits.Add64(lo, z[i], 0)
+ hi, _ = bits.Add64(hi, 0, cc)
+ z[i], cc = bits.Add64(lo, carry, 0)
+ carry, _ = bits.Add64(hi, 0, cc)
+ }
+ z[len(x)] = carry
+}
+
+// Cmov moves x into z if b=1.
+func (z *scalar64) Cmov(b uint64, x *scalar64) {
+ m := uint64(0) - b
+ for i := range z {
+ z[i] = (z[i] &^ m) | (x[i] & m)
+ }
+}
+
+// leftShift shifts to the left the words of z returning the more significant word.
+func (z *scalar64) leftShift(low uint64) uint64 {
+ high := z[_N-1]
+ for i := _N - 1; i > 0; i-- {
+ z[i] = z[i-1]
+ }
+ z[0] = low
+ return high
+}
+
+// reduceOneWord calculates z = z + 2^448*x such that the result fits in a Scalar.
+func (z *scalar64) reduceOneWord(x uint64) {
+ prod := (&scalar64{})[:]
+ mulWord(prod, residue448[:], x)
+ cc := add(z[:], z[:], prod)
+ mulWord(prod, residue448[:], cc)
+ add(z[:], z[:], prod)
+}
+
+// modOrder reduces z mod order.
+func (z *scalar64) modOrder() {
+ var o64, x scalar64
+ o64.fromScalar(&order)
+ // Performs: while (z >= order) { z = z-order }
+ // At most 8 (eight) iterations reduce 3 bits by subtracting.
+ for i := 0; i < 8; i++ {
+ c := sub(x[:], z[:], o64[:]) // (c || x) = z-order
+ z.Cmov(1-c, &x) // if c != 0 { z = x }
+ }
+}
+
+// FromBytes stores z = x mod order, where x is a number stored in little-endian order.
+func (z *Scalar) FromBytes(x []byte) {
+ n := len(x)
+ nCeil := (n + 7) >> 3
+ for i := range z {
+ z[i] = 0
+ }
+ if nCeil < _N {
+ copy(z[:], x)
+ return
+ }
+ copy(z[:], x[8*(nCeil-_N):])
+ var z64 scalar64
+ z64.fromScalar(z)
+ for i := nCeil - _N - 1; i >= 0; i-- {
+ low := binary.LittleEndian.Uint64(x[8*i:])
+ high := z64.leftShift(low)
+ z64.reduceOneWord(high)
+ }
+ z64.modOrder()
+ z64.toScalar(z)
+}
+
+// divBy4 calculates z = x/4 mod order.
+func (z *Scalar) divBy4(x *Scalar) { z.Mul(x, &invFour) }
+
+// Red reduces z mod order.
+func (z *Scalar) Red() { var t scalar64; t.fromScalar(z); t.modOrder(); t.toScalar(z) }
+
+// Neg calculates z = -z mod order.
+func (z *Scalar) Neg() { z.Sub(&order, z) }
+
+// Add calculates z = x+y mod order.
+func (z *Scalar) Add(x, y *Scalar) {
+ var z64, x64, y64, t scalar64
+ x64.fromScalar(x)
+ y64.fromScalar(y)
+ c := add(z64[:], x64[:], y64[:])
+ add(t[:], z64[:], residue448[:])
+ z64.Cmov(c, &t)
+ z64.modOrder()
+ z64.toScalar(z)
+}
+
+// Sub calculates z = x-y mod order.
+func (z *Scalar) Sub(x, y *Scalar) {
+ var z64, x64, y64, t scalar64
+ x64.fromScalar(x)
+ y64.fromScalar(y)
+ c := sub(z64[:], x64[:], y64[:])
+ sub(t[:], z64[:], residue448[:])
+ z64.Cmov(c, &t)
+ z64.modOrder()
+ z64.toScalar(z)
+}
+
+// Mul calculates z = x*y mod order.
+func (z *Scalar) Mul(x, y *Scalar) {
+ var z64, x64, y64 scalar64
+ prod := (&[_N + 1]uint64{})[:]
+ x64.fromScalar(x)
+ y64.fromScalar(y)
+ mulWord(prod, x64[:], y64[_N-1])
+ copy(z64[:], prod[:_N])
+ z64.reduceOneWord(prod[_N])
+ for i := _N - 2; i >= 0; i-- {
+ h := z64.leftShift(0)
+ z64.reduceOneWord(h)
+ mulWord(prod, x64[:], y64[i])
+ c := add(z64[:], z64[:], prod[:_N])
+ z64.reduceOneWord(prod[_N] + c)
+ }
+ z64.modOrder()
+ z64.toScalar(z)
+}
+
+// IsZero returns true if z=0.
+func (z *Scalar) IsZero() bool { z.Red(); return *z == Scalar{} }
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go
new file mode 100644
index 0000000..83d7cda
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go
@@ -0,0 +1,138 @@
+package goldilocks
+
+import (
+ "crypto/subtle"
+ "math/bits"
+
+ "github.com/cloudflare/circl/internal/conv"
+ "github.com/cloudflare/circl/math"
+ fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// twistCurve is -x^2+y^2=1-39082x^2y^2 and is 4-isogenous to Goldilocks.
+type twistCurve struct{}
+
+// Identity returns the identity point.
+func (twistCurve) Identity() *twistPoint {
+ return &twistPoint{
+ y: fp.One(),
+ z: fp.One(),
+ }
+}
+
+// subYDiv16 update x = (x - y) / 16.
+func subYDiv16(x *scalar64, y int64) {
+ s := uint64(y >> 63)
+ x0, b0 := bits.Sub64((*x)[0], uint64(y), 0)
+ x1, b1 := bits.Sub64((*x)[1], s, b0)
+ x2, b2 := bits.Sub64((*x)[2], s, b1)
+ x3, b3 := bits.Sub64((*x)[3], s, b2)
+ x4, b4 := bits.Sub64((*x)[4], s, b3)
+ x5, b5 := bits.Sub64((*x)[5], s, b4)
+ x6, _ := bits.Sub64((*x)[6], s, b5)
+ x[0] = (x0 >> 4) | (x1 << 60)
+ x[1] = (x1 >> 4) | (x2 << 60)
+ x[2] = (x2 >> 4) | (x3 << 60)
+ x[3] = (x3 >> 4) | (x4 << 60)
+ x[4] = (x4 >> 4) | (x5 << 60)
+ x[5] = (x5 >> 4) | (x6 << 60)
+ x[6] = (x6 >> 4)
+}
+
+func recodeScalar(d *[113]int8, k *Scalar) {
+ var k64 scalar64
+ k64.fromScalar(k)
+ for i := 0; i < 112; i++ {
+ d[i] = int8((k64[0] & 0x1f) - 16)
+ subYDiv16(&k64, int64(d[i]))
+ }
+ d[112] = int8(k64[0])
+}
+
+// ScalarMult returns kP.
+func (e twistCurve) ScalarMult(k *Scalar, P *twistPoint) *twistPoint {
+ var TabP [8]preTwistPointProy
+ var S preTwistPointProy
+ var d [113]int8
+
+ var isZero int
+ if k.IsZero() {
+ isZero = 1
+ }
+ subtle.ConstantTimeCopy(isZero, k[:], order[:])
+
+ minusK := *k
+ isEven := 1 - int(k[0]&0x1)
+ minusK.Neg()
+ subtle.ConstantTimeCopy(isEven, k[:], minusK[:])
+ recodeScalar(&d, k)
+
+ P.oddMultiples(TabP[:])
+ Q := e.Identity()
+ for i := 112; i >= 0; i-- {
+ Q.Double()
+ Q.Double()
+ Q.Double()
+ Q.Double()
+ mask := d[i] >> 7
+ absDi := (d[i] + mask) ^ mask
+ inx := int32((absDi - 1) >> 1)
+ sig := int((d[i] >> 7) & 0x1)
+ for j := range TabP {
+ S.cmov(&TabP[j], uint(subtle.ConstantTimeEq(inx, int32(j))))
+ }
+ S.cneg(sig)
+ Q.mixAdd(&S)
+ }
+ Q.cneg(uint(isEven))
+ return Q
+}
+
+const (
+ omegaFix = 7
+ omegaVar = 5
+)
+
+// CombinedMult returns mG+nP.
+func (e twistCurve) CombinedMult(m, n *Scalar, P *twistPoint) *twistPoint {
+ nafFix := math.OmegaNAF(conv.BytesLe2BigInt(m[:]), omegaFix)
+ nafVar := math.OmegaNAF(conv.BytesLe2BigInt(n[:]), omegaVar)
+
+ if len(nafFix) > len(nafVar) {
+ nafVar = append(nafVar, make([]int32, len(nafFix)-len(nafVar))...)
+ } else if len(nafFix) < len(nafVar) {
+ nafFix = append(nafFix, make([]int32, len(nafVar)-len(nafFix))...)
+ }
+
+ var TabQ [1 << (omegaVar - 2)]preTwistPointProy
+ P.oddMultiples(TabQ[:])
+ Q := e.Identity()
+ for i := len(nafFix) - 1; i >= 0; i-- {
+ Q.Double()
+ // Generator point
+ if nafFix[i] != 0 {
+ idxM := absolute(nafFix[i]) >> 1
+ R := tabVerif[idxM]
+ if nafFix[i] < 0 {
+ R.neg()
+ }
+ Q.mixAddZ1(&R)
+ }
+ // Variable input point
+ if nafVar[i] != 0 {
+ idxN := absolute(nafVar[i]) >> 1
+ S := TabQ[idxN]
+ if nafVar[i] < 0 {
+ S.neg()
+ }
+ Q.mixAdd(&S)
+ }
+ }
+ return Q
+}
+
+// absolute returns always a positive value.
+func absolute(x int32) int32 {
+ mask := x >> 31
+ return (x + mask) ^ mask
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go
new file mode 100644
index 0000000..c55db77
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go
@@ -0,0 +1,135 @@
+package goldilocks
+
+import (
+ "fmt"
+
+ fp "github.com/cloudflare/circl/math/fp448"
+)
+
+type twistPoint struct{ x, y, z, ta, tb fp.Elt }
+
+type preTwistPointAffine struct{ addYX, subYX, dt2 fp.Elt }
+
+type preTwistPointProy struct {
+ preTwistPointAffine
+ z2 fp.Elt
+}
+
+func (P *twistPoint) String() string {
+ return fmt.Sprintf("x: %v\ny: %v\nz: %v\nta: %v\ntb: %v", P.x, P.y, P.z, P.ta, P.tb)
+}
+
+// cneg conditionally negates the point if b=1.
+func (P *twistPoint) cneg(b uint) {
+ t := &fp.Elt{}
+ fp.Neg(t, &P.x)
+ fp.Cmov(&P.x, t, b)
+ fp.Neg(t, &P.ta)
+ fp.Cmov(&P.ta, t, b)
+}
+
+// Double updates P with 2P.
+func (P *twistPoint) Double() {
+ // This is formula (7) from "Twisted Edwards Curves Revisited" by
+ // Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+ // https://doi.org/10.1007/978-3-540-89255-7_20
+ Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
+ fp.Add(e, Px, Py) // x+y
+ fp.Sqr(a, Px) // A = x^2
+ fp.Sqr(b, Py) // B = y^2
+ fp.Sqr(c, Pz) // z^2
+ fp.Add(c, c, c) // C = 2*z^2
+ fp.Add(h, a, b) // H = A+B
+ fp.Sqr(e, e) // (x+y)^2
+ fp.Sub(e, e, h) // E = (x+y)^2-A-B
+ fp.Sub(g, b, a) // G = B-A
+ fp.Sub(f, c, g) // F = C-G
+ fp.Mul(Pz, f, g) // Z = F * G
+ fp.Mul(Px, e, f) // X = E * F
+ fp.Mul(Py, g, h) // Y = G * H, T = E * H
+}
+
+// mixAdd calculates P= P+Q, where Q is a precomputed point with Z_Q = 1.
+func (P *twistPoint) mixAddZ1(Q *preTwistPointAffine) {
+ fp.Add(&P.z, &P.z, &P.z) // D = 2*z1 (z2=1)
+ P.coreAddition(Q)
+}
+
+// coreAddition calculates P=P+Q for curves with A=-1.
+func (P *twistPoint) coreAddition(Q *preTwistPointAffine) {
+ // This is the formula following (5) from "Twisted Edwards Curves Revisited" by
+ // Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+ // https://doi.org/10.1007/978-3-540-89255-7_20
+ Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
+ a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
+ fp.Mul(c, Pta, Ptb) // t1 = ta*tb
+ fp.Sub(h, Py, Px) // y1-x1
+ fp.Add(b, Py, Px) // y1+x1
+ fp.Mul(a, h, subYX2) // A = (y1-x1)*(y2-x2)
+ fp.Mul(b, b, addYX2) // B = (y1+x1)*(y2+x2)
+ fp.Mul(c, c, dt2) // C = 2*D*t1*t2
+ fp.Sub(e, b, a) // E = B-A
+ fp.Add(h, b, a) // H = B+A
+ fp.Sub(f, d, c) // F = D-C
+ fp.Add(g, d, c) // G = D+C
+ fp.Mul(Pz, f, g) // Z = F * G
+ fp.Mul(Px, e, f) // X = E * F
+ fp.Mul(Py, g, h) // Y = G * H, T = E * H
+}
+
+func (P *preTwistPointAffine) neg() {
+ P.addYX, P.subYX = P.subYX, P.addYX
+ fp.Neg(&P.dt2, &P.dt2)
+}
+
+func (P *preTwistPointAffine) cneg(b int) {
+ t := &fp.Elt{}
+ fp.Cswap(&P.addYX, &P.subYX, uint(b))
+ fp.Neg(t, &P.dt2)
+ fp.Cmov(&P.dt2, t, uint(b))
+}
+
+func (P *preTwistPointAffine) cmov(Q *preTwistPointAffine, b uint) {
+ fp.Cmov(&P.addYX, &Q.addYX, b)
+ fp.Cmov(&P.subYX, &Q.subYX, b)
+ fp.Cmov(&P.dt2, &Q.dt2, b)
+}
+
+// mixAdd calculates P= P+Q, where Q is a precomputed point with Z_Q != 1.
+func (P *twistPoint) mixAdd(Q *preTwistPointProy) {
+ fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2
+ P.coreAddition(&Q.preTwistPointAffine)
+}
+
+// oddMultiples calculates T[i] = (2*i-1)P for 0 < i < len(T).
+func (P *twistPoint) oddMultiples(T []preTwistPointProy) {
+ if n := len(T); n > 0 {
+ T[0].FromTwistPoint(P)
+ _2P := *P
+ _2P.Double()
+ R := &preTwistPointProy{}
+ R.FromTwistPoint(&_2P)
+ for i := 1; i < n; i++ {
+ P.mixAdd(R)
+ T[i].FromTwistPoint(P)
+ }
+ }
+}
+
+// cmov conditionally moves Q into P if b=1.
+func (P *preTwistPointProy) cmov(Q *preTwistPointProy, b uint) {
+ P.preTwistPointAffine.cmov(&Q.preTwistPointAffine, b)
+ fp.Cmov(&P.z2, &Q.z2, b)
+}
+
+// FromTwistPoint precomputes some coordinates of Q for missed addition.
+func (P *preTwistPointProy) FromTwistPoint(Q *twistPoint) {
+ fp.Add(&P.addYX, &Q.y, &Q.x) // addYX = X + Y
+ fp.Sub(&P.subYX, &Q.y, &Q.x) // subYX = Y - X
+ fp.Mul(&P.dt2, &Q.ta, &Q.tb) // T = ta*tb
+ fp.Mul(&P.dt2, &P.dt2, ¶mDTwist) // D*T
+ fp.Add(&P.dt2, &P.dt2, &P.dt2) // dt2 = 2*D*T
+ fp.Add(&P.z2, &Q.z, &Q.z) // z2 = 2*Z
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go
new file mode 100644
index 0000000..ed432e0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go
@@ -0,0 +1,216 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+var tabFixMult = [fxV][fx2w1]preTwistPointAffine{
+ {
+ {
+ addYX: fp.Elt{0x65, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2b, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+ subYX: fp.Elt{0x64, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2d, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+ dt2: fp.Elt{0x1a, 0x33, 0xea, 0x64, 0x45, 0x1c, 0xdf, 0x17, 0x1d, 0x16, 0x34, 0x28, 0xd6, 0x61, 0x19, 0x67, 0x79, 0xb4, 0x13, 0xcf, 0x3e, 0x7c, 0x0e, 0x72, 0xda, 0xf1, 0x5f, 0xda, 0xe6, 0xcf, 0x42, 0xd3, 0xb6, 0x17, 0xc2, 0x68, 0x13, 0x2d, 0xd9, 0x60, 0x3e, 0xae, 0xf0, 0x5b, 0x96, 0xf0, 0xcd, 0xaf, 0xea, 0xb7, 0x0d, 0x59, 0x16, 0xa7, 0xff, 0x55},
+ },
+ {
+ addYX: fp.Elt{0xca, 0xd8, 0x7d, 0x86, 0x1a, 0xef, 0xad, 0x11, 0xe3, 0x27, 0x41, 0x7e, 0x7f, 0x3e, 0xa9, 0xd2, 0xb5, 0x4e, 0x50, 0xe0, 0x77, 0x91, 0xc2, 0x13, 0x52, 0x73, 0x41, 0x09, 0xa6, 0x57, 0x9a, 0xc8, 0xa8, 0x90, 0x9d, 0x26, 0x14, 0xbb, 0xa1, 0x2a, 0xf7, 0x45, 0x43, 0x4e, 0xea, 0x35, 0x62, 0xe1, 0x08, 0x85, 0x46, 0xb8, 0x24, 0x05, 0x2d, 0xab},
+ subYX: fp.Elt{0x9b, 0xe6, 0xd3, 0xe5, 0xfe, 0x50, 0x36, 0x3c, 0x3c, 0x6d, 0x74, 0x1d, 0x74, 0xc0, 0xde, 0x5b, 0x45, 0x27, 0xe5, 0x12, 0xee, 0x63, 0x35, 0x6b, 0x13, 0xe2, 0x41, 0x6b, 0x3a, 0x05, 0x2b, 0xb1, 0x89, 0x26, 0xb6, 0xc6, 0xd1, 0x84, 0xff, 0x0e, 0x9b, 0xa3, 0xfb, 0x21, 0x36, 0x6b, 0x01, 0xf7, 0x9f, 0x7c, 0xeb, 0xf5, 0x18, 0x7a, 0x2a, 0x70},
+ dt2: fp.Elt{0x09, 0xad, 0x99, 0x1a, 0x38, 0xd3, 0xdf, 0x22, 0x37, 0x32, 0x61, 0x8b, 0xf3, 0x19, 0x48, 0x08, 0xe8, 0x49, 0xb6, 0x4a, 0xa7, 0xed, 0xa4, 0xa2, 0xee, 0x86, 0xd7, 0x31, 0x5e, 0xce, 0x95, 0x76, 0x86, 0x42, 0x1c, 0x9d, 0x07, 0x14, 0x8c, 0x34, 0x18, 0x9c, 0x6d, 0x3a, 0xdf, 0xa9, 0xe8, 0x36, 0x7e, 0xe4, 0x95, 0xbe, 0xb5, 0x09, 0xf8, 0x9c},
+ },
+ {
+ addYX: fp.Elt{0x51, 0xdb, 0x49, 0xa8, 0x9f, 0xe3, 0xd7, 0xec, 0x0d, 0x0f, 0x49, 0xe8, 0xb6, 0xc5, 0x0f, 0x5a, 0x1c, 0xce, 0x54, 0x0d, 0xb1, 0x8d, 0x5b, 0xbf, 0xf4, 0xaa, 0x34, 0x77, 0xc4, 0x5d, 0x59, 0xb6, 0xc5, 0x0e, 0x5a, 0xd8, 0x5b, 0x30, 0xc2, 0x1d, 0xec, 0x85, 0x1c, 0x42, 0xbe, 0x24, 0x2e, 0x50, 0x55, 0x44, 0xb2, 0x3a, 0x01, 0xaa, 0x98, 0xfb},
+ subYX: fp.Elt{0xe7, 0x29, 0xb7, 0xd0, 0xaa, 0x4f, 0x32, 0x53, 0x56, 0xde, 0xbc, 0xd1, 0x92, 0x5d, 0x19, 0xbe, 0xa3, 0xe3, 0x75, 0x48, 0xe0, 0x7a, 0x1b, 0x54, 0x7a, 0xb7, 0x41, 0x77, 0x84, 0x38, 0xdd, 0x14, 0x9f, 0xca, 0x3f, 0xa3, 0xc8, 0xa7, 0x04, 0x70, 0xf1, 0x4d, 0x3d, 0xb3, 0x84, 0x79, 0xcb, 0xdb, 0xe4, 0xc5, 0x42, 0x9b, 0x57, 0x19, 0xf1, 0x2d},
+ dt2: fp.Elt{0x20, 0xb4, 0x94, 0x9e, 0xdf, 0x31, 0x44, 0x0b, 0xc9, 0x7b, 0x75, 0x40, 0x9d, 0xd1, 0x96, 0x39, 0x70, 0x71, 0x15, 0xc8, 0x93, 0xd5, 0xc5, 0xe5, 0xba, 0xfe, 0xee, 0x08, 0x6a, 0x98, 0x0a, 0x1b, 0xb2, 0xaa, 0x3a, 0xf4, 0xa4, 0x79, 0xf9, 0x8e, 0x4d, 0x65, 0x10, 0x9b, 0x3a, 0x6e, 0x7c, 0x87, 0x94, 0x92, 0x11, 0x65, 0xbf, 0x1a, 0x09, 0xde},
+ },
+ {
+ addYX: fp.Elt{0xf3, 0x84, 0x76, 0x77, 0xa5, 0x6b, 0x27, 0x3b, 0x83, 0x3d, 0xdf, 0xa0, 0xeb, 0x32, 0x6d, 0x58, 0x81, 0x57, 0x64, 0xc2, 0x21, 0x7c, 0x9b, 0xea, 0xe6, 0xb0, 0x93, 0xf9, 0xe7, 0xc3, 0xed, 0x5a, 0x8e, 0xe2, 0xb4, 0x72, 0x76, 0x66, 0x0f, 0x22, 0x29, 0x94, 0x3e, 0x63, 0x48, 0x5e, 0x80, 0xcb, 0xac, 0xfa, 0x95, 0xb6, 0x4b, 0xc4, 0x95, 0x33},
+ subYX: fp.Elt{0x0c, 0x55, 0xd1, 0x5e, 0x5f, 0xbf, 0xbf, 0xe2, 0x4c, 0xfc, 0x37, 0x4a, 0xc4, 0xb1, 0xf4, 0x83, 0x61, 0x93, 0x60, 0x8e, 0x9f, 0x31, 0xf0, 0xa0, 0x41, 0xff, 0x1d, 0xe2, 0x7f, 0xca, 0x40, 0xd6, 0x88, 0xe8, 0x91, 0x61, 0xe2, 0x11, 0x18, 0x83, 0xf3, 0x25, 0x2f, 0x3f, 0x49, 0x40, 0xd4, 0x83, 0xe2, 0xd7, 0x74, 0x6a, 0x16, 0x86, 0x4e, 0xab},
+ dt2: fp.Elt{0xdd, 0x58, 0x65, 0xd8, 0x9f, 0xdd, 0x70, 0x7f, 0x0f, 0xec, 0xbd, 0x5c, 0x5c, 0x9b, 0x7e, 0x1b, 0x9f, 0x79, 0x36, 0x1f, 0xfd, 0x79, 0x10, 0x1c, 0x52, 0xf3, 0x22, 0xa4, 0x1f, 0x71, 0x6e, 0x63, 0x14, 0xf4, 0xa7, 0x3e, 0xbe, 0xad, 0x43, 0x30, 0x38, 0x8c, 0x29, 0xc6, 0xcf, 0x50, 0x75, 0x21, 0xe5, 0x78, 0xfd, 0xb0, 0x9a, 0xc4, 0x6d, 0xd4},
+ },
+ },
+ {
+ {
+ addYX: fp.Elt{0x7a, 0xa1, 0x38, 0xa6, 0xfd, 0x0e, 0x96, 0xd5, 0x26, 0x76, 0x86, 0x70, 0x80, 0x30, 0xa6, 0x67, 0xeb, 0xf4, 0x39, 0xdb, 0x22, 0xf5, 0x9f, 0x98, 0xe4, 0xb5, 0x3a, 0x0c, 0x59, 0xbf, 0x85, 0xc6, 0xf0, 0x0b, 0x1c, 0x41, 0x38, 0x09, 0x01, 0xdb, 0xd6, 0x3c, 0xb7, 0xf1, 0x08, 0x6b, 0x4b, 0x9e, 0x63, 0x53, 0x83, 0xd3, 0xab, 0xa3, 0x72, 0x0d},
+ subYX: fp.Elt{0x84, 0x68, 0x25, 0xe8, 0xe9, 0x8f, 0x91, 0xbf, 0xf7, 0xa4, 0x30, 0xae, 0xea, 0x9f, 0xdd, 0x56, 0x64, 0x09, 0xc9, 0x54, 0x68, 0x4e, 0x33, 0xc5, 0x6f, 0x7b, 0x2d, 0x52, 0x2e, 0x42, 0xbe, 0xbe, 0xf5, 0x64, 0xbf, 0x77, 0x54, 0xdf, 0xb0, 0x10, 0xd2, 0x16, 0x5d, 0xce, 0xaf, 0x9f, 0xfb, 0xa3, 0x63, 0x50, 0xcb, 0xc0, 0xd0, 0x88, 0x44, 0xa3},
+ dt2: fp.Elt{0xc3, 0x8b, 0xa5, 0xf1, 0x44, 0xe4, 0x41, 0xcd, 0x75, 0xe3, 0x17, 0x69, 0x5b, 0xb9, 0xbb, 0xee, 0x82, 0xbb, 0xce, 0x57, 0xdf, 0x2a, 0x9c, 0x12, 0xab, 0x66, 0x08, 0x68, 0x05, 0x1b, 0x87, 0xee, 0x5d, 0x1e, 0x18, 0x14, 0x22, 0x4b, 0x99, 0x61, 0x75, 0x28, 0xe7, 0x65, 0x1c, 0x36, 0xb6, 0x18, 0x09, 0xa8, 0xdf, 0xef, 0x30, 0x35, 0xbc, 0x58},
+ },
+ {
+ addYX: fp.Elt{0xc5, 0xd3, 0x0e, 0x6f, 0xaf, 0x06, 0x69, 0xc4, 0x07, 0x9e, 0x58, 0x6e, 0x3f, 0x49, 0xd9, 0x0a, 0x3c, 0x2c, 0x37, 0xcd, 0x27, 0x4d, 0x87, 0x91, 0x7a, 0xb0, 0x28, 0xad, 0x2f, 0x68, 0x92, 0x05, 0x97, 0xf1, 0x30, 0x5f, 0x4c, 0x10, 0x20, 0x30, 0xd3, 0x08, 0x3f, 0xc1, 0xc6, 0xb7, 0xb5, 0xd1, 0x71, 0x7b, 0xa8, 0x0a, 0xd8, 0xf5, 0x17, 0xcf},
+ subYX: fp.Elt{0x64, 0xd4, 0x8f, 0x91, 0x40, 0xab, 0x6e, 0x1a, 0x62, 0x83, 0xdc, 0xd7, 0x30, 0x1a, 0x4a, 0x2a, 0x4c, 0x54, 0x86, 0x19, 0x81, 0x5d, 0x04, 0x52, 0xa3, 0xca, 0x82, 0x38, 0xdc, 0x1e, 0xf0, 0x7a, 0x78, 0x76, 0x49, 0x4f, 0x71, 0xc4, 0x74, 0x2f, 0xf0, 0x5b, 0x2e, 0x5e, 0xac, 0xef, 0x17, 0xe4, 0x8e, 0x6e, 0xed, 0x43, 0x23, 0x61, 0x99, 0x49},
+ dt2: fp.Elt{0x64, 0x90, 0x72, 0x76, 0xf8, 0x2c, 0x7d, 0x57, 0xf9, 0x30, 0x5e, 0x7a, 0x10, 0x74, 0x19, 0x39, 0xd9, 0xaf, 0x0a, 0xf1, 0x43, 0xed, 0x88, 0x9c, 0x8b, 0xdc, 0x9b, 0x1c, 0x90, 0xe7, 0xf7, 0xa3, 0xa5, 0x0d, 0xc6, 0xbc, 0x30, 0xfb, 0x91, 0x1a, 0x51, 0xba, 0x2d, 0xbe, 0x89, 0xdf, 0x1d, 0xdc, 0x53, 0xa8, 0x82, 0x8a, 0xd3, 0x8d, 0x16, 0x68},
+ },
+ {
+ addYX: fp.Elt{0xef, 0x5c, 0xe3, 0x74, 0xbf, 0x13, 0x4a, 0xbf, 0x66, 0x73, 0x64, 0xb7, 0xd4, 0xce, 0x98, 0x82, 0x05, 0xfa, 0x98, 0x0c, 0x0a, 0xae, 0xe5, 0x6b, 0x9f, 0xac, 0xbb, 0x6e, 0x1f, 0xcf, 0xff, 0xa6, 0x71, 0x9a, 0xa8, 0x7a, 0x9e, 0x64, 0x1f, 0x20, 0x4a, 0x61, 0xa2, 0xd6, 0x50, 0xe3, 0xba, 0x81, 0x0c, 0x50, 0x59, 0x69, 0x59, 0x15, 0x55, 0xdb},
+ subYX: fp.Elt{0xe8, 0x77, 0x4d, 0xe8, 0x66, 0x3d, 0xc1, 0x00, 0x3c, 0xf2, 0x25, 0x00, 0xdc, 0xb2, 0xe5, 0x9b, 0x12, 0x89, 0xf3, 0xd6, 0xea, 0x85, 0x60, 0xfe, 0x67, 0x91, 0xfd, 0x04, 0x7c, 0xe0, 0xf1, 0x86, 0x06, 0x11, 0x66, 0xee, 0xd4, 0xd5, 0xbe, 0x3b, 0x0f, 0xe3, 0x59, 0xb3, 0x4f, 0x00, 0xb6, 0xce, 0x80, 0xc1, 0x61, 0xf7, 0xaf, 0x04, 0x6a, 0x3c},
+ dt2: fp.Elt{0x00, 0xd7, 0x32, 0x93, 0x67, 0x70, 0x6f, 0xd7, 0x69, 0xab, 0xb1, 0xd3, 0xdc, 0xd6, 0xa8, 0xdd, 0x35, 0x25, 0xca, 0xd3, 0x8a, 0x6d, 0xce, 0xfb, 0xfd, 0x2b, 0x83, 0xf0, 0xd4, 0xac, 0x66, 0xfb, 0x72, 0x87, 0x7e, 0x55, 0xb7, 0x91, 0x58, 0x10, 0xc3, 0x11, 0x7e, 0x15, 0xfe, 0x7c, 0x55, 0x90, 0xa3, 0x9e, 0xed, 0x9a, 0x7f, 0xa7, 0xb7, 0xeb},
+ },
+ {
+ addYX: fp.Elt{0x25, 0x0f, 0xc2, 0x09, 0x9c, 0x10, 0xc8, 0x7c, 0x93, 0xa7, 0xbe, 0xe9, 0x26, 0x25, 0x7c, 0x21, 0xfe, 0xe7, 0x5f, 0x3c, 0x02, 0x83, 0xa7, 0x9e, 0xdf, 0xc0, 0x94, 0x2b, 0x7d, 0x1a, 0xd0, 0x1d, 0xcc, 0x2e, 0x7d, 0xd4, 0x85, 0xe7, 0xc1, 0x15, 0x66, 0xd6, 0xd6, 0x32, 0xb8, 0xf7, 0x63, 0xaa, 0x3b, 0xa5, 0xea, 0x49, 0xad, 0x88, 0x9b, 0x66},
+ subYX: fp.Elt{0x09, 0x97, 0x79, 0x36, 0x41, 0x56, 0x9b, 0xdf, 0x15, 0xd8, 0x43, 0x28, 0x17, 0x5b, 0x96, 0xc9, 0xcf, 0x39, 0x1f, 0x13, 0xf7, 0x4d, 0x1d, 0x1f, 0xda, 0x51, 0x56, 0xe7, 0x0a, 0x5a, 0x65, 0xb6, 0x2a, 0x87, 0x49, 0x86, 0xc2, 0x2b, 0xcd, 0xfe, 0x07, 0xf6, 0x4c, 0xe2, 0x1d, 0x9b, 0xd8, 0x82, 0x09, 0x5b, 0x11, 0x10, 0x62, 0x56, 0x89, 0xbd},
+ dt2: fp.Elt{0xd9, 0x15, 0x73, 0xf2, 0x96, 0x35, 0x53, 0xb0, 0xe7, 0xa8, 0x0b, 0x93, 0x35, 0x0b, 0x3a, 0x00, 0xf5, 0x18, 0xb1, 0xc3, 0x12, 0x3f, 0x91, 0x17, 0xc1, 0x4c, 0x15, 0x5a, 0x86, 0x92, 0x11, 0xbd, 0x44, 0x40, 0x5a, 0x7b, 0x15, 0x89, 0xba, 0xc1, 0xc1, 0xbc, 0x43, 0x45, 0xe6, 0x52, 0x02, 0x73, 0x0a, 0xd0, 0x2a, 0x19, 0xda, 0x47, 0xa8, 0xff},
+ },
+ },
+}
+
+// tabVerif contains the odd multiples of P. The entry T[i] = (2i+1)P, where
+// P = phi(G) and G is the generator of the Goldilocks curve, and phi is a
+// 4-degree isogeny.
+var tabVerif = [1 << (omegaFix - 2)]preTwistPointAffine{
+ { /* 1P*/
+ addYX: fp.Elt{0x65, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2b, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+ subYX: fp.Elt{0x64, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2d, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+ dt2: fp.Elt{0x1a, 0x33, 0xea, 0x64, 0x45, 0x1c, 0xdf, 0x17, 0x1d, 0x16, 0x34, 0x28, 0xd6, 0x61, 0x19, 0x67, 0x79, 0xb4, 0x13, 0xcf, 0x3e, 0x7c, 0x0e, 0x72, 0xda, 0xf1, 0x5f, 0xda, 0xe6, 0xcf, 0x42, 0xd3, 0xb6, 0x17, 0xc2, 0x68, 0x13, 0x2d, 0xd9, 0x60, 0x3e, 0xae, 0xf0, 0x5b, 0x96, 0xf0, 0xcd, 0xaf, 0xea, 0xb7, 0x0d, 0x59, 0x16, 0xa7, 0xff, 0x55},
+ },
+ { /* 3P*/
+ addYX: fp.Elt{0xd1, 0xe9, 0xa8, 0x33, 0x20, 0x76, 0x18, 0x08, 0x45, 0x2a, 0xc9, 0x67, 0x2a, 0xc3, 0x15, 0x24, 0xf9, 0x74, 0x21, 0x30, 0x99, 0x59, 0x8b, 0xb2, 0xf0, 0xa4, 0x07, 0xe2, 0x6a, 0x36, 0x8d, 0xd9, 0xd2, 0x4a, 0x7f, 0x73, 0x50, 0x39, 0x3d, 0xaa, 0xa7, 0x51, 0x73, 0x0d, 0x2b, 0x8b, 0x96, 0x47, 0xac, 0x3c, 0x5d, 0xaa, 0x39, 0x9c, 0xcf, 0xd5},
+ subYX: fp.Elt{0x6b, 0x11, 0x5d, 0x1a, 0xf9, 0x41, 0x9d, 0xc5, 0x30, 0x3e, 0xad, 0x25, 0x2c, 0x04, 0x45, 0xea, 0xcc, 0x67, 0x07, 0x85, 0xe9, 0xda, 0x0e, 0xb5, 0x40, 0xb7, 0x32, 0xb4, 0x49, 0xdd, 0xff, 0xaa, 0xfc, 0xbb, 0x19, 0xca, 0x8b, 0x79, 0x2b, 0x8f, 0x8d, 0x00, 0x33, 0xc2, 0xad, 0xe9, 0xd3, 0x12, 0xa8, 0xaa, 0x87, 0x62, 0xad, 0x2d, 0xff, 0xa4},
+ dt2: fp.Elt{0xb0, 0xaf, 0x3b, 0xea, 0xf0, 0x42, 0x0b, 0x5e, 0x88, 0xd3, 0x98, 0x08, 0x87, 0x59, 0x72, 0x0a, 0xc2, 0xdf, 0xcb, 0x7f, 0x59, 0xb5, 0x4c, 0x63, 0x68, 0xe8, 0x41, 0x38, 0x67, 0x4f, 0xe9, 0xc6, 0xb2, 0x6b, 0x08, 0xa7, 0xf7, 0x0e, 0xcd, 0xea, 0xca, 0x3d, 0xaf, 0x8e, 0xda, 0x4b, 0x2e, 0xd2, 0x88, 0x64, 0x8d, 0xc5, 0x5f, 0x76, 0x0f, 0x3d},
+ },
+ { /* 5P*/
+ addYX: fp.Elt{0xe5, 0x65, 0xc9, 0xe2, 0x75, 0xf0, 0x7d, 0x1a, 0xba, 0xa4, 0x40, 0x4b, 0x93, 0x12, 0xa2, 0x80, 0x95, 0x0d, 0x03, 0x93, 0xe8, 0xa5, 0x4d, 0xe2, 0x3d, 0x81, 0xf5, 0xce, 0xd4, 0x2d, 0x25, 0x59, 0x16, 0x5c, 0xe7, 0xda, 0xc7, 0x45, 0xd2, 0x7e, 0x2c, 0x38, 0xd4, 0x37, 0x64, 0xb2, 0xc2, 0x28, 0xc5, 0x72, 0x16, 0x32, 0x45, 0x36, 0x6f, 0x9f},
+ subYX: fp.Elt{0x09, 0xf4, 0x7e, 0xbd, 0x89, 0xdb, 0x19, 0x58, 0xe1, 0x08, 0x00, 0x8a, 0xf4, 0x5f, 0x2a, 0x32, 0x40, 0xf0, 0x2c, 0x3f, 0x5d, 0xe4, 0xfc, 0x89, 0x11, 0x24, 0xb4, 0x2f, 0x97, 0xad, 0xac, 0x8f, 0x19, 0xab, 0xfa, 0x12, 0xe5, 0xf9, 0x50, 0x4e, 0x50, 0x6f, 0x32, 0x30, 0x88, 0xa6, 0xe5, 0x48, 0x28, 0xa2, 0x1b, 0x9f, 0xcd, 0xe2, 0x43, 0x38},
+ dt2: fp.Elt{0xa9, 0xcc, 0x53, 0x39, 0x86, 0x02, 0x60, 0x75, 0x34, 0x99, 0x57, 0xbd, 0xfc, 0x5a, 0x8e, 0xce, 0x5e, 0x98, 0x22, 0xd0, 0xa5, 0x24, 0xff, 0x90, 0x28, 0x9f, 0x58, 0xf3, 0x39, 0xe9, 0xba, 0x36, 0x23, 0xfb, 0x7f, 0x41, 0xcc, 0x2b, 0x5a, 0x25, 0x3f, 0x4c, 0x2a, 0xf1, 0x52, 0x6f, 0x2f, 0x07, 0xe3, 0x88, 0x81, 0x77, 0xdd, 0x7c, 0x88, 0x82},
+ },
+ { /* 7P*/
+ addYX: fp.Elt{0xf7, 0xee, 0x88, 0xfd, 0x3a, 0xbf, 0x7e, 0x28, 0x39, 0x23, 0x79, 0xe6, 0x5c, 0x56, 0xcb, 0xb5, 0x48, 0x6a, 0x80, 0x6d, 0x37, 0x60, 0x6c, 0x10, 0x35, 0x49, 0x4b, 0x46, 0x60, 0xd4, 0x79, 0xd4, 0x53, 0xd3, 0x67, 0x88, 0xd0, 0x41, 0xd5, 0x43, 0x85, 0xc8, 0x71, 0xe3, 0x1c, 0xb6, 0xda, 0x22, 0x64, 0x8f, 0x80, 0xac, 0xad, 0x7d, 0xd5, 0x82},
+ subYX: fp.Elt{0x92, 0x40, 0xc1, 0x83, 0x21, 0x9b, 0xd5, 0x7d, 0x3f, 0x29, 0xb6, 0x26, 0xef, 0x12, 0xb9, 0x27, 0x39, 0x42, 0x37, 0x97, 0x09, 0x9a, 0x08, 0xe1, 0x68, 0xb6, 0x7a, 0x3f, 0x9f, 0x45, 0xf8, 0x37, 0x19, 0x83, 0x97, 0xe6, 0x73, 0x30, 0x32, 0x35, 0xcf, 0xae, 0x5c, 0x12, 0x68, 0xdf, 0x6e, 0x2b, 0xde, 0x83, 0xa0, 0x44, 0x74, 0x2e, 0x4a, 0xe9},
+ dt2: fp.Elt{0xcb, 0x22, 0x0a, 0xda, 0x6b, 0xc1, 0x8a, 0x29, 0xa1, 0xac, 0x8b, 0x5b, 0x8b, 0x32, 0x20, 0xf2, 0x21, 0xae, 0x0c, 0x43, 0xc4, 0xd7, 0x19, 0x37, 0x3d, 0x79, 0x25, 0x98, 0x6c, 0x9c, 0x22, 0x31, 0x2a, 0x55, 0x9f, 0xda, 0x5e, 0xa8, 0x13, 0xdb, 0x8e, 0x2e, 0x16, 0x39, 0xf4, 0x91, 0x6f, 0xec, 0x71, 0x71, 0xc9, 0x10, 0xf2, 0xa4, 0x8f, 0x11},
+ },
+ { /* 9P*/
+ addYX: fp.Elt{0x85, 0xdd, 0x37, 0x62, 0x74, 0x8e, 0x33, 0x5b, 0x25, 0x12, 0x1b, 0xe7, 0xdf, 0x47, 0xe5, 0x12, 0xfd, 0x3a, 0x3a, 0xf5, 0x5d, 0x4c, 0xa2, 0x29, 0x3c, 0x5c, 0x2f, 0xee, 0x18, 0x19, 0x0a, 0x2b, 0xef, 0x67, 0x50, 0x7a, 0x0d, 0x29, 0xae, 0x55, 0x82, 0xcd, 0xd6, 0x41, 0x90, 0xb4, 0x13, 0x31, 0x5d, 0x11, 0xb8, 0xaa, 0x12, 0x86, 0x08, 0xac},
+ subYX: fp.Elt{0xcc, 0x37, 0x8d, 0x83, 0x5f, 0xfd, 0xde, 0xd5, 0xf7, 0xf1, 0xae, 0x0a, 0xa7, 0x0b, 0xeb, 0x6d, 0x19, 0x8a, 0xb6, 0x1a, 0x59, 0xd8, 0xff, 0x3c, 0xbc, 0xbc, 0xef, 0x9c, 0xda, 0x7b, 0x75, 0x12, 0xaf, 0x80, 0x8f, 0x2c, 0x3c, 0xaa, 0x0b, 0x17, 0x86, 0x36, 0x78, 0x18, 0xc8, 0x8a, 0xf6, 0xb8, 0x2c, 0x2f, 0x57, 0x2c, 0x62, 0x57, 0xf6, 0x90},
+ dt2: fp.Elt{0x83, 0xbc, 0xa2, 0x07, 0xa5, 0x38, 0x96, 0xea, 0xfe, 0x11, 0x46, 0x1d, 0x3b, 0xcd, 0x42, 0xc5, 0xee, 0x67, 0x04, 0x72, 0x08, 0xd8, 0xd9, 0x96, 0x07, 0xf7, 0xac, 0xc3, 0x64, 0xf1, 0x98, 0x2c, 0x55, 0xd7, 0x7d, 0xc8, 0x6c, 0xbd, 0x2c, 0xff, 0x15, 0xd6, 0x6e, 0xb8, 0x17, 0x8e, 0xa8, 0x27, 0x66, 0xb1, 0x73, 0x79, 0x96, 0xff, 0x29, 0x10},
+ },
+ { /* 11P*/
+ addYX: fp.Elt{0x76, 0xcb, 0x9b, 0x0c, 0x5b, 0xfe, 0xe1, 0x2a, 0xdd, 0x6f, 0x6c, 0xdd, 0x6f, 0xb4, 0xc0, 0xc2, 0x1b, 0x4b, 0x38, 0xe8, 0x66, 0x8c, 0x1e, 0x31, 0x63, 0xb9, 0x94, 0xcd, 0xc3, 0x8c, 0x44, 0x25, 0x7b, 0xd5, 0x39, 0x80, 0xfc, 0x01, 0xaa, 0xf7, 0x2a, 0x61, 0x8a, 0x25, 0xd2, 0x5f, 0xc5, 0x66, 0x38, 0xa4, 0x17, 0xcf, 0x3e, 0x11, 0x0f, 0xa3},
+ subYX: fp.Elt{0xe0, 0xb6, 0xd1, 0x9c, 0x71, 0x49, 0x2e, 0x7b, 0xde, 0x00, 0xda, 0x6b, 0xf1, 0xec, 0xe6, 0x7a, 0x15, 0x38, 0x71, 0xe9, 0x7b, 0xdb, 0xf8, 0x98, 0xc0, 0x91, 0x2e, 0x53, 0xee, 0x92, 0x87, 0x25, 0xc9, 0xb0, 0xbb, 0x33, 0x15, 0x46, 0x7f, 0xfd, 0x4f, 0x8b, 0x77, 0x05, 0x96, 0xb6, 0xe2, 0x08, 0xdb, 0x0d, 0x09, 0xee, 0x5b, 0xd1, 0x2a, 0x63},
+ dt2: fp.Elt{0x8f, 0x7b, 0x57, 0x8c, 0xbf, 0x06, 0x0d, 0x43, 0x21, 0x92, 0x94, 0x2d, 0x6a, 0x38, 0x07, 0x0f, 0xa0, 0xf1, 0xe3, 0xd8, 0x2a, 0xbf, 0x46, 0xc6, 0x9e, 0x1f, 0x8f, 0x2b, 0x46, 0x84, 0x0b, 0x74, 0xed, 0xff, 0xf8, 0xa5, 0x94, 0xae, 0xf1, 0x67, 0xb1, 0x9b, 0xdd, 0x4a, 0xd0, 0xdb, 0xc2, 0xb5, 0x58, 0x49, 0x0c, 0xa9, 0x1d, 0x7d, 0xa9, 0xd3},
+ },
+ { /* 13P*/
+ addYX: fp.Elt{0x73, 0x84, 0x2e, 0x31, 0x1f, 0xdc, 0xed, 0x9f, 0x74, 0xfa, 0xe0, 0x35, 0xb1, 0x85, 0x6a, 0x8d, 0x86, 0xd0, 0xff, 0xd6, 0x08, 0x43, 0x73, 0x1a, 0xd5, 0xf8, 0x43, 0xd4, 0xb3, 0xe5, 0x3f, 0xa8, 0x84, 0x17, 0x59, 0x65, 0x4e, 0xe6, 0xee, 0x54, 0x9c, 0xda, 0x5e, 0x7e, 0x98, 0x29, 0x6d, 0x73, 0x34, 0x1f, 0x99, 0x80, 0x54, 0x54, 0x81, 0x0b},
+ subYX: fp.Elt{0xb1, 0xe5, 0xbb, 0x80, 0x22, 0x9c, 0x81, 0x6d, 0xaf, 0x27, 0x65, 0x6f, 0x7e, 0x9c, 0xb6, 0x8d, 0x35, 0x5c, 0x2e, 0x20, 0x48, 0x7a, 0x28, 0xf0, 0x97, 0xfe, 0xb7, 0x71, 0xce, 0xd6, 0xad, 0x3a, 0x81, 0xf6, 0x74, 0x5e, 0xf3, 0xfd, 0x1b, 0xd4, 0x1e, 0x7c, 0xc2, 0xb7, 0xc8, 0xa6, 0xc9, 0x89, 0x03, 0x47, 0xec, 0x24, 0xd6, 0x0e, 0xec, 0x9c},
+ dt2: fp.Elt{0x91, 0x0a, 0x43, 0x34, 0x20, 0xc2, 0x64, 0xf7, 0x4e, 0x48, 0xc8, 0xd2, 0x95, 0x83, 0xd1, 0xa4, 0xfb, 0x4e, 0x41, 0x3b, 0x0d, 0xd5, 0x07, 0xd9, 0xf1, 0x13, 0x16, 0x78, 0x54, 0x57, 0xd0, 0xf1, 0x4f, 0x20, 0xac, 0xcf, 0x9c, 0x3b, 0x33, 0x0b, 0x99, 0x54, 0xc3, 0x7f, 0x3e, 0x57, 0x26, 0x86, 0xd5, 0xa5, 0x2b, 0x8d, 0xe3, 0x19, 0x36, 0xf7},
+ },
+ { /* 15P*/
+ addYX: fp.Elt{0x23, 0x69, 0x47, 0x14, 0xf9, 0x9a, 0x50, 0xff, 0x64, 0xd1, 0x50, 0x35, 0xc3, 0x11, 0xd3, 0x19, 0xcf, 0x87, 0xda, 0x30, 0x0b, 0x50, 0xda, 0xc0, 0xe0, 0x25, 0x00, 0xe5, 0x68, 0x93, 0x04, 0xc2, 0xaf, 0xbd, 0x2f, 0x36, 0x5f, 0x47, 0x96, 0x10, 0xa8, 0xbd, 0xe4, 0x88, 0xac, 0x80, 0x52, 0x61, 0x73, 0xe9, 0x63, 0xdd, 0x99, 0xad, 0x20, 0x5b},
+ subYX: fp.Elt{0x1b, 0x5e, 0xa2, 0x2a, 0x25, 0x0f, 0x86, 0xc0, 0xb1, 0x2e, 0x0c, 0x13, 0x40, 0x8d, 0xf0, 0xe6, 0x00, 0x55, 0x08, 0xc5, 0x7d, 0xf4, 0xc9, 0x31, 0x25, 0x3a, 0x99, 0x69, 0xdd, 0x67, 0x63, 0x9a, 0xd6, 0x89, 0x2e, 0xa1, 0x19, 0xca, 0x2c, 0xd9, 0x59, 0x5f, 0x5d, 0xc3, 0x6e, 0x62, 0x36, 0x12, 0x59, 0x15, 0xe1, 0xdc, 0xa4, 0xad, 0xc9, 0xd0},
+ dt2: fp.Elt{0xbc, 0xea, 0xfc, 0xaf, 0x66, 0x23, 0xb7, 0x39, 0x6b, 0x2a, 0x96, 0xa8, 0x54, 0x43, 0xe9, 0xaa, 0x32, 0x40, 0x63, 0x92, 0x5e, 0xdf, 0x35, 0xc2, 0x9f, 0x24, 0x0c, 0xed, 0xfc, 0xde, 0x73, 0x8f, 0xa7, 0xd5, 0xa3, 0x2b, 0x18, 0x1f, 0xb0, 0xf8, 0xeb, 0x55, 0xd9, 0xc3, 0xfd, 0x28, 0x7c, 0x4f, 0xce, 0x0d, 0xf7, 0xae, 0xc2, 0x83, 0xc3, 0x78},
+ },
+ { /* 17P*/
+ addYX: fp.Elt{0x71, 0xe6, 0x60, 0x93, 0x37, 0xdb, 0x01, 0xa5, 0x4c, 0xba, 0xe8, 0x8e, 0xd5, 0xf9, 0xd3, 0x98, 0xe5, 0xeb, 0xab, 0x3a, 0x15, 0x8b, 0x35, 0x60, 0xbe, 0xe5, 0x9c, 0x2d, 0x10, 0x9b, 0x2e, 0xcf, 0x65, 0x64, 0xea, 0x8f, 0x72, 0xce, 0xf5, 0x18, 0xe5, 0xe2, 0xf0, 0x0e, 0xae, 0x04, 0xec, 0xa0, 0x20, 0x65, 0x63, 0x07, 0xb1, 0x9f, 0x03, 0x97},
+ subYX: fp.Elt{0x9e, 0x41, 0x64, 0x30, 0x95, 0x7f, 0x3a, 0x89, 0x7b, 0x0a, 0x79, 0x59, 0x23, 0x9a, 0x3b, 0xfe, 0xa4, 0x13, 0x08, 0xb2, 0x2e, 0x04, 0x50, 0x10, 0x30, 0xcd, 0x2e, 0xa4, 0x91, 0x71, 0x50, 0x36, 0x4a, 0x02, 0xf4, 0x8d, 0xa3, 0x36, 0x1b, 0xf4, 0x52, 0xba, 0x15, 0x04, 0x8b, 0x80, 0x25, 0xd9, 0xae, 0x67, 0x20, 0xd9, 0x88, 0x8f, 0x97, 0xa6},
+ dt2: fp.Elt{0xb5, 0xe7, 0x46, 0xbd, 0x55, 0x23, 0xa0, 0x68, 0xc0, 0x12, 0xd9, 0xf1, 0x0a, 0x75, 0xe2, 0xda, 0xf4, 0x6b, 0xca, 0x14, 0xe4, 0x9f, 0x0f, 0xb5, 0x3c, 0xa6, 0xa5, 0xa2, 0x63, 0x94, 0xd1, 0x1c, 0x39, 0x58, 0x57, 0x02, 0x27, 0x98, 0xb6, 0x47, 0xc6, 0x61, 0x4b, 0x5c, 0xab, 0x6f, 0x2d, 0xab, 0xe3, 0xc1, 0x69, 0xf9, 0x12, 0xb0, 0xc8, 0xd5},
+ },
+ { /* 19P*/
+ addYX: fp.Elt{0x19, 0x7d, 0xd5, 0xac, 0x79, 0xa2, 0x82, 0x9b, 0x28, 0x31, 0x22, 0xc0, 0x73, 0x02, 0x76, 0x17, 0x10, 0x70, 0x79, 0x57, 0xc9, 0x84, 0x62, 0x8e, 0x04, 0x04, 0x61, 0x67, 0x08, 0x48, 0xb4, 0x4b, 0xde, 0x53, 0x8c, 0xff, 0x36, 0x1b, 0x62, 0x86, 0x5d, 0xe1, 0x9b, 0xb1, 0xe5, 0xe8, 0x44, 0x64, 0xa1, 0x68, 0x3f, 0xa8, 0x45, 0x52, 0x91, 0xed},
+ subYX: fp.Elt{0x42, 0x1a, 0x36, 0x1f, 0x90, 0x15, 0x24, 0x8d, 0x24, 0x80, 0xe6, 0xfe, 0x1e, 0xf0, 0xad, 0xaf, 0x6a, 0x93, 0xf0, 0xa6, 0x0d, 0x5d, 0xea, 0xf6, 0x62, 0x96, 0x7a, 0x05, 0x76, 0x85, 0x74, 0x32, 0xc7, 0xc8, 0x64, 0x53, 0x62, 0xe7, 0x54, 0x84, 0xe0, 0x40, 0x66, 0x19, 0x70, 0x40, 0x95, 0x35, 0x68, 0x64, 0x43, 0xcd, 0xba, 0x29, 0x32, 0xa8},
+ dt2: fp.Elt{0x3e, 0xf6, 0xd6, 0xe4, 0x99, 0xeb, 0x20, 0x66, 0x08, 0x2e, 0x26, 0x64, 0xd7, 0x76, 0xf3, 0xb4, 0xc5, 0xa4, 0x35, 0x92, 0xd2, 0x99, 0x70, 0x5a, 0x1a, 0xe9, 0xe9, 0x3d, 0x3b, 0xe1, 0xcd, 0x0e, 0xee, 0x24, 0x13, 0x03, 0x22, 0xd6, 0xd6, 0x72, 0x08, 0x2b, 0xde, 0xfd, 0x93, 0xed, 0x0c, 0x7f, 0x5e, 0x31, 0x22, 0x4d, 0x80, 0x78, 0xc0, 0x48},
+ },
+ { /* 21P*/
+ addYX: fp.Elt{0x8f, 0x72, 0xd2, 0x9e, 0xc4, 0xcd, 0x2c, 0xbf, 0xa8, 0xd3, 0x24, 0x62, 0x28, 0xee, 0x39, 0x0a, 0x19, 0x3a, 0x58, 0xff, 0x21, 0x2e, 0x69, 0x6c, 0x6e, 0x18, 0xd0, 0xcd, 0x61, 0xc1, 0x18, 0x02, 0x5a, 0xe9, 0xe3, 0xef, 0x1f, 0x8e, 0x10, 0xe8, 0x90, 0x2b, 0x48, 0xcd, 0xee, 0x38, 0xbd, 0x3a, 0xca, 0xbc, 0x2d, 0xe2, 0x3a, 0x03, 0x71, 0x02},
+ subYX: fp.Elt{0xf8, 0xa4, 0x32, 0x26, 0x66, 0xaf, 0x3b, 0x53, 0xe7, 0xb0, 0x91, 0x92, 0xf5, 0x3c, 0x74, 0xce, 0xf2, 0xdd, 0x68, 0xa9, 0xf4, 0xcd, 0x5f, 0x60, 0xab, 0x71, 0xdf, 0xcd, 0x5c, 0x5d, 0x51, 0x72, 0x3a, 0x96, 0xea, 0xd6, 0xde, 0x54, 0x8e, 0x55, 0x4c, 0x08, 0x4c, 0x60, 0xdd, 0x34, 0xa9, 0x6f, 0xf3, 0x04, 0x02, 0xa8, 0xa6, 0x4e, 0x4d, 0x62},
+ dt2: fp.Elt{0x76, 0x4a, 0xae, 0x38, 0x62, 0x69, 0x72, 0xdc, 0xe8, 0x43, 0xbe, 0x1d, 0x61, 0xde, 0x31, 0xc3, 0x42, 0x8f, 0x33, 0x9d, 0xca, 0xc7, 0x9c, 0xec, 0x6a, 0xe2, 0xaa, 0x01, 0x49, 0x78, 0x8d, 0x72, 0x4f, 0x38, 0xea, 0x52, 0xc2, 0xd3, 0xc9, 0x39, 0x71, 0xba, 0xb9, 0x09, 0x9b, 0xa3, 0x7f, 0x45, 0x43, 0x65, 0x36, 0x29, 0xca, 0xe7, 0x5c, 0x5f},
+ },
+ { /* 23P*/
+ addYX: fp.Elt{0x89, 0x42, 0x35, 0x48, 0x6d, 0x74, 0xe5, 0x1f, 0xc3, 0xdd, 0x28, 0x5b, 0x84, 0x41, 0x33, 0x9f, 0x42, 0xf3, 0x1d, 0x5d, 0x15, 0x6d, 0x76, 0x33, 0x36, 0xaf, 0xe9, 0xdd, 0xfa, 0x63, 0x4f, 0x7a, 0x9c, 0xeb, 0x1c, 0x4f, 0x34, 0x65, 0x07, 0x54, 0xbb, 0x4c, 0x8b, 0x62, 0x9d, 0xd0, 0x06, 0x99, 0xb3, 0xe9, 0xda, 0x85, 0x19, 0xb0, 0x3d, 0x3c},
+ subYX: fp.Elt{0xbb, 0x99, 0xf6, 0xbf, 0xaf, 0x2c, 0x22, 0x0d, 0x7a, 0xaa, 0x98, 0x6f, 0x01, 0x82, 0x99, 0xcf, 0x88, 0xbd, 0x0e, 0x3a, 0x89, 0xe0, 0x9c, 0x8c, 0x17, 0x20, 0xc4, 0xe0, 0xcf, 0x43, 0x7a, 0xef, 0x0d, 0x9f, 0x87, 0xd4, 0xfb, 0xf2, 0x96, 0xb8, 0x03, 0xe8, 0xcb, 0x5c, 0xec, 0x65, 0x5f, 0x49, 0xa4, 0x7c, 0x85, 0xb4, 0xf6, 0xc7, 0xdb, 0xa3},
+ dt2: fp.Elt{0x11, 0xf3, 0x32, 0xa3, 0xa7, 0xb2, 0x7d, 0x51, 0x82, 0x44, 0xeb, 0xa2, 0x7d, 0x72, 0xcb, 0xc6, 0xf6, 0xc7, 0xb2, 0x38, 0x0e, 0x0f, 0x4f, 0x29, 0x00, 0xe4, 0x5b, 0x94, 0x46, 0x86, 0x66, 0xa1, 0x83, 0xb3, 0xeb, 0x15, 0xb6, 0x31, 0x50, 0x28, 0xeb, 0xed, 0x0d, 0x32, 0x39, 0xe9, 0x23, 0x81, 0x99, 0x3e, 0xff, 0x17, 0x4c, 0x11, 0x43, 0xd1},
+ },
+ { /* 25P*/
+ addYX: fp.Elt{0xce, 0xe7, 0xf8, 0x94, 0x8f, 0x96, 0xf8, 0x96, 0xe6, 0x72, 0x20, 0x44, 0x2c, 0xa7, 0xfc, 0xba, 0xc8, 0xe1, 0xbb, 0xc9, 0x16, 0x85, 0xcd, 0x0b, 0xe5, 0xb5, 0x5a, 0x7f, 0x51, 0x43, 0x63, 0x8b, 0x23, 0x8e, 0x1d, 0x31, 0xff, 0x46, 0x02, 0x66, 0xcc, 0x9e, 0x4d, 0xa2, 0xca, 0xe2, 0xc7, 0xfd, 0x22, 0xb1, 0xdb, 0xdf, 0x6f, 0xe6, 0xa5, 0x82},
+ subYX: fp.Elt{0xd0, 0xf5, 0x65, 0x40, 0xec, 0x8e, 0x65, 0x42, 0x78, 0xc1, 0x65, 0xe4, 0x10, 0xc8, 0x0b, 0x1b, 0xdd, 0x96, 0x68, 0xce, 0xee, 0x45, 0x55, 0xd8, 0x6e, 0xd3, 0xe6, 0x77, 0x19, 0xae, 0xc2, 0x8d, 0x8d, 0x3e, 0x14, 0x3f, 0x6d, 0x00, 0x2f, 0x9b, 0xd1, 0x26, 0x60, 0x28, 0x0f, 0x3a, 0x47, 0xb3, 0xe6, 0x68, 0x28, 0x24, 0x25, 0xca, 0xc8, 0x06},
+ dt2: fp.Elt{0x54, 0xbb, 0x60, 0x92, 0xdb, 0x8f, 0x0f, 0x38, 0xe0, 0xe6, 0xe4, 0xc9, 0xcc, 0x14, 0x62, 0x01, 0xc4, 0x2b, 0x0f, 0xcf, 0xed, 0x7d, 0x8e, 0xa4, 0xd9, 0x73, 0x0b, 0xba, 0x0c, 0xaf, 0x0c, 0xf9, 0xe2, 0xeb, 0x29, 0x2a, 0x53, 0xdf, 0x2c, 0x5a, 0xfa, 0x8f, 0xc1, 0x01, 0xd7, 0xb1, 0x45, 0x73, 0x92, 0x32, 0x83, 0x85, 0x12, 0x74, 0x89, 0x44},
+ },
+ { /* 27P*/
+ addYX: fp.Elt{0x0b, 0x73, 0x3c, 0xc2, 0xb1, 0x2e, 0xe1, 0xa7, 0xf5, 0xc9, 0x7a, 0xfb, 0x3d, 0x2d, 0xac, 0x59, 0xdb, 0xfa, 0x36, 0x11, 0xd1, 0x13, 0x04, 0x51, 0x1d, 0xab, 0x9b, 0x6b, 0x93, 0xfe, 0xda, 0xb0, 0x8e, 0xb4, 0x79, 0x11, 0x21, 0x0f, 0x65, 0xb9, 0xbb, 0x79, 0x96, 0x2a, 0xfd, 0x30, 0xe0, 0xb4, 0x2d, 0x9a, 0x55, 0x25, 0x5d, 0xd4, 0xad, 0x2a},
+ subYX: fp.Elt{0x9e, 0xc5, 0x04, 0xfe, 0xec, 0x3c, 0x64, 0x1c, 0xed, 0x95, 0xed, 0xae, 0xaf, 0x5c, 0x6e, 0x08, 0x9e, 0x02, 0x29, 0x59, 0x7e, 0x5f, 0xc4, 0x9a, 0xd5, 0x32, 0x72, 0x86, 0xe1, 0x4e, 0x3c, 0xce, 0x99, 0x69, 0x3b, 0xc4, 0xdd, 0x4d, 0xb7, 0xbb, 0xda, 0x3b, 0x1a, 0x99, 0xaa, 0x62, 0x15, 0xc1, 0xf0, 0xb6, 0x6c, 0xec, 0x56, 0xc1, 0xff, 0x0c},
+ dt2: fp.Elt{0x2f, 0xf1, 0x3f, 0x7a, 0x2d, 0x56, 0x19, 0x7f, 0xea, 0xbe, 0x59, 0x2e, 0x13, 0x67, 0x81, 0xfb, 0xdb, 0xc8, 0xa3, 0x1d, 0xd5, 0xe9, 0x13, 0x8b, 0x29, 0xdf, 0xcf, 0x9f, 0xe7, 0xd9, 0x0b, 0x70, 0xd3, 0x15, 0x57, 0x4a, 0xe9, 0x50, 0x12, 0x1b, 0x81, 0x4b, 0x98, 0x98, 0xa8, 0x31, 0x1d, 0x27, 0x47, 0x38, 0xed, 0x57, 0x99, 0x26, 0xb2, 0xee},
+ },
+ { /* 29P*/
+ addYX: fp.Elt{0x1c, 0xb2, 0xb2, 0x67, 0x3b, 0x8b, 0x3d, 0x5a, 0x30, 0x7e, 0x38, 0x7e, 0x3c, 0x3d, 0x28, 0x56, 0x59, 0xd8, 0x87, 0x53, 0x8b, 0xe6, 0x6c, 0x5d, 0xe5, 0x0a, 0x33, 0x10, 0xce, 0xa2, 0x17, 0x0d, 0xe8, 0x76, 0xee, 0x68, 0xa8, 0x72, 0x54, 0xbd, 0xa6, 0x24, 0x94, 0x6e, 0x77, 0xc7, 0x53, 0xb7, 0x89, 0x1c, 0x7a, 0xe9, 0x78, 0x9a, 0x74, 0x5f},
+ subYX: fp.Elt{0x76, 0x96, 0x1c, 0xcf, 0x08, 0x55, 0xd8, 0x1e, 0x0d, 0xa3, 0x59, 0x95, 0x32, 0xf4, 0xc2, 0x8e, 0x84, 0x5e, 0x4b, 0x04, 0xda, 0x71, 0xc9, 0x78, 0x52, 0xde, 0x14, 0xb4, 0x31, 0xf4, 0xd4, 0xb8, 0x58, 0xc5, 0x20, 0xe8, 0xdd, 0x15, 0xb5, 0xee, 0xea, 0x61, 0xe0, 0xf5, 0xd6, 0xae, 0x55, 0x59, 0x05, 0x3e, 0xaf, 0x74, 0xac, 0x1f, 0x17, 0x82},
+ dt2: fp.Elt{0x59, 0x24, 0xcd, 0xfc, 0x11, 0x7e, 0x85, 0x18, 0x3d, 0x69, 0xf7, 0x71, 0x31, 0x66, 0x98, 0x42, 0x95, 0x00, 0x8c, 0xb2, 0xae, 0x39, 0x7e, 0x85, 0xd6, 0xb0, 0x02, 0xec, 0xce, 0xfc, 0x25, 0xb2, 0xe3, 0x99, 0x8e, 0x5b, 0x61, 0x96, 0x2e, 0x6d, 0x96, 0x57, 0x71, 0xa5, 0x93, 0x41, 0x0e, 0x6f, 0xfd, 0x0a, 0xbf, 0xa9, 0xf7, 0x56, 0xa9, 0x3e},
+ },
+ { /* 31P*/
+ addYX: fp.Elt{0xa2, 0x2e, 0x0c, 0x17, 0x4d, 0xcc, 0x85, 0x2c, 0x18, 0xa0, 0xd2, 0x08, 0xba, 0x11, 0xfa, 0x47, 0x71, 0x86, 0xaf, 0x36, 0x6a, 0xd7, 0xfe, 0xb9, 0xb0, 0x2f, 0x89, 0x98, 0x49, 0x69, 0xf8, 0x6a, 0xad, 0x27, 0x5e, 0x0a, 0x22, 0x60, 0x5e, 0x5d, 0xca, 0x06, 0x51, 0x27, 0x99, 0x29, 0x85, 0x68, 0x98, 0xe1, 0xc4, 0x21, 0x50, 0xa0, 0xe9, 0xc1},
+ subYX: fp.Elt{0x4d, 0x70, 0xee, 0x91, 0x92, 0x3f, 0xb7, 0xd3, 0x1d, 0xdb, 0x8d, 0x6e, 0x16, 0xf5, 0x65, 0x7d, 0x5f, 0xb5, 0x6c, 0x59, 0x26, 0x70, 0x4b, 0xf2, 0xfc, 0xe7, 0xdf, 0x86, 0xfe, 0xa5, 0xa7, 0xa6, 0x5d, 0xfb, 0x06, 0xe9, 0xf9, 0xcc, 0xc0, 0x37, 0xcc, 0xd8, 0x09, 0x04, 0xd2, 0xa5, 0x1d, 0xd7, 0xb7, 0xce, 0x92, 0xac, 0x3c, 0xad, 0xfb, 0xae},
+ dt2: fp.Elt{0x17, 0xa3, 0x9a, 0xc7, 0x86, 0x2a, 0x51, 0xf7, 0x96, 0x79, 0x49, 0x22, 0x2e, 0x5a, 0x01, 0x5c, 0xb5, 0x95, 0xd4, 0xe8, 0xcb, 0x00, 0xca, 0x2d, 0x55, 0xb6, 0x34, 0x36, 0x0b, 0x65, 0x46, 0xf0, 0x49, 0xfc, 0x87, 0x86, 0xe5, 0xc3, 0x15, 0xdb, 0x32, 0xcd, 0xf2, 0xd3, 0x82, 0x4c, 0xe6, 0x61, 0x8a, 0xaf, 0xd4, 0x9e, 0x0f, 0x5a, 0xf2, 0x81},
+ },
+ { /* 33P*/
+ addYX: fp.Elt{0x88, 0x10, 0xc0, 0xcb, 0xf5, 0x77, 0xae, 0xa5, 0xbe, 0xf6, 0xcd, 0x2e, 0x8b, 0x7e, 0xbd, 0x79, 0x62, 0x4a, 0xeb, 0x69, 0xc3, 0x28, 0xaa, 0x72, 0x87, 0xa9, 0x25, 0x87, 0x46, 0xea, 0x0e, 0x62, 0xa3, 0x6a, 0x1a, 0xe2, 0xba, 0xdc, 0x81, 0x10, 0x33, 0x01, 0xf6, 0x16, 0x89, 0x80, 0xc6, 0xcd, 0xdb, 0xdc, 0xba, 0x0e, 0x09, 0x4a, 0x35, 0x4a},
+ subYX: fp.Elt{0x86, 0xb2, 0x2b, 0xd0, 0xb8, 0x4a, 0x6d, 0x66, 0x7b, 0x32, 0xdf, 0x3b, 0x1a, 0x19, 0x1f, 0x63, 0xee, 0x1f, 0x3d, 0x1c, 0x5c, 0x14, 0x60, 0x5b, 0x72, 0x49, 0x07, 0xb1, 0x0d, 0x72, 0xc6, 0x35, 0xf0, 0xbc, 0x5e, 0xda, 0x80, 0x6b, 0x64, 0x5b, 0xe5, 0x34, 0x54, 0x39, 0xdd, 0xe6, 0x3c, 0xcb, 0xe5, 0x29, 0x32, 0x06, 0xc6, 0xb1, 0x96, 0x34},
+ dt2: fp.Elt{0x85, 0x86, 0xf5, 0x84, 0x86, 0xe6, 0x77, 0x8a, 0x71, 0x85, 0x0c, 0x4f, 0x81, 0x5b, 0x29, 0x06, 0xb5, 0x2e, 0x26, 0x71, 0x07, 0x78, 0x07, 0xae, 0xbc, 0x95, 0x46, 0xc3, 0x65, 0xac, 0xe3, 0x76, 0x51, 0x7d, 0xd4, 0x85, 0x31, 0xe3, 0x43, 0xf3, 0x1b, 0x7c, 0xf7, 0x6b, 0x2c, 0xf8, 0x1c, 0xbb, 0x8d, 0xca, 0xab, 0x4b, 0xba, 0x7f, 0xa4, 0xe2},
+ },
+ { /* 35P*/
+ addYX: fp.Elt{0x1a, 0xee, 0xe7, 0xa4, 0x8a, 0x9d, 0x53, 0x80, 0xc6, 0xb8, 0x4e, 0xdc, 0x89, 0xe0, 0xc4, 0x2b, 0x60, 0x52, 0x6f, 0xec, 0x81, 0xd2, 0x55, 0x6b, 0x1b, 0x6f, 0x17, 0x67, 0x8e, 0x42, 0x26, 0x4c, 0x65, 0x23, 0x29, 0xc6, 0x7b, 0xcd, 0x9f, 0xad, 0x4b, 0x42, 0xd3, 0x0c, 0x75, 0xc3, 0x8a, 0xf5, 0xbe, 0x9e, 0x55, 0xf7, 0x47, 0x5d, 0xbd, 0x3a},
+ subYX: fp.Elt{0x0d, 0xa8, 0x3b, 0xf9, 0xc7, 0x7e, 0xc6, 0x86, 0x94, 0xc0, 0x01, 0xff, 0x27, 0xce, 0x43, 0xac, 0xe5, 0xe1, 0xd2, 0x8d, 0xc1, 0x22, 0x31, 0xbe, 0xe1, 0xaf, 0xf9, 0x4a, 0x78, 0xa1, 0x0c, 0xaa, 0xd4, 0x80, 0xe4, 0x09, 0x8d, 0xfb, 0x1d, 0x52, 0xc8, 0x60, 0x2d, 0xf2, 0xa2, 0x89, 0x02, 0x56, 0x3d, 0x56, 0x27, 0x85, 0xc7, 0xf0, 0x2b, 0x9a},
+ dt2: fp.Elt{0x62, 0x7c, 0xc7, 0x6b, 0x2c, 0x9d, 0x0a, 0x7c, 0xe5, 0x50, 0x3c, 0xe6, 0x87, 0x1c, 0x82, 0x30, 0x67, 0x3c, 0x39, 0xb6, 0xa0, 0x31, 0xfb, 0x03, 0x7b, 0xa1, 0x58, 0xdf, 0x12, 0x76, 0x5d, 0x5d, 0x0a, 0x8f, 0x9b, 0x37, 0x32, 0xc3, 0x60, 0x33, 0xea, 0x9f, 0x0a, 0x99, 0xfa, 0x20, 0xd0, 0x33, 0x21, 0xc3, 0x94, 0xd4, 0x86, 0x49, 0x7c, 0x4e},
+ },
+ { /* 37P*/
+ addYX: fp.Elt{0xc7, 0x0c, 0x71, 0xfe, 0x55, 0xd1, 0x95, 0x8f, 0x43, 0xbb, 0x6b, 0x74, 0x30, 0xbd, 0xe8, 0x6f, 0x1c, 0x1b, 0x06, 0x62, 0xf5, 0xfc, 0x65, 0xa0, 0xeb, 0x81, 0x12, 0xc9, 0x64, 0x66, 0x61, 0xde, 0xf3, 0x6d, 0xd4, 0xae, 0x8e, 0xb1, 0x72, 0xe0, 0xcd, 0x37, 0x01, 0x28, 0x52, 0xd7, 0x39, 0x46, 0x0c, 0x55, 0xcf, 0x47, 0x70, 0xef, 0xa1, 0x17},
+ subYX: fp.Elt{0x8d, 0x58, 0xde, 0x83, 0x88, 0x16, 0x0e, 0x12, 0x42, 0x03, 0x50, 0x60, 0x4b, 0xdf, 0xbf, 0x95, 0xcc, 0x7d, 0x18, 0x17, 0x7e, 0x31, 0x5d, 0x8a, 0x66, 0xc1, 0xcf, 0x14, 0xea, 0xf4, 0xf4, 0xe5, 0x63, 0x2d, 0x32, 0x86, 0x9b, 0xed, 0x1f, 0x4f, 0x03, 0xaf, 0x33, 0x92, 0xcb, 0xaf, 0x9c, 0x05, 0x0d, 0x47, 0x1b, 0x42, 0xba, 0x13, 0x22, 0x98},
+ dt2: fp.Elt{0xb5, 0x48, 0xeb, 0x7d, 0x3d, 0x10, 0x9f, 0x59, 0xde, 0xf8, 0x1c, 0x4f, 0x7d, 0x9d, 0x40, 0x4d, 0x9e, 0x13, 0x24, 0xb5, 0x21, 0x09, 0xb7, 0xee, 0x98, 0x5c, 0x56, 0xbc, 0x5e, 0x2b, 0x78, 0x38, 0x06, 0xac, 0xe3, 0xe0, 0xfa, 0x2e, 0xde, 0x4f, 0xd2, 0xb3, 0xfb, 0x2d, 0x71, 0x84, 0xd1, 0x9d, 0x12, 0x5b, 0x35, 0xc8, 0x03, 0x68, 0x67, 0xc7},
+ },
+ { /* 39P*/
+ addYX: fp.Elt{0xb6, 0x65, 0xfb, 0xa7, 0x06, 0x35, 0xbb, 0xe0, 0x31, 0x8d, 0x91, 0x40, 0x98, 0xab, 0x30, 0xe4, 0xca, 0x12, 0x59, 0x89, 0xed, 0x65, 0x5d, 0x7f, 0xae, 0x69, 0xa0, 0xa4, 0xfa, 0x78, 0xb4, 0xf7, 0xed, 0xae, 0x86, 0x78, 0x79, 0x64, 0x24, 0xa6, 0xd4, 0xe1, 0xf6, 0xd3, 0xa0, 0x89, 0xba, 0x20, 0xf4, 0x54, 0x0d, 0x8f, 0xdb, 0x1a, 0x79, 0xdb},
+ subYX: fp.Elt{0xe1, 0x82, 0x0c, 0x4d, 0xde, 0x9f, 0x40, 0xf0, 0xc1, 0xbd, 0x8b, 0xd3, 0x24, 0x03, 0xcd, 0xf2, 0x92, 0x7d, 0xe2, 0x68, 0x7f, 0xf1, 0xbe, 0x69, 0xde, 0x34, 0x67, 0x4c, 0x85, 0x3b, 0xec, 0x98, 0xcc, 0x4d, 0x3e, 0xc0, 0x96, 0x27, 0xe6, 0x75, 0xfc, 0xdf, 0x37, 0xc0, 0x1e, 0x27, 0xe0, 0xf6, 0xc2, 0xbd, 0xbc, 0x3d, 0x9b, 0x39, 0xdc, 0xe2},
+ dt2: fp.Elt{0xd8, 0x29, 0xa7, 0x39, 0xe3, 0x9f, 0x2f, 0x0e, 0x4b, 0x24, 0x21, 0x70, 0xef, 0xfd, 0x91, 0xea, 0xbf, 0xe1, 0x72, 0x90, 0xcc, 0xc9, 0x84, 0x0e, 0xad, 0xd5, 0xe6, 0xbb, 0xc5, 0x99, 0x7f, 0xa4, 0xf0, 0x2e, 0xcc, 0x95, 0x64, 0x27, 0x19, 0xd8, 0x4c, 0x27, 0x0d, 0xff, 0xb6, 0x29, 0xe2, 0x6c, 0xfa, 0xbb, 0x4d, 0x9c, 0xbb, 0xaf, 0xa5, 0xec},
+ },
+ { /* 41P*/
+ addYX: fp.Elt{0xd6, 0x33, 0x3f, 0x9f, 0xcf, 0xfd, 0x4c, 0xd1, 0xfe, 0xe5, 0xeb, 0x64, 0x27, 0xae, 0x7a, 0xa2, 0x82, 0x50, 0x6d, 0xaa, 0xe3, 0x5d, 0xe2, 0x48, 0x60, 0xb3, 0x76, 0x04, 0xd9, 0x19, 0xa7, 0xa1, 0x73, 0x8d, 0x38, 0xa9, 0xaf, 0x45, 0xb5, 0xb2, 0x62, 0x9b, 0xf1, 0x35, 0x7b, 0x84, 0x66, 0xeb, 0x06, 0xef, 0xf1, 0xb2, 0x2d, 0x6a, 0x61, 0x15},
+ subYX: fp.Elt{0x86, 0x50, 0x42, 0xf7, 0xda, 0x59, 0xb2, 0xcf, 0x0d, 0x3d, 0xee, 0x8e, 0x53, 0x5d, 0xf7, 0x9e, 0x6a, 0x26, 0x2d, 0xc7, 0x8c, 0x8e, 0x18, 0x50, 0x6d, 0xb7, 0x51, 0x4c, 0xa7, 0x52, 0x6e, 0x0e, 0x0a, 0x16, 0x74, 0xb2, 0x81, 0x8b, 0x56, 0x27, 0x22, 0x84, 0xf4, 0x56, 0xc5, 0x06, 0xe1, 0x8b, 0xca, 0x2d, 0xdb, 0x9a, 0xf6, 0x10, 0x9c, 0x51},
+ dt2: fp.Elt{0x1f, 0x16, 0xa2, 0x78, 0x96, 0x1b, 0x85, 0x9c, 0x76, 0x49, 0xd4, 0x0f, 0xac, 0xb0, 0xf4, 0xd0, 0x06, 0x2c, 0x7e, 0x6d, 0x6e, 0x8e, 0xc7, 0x9f, 0x18, 0xad, 0xfc, 0x88, 0x0c, 0x0c, 0x09, 0x05, 0x05, 0xa0, 0x79, 0x72, 0x32, 0x72, 0x87, 0x0f, 0x49, 0x87, 0x0c, 0xb4, 0x12, 0xc2, 0x09, 0xf8, 0x9f, 0x30, 0x72, 0xa9, 0x47, 0x13, 0x93, 0x49},
+ },
+ { /* 43P*/
+ addYX: fp.Elt{0xcc, 0xb1, 0x4c, 0xd3, 0xc0, 0x9e, 0x9e, 0x4d, 0x6d, 0x28, 0x0b, 0xa5, 0x94, 0xa7, 0x2e, 0xc2, 0xc7, 0xaf, 0x29, 0x73, 0xc9, 0x68, 0xea, 0x0f, 0x34, 0x37, 0x8d, 0x96, 0x8f, 0x3a, 0x3d, 0x73, 0x1e, 0x6d, 0x9f, 0xcf, 0x8d, 0x83, 0xb5, 0x71, 0xb9, 0xe1, 0x4b, 0x67, 0x71, 0xea, 0xcf, 0x56, 0xe5, 0xeb, 0x72, 0x15, 0x2f, 0x9e, 0xa8, 0xaa},
+ subYX: fp.Elt{0xf4, 0x3e, 0x85, 0x1c, 0x1a, 0xef, 0x50, 0xd1, 0xb4, 0x20, 0xb2, 0x60, 0x05, 0x98, 0xfe, 0x47, 0x3b, 0xc1, 0x76, 0xca, 0x2c, 0x4e, 0x5a, 0x42, 0xa3, 0xf7, 0x20, 0xaa, 0x57, 0x39, 0xee, 0x34, 0x1f, 0xe1, 0x68, 0xd3, 0x7e, 0x06, 0xc4, 0x6c, 0xc7, 0x76, 0x2b, 0xe4, 0x1c, 0x48, 0x44, 0xe6, 0xe5, 0x44, 0x24, 0x8d, 0xb3, 0xb6, 0x88, 0x32},
+ dt2: fp.Elt{0x18, 0xa7, 0xba, 0xd0, 0x44, 0x6f, 0x33, 0x31, 0x00, 0xf8, 0xf6, 0x12, 0xe3, 0xc5, 0xc7, 0xb5, 0x91, 0x9c, 0x91, 0xb5, 0x75, 0x18, 0x18, 0x8a, 0xab, 0xed, 0x24, 0x11, 0x2e, 0xce, 0x5a, 0x0f, 0x94, 0x5f, 0x2e, 0xca, 0xd3, 0x80, 0xea, 0xe5, 0x34, 0x96, 0x67, 0x8b, 0x6a, 0x26, 0x5e, 0xc8, 0x9d, 0x2c, 0x5e, 0x6c, 0xa2, 0x0c, 0xbf, 0xf0},
+ },
+ { /* 45P*/
+ addYX: fp.Elt{0xb3, 0xbf, 0xa3, 0x85, 0xee, 0xf6, 0x58, 0x02, 0x78, 0xc4, 0x30, 0xd6, 0x57, 0x59, 0x8c, 0x88, 0x08, 0x7c, 0xbc, 0xbe, 0x0a, 0x74, 0xa9, 0xde, 0x69, 0xe7, 0x41, 0xd8, 0xbf, 0x66, 0x8d, 0x3d, 0x28, 0x00, 0x8c, 0x47, 0x65, 0x34, 0xfe, 0x86, 0x9e, 0x6a, 0xf2, 0x41, 0x6a, 0x94, 0xc4, 0x88, 0x75, 0x23, 0x0d, 0x52, 0x69, 0xee, 0x07, 0x89},
+ subYX: fp.Elt{0x22, 0x3c, 0xa1, 0x70, 0x58, 0x97, 0x93, 0xbe, 0x59, 0xa8, 0x0b, 0x8a, 0x46, 0x2a, 0x38, 0x1e, 0x08, 0x6b, 0x61, 0x9f, 0xf2, 0x4a, 0x8b, 0x80, 0x68, 0x6e, 0xc8, 0x92, 0x60, 0xf3, 0xc9, 0x89, 0xb2, 0x6d, 0x63, 0xb0, 0xeb, 0x83, 0x15, 0x63, 0x0e, 0x64, 0xbb, 0xb8, 0xfe, 0xb4, 0x81, 0x90, 0x01, 0x28, 0x10, 0xb9, 0x74, 0x6e, 0xde, 0xa4},
+ dt2: fp.Elt{0x1a, 0x23, 0x45, 0xa8, 0x6f, 0x4e, 0xa7, 0x4a, 0x0c, 0xeb, 0xb0, 0x43, 0xf9, 0xef, 0x99, 0x60, 0x5b, 0xdb, 0x66, 0xc0, 0x86, 0x71, 0x43, 0xb1, 0x22, 0x7b, 0x1c, 0xe7, 0x8d, 0x09, 0x1d, 0x83, 0x76, 0x9c, 0xd3, 0x5a, 0xdd, 0x42, 0xd9, 0x2f, 0x2d, 0xba, 0x7a, 0xc2, 0xd9, 0x6b, 0xd4, 0x7a, 0xf1, 0xd5, 0x5f, 0x6b, 0x85, 0xbf, 0x0b, 0xf1},
+ },
+ { /* 47P*/
+ addYX: fp.Elt{0xb2, 0x83, 0xfa, 0x1f, 0xd2, 0xce, 0xb6, 0xf2, 0x2d, 0xea, 0x1b, 0xe5, 0x29, 0xa5, 0x72, 0xf9, 0x25, 0x48, 0x4e, 0xf2, 0x50, 0x1b, 0x39, 0xda, 0x34, 0xc5, 0x16, 0x13, 0xb4, 0x0c, 0xa1, 0x00, 0x79, 0x7a, 0xf5, 0x8b, 0xf3, 0x70, 0x14, 0xb6, 0xfc, 0x9a, 0x47, 0x68, 0x1e, 0x42, 0x70, 0x64, 0x2a, 0x84, 0x3e, 0x3d, 0x20, 0x58, 0xf9, 0x6a},
+ subYX: fp.Elt{0xd9, 0xee, 0xc0, 0xc4, 0xf5, 0xc2, 0x86, 0xaf, 0x45, 0xd2, 0xd2, 0x87, 0x1b, 0x64, 0xd5, 0xe0, 0x8c, 0x44, 0x00, 0x4f, 0x43, 0x89, 0x04, 0x48, 0x4a, 0x0b, 0xca, 0x94, 0x06, 0x2f, 0x23, 0x5b, 0x6c, 0x8d, 0x44, 0x66, 0x53, 0xf5, 0x5a, 0x20, 0x72, 0x28, 0x58, 0x84, 0xcc, 0x73, 0x22, 0x5e, 0xd1, 0x0b, 0x56, 0x5e, 0x6a, 0xa3, 0x11, 0x91},
+ dt2: fp.Elt{0x6e, 0x9f, 0x88, 0xa8, 0x68, 0x2f, 0x12, 0x37, 0x88, 0xfc, 0x92, 0x8f, 0x24, 0xeb, 0x5b, 0x2a, 0x2a, 0xd0, 0x14, 0x40, 0x4c, 0xa9, 0xa4, 0x03, 0x0c, 0x45, 0x48, 0x13, 0xe8, 0xa6, 0x37, 0xab, 0xc0, 0x06, 0x38, 0x6c, 0x96, 0x73, 0x40, 0x6c, 0xc6, 0xea, 0x56, 0xc6, 0xe9, 0x1a, 0x69, 0xeb, 0x7a, 0xd1, 0x33, 0x69, 0x58, 0x2b, 0xea, 0x2f},
+ },
+ { /* 49P*/
+ addYX: fp.Elt{0x58, 0xa8, 0x05, 0x41, 0x00, 0x9d, 0xaa, 0xd9, 0x98, 0xcf, 0xb9, 0x41, 0xb5, 0x4a, 0x8d, 0xe2, 0xe7, 0xc0, 0x72, 0xef, 0xc8, 0x28, 0x6b, 0x68, 0x9d, 0xc9, 0xdf, 0x05, 0x8b, 0xd0, 0x04, 0x74, 0x79, 0x45, 0x52, 0x05, 0xa3, 0x6e, 0x35, 0x3a, 0xe3, 0xef, 0xb2, 0xdc, 0x08, 0x6f, 0x4e, 0x76, 0x85, 0x67, 0xba, 0x23, 0x8f, 0xdd, 0xaf, 0x09},
+ subYX: fp.Elt{0xb4, 0x38, 0xc8, 0xff, 0x4f, 0x65, 0x2a, 0x7e, 0xad, 0xb1, 0xc6, 0xb9, 0x3d, 0xd6, 0xf7, 0x14, 0xcf, 0xf6, 0x98, 0x75, 0xbb, 0x47, 0x83, 0x90, 0xe7, 0xe1, 0xf6, 0x14, 0x99, 0x7e, 0xfa, 0xe4, 0x77, 0x24, 0xe3, 0xe7, 0xf0, 0x1e, 0xdb, 0x27, 0x4e, 0x16, 0x04, 0xf2, 0x08, 0x52, 0xfc, 0xec, 0x55, 0xdb, 0x2e, 0x67, 0xe1, 0x94, 0x32, 0x89},
+ dt2: fp.Elt{0x00, 0xad, 0x03, 0x35, 0x1a, 0xb1, 0x88, 0xf0, 0xc9, 0x11, 0xe4, 0x12, 0x52, 0x61, 0xfd, 0x8a, 0x1b, 0x6a, 0x0a, 0x4c, 0x42, 0x46, 0x22, 0x0e, 0xa5, 0xf9, 0xe2, 0x50, 0xf2, 0xb2, 0x1f, 0x20, 0x78, 0x10, 0xf6, 0xbf, 0x7f, 0x0c, 0x9c, 0xad, 0x40, 0x8b, 0x82, 0xd4, 0xba, 0x69, 0x09, 0xac, 0x4b, 0x6d, 0xc4, 0x49, 0x17, 0x81, 0x57, 0x3b},
+ },
+ { /* 51P*/
+ addYX: fp.Elt{0x0d, 0xfe, 0xb4, 0x35, 0x11, 0xbd, 0x1d, 0x6b, 0xc2, 0xc5, 0x3b, 0xd2, 0x23, 0x2c, 0x72, 0xe3, 0x48, 0xb1, 0x48, 0x73, 0xfb, 0xa3, 0x21, 0x6e, 0xc0, 0x09, 0x69, 0xac, 0xe1, 0x60, 0xbc, 0x24, 0x03, 0x99, 0x63, 0x0a, 0x00, 0xf0, 0x75, 0xf6, 0x92, 0xc5, 0xd6, 0xdb, 0x51, 0xd4, 0x7d, 0xe6, 0xf4, 0x11, 0x79, 0xd7, 0xc3, 0xaf, 0x48, 0xd0},
+ subYX: fp.Elt{0xf4, 0x4f, 0xaf, 0x31, 0xe3, 0x10, 0x89, 0x95, 0xf0, 0x8a, 0xf6, 0x31, 0x9f, 0x48, 0x02, 0xba, 0x42, 0x2b, 0x3c, 0x22, 0x8b, 0xcc, 0x12, 0x98, 0x6e, 0x7a, 0x64, 0x3a, 0xc4, 0xca, 0x32, 0x2a, 0x72, 0xf8, 0x2c, 0xcf, 0x78, 0x5e, 0x7a, 0x75, 0x6e, 0x72, 0x46, 0x48, 0x62, 0x28, 0xac, 0x58, 0x1a, 0xc6, 0x59, 0x88, 0x2a, 0x44, 0x9e, 0x83},
+ dt2: fp.Elt{0xb3, 0xde, 0x36, 0xfd, 0xeb, 0x1b, 0xd4, 0x24, 0x1b, 0x08, 0x8c, 0xfe, 0xa9, 0x41, 0xa1, 0x64, 0xf2, 0x6d, 0xdb, 0xf9, 0x94, 0xae, 0x86, 0x71, 0xab, 0x10, 0xbf, 0xa3, 0xb2, 0xa0, 0xdf, 0x10, 0x8c, 0x74, 0xce, 0xb3, 0xfc, 0xdb, 0xba, 0x15, 0xf6, 0x91, 0x7a, 0x9c, 0x36, 0x1e, 0x45, 0x07, 0x3c, 0xec, 0x1a, 0x61, 0x26, 0x93, 0xe3, 0x50},
+ },
+ { /* 53P*/
+ addYX: fp.Elt{0xc5, 0x50, 0xc5, 0x83, 0xb0, 0xbd, 0xd9, 0xf6, 0x6d, 0x15, 0x5e, 0xc1, 0x1a, 0x33, 0xa0, 0xce, 0x13, 0x70, 0x3b, 0xe1, 0x31, 0xc6, 0xc4, 0x02, 0xec, 0x8c, 0xd5, 0x9c, 0x97, 0xd3, 0x12, 0xc4, 0xa2, 0xf9, 0xd5, 0xfb, 0x22, 0x69, 0x94, 0x09, 0x2f, 0x59, 0xce, 0xdb, 0xf2, 0xf2, 0x00, 0xe0, 0xa9, 0x08, 0x44, 0x2e, 0x8b, 0x6b, 0xf5, 0xb3},
+ subYX: fp.Elt{0x90, 0xdd, 0xec, 0xa2, 0x65, 0xb7, 0x61, 0xbc, 0xaa, 0x70, 0xa2, 0x15, 0xd8, 0xb0, 0xf8, 0x8e, 0x23, 0x3d, 0x9f, 0x46, 0xa3, 0x29, 0x20, 0xd1, 0xa1, 0x15, 0x81, 0xc6, 0xb6, 0xde, 0xbe, 0x60, 0x63, 0x24, 0xac, 0x15, 0xfb, 0xeb, 0xd3, 0xea, 0x57, 0x13, 0x86, 0x38, 0x1e, 0x22, 0xf4, 0x8c, 0x5d, 0xaf, 0x1b, 0x27, 0x21, 0x4f, 0xa3, 0x63},
+ dt2: fp.Elt{0x07, 0x15, 0x87, 0xc4, 0xfd, 0xa1, 0x97, 0x7a, 0x07, 0x1f, 0x56, 0xcc, 0xe3, 0x6a, 0x01, 0x90, 0xce, 0xf9, 0xfa, 0x50, 0xb2, 0xe0, 0x87, 0x8b, 0x6c, 0x63, 0x6c, 0xf6, 0x2a, 0x09, 0xef, 0xef, 0xd2, 0x31, 0x40, 0x25, 0xf6, 0x84, 0xcb, 0xe0, 0xc4, 0x23, 0xc1, 0xcb, 0xe2, 0x02, 0x83, 0x2d, 0xed, 0x74, 0x74, 0x8b, 0xf8, 0x7c, 0x81, 0x18},
+ },
+ { /* 55P*/
+ addYX: fp.Elt{0x9e, 0xe5, 0x59, 0x95, 0x63, 0x2e, 0xac, 0x8b, 0x03, 0x3c, 0xc1, 0x8e, 0xe1, 0x5b, 0x56, 0x3c, 0x16, 0x41, 0xe4, 0xc2, 0x60, 0x0c, 0x6d, 0x65, 0x9f, 0xfc, 0x27, 0x68, 0x43, 0x44, 0x05, 0x12, 0x6c, 0xda, 0x04, 0xef, 0xcf, 0xcf, 0xdc, 0x0a, 0x1a, 0x7f, 0x12, 0xd3, 0xeb, 0x02, 0xb6, 0x04, 0xca, 0xd6, 0xcb, 0xf0, 0x22, 0xba, 0x35, 0x6d},
+ subYX: fp.Elt{0x09, 0x6d, 0xf9, 0x64, 0x4c, 0xe6, 0x41, 0xff, 0x01, 0x4d, 0xce, 0x1e, 0xfa, 0x38, 0xa2, 0x25, 0x62, 0xff, 0x03, 0x39, 0x18, 0x91, 0xbb, 0x9d, 0xce, 0x02, 0xf0, 0xf1, 0x3c, 0x55, 0x18, 0xa9, 0xab, 0x4d, 0xd2, 0x35, 0xfd, 0x8d, 0xa9, 0xb2, 0xad, 0xb7, 0x06, 0x6e, 0xc6, 0x69, 0x49, 0xd6, 0x98, 0x98, 0x0b, 0x22, 0x81, 0x6b, 0xbd, 0xa0},
+ dt2: fp.Elt{0x22, 0xf4, 0x85, 0x5d, 0x2b, 0xf1, 0x55, 0xa5, 0xd6, 0x27, 0x86, 0x57, 0x12, 0x1f, 0x16, 0x0a, 0x5a, 0x9b, 0xf2, 0x38, 0xb6, 0x28, 0xd8, 0x99, 0x0c, 0x89, 0x1d, 0x7f, 0xca, 0x21, 0x17, 0x1a, 0x0b, 0x02, 0x5f, 0x77, 0x2f, 0x73, 0x30, 0x7c, 0xc8, 0xd7, 0x2b, 0xcc, 0xe7, 0xf3, 0x21, 0xac, 0x53, 0xa7, 0x11, 0x5d, 0xd8, 0x1d, 0x9b, 0xf5},
+ },
+ { /* 57P*/
+ addYX: fp.Elt{0x94, 0x63, 0x5d, 0xef, 0xfd, 0x6d, 0x25, 0x4e, 0x6d, 0x29, 0x03, 0xed, 0x24, 0x28, 0x27, 0x57, 0x47, 0x3e, 0x6a, 0x1a, 0xfe, 0x37, 0xee, 0x5f, 0x83, 0x29, 0x14, 0xfd, 0x78, 0x25, 0x8a, 0xe1, 0x02, 0x38, 0xd8, 0xca, 0x65, 0x55, 0x40, 0x7d, 0x48, 0x2c, 0x7c, 0x7e, 0x60, 0xb6, 0x0c, 0x6d, 0xf7, 0xe8, 0xb3, 0x62, 0x53, 0xd6, 0x9c, 0x2b},
+ subYX: fp.Elt{0x47, 0x25, 0x70, 0x62, 0xf5, 0x65, 0x93, 0x62, 0x08, 0xac, 0x59, 0x66, 0xdb, 0x08, 0xd9, 0x1a, 0x19, 0xaf, 0xf4, 0xef, 0x02, 0xa2, 0x78, 0xa9, 0x55, 0x1c, 0xfa, 0x08, 0x11, 0xcb, 0xa3, 0x71, 0x74, 0xb1, 0x62, 0xe7, 0xc7, 0xf3, 0x5a, 0xb5, 0x8b, 0xd4, 0xf6, 0x10, 0x57, 0x79, 0x72, 0x2f, 0x13, 0x86, 0x7b, 0x44, 0x5f, 0x48, 0xfd, 0x88},
+ dt2: fp.Elt{0x10, 0x02, 0xcd, 0x05, 0x9a, 0xc3, 0x32, 0x6d, 0x10, 0x3a, 0x74, 0xba, 0x06, 0xc4, 0x3b, 0x34, 0xbc, 0x36, 0xed, 0xa3, 0xba, 0x9a, 0xdb, 0x6d, 0xd4, 0x69, 0x99, 0x97, 0xd0, 0xe4, 0xdd, 0xf5, 0xd4, 0x7c, 0xd3, 0x4e, 0xab, 0xd1, 0x3b, 0xbb, 0xe9, 0xc7, 0x6a, 0x94, 0x25, 0x61, 0xf0, 0x06, 0xc5, 0x12, 0xa8, 0x86, 0xe5, 0x35, 0x46, 0xeb},
+ },
+ { /* 59P*/
+ addYX: fp.Elt{0x9e, 0x95, 0x11, 0xc6, 0xc7, 0xe8, 0xee, 0x5a, 0x26, 0xa0, 0x72, 0x72, 0x59, 0x91, 0x59, 0x16, 0x49, 0x99, 0x7e, 0xbb, 0xd7, 0x15, 0xb4, 0xf2, 0x40, 0xf9, 0x5a, 0x4d, 0xc8, 0xa0, 0xe2, 0x34, 0x7b, 0x34, 0xf3, 0x99, 0xbf, 0xa9, 0xf3, 0x79, 0xc1, 0x1a, 0x0c, 0xf4, 0x86, 0x74, 0x4e, 0xcb, 0xbc, 0x90, 0xad, 0xb6, 0x51, 0x6d, 0xaa, 0x33},
+ subYX: fp.Elt{0x9f, 0xd1, 0xc5, 0xa2, 0x6c, 0x24, 0x88, 0x15, 0x71, 0x68, 0xf6, 0x07, 0x45, 0x02, 0xc4, 0x73, 0x7e, 0x75, 0x87, 0xca, 0x7c, 0xf0, 0x92, 0x00, 0x75, 0xd6, 0x5a, 0xdd, 0xe0, 0x64, 0x16, 0x9d, 0x62, 0x80, 0x33, 0x9f, 0xf4, 0x8e, 0x1a, 0x15, 0x1c, 0xd3, 0x0f, 0x4d, 0x4f, 0x62, 0x2d, 0xd7, 0xa5, 0x77, 0xe3, 0xea, 0xf0, 0xfb, 0x1a, 0xdb},
+ dt2: fp.Elt{0x6a, 0xa2, 0xb1, 0xaa, 0xfb, 0x5a, 0x32, 0x4e, 0xff, 0x47, 0x06, 0xd5, 0x9a, 0x4f, 0xce, 0x83, 0x5b, 0x82, 0x34, 0x3e, 0x47, 0xb8, 0xf8, 0xe9, 0x7c, 0x67, 0x69, 0x8d, 0x9c, 0xb7, 0xde, 0x57, 0xf4, 0x88, 0x41, 0x56, 0x0c, 0x87, 0x1e, 0xc9, 0x2f, 0x54, 0xbf, 0x5c, 0x68, 0x2c, 0xd9, 0xc4, 0xef, 0x53, 0x73, 0x1e, 0xa6, 0x38, 0x02, 0x10},
+ },
+ { /* 61P*/
+ addYX: fp.Elt{0x08, 0x80, 0x4a, 0xc9, 0xb7, 0xa8, 0x88, 0xd9, 0xfc, 0x6a, 0xc0, 0x3e, 0xc2, 0x33, 0x4d, 0x2b, 0x2a, 0xa3, 0x6d, 0x72, 0x3e, 0xdc, 0x34, 0x68, 0x08, 0xbf, 0x27, 0xef, 0xf4, 0xff, 0xe2, 0x0c, 0x31, 0x0c, 0xa2, 0x0a, 0x1f, 0x65, 0xc1, 0x4c, 0x61, 0xd3, 0x1b, 0xbc, 0x25, 0xb1, 0xd0, 0xd4, 0x89, 0xb2, 0x53, 0xfb, 0x43, 0xa5, 0xaf, 0x04},
+ subYX: fp.Elt{0xe3, 0xe1, 0x37, 0xad, 0x58, 0xa9, 0x55, 0x81, 0xee, 0x64, 0x21, 0xb9, 0xf5, 0x4c, 0x35, 0xea, 0x4a, 0xd3, 0x26, 0xaa, 0x90, 0xd4, 0x60, 0x46, 0x09, 0x4b, 0x4a, 0x62, 0xf9, 0xcd, 0xe1, 0xee, 0xbb, 0xc2, 0x09, 0x0b, 0xb0, 0x96, 0x8e, 0x43, 0x77, 0xaf, 0x25, 0x20, 0x5e, 0x47, 0xe4, 0x1d, 0x50, 0x69, 0x74, 0x08, 0xd7, 0xb9, 0x90, 0x13},
+ dt2: fp.Elt{0x51, 0x91, 0x95, 0x64, 0x03, 0x16, 0xfd, 0x6e, 0x26, 0x94, 0x6b, 0x61, 0xe7, 0xd9, 0xe0, 0x4a, 0x6d, 0x7c, 0xfa, 0xc0, 0xe2, 0x43, 0x23, 0x53, 0x70, 0xf5, 0x6f, 0x73, 0x8b, 0x81, 0xb0, 0x0c, 0xee, 0x2e, 0x46, 0xf2, 0x8d, 0xa6, 0xfb, 0xb5, 0x1c, 0x33, 0xbf, 0x90, 0x59, 0xc9, 0x7c, 0xb8, 0x6f, 0xad, 0x75, 0x02, 0x90, 0x8e, 0x59, 0x75},
+ },
+ { /* 63P*/
+ addYX: fp.Elt{0x36, 0x4d, 0x77, 0x04, 0xb8, 0x7d, 0x4a, 0xd1, 0xc5, 0xbb, 0x7b, 0x50, 0x5f, 0x8d, 0x9d, 0x62, 0x0f, 0x66, 0x71, 0xec, 0x87, 0xc5, 0x80, 0x82, 0xc8, 0xf4, 0x6a, 0x94, 0x92, 0x5b, 0xb0, 0x16, 0x9b, 0xb2, 0xc9, 0x6f, 0x2b, 0x2d, 0xee, 0x95, 0x73, 0x2e, 0xc2, 0x1b, 0xc5, 0x55, 0x36, 0x86, 0x24, 0xf8, 0x20, 0x05, 0x0d, 0x93, 0xd7, 0x76},
+ subYX: fp.Elt{0x7f, 0x01, 0xeb, 0x2e, 0x48, 0x4d, 0x1d, 0xf1, 0x06, 0x7e, 0x7c, 0x2a, 0x43, 0xbf, 0x28, 0xac, 0xe9, 0x58, 0x13, 0xc8, 0xbf, 0x8e, 0xc0, 0xef, 0xe8, 0x4f, 0x46, 0x8a, 0xe7, 0xc0, 0xf6, 0x0f, 0x0a, 0x03, 0x48, 0x91, 0x55, 0x39, 0x2a, 0xe3, 0xdc, 0xf6, 0x22, 0x9d, 0x4d, 0x71, 0x55, 0x68, 0x25, 0x6e, 0x95, 0x52, 0xee, 0x4c, 0xd9, 0x01},
+ dt2: fp.Elt{0xac, 0x33, 0x3f, 0x7c, 0x27, 0x35, 0x15, 0x91, 0x33, 0x8d, 0xf9, 0xc4, 0xf4, 0xf3, 0x90, 0x09, 0x75, 0x69, 0x62, 0x9f, 0x61, 0x35, 0x83, 0x92, 0x04, 0xef, 0x96, 0x38, 0x80, 0x9e, 0x88, 0xb3, 0x67, 0x95, 0xbe, 0x79, 0x3c, 0x35, 0xd8, 0xdc, 0xb2, 0x3e, 0x2d, 0xe6, 0x46, 0xbe, 0x81, 0xf3, 0x32, 0x0e, 0x37, 0x23, 0x75, 0x2a, 0x3d, 0xa0},
+ },
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go
new file mode 100644
index 0000000..f6ac5ed
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go
@@ -0,0 +1,62 @@
+package goldilocks
+
+import (
+ "crypto/subtle"
+
+ mlsb "github.com/cloudflare/circl/math/mlsbset"
+)
+
+const (
+ // MLSBRecoding parameters
+ fxT = 448
+ fxV = 2
+ fxW = 3
+ fx2w1 = 1 << (uint(fxW) - 1)
+)
+
+// ScalarBaseMult returns kG where G is the generator point.
+func (e twistCurve) ScalarBaseMult(k *Scalar) *twistPoint {
+ m, err := mlsb.New(fxT, fxV, fxW)
+ if err != nil {
+ panic(err)
+ }
+ if m.IsExtended() {
+ panic("not extended")
+ }
+
+ var isZero int
+ if k.IsZero() {
+ isZero = 1
+ }
+ subtle.ConstantTimeCopy(isZero, k[:], order[:])
+
+ minusK := *k
+ isEven := 1 - int(k[0]&0x1)
+ minusK.Neg()
+ subtle.ConstantTimeCopy(isEven, k[:], minusK[:])
+ c, err := m.Encode(k[:])
+ if err != nil {
+ panic(err)
+ }
+
+ gP := c.Exp(groupMLSB{})
+ P := gP.(*twistPoint)
+ P.cneg(uint(isEven))
+ return P
+}
+
+type groupMLSB struct{}
+
+func (e groupMLSB) ExtendedEltP() mlsb.EltP { return nil }
+func (e groupMLSB) Sqr(x mlsb.EltG) { x.(*twistPoint).Double() }
+func (e groupMLSB) Mul(x mlsb.EltG, y mlsb.EltP) { x.(*twistPoint).mixAddZ1(y.(*preTwistPointAffine)) }
+func (e groupMLSB) Identity() mlsb.EltG { return twistCurve{}.Identity() }
+func (e groupMLSB) NewEltP() mlsb.EltP { return &preTwistPointAffine{} }
+func (e groupMLSB) Lookup(a mlsb.EltP, v uint, s, u int32) {
+ Tabj := &tabFixMult[v]
+ P := a.(*preTwistPointAffine)
+ for k := range Tabj {
+ P.cmov(&Tabj[k], uint(subtle.ConstantTimeEq(int32(k), u)))
+ }
+ P.cneg(int(s >> 31))
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/conv/conv.go b/vendor/github.com/cloudflare/circl/internal/conv/conv.go
new file mode 100644
index 0000000..649a8e9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/conv/conv.go
@@ -0,0 +1,140 @@
+package conv
+
+import (
+ "encoding/binary"
+ "fmt"
+ "math/big"
+ "strings"
+)
+
+// BytesLe2Hex returns an hexadecimal string of a number stored in a
+// little-endian order slice x.
+func BytesLe2Hex(x []byte) string {
+ b := &strings.Builder{}
+ b.Grow(2*len(x) + 2)
+ fmt.Fprint(b, "0x")
+ if len(x) == 0 {
+ fmt.Fprint(b, "00")
+ }
+ for i := len(x) - 1; i >= 0; i-- {
+ fmt.Fprintf(b, "%02x", x[i])
+ }
+ return b.String()
+}
+
+// BytesLe2BigInt converts a little-endian slice x into a big-endian
+// math/big.Int.
+func BytesLe2BigInt(x []byte) *big.Int {
+ n := len(x)
+ b := new(big.Int)
+ if len(x) > 0 {
+ y := make([]byte, n)
+ for i := 0; i < n; i++ {
+ y[n-1-i] = x[i]
+ }
+ b.SetBytes(y)
+ }
+ return b
+}
+
+// BytesBe2Uint64Le converts a big-endian slice x to a little-endian slice of uint64.
+func BytesBe2Uint64Le(x []byte) []uint64 {
+ l := len(x)
+ z := make([]uint64, (l+7)/8)
+ blocks := l / 8
+ for i := 0; i < blocks; i++ {
+ z[i] = binary.BigEndian.Uint64(x[l-8*(i+1):])
+ }
+ remBytes := l % 8
+ for i := 0; i < remBytes; i++ {
+ z[blocks] |= uint64(x[l-1-8*blocks-i]) << uint(8*i)
+ }
+ return z
+}
+
+// BigInt2BytesLe stores a positive big.Int number x into a little-endian slice z.
+// The slice is modified if the bitlength of x <= 8*len(z) (padding with zeros).
+// If x does not fit in the slice or is negative, z is not modified.
+func BigInt2BytesLe(z []byte, x *big.Int) {
+ xLen := (x.BitLen() + 7) >> 3
+ zLen := len(z)
+ if zLen >= xLen && x.Sign() >= 0 {
+ y := x.Bytes()
+ for i := 0; i < xLen; i++ {
+ z[i] = y[xLen-1-i]
+ }
+ for i := xLen; i < zLen; i++ {
+ z[i] = 0
+ }
+ }
+}
+
+// Uint64Le2BigInt converts a little-endian slice x into a big number.
+func Uint64Le2BigInt(x []uint64) *big.Int {
+ n := len(x)
+ b := new(big.Int)
+ var bi big.Int
+ for i := n - 1; i >= 0; i-- {
+ bi.SetUint64(x[i])
+ b.Lsh(b, 64)
+ b.Add(b, &bi)
+ }
+ return b
+}
+
+// Uint64Le2BytesLe converts a little-endian slice x to a little-endian slice of bytes.
+func Uint64Le2BytesLe(x []uint64) []byte {
+ b := make([]byte, 8*len(x))
+ n := len(x)
+ for i := 0; i < n; i++ {
+ binary.LittleEndian.PutUint64(b[i*8:], x[i])
+ }
+ return b
+}
+
+// Uint64Le2BytesBe converts a little-endian slice x to a big-endian slice of bytes.
+func Uint64Le2BytesBe(x []uint64) []byte {
+ b := make([]byte, 8*len(x))
+ n := len(x)
+ for i := 0; i < n; i++ {
+ binary.BigEndian.PutUint64(b[i*8:], x[n-1-i])
+ }
+ return b
+}
+
+// Uint64Le2Hex returns an hexadecimal string of a number stored in a
+// little-endian order slice x.
+func Uint64Le2Hex(x []uint64) string {
+ b := new(strings.Builder)
+ b.Grow(16*len(x) + 2)
+ fmt.Fprint(b, "0x")
+ if len(x) == 0 {
+ fmt.Fprint(b, "00")
+ }
+ for i := len(x) - 1; i >= 0; i-- {
+ fmt.Fprintf(b, "%016x", x[i])
+ }
+ return b.String()
+}
+
+// BigInt2Uint64Le stores a positive big.Int number x into a little-endian slice z.
+// The slice is modified if the bitlength of x <= 8*len(z) (padding with zeros).
+// If x does not fit in the slice or is negative, z is not modified.
+func BigInt2Uint64Le(z []uint64, x *big.Int) {
+ xLen := (x.BitLen() + 63) >> 6 // number of 64-bit words
+ zLen := len(z)
+ if zLen >= xLen && x.Sign() > 0 {
+ var y, yi big.Int
+ y.Set(x)
+ two64 := big.NewInt(1)
+ two64.Lsh(two64, 64).Sub(two64, big.NewInt(1))
+ for i := 0; i < xLen; i++ {
+ yi.And(&y, two64)
+ z[i] = yi.Uint64()
+ y.Rsh(&y, 64)
+ }
+ }
+ for i := xLen; i < zLen; i++ {
+ z[i] = 0
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/doc.go b/vendor/github.com/cloudflare/circl/internal/sha3/doc.go
new file mode 100644
index 0000000..7e02309
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/doc.go
@@ -0,0 +1,62 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha3 implements the SHA-3 fixed-output-length hash functions and
+// the SHAKE variable-output-length hash functions defined by FIPS-202.
+//
+// Both types of hash function use the "sponge" construction and the Keccak
+// permutation. For a detailed specification see http://keccak.noekeon.org/
+//
+// # Guidance
+//
+// If you aren't sure what function you need, use SHAKE256 with at least 64
+// bytes of output. The SHAKE instances are faster than the SHA3 instances;
+// the latter have to allocate memory to conform to the hash.Hash interface.
+//
+// If you need a secret-key MAC (message authentication code), prepend the
+// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
+// output.
+//
+// # Security strengths
+//
+// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
+// strength against preimage attacks of x bits. Since they only produce "x"
+// bits of output, their collision-resistance is only "x/2" bits.
+//
+// The SHAKE-256 and -128 functions have a generic security strength of 256 and
+// 128 bits against all attacks, provided that at least 2x bits of their output
+// is used. Requesting more than 64 or 32 bytes of output, respectively, does
+// not increase the collision-resistance of the SHAKE functions.
+//
+// # The sponge construction
+//
+// A sponge builds a pseudo-random function from a public pseudo-random
+// permutation, by applying the permutation to a state of "rate + capacity"
+// bytes, but hiding "capacity" of the bytes.
+//
+// A sponge starts out with a zero state. To hash an input using a sponge, up
+// to "rate" bytes of the input are XORed into the sponge's state. The sponge
+// is then "full" and the permutation is applied to "empty" it. This process is
+// repeated until all the input has been "absorbed". The input is then padded.
+// The digest is "squeezed" from the sponge in the same way, except that output
+// is copied out instead of input being XORed in.
+//
+// A sponge is parameterized by its generic security strength, which is equal
+// to half its capacity; capacity + rate is equal to the permutation's width.
+// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
+// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
+//
+// # Recommendations
+//
+// The SHAKE functions are recommended for most new uses. They can produce
+// output of arbitrary length. SHAKE256, with an output length of at least
+// 64 bytes, provides 256-bit security against all attacks. The Keccak team
+// recommends it for most applications upgrading from SHA2-512. (NIST chose a
+// much stronger, but much slower, sponge instance for SHA3-512.)
+//
+// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
+// They produce output of the same length, with the same security strengths
+// against all attacks. This means, in particular, that SHA3-256 only has
+// 128-bit collision resistance, because its output length is 32 bytes.
+package sha3
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go b/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go
new file mode 100644
index 0000000..7d2365a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go
@@ -0,0 +1,69 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() State {
+ return State{rate: 144, outputLen: 28, dsbyte: 0x06}
+}
+
+// New256 creates a new SHA3-256 hash.
+// Its generic security strength is 256 bits against preimage attacks,
+// and 128 bits against collision attacks.
+func New256() State {
+ return State{rate: 136, outputLen: 32, dsbyte: 0x06}
+}
+
+// New384 creates a new SHA3-384 hash.
+// Its generic security strength is 384 bits against preimage attacks,
+// and 192 bits against collision attacks.
+func New384() State {
+ return State{rate: 104, outputLen: 48, dsbyte: 0x06}
+}
+
+// New512 creates a new SHA3-512 hash.
+// Its generic security strength is 512 bits against preimage attacks,
+// and 256 bits against collision attacks.
+func New512() State {
+ return State{rate: 72, outputLen: 64, dsbyte: 0x06}
+}
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+ h := New224()
+ _, _ = h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+ h := New256()
+ _, _ = h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+ h := New384()
+ _, _ = h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+ h := New512()
+ _, _ = h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go
new file mode 100644
index 0000000..1755fd1
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go
@@ -0,0 +1,391 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// KeccakF1600 applies the Keccak permutation to a 1600b-wide
+// state represented as a slice of 25 uint64s.
+// If turbo is true, applies the 12-round variant instead of the
+// regular 24-round variant.
+// nolint:funlen
+func KeccakF1600(a *[25]uint64, turbo bool) {
+ // Implementation translated from Keccak-inplace.c
+ // in the keccak reference code.
+ var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
+
+ i := 0
+
+ if turbo {
+ i = 12
+ }
+
+ for ; i < 24; i += 4 {
+ // Combines the 5 steps in each round into 2 steps.
+ // Unrolls 4 rounds per loop and spreads some steps across rounds.
+
+ // Round 1
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[6] ^ d1
+ bc1 = t<<44 | t>>(64-44)
+ t = a[12] ^ d2
+ bc2 = t<<43 | t>>(64-43)
+ t = a[18] ^ d3
+ bc3 = t<<21 | t>>(64-21)
+ t = a[24] ^ d4
+ bc4 = t<<14 | t>>(64-14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i]
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc2 = t<<3 | t>>(64-3)
+ t = a[16] ^ d1
+ bc3 = t<<45 | t>>(64-45)
+ t = a[22] ^ d2
+ bc4 = t<<61 | t>>(64-61)
+ t = a[3] ^ d3
+ bc0 = t<<28 | t>>(64-28)
+ t = a[9] ^ d4
+ bc1 = t<<20 | t>>(64-20)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc4 = t<<18 | t>>(64-18)
+ t = a[1] ^ d1
+ bc0 = t<<1 | t>>(64-1)
+ t = a[7] ^ d2
+ bc1 = t<<6 | t>>(64-6)
+ t = a[13] ^ d3
+ bc2 = t<<25 | t>>(64-25)
+ t = a[19] ^ d4
+ bc3 = t<<8 | t>>(64-8)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc1 = t<<36 | t>>(64-36)
+ t = a[11] ^ d1
+ bc2 = t<<10 | t>>(64-10)
+ t = a[17] ^ d2
+ bc3 = t<<15 | t>>(64-15)
+ t = a[23] ^ d3
+ bc4 = t<<56 | t>>(64-56)
+ t = a[4] ^ d4
+ bc0 = t<<27 | t>>(64-27)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc3 = t<<41 | t>>(64-41)
+ t = a[21] ^ d1
+ bc4 = t<<2 | t>>(64-2)
+ t = a[2] ^ d2
+ bc0 = t<<62 | t>>(64-62)
+ t = a[8] ^ d3
+ bc1 = t<<55 | t>>(64-55)
+ t = a[14] ^ d4
+ bc2 = t<<39 | t>>(64-39)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 2
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[16] ^ d1
+ bc1 = t<<44 | t>>(64-44)
+ t = a[7] ^ d2
+ bc2 = t<<43 | t>>(64-43)
+ t = a[23] ^ d3
+ bc3 = t<<21 | t>>(64-21)
+ t = a[14] ^ d4
+ bc4 = t<<14 | t>>(64-14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+1]
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc2 = t<<3 | t>>(64-3)
+ t = a[11] ^ d1
+ bc3 = t<<45 | t>>(64-45)
+ t = a[2] ^ d2
+ bc4 = t<<61 | t>>(64-61)
+ t = a[18] ^ d3
+ bc0 = t<<28 | t>>(64-28)
+ t = a[9] ^ d4
+ bc1 = t<<20 | t>>(64-20)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc4 = t<<18 | t>>(64-18)
+ t = a[6] ^ d1
+ bc0 = t<<1 | t>>(64-1)
+ t = a[22] ^ d2
+ bc1 = t<<6 | t>>(64-6)
+ t = a[13] ^ d3
+ bc2 = t<<25 | t>>(64-25)
+ t = a[4] ^ d4
+ bc3 = t<<8 | t>>(64-8)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc1 = t<<36 | t>>(64-36)
+ t = a[1] ^ d1
+ bc2 = t<<10 | t>>(64-10)
+ t = a[17] ^ d2
+ bc3 = t<<15 | t>>(64-15)
+ t = a[8] ^ d3
+ bc4 = t<<56 | t>>(64-56)
+ t = a[24] ^ d4
+ bc0 = t<<27 | t>>(64-27)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc3 = t<<41 | t>>(64-41)
+ t = a[21] ^ d1
+ bc4 = t<<2 | t>>(64-2)
+ t = a[12] ^ d2
+ bc0 = t<<62 | t>>(64-62)
+ t = a[3] ^ d3
+ bc1 = t<<55 | t>>(64-55)
+ t = a[19] ^ d4
+ bc2 = t<<39 | t>>(64-39)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 3
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[11] ^ d1
+ bc1 = t<<44 | t>>(64-44)
+ t = a[22] ^ d2
+ bc2 = t<<43 | t>>(64-43)
+ t = a[8] ^ d3
+ bc3 = t<<21 | t>>(64-21)
+ t = a[19] ^ d4
+ bc4 = t<<14 | t>>(64-14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+2]
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc2 = t<<3 | t>>(64-3)
+ t = a[1] ^ d1
+ bc3 = t<<45 | t>>(64-45)
+ t = a[12] ^ d2
+ bc4 = t<<61 | t>>(64-61)
+ t = a[23] ^ d3
+ bc0 = t<<28 | t>>(64-28)
+ t = a[9] ^ d4
+ bc1 = t<<20 | t>>(64-20)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc4 = t<<18 | t>>(64-18)
+ t = a[16] ^ d1
+ bc0 = t<<1 | t>>(64-1)
+ t = a[2] ^ d2
+ bc1 = t<<6 | t>>(64-6)
+ t = a[13] ^ d3
+ bc2 = t<<25 | t>>(64-25)
+ t = a[24] ^ d4
+ bc3 = t<<8 | t>>(64-8)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc1 = t<<36 | t>>(64-36)
+ t = a[6] ^ d1
+ bc2 = t<<10 | t>>(64-10)
+ t = a[17] ^ d2
+ bc3 = t<<15 | t>>(64-15)
+ t = a[3] ^ d3
+ bc4 = t<<56 | t>>(64-56)
+ t = a[14] ^ d4
+ bc0 = t<<27 | t>>(64-27)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc3 = t<<41 | t>>(64-41)
+ t = a[21] ^ d1
+ bc4 = t<<2 | t>>(64-2)
+ t = a[7] ^ d2
+ bc0 = t<<62 | t>>(64-62)
+ t = a[18] ^ d3
+ bc1 = t<<55 | t>>(64-55)
+ t = a[4] ^ d4
+ bc2 = t<<39 | t>>(64-39)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 4
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[1] ^ d1
+ bc1 = t<<44 | t>>(64-44)
+ t = a[2] ^ d2
+ bc2 = t<<43 | t>>(64-43)
+ t = a[3] ^ d3
+ bc3 = t<<21 | t>>(64-21)
+ t = a[4] ^ d4
+ bc4 = t<<14 | t>>(64-14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+3]
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc2 = t<<3 | t>>(64-3)
+ t = a[6] ^ d1
+ bc3 = t<<45 | t>>(64-45)
+ t = a[7] ^ d2
+ bc4 = t<<61 | t>>(64-61)
+ t = a[8] ^ d3
+ bc0 = t<<28 | t>>(64-28)
+ t = a[9] ^ d4
+ bc1 = t<<20 | t>>(64-20)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc4 = t<<18 | t>>(64-18)
+ t = a[11] ^ d1
+ bc0 = t<<1 | t>>(64-1)
+ t = a[12] ^ d2
+ bc1 = t<<6 | t>>(64-6)
+ t = a[13] ^ d3
+ bc2 = t<<25 | t>>(64-25)
+ t = a[14] ^ d4
+ bc3 = t<<8 | t>>(64-8)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc1 = t<<36 | t>>(64-36)
+ t = a[16] ^ d1
+ bc2 = t<<10 | t>>(64-10)
+ t = a[17] ^ d2
+ bc3 = t<<15 | t>>(64-15)
+ t = a[18] ^ d3
+ bc4 = t<<56 | t>>(64-56)
+ t = a[19] ^ d4
+ bc0 = t<<27 | t>>(64-27)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc3 = t<<41 | t>>(64-41)
+ t = a[21] ^ d1
+ bc4 = t<<2 | t>>(64-2)
+ t = a[22] ^ d2
+ bc0 = t<<62 | t>>(64-62)
+ t = a[23] ^ d3
+ bc1 = t<<55 | t>>(64-55)
+ t = a[24] ^ d4
+ bc2 = t<<39 | t>>(64-39)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/rc.go b/vendor/github.com/cloudflare/circl/internal/sha3/rc.go
new file mode 100644
index 0000000..6a3df42
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/rc.go
@@ -0,0 +1,29 @@
+package sha3
+
+// RC stores the round constants for use in the ι step.
+var RC = [24]uint64{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808A,
+ 0x8000000080008000,
+ 0x000000000000808B,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008A,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000A,
+ 0x000000008000808B,
+ 0x800000000000008B,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800A,
+ 0x800000008000000A,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go
new file mode 100644
index 0000000..a0df5aa
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go
@@ -0,0 +1,200 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+ // spongeAbsorbing indicates that the sponge is absorbing input.
+ spongeAbsorbing spongeDirection = iota
+ // spongeSqueezing indicates that the sponge is being squeezed.
+ spongeSqueezing
+)
+
+const (
+ // maxRate is the maximum size of the internal buffer. SHAKE-256
+ // currently needs the largest buffer.
+ maxRate = 168
+)
+
+func (d *State) buf() []byte {
+ return d.storage.asBytes()[d.bufo:d.bufe]
+}
+
+type State struct {
+ // Generic sponge components.
+ a [25]uint64 // main state of the hash
+ rate int // the number of bytes of state to use
+
+ bufo int // offset of buffer in storage
+ bufe int // end of buffer in storage
+
+ // dsbyte contains the "domain separation" bits and the first bit of
+ // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+ // SHA-3 and SHAKE functions by appending bitstrings to the message.
+ // Using a little-endian bit-ordering convention, these are "01" for SHA-3
+ // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+ // padding rule from section 5.1 is applied to pad the message to a multiple
+ // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+ // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+ // giving 00000110b (0x06) and 00011111b (0x1f).
+ // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+ // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+ // Extendable-Output Functions (May 2014)"
+ dsbyte byte
+
+ storage storageBuf
+
+ // Specific to SHA-3 and SHAKE.
+ outputLen int // the default output size in bytes
+ state spongeDirection // whether the sponge is absorbing or squeezing
+ turbo bool // Whether we're using 12 rounds instead of 24
+}
+
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *State) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *State) Size() int { return d.outputLen }
+
+// Reset clears the internal state by zeroing the sponge state and
+// the byte buffer, and setting Sponge.state to absorbing.
+func (d *State) Reset() {
+ // Zero the permutation's state.
+ for i := range d.a {
+ d.a[i] = 0
+ }
+ d.state = spongeAbsorbing
+ d.bufo = 0
+ d.bufe = 0
+}
+
+func (d *State) clone() *State {
+ ret := *d
+ return &ret
+}
+
+// permute applies the KeccakF-1600 permutation. It handles
+// any input-output buffering.
+func (d *State) permute() {
+ switch d.state {
+ case spongeAbsorbing:
+ // If we're absorbing, we need to xor the input into the state
+ // before applying the permutation.
+ xorIn(d, d.buf())
+ d.bufe = 0
+ d.bufo = 0
+ KeccakF1600(&d.a, d.turbo)
+ case spongeSqueezing:
+ // If we're squeezing, we need to apply the permutation before
+ // copying more output.
+ KeccakF1600(&d.a, d.turbo)
+ d.bufe = d.rate
+ d.bufo = 0
+ copyOut(d, d.buf())
+ }
+}
+
+// pads appends the domain separation bits in dsbyte, applies
+// the multi-bitrate 10..1 padding rule, and permutes the state.
+func (d *State) padAndPermute(dsbyte byte) {
+ // Pad with this instance's domain-separator bits. We know that there's
+ // at least one byte of space in d.buf() because, if it were full,
+ // permute would have been called to empty it. dsbyte also contains the
+ // first one bit for the padding. See the comment in the state struct.
+ zerosStart := d.bufe + 1
+ d.bufe = d.rate
+ buf := d.buf()
+ buf[zerosStart-1] = dsbyte
+ for i := zerosStart; i < d.rate; i++ {
+ buf[i] = 0
+ }
+ // This adds the final one bit for the padding. Because of the way that
+ // bits are numbered from the LSB upwards, the final bit is the MSB of
+ // the last byte.
+ buf[d.rate-1] ^= 0x80
+ // Apply the permutation
+ d.permute()
+ d.state = spongeSqueezing
+ d.bufe = d.rate
+ copyOut(d, buf)
+}
+
+// Write absorbs more data into the hash's state. It produces an error
+// if more data is written to the ShakeHash after writing
+func (d *State) Write(p []byte) (written int, err error) {
+ if d.state != spongeAbsorbing {
+ panic("sha3: write to sponge after read")
+ }
+ written = len(p)
+
+ for len(p) > 0 {
+ bufl := d.bufe - d.bufo
+ if bufl == 0 && len(p) >= d.rate {
+ // The fast path; absorb a full "rate" bytes of input and apply the permutation.
+ xorIn(d, p[:d.rate])
+ p = p[d.rate:]
+ KeccakF1600(&d.a, d.turbo)
+ } else {
+ // The slow path; buffer the input until we can fill the sponge, and then xor it in.
+ todo := d.rate - bufl
+ if todo > len(p) {
+ todo = len(p)
+ }
+ d.bufe += todo
+ buf := d.buf()
+ copy(buf[bufl:], p[:todo])
+ p = p[todo:]
+
+ // If the sponge is full, apply the permutation.
+ if d.bufe == d.rate {
+ d.permute()
+ }
+ }
+ }
+
+ return written, nil
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *State) Read(out []byte) (n int, err error) {
+ // If we're still absorbing, pad and apply the permutation.
+ if d.state == spongeAbsorbing {
+ d.padAndPermute(d.dsbyte)
+ }
+
+ n = len(out)
+
+ // Now, do the squeezing.
+ for len(out) > 0 {
+ buf := d.buf()
+ n := copy(out, buf)
+ d.bufo += n
+ out = out[n:]
+
+ // Apply the permutation if we've squeezed the sponge dry.
+ if d.bufo == d.bufe {
+ d.permute()
+ }
+ }
+
+ return
+}
+
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes.
+func (d *State) Sum(in []byte) []byte {
+ // Make a copy of the original hash so that caller can keep writing
+ // and summing.
+ dup := d.clone()
+ hash := make([]byte, dup.outputLen)
+ _, _ = dup.Read(hash)
+ return append(in, hash...)
+}
+
+func (d *State) IsAbsorbing() bool {
+ return d.state == spongeAbsorbing
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s b/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s
new file mode 100644
index 0000000..8a4458f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s
@@ -0,0 +1,33 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo,!appengine
+
+#include "textflag.h"
+
+// func kimd(function code, chain *[200]byte, src []byte)
+TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG src+16(FP), R2, R3 // R2=base, R3=len
+
+continue:
+ WORD $0xB93E0002 // KIMD --, R2
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
+
+// func klmd(function code, chain *[200]byte, dst, src []byte)
+TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
+ // TODO: SHAKE support
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG dst+16(FP), R2, R3 // R2=base, R3=len
+ LMG src+40(FP), R4, R5 // R4=base, R5=len
+
+continue:
+ WORD $0xB93F0024 // KLMD R2, R4
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/shake.go b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go
new file mode 100644
index 0000000..77817f7
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go
@@ -0,0 +1,119 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE and cSHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+//
+//
+// SHAKE implementation is based on FIPS PUB 202 [1]
+// cSHAKE implementations is based on NIST SP 800-185 [2]
+//
+// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+// [2] https://doi.org/10.6028/NIST.SP.800-185
+
+import (
+ "io"
+)
+
+// ShakeHash defines the interface to hash functions that
+// support arbitrary-length output.
+type ShakeHash interface {
+ // Write absorbs more data into the hash's state. It panics if input is
+ // written to it after output has been read from it.
+ io.Writer
+
+ // Read reads more output from the hash; reading affects the hash's
+ // state. (ShakeHash.Read is thus very different from Hash.Sum)
+ // It never returns an error.
+ io.Reader
+
+ // Clone returns a copy of the ShakeHash in its current state.
+ Clone() ShakeHash
+
+ // Reset resets the ShakeHash to its initial state.
+ Reset()
+}
+
+// Consts for configuring initial SHA-3 state
+const (
+ dsbyteShake = 0x1f
+ rate128 = 168
+ rate256 = 136
+)
+
+// Clone returns copy of SHAKE context within its current state.
+func (d *State) Clone() ShakeHash {
+ return d.clone()
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() State {
+ return State{rate: rate128, dsbyte: dsbyteShake}
+}
+
+// NewTurboShake128 creates a new TurboSHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
+func NewTurboShake128(D byte) State {
+ if D == 0 || D > 0x7f {
+ panic("turboshake: D out of range")
+ }
+ return State{rate: rate128, dsbyte: D, turbo: true}
+}
+
+// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+func NewShake256() State {
+ return State{rate: rate256, dsbyte: dsbyteShake}
+}
+
+// NewTurboShake256 creates a new TurboSHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
+func NewTurboShake256(D byte) State {
+ if D == 0 || D > 0x7f {
+ panic("turboshake: D out of range")
+ }
+ return State{rate: rate256, dsbyte: D, turbo: true}
+}
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+ h := NewShake128()
+ _, _ = h.Write(data)
+ _, _ = h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+ h := NewShake256()
+ _, _ = h.Write(data)
+ _, _ = h.Read(hash)
+}
+
+// TurboShakeSum128 writes an arbitrary-length digest of data into hash.
+func TurboShakeSum128(hash, data []byte, D byte) {
+ h := NewTurboShake128(D)
+ _, _ = h.Write(data)
+ _, _ = h.Read(hash)
+}
+
+// TurboShakeSum256 writes an arbitrary-length digest of data into hash.
+func TurboShakeSum256(hash, data []byte, D byte) {
+ h := NewTurboShake256(D)
+ _, _ = h.Write(data)
+ _, _ = h.Read(hash)
+}
+
+func (d *State) SwitchDS(D byte) {
+ d.dsbyte = D
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/xor.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor.go
new file mode 100644
index 0000000..1e21337
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor.go
@@ -0,0 +1,15 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !386 && !ppc64le) || appengine
+// +build !amd64,!386,!ppc64le appengine
+
+package sha3
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate]byte
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+ return (*[maxRate]byte)(b)
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
new file mode 100644
index 0000000..2b0c661
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
@@ -0,0 +1,33 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 || appengine) && (!386 || appengine) && (!ppc64le || appengine)
+// +build !amd64 appengine
+// +build !386 appengine
+// +build !ppc64le appengine
+
+package sha3
+
+import "encoding/binary"
+
+// xorIn xors the bytes in buf into the state; it
+// makes no non-portable assumptions about memory layout
+// or alignment.
+func xorIn(d *State, buf []byte) {
+ n := len(buf) / 8
+
+ for i := 0; i < n; i++ {
+ a := binary.LittleEndian.Uint64(buf)
+ d.a[i] ^= a
+ buf = buf[8:]
+ }
+}
+
+// copyOut copies ulint64s to a byte buffer.
+func copyOut(d *State, b []byte) {
+ for i := 0; len(b) >= 8; i++ {
+ binary.LittleEndian.PutUint64(b, d.a[i])
+ b = b[8:]
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
new file mode 100644
index 0000000..052fc8d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
@@ -0,0 +1,61 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (amd64 || 386 || ppc64le) && !appengine
+// +build amd64 386 ppc64le
+// +build !appengine
+
+package sha3
+
+import "unsafe"
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate / 8]uint64
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+ return (*[maxRate]byte)(unsafe.Pointer(b))
+}
+
+// xorInuses unaligned reads and writes to update d.a to contain d.a
+// XOR buf.
+func xorIn(d *State, buf []byte) {
+ n := len(buf)
+ bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
+ if n >= 72 {
+ d.a[0] ^= bw[0]
+ d.a[1] ^= bw[1]
+ d.a[2] ^= bw[2]
+ d.a[3] ^= bw[3]
+ d.a[4] ^= bw[4]
+ d.a[5] ^= bw[5]
+ d.a[6] ^= bw[6]
+ d.a[7] ^= bw[7]
+ d.a[8] ^= bw[8]
+ }
+ if n >= 104 {
+ d.a[9] ^= bw[9]
+ d.a[10] ^= bw[10]
+ d.a[11] ^= bw[11]
+ d.a[12] ^= bw[12]
+ }
+ if n >= 136 {
+ d.a[13] ^= bw[13]
+ d.a[14] ^= bw[14]
+ d.a[15] ^= bw[15]
+ d.a[16] ^= bw[16]
+ }
+ if n >= 144 {
+ d.a[17] ^= bw[17]
+ }
+ if n >= 168 {
+ d.a[18] ^= bw[18]
+ d.a[19] ^= bw[19]
+ d.a[20] ^= bw[20]
+ }
+}
+
+func copyOut(d *State, buf []byte) {
+ ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
+ copy(buf, ab[:])
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp.go
new file mode 100644
index 0000000..57a50ff
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp.go
@@ -0,0 +1,205 @@
+// Package fp25519 provides prime field arithmetic over GF(2^255-19).
+package fp25519
+
+import (
+ "errors"
+
+ "github.com/cloudflare/circl/internal/conv"
+)
+
+// Size in bytes of an element.
+const Size = 32
+
+// Elt is a prime field element.
+type Elt [Size]byte
+
+func (e Elt) String() string { return conv.BytesLe2Hex(e[:]) }
+
+// p is the prime modulus 2^255-19.
+var p = Elt{
+ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+}
+
+// P returns the prime modulus 2^255-19.
+func P() Elt { return p }
+
+// ToBytes stores in b the little-endian byte representation of x.
+func ToBytes(b []byte, x *Elt) error {
+ if len(b) != Size {
+ return errors.New("wrong size")
+ }
+ Modp(x)
+ copy(b, x[:])
+ return nil
+}
+
+// IsZero returns true if x is equal to 0.
+func IsZero(x *Elt) bool { Modp(x); return *x == Elt{} }
+
+// SetOne assigns x=1.
+func SetOne(x *Elt) { *x = Elt{}; x[0] = 1 }
+
+// Neg calculates z = -x.
+func Neg(z, x *Elt) { Sub(z, &p, x) }
+
+// InvSqrt calculates z = sqrt(x/y) iff x/y is a quadratic-residue, which is
+// indicated by returning isQR = true. Otherwise, when x/y is a quadratic
+// non-residue, z will have an undetermined value and isQR = false.
+func InvSqrt(z, x, y *Elt) (isQR bool) {
+ sqrtMinusOne := &Elt{
+ 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4,
+ 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f,
+ 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b,
+ 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b,
+ }
+ t0, t1, t2, t3 := &Elt{}, &Elt{}, &Elt{}, &Elt{}
+
+ Mul(t0, x, y) // t0 = u*v
+ Sqr(t1, y) // t1 = v^2
+ Mul(t2, t0, t1) // t2 = u*v^3
+ Sqr(t0, t1) // t0 = v^4
+ Mul(t1, t0, t2) // t1 = u*v^7
+
+ var Tab [4]*Elt
+ Tab[0] = &Elt{}
+ Tab[1] = &Elt{}
+ Tab[2] = t3
+ Tab[3] = t1
+
+ *Tab[0] = *t1
+ Sqr(Tab[0], Tab[0])
+ Sqr(Tab[1], Tab[0])
+ Sqr(Tab[1], Tab[1])
+ Mul(Tab[1], Tab[1], Tab[3])
+ Mul(Tab[0], Tab[0], Tab[1])
+ Sqr(Tab[0], Tab[0])
+ Mul(Tab[0], Tab[0], Tab[1])
+ Sqr(Tab[1], Tab[0])
+ for i := 0; i < 4; i++ {
+ Sqr(Tab[1], Tab[1])
+ }
+ Mul(Tab[1], Tab[1], Tab[0])
+ Sqr(Tab[2], Tab[1])
+ for i := 0; i < 4; i++ {
+ Sqr(Tab[2], Tab[2])
+ }
+ Mul(Tab[2], Tab[2], Tab[0])
+ Sqr(Tab[1], Tab[2])
+ for i := 0; i < 14; i++ {
+ Sqr(Tab[1], Tab[1])
+ }
+ Mul(Tab[1], Tab[1], Tab[2])
+ Sqr(Tab[2], Tab[1])
+ for i := 0; i < 29; i++ {
+ Sqr(Tab[2], Tab[2])
+ }
+ Mul(Tab[2], Tab[2], Tab[1])
+ Sqr(Tab[1], Tab[2])
+ for i := 0; i < 59; i++ {
+ Sqr(Tab[1], Tab[1])
+ }
+ Mul(Tab[1], Tab[1], Tab[2])
+ for i := 0; i < 5; i++ {
+ Sqr(Tab[1], Tab[1])
+ }
+ Mul(Tab[1], Tab[1], Tab[0])
+ Sqr(Tab[2], Tab[1])
+ for i := 0; i < 124; i++ {
+ Sqr(Tab[2], Tab[2])
+ }
+ Mul(Tab[2], Tab[2], Tab[1])
+ Sqr(Tab[2], Tab[2])
+ Sqr(Tab[2], Tab[2])
+ Mul(Tab[2], Tab[2], Tab[3])
+
+ Mul(z, t3, t2) // z = xy^(p+3)/8 = xy^3*(xy^7)^(p-5)/8
+ // Checking whether y z^2 == x
+ Sqr(t0, z) // t0 = z^2
+ Mul(t0, t0, y) // t0 = yz^2
+ Sub(t1, t0, x) // t1 = t0-u
+ Add(t2, t0, x) // t2 = t0+u
+ if IsZero(t1) {
+ return true
+ } else if IsZero(t2) {
+ Mul(z, z, sqrtMinusOne) // z = z*sqrt(-1)
+ return true
+ } else {
+ return false
+ }
+}
+
+// Inv calculates z = 1/x mod p.
+func Inv(z, x *Elt) {
+ x0, x1, x2 := &Elt{}, &Elt{}, &Elt{}
+ Sqr(x1, x)
+ Sqr(x0, x1)
+ Sqr(x0, x0)
+ Mul(x0, x0, x)
+ Mul(z, x0, x1)
+ Sqr(x1, z)
+ Mul(x0, x0, x1)
+ Sqr(x1, x0)
+ for i := 0; i < 4; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x0, x0, x1)
+ Sqr(x1, x0)
+ for i := 0; i < 9; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, x0)
+ Sqr(x2, x1)
+ for i := 0; i < 19; i++ {
+ Sqr(x2, x2)
+ }
+ Mul(x2, x2, x1)
+ for i := 0; i < 10; i++ {
+ Sqr(x2, x2)
+ }
+ Mul(x2, x2, x0)
+ Sqr(x0, x2)
+ for i := 0; i < 49; i++ {
+ Sqr(x0, x0)
+ }
+ Mul(x0, x0, x2)
+ Sqr(x1, x0)
+ for i := 0; i < 99; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, x0)
+ for i := 0; i < 50; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, x2)
+ for i := 0; i < 5; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(z, z, x1)
+}
+
+// Cmov assigns y to x if n is 1.
+func Cmov(x, y *Elt, n uint) { cmov(x, y, n) }
+
+// Cswap interchanges x and y if n is 1.
+func Cswap(x, y *Elt, n uint) { cswap(x, y, n) }
+
+// Add calculates z = x+y mod p.
+func Add(z, x, y *Elt) { add(z, x, y) }
+
+// Sub calculates z = x-y mod p.
+func Sub(z, x, y *Elt) { sub(z, x, y) }
+
+// AddSub calculates (x,y) = (x+y mod p, x-y mod p).
+func AddSub(x, y *Elt) { addsub(x, y) }
+
+// Mul calculates z = x*y mod p.
+func Mul(z, x, y *Elt) { mul(z, x, y) }
+
+// Sqr calculates z = x^2 mod p.
+func Sqr(z, x *Elt) { sqr(z, x) }
+
+// Modp ensures that z is between [0,p-1].
+func Modp(z *Elt) { modp(z) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go
new file mode 100644
index 0000000..057f0d2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go
@@ -0,0 +1,45 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package fp25519
+
+import (
+ "golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func cmov(x, y *Elt, n uint) { cmovAmd64(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapAmd64(x, y, n) }
+func add(z, x, y *Elt) { addAmd64(z, x, y) }
+func sub(z, x, y *Elt) { subAmd64(z, x, y) }
+func addsub(x, y *Elt) { addsubAmd64(x, y) }
+func mul(z, x, y *Elt) { mulAmd64(z, x, y) }
+func sqr(z, x *Elt) { sqrAmd64(z, x) }
+func modp(z *Elt) { modpAmd64(z) }
+
+//go:noescape
+func cmovAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func cswapAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func addAmd64(z, x, y *Elt)
+
+//go:noescape
+func subAmd64(z, x, y *Elt)
+
+//go:noescape
+func addsubAmd64(x, y *Elt)
+
+//go:noescape
+func mulAmd64(z, x, y *Elt)
+
+//go:noescape
+func sqrAmd64(z, x *Elt)
+
+//go:noescape
+func modpAmd64(z *Elt)
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h
new file mode 100644
index 0000000..b884b58
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h
@@ -0,0 +1,351 @@
+// This code was imported from https://github.com/armfazh/rfc7748_precomputed
+
+// CHECK_BMI2ADX triggers bmi2adx if supported,
+// otherwise it fallbacks to legacy code.
+#define CHECK_BMI2ADX(label, legacy, bmi2adx) \
+ CMPB ·hasBmi2Adx(SB), $0 \
+ JE label \
+ bmi2adx \
+ RET \
+ label: \
+ legacy \
+ RET
+
+// cselect is a conditional move
+// if b=1: it copies y into x;
+// if b=0: x remains with the same value;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, FLAGS
+// Instr: x86_64, cmov
+#define cselect(x,y,b) \
+ TESTQ b, b \
+ MOVQ 0+x, AX; MOVQ 0+y, DX; CMOVQNE DX, AX; MOVQ AX, 0+x; \
+ MOVQ 8+x, AX; MOVQ 8+y, DX; CMOVQNE DX, AX; MOVQ AX, 8+x; \
+ MOVQ 16+x, AX; MOVQ 16+y, DX; CMOVQNE DX, AX; MOVQ AX, 16+x; \
+ MOVQ 24+x, AX; MOVQ 24+y, DX; CMOVQNE DX, AX; MOVQ AX, 24+x;
+
+// cswap is a conditional swap
+// if b=1: x,y <- y,x;
+// if b=0: x,y remain with the same values;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, R8, FLAGS
+// Instr: x86_64, cmov
+#define cswap(x,y,b) \
+ TESTQ b, b \
+ MOVQ 0+x, AX; MOVQ AX, R8; MOVQ 0+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 0+x; MOVQ DX, 0+y; \
+ MOVQ 8+x, AX; MOVQ AX, R8; MOVQ 8+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 8+x; MOVQ DX, 8+y; \
+ MOVQ 16+x, AX; MOVQ AX, R8; MOVQ 16+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 16+x; MOVQ DX, 16+y; \
+ MOVQ 24+x, AX; MOVQ AX, R8; MOVQ 24+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 24+x; MOVQ DX, 24+y;
+
+// additionLeg adds x and y and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov
+#define additionLeg(z,x,y) \
+ MOVL $38, AX; \
+ MOVL $0, DX; \
+ MOVQ 0+x, R8; ADDQ 0+y, R8; \
+ MOVQ 8+x, R9; ADCQ 8+y, R9; \
+ MOVQ 16+x, R10; ADCQ 16+y, R10; \
+ MOVQ 24+x, R11; ADCQ 24+y, R11; \
+ CMOVQCS AX, DX; \
+ ADDQ DX, R8; \
+ ADCQ $0, R9; MOVQ R9, 8+z; \
+ ADCQ $0, R10; MOVQ R10, 16+z; \
+ ADCQ $0, R11; MOVQ R11, 24+z; \
+ MOVL $0, DX; \
+ CMOVQCS AX, DX; \
+ ADDQ DX, R8; MOVQ R8, 0+z;
+
+// additionAdx adds x and y and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov, adx
+#define additionAdx(z,x,y) \
+ MOVL $38, AX; \
+ XORL DX, DX; \
+ MOVQ 0+x, R8; ADCXQ 0+y, R8; \
+ MOVQ 8+x, R9; ADCXQ 8+y, R9; \
+ MOVQ 16+x, R10; ADCXQ 16+y, R10; \
+ MOVQ 24+x, R11; ADCXQ 24+y, R11; \
+ CMOVQCS AX, DX ; \
+ XORL AX, AX; \
+ ADCXQ DX, R8; \
+ ADCXQ AX, R9; MOVQ R9, 8+z; \
+ ADCXQ AX, R10; MOVQ R10, 16+z; \
+ ADCXQ AX, R11; MOVQ R11, 24+z; \
+ MOVL $38, DX; \
+ CMOVQCS DX, AX; \
+ ADDQ AX, R8; MOVQ R8, 0+z;
+
+// subtraction subtracts y from x and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov
+#define subtraction(z,x,y) \
+ MOVL $38, AX; \
+ MOVQ 0+x, R8; SUBQ 0+y, R8; \
+ MOVQ 8+x, R9; SBBQ 8+y, R9; \
+ MOVQ 16+x, R10; SBBQ 16+y, R10; \
+ MOVQ 24+x, R11; SBBQ 24+y, R11; \
+ MOVL $0, DX; \
+ CMOVQCS AX, DX; \
+ SUBQ DX, R8; \
+ SBBQ $0, R9; MOVQ R9, 8+z; \
+ SBBQ $0, R10; MOVQ R10, 16+z; \
+ SBBQ $0, R11; MOVQ R11, 24+z; \
+ MOVL $0, DX; \
+ CMOVQCS AX, DX; \
+ SUBQ DX, R8; MOVQ R8, 0+z;
+
+// integerMulAdx multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerMulAdx(z,x,y) \
+ MOVL $0,R15; \
+ MOVQ 0+y, DX; XORL AX, AX; \
+ MULXQ 0+x, AX, R8; MOVQ AX, 0+z; \
+ MULXQ 8+x, AX, R9; ADCXQ AX, R8; \
+ MULXQ 16+x, AX, R10; ADCXQ AX, R9; \
+ MULXQ 24+x, AX, R11; ADCXQ AX, R10; \
+ MOVL $0, AX;;;;;;;;; ADCXQ AX, R11; \
+ MOVQ 8+y, DX; XORL AX, AX; \
+ MULXQ 0+x, AX, R12; ADCXQ R8, AX; MOVQ AX, 8+z; \
+ MULXQ 8+x, AX, R13; ADCXQ R9, R12; ADOXQ AX, R12; \
+ MULXQ 16+x, AX, R14; ADCXQ R10, R13; ADOXQ AX, R13; \
+ MULXQ 24+x, AX, R15; ADCXQ R11, R14; ADOXQ AX, R14; \
+ MOVL $0, AX;;;;;;;;; ADCXQ AX, R15; ADOXQ AX, R15; \
+ MOVQ 16+y, DX; XORL AX, AX; \
+ MULXQ 0+x, AX, R8; ADCXQ R12, AX; MOVQ AX, 16+z; \
+ MULXQ 8+x, AX, R9; ADCXQ R13, R8; ADOXQ AX, R8; \
+ MULXQ 16+x, AX, R10; ADCXQ R14, R9; ADOXQ AX, R9; \
+ MULXQ 24+x, AX, R11; ADCXQ R15, R10; ADOXQ AX, R10; \
+ MOVL $0, AX;;;;;;;;; ADCXQ AX, R11; ADOXQ AX, R11; \
+ MOVQ 24+y, DX; XORL AX, AX; \
+ MULXQ 0+x, AX, R12; ADCXQ R8, AX; MOVQ AX, 24+z; \
+ MULXQ 8+x, AX, R13; ADCXQ R9, R12; ADOXQ AX, R12; MOVQ R12, 32+z; \
+ MULXQ 16+x, AX, R14; ADCXQ R10, R13; ADOXQ AX, R13; MOVQ R13, 40+z; \
+ MULXQ 24+x, AX, R15; ADCXQ R11, R14; ADOXQ AX, R14; MOVQ R14, 48+z; \
+ MOVL $0, AX;;;;;;;;; ADCXQ AX, R15; ADOXQ AX, R15; MOVQ R15, 56+z;
+
+// integerMulLeg multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerMulLeg(z,x,y) \
+ MOVQ 0+y, R8; \
+ MOVQ 0+x, AX; MULQ R8; MOVQ AX, 0+z; MOVQ DX, R15; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R8; \
+ ADDQ R13, R15; \
+ ADCQ R14, R10; MOVQ R10, 16+z; \
+ ADCQ AX, R11; MOVQ R11, 24+z; \
+ ADCQ $0, DX; MOVQ DX, 32+z; \
+ MOVQ 8+y, R8; \
+ MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R8; \
+ ADDQ R12, R15; MOVQ R15, 8+z; \
+ ADCQ R13, R9; \
+ ADCQ R14, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, DX; \
+ ADCQ 16+z, R9; MOVQ R9, R15; \
+ ADCQ 24+z, R10; MOVQ R10, 24+z; \
+ ADCQ 32+z, R11; MOVQ R11, 32+z; \
+ ADCQ $0, DX; MOVQ DX, 40+z; \
+ MOVQ 16+y, R8; \
+ MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R8; \
+ ADDQ R12, R15; MOVQ R15, 16+z; \
+ ADCQ R13, R9; \
+ ADCQ R14, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, DX; \
+ ADCQ 24+z, R9; MOVQ R9, R15; \
+ ADCQ 32+z, R10; MOVQ R10, 32+z; \
+ ADCQ 40+z, R11; MOVQ R11, 40+z; \
+ ADCQ $0, DX; MOVQ DX, 48+z; \
+ MOVQ 24+y, R8; \
+ MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R8; \
+ ADDQ R12, R15; MOVQ R15, 24+z; \
+ ADCQ R13, R9; \
+ ADCQ R14, R10; \
+ ADCQ AX, R11; \
+ ADCQ $0, DX; \
+ ADCQ 32+z, R9; MOVQ R9, 32+z; \
+ ADCQ 40+z, R10; MOVQ R10, 40+z; \
+ ADCQ 48+z, R11; MOVQ R11, 48+z; \
+ ADCQ $0, DX; MOVQ DX, 56+z;
+
+// integerSqrLeg squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerSqrLeg(z,x) \
+ MOVQ 0+x, R8; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, R9; MOVQ DX, R10; /* A[0]*A[1] */ \
+ MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; /* A[0]*A[2] */ \
+ MOVQ 24+x, AX; MULQ R8; MOVQ AX, R15; MOVQ DX, R12; /* A[0]*A[3] */ \
+ MOVQ 24+x, R8; \
+ MOVQ 8+x, AX; MULQ R8; MOVQ AX, CX; MOVQ DX, R13; /* A[3]*A[1] */ \
+ MOVQ 16+x, AX; MULQ R8; /* A[3]*A[2] */ \
+ \
+ ADDQ R14, R10;\
+ ADCQ R15, R11; MOVL $0, R15;\
+ ADCQ CX, R12;\
+ ADCQ AX, R13;\
+ ADCQ $0, DX; MOVQ DX, R14;\
+ MOVQ 8+x, AX; MULQ 16+x;\
+ \
+ ADDQ AX, R11;\
+ ADCQ DX, R12;\
+ ADCQ $0, R13;\
+ ADCQ $0, R14;\
+ ADCQ $0, R15;\
+ \
+ SHLQ $1, R14, R15; MOVQ R15, 56+z;\
+ SHLQ $1, R13, R14; MOVQ R14, 48+z;\
+ SHLQ $1, R12, R13; MOVQ R13, 40+z;\
+ SHLQ $1, R11, R12; MOVQ R12, 32+z;\
+ SHLQ $1, R10, R11; MOVQ R11, 24+z;\
+ SHLQ $1, R9, R10; MOVQ R10, 16+z;\
+ SHLQ $1, R9; MOVQ R9, 8+z;\
+ \
+ MOVQ 0+x,AX; MULQ AX; MOVQ AX, 0+z; MOVQ DX, R9;\
+ MOVQ 8+x,AX; MULQ AX; MOVQ AX, R10; MOVQ DX, R11;\
+ MOVQ 16+x,AX; MULQ AX; MOVQ AX, R12; MOVQ DX, R13;\
+ MOVQ 24+x,AX; MULQ AX; MOVQ AX, R14; MOVQ DX, R15;\
+ \
+ ADDQ 8+z, R9; MOVQ R9, 8+z;\
+ ADCQ 16+z, R10; MOVQ R10, 16+z;\
+ ADCQ 24+z, R11; MOVQ R11, 24+z;\
+ ADCQ 32+z, R12; MOVQ R12, 32+z;\
+ ADCQ 40+z, R13; MOVQ R13, 40+z;\
+ ADCQ 48+z, R14; MOVQ R14, 48+z;\
+ ADCQ 56+z, R15; MOVQ R15, 56+z;
+
+// integerSqrAdx squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerSqrAdx(z,x) \
+ MOVQ 0+x, DX; /* A[0] */ \
+ MULXQ 8+x, R8, R14; /* A[1]*A[0] */ XORL R15, R15; \
+ MULXQ 16+x, R9, R10; /* A[2]*A[0] */ ADCXQ R14, R9; \
+ MULXQ 24+x, AX, CX; /* A[3]*A[0] */ ADCXQ AX, R10; \
+ MOVQ 24+x, DX; /* A[3] */ \
+ MULXQ 8+x, R11, R12; /* A[1]*A[3] */ ADCXQ CX, R11; \
+ MULXQ 16+x, AX, R13; /* A[2]*A[3] */ ADCXQ AX, R12; \
+ MOVQ 8+x, DX; /* A[1] */ ADCXQ R15, R13; \
+ MULXQ 16+x, AX, CX; /* A[2]*A[1] */ MOVL $0, R14; \
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADCXQ R15, R14; \
+ XORL R15, R15; \
+ ADOXQ AX, R10; ADCXQ R8, R8; \
+ ADOXQ CX, R11; ADCXQ R9, R9; \
+ ADOXQ R15, R12; ADCXQ R10, R10; \
+ ADOXQ R15, R13; ADCXQ R11, R11; \
+ ADOXQ R15, R14; ADCXQ R12, R12; \
+ ;;;;;;;;;;;;;;; ADCXQ R13, R13; \
+ ;;;;;;;;;;;;;;; ADCXQ R14, R14; \
+ MOVQ 0+x, DX; MULXQ DX, AX, CX; /* A[0]^2 */ \
+ ;;;;;;;;;;;;;;; MOVQ AX, 0+z; \
+ ADDQ CX, R8; MOVQ R8, 8+z; \
+ MOVQ 8+x, DX; MULXQ DX, AX, CX; /* A[1]^2 */ \
+ ADCQ AX, R9; MOVQ R9, 16+z; \
+ ADCQ CX, R10; MOVQ R10, 24+z; \
+ MOVQ 16+x, DX; MULXQ DX, AX, CX; /* A[2]^2 */ \
+ ADCQ AX, R11; MOVQ R11, 32+z; \
+ ADCQ CX, R12; MOVQ R12, 40+z; \
+ MOVQ 24+x, DX; MULXQ DX, AX, CX; /* A[3]^2 */ \
+ ADCQ AX, R13; MOVQ R13, 48+z; \
+ ADCQ CX, R14; MOVQ R14, 56+z;
+
+// reduceFromDouble finds z congruent to x modulo p such that 0> 63)
+ // PUT BIT 255 IN CARRY FLAG AND CLEAR
+ x3 &^= 1 << 63
+
+ x0, c0 := bits.Add64(x0, cx, 0)
+ x1, c1 := bits.Add64(x1, 0, c0)
+ x2, c2 := bits.Add64(x2, 0, c1)
+ x3, _ = bits.Add64(x3, 0, c2)
+
+ // TEST FOR BIT 255 AGAIN; ONLY TRIGGERED ON OVERFLOW MODULO 2^255-19
+ // cx = C[255] ? 0 : 19
+ cx = uint64(19) &^ (-(x3 >> 63))
+ // CLEAR BIT 255
+ x3 &^= 1 << 63
+
+ x0, c0 = bits.Sub64(x0, cx, 0)
+ x1, c1 = bits.Sub64(x1, 0, c0)
+ x2, c2 = bits.Sub64(x2, 0, c1)
+ x3, _ = bits.Sub64(x3, 0, c2)
+
+ binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+ binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+ binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+ binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+}
+
+func red64(z *Elt, x0, x1, x2, x3, x4, x5, x6, x7 uint64) {
+ h0, l0 := bits.Mul64(x4, 38)
+ h1, l1 := bits.Mul64(x5, 38)
+ h2, l2 := bits.Mul64(x6, 38)
+ h3, l3 := bits.Mul64(x7, 38)
+
+ l1, c0 := bits.Add64(h0, l1, 0)
+ l2, c1 := bits.Add64(h1, l2, c0)
+ l3, c2 := bits.Add64(h2, l3, c1)
+ l4, _ := bits.Add64(h3, 0, c2)
+
+ l0, c0 = bits.Add64(l0, x0, 0)
+ l1, c1 = bits.Add64(l1, x1, c0)
+ l2, c2 = bits.Add64(l2, x2, c1)
+ l3, c3 := bits.Add64(l3, x3, c2)
+ l4, _ = bits.Add64(l4, 0, c3)
+
+ _, l4 = bits.Mul64(l4, 38)
+ l0, c0 = bits.Add64(l0, l4, 0)
+ z1, c1 := bits.Add64(l1, 0, c0)
+ z2, c2 := bits.Add64(l2, 0, c1)
+ z3, c3 := bits.Add64(l3, 0, c2)
+ z0, _ := bits.Add64(l0, (-c3)&38, 0)
+
+ binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+ binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+ binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+ binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go
new file mode 100644
index 0000000..26ca4d0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go
@@ -0,0 +1,13 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package fp25519
+
+func cmov(x, y *Elt, n uint) { cmovGeneric(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapGeneric(x, y, n) }
+func add(z, x, y *Elt) { addGeneric(z, x, y) }
+func sub(z, x, y *Elt) { subGeneric(z, x, y) }
+func addsub(x, y *Elt) { addsubGeneric(x, y) }
+func mul(z, x, y *Elt) { mulGeneric(z, x, y) }
+func sqr(z, x *Elt) { sqrGeneric(z, x) }
+func modp(z *Elt) { modpGeneric(z) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp.go b/vendor/github.com/cloudflare/circl/math/fp448/fp.go
new file mode 100644
index 0000000..a5e3660
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp.go
@@ -0,0 +1,164 @@
+// Package fp448 provides prime field arithmetic over GF(2^448-2^224-1).
+package fp448
+
+import (
+ "errors"
+
+ "github.com/cloudflare/circl/internal/conv"
+)
+
+// Size in bytes of an element.
+const Size = 56
+
+// Elt is a prime field element.
+type Elt [Size]byte
+
+func (e Elt) String() string { return conv.BytesLe2Hex(e[:]) }
+
+// p is the prime modulus 2^448-2^224-1.
+var p = Elt{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+}
+
+// P returns the prime modulus 2^448-2^224-1.
+func P() Elt { return p }
+
+// ToBytes stores in b the little-endian byte representation of x.
+func ToBytes(b []byte, x *Elt) error {
+ if len(b) != Size {
+ return errors.New("wrong size")
+ }
+ Modp(x)
+ copy(b, x[:])
+ return nil
+}
+
+// IsZero returns true if x is equal to 0.
+func IsZero(x *Elt) bool { Modp(x); return *x == Elt{} }
+
+// IsOne returns true if x is equal to 1.
+func IsOne(x *Elt) bool { Modp(x); return *x == Elt{1} }
+
+// SetOne assigns x=1.
+func SetOne(x *Elt) { *x = Elt{1} }
+
+// One returns the 1 element.
+func One() (x Elt) { x = Elt{1}; return }
+
+// Neg calculates z = -x.
+func Neg(z, x *Elt) { Sub(z, &p, x) }
+
+// Modp ensures that z is between [0,p-1].
+func Modp(z *Elt) { Sub(z, z, &p) }
+
+// InvSqrt calculates z = sqrt(x/y) iff x/y is a quadratic-residue. If so,
+// isQR = true; otherwise, isQR = false, since x/y is a quadratic non-residue,
+// and z = sqrt(-x/y).
+func InvSqrt(z, x, y *Elt) (isQR bool) {
+ // First note that x^(2(k+1)) = x^(p-1)/2 * x = legendre(x) * x
+ // so that's x if x is a quadratic residue and -x otherwise.
+ // Next, y^(6k+3) = y^(4k+2) * y^(2k+1) = y^(p-1) * y^((p-1)/2) = legendre(y).
+ // So the z we compute satisfies z^2 y = x^(2(k+1)) y^(6k+3) = legendre(x)*legendre(y).
+ // Thus if x and y are quadratic residues, then z is indeed sqrt(x/y).
+ t0, t1 := &Elt{}, &Elt{}
+ Mul(t0, x, y) // x*y
+ Sqr(t1, y) // y^2
+ Mul(t1, t0, t1) // x*y^3
+ powPminus3div4(z, t1) // (x*y^3)^k
+ Mul(z, z, t0) // z = x*y*(x*y^3)^k = x^(k+1) * y^(3k+1)
+
+ // Check if x/y is a quadratic residue
+ Sqr(t0, z) // z^2
+ Mul(t0, t0, y) // y*z^2
+ Sub(t0, t0, x) // y*z^2-x
+ return IsZero(t0)
+}
+
+// Inv calculates z = 1/x mod p.
+func Inv(z, x *Elt) {
+ // Calculates z = x^(4k+1) = x^(p-3+1) = x^(p-2) = x^-1, where k = (p-3)/4.
+ t := &Elt{}
+ powPminus3div4(t, x) // t = x^k
+ Sqr(t, t) // t = x^2k
+ Sqr(t, t) // t = x^4k
+ Mul(z, t, x) // z = x^(4k+1)
+}
+
+// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
+func powPminus3div4(z, x *Elt) {
+ x0, x1 := &Elt{}, &Elt{}
+ Sqr(z, x)
+ Mul(z, z, x)
+ Sqr(x0, z)
+ Mul(x0, x0, x)
+ Sqr(z, x0)
+ Sqr(z, z)
+ Sqr(z, z)
+ Mul(z, z, x0)
+ Sqr(x1, z)
+ for i := 0; i < 5; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, z)
+ Sqr(z, x1)
+ for i := 0; i < 11; i++ {
+ Sqr(z, z)
+ }
+ Mul(z, z, x1)
+ Sqr(z, z)
+ Sqr(z, z)
+ Sqr(z, z)
+ Mul(z, z, x0)
+ Sqr(x1, z)
+ for i := 0; i < 26; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, z)
+ Sqr(z, x1)
+ for i := 0; i < 53; i++ {
+ Sqr(z, z)
+ }
+ Mul(z, z, x1)
+ Sqr(z, z)
+ Sqr(z, z)
+ Sqr(z, z)
+ Mul(z, z, x0)
+ Sqr(x1, z)
+ for i := 0; i < 110; i++ {
+ Sqr(x1, x1)
+ }
+ Mul(x1, x1, z)
+ Sqr(z, x1)
+ Mul(z, z, x)
+ for i := 0; i < 223; i++ {
+ Sqr(z, z)
+ }
+ Mul(z, z, x1)
+}
+
+// Cmov assigns y to x if n is 1.
+func Cmov(x, y *Elt, n uint) { cmov(x, y, n) }
+
+// Cswap interchanges x and y if n is 1.
+func Cswap(x, y *Elt, n uint) { cswap(x, y, n) }
+
+// Add calculates z = x+y mod p.
+func Add(z, x, y *Elt) { add(z, x, y) }
+
+// Sub calculates z = x-y mod p.
+func Sub(z, x, y *Elt) { sub(z, x, y) }
+
+// AddSub calculates (x,y) = (x+y mod p, x-y mod p).
+func AddSub(x, y *Elt) { addsub(x, y) }
+
+// Mul calculates z = x*y mod p.
+func Mul(z, x, y *Elt) { mul(z, x, y) }
+
+// Sqr calculates z = x^2 mod p.
+func Sqr(z, x *Elt) { sqr(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go
new file mode 100644
index 0000000..6a12209
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go
@@ -0,0 +1,43 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package fp448
+
+import (
+ "golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func cmov(x, y *Elt, n uint) { cmovAmd64(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapAmd64(x, y, n) }
+func add(z, x, y *Elt) { addAmd64(z, x, y) }
+func sub(z, x, y *Elt) { subAmd64(z, x, y) }
+func addsub(x, y *Elt) { addsubAmd64(x, y) }
+func mul(z, x, y *Elt) { mulAmd64(z, x, y) }
+func sqr(z, x *Elt) { sqrAmd64(z, x) }
+
+/* Functions defined in fp_amd64.s */
+
+//go:noescape
+func cmovAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func cswapAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func addAmd64(z, x, y *Elt)
+
+//go:noescape
+func subAmd64(z, x, y *Elt)
+
+//go:noescape
+func addsubAmd64(x, y *Elt)
+
+//go:noescape
+func mulAmd64(z, x, y *Elt)
+
+//go:noescape
+func sqrAmd64(z, x *Elt)
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h
new file mode 100644
index 0000000..536fe5b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h
@@ -0,0 +1,591 @@
+// This code was imported from https://github.com/armfazh/rfc7748_precomputed
+
+// CHECK_BMI2ADX triggers bmi2adx if supported,
+// otherwise it fallbacks to legacy code.
+#define CHECK_BMI2ADX(label, legacy, bmi2adx) \
+ CMPB ·hasBmi2Adx(SB), $0 \
+ JE label \
+ bmi2adx \
+ RET \
+ label: \
+ legacy \
+ RET
+
+// cselect is a conditional move
+// if b=1: it copies y into x;
+// if b=0: x remains with the same value;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, FLAGS
+// Instr: x86_64, cmov
+#define cselect(x,y,b) \
+ TESTQ b, b \
+ MOVQ 0+x, AX; MOVQ 0+y, DX; CMOVQNE DX, AX; MOVQ AX, 0+x; \
+ MOVQ 8+x, AX; MOVQ 8+y, DX; CMOVQNE DX, AX; MOVQ AX, 8+x; \
+ MOVQ 16+x, AX; MOVQ 16+y, DX; CMOVQNE DX, AX; MOVQ AX, 16+x; \
+ MOVQ 24+x, AX; MOVQ 24+y, DX; CMOVQNE DX, AX; MOVQ AX, 24+x; \
+ MOVQ 32+x, AX; MOVQ 32+y, DX; CMOVQNE DX, AX; MOVQ AX, 32+x; \
+ MOVQ 40+x, AX; MOVQ 40+y, DX; CMOVQNE DX, AX; MOVQ AX, 40+x; \
+ MOVQ 48+x, AX; MOVQ 48+y, DX; CMOVQNE DX, AX; MOVQ AX, 48+x;
+
+// cswap is a conditional swap
+// if b=1: x,y <- y,x;
+// if b=0: x,y remain with the same values;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, R8, FLAGS
+// Instr: x86_64, cmov
+#define cswap(x,y,b) \
+ TESTQ b, b \
+ MOVQ 0+x, AX; MOVQ AX, R8; MOVQ 0+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 0+x; MOVQ DX, 0+y; \
+ MOVQ 8+x, AX; MOVQ AX, R8; MOVQ 8+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 8+x; MOVQ DX, 8+y; \
+ MOVQ 16+x, AX; MOVQ AX, R8; MOVQ 16+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 16+x; MOVQ DX, 16+y; \
+ MOVQ 24+x, AX; MOVQ AX, R8; MOVQ 24+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 24+x; MOVQ DX, 24+y; \
+ MOVQ 32+x, AX; MOVQ AX, R8; MOVQ 32+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 32+x; MOVQ DX, 32+y; \
+ MOVQ 40+x, AX; MOVQ AX, R8; MOVQ 40+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 40+x; MOVQ DX, 40+y; \
+ MOVQ 48+x, AX; MOVQ AX, R8; MOVQ 48+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 48+x; MOVQ DX, 48+y;
+
+// additionLeg adds x and y and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64
+#define additionLeg(z,x,y) \
+ MOVQ 0+x, R8; ADDQ 0+y, R8; \
+ MOVQ 8+x, R9; ADCQ 8+y, R9; \
+ MOVQ 16+x, R10; ADCQ 16+y, R10; \
+ MOVQ 24+x, R11; ADCQ 24+y, R11; \
+ MOVQ 32+x, R12; ADCQ 32+y, R12; \
+ MOVQ 40+x, R13; ADCQ 40+y, R13; \
+ MOVQ 48+x, R14; ADCQ 48+y, R14; \
+ MOVQ $0, AX; ADCQ $0, AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ ADDQ AX, R8; MOVQ $0, AX; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ DX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ ADCQ $0, AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ ADDQ AX, R8; MOVQ R8, 0+z; \
+ ADCQ $0, R9; MOVQ R9, 8+z; \
+ ADCQ $0, R10; MOVQ R10, 16+z; \
+ ADCQ DX, R11; MOVQ R11, 24+z; \
+ ADCQ $0, R12; MOVQ R12, 32+z; \
+ ADCQ $0, R13; MOVQ R13, 40+z; \
+ ADCQ $0, R14; MOVQ R14, 48+z;
+
+
+// additionAdx adds x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, adx
+#define additionAdx(z,x,y) \
+ MOVL $32, R15; \
+ XORL DX, DX; \
+ MOVQ 0+x, R8; ADCXQ 0+y, R8; \
+ MOVQ 8+x, R9; ADCXQ 8+y, R9; \
+ MOVQ 16+x, R10; ADCXQ 16+y, R10; \
+ MOVQ 24+x, R11; ADCXQ 24+y, R11; \
+ MOVQ 32+x, R12; ADCXQ 32+y, R12; \
+ MOVQ 40+x, R13; ADCXQ 40+y, R13; \
+ MOVQ 48+x, R14; ADCXQ 48+y, R14; \
+ ;;;;;;;;;;;;;;; ADCXQ DX, DX; \
+ XORL AX, AX; \
+ ADCXQ DX, R8; SHLXQ R15, DX, DX; \
+ ADCXQ AX, R9; \
+ ADCXQ AX, R10; \
+ ADCXQ DX, R11; \
+ ADCXQ AX, R12; \
+ ADCXQ AX, R13; \
+ ADCXQ AX, R14; \
+ ADCXQ AX, AX; \
+ XORL DX, DX; \
+ ADCXQ AX, R8; MOVQ R8, 0+z; SHLXQ R15, AX, AX; \
+ ADCXQ DX, R9; MOVQ R9, 8+z; \
+ ADCXQ DX, R10; MOVQ R10, 16+z; \
+ ADCXQ AX, R11; MOVQ R11, 24+z; \
+ ADCXQ DX, R12; MOVQ R12, 32+z; \
+ ADCXQ DX, R13; MOVQ R13, 40+z; \
+ ADCXQ DX, R14; MOVQ R14, 48+z;
+
+// subtraction subtracts y from x and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64
+#define subtraction(z,x,y) \
+ MOVQ 0+x, R8; SUBQ 0+y, R8; \
+ MOVQ 8+x, R9; SBBQ 8+y, R9; \
+ MOVQ 16+x, R10; SBBQ 16+y, R10; \
+ MOVQ 24+x, R11; SBBQ 24+y, R11; \
+ MOVQ 32+x, R12; SBBQ 32+y, R12; \
+ MOVQ 40+x, R13; SBBQ 40+y, R13; \
+ MOVQ 48+x, R14; SBBQ 48+y, R14; \
+ MOVQ $0, AX; SETCS AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ SUBQ AX, R8; MOVQ $0, AX; \
+ SBBQ $0, R9; \
+ SBBQ $0, R10; \
+ SBBQ DX, R11; \
+ SBBQ $0, R12; \
+ SBBQ $0, R13; \
+ SBBQ $0, R14; \
+ SETCS AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ SUBQ AX, R8; MOVQ R8, 0+z; \
+ SBBQ $0, R9; MOVQ R9, 8+z; \
+ SBBQ $0, R10; MOVQ R10, 16+z; \
+ SBBQ DX, R11; MOVQ R11, 24+z; \
+ SBBQ $0, R12; MOVQ R12, 32+z; \
+ SBBQ $0, R13; MOVQ R13, 40+z; \
+ SBBQ $0, R14; MOVQ R14, 48+z;
+
+// maddBmi2Adx multiplies x and y and accumulates in z
+// Uses: AX, DX, R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define maddBmi2Adx(z,x,y,i,r0,r1,r2,r3,r4,r5,r6) \
+ MOVQ i+y, DX; XORL AX, AX; \
+ MULXQ 0+x, AX, R8; ADOXQ AX, r0; ADCXQ R8, r1; MOVQ r0,i+z; \
+ MULXQ 8+x, AX, r0; ADOXQ AX, r1; ADCXQ r0, r2; MOVQ $0, R8; \
+ MULXQ 16+x, AX, r0; ADOXQ AX, r2; ADCXQ r0, r3; \
+ MULXQ 24+x, AX, r0; ADOXQ AX, r3; ADCXQ r0, r4; \
+ MULXQ 32+x, AX, r0; ADOXQ AX, r4; ADCXQ r0, r5; \
+ MULXQ 40+x, AX, r0; ADOXQ AX, r5; ADCXQ r0, r6; \
+ MULXQ 48+x, AX, r0; ADOXQ AX, r6; ADCXQ R8, r0; \
+ ;;;;;;;;;;;;;;;;;;; ADOXQ R8, r0;
+
+// integerMulAdx multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerMulAdx(z,x,y) \
+ MOVL $0,R15; \
+ MOVQ 0+y, DX; XORL AX, AX; MOVQ $0, R8; \
+ MULXQ 0+x, AX, R9; MOVQ AX, 0+z; \
+ MULXQ 8+x, AX, R10; ADCXQ AX, R9; \
+ MULXQ 16+x, AX, R11; ADCXQ AX, R10; \
+ MULXQ 24+x, AX, R12; ADCXQ AX, R11; \
+ MULXQ 32+x, AX, R13; ADCXQ AX, R12; \
+ MULXQ 40+x, AX, R14; ADCXQ AX, R13; \
+ MULXQ 48+x, AX, R15; ADCXQ AX, R14; \
+ ;;;;;;;;;;;;;;;;;;;; ADCXQ R8, R15; \
+ maddBmi2Adx(z,x,y, 8, R9,R10,R11,R12,R13,R14,R15) \
+ maddBmi2Adx(z,x,y,16,R10,R11,R12,R13,R14,R15, R9) \
+ maddBmi2Adx(z,x,y,24,R11,R12,R13,R14,R15, R9,R10) \
+ maddBmi2Adx(z,x,y,32,R12,R13,R14,R15, R9,R10,R11) \
+ maddBmi2Adx(z,x,y,40,R13,R14,R15, R9,R10,R11,R12) \
+ maddBmi2Adx(z,x,y,48,R14,R15, R9,R10,R11,R12,R13) \
+ MOVQ R15, 56+z; \
+ MOVQ R9, 64+z; \
+ MOVQ R10, 72+z; \
+ MOVQ R11, 80+z; \
+ MOVQ R12, 88+z; \
+ MOVQ R13, 96+z; \
+ MOVQ R14, 104+z;
+
+// maddLegacy multiplies x and y and accumulates in z
+// Uses: AX, DX, R15, FLAGS
+// Instr: x86_64
+#define maddLegacy(z,x,y,i) \
+ MOVQ i+y, R15; \
+ MOVQ 0+x, AX; MULQ R15; MOVQ AX, R8; ;;;;;;;;;;;; MOVQ DX, R9; \
+ MOVQ 8+x, AX; MULQ R15; ADDQ AX, R9; ADCQ $0, DX; MOVQ DX, R10; \
+ MOVQ 16+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
+ MOVQ 24+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
+ MOVQ 32+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
+ MOVQ 40+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
+ MOVQ 48+x, AX; MULQ R15; ADDQ AX, R14; ADCQ $0, DX; \
+ ADDQ 0+i+z, R8; MOVQ R8, 0+i+z; \
+ ADCQ 8+i+z, R9; MOVQ R9, 8+i+z; \
+ ADCQ 16+i+z, R10; MOVQ R10, 16+i+z; \
+ ADCQ 24+i+z, R11; MOVQ R11, 24+i+z; \
+ ADCQ 32+i+z, R12; MOVQ R12, 32+i+z; \
+ ADCQ 40+i+z, R13; MOVQ R13, 40+i+z; \
+ ADCQ 48+i+z, R14; MOVQ R14, 48+i+z; \
+ ADCQ $0, DX; MOVQ DX, 56+i+z;
+
+// integerMulLeg multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerMulLeg(z,x,y) \
+ MOVQ 0+y, R15; \
+ MOVQ 0+x, AX; MULQ R15; MOVQ AX, 0+z; ;;;;;;;;;;;; MOVQ DX, R8; \
+ MOVQ 8+x, AX; MULQ R15; ADDQ AX, R8; ADCQ $0, DX; MOVQ DX, R9; MOVQ R8, 8+z; \
+ MOVQ 16+x, AX; MULQ R15; ADDQ AX, R9; ADCQ $0, DX; MOVQ DX, R10; MOVQ R9, 16+z; \
+ MOVQ 24+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; MOVQ R10, 24+z; \
+ MOVQ 32+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; MOVQ R11, 32+z; \
+ MOVQ 40+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; MOVQ R12, 40+z; \
+ MOVQ 48+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX,56+z; MOVQ R13, 48+z; \
+ maddLegacy(z,x,y, 8) \
+ maddLegacy(z,x,y,16) \
+ maddLegacy(z,x,y,24) \
+ maddLegacy(z,x,y,32) \
+ maddLegacy(z,x,y,40) \
+ maddLegacy(z,x,y,48)
+
+// integerSqrLeg squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerSqrLeg(z,x) \
+ XORL R15, R15; \
+ MOVQ 0+x, CX; \
+ MOVQ CX, AX; MULQ CX; MOVQ AX, 0+z; MOVQ DX, R8; \
+ ADDQ CX, CX; ADCQ $0, R15; \
+ MOVQ 8+x, AX; MULQ CX; ADDQ AX, R8; ADCQ $0, DX; MOVQ DX, R9; MOVQ R8, 8+z; \
+ MOVQ 16+x, AX; MULQ CX; ADDQ AX, R9; ADCQ $0, DX; MOVQ DX, R10; \
+ MOVQ 24+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
+ MOVQ 32+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
+ MOVQ 40+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
+ \
+ MOVQ 8+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R9; ADCQ $0, DX; MOVQ R9,16+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 8+x, AX; ADDQ AX, DX; ADCQ $0, R11; MOVQ DX, R8; \
+ ADDQ 8+x, CX; ADCQ $0, R15; \
+ MOVQ 16+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX, R8; MOVQ R10, 24+z; \
+ MOVQ 24+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; ADDQ R8, R11; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 32+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 40+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; ADDQ R8, R13; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R9; \
+ \
+ MOVQ 16+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ R11, 32+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 16+x,AX; ADDQ AX, DX; ADCQ $0, R13; MOVQ DX, R8; \
+ ADDQ 16+x, CX; ADCQ $0, R15; \
+ MOVQ 24+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; MOVQ R12, 40+z; \
+ MOVQ 32+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; ADDQ R8, R13; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 40+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R9; ADCQ $0, DX; ADDQ R8, R9; ADCQ $0, DX; MOVQ DX,R10; \
+ \
+ MOVQ 24+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ R13, 48+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 24+x,AX; ADDQ AX, DX; ADCQ $0, R9; MOVQ DX, R8; \
+ ADDQ 24+x, CX; ADCQ $0, R15; \
+ MOVQ 32+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R8; MOVQ R14, 56+z; \
+ MOVQ 40+x, AX; MULQ CX; ADDQ AX, R9; ADCQ $0, DX; ADDQ R8, R9; ADCQ $0, DX; MOVQ DX, R8; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX,R11; \
+ \
+ MOVQ 32+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R9; ADCQ $0, DX; MOVQ R9, 64+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 32+x,AX; ADDQ AX, DX; ADCQ $0, R11; MOVQ DX, R8; \
+ ADDQ 32+x, CX; ADCQ $0, R15; \
+ MOVQ 40+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX, R8; MOVQ R10, 72+z; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; ADDQ R8, R11; ADCQ $0, DX; MOVQ DX,R12; \
+ \
+ XORL R13, R13; \
+ XORL R14, R14; \
+ MOVQ 40+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ R11, 80+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 40+x,AX; ADDQ AX, DX; ADCQ $0, R13; MOVQ DX, R8; \
+ ADDQ 40+x, CX; ADCQ $0, R15; \
+ MOVQ 48+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; MOVQ R12, 88+z; \
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADDQ R8, R13; ADCQ $0,R14; \
+ \
+ XORL R9, R9; \
+ MOVQ 48+x, CX; \
+ MOVQ CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+ ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ R13, 96+z; \
+ MOVQ R15, AX; NEGQ AX; ANDQ 48+x,AX; ADDQ AX, DX; ADCQ $0, R9; MOVQ DX, R8; \
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADDQ R8,R14; ADCQ $0, R9; MOVQ R14, 104+z;
+
+
+// integerSqrAdx squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerSqrAdx(z,x) \
+ XORL R15, R15; \
+ MOVQ 0+x, DX; \
+ ;;;;;;;;;;;;;; MULXQ DX, AX, R8; MOVQ AX, 0+z; \
+ ADDQ DX, DX; ADCQ $0, R15; CLC; \
+ MULXQ 8+x, AX, R9; ADCXQ AX, R8; MOVQ R8, 8+z; \
+ MULXQ 16+x, AX, R10; ADCXQ AX, R9; MOVQ $0, R8;\
+ MULXQ 24+x, AX, R11; ADCXQ AX, R10; \
+ MULXQ 32+x, AX, R12; ADCXQ AX, R11; \
+ MULXQ 40+x, AX, R13; ADCXQ AX, R12; \
+ MULXQ 48+x, AX, R14; ADCXQ AX, R13; \
+ ;;;;;;;;;;;;;;;;;;;; ADCXQ R8, R14; \
+ \
+ MOVQ 8+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 8+x, R8; \
+ ADDQ AX, R9; MOVQ R9, 16+z; \
+ ADCQ CX, R8; \
+ ADCQ $0, R11; \
+ ADDQ 8+x, DX; \
+ ADCQ $0, R15; \
+ XORL R9, R9; ;;;;;;;;;;;;;;;;;;;;; ADOXQ R8, R10; \
+ MULXQ 16+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; MOVQ R10, 24+z; \
+ MULXQ 24+x, AX, CX; ADCXQ AX, R11; ADOXQ CX, R12; MOVQ $0, R10; \
+ MULXQ 32+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; \
+ MULXQ 40+x, AX, CX; ADCXQ AX, R13; ADOXQ CX, R14; \
+ MULXQ 48+x, AX, CX; ADCXQ AX, R14; ADOXQ CX, R9; \
+ ;;;;;;;;;;;;;;;;;;; ADCXQ R10, R9; \
+ \
+ MOVQ 16+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 16+x, R8; \
+ ADDQ AX, R11; MOVQ R11, 32+z; \
+ ADCQ CX, R8; \
+ ADCQ $0, R13; \
+ ADDQ 16+x, DX; \
+ ADCQ $0, R15; \
+ XORL R11, R11; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R12; \
+ MULXQ 24+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; MOVQ R12, 40+z; \
+ MULXQ 32+x, AX, CX; ADCXQ AX, R13; ADOXQ CX, R14; MOVQ $0, R12; \
+ MULXQ 40+x, AX, CX; ADCXQ AX, R14; ADOXQ CX, R9; \
+ MULXQ 48+x, AX, CX; ADCXQ AX, R9; ADOXQ CX, R10; \
+ ;;;;;;;;;;;;;;;;;;; ADCXQ R11,R10; \
+ \
+ MOVQ 24+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 24+x, R8; \
+ ADDQ AX, R13; MOVQ R13, 48+z; \
+ ADCQ CX, R8; \
+ ADCQ $0, R9; \
+ ADDQ 24+x, DX; \
+ ADCQ $0, R15; \
+ XORL R13, R13; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R14; \
+ MULXQ 32+x, AX, CX; ADCXQ AX, R14; ADOXQ CX, R9; MOVQ R14, 56+z; \
+ MULXQ 40+x, AX, CX; ADCXQ AX, R9; ADOXQ CX, R10; MOVQ $0, R14; \
+ MULXQ 48+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; \
+ ;;;;;;;;;;;;;;;;;;; ADCXQ R12,R11; \
+ \
+ MOVQ 32+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 32+x, R8; \
+ ADDQ AX, R9; MOVQ R9, 64+z; \
+ ADCQ CX, R8; \
+ ADCQ $0, R11; \
+ ADDQ 32+x, DX; \
+ ADCQ $0, R15; \
+ XORL R9, R9; ;;;;;;;;;;;;;;;;;;;;; ADOXQ R8, R10; \
+ MULXQ 40+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; MOVQ R10, 72+z; \
+ MULXQ 48+x, AX, CX; ADCXQ AX, R11; ADOXQ CX, R12; \
+ ;;;;;;;;;;;;;;;;;;; ADCXQ R13,R12; \
+ \
+ MOVQ 40+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 40+x, R8; \
+ ADDQ AX, R11; MOVQ R11, 80+z; \
+ ADCQ CX, R8; \
+ ADCQ $0, R13; \
+ ADDQ 40+x, DX; \
+ ADCQ $0, R15; \
+ XORL R11, R11; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R12; \
+ MULXQ 48+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; MOVQ R12, 88+z; \
+ ;;;;;;;;;;;;;;;;;;; ADCXQ R14,R13; \
+ \
+ MOVQ 48+x, DX; \
+ MOVQ DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ $0, R15; \
+ MULXQ AX, AX, CX; \
+ MOVQ R15, R8; NEGQ R8; ANDQ 48+x, R8; \
+ XORL R10, R10; ;;;;;;;;;;;;;; ADOXQ CX, R14; \
+ ;;;;;;;;;;;;;; ADCXQ AX, R13; ;;;;;;;;;;;;;; MOVQ R13, 96+z; \
+ ;;;;;;;;;;;;;; ADCXQ R8, R14; MOVQ R14, 104+z;
+
+// reduceFromDoubleLeg finds a z=x modulo p such that z<2^448 and stores in z
+// Uses: AX, R8-R15, FLAGS
+// Instr: x86_64
+#define reduceFromDoubleLeg(z,x) \
+ /* ( ,2C13,2C12,2C11,2C10|C10,C9,C8, C7) + (C6,...,C0) */ \
+ /* (r14, r13, r12, r11, r10,r9,r8,r15) */ \
+ MOVQ 80+x,AX; MOVQ AX,R10; \
+ MOVQ $0xFFFFFFFF00000000, R8; \
+ ANDQ R8,R10; \
+ \
+ MOVQ $0,R14; \
+ MOVQ 104+x,R13; SHLQ $1,R13,R14; \
+ MOVQ 96+x,R12; SHLQ $1,R12,R13; \
+ MOVQ 88+x,R11; SHLQ $1,R11,R12; \
+ MOVQ 72+x, R9; SHLQ $1,R10,R11; \
+ MOVQ 64+x, R8; SHLQ $1,R10; \
+ MOVQ $0xFFFFFFFF,R15; ANDQ R15,AX; ORQ AX,R10; \
+ MOVQ 56+x,R15; \
+ \
+ ADDQ 0+x,R15; MOVQ R15, 0+z; MOVQ 56+x,R15; \
+ ADCQ 8+x, R8; MOVQ R8, 8+z; MOVQ 64+x, R8; \
+ ADCQ 16+x, R9; MOVQ R9,16+z; MOVQ 72+x, R9; \
+ ADCQ 24+x,R10; MOVQ R10,24+z; MOVQ 80+x,R10; \
+ ADCQ 32+x,R11; MOVQ R11,32+z; MOVQ 88+x,R11; \
+ ADCQ 40+x,R12; MOVQ R12,40+z; MOVQ 96+x,R12; \
+ ADCQ 48+x,R13; MOVQ R13,48+z; MOVQ 104+x,R13; \
+ ADCQ $0,R14; \
+ /* (c10c9,c9c8,c8c7,c7c13,c13c12,c12c11,c11c10) + (c6,...,c0) */ \
+ /* ( r9, r8, r15, r13, r12, r11, r10) */ \
+ MOVQ R10, AX; \
+ SHRQ $32,R11,R10; \
+ SHRQ $32,R12,R11; \
+ SHRQ $32,R13,R12; \
+ SHRQ $32,R15,R13; \
+ SHRQ $32, R8,R15; \
+ SHRQ $32, R9, R8; \
+ SHRQ $32, AX, R9; \
+ \
+ ADDQ 0+z,R10; \
+ ADCQ 8+z,R11; \
+ ADCQ 16+z,R12; \
+ ADCQ 24+z,R13; \
+ ADCQ 32+z,R15; \
+ ADCQ 40+z, R8; \
+ ADCQ 48+z, R9; \
+ ADCQ $0,R14; \
+ /* ( c7) + (c6,...,c0) */ \
+ /* (r14) */ \
+ MOVQ R14, AX; SHLQ $32, AX; \
+ ADDQ R14,R10; MOVQ $0,R14; \
+ ADCQ $0,R11; \
+ ADCQ $0,R12; \
+ ADCQ AX,R13; \
+ ADCQ $0,R15; \
+ ADCQ $0, R8; \
+ ADCQ $0, R9; \
+ ADCQ $0,R14; \
+ /* ( c7) + (c6,...,c0) */ \
+ /* (r14) */ \
+ MOVQ R14, AX; SHLQ $32,AX; \
+ ADDQ R14,R10; MOVQ R10, 0+z; \
+ ADCQ $0,R11; MOVQ R11, 8+z; \
+ ADCQ $0,R12; MOVQ R12,16+z; \
+ ADCQ AX,R13; MOVQ R13,24+z; \
+ ADCQ $0,R15; MOVQ R15,32+z; \
+ ADCQ $0, R8; MOVQ R8,40+z; \
+ ADCQ $0, R9; MOVQ R9,48+z;
+
+// reduceFromDoubleAdx finds a z=x modulo p such that z<2^448 and stores in z
+// Uses: AX, R8-R15, FLAGS
+// Instr: x86_64, adx
+#define reduceFromDoubleAdx(z,x) \
+ /* ( ,2C13,2C12,2C11,2C10|C10,C9,C8, C7) + (C6,...,C0) */ \
+ /* (r14, r13, r12, r11, r10,r9,r8,r15) */ \
+ MOVQ 80+x,AX; MOVQ AX,R10; \
+ MOVQ $0xFFFFFFFF00000000, R8; \
+ ANDQ R8,R10; \
+ \
+ MOVQ $0,R14; \
+ MOVQ 104+x,R13; SHLQ $1,R13,R14; \
+ MOVQ 96+x,R12; SHLQ $1,R12,R13; \
+ MOVQ 88+x,R11; SHLQ $1,R11,R12; \
+ MOVQ 72+x, R9; SHLQ $1,R10,R11; \
+ MOVQ 64+x, R8; SHLQ $1,R10; \
+ MOVQ $0xFFFFFFFF,R15; ANDQ R15,AX; ORQ AX,R10; \
+ MOVQ 56+x,R15; \
+ \
+ XORL AX,AX; \
+ ADCXQ 0+x,R15; MOVQ R15, 0+z; MOVQ 56+x,R15; \
+ ADCXQ 8+x, R8; MOVQ R8, 8+z; MOVQ 64+x, R8; \
+ ADCXQ 16+x, R9; MOVQ R9,16+z; MOVQ 72+x, R9; \
+ ADCXQ 24+x,R10; MOVQ R10,24+z; MOVQ 80+x,R10; \
+ ADCXQ 32+x,R11; MOVQ R11,32+z; MOVQ 88+x,R11; \
+ ADCXQ 40+x,R12; MOVQ R12,40+z; MOVQ 96+x,R12; \
+ ADCXQ 48+x,R13; MOVQ R13,48+z; MOVQ 104+x,R13; \
+ ADCXQ AX,R14; \
+ /* (c10c9,c9c8,c8c7,c7c13,c13c12,c12c11,c11c10) + (c6,...,c0) */ \
+ /* ( r9, r8, r15, r13, r12, r11, r10) */ \
+ MOVQ R10, AX; \
+ SHRQ $32,R11,R10; \
+ SHRQ $32,R12,R11; \
+ SHRQ $32,R13,R12; \
+ SHRQ $32,R15,R13; \
+ SHRQ $32, R8,R15; \
+ SHRQ $32, R9, R8; \
+ SHRQ $32, AX, R9; \
+ \
+ XORL AX,AX; \
+ ADCXQ 0+z,R10; \
+ ADCXQ 8+z,R11; \
+ ADCXQ 16+z,R12; \
+ ADCXQ 24+z,R13; \
+ ADCXQ 32+z,R15; \
+ ADCXQ 40+z, R8; \
+ ADCXQ 48+z, R9; \
+ ADCXQ AX,R14; \
+ /* ( c7) + (c6,...,c0) */ \
+ /* (r14) */ \
+ MOVQ R14, AX; SHLQ $32, AX; \
+ CLC; \
+ ADCXQ R14,R10; MOVQ $0,R14; \
+ ADCXQ R14,R11; \
+ ADCXQ R14,R12; \
+ ADCXQ AX,R13; \
+ ADCXQ R14,R15; \
+ ADCXQ R14, R8; \
+ ADCXQ R14, R9; \
+ ADCXQ R14,R14; \
+ /* ( c7) + (c6,...,c0) */ \
+ /* (r14) */ \
+ MOVQ R14, AX; SHLQ $32, AX; \
+ CLC; \
+ ADCXQ R14,R10; MOVQ R10, 0+z; MOVQ $0,R14; \
+ ADCXQ R14,R11; MOVQ R11, 8+z; \
+ ADCXQ R14,R12; MOVQ R12,16+z; \
+ ADCXQ AX,R13; MOVQ R13,24+z; \
+ ADCXQ R14,R15; MOVQ R15,32+z; \
+ ADCXQ R14, R8; MOVQ R8,40+z; \
+ ADCXQ R14, R9; MOVQ R9,48+z;
+
+// addSub calculates two operations: x,y = x+y,x-y
+// Uses: AX, DX, R8-R15, FLAGS
+#define addSub(x,y) \
+ MOVQ 0+x, R8; ADDQ 0+y, R8; \
+ MOVQ 8+x, R9; ADCQ 8+y, R9; \
+ MOVQ 16+x, R10; ADCQ 16+y, R10; \
+ MOVQ 24+x, R11; ADCQ 24+y, R11; \
+ MOVQ 32+x, R12; ADCQ 32+y, R12; \
+ MOVQ 40+x, R13; ADCQ 40+y, R13; \
+ MOVQ 48+x, R14; ADCQ 48+y, R14; \
+ MOVQ $0, AX; ADCQ $0, AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ ADDQ AX, R8; MOVQ $0, AX; \
+ ADCQ $0, R9; \
+ ADCQ $0, R10; \
+ ADCQ DX, R11; \
+ ADCQ $0, R12; \
+ ADCQ $0, R13; \
+ ADCQ $0, R14; \
+ ADCQ $0, AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ ADDQ AX, R8; MOVQ 0+x,AX; MOVQ R8, 0+x; MOVQ AX, R8; \
+ ADCQ $0, R9; MOVQ 8+x,AX; MOVQ R9, 8+x; MOVQ AX, R9; \
+ ADCQ $0, R10; MOVQ 16+x,AX; MOVQ R10, 16+x; MOVQ AX, R10; \
+ ADCQ DX, R11; MOVQ 24+x,AX; MOVQ R11, 24+x; MOVQ AX, R11; \
+ ADCQ $0, R12; MOVQ 32+x,AX; MOVQ R12, 32+x; MOVQ AX, R12; \
+ ADCQ $0, R13; MOVQ 40+x,AX; MOVQ R13, 40+x; MOVQ AX, R13; \
+ ADCQ $0, R14; MOVQ 48+x,AX; MOVQ R14, 48+x; MOVQ AX, R14; \
+ SUBQ 0+y, R8; \
+ SBBQ 8+y, R9; \
+ SBBQ 16+y, R10; \
+ SBBQ 24+y, R11; \
+ SBBQ 32+y, R12; \
+ SBBQ 40+y, R13; \
+ SBBQ 48+y, R14; \
+ MOVQ $0, AX; SETCS AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ SUBQ AX, R8; MOVQ $0, AX; \
+ SBBQ $0, R9; \
+ SBBQ $0, R10; \
+ SBBQ DX, R11; \
+ SBBQ $0, R12; \
+ SBBQ $0, R13; \
+ SBBQ $0, R14; \
+ SETCS AX; \
+ MOVQ AX, DX; \
+ SHLQ $32, DX; \
+ SUBQ AX, R8; MOVQ R8, 0+y; \
+ SBBQ $0, R9; MOVQ R9, 8+y; \
+ SBBQ $0, R10; MOVQ R10, 16+y; \
+ SBBQ DX, R11; MOVQ R11, 24+y; \
+ SBBQ $0, R12; MOVQ R12, 32+y; \
+ SBBQ $0, R13; MOVQ R13, 40+y; \
+ SBBQ $0, R14; MOVQ R14, 48+y;
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
new file mode 100644
index 0000000..3f1f07c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
@@ -0,0 +1,75 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+#include "fp_amd64.h"
+
+// func cmovAmd64(x, y *Elt, n uint)
+TEXT ·cmovAmd64(SB),NOSPLIT,$0-24
+ MOVQ x+0(FP), DI
+ MOVQ y+8(FP), SI
+ MOVQ n+16(FP), BX
+ cselect(0(DI),0(SI),BX)
+ RET
+
+// func cswapAmd64(x, y *Elt, n uint)
+TEXT ·cswapAmd64(SB),NOSPLIT,$0-24
+ MOVQ x+0(FP), DI
+ MOVQ y+8(FP), SI
+ MOVQ n+16(FP), BX
+ cswap(0(DI),0(SI),BX)
+ RET
+
+// func subAmd64(z, x, y *Elt)
+TEXT ·subAmd64(SB),NOSPLIT,$0-24
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ MOVQ y+16(FP), BX
+ subtraction(0(DI),0(SI),0(BX))
+ RET
+
+// func addsubAmd64(x, y *Elt)
+TEXT ·addsubAmd64(SB),NOSPLIT,$0-16
+ MOVQ x+0(FP), DI
+ MOVQ y+8(FP), SI
+ addSub(0(DI),0(SI))
+ RET
+
+#define addLegacy \
+ additionLeg(0(DI),0(SI),0(BX))
+#define addBmi2Adx \
+ additionAdx(0(DI),0(SI),0(BX))
+
+#define mulLegacy \
+ integerMulLeg(0(SP),0(SI),0(BX)) \
+ reduceFromDoubleLeg(0(DI),0(SP))
+#define mulBmi2Adx \
+ integerMulAdx(0(SP),0(SI),0(BX)) \
+ reduceFromDoubleAdx(0(DI),0(SP))
+
+#define sqrLegacy \
+ integerSqrLeg(0(SP),0(SI)) \
+ reduceFromDoubleLeg(0(DI),0(SP))
+#define sqrBmi2Adx \
+ integerSqrAdx(0(SP),0(SI)) \
+ reduceFromDoubleAdx(0(DI),0(SP))
+
+// func addAmd64(z, x, y *Elt)
+TEXT ·addAmd64(SB),NOSPLIT,$0-24
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ MOVQ y+16(FP), BX
+ CHECK_BMI2ADX(LADD, addLegacy, addBmi2Adx)
+
+// func mulAmd64(z, x, y *Elt)
+TEXT ·mulAmd64(SB),NOSPLIT,$112-24
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ MOVQ y+16(FP), BX
+ CHECK_BMI2ADX(LMUL, mulLegacy, mulBmi2Adx)
+
+// func sqrAmd64(z, x *Elt)
+TEXT ·sqrAmd64(SB),NOSPLIT,$112-16
+ MOVQ z+0(FP), DI
+ MOVQ x+8(FP), SI
+ CHECK_BMI2ADX(LSQR, sqrLegacy, sqrBmi2Adx)
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go
new file mode 100644
index 0000000..47a0b63
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go
@@ -0,0 +1,339 @@
+package fp448
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+func cmovGeneric(x, y *Elt, n uint) {
+ m := -uint64(n & 0x1)
+ x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+ y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+ y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+ y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+ y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+ y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+ y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+ y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+ x0 = (x0 &^ m) | (y0 & m)
+ x1 = (x1 &^ m) | (y1 & m)
+ x2 = (x2 &^ m) | (y2 & m)
+ x3 = (x3 &^ m) | (y3 & m)
+ x4 = (x4 &^ m) | (y4 & m)
+ x5 = (x5 &^ m) | (y5 & m)
+ x6 = (x6 &^ m) | (y6 & m)
+
+ binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+ binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+ binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+ binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+ binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
+ binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
+ binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
+}
+
+func cswapGeneric(x, y *Elt, n uint) {
+ m := -uint64(n & 0x1)
+ x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+ y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+ y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+ y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+ y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+ y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+ y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+ y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+ t0 := m & (x0 ^ y0)
+ t1 := m & (x1 ^ y1)
+ t2 := m & (x2 ^ y2)
+ t3 := m & (x3 ^ y3)
+ t4 := m & (x4 ^ y4)
+ t5 := m & (x5 ^ y5)
+ t6 := m & (x6 ^ y6)
+ x0 ^= t0
+ x1 ^= t1
+ x2 ^= t2
+ x3 ^= t3
+ x4 ^= t4
+ x5 ^= t5
+ x6 ^= t6
+ y0 ^= t0
+ y1 ^= t1
+ y2 ^= t2
+ y3 ^= t3
+ y4 ^= t4
+ y5 ^= t5
+ y6 ^= t6
+
+ binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+ binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+ binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+ binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+ binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
+ binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
+ binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
+
+ binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
+ binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
+ binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
+ binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
+ binary.LittleEndian.PutUint64(y[4*8:5*8], y4)
+ binary.LittleEndian.PutUint64(y[5*8:6*8], y5)
+ binary.LittleEndian.PutUint64(y[6*8:7*8], y6)
+}
+
+func addGeneric(z, x, y *Elt) {
+ x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+ y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+ y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+ y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+ y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+ y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+ y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+ y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+ z0, c0 := bits.Add64(x0, y0, 0)
+ z1, c1 := bits.Add64(x1, y1, c0)
+ z2, c2 := bits.Add64(x2, y2, c1)
+ z3, c3 := bits.Add64(x3, y3, c2)
+ z4, c4 := bits.Add64(x4, y4, c3)
+ z5, c5 := bits.Add64(x5, y5, c4)
+ z6, z7 := bits.Add64(x6, y6, c5)
+
+ z0, c0 = bits.Add64(z0, z7, 0)
+ z1, c1 = bits.Add64(z1, 0, c0)
+ z2, c2 = bits.Add64(z2, 0, c1)
+ z3, c3 = bits.Add64(z3, z7<<32, c2)
+ z4, c4 = bits.Add64(z4, 0, c3)
+ z5, c5 = bits.Add64(z5, 0, c4)
+ z6, z7 = bits.Add64(z6, 0, c5)
+
+ z0, c0 = bits.Add64(z0, z7, 0)
+ z1, c1 = bits.Add64(z1, 0, c0)
+ z2, c2 = bits.Add64(z2, 0, c1)
+ z3, c3 = bits.Add64(z3, z7<<32, c2)
+ z4, c4 = bits.Add64(z4, 0, c3)
+ z5, c5 = bits.Add64(z5, 0, c4)
+ z6, _ = bits.Add64(z6, 0, c5)
+
+ binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+ binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+ binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+ binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+ binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
+ binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
+ binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
+}
+
+func subGeneric(z, x, y *Elt) {
+ x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+ y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+ y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+ y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+ y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+ y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+ y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+ y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+ z0, c0 := bits.Sub64(x0, y0, 0)
+ z1, c1 := bits.Sub64(x1, y1, c0)
+ z2, c2 := bits.Sub64(x2, y2, c1)
+ z3, c3 := bits.Sub64(x3, y3, c2)
+ z4, c4 := bits.Sub64(x4, y4, c3)
+ z5, c5 := bits.Sub64(x5, y5, c4)
+ z6, z7 := bits.Sub64(x6, y6, c5)
+
+ z0, c0 = bits.Sub64(z0, z7, 0)
+ z1, c1 = bits.Sub64(z1, 0, c0)
+ z2, c2 = bits.Sub64(z2, 0, c1)
+ z3, c3 = bits.Sub64(z3, z7<<32, c2)
+ z4, c4 = bits.Sub64(z4, 0, c3)
+ z5, c5 = bits.Sub64(z5, 0, c4)
+ z6, z7 = bits.Sub64(z6, 0, c5)
+
+ z0, c0 = bits.Sub64(z0, z7, 0)
+ z1, c1 = bits.Sub64(z1, 0, c0)
+ z2, c2 = bits.Sub64(z2, 0, c1)
+ z3, c3 = bits.Sub64(z3, z7<<32, c2)
+ z4, c4 = bits.Sub64(z4, 0, c3)
+ z5, c5 = bits.Sub64(z5, 0, c4)
+ z6, _ = bits.Sub64(z6, 0, c5)
+
+ binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+ binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+ binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+ binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+ binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
+ binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
+ binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
+}
+
+func addsubGeneric(x, y *Elt) {
+ z := &Elt{}
+ addGeneric(z, x, y)
+ subGeneric(y, x, y)
+ *x = *z
+}
+
+func mulGeneric(z, x, y *Elt) {
+ x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+ x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+ x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+ x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+ x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+ x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+ x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+ y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+ y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+ y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+ y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+ y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+ y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+ y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+ yy := [7]uint64{y0, y1, y2, y3, y4, y5, y6}
+ zz := [7]uint64{}
+
+ yi := yy[0]
+ h0, l0 := bits.Mul64(x0, yi)
+ h1, l1 := bits.Mul64(x1, yi)
+ h2, l2 := bits.Mul64(x2, yi)
+ h3, l3 := bits.Mul64(x3, yi)
+ h4, l4 := bits.Mul64(x4, yi)
+ h5, l5 := bits.Mul64(x5, yi)
+ h6, l6 := bits.Mul64(x6, yi)
+
+ zz[0] = l0
+ a0, c0 := bits.Add64(h0, l1, 0)
+ a1, c1 := bits.Add64(h1, l2, c0)
+ a2, c2 := bits.Add64(h2, l3, c1)
+ a3, c3 := bits.Add64(h3, l4, c2)
+ a4, c4 := bits.Add64(h4, l5, c3)
+ a5, c5 := bits.Add64(h5, l6, c4)
+ a6, _ := bits.Add64(h6, 0, c5)
+
+ for i := 1; i < 7; i++ {
+ yi = yy[i]
+ h0, l0 = bits.Mul64(x0, yi)
+ h1, l1 = bits.Mul64(x1, yi)
+ h2, l2 = bits.Mul64(x2, yi)
+ h3, l3 = bits.Mul64(x3, yi)
+ h4, l4 = bits.Mul64(x4, yi)
+ h5, l5 = bits.Mul64(x5, yi)
+ h6, l6 = bits.Mul64(x6, yi)
+
+ zz[i], c0 = bits.Add64(a0, l0, 0)
+ a0, c1 = bits.Add64(a1, l1, c0)
+ a1, c2 = bits.Add64(a2, l2, c1)
+ a2, c3 = bits.Add64(a3, l3, c2)
+ a3, c4 = bits.Add64(a4, l4, c3)
+ a4, c5 = bits.Add64(a5, l5, c4)
+ a5, a6 = bits.Add64(a6, l6, c5)
+
+ a0, c0 = bits.Add64(a0, h0, 0)
+ a1, c1 = bits.Add64(a1, h1, c0)
+ a2, c2 = bits.Add64(a2, h2, c1)
+ a3, c3 = bits.Add64(a3, h3, c2)
+ a4, c4 = bits.Add64(a4, h4, c3)
+ a5, c5 = bits.Add64(a5, h5, c4)
+ a6, _ = bits.Add64(a6, h6, c5)
+ }
+ red64(z, &zz, &[7]uint64{a0, a1, a2, a3, a4, a5, a6})
+}
+
+func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) }
+
+func red64(z *Elt, l, h *[7]uint64) {
+ /* (2C13, 2C12, 2C11, 2C10|C10, C9, C8, C7) + (C6,...,C0) */
+ h0 := h[0]
+ h1 := h[1]
+ h2 := h[2]
+ h3 := ((h[3] & (0xFFFFFFFF << 32)) << 1) | (h[3] & 0xFFFFFFFF)
+ h4 := (h[3] >> 63) | (h[4] << 1)
+ h5 := (h[4] >> 63) | (h[5] << 1)
+ h6 := (h[5] >> 63) | (h[6] << 1)
+ h7 := (h[6] >> 63)
+
+ l0, c0 := bits.Add64(h0, l[0], 0)
+ l1, c1 := bits.Add64(h1, l[1], c0)
+ l2, c2 := bits.Add64(h2, l[2], c1)
+ l3, c3 := bits.Add64(h3, l[3], c2)
+ l4, c4 := bits.Add64(h4, l[4], c3)
+ l5, c5 := bits.Add64(h5, l[5], c4)
+ l6, c6 := bits.Add64(h6, l[6], c5)
+ l7, _ := bits.Add64(h7, 0, c6)
+
+ /* (C10C9, C9C8,C8C7,C7C13,C13C12,C12C11,C11C10) + (C6,...,C0) */
+ h0 = (h[3] >> 32) | (h[4] << 32)
+ h1 = (h[4] >> 32) | (h[5] << 32)
+ h2 = (h[5] >> 32) | (h[6] << 32)
+ h3 = (h[6] >> 32) | (h[0] << 32)
+ h4 = (h[0] >> 32) | (h[1] << 32)
+ h5 = (h[1] >> 32) | (h[2] << 32)
+ h6 = (h[2] >> 32) | (h[3] << 32)
+
+ l0, c0 = bits.Add64(l0, h0, 0)
+ l1, c1 = bits.Add64(l1, h1, c0)
+ l2, c2 = bits.Add64(l2, h2, c1)
+ l3, c3 = bits.Add64(l3, h3, c2)
+ l4, c4 = bits.Add64(l4, h4, c3)
+ l5, c5 = bits.Add64(l5, h5, c4)
+ l6, c6 = bits.Add64(l6, h6, c5)
+ l7, _ = bits.Add64(l7, 0, c6)
+
+ /* (C7) + (C6,...,C0) */
+ l0, c0 = bits.Add64(l0, l7, 0)
+ l1, c1 = bits.Add64(l1, 0, c0)
+ l2, c2 = bits.Add64(l2, 0, c1)
+ l3, c3 = bits.Add64(l3, l7<<32, c2)
+ l4, c4 = bits.Add64(l4, 0, c3)
+ l5, c5 = bits.Add64(l5, 0, c4)
+ l6, l7 = bits.Add64(l6, 0, c5)
+
+ /* (C7) + (C6,...,C0) */
+ l0, c0 = bits.Add64(l0, l7, 0)
+ l1, c1 = bits.Add64(l1, 0, c0)
+ l2, c2 = bits.Add64(l2, 0, c1)
+ l3, c3 = bits.Add64(l3, l7<<32, c2)
+ l4, c4 = bits.Add64(l4, 0, c3)
+ l5, c5 = bits.Add64(l5, 0, c4)
+ l6, _ = bits.Add64(l6, 0, c5)
+
+ binary.LittleEndian.PutUint64(z[0*8:1*8], l0)
+ binary.LittleEndian.PutUint64(z[1*8:2*8], l1)
+ binary.LittleEndian.PutUint64(z[2*8:3*8], l2)
+ binary.LittleEndian.PutUint64(z[3*8:4*8], l3)
+ binary.LittleEndian.PutUint64(z[4*8:5*8], l4)
+ binary.LittleEndian.PutUint64(z[5*8:6*8], l5)
+ binary.LittleEndian.PutUint64(z[6*8:7*8], l6)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go
new file mode 100644
index 0000000..a62225d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go
@@ -0,0 +1,12 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package fp448
+
+func cmov(x, y *Elt, n uint) { cmovGeneric(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapGeneric(x, y, n) }
+func add(z, x, y *Elt) { addGeneric(z, x, y) }
+func sub(z, x, y *Elt) { subGeneric(z, x, y) }
+func addsub(x, y *Elt) { addsubGeneric(x, y) }
+func mul(z, x, y *Elt) { mulGeneric(z, x, y) }
+func sqr(z, x *Elt) { sqrGeneric(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go b/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go
new file mode 100644
index 0000000..2d7afc8
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go
@@ -0,0 +1,75 @@
+//go:build gofuzz
+// +build gofuzz
+
+// How to run the fuzzer:
+//
+// $ go get -u github.com/dvyukov/go-fuzz/go-fuzz
+// $ go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
+// $ go-fuzz-build -libfuzzer -func FuzzReduction -o lib.a
+// $ clang -fsanitize=fuzzer lib.a -o fu.exe
+// $ ./fu.exe
+package fp448
+
+import (
+ "encoding/binary"
+ "fmt"
+ "math/big"
+
+ "github.com/cloudflare/circl/internal/conv"
+)
+
+// FuzzReduction is a fuzzer target for red64 function, which reduces t
+// (112 bits) to a number t' (56 bits) congruent modulo p448.
+func FuzzReduction(data []byte) int {
+ if len(data) != 2*Size {
+ return -1
+ }
+ var got, want Elt
+ var lo, hi [7]uint64
+ a := data[:Size]
+ b := data[Size:]
+ lo[0] = binary.LittleEndian.Uint64(a[0*8 : 1*8])
+ lo[1] = binary.LittleEndian.Uint64(a[1*8 : 2*8])
+ lo[2] = binary.LittleEndian.Uint64(a[2*8 : 3*8])
+ lo[3] = binary.LittleEndian.Uint64(a[3*8 : 4*8])
+ lo[4] = binary.LittleEndian.Uint64(a[4*8 : 5*8])
+ lo[5] = binary.LittleEndian.Uint64(a[5*8 : 6*8])
+ lo[6] = binary.LittleEndian.Uint64(a[6*8 : 7*8])
+
+ hi[0] = binary.LittleEndian.Uint64(b[0*8 : 1*8])
+ hi[1] = binary.LittleEndian.Uint64(b[1*8 : 2*8])
+ hi[2] = binary.LittleEndian.Uint64(b[2*8 : 3*8])
+ hi[3] = binary.LittleEndian.Uint64(b[3*8 : 4*8])
+ hi[4] = binary.LittleEndian.Uint64(b[4*8 : 5*8])
+ hi[5] = binary.LittleEndian.Uint64(b[5*8 : 6*8])
+ hi[6] = binary.LittleEndian.Uint64(b[6*8 : 7*8])
+
+ red64(&got, &lo, &hi)
+
+ t := conv.BytesLe2BigInt(data[:2*Size])
+
+ two448 := big.NewInt(1)
+ two448.Lsh(two448, 448) // 2^448
+ mask448 := big.NewInt(1)
+ mask448.Sub(two448, mask448) // 2^448-1
+ two224plus1 := big.NewInt(1)
+ two224plus1.Lsh(two224plus1, 224)
+ two224plus1.Add(two224plus1, big.NewInt(1)) // 2^224+1
+
+ var loBig, hiBig big.Int
+ for t.Cmp(two448) >= 0 {
+ loBig.And(t, mask448)
+ hiBig.Rsh(t, 448)
+ t.Mul(&hiBig, two224plus1)
+ t.Add(t, &loBig)
+ }
+ conv.BigInt2BytesLe(want[:], t)
+
+ if got != want {
+ fmt.Printf("in: %v\n", conv.BytesLe2BigInt(data[:2*Size]))
+ fmt.Printf("got: %v\n", got)
+ fmt.Printf("want: %v\n", want)
+ panic("error found")
+ }
+ return 1
+}
diff --git a/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go b/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go
new file mode 100644
index 0000000..a43851b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go
@@ -0,0 +1,122 @@
+// Package mlsbset provides a constant-time exponentiation method with precomputation.
+//
+// References: "Efficient and secure algorithms for GLV-based scalar
+// multiplication and their implementation on GLV–GLS curves" by (Faz-Hernandez et al.)
+// - https://doi.org/10.1007/s13389-014-0085-7
+// - https://eprint.iacr.org/2013/158
+package mlsbset
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+
+ "github.com/cloudflare/circl/internal/conv"
+)
+
+// EltG is a group element.
+type EltG interface{}
+
+// EltP is a precomputed group element.
+type EltP interface{}
+
+// Group defines the operations required by MLSBSet exponentiation method.
+type Group interface {
+ Identity() EltG // Returns the identity of the group.
+ Sqr(x EltG) // Calculates x = x^2.
+ Mul(x EltG, y EltP) // Calculates x = x*y.
+ NewEltP() EltP // Returns an arbitrary precomputed element.
+ ExtendedEltP() EltP // Returns the precomputed element x^(2^(w*d)).
+ Lookup(a EltP, v uint, s, u int32) // Sets a = s*T[v][u].
+}
+
+// Params contains the parameters of the encoding.
+type Params struct {
+ T uint // T is the maximum size (in bits) of exponents.
+ V uint // V is the number of tables.
+ W uint // W is the window size.
+ E uint // E is the number of digits per table.
+ D uint // D is the number of digits in total.
+ L uint // L is the length of the code.
+}
+
+// Encoder allows to convert integers into valid powers.
+type Encoder struct{ p Params }
+
+// New produces an encoder of the MLSBSet algorithm.
+func New(t, v, w uint) (Encoder, error) {
+ if !(t > 1 && v >= 1 && w >= 2) {
+ return Encoder{}, errors.New("t>1, v>=1, w>=2")
+ }
+ e := (t + w*v - 1) / (w * v)
+ d := e * v
+ l := d * w
+ return Encoder{Params{t, v, w, e, d, l}}, nil
+}
+
+// Encode converts an odd integer k into a valid power for exponentiation.
+func (m Encoder) Encode(k []byte) (*Power, error) {
+ if len(k) == 0 {
+ return nil, errors.New("empty slice")
+ }
+ if !(len(k) <= int(m.p.L+7)>>3) {
+ return nil, errors.New("k too big")
+ }
+ if k[0]%2 == 0 {
+ return nil, errors.New("k must be odd")
+ }
+ ap := int((m.p.L+7)/8) - len(k)
+ k = append(k, make([]byte, ap)...)
+ s := m.signs(k)
+ b := make([]int32, m.p.L-m.p.D)
+ c := conv.BytesLe2BigInt(k)
+ c.Rsh(c, m.p.D)
+ var bi big.Int
+ for i := m.p.D; i < m.p.L; i++ {
+ c0 := int32(c.Bit(0))
+ b[i-m.p.D] = s[i%m.p.D] * c0
+ bi.SetInt64(int64(b[i-m.p.D] >> 1))
+ c.Rsh(c, 1)
+ c.Sub(c, &bi)
+ }
+ carry := int(c.Int64())
+ return &Power{m, s, b, carry}, nil
+}
+
+// signs calculates the set of signs.
+func (m Encoder) signs(k []byte) []int32 {
+ s := make([]int32, m.p.D)
+ s[m.p.D-1] = 1
+ for i := uint(1); i < m.p.D; i++ {
+ ki := int32((k[i>>3] >> (i & 0x7)) & 0x1)
+ s[i-1] = 2*ki - 1
+ }
+ return s
+}
+
+// GetParams returns the complementary parameters of the encoding.
+func (m Encoder) GetParams() Params { return m.p }
+
+// tableSize returns the size of each table.
+func (m Encoder) tableSize() uint { return 1 << (m.p.W - 1) }
+
+// Elts returns the total number of elements that must be precomputed.
+func (m Encoder) Elts() uint { return m.p.V * m.tableSize() }
+
+// IsExtended returns true if the element x^(2^(wd)) must be calculated.
+func (m Encoder) IsExtended() bool { q := m.p.T / (m.p.V * m.p.W); return m.p.T == q*m.p.V*m.p.W }
+
+// Ops returns the number of squares and multiplications executed during an exponentiation.
+func (m Encoder) Ops() (S uint, M uint) {
+ S = m.p.E
+ M = m.p.E * m.p.V
+ if m.IsExtended() {
+ M++
+ }
+ return
+}
+
+func (m Encoder) String() string {
+ return fmt.Sprintf("T: %v W: %v V: %v e: %v d: %v l: %v wv|t: %v",
+ m.p.T, m.p.W, m.p.V, m.p.E, m.p.D, m.p.L, m.IsExtended())
+}
diff --git a/vendor/github.com/cloudflare/circl/math/mlsbset/power.go b/vendor/github.com/cloudflare/circl/math/mlsbset/power.go
new file mode 100644
index 0000000..3f214c3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/mlsbset/power.go
@@ -0,0 +1,64 @@
+package mlsbset
+
+import "fmt"
+
+// Power is a valid exponent produced by the MLSBSet encoding algorithm.
+type Power struct {
+ set Encoder // parameters of code.
+ s []int32 // set of signs.
+ b []int32 // set of digits.
+ c int // carry is {0,1}.
+}
+
+// Exp is calculates x^k, where x is a predetermined element of a group G.
+func (p *Power) Exp(G Group) EltG {
+ a, b := G.Identity(), G.NewEltP()
+ for e := int(p.set.p.E - 1); e >= 0; e-- {
+ G.Sqr(a)
+ for v := uint(0); v < p.set.p.V; v++ {
+ sgnElt, idElt := p.Digit(v, uint(e))
+ G.Lookup(b, v, sgnElt, idElt)
+ G.Mul(a, b)
+ }
+ }
+ if p.set.IsExtended() && p.c == 1 {
+ G.Mul(a, G.ExtendedEltP())
+ }
+ return a
+}
+
+// Digit returns the (v,e)-th digit and its sign.
+func (p *Power) Digit(v, e uint) (sgn, dig int32) {
+ sgn = p.bit(0, v, e)
+ dig = 0
+ for i := p.set.p.W - 1; i > 0; i-- {
+ dig = 2*dig + p.bit(i, v, e)
+ }
+ mask := dig >> 31
+ dig = (dig + mask) ^ mask
+ return sgn, dig
+}
+
+// bit returns the (w,v,e)-th bit of the code.
+func (p *Power) bit(w, v, e uint) int32 {
+ if !(w < p.set.p.W &&
+ v < p.set.p.V &&
+ e < p.set.p.E) {
+ panic(fmt.Errorf("indexes outside (%v,%v,%v)", w, v, e))
+ }
+ if w == 0 {
+ return p.s[p.set.p.E*v+e]
+ }
+ return p.b[p.set.p.D*(w-1)+p.set.p.E*v+e]
+}
+
+func (p *Power) String() string {
+ dig := ""
+ for j := uint(0); j < p.set.p.V; j++ {
+ for i := uint(0); i < p.set.p.E; i++ {
+ s, d := p.Digit(j, i)
+ dig += fmt.Sprintf("(%2v,%2v) = %+2v %+2v\n", j, i, s, d)
+ }
+ }
+ return fmt.Sprintf("len: %v\ncarry: %v\ndigits:\n%v", len(p.b)+len(p.s), p.c, dig)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/primes.go b/vendor/github.com/cloudflare/circl/math/primes.go
new file mode 100644
index 0000000..158fd83
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/primes.go
@@ -0,0 +1,34 @@
+package math
+
+import (
+ "crypto/rand"
+ "io"
+ "math/big"
+)
+
+// IsSafePrime reports whether p is (probably) a safe prime.
+// The prime p=2*q+1 is safe prime if both p and q are primes.
+// Note that ProbablyPrime is not suitable for judging primes
+// that an adversary may have crafted to fool the test.
+func IsSafePrime(p *big.Int) bool {
+ pdiv2 := new(big.Int).Rsh(p, 1)
+ return p.ProbablyPrime(20) && pdiv2.ProbablyPrime(20)
+}
+
+// SafePrime returns a number of the given bit length that is a safe prime with high probability.
+// The number returned p=2*q+1 is a safe prime if both p and q are primes.
+// SafePrime will return error for any error returned by rand.Read or if bits < 2.
+func SafePrime(random io.Reader, bits int) (*big.Int, error) {
+ one := big.NewInt(1)
+ p := new(big.Int)
+ for {
+ q, err := rand.Prime(random, bits-1)
+ if err != nil {
+ return nil, err
+ }
+ p.Lsh(q, 1).Add(p, one)
+ if p.ProbablyPrime(20) {
+ return p, nil
+ }
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/math/wnaf.go b/vendor/github.com/cloudflare/circl/math/wnaf.go
new file mode 100644
index 0000000..94a1ec5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/wnaf.go
@@ -0,0 +1,84 @@
+// Package math provides some utility functions for big integers.
+package math
+
+import "math/big"
+
+// SignedDigit obtains the signed-digit recoding of n and returns a list L of
+// digits such that n = sum( L[i]*2^(i*(w-1)) ), and each L[i] is an odd number
+// in the set {±1, ±3, ..., ±2^(w-1)-1}. The third parameter ensures that the
+// output has ceil(l/(w-1)) digits.
+//
+// Restrictions:
+// - n is odd and n > 0.
+// - 1 < w < 32.
+// - l >= bit length of n.
+//
+// References:
+// - Alg.6 in "Exponent Recoding and Regular Exponentiation Algorithms"
+// by Joye-Tunstall. http://doi.org/10.1007/978-3-642-02384-2_21
+// - Alg.6 in "Selecting Elliptic Curves for Cryptography: An Efficiency and
+// Security Analysis" by Bos et al. http://doi.org/10.1007/s13389-015-0097-y
+func SignedDigit(n *big.Int, w, l uint) []int32 {
+ if n.Sign() <= 0 || n.Bit(0) == 0 {
+ panic("n must be non-zero, odd, and positive")
+ }
+ if w <= 1 || w >= 32 {
+ panic("Verify that 1 < w < 32")
+ }
+ if uint(n.BitLen()) > l {
+ panic("n is too big to fit in l digits")
+ }
+ lenN := (l + (w - 1) - 1) / (w - 1) // ceil(l/(w-1))
+ L := make([]int32, lenN+1)
+ var k, v big.Int
+ k.Set(n)
+
+ var i uint
+ for i = 0; i < lenN; i++ {
+ words := k.Bits()
+ value := int32(words[0] & ((1 << w) - 1))
+ value -= int32(1) << (w - 1)
+ L[i] = value
+ v.SetInt64(int64(value))
+ k.Sub(&k, &v)
+ k.Rsh(&k, w-1)
+ }
+ L[i] = int32(k.Int64())
+ return L
+}
+
+// OmegaNAF obtains the window-w Non-Adjacent Form of a positive number n and
+// 1 < w < 32. The returned slice L holds n = sum( L[i]*2^i ).
+//
+// Reference:
+// - Alg.9 "Efficient arithmetic on Koblitz curves" by Solinas.
+// http://doi.org/10.1023/A:1008306223194
+func OmegaNAF(n *big.Int, w uint) (L []int32) {
+ if n.Sign() < 0 {
+ panic("n must be positive")
+ }
+ if w <= 1 || w >= 32 {
+ panic("Verify that 1 < w < 32")
+ }
+
+ L = make([]int32, n.BitLen()+1)
+ var k, v big.Int
+ k.Set(n)
+
+ i := 0
+ for ; k.Sign() > 0; i++ {
+ value := int32(0)
+ if k.Bit(0) == 1 {
+ words := k.Bits()
+ value = int32(words[0] & ((1 << w) - 1))
+ if value >= (int32(1) << (w - 1)) {
+ value -= int32(1) << w
+ }
+ v.SetInt64(int64(value))
+ k.Sub(&k, &v)
+ }
+ L[i] = value
+ k.Rsh(&k, 1)
+ }
+ return L[:i]
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go
new file mode 100644
index 0000000..2c73c26
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go
@@ -0,0 +1,453 @@
+// Package ed25519 implements Ed25519 signature scheme as described in RFC-8032.
+//
+// This package provides optimized implementations of the three signature
+// variants and maintaining closer compatibility with crypto/ed25519.
+//
+// | Scheme Name | Sign Function | Verification | Context |
+// |-------------|-------------------|---------------|-------------------|
+// | Ed25519 | Sign | Verify | None |
+// | Ed25519Ph | SignPh | VerifyPh | Yes, can be empty |
+// | Ed25519Ctx | SignWithCtx | VerifyWithCtx | Yes, non-empty |
+// | All above | (PrivateKey).Sign | VerifyAny | As above |
+//
+// Specific functions for sign and verify are defined. A generic signing
+// function for all schemes is available through the crypto.Signer interface,
+// which is implemented by the PrivateKey type. A correspond all-in-one
+// verification method is provided by the VerifyAny function.
+//
+// Signing with Ed25519Ph or Ed25519Ctx requires a context string for domain
+// separation. This parameter is passed using a SignerOptions struct defined
+// in this package. While Ed25519Ph accepts an empty context, Ed25519Ctx
+// enforces non-empty context strings.
+//
+// # Compatibility with crypto.ed25519
+//
+// These functions are compatible with the “Ed25519” function defined in
+// RFC-8032. However, unlike RFC 8032's formulation, this package's private
+// key representation includes a public key suffix to make multiple signing
+// operations with the same key more efficient. This package refers to the
+// RFC-8032 private key as the “seed”.
+//
+// References
+//
+// - RFC-8032: https://rfc-editor.org/rfc/rfc8032.txt
+// - Ed25519: https://ed25519.cr.yp.to/
+// - EdDSA: High-speed high-security signatures. https://doi.org/10.1007/s13389-012-0027-1
+package ed25519
+
+import (
+ "bytes"
+ "crypto"
+ cryptoRand "crypto/rand"
+ "crypto/sha512"
+ "crypto/subtle"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+
+ "github.com/cloudflare/circl/sign"
+)
+
+const (
+ // ContextMaxSize is the maximum length (in bytes) allowed for context.
+ ContextMaxSize = 255
+ // PublicKeySize is the size, in bytes, of public keys as used in this package.
+ PublicKeySize = 32
+ // PrivateKeySize is the size, in bytes, of private keys as used in this package.
+ PrivateKeySize = 64
+ // SignatureSize is the size, in bytes, of signatures generated and verified by this package.
+ SignatureSize = 64
+ // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
+ SeedSize = 32
+)
+
+const (
+ paramB = 256 / 8 // Size of keys in bytes.
+)
+
+// SignerOptions implements crypto.SignerOpts and augments with parameters
+// that are specific to the Ed25519 signature schemes.
+type SignerOptions struct {
+ // Hash must be crypto.Hash(0) for Ed25519/Ed25519ctx, or crypto.SHA512
+ // for Ed25519ph.
+ crypto.Hash
+
+ // Context is an optional domain separation string for Ed25519ph and a
+ // must for Ed25519ctx. Its length must be less or equal than 255 bytes.
+ Context string
+
+ // Scheme is an identifier for choosing a signature scheme. The zero value
+ // is ED25519.
+ Scheme SchemeID
+}
+
+// SchemeID is an identifier for each signature scheme.
+type SchemeID uint
+
+const (
+ ED25519 SchemeID = iota
+ ED25519Ph
+ ED25519Ctx
+)
+
+// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
+type PrivateKey []byte
+
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(PrivateKey)
+ return ok && subtle.ConstantTimeCompare(priv, xx) == 1
+}
+
+// Public returns the PublicKey corresponding to priv.
+func (priv PrivateKey) Public() crypto.PublicKey {
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, priv[SeedSize:])
+ return publicKey
+}
+
+// Seed returns the private key seed corresponding to priv. It is provided for
+// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
+// in this package.
+func (priv PrivateKey) Seed() []byte {
+ seed := make([]byte, SeedSize)
+ copy(seed, priv[:SeedSize])
+ return seed
+}
+
+func (priv PrivateKey) Scheme() sign.Scheme { return sch }
+
+func (pub PublicKey) Scheme() sign.Scheme { return sch }
+
+func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
+ privateKey := make(PrivateKey, PrivateKeySize)
+ copy(privateKey, priv)
+ return privateKey, nil
+}
+
+func (pub PublicKey) MarshalBinary() (data []byte, err error) {
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, pub)
+ return publicKey, nil
+}
+
+// Equal reports whether pub and x have the same value.
+func (pub PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(PublicKey)
+ return ok && bytes.Equal(pub, xx)
+}
+
+// Sign creates a signature of a message with priv key.
+// This function is compatible with crypto.ed25519 and also supports the
+// three signature variants defined in RFC-8032, namely Ed25519 (or pure
+// EdDSA), Ed25519Ph, and Ed25519Ctx.
+// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
+// variant. This can be achieved by passing crypto.Hash(0) as the value for
+// opts.
+// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
+// This can be achieved by passing crypto.SHA512 as the value for opts.
+// Use a SignerOptions struct (defined in this package) to pass a context
+// string for signing.
+func (priv PrivateKey) Sign(
+ rand io.Reader,
+ message []byte,
+ opts crypto.SignerOpts,
+) (signature []byte, err error) {
+ var ctx string
+ var scheme SchemeID
+ if o, ok := opts.(SignerOptions); ok {
+ ctx = o.Context
+ scheme = o.Scheme
+ }
+
+ switch true {
+ case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
+ return Sign(priv, message), nil
+ case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
+ return SignPh(priv, message, ctx), nil
+ case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
+ return SignWithCtx(priv, message, ctx), nil
+ default:
+ return nil, errors.New("ed25519: bad hash algorithm")
+ }
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
+ if rand == nil {
+ rand = cryptoRand.Reader
+ }
+
+ seed := make([]byte, SeedSize)
+ if _, err := io.ReadFull(rand, seed); err != nil {
+ return nil, nil, err
+ }
+
+ privateKey := NewKeyFromSeed(seed)
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, privateKey[SeedSize:])
+
+ return publicKey, privateKey, nil
+}
+
+// NewKeyFromSeed calculates a private key from a seed. It will panic if
+// len(seed) is not SeedSize. This function is provided for interoperability
+// with RFC 8032. RFC 8032's private keys correspond to seeds in this
+// package.
+func NewKeyFromSeed(seed []byte) PrivateKey {
+ privateKey := make(PrivateKey, PrivateKeySize)
+ newKeyFromSeed(privateKey, seed)
+ return privateKey
+}
+
+func newKeyFromSeed(privateKey, seed []byte) {
+ if l := len(seed); l != SeedSize {
+ panic("ed25519: bad seed length: " + strconv.Itoa(l))
+ }
+ var P pointR1
+ k := sha512.Sum512(seed)
+ clamp(k[:])
+ reduceModOrder(k[:paramB], false)
+ P.fixedMult(k[:paramB])
+ copy(privateKey[:SeedSize], seed)
+ _ = P.ToBytes(privateKey[SeedSize:])
+}
+
+func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
+ if l := len(privateKey); l != PrivateKeySize {
+ panic("ed25519: bad private key length: " + strconv.Itoa(l))
+ }
+
+ H := sha512.New()
+ var PHM []byte
+
+ if preHash {
+ _, _ = H.Write(message)
+ PHM = H.Sum(nil)
+ H.Reset()
+ } else {
+ PHM = message
+ }
+
+ // 1. Hash the 32-byte private key using SHA-512.
+ _, _ = H.Write(privateKey[:SeedSize])
+ h := H.Sum(nil)
+ clamp(h[:])
+ prefix, s := h[paramB:], h[:paramB]
+
+ // 2. Compute SHA-512(dom2(F, C) || prefix || PH(M))
+ H.Reset()
+
+ writeDom(H, ctx, preHash)
+
+ _, _ = H.Write(prefix)
+ _, _ = H.Write(PHM)
+ r := H.Sum(nil)
+ reduceModOrder(r[:], true)
+
+ // 3. Compute the point [r]B.
+ var P pointR1
+ P.fixedMult(r[:paramB])
+ R := (&[paramB]byte{})[:]
+ if err := P.ToBytes(R); err != nil {
+ panic(err)
+ }
+
+ // 4. Compute SHA512(dom2(F, C) || R || A || PH(M)).
+ H.Reset()
+
+ writeDom(H, ctx, preHash)
+
+ _, _ = H.Write(R)
+ _, _ = H.Write(privateKey[SeedSize:])
+ _, _ = H.Write(PHM)
+ hRAM := H.Sum(nil)
+
+ reduceModOrder(hRAM[:], true)
+
+ // 5. Compute S = (r + k * s) mod order.
+ S := (&[paramB]byte{})[:]
+ calculateS(S, r[:paramB], hRAM[:paramB], s)
+
+ // 6. The signature is the concatenation of R and S.
+ copy(signature[:paramB], R[:])
+ copy(signature[paramB:], S[:])
+}
+
+// Sign signs the message with privateKey and returns a signature.
+// This function supports the signature variant defined in RFC-8032: Ed25519,
+// also known as the pure version of EdDSA.
+// It will panic if len(privateKey) is not PrivateKeySize.
+func Sign(privateKey PrivateKey, message []byte) []byte {
+ signature := make([]byte, SignatureSize)
+ signAll(signature, privateKey, message, []byte(""), false)
+ return signature
+}
+
+// SignPh creates a signature of a message with private key and context.
+// This function supports the signature variant defined in RFC-8032: Ed25519ph,
+// meaning it internally hashes the message using SHA-512, and optionally
+// accepts a context string.
+// It will panic if len(privateKey) is not PrivateKeySize.
+// Context could be passed to this function, which length should be no more than
+// ContextMaxSize=255. It can be empty.
+func SignPh(privateKey PrivateKey, message []byte, ctx string) []byte {
+ if len(ctx) > ContextMaxSize {
+ panic(fmt.Errorf("ed25519: bad context length: %v", len(ctx)))
+ }
+
+ signature := make([]byte, SignatureSize)
+ signAll(signature, privateKey, message, []byte(ctx), true)
+ return signature
+}
+
+// SignWithCtx creates a signature of a message with private key and context.
+// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
+// meaning it accepts a non-empty context string.
+// It will panic if len(privateKey) is not PrivateKeySize.
+// Context must be passed to this function, which length should be no more than
+// ContextMaxSize=255 and cannot be empty.
+func SignWithCtx(privateKey PrivateKey, message []byte, ctx string) []byte {
+ if len(ctx) == 0 || len(ctx) > ContextMaxSize {
+ panic(fmt.Errorf("ed25519: bad context length: %v > %v", len(ctx), ContextMaxSize))
+ }
+
+ signature := make([]byte, SignatureSize)
+ signAll(signature, privateKey, message, []byte(ctx), false)
+ return signature
+}
+
+func verify(public PublicKey, message, signature, ctx []byte, preHash bool) bool {
+ if len(public) != PublicKeySize ||
+ len(signature) != SignatureSize ||
+ !isLessThanOrder(signature[paramB:]) {
+ return false
+ }
+
+ var P pointR1
+ if ok := P.FromBytes(public); !ok {
+ return false
+ }
+
+ H := sha512.New()
+ var PHM []byte
+
+ if preHash {
+ _, _ = H.Write(message)
+ PHM = H.Sum(nil)
+ H.Reset()
+ } else {
+ PHM = message
+ }
+
+ R := signature[:paramB]
+
+ writeDom(H, ctx, preHash)
+
+ _, _ = H.Write(R)
+ _, _ = H.Write(public)
+ _, _ = H.Write(PHM)
+ hRAM := H.Sum(nil)
+ reduceModOrder(hRAM[:], true)
+
+ var Q pointR1
+ encR := (&[paramB]byte{})[:]
+ P.neg()
+ Q.doubleMult(&P, signature[paramB:], hRAM[:paramB])
+ _ = Q.ToBytes(encR)
+ return bytes.Equal(R, encR)
+}
+
+// VerifyAny returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports all the three signature variants defined in RFC-8032,
+// namely Ed25519 (or pure EdDSA), Ed25519Ph, and Ed25519Ctx.
+// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
+// variant. This can be achieved by passing crypto.Hash(0) as the value for opts.
+// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
+// This can be achieved by passing crypto.SHA512 as the value for opts.
+// Use a SignerOptions struct to pass a context string for signing.
+func VerifyAny(public PublicKey, message, signature []byte, opts crypto.SignerOpts) bool {
+ var ctx string
+ var scheme SchemeID
+ if o, ok := opts.(SignerOptions); ok {
+ ctx = o.Context
+ scheme = o.Scheme
+ }
+
+ switch true {
+ case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
+ return Verify(public, message, signature)
+ case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
+ return VerifyPh(public, message, signature, ctx)
+ case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
+ return VerifyWithCtx(public, message, signature, ctx)
+ default:
+ return false
+ }
+}
+
+// Verify returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed25519,
+// also known as the pure version of EdDSA.
+func Verify(public PublicKey, message, signature []byte) bool {
+ return verify(public, message, signature, []byte(""), false)
+}
+
+// VerifyPh returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed25519ph,
+// meaning it internally hashes the message using SHA-512.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func VerifyPh(public PublicKey, message, signature []byte, ctx string) bool {
+ return verify(public, message, signature, []byte(ctx), true)
+}
+
+// VerifyWithCtx returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded, or when context is
+// not provided.
+// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
+// meaning it does not handle prehashed messages. Non-empty context string must be
+// provided, and must not be more than 255 of length.
+func VerifyWithCtx(public PublicKey, message, signature []byte, ctx string) bool {
+ if len(ctx) == 0 || len(ctx) > ContextMaxSize {
+ return false
+ }
+
+ return verify(public, message, signature, []byte(ctx), false)
+}
+
+func clamp(k []byte) {
+ k[0] &= 248
+ k[paramB-1] = (k[paramB-1] & 127) | 64
+}
+
+// isLessThanOrder returns true if 0 <= x < order.
+func isLessThanOrder(x []byte) bool {
+ i := len(order) - 1
+ for i > 0 && x[i] == order[i] {
+ i--
+ }
+ return x[i] < order[i]
+}
+
+func writeDom(h io.Writer, ctx []byte, preHash bool) {
+ dom2 := "SigEd25519 no Ed25519 collisions"
+
+ if len(ctx) > 0 {
+ _, _ = h.Write([]byte(dom2))
+ if preHash {
+ _, _ = h.Write([]byte{byte(0x01), byte(len(ctx))})
+ } else {
+ _, _ = h.Write([]byte{byte(0x00), byte(len(ctx))})
+ }
+ _, _ = h.Write(ctx)
+ } else if preHash {
+ _, _ = h.Write([]byte(dom2))
+ _, _ = h.Write([]byte{0x01, 0x00})
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go b/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go
new file mode 100644
index 0000000..10efafd
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go
@@ -0,0 +1,175 @@
+package ed25519
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+var order = [paramB]byte{
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+ 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+}
+
+// isLessThan returns true if 0 <= x < y, and assumes that slices have the same length.
+func isLessThan(x, y []byte) bool {
+ i := len(x) - 1
+ for i > 0 && x[i] == y[i] {
+ i--
+ }
+ return x[i] < y[i]
+}
+
+// reduceModOrder calculates k = k mod order of the curve.
+func reduceModOrder(k []byte, is512Bit bool) {
+ var X [((2 * paramB) * 8) / 64]uint64
+ numWords := len(k) >> 3
+ for i := 0; i < numWords; i++ {
+ X[i] = binary.LittleEndian.Uint64(k[i*8 : (i+1)*8])
+ }
+ red512(&X, is512Bit)
+ for i := 0; i < numWords; i++ {
+ binary.LittleEndian.PutUint64(k[i*8:(i+1)*8], X[i])
+ }
+}
+
+// red512 calculates x = x mod Order of the curve.
+func red512(x *[8]uint64, full bool) {
+ // Implementation of Algs.(14.47)+(14.52) of Handbook of Applied
+ // Cryptography, by A. Menezes, P. van Oorschot, and S. Vanstone.
+ const (
+ ell0 = uint64(0x5812631a5cf5d3ed)
+ ell1 = uint64(0x14def9dea2f79cd6)
+ ell160 = uint64(0x812631a5cf5d3ed0)
+ ell161 = uint64(0x4def9dea2f79cd65)
+ ell162 = uint64(0x0000000000000001)
+ )
+
+ var c0, c1, c2, c3 uint64
+ r0, r1, r2, r3, r4 := x[0], x[1], x[2], x[3], uint64(0)
+
+ if full {
+ q0, q1, q2, q3 := x[4], x[5], x[6], x[7]
+
+ for i := 0; i < 3; i++ {
+ h0, s0 := bits.Mul64(q0, ell160)
+ h1, s1 := bits.Mul64(q1, ell160)
+ h2, s2 := bits.Mul64(q2, ell160)
+ h3, s3 := bits.Mul64(q3, ell160)
+
+ s1, c0 = bits.Add64(h0, s1, 0)
+ s2, c1 = bits.Add64(h1, s2, c0)
+ s3, c2 = bits.Add64(h2, s3, c1)
+ s4, _ := bits.Add64(h3, 0, c2)
+
+ h0, l0 := bits.Mul64(q0, ell161)
+ h1, l1 := bits.Mul64(q1, ell161)
+ h2, l2 := bits.Mul64(q2, ell161)
+ h3, l3 := bits.Mul64(q3, ell161)
+
+ l1, c0 = bits.Add64(h0, l1, 0)
+ l2, c1 = bits.Add64(h1, l2, c0)
+ l3, c2 = bits.Add64(h2, l3, c1)
+ l4, _ := bits.Add64(h3, 0, c2)
+
+ s1, c0 = bits.Add64(s1, l0, 0)
+ s2, c1 = bits.Add64(s2, l1, c0)
+ s3, c2 = bits.Add64(s3, l2, c1)
+ s4, c3 = bits.Add64(s4, l3, c2)
+ s5, s6 := bits.Add64(l4, 0, c3)
+
+ s2, c0 = bits.Add64(s2, q0, 0)
+ s3, c1 = bits.Add64(s3, q1, c0)
+ s4, c2 = bits.Add64(s4, q2, c1)
+ s5, c3 = bits.Add64(s5, q3, c2)
+ s6, s7 := bits.Add64(s6, 0, c3)
+
+ q := q0 | q1 | q2 | q3
+ m := -((q | -q) >> 63) // if q=0 then m=0...0 else m=1..1
+ s0 &= m
+ s1 &= m
+ s2 &= m
+ s3 &= m
+ q0, q1, q2, q3 = s4, s5, s6, s7
+
+ if (i+1)%2 == 0 {
+ r0, c0 = bits.Add64(r0, s0, 0)
+ r1, c1 = bits.Add64(r1, s1, c0)
+ r2, c2 = bits.Add64(r2, s2, c1)
+ r3, c3 = bits.Add64(r3, s3, c2)
+ r4, _ = bits.Add64(r4, 0, c3)
+ } else {
+ r0, c0 = bits.Sub64(r0, s0, 0)
+ r1, c1 = bits.Sub64(r1, s1, c0)
+ r2, c2 = bits.Sub64(r2, s2, c1)
+ r3, c3 = bits.Sub64(r3, s3, c2)
+ r4, _ = bits.Sub64(r4, 0, c3)
+ }
+ }
+
+ m := -(r4 >> 63)
+ r0, c0 = bits.Add64(r0, m&ell160, 0)
+ r1, c1 = bits.Add64(r1, m&ell161, c0)
+ r2, c2 = bits.Add64(r2, m&ell162, c1)
+ r3, c3 = bits.Add64(r3, 0, c2)
+ r4, _ = bits.Add64(r4, m&1, c3)
+ x[4], x[5], x[6], x[7] = 0, 0, 0, 0
+ }
+
+ q0 := (r4 << 4) | (r3 >> 60)
+ r3 &= (uint64(1) << 60) - 1
+
+ h0, s0 := bits.Mul64(ell0, q0)
+ h1, s1 := bits.Mul64(ell1, q0)
+ s1, c0 = bits.Add64(h0, s1, 0)
+ s2, _ := bits.Add64(h1, 0, c0)
+
+ r0, c0 = bits.Sub64(r0, s0, 0)
+ r1, c1 = bits.Sub64(r1, s1, c0)
+ r2, c2 = bits.Sub64(r2, s2, c1)
+ r3, _ = bits.Sub64(r3, 0, c2)
+
+ x[0], x[1], x[2], x[3] = r0, r1, r2, r3
+}
+
+// calculateS performs s = r+k*a mod Order of the curve.
+func calculateS(s, r, k, a []byte) {
+ K := [4]uint64{
+ binary.LittleEndian.Uint64(k[0*8 : 1*8]),
+ binary.LittleEndian.Uint64(k[1*8 : 2*8]),
+ binary.LittleEndian.Uint64(k[2*8 : 3*8]),
+ binary.LittleEndian.Uint64(k[3*8 : 4*8]),
+ }
+ S := [8]uint64{
+ binary.LittleEndian.Uint64(r[0*8 : 1*8]),
+ binary.LittleEndian.Uint64(r[1*8 : 2*8]),
+ binary.LittleEndian.Uint64(r[2*8 : 3*8]),
+ binary.LittleEndian.Uint64(r[3*8 : 4*8]),
+ }
+ var c3 uint64
+ for i := range K {
+ ai := binary.LittleEndian.Uint64(a[i*8 : (i+1)*8])
+
+ h0, l0 := bits.Mul64(K[0], ai)
+ h1, l1 := bits.Mul64(K[1], ai)
+ h2, l2 := bits.Mul64(K[2], ai)
+ h3, l3 := bits.Mul64(K[3], ai)
+
+ l1, c0 := bits.Add64(h0, l1, 0)
+ l2, c1 := bits.Add64(h1, l2, c0)
+ l3, c2 := bits.Add64(h2, l3, c1)
+ l4, _ := bits.Add64(h3, 0, c2)
+
+ S[i+0], c0 = bits.Add64(S[i+0], l0, 0)
+ S[i+1], c1 = bits.Add64(S[i+1], l1, c0)
+ S[i+2], c2 = bits.Add64(S[i+2], l2, c1)
+ S[i+3], c3 = bits.Add64(S[i+3], l3, c2)
+ S[i+4], _ = bits.Add64(S[i+4], l4, c3)
+ }
+ red512(&S, true)
+ binary.LittleEndian.PutUint64(s[0*8:1*8], S[0])
+ binary.LittleEndian.PutUint64(s[1*8:2*8], S[1])
+ binary.LittleEndian.PutUint64(s[2*8:3*8], S[2])
+ binary.LittleEndian.PutUint64(s[3*8:4*8], S[3])
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go b/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go
new file mode 100644
index 0000000..3216aae
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go
@@ -0,0 +1,180 @@
+package ed25519
+
+import (
+ "crypto/subtle"
+ "encoding/binary"
+ "math/bits"
+
+ "github.com/cloudflare/circl/internal/conv"
+ "github.com/cloudflare/circl/math"
+ fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+var paramD = fp.Elt{
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52,
+}
+
+// mLSBRecoding parameters.
+const (
+ fxT = 257
+ fxV = 2
+ fxW = 3
+ fx2w1 = 1 << (uint(fxW) - 1)
+ numWords64 = (paramB * 8 / 64)
+)
+
+// mLSBRecoding is the odd-only modified LSB-set.
+//
+// Reference:
+//
+// "Efficient and secure algorithms for GLV-based scalar multiplication and
+// their implementation on GLV–GLS curves" by (Faz-Hernandez et al.)
+// http://doi.org/10.1007/s13389-014-0085-7.
+func mLSBRecoding(L []int8, k []byte) {
+ const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
+ const dd = ee * fxV
+ const ll = dd * fxW
+ if len(L) == (ll + 1) {
+ var m [numWords64 + 1]uint64
+ for i := 0; i < numWords64; i++ {
+ m[i] = binary.LittleEndian.Uint64(k[8*i : 8*i+8])
+ }
+ condAddOrderN(&m)
+ L[dd-1] = 1
+ for i := 0; i < dd-1; i++ {
+ kip1 := (m[(i+1)/64] >> (uint(i+1) % 64)) & 0x1
+ L[i] = int8(kip1<<1) - 1
+ }
+ { // right-shift by d
+ right := uint(dd % 64)
+ left := uint(64) - right
+ lim := ((numWords64+1)*64 - dd) / 64
+ j := dd / 64
+ for i := 0; i < lim; i++ {
+ m[i] = (m[i+j] >> right) | (m[i+j+1] << left)
+ }
+ m[lim] = m[lim+j] >> right
+ }
+ for i := dd; i < ll; i++ {
+ L[i] = L[i%dd] * int8(m[0]&0x1)
+ div2subY(m[:], int64(L[i]>>1), numWords64)
+ }
+ L[ll] = int8(m[0])
+ }
+}
+
+// absolute returns always a positive value.
+func absolute(x int32) int32 {
+ mask := x >> 31
+ return (x + mask) ^ mask
+}
+
+// condAddOrderN updates x = x+order if x is even, otherwise x remains unchanged.
+func condAddOrderN(x *[numWords64 + 1]uint64) {
+ isOdd := (x[0] & 0x1) - 1
+ c := uint64(0)
+ for i := 0; i < numWords64; i++ {
+ orderWord := binary.LittleEndian.Uint64(order[8*i : 8*i+8])
+ o := isOdd & orderWord
+ x0, c0 := bits.Add64(x[i], o, c)
+ x[i] = x0
+ c = c0
+ }
+ x[numWords64], _ = bits.Add64(x[numWords64], 0, c)
+}
+
+// div2subY update x = (x/2) - y.
+func div2subY(x []uint64, y int64, l int) {
+ s := uint64(y >> 63)
+ for i := 0; i < l-1; i++ {
+ x[i] = (x[i] >> 1) | (x[i+1] << 63)
+ }
+ x[l-1] = (x[l-1] >> 1)
+
+ b := uint64(0)
+ x0, b0 := bits.Sub64(x[0], uint64(y), b)
+ x[0] = x0
+ b = b0
+ for i := 1; i < l-1; i++ {
+ x0, b0 := bits.Sub64(x[i], s, b)
+ x[i] = x0
+ b = b0
+ }
+ x[l-1], _ = bits.Sub64(x[l-1], s, b)
+}
+
+func (P *pointR1) fixedMult(scalar []byte) {
+ if len(scalar) != paramB {
+ panic("wrong scalar size")
+ }
+ const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
+ const dd = ee * fxV
+ const ll = dd * fxW
+
+ L := make([]int8, ll+1)
+ mLSBRecoding(L[:], scalar)
+ S := &pointR3{}
+ P.SetIdentity()
+ for ii := ee - 1; ii >= 0; ii-- {
+ P.double()
+ for j := 0; j < fxV; j++ {
+ dig := L[fxW*dd-j*ee+ii-ee]
+ for i := (fxW-1)*dd - j*ee + ii - ee; i >= (2*dd - j*ee + ii - ee); i = i - dd {
+ dig = 2*dig + L[i]
+ }
+ idx := absolute(int32(dig))
+ sig := L[dd-j*ee+ii-ee]
+ Tabj := &tabSign[fxV-j-1]
+ for k := 0; k < fx2w1; k++ {
+ S.cmov(&Tabj[k], subtle.ConstantTimeEq(int32(k), idx))
+ }
+ S.cneg(subtle.ConstantTimeEq(int32(sig), -1))
+ P.mixAdd(S)
+ }
+ }
+}
+
+const (
+ omegaFix = 7
+ omegaVar = 5
+)
+
+// doubleMult returns P=mG+nQ.
+func (P *pointR1) doubleMult(Q *pointR1, m, n []byte) {
+ nafFix := math.OmegaNAF(conv.BytesLe2BigInt(m), omegaFix)
+ nafVar := math.OmegaNAF(conv.BytesLe2BigInt(n), omegaVar)
+
+ if len(nafFix) > len(nafVar) {
+ nafVar = append(nafVar, make([]int32, len(nafFix)-len(nafVar))...)
+ } else if len(nafFix) < len(nafVar) {
+ nafFix = append(nafFix, make([]int32, len(nafVar)-len(nafFix))...)
+ }
+
+ var TabQ [1 << (omegaVar - 2)]pointR2
+ Q.oddMultiples(TabQ[:])
+ P.SetIdentity()
+ for i := len(nafFix) - 1; i >= 0; i-- {
+ P.double()
+ // Generator point
+ if nafFix[i] != 0 {
+ idxM := absolute(nafFix[i]) >> 1
+ R := tabVerif[idxM]
+ if nafFix[i] < 0 {
+ R.neg()
+ }
+ P.mixAdd(&R)
+ }
+ // Variable input point
+ if nafVar[i] != 0 {
+ idxN := absolute(nafVar[i]) >> 1
+ S := TabQ[idxN]
+ if nafVar[i] < 0 {
+ S.neg()
+ }
+ P.add(&S)
+ }
+ }
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/point.go b/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
new file mode 100644
index 0000000..374a695
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
@@ -0,0 +1,195 @@
+package ed25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+type (
+ pointR1 struct{ x, y, z, ta, tb fp.Elt }
+ pointR2 struct {
+ pointR3
+ z2 fp.Elt
+ }
+)
+type pointR3 struct{ addYX, subYX, dt2 fp.Elt }
+
+func (P *pointR1) neg() {
+ fp.Neg(&P.x, &P.x)
+ fp.Neg(&P.ta, &P.ta)
+}
+
+func (P *pointR1) SetIdentity() {
+ P.x = fp.Elt{}
+ fp.SetOne(&P.y)
+ fp.SetOne(&P.z)
+ P.ta = fp.Elt{}
+ P.tb = fp.Elt{}
+}
+
+func (P *pointR1) toAffine() {
+ fp.Inv(&P.z, &P.z)
+ fp.Mul(&P.x, &P.x, &P.z)
+ fp.Mul(&P.y, &P.y, &P.z)
+ fp.Modp(&P.x)
+ fp.Modp(&P.y)
+ fp.SetOne(&P.z)
+ P.ta = P.x
+ P.tb = P.y
+}
+
+func (P *pointR1) ToBytes(k []byte) error {
+ P.toAffine()
+ var x [fp.Size]byte
+ err := fp.ToBytes(k[:fp.Size], &P.y)
+ if err != nil {
+ return err
+ }
+ err = fp.ToBytes(x[:], &P.x)
+ if err != nil {
+ return err
+ }
+ b := x[0] & 1
+ k[paramB-1] = k[paramB-1] | (b << 7)
+ return nil
+}
+
+func (P *pointR1) FromBytes(k []byte) bool {
+ if len(k) != paramB {
+ panic("wrong size")
+ }
+ signX := k[paramB-1] >> 7
+ copy(P.y[:], k[:fp.Size])
+ P.y[fp.Size-1] &= 0x7F
+ p := fp.P()
+ if !isLessThan(P.y[:], p[:]) {
+ return false
+ }
+
+ one, u, v := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+ fp.SetOne(one)
+ fp.Sqr(u, &P.y) // u = y^2
+ fp.Mul(v, u, ¶mD) // v = dy^2
+ fp.Sub(u, u, one) // u = y^2-1
+ fp.Add(v, v, one) // v = dy^2+1
+ isQR := fp.InvSqrt(&P.x, u, v) // x = sqrt(u/v)
+ if !isQR {
+ return false
+ }
+ fp.Modp(&P.x) // x = x mod p
+ if fp.IsZero(&P.x) && signX == 1 {
+ return false
+ }
+ if signX != (P.x[0] & 1) {
+ fp.Neg(&P.x, &P.x)
+ }
+ P.ta = P.x
+ P.tb = P.y
+ fp.SetOne(&P.z)
+ return true
+}
+
+// double calculates 2P for curves with A=-1.
+func (P *pointR1) double() {
+ Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
+ fp.Add(e, Px, Py) // x+y
+ fp.Sqr(a, Px) // A = x^2
+ fp.Sqr(b, Py) // B = y^2
+ fp.Sqr(c, Pz) // z^2
+ fp.Add(c, c, c) // C = 2*z^2
+ fp.Add(h, a, b) // H = A+B
+ fp.Sqr(e, e) // (x+y)^2
+ fp.Sub(e, e, h) // E = (x+y)^2-A-B
+ fp.Sub(g, b, a) // G = B-A
+ fp.Sub(f, c, g) // F = C-G
+ fp.Mul(Pz, f, g) // Z = F * G
+ fp.Mul(Px, e, f) // X = E * F
+ fp.Mul(Py, g, h) // Y = G * H, T = E * H
+}
+
+func (P *pointR1) mixAdd(Q *pointR3) {
+ fp.Add(&P.z, &P.z, &P.z) // D = 2*z1
+ P.coreAddition(Q)
+}
+
+func (P *pointR1) add(Q *pointR2) {
+ fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2
+ P.coreAddition(&Q.pointR3)
+}
+
+// coreAddition calculates P=P+Q for curves with A=-1.
+func (P *pointR1) coreAddition(Q *pointR3) {
+ Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+ addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
+ a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
+ fp.Mul(c, Pta, Ptb) // t1 = ta*tb
+ fp.Sub(h, Py, Px) // y1-x1
+ fp.Add(b, Py, Px) // y1+x1
+ fp.Mul(a, h, subYX2) // A = (y1-x1)*(y2-x2)
+ fp.Mul(b, b, addYX2) // B = (y1+x1)*(y2+x2)
+ fp.Mul(c, c, dt2) // C = 2*D*t1*t2
+ fp.Sub(e, b, a) // E = B-A
+ fp.Add(h, b, a) // H = B+A
+ fp.Sub(f, d, c) // F = D-C
+ fp.Add(g, d, c) // G = D+C
+ fp.Mul(Pz, f, g) // Z = F * G
+ fp.Mul(Px, e, f) // X = E * F
+ fp.Mul(Py, g, h) // Y = G * H, T = E * H
+}
+
+func (P *pointR1) oddMultiples(T []pointR2) {
+ var R pointR2
+ n := len(T)
+ T[0].fromR1(P)
+ _2P := *P
+ _2P.double()
+ R.fromR1(&_2P)
+ for i := 1; i < n; i++ {
+ P.add(&R)
+ T[i].fromR1(P)
+ }
+}
+
+func (P *pointR1) isEqual(Q *pointR1) bool {
+ l, r := &fp.Elt{}, &fp.Elt{}
+ fp.Mul(l, &P.x, &Q.z)
+ fp.Mul(r, &Q.x, &P.z)
+ fp.Sub(l, l, r)
+ b := fp.IsZero(l)
+ fp.Mul(l, &P.y, &Q.z)
+ fp.Mul(r, &Q.y, &P.z)
+ fp.Sub(l, l, r)
+ b = b && fp.IsZero(l)
+ fp.Mul(l, &P.ta, &P.tb)
+ fp.Mul(l, l, &Q.z)
+ fp.Mul(r, &Q.ta, &Q.tb)
+ fp.Mul(r, r, &P.z)
+ fp.Sub(l, l, r)
+ b = b && fp.IsZero(l)
+ return b
+}
+
+func (P *pointR3) neg() {
+ P.addYX, P.subYX = P.subYX, P.addYX
+ fp.Neg(&P.dt2, &P.dt2)
+}
+
+func (P *pointR2) fromR1(Q *pointR1) {
+ fp.Add(&P.addYX, &Q.y, &Q.x)
+ fp.Sub(&P.subYX, &Q.y, &Q.x)
+ fp.Mul(&P.dt2, &Q.ta, &Q.tb)
+ fp.Mul(&P.dt2, &P.dt2, ¶mD)
+ fp.Add(&P.dt2, &P.dt2, &P.dt2)
+ fp.Add(&P.z2, &Q.z, &Q.z)
+}
+
+func (P *pointR3) cneg(b int) {
+ t := &fp.Elt{}
+ fp.Cswap(&P.addYX, &P.subYX, uint(b))
+ fp.Neg(t, &P.dt2)
+ fp.Cmov(&P.dt2, t, uint(b))
+}
+
+func (P *pointR3) cmov(Q *pointR3, b int) {
+ fp.Cmov(&P.addYX, &Q.addYX, uint(b))
+ fp.Cmov(&P.subYX, &Q.subYX, uint(b))
+ fp.Cmov(&P.dt2, &Q.dt2, uint(b))
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go
new file mode 100644
index 0000000..c3505b6
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go
@@ -0,0 +1,9 @@
+//go:build go1.13
+// +build go1.13
+
+package ed25519
+
+import cryptoEd25519 "crypto/ed25519"
+
+// PublicKey is the type of Ed25519 public keys.
+type PublicKey cryptoEd25519.PublicKey
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go
new file mode 100644
index 0000000..d57d86e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go
@@ -0,0 +1,7 @@
+//go:build !go1.13
+// +build !go1.13
+
+package ed25519
+
+// PublicKey is the type of Ed25519 public keys.
+type PublicKey []byte
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go b/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go
new file mode 100644
index 0000000..e4520f5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go
@@ -0,0 +1,87 @@
+package ed25519
+
+import (
+ "crypto/rand"
+ "encoding/asn1"
+
+ "github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string { return "Ed25519" }
+func (*scheme) PublicKeySize() int { return PublicKeySize }
+func (*scheme) PrivateKeySize() int { return PrivateKeySize }
+func (*scheme) SignatureSize() int { return SignatureSize }
+func (*scheme) SeedSize() int { return SeedSize }
+func (*scheme) TLSIdentifier() uint { return 0x0807 }
+func (*scheme) SupportsContext() bool { return false }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+ return asn1.ObjectIdentifier{1, 3, 101, 112}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+ return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+ sk sign.PrivateKey,
+ message []byte,
+ opts *sign.SignatureOpts,
+) []byte {
+ priv, ok := sk.(PrivateKey)
+ if !ok {
+ panic(sign.ErrTypeMismatch)
+ }
+ if opts != nil && opts.Context != "" {
+ panic(sign.ErrContextNotSupported)
+ }
+ return Sign(priv, message)
+}
+
+func (*scheme) Verify(
+ pk sign.PublicKey,
+ message, signature []byte,
+ opts *sign.SignatureOpts,
+) bool {
+ pub, ok := pk.(PublicKey)
+ if !ok {
+ panic(sign.ErrTypeMismatch)
+ }
+ if opts != nil {
+ if opts.Context != "" {
+ panic(sign.ErrContextNotSupported)
+ }
+ }
+ return Verify(pub, message, signature)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+ privateKey := NewKeyFromSeed(seed)
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, privateKey[SeedSize:])
+ return publicKey, privateKey
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+ if len(buf) < PublicKeySize {
+ return nil, sign.ErrPubKeySize
+ }
+ pub := make(PublicKey, PublicKeySize)
+ copy(pub, buf[:PublicKeySize])
+ return pub, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+ if len(buf) < PrivateKeySize {
+ return nil, sign.ErrPrivKeySize
+ }
+ priv := make(PrivateKey, PrivateKeySize)
+ copy(priv, buf[:PrivateKeySize])
+ return priv, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go b/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go
new file mode 100644
index 0000000..8763b42
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go
@@ -0,0 +1,213 @@
+package ed25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+var tabSign = [fxV][fx2w1]pointR3{
+ {
+ pointR3{
+ addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
+ subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
+ dt2: fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
+ },
+ {
+ addYX: fp.Elt{0x7c, 0xb0, 0x9e, 0xe6, 0xc5, 0xbf, 0xfa, 0x13, 0x8e, 0x0d, 0x22, 0xde, 0xc8, 0xd1, 0xce, 0x52, 0x02, 0xd5, 0x62, 0x31, 0x71, 0x0e, 0x8e, 0x9d, 0xb0, 0xd6, 0x00, 0xa5, 0x5a, 0x0e, 0xce, 0x72},
+ subYX: fp.Elt{0x1a, 0x8e, 0x5c, 0xdc, 0xa4, 0xb3, 0x6c, 0x51, 0x18, 0xa0, 0x09, 0x80, 0x9a, 0x46, 0x33, 0xd5, 0xe0, 0x3c, 0x4d, 0x3b, 0xfc, 0x49, 0xa2, 0x43, 0x29, 0xe1, 0x29, 0xa9, 0x93, 0xea, 0x7c, 0x35},
+ dt2: fp.Elt{0x08, 0x46, 0x6f, 0x68, 0x7f, 0x0b, 0x7c, 0x9e, 0xad, 0xba, 0x07, 0x61, 0x74, 0x83, 0x2f, 0xfc, 0x26, 0xd6, 0x09, 0xb9, 0x00, 0x34, 0x36, 0x4f, 0x01, 0xf3, 0x48, 0xdb, 0x43, 0xba, 0x04, 0x44},
+ },
+ {
+ addYX: fp.Elt{0x4c, 0xda, 0x0d, 0x13, 0x66, 0xfd, 0x82, 0x84, 0x9f, 0x75, 0x5b, 0xa2, 0x17, 0xfe, 0x34, 0xbf, 0x1f, 0xcb, 0xba, 0x90, 0x55, 0x80, 0x83, 0xfd, 0x63, 0xb9, 0x18, 0xf8, 0x5b, 0x5d, 0x94, 0x1e},
+ subYX: fp.Elt{0xb9, 0xdb, 0x6c, 0x04, 0x88, 0x22, 0xd8, 0x79, 0x83, 0x2f, 0x8d, 0x65, 0x6b, 0xd2, 0xab, 0x1b, 0xdd, 0x65, 0xe5, 0x93, 0x63, 0xf8, 0xa2, 0xd8, 0x3c, 0xf1, 0x4b, 0xc5, 0x99, 0xd1, 0xf2, 0x12},
+ dt2: fp.Elt{0x05, 0x4c, 0xb8, 0x3b, 0xfe, 0xf5, 0x9f, 0x2e, 0xd1, 0xb2, 0xb8, 0xff, 0xfe, 0x6d, 0xd9, 0x37, 0xe0, 0xae, 0xb4, 0x5a, 0x51, 0x80, 0x7e, 0x9b, 0x1d, 0xd1, 0x8d, 0x8c, 0x56, 0xb1, 0x84, 0x35},
+ },
+ {
+ addYX: fp.Elt{0x39, 0x71, 0x43, 0x34, 0xe3, 0x42, 0x45, 0xa1, 0xf2, 0x68, 0x71, 0xa7, 0xe8, 0x23, 0xfd, 0x9f, 0x86, 0x48, 0xff, 0xe5, 0x96, 0x74, 0xcf, 0x05, 0x49, 0xe2, 0xb3, 0x6c, 0x17, 0x77, 0x2f, 0x6d},
+ subYX: fp.Elt{0x73, 0x3f, 0xc1, 0xc7, 0x6a, 0x66, 0xa1, 0x20, 0xdd, 0x11, 0xfb, 0x7a, 0x6e, 0xa8, 0x51, 0xb8, 0x3f, 0x9d, 0xa2, 0x97, 0x84, 0xb5, 0xc7, 0x90, 0x7c, 0xab, 0x48, 0xd6, 0x84, 0xa3, 0xd5, 0x1a},
+ dt2: fp.Elt{0x63, 0x27, 0x3c, 0x49, 0x4b, 0xfc, 0x22, 0xf2, 0x0b, 0x50, 0xc2, 0x0f, 0xb4, 0x1f, 0x31, 0x0c, 0x2f, 0x53, 0xab, 0xaa, 0x75, 0x6f, 0xe0, 0x69, 0x39, 0x56, 0xe0, 0x3b, 0xb7, 0xa8, 0xbf, 0x45},
+ },
+ },
+ {
+ {
+ addYX: fp.Elt{0x00, 0x45, 0xd9, 0x0d, 0x58, 0x03, 0xfc, 0x29, 0x93, 0xec, 0xbb, 0x6f, 0xa4, 0x7a, 0xd2, 0xec, 0xf8, 0xa7, 0xe2, 0xc2, 0x5f, 0x15, 0x0a, 0x13, 0xd5, 0xa1, 0x06, 0xb7, 0x1a, 0x15, 0x6b, 0x41},
+ subYX: fp.Elt{0x85, 0x8c, 0xb2, 0x17, 0xd6, 0x3b, 0x0a, 0xd3, 0xea, 0x3b, 0x77, 0x39, 0xb7, 0x77, 0xd3, 0xc5, 0xbf, 0x5c, 0x6a, 0x1e, 0x8c, 0xe7, 0xc6, 0xc6, 0xc4, 0xb7, 0x2a, 0x8b, 0xf7, 0xb8, 0x61, 0x0d},
+ dt2: fp.Elt{0xb0, 0x36, 0xc1, 0xe9, 0xef, 0xd7, 0xa8, 0x56, 0x20, 0x4b, 0xe4, 0x58, 0xcd, 0xe5, 0x07, 0xbd, 0xab, 0xe0, 0x57, 0x1b, 0xda, 0x2f, 0xe6, 0xaf, 0xd2, 0xe8, 0x77, 0x42, 0xf7, 0x2a, 0x1a, 0x19},
+ },
+ {
+ addYX: fp.Elt{0x6a, 0x6d, 0x6d, 0xd1, 0xfa, 0xf5, 0x03, 0x30, 0xbd, 0x6d, 0xc2, 0xc8, 0xf5, 0x38, 0x80, 0x4f, 0xb2, 0xbe, 0xa1, 0x76, 0x50, 0x1a, 0x73, 0xf2, 0x78, 0x2b, 0x8e, 0x3a, 0x1e, 0x34, 0x47, 0x7b},
+ subYX: fp.Elt{0xc3, 0x2c, 0x36, 0xdc, 0xc5, 0x45, 0xbc, 0xef, 0x1b, 0x64, 0xd6, 0x65, 0x28, 0xe9, 0xda, 0x84, 0x13, 0xbe, 0x27, 0x8e, 0x3f, 0x98, 0x2a, 0x37, 0xee, 0x78, 0x97, 0xd6, 0xc0, 0x6f, 0xb4, 0x53},
+ dt2: fp.Elt{0x58, 0x5d, 0xa7, 0xa3, 0x68, 0xbb, 0x20, 0x30, 0x2e, 0x03, 0xe9, 0xb1, 0xd4, 0x90, 0x72, 0xe3, 0x71, 0xb2, 0x36, 0x3e, 0x73, 0xa0, 0x2e, 0x3d, 0xd1, 0x85, 0x33, 0x62, 0x4e, 0xa7, 0x7b, 0x31},
+ },
+ {
+ addYX: fp.Elt{0xbf, 0xc4, 0x38, 0x53, 0xfb, 0x68, 0xa9, 0x77, 0xce, 0x55, 0xf9, 0x05, 0xcb, 0xeb, 0xfb, 0x8c, 0x46, 0xc2, 0x32, 0x7c, 0xf0, 0xdb, 0xd7, 0x2c, 0x62, 0x8e, 0xdd, 0x54, 0x75, 0xcf, 0x3f, 0x33},
+ subYX: fp.Elt{0x49, 0x50, 0x1f, 0x4e, 0x6e, 0x55, 0x55, 0xde, 0x8c, 0x4e, 0x77, 0x96, 0x38, 0x3b, 0xfe, 0xb6, 0x43, 0x3c, 0x86, 0x69, 0xc2, 0x72, 0x66, 0x1f, 0x6b, 0xf9, 0x87, 0xbc, 0x4f, 0x37, 0x3e, 0x3c},
+ dt2: fp.Elt{0xd2, 0x2f, 0x06, 0x6b, 0x08, 0x07, 0x69, 0x77, 0xc0, 0x94, 0xcc, 0xae, 0x43, 0x00, 0x59, 0x6e, 0xa3, 0x63, 0xa8, 0xdd, 0xfa, 0x24, 0x18, 0xd0, 0x35, 0xc7, 0x78, 0xf7, 0x0d, 0xd4, 0x5a, 0x1e},
+ },
+ {
+ addYX: fp.Elt{0x45, 0xc1, 0x17, 0x51, 0xf8, 0xed, 0x7e, 0xc7, 0xa9, 0x1a, 0x11, 0x6e, 0x2d, 0xef, 0x0b, 0xd5, 0x3f, 0x98, 0xb0, 0xa3, 0x9d, 0x65, 0xf1, 0xcd, 0x53, 0x4a, 0x8a, 0x18, 0x70, 0x0a, 0x7f, 0x23},
+ subYX: fp.Elt{0xdd, 0xef, 0xbe, 0x3a, 0x31, 0xe0, 0xbc, 0xbe, 0x6d, 0x5d, 0x79, 0x87, 0xd6, 0xbe, 0x68, 0xe3, 0x59, 0x76, 0x8c, 0x86, 0x0e, 0x7a, 0x92, 0x13, 0x14, 0x8f, 0x67, 0xb3, 0xcb, 0x1a, 0x76, 0x76},
+ dt2: fp.Elt{0x56, 0x7a, 0x1c, 0x9d, 0xca, 0x96, 0xf9, 0xf9, 0x03, 0x21, 0xd4, 0xe8, 0xb3, 0xd5, 0xe9, 0x52, 0xc8, 0x54, 0x1e, 0x1b, 0x13, 0xb6, 0xfd, 0x47, 0x7d, 0x02, 0x32, 0x33, 0x27, 0xe2, 0x1f, 0x19},
+ },
+ },
+}
+
+var tabVerif = [1 << (omegaFix - 2)]pointR3{
+ { /* 1P */
+ addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
+ subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
+ dt2: fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
+ },
+ { /* 3P */
+ addYX: fp.Elt{0x30, 0x97, 0xee, 0x4c, 0xa8, 0xb0, 0x25, 0xaf, 0x8a, 0x4b, 0x86, 0xe8, 0x30, 0x84, 0x5a, 0x02, 0x32, 0x67, 0x01, 0x9f, 0x02, 0x50, 0x1b, 0xc1, 0xf4, 0xf8, 0x80, 0x9a, 0x1b, 0x4e, 0x16, 0x7a},
+ subYX: fp.Elt{0x65, 0xd2, 0xfc, 0xa4, 0xe8, 0x1f, 0x61, 0x56, 0x7d, 0xba, 0xc1, 0xe5, 0xfd, 0x53, 0xd3, 0x3b, 0xbd, 0xd6, 0x4b, 0x21, 0x1a, 0xf3, 0x31, 0x81, 0x62, 0xda, 0x5b, 0x55, 0x87, 0x15, 0xb9, 0x2a},
+ dt2: fp.Elt{0x89, 0xd8, 0xd0, 0x0d, 0x3f, 0x93, 0xae, 0x14, 0x62, 0xda, 0x35, 0x1c, 0x22, 0x23, 0x94, 0x58, 0x4c, 0xdb, 0xf2, 0x8c, 0x45, 0xe5, 0x70, 0xd1, 0xc6, 0xb4, 0xb9, 0x12, 0xaf, 0x26, 0x28, 0x5a},
+ },
+ { /* 5P */
+ addYX: fp.Elt{0x33, 0xbb, 0xa5, 0x08, 0x44, 0xbc, 0x12, 0xa2, 0x02, 0xed, 0x5e, 0xc7, 0xc3, 0x48, 0x50, 0x8d, 0x44, 0xec, 0xbf, 0x5a, 0x0c, 0xeb, 0x1b, 0xdd, 0xeb, 0x06, 0xe2, 0x46, 0xf1, 0xcc, 0x45, 0x29},
+ subYX: fp.Elt{0xba, 0xd6, 0x47, 0xa4, 0xc3, 0x82, 0x91, 0x7f, 0xb7, 0x29, 0x27, 0x4b, 0xd1, 0x14, 0x00, 0xd5, 0x87, 0xa0, 0x64, 0xb8, 0x1c, 0xf1, 0x3c, 0xe3, 0xf3, 0x55, 0x1b, 0xeb, 0x73, 0x7e, 0x4a, 0x15},
+ dt2: fp.Elt{0x85, 0x82, 0x2a, 0x81, 0xf1, 0xdb, 0xbb, 0xbc, 0xfc, 0xd1, 0xbd, 0xd0, 0x07, 0x08, 0x0e, 0x27, 0x2d, 0xa7, 0xbd, 0x1b, 0x0b, 0x67, 0x1b, 0xb4, 0x9a, 0xb6, 0x3b, 0x6b, 0x69, 0xbe, 0xaa, 0x43},
+ },
+ { /* 7P */
+ addYX: fp.Elt{0xbf, 0xa3, 0x4e, 0x94, 0xd0, 0x5c, 0x1a, 0x6b, 0xd2, 0xc0, 0x9d, 0xb3, 0x3a, 0x35, 0x70, 0x74, 0x49, 0x2e, 0x54, 0x28, 0x82, 0x52, 0xb2, 0x71, 0x7e, 0x92, 0x3c, 0x28, 0x69, 0xea, 0x1b, 0x46},
+ subYX: fp.Elt{0xb1, 0x21, 0x32, 0xaa, 0x9a, 0x2c, 0x6f, 0xba, 0xa7, 0x23, 0xba, 0x3b, 0x53, 0x21, 0xa0, 0x6c, 0x3a, 0x2c, 0x19, 0x92, 0x4f, 0x76, 0xea, 0x9d, 0xe0, 0x17, 0x53, 0x2e, 0x5d, 0xdd, 0x6e, 0x1d},
+ dt2: fp.Elt{0xa2, 0xb3, 0xb8, 0x01, 0xc8, 0x6d, 0x83, 0xf1, 0x9a, 0xa4, 0x3e, 0x05, 0x47, 0x5f, 0x03, 0xb3, 0xf3, 0xad, 0x77, 0x58, 0xba, 0x41, 0x9c, 0x52, 0xa7, 0x90, 0x0f, 0x6a, 0x1c, 0xbb, 0x9f, 0x7a},
+ },
+ { /* 9P */
+ addYX: fp.Elt{0x2f, 0x63, 0xa8, 0xa6, 0x8a, 0x67, 0x2e, 0x9b, 0xc5, 0x46, 0xbc, 0x51, 0x6f, 0x9e, 0x50, 0xa6, 0xb5, 0xf5, 0x86, 0xc6, 0xc9, 0x33, 0xb2, 0xce, 0x59, 0x7f, 0xdd, 0x8a, 0x33, 0xed, 0xb9, 0x34},
+ subYX: fp.Elt{0x64, 0x80, 0x9d, 0x03, 0x7e, 0x21, 0x6e, 0xf3, 0x9b, 0x41, 0x20, 0xf5, 0xb6, 0x81, 0xa0, 0x98, 0x44, 0xb0, 0x5e, 0xe7, 0x08, 0xc6, 0xcb, 0x96, 0x8f, 0x9c, 0xdc, 0xfa, 0x51, 0x5a, 0xc0, 0x49},
+ dt2: fp.Elt{0x1b, 0xaf, 0x45, 0x90, 0xbf, 0xe8, 0xb4, 0x06, 0x2f, 0xd2, 0x19, 0xa7, 0xe8, 0x83, 0xff, 0xe2, 0x16, 0xcf, 0xd4, 0x93, 0x29, 0xfc, 0xf6, 0xaa, 0x06, 0x8b, 0x00, 0x1b, 0x02, 0x72, 0xc1, 0x73},
+ },
+ { /* 11P */
+ addYX: fp.Elt{0xde, 0x2a, 0x80, 0x8a, 0x84, 0x00, 0xbf, 0x2f, 0x27, 0x2e, 0x30, 0x02, 0xcf, 0xfe, 0xd9, 0xe5, 0x06, 0x34, 0x70, 0x17, 0x71, 0x84, 0x3e, 0x11, 0xaf, 0x8f, 0x6d, 0x54, 0xe2, 0xaa, 0x75, 0x42},
+ subYX: fp.Elt{0x48, 0x43, 0x86, 0x49, 0x02, 0x5b, 0x5f, 0x31, 0x81, 0x83, 0x08, 0x77, 0x69, 0xb3, 0xd6, 0x3e, 0x95, 0xeb, 0x8d, 0x6a, 0x55, 0x75, 0xa0, 0xa3, 0x7f, 0xc7, 0xd5, 0x29, 0x80, 0x59, 0xab, 0x18},
+ dt2: fp.Elt{0xe9, 0x89, 0x60, 0xfd, 0xc5, 0x2c, 0x2b, 0xd8, 0xa4, 0xe4, 0x82, 0x32, 0xa1, 0xb4, 0x1e, 0x03, 0x22, 0x86, 0x1a, 0xb5, 0x99, 0x11, 0x31, 0x44, 0x48, 0xf9, 0x3d, 0xb5, 0x22, 0x55, 0xc6, 0x3d},
+ },
+ { /* 13P */
+ addYX: fp.Elt{0x6d, 0x7f, 0x00, 0xa2, 0x22, 0xc2, 0x70, 0xbf, 0xdb, 0xde, 0xbc, 0xb5, 0x9a, 0xb3, 0x84, 0xbf, 0x07, 0xba, 0x07, 0xfb, 0x12, 0x0e, 0x7a, 0x53, 0x41, 0xf2, 0x46, 0xc3, 0xee, 0xd7, 0x4f, 0x23},
+ subYX: fp.Elt{0x93, 0xbf, 0x7f, 0x32, 0x3b, 0x01, 0x6f, 0x50, 0x6b, 0x6f, 0x77, 0x9b, 0xc9, 0xeb, 0xfc, 0xae, 0x68, 0x59, 0xad, 0xaa, 0x32, 0xb2, 0x12, 0x9d, 0xa7, 0x24, 0x60, 0x17, 0x2d, 0x88, 0x67, 0x02},
+ dt2: fp.Elt{0x78, 0xa3, 0x2e, 0x73, 0x19, 0xa1, 0x60, 0x53, 0x71, 0xd4, 0x8d, 0xdf, 0xb1, 0xe6, 0x37, 0x24, 0x33, 0xe5, 0xa7, 0x91, 0xf8, 0x37, 0xef, 0xa2, 0x63, 0x78, 0x09, 0xaa, 0xfd, 0xa6, 0x7b, 0x49},
+ },
+ { /* 15P */
+ addYX: fp.Elt{0xa0, 0xea, 0xcf, 0x13, 0x03, 0xcc, 0xce, 0x24, 0x6d, 0x24, 0x9c, 0x18, 0x8d, 0xc2, 0x48, 0x86, 0xd0, 0xd4, 0xf2, 0xc1, 0xfa, 0xbd, 0xbd, 0x2d, 0x2b, 0xe7, 0x2d, 0xf1, 0x17, 0x29, 0xe2, 0x61},
+ subYX: fp.Elt{0x0b, 0xcf, 0x8c, 0x46, 0x86, 0xcd, 0x0b, 0x04, 0xd6, 0x10, 0x99, 0x2a, 0xa4, 0x9b, 0x82, 0xd3, 0x92, 0x51, 0xb2, 0x07, 0x08, 0x30, 0x08, 0x75, 0xbf, 0x5e, 0xd0, 0x18, 0x42, 0xcd, 0xb5, 0x43},
+ dt2: fp.Elt{0x16, 0xb5, 0xd0, 0x9b, 0x2f, 0x76, 0x9a, 0x5d, 0xee, 0xde, 0x3f, 0x37, 0x4e, 0xaf, 0x38, 0xeb, 0x70, 0x42, 0xd6, 0x93, 0x7d, 0x5a, 0x2e, 0x03, 0x42, 0xd8, 0xe4, 0x0a, 0x21, 0x61, 0x1d, 0x51},
+ },
+ { /* 17P */
+ addYX: fp.Elt{0x81, 0x9d, 0x0e, 0x95, 0xef, 0x76, 0xc6, 0x92, 0x4f, 0x04, 0xd7, 0xc0, 0xcd, 0x20, 0x46, 0xa5, 0x48, 0x12, 0x8f, 0x6f, 0x64, 0x36, 0x9b, 0xaa, 0xe3, 0x55, 0xb8, 0xdd, 0x24, 0x59, 0x32, 0x6d},
+ subYX: fp.Elt{0x87, 0xde, 0x20, 0x44, 0x48, 0x86, 0x13, 0x08, 0xb4, 0xed, 0x92, 0xb5, 0x16, 0xf0, 0x1c, 0x8a, 0x25, 0x2d, 0x94, 0x29, 0x27, 0x4e, 0xfa, 0x39, 0x10, 0x28, 0x48, 0xe2, 0x6f, 0xfe, 0xa7, 0x71},
+ dt2: fp.Elt{0x54, 0xc8, 0xc8, 0xa5, 0xb8, 0x82, 0x71, 0x6c, 0x03, 0x2a, 0x5f, 0xfe, 0x79, 0x14, 0xfd, 0x33, 0x0c, 0x8d, 0x77, 0x83, 0x18, 0x59, 0xcf, 0x72, 0xa9, 0xea, 0x9e, 0x55, 0xb6, 0xc4, 0x46, 0x47},
+ },
+ { /* 19P */
+ addYX: fp.Elt{0x2b, 0x9a, 0xc6, 0x6d, 0x3c, 0x7b, 0x77, 0xd3, 0x17, 0xf6, 0x89, 0x6f, 0x27, 0xb2, 0xfa, 0xde, 0xb5, 0x16, 0x3a, 0xb5, 0xf7, 0x1c, 0x65, 0x45, 0xb7, 0x9f, 0xfe, 0x34, 0xde, 0x51, 0x9a, 0x5c},
+ subYX: fp.Elt{0x47, 0x11, 0x74, 0x64, 0xc8, 0x46, 0x85, 0x34, 0x49, 0xc8, 0xfc, 0x0e, 0xdd, 0xae, 0x35, 0x7d, 0x32, 0xa3, 0x72, 0x06, 0x76, 0x9a, 0x93, 0xff, 0xd6, 0xe6, 0xb5, 0x7d, 0x49, 0x63, 0x96, 0x21},
+ dt2: fp.Elt{0x67, 0x0e, 0xf1, 0x79, 0xcf, 0xf1, 0x10, 0xf5, 0x5b, 0x51, 0x58, 0xe6, 0xa1, 0xda, 0xdd, 0xff, 0x77, 0x22, 0x14, 0x10, 0x17, 0xa7, 0xc3, 0x09, 0xbb, 0x23, 0x82, 0x60, 0x3c, 0x50, 0x04, 0x48},
+ },
+ { /* 21P */
+ addYX: fp.Elt{0xc7, 0x7f, 0xa3, 0x2c, 0xd0, 0x9e, 0x24, 0xc4, 0xab, 0xac, 0x15, 0xa6, 0xe3, 0xa0, 0x59, 0xa0, 0x23, 0x0e, 0x6e, 0xc9, 0xd7, 0x6e, 0xa9, 0x88, 0x6d, 0x69, 0x50, 0x16, 0xa5, 0x98, 0x33, 0x55},
+ subYX: fp.Elt{0x75, 0xd1, 0x36, 0x3a, 0xd2, 0x21, 0x68, 0x3b, 0x32, 0x9e, 0x9b, 0xe9, 0xa7, 0x0a, 0xb4, 0xbb, 0x47, 0x8a, 0x83, 0x20, 0xe4, 0x5c, 0x9e, 0x5d, 0x5e, 0x4c, 0xde, 0x58, 0x88, 0x09, 0x1e, 0x77},
+ dt2: fp.Elt{0xdf, 0x1e, 0x45, 0x78, 0xd2, 0xf5, 0x12, 0x9a, 0xcb, 0x9c, 0x89, 0x85, 0x79, 0x5d, 0xda, 0x3a, 0x08, 0x95, 0xa5, 0x9f, 0x2d, 0x4a, 0x7f, 0x47, 0x11, 0xa6, 0xf5, 0x8f, 0xd6, 0xd1, 0x5e, 0x5a},
+ },
+ { /* 23P */
+ addYX: fp.Elt{0x83, 0x0e, 0x15, 0xfe, 0x2a, 0x12, 0x95, 0x11, 0xd8, 0x35, 0x4b, 0x7e, 0x25, 0x9a, 0x20, 0xcf, 0x20, 0x1e, 0x71, 0x1e, 0x29, 0xf8, 0x87, 0x73, 0xf0, 0x92, 0xbf, 0xd8, 0x97, 0xb8, 0xac, 0x44},
+ subYX: fp.Elt{0x59, 0x73, 0x52, 0x58, 0xc5, 0xe0, 0xe5, 0xba, 0x7e, 0x9d, 0xdb, 0xca, 0x19, 0x5c, 0x2e, 0x39, 0xe9, 0xab, 0x1c, 0xda, 0x1e, 0x3c, 0x65, 0x28, 0x44, 0xdc, 0xef, 0x5f, 0x13, 0x60, 0x9b, 0x01},
+ dt2: fp.Elt{0x83, 0x4b, 0x13, 0x5e, 0x14, 0x68, 0x60, 0x1e, 0x16, 0x4c, 0x30, 0x24, 0x4f, 0xe6, 0xf5, 0xc4, 0xd7, 0x3e, 0x1a, 0xfc, 0xa8, 0x88, 0x6e, 0x50, 0x92, 0x2f, 0xad, 0xe6, 0xfd, 0x49, 0x0c, 0x15},
+ },
+ { /* 25P */
+ addYX: fp.Elt{0x38, 0x11, 0x47, 0x09, 0x95, 0xf2, 0x7b, 0x8e, 0x51, 0xa6, 0x75, 0x4f, 0x39, 0xef, 0x6f, 0x5d, 0xad, 0x08, 0xa7, 0x25, 0xc4, 0x79, 0xaf, 0x10, 0x22, 0x99, 0xb9, 0x5b, 0x07, 0x5a, 0x2b, 0x6b},
+ subYX: fp.Elt{0x68, 0xa8, 0xdc, 0x9c, 0x3c, 0x86, 0x49, 0xb8, 0xd0, 0x4a, 0x71, 0xb8, 0xdb, 0x44, 0x3f, 0xc8, 0x8d, 0x16, 0x36, 0x0c, 0x56, 0xe3, 0x3e, 0xfe, 0xc1, 0xfb, 0x05, 0x1e, 0x79, 0xd7, 0xa6, 0x78},
+ dt2: fp.Elt{0x76, 0xb9, 0xa0, 0x47, 0x4b, 0x70, 0xbf, 0x58, 0xd5, 0x48, 0x17, 0x74, 0x55, 0xb3, 0x01, 0xa6, 0x90, 0xf5, 0x42, 0xd5, 0xb1, 0x1f, 0x2b, 0xaa, 0x00, 0x5d, 0xd5, 0x4a, 0xfc, 0x7f, 0x5c, 0x72},
+ },
+ { /* 27P */
+ addYX: fp.Elt{0xb2, 0x99, 0xcf, 0xd1, 0x15, 0x67, 0x42, 0xe4, 0x34, 0x0d, 0xa2, 0x02, 0x11, 0xd5, 0x52, 0x73, 0x9f, 0x10, 0x12, 0x8b, 0x7b, 0x15, 0xd1, 0x23, 0xa3, 0xf3, 0xb1, 0x7c, 0x27, 0xc9, 0x4c, 0x79},
+ subYX: fp.Elt{0xc0, 0x98, 0xd0, 0x1c, 0xf7, 0x2b, 0x80, 0x91, 0x66, 0x63, 0x5e, 0xed, 0xa4, 0x6c, 0x41, 0xfe, 0x4c, 0x99, 0x02, 0x49, 0x71, 0x5d, 0x58, 0xdf, 0xe7, 0xfa, 0x55, 0xf8, 0x25, 0x46, 0xd5, 0x4c},
+ dt2: fp.Elt{0x53, 0x50, 0xac, 0xc2, 0x26, 0xc4, 0xf6, 0x4a, 0x58, 0x72, 0xf6, 0x32, 0xad, 0xed, 0x9a, 0xbc, 0x21, 0x10, 0x31, 0x0a, 0xf1, 0x32, 0xd0, 0x2a, 0x85, 0x8e, 0xcc, 0x6f, 0x7b, 0x35, 0x08, 0x70},
+ },
+ { /* 29P */
+ addYX: fp.Elt{0x01, 0x3f, 0x77, 0x38, 0x27, 0x67, 0x88, 0x0b, 0xfb, 0xcc, 0xfb, 0x95, 0xfa, 0xc8, 0xcc, 0xb8, 0xb6, 0x29, 0xad, 0xb9, 0xa3, 0xd5, 0x2d, 0x8d, 0x6a, 0x0f, 0xad, 0x51, 0x98, 0x7e, 0xef, 0x06},
+ subYX: fp.Elt{0x34, 0x4a, 0x58, 0x82, 0xbb, 0x9f, 0x1b, 0xd0, 0x2b, 0x79, 0xb4, 0xd2, 0x63, 0x64, 0xab, 0x47, 0x02, 0x62, 0x53, 0x48, 0x9c, 0x63, 0x31, 0xb6, 0x28, 0xd4, 0xd6, 0x69, 0x36, 0x2a, 0xa9, 0x13},
+ dt2: fp.Elt{0xe5, 0x7d, 0x57, 0xc0, 0x1c, 0x77, 0x93, 0xca, 0x5c, 0xdc, 0x35, 0x50, 0x1e, 0xe4, 0x40, 0x75, 0x71, 0xe0, 0x02, 0xd8, 0x01, 0x0f, 0x68, 0x24, 0x6a, 0xf8, 0x2a, 0x8a, 0xdf, 0x6d, 0x29, 0x3c},
+ },
+ { /* 31P */
+ addYX: fp.Elt{0x13, 0xa7, 0x14, 0xd9, 0xf9, 0x15, 0xad, 0xae, 0x12, 0xf9, 0x8f, 0x8c, 0xf9, 0x7b, 0x2f, 0xa9, 0x30, 0xd7, 0x53, 0x9f, 0x17, 0x23, 0xf8, 0xaf, 0xba, 0x77, 0x0c, 0x49, 0x93, 0xd3, 0x99, 0x7a},
+ subYX: fp.Elt{0x41, 0x25, 0x1f, 0xbb, 0x2e, 0x4d, 0xeb, 0xfc, 0x1f, 0xb9, 0xad, 0x40, 0xc7, 0x10, 0x95, 0xb8, 0x05, 0xad, 0xa1, 0xd0, 0x7d, 0xa3, 0x71, 0xfc, 0x7b, 0x71, 0x47, 0x07, 0x70, 0x2c, 0x89, 0x0a},
+ dt2: fp.Elt{0xe8, 0xa3, 0xbd, 0x36, 0x24, 0xed, 0x52, 0x8f, 0x94, 0x07, 0xe8, 0x57, 0x41, 0xc8, 0xa8, 0x77, 0xe0, 0x9c, 0x2f, 0x26, 0x63, 0x65, 0xa9, 0xa5, 0xd2, 0xf7, 0x02, 0x83, 0xd2, 0x62, 0x67, 0x28},
+ },
+ { /* 33P */
+ addYX: fp.Elt{0x25, 0x5b, 0xe3, 0x3c, 0x09, 0x36, 0x78, 0x4e, 0x97, 0xaa, 0x6b, 0xb2, 0x1d, 0x18, 0xe1, 0x82, 0x3f, 0xb8, 0xc7, 0xcb, 0xd3, 0x92, 0xc1, 0x0c, 0x3a, 0x9d, 0x9d, 0x6a, 0x04, 0xda, 0xf1, 0x32},
+ subYX: fp.Elt{0xbd, 0xf5, 0x2e, 0xce, 0x2b, 0x8e, 0x55, 0x7c, 0x63, 0xbc, 0x47, 0x67, 0xb4, 0x6c, 0x98, 0xe4, 0xb8, 0x89, 0xbb, 0x3b, 0x9f, 0x17, 0x4a, 0x15, 0x7a, 0x76, 0xf1, 0xd6, 0xa3, 0xf2, 0x86, 0x76},
+ dt2: fp.Elt{0x6a, 0x7c, 0x59, 0x6d, 0xa6, 0x12, 0x8d, 0xaa, 0x2b, 0x85, 0xd3, 0x04, 0x03, 0x93, 0x11, 0x8f, 0x22, 0xb0, 0x09, 0xc2, 0x73, 0xdc, 0x91, 0x3f, 0xa6, 0x28, 0xad, 0xa9, 0xf8, 0x05, 0x13, 0x56},
+ },
+ { /* 35P */
+ addYX: fp.Elt{0xd1, 0xae, 0x92, 0xec, 0x8d, 0x97, 0x0c, 0x10, 0xe5, 0x73, 0x6d, 0x4d, 0x43, 0xd5, 0x43, 0xca, 0x48, 0xba, 0x47, 0xd8, 0x22, 0x1b, 0x13, 0x83, 0x2c, 0x4d, 0x5d, 0xe3, 0x53, 0xec, 0xaa},
+ subYX: fp.Elt{0xd5, 0xc0, 0xb0, 0xe7, 0x28, 0xcc, 0x22, 0x67, 0x53, 0x5c, 0x07, 0xdb, 0xbb, 0xe9, 0x9d, 0x70, 0x61, 0x0a, 0x01, 0xd7, 0xa7, 0x8d, 0xf6, 0xca, 0x6c, 0xcc, 0x57, 0x2c, 0xef, 0x1a, 0x0a, 0x03},
+ dt2: fp.Elt{0xaa, 0xd2, 0x3a, 0x00, 0x73, 0xf7, 0xb1, 0x7b, 0x08, 0x66, 0x21, 0x2b, 0x80, 0x29, 0x3f, 0x0b, 0x3e, 0xd2, 0x0e, 0x52, 0x86, 0xdc, 0x21, 0x78, 0x80, 0x54, 0x06, 0x24, 0x1c, 0x9c, 0xbe, 0x20},
+ },
+ { /* 37P */
+ addYX: fp.Elt{0xa6, 0x73, 0x96, 0x24, 0xd8, 0x87, 0x53, 0xe1, 0x93, 0xe4, 0x46, 0xf5, 0x2d, 0xbc, 0x43, 0x59, 0xb5, 0x63, 0x6f, 0xc3, 0x81, 0x9a, 0x7f, 0x1c, 0xde, 0xc1, 0x0a, 0x1f, 0x36, 0xb3, 0x0a, 0x75},
+ subYX: fp.Elt{0x60, 0x5e, 0x02, 0xe2, 0x4a, 0xe4, 0xe0, 0x20, 0x38, 0xb9, 0xdc, 0xcb, 0x2f, 0x3b, 0x3b, 0xb0, 0x1c, 0x0d, 0x5a, 0xf9, 0x9c, 0x63, 0x5d, 0x10, 0x11, 0xe3, 0x67, 0x50, 0x54, 0x4c, 0x76, 0x69},
+ dt2: fp.Elt{0x37, 0x10, 0xf8, 0xa2, 0x83, 0x32, 0x8a, 0x1e, 0xf1, 0xcb, 0x7f, 0xbd, 0x23, 0xda, 0x2e, 0x6f, 0x63, 0x25, 0x2e, 0xac, 0x5b, 0xd1, 0x2f, 0xb7, 0x40, 0x50, 0x07, 0xb7, 0x3f, 0x6b, 0xf9, 0x54},
+ },
+ { /* 39P */
+ addYX: fp.Elt{0x79, 0x92, 0x66, 0x29, 0x04, 0xf2, 0xad, 0x0f, 0x4a, 0x72, 0x7d, 0x7d, 0x04, 0xa2, 0xdd, 0x3a, 0xf1, 0x60, 0x57, 0x8c, 0x82, 0x94, 0x3d, 0x6f, 0x9e, 0x53, 0xb7, 0x2b, 0xc5, 0xe9, 0x7f, 0x3d},
+ subYX: fp.Elt{0xcd, 0x1e, 0xb1, 0x16, 0xc6, 0xaf, 0x7d, 0x17, 0x79, 0x64, 0x57, 0xfa, 0x9c, 0x4b, 0x76, 0x89, 0x85, 0xe7, 0xec, 0xe6, 0x10, 0xa1, 0xa8, 0xb7, 0xf0, 0xdb, 0x85, 0xbe, 0x9f, 0x83, 0xe6, 0x78},
+ dt2: fp.Elt{0x6b, 0x85, 0xb8, 0x37, 0xf7, 0x2d, 0x33, 0x70, 0x8a, 0x17, 0x1a, 0x04, 0x43, 0x5d, 0xd0, 0x75, 0x22, 0x9e, 0xe5, 0xa0, 0x4a, 0xf7, 0x0f, 0x32, 0x42, 0x82, 0x08, 0x50, 0xf3, 0x68, 0xf2, 0x70},
+ },
+ { /* 41P */
+ addYX: fp.Elt{0x47, 0x5f, 0x80, 0xb1, 0x83, 0x45, 0x86, 0x66, 0x19, 0x7c, 0xdd, 0x60, 0xd1, 0xc5, 0x35, 0xf5, 0x06, 0xb0, 0x4c, 0x1e, 0xb7, 0x4e, 0x87, 0xe9, 0xd9, 0x89, 0xd8, 0xfa, 0x5c, 0x34, 0x0d, 0x7c},
+ subYX: fp.Elt{0x55, 0xf3, 0xdc, 0x70, 0x20, 0x11, 0x24, 0x23, 0x17, 0xe1, 0xfc, 0xe7, 0x7e, 0xc9, 0x0c, 0x38, 0x98, 0xb6, 0x52, 0x35, 0xed, 0xde, 0x1d, 0xb3, 0xb9, 0xc4, 0xb8, 0x39, 0xc0, 0x56, 0x4e, 0x40},
+ dt2: fp.Elt{0x8a, 0x33, 0x78, 0x8c, 0x4b, 0x1f, 0x1f, 0x59, 0xe1, 0xb5, 0xe0, 0x67, 0xb1, 0x6a, 0x36, 0xa0, 0x44, 0x3d, 0x5f, 0xb4, 0x52, 0x41, 0xbc, 0x5c, 0x77, 0xc7, 0xae, 0x2a, 0x76, 0x54, 0xd7, 0x20},
+ },
+ { /* 43P */
+ addYX: fp.Elt{0x58, 0xb7, 0x3b, 0xc7, 0x6f, 0xc3, 0x8f, 0x5e, 0x9a, 0xbb, 0x3c, 0x36, 0xa5, 0x43, 0xe5, 0xac, 0x22, 0xc9, 0x3b, 0x90, 0x7d, 0x4a, 0x93, 0xa9, 0x62, 0xec, 0xce, 0xf3, 0x46, 0x1e, 0x8f, 0x2b},
+ subYX: fp.Elt{0x43, 0xf5, 0xb9, 0x35, 0xb1, 0xfe, 0x74, 0x9d, 0x6c, 0x95, 0x8c, 0xde, 0xf1, 0x7d, 0xb3, 0x84, 0xa9, 0x8b, 0x13, 0x57, 0x07, 0x2b, 0x32, 0xe9, 0xe1, 0x4c, 0x0b, 0x79, 0xa8, 0xad, 0xb8, 0x38},
+ dt2: fp.Elt{0x5d, 0xf9, 0x51, 0xdf, 0x9c, 0x4a, 0xc0, 0xb5, 0xac, 0xde, 0x1f, 0xcb, 0xae, 0x52, 0x39, 0x2b, 0xda, 0x66, 0x8b, 0x32, 0x8b, 0x6d, 0x10, 0x1d, 0x53, 0x19, 0xba, 0xce, 0x32, 0xeb, 0x9a, 0x04},
+ },
+ { /* 45P */
+ addYX: fp.Elt{0x31, 0x79, 0xfc, 0x75, 0x0b, 0x7d, 0x50, 0xaa, 0xd3, 0x25, 0x67, 0x7a, 0x4b, 0x92, 0xef, 0x0f, 0x30, 0x39, 0x6b, 0x39, 0x2b, 0x54, 0x82, 0x1d, 0xfc, 0x74, 0xf6, 0x30, 0x75, 0xe1, 0x5e, 0x79},
+ subYX: fp.Elt{0x7e, 0xfe, 0xdc, 0x63, 0x3c, 0x7d, 0x76, 0xd7, 0x40, 0x6e, 0x85, 0x97, 0x48, 0x59, 0x9c, 0x20, 0x13, 0x7c, 0x4f, 0xe1, 0x61, 0x68, 0x67, 0xb6, 0xfc, 0x25, 0xd6, 0xc8, 0xe0, 0x65, 0xc6, 0x51},
+ dt2: fp.Elt{0x81, 0xbd, 0xec, 0x52, 0x0a, 0x5b, 0x4a, 0x25, 0xe7, 0xaf, 0x34, 0xe0, 0x6e, 0x1f, 0x41, 0x5d, 0x31, 0x4a, 0xee, 0xca, 0x0d, 0x4d, 0xa2, 0xe6, 0x77, 0x44, 0xc5, 0x9d, 0xf4, 0x9b, 0xd1, 0x6c},
+ },
+ { /* 47P */
+ addYX: fp.Elt{0x86, 0xc3, 0xaf, 0x65, 0x21, 0x61, 0xfe, 0x1f, 0x10, 0x1b, 0xd5, 0xb8, 0x88, 0x2a, 0x2a, 0x08, 0xaa, 0x0b, 0x99, 0x20, 0x7e, 0x62, 0xf6, 0x76, 0xe7, 0x43, 0x9e, 0x42, 0xa7, 0xb3, 0x01, 0x5e},
+ subYX: fp.Elt{0xa3, 0x9c, 0x17, 0x52, 0x90, 0x61, 0x87, 0x7e, 0x85, 0x9f, 0x2c, 0x0b, 0x06, 0x0a, 0x1d, 0x57, 0x1e, 0x71, 0x99, 0x84, 0xa8, 0xba, 0xa2, 0x80, 0x38, 0xe6, 0xb2, 0x40, 0xdb, 0xf3, 0x20, 0x75},
+ dt2: fp.Elt{0xa1, 0x57, 0x93, 0xd3, 0xe3, 0x0b, 0xb5, 0x3d, 0xa5, 0x94, 0x9e, 0x59, 0xdd, 0x6c, 0x7b, 0x96, 0x6e, 0x1e, 0x31, 0xdf, 0x64, 0x9a, 0x30, 0x1a, 0x86, 0xc9, 0xf3, 0xce, 0x9c, 0x2c, 0x09, 0x71},
+ },
+ { /* 49P */
+ addYX: fp.Elt{0xcf, 0x1d, 0x05, 0x74, 0xac, 0xd8, 0x6b, 0x85, 0x1e, 0xaa, 0xb7, 0x55, 0x08, 0xa4, 0xf6, 0x03, 0xeb, 0x3c, 0x74, 0xc9, 0xcb, 0xe7, 0x4a, 0x3a, 0xde, 0xab, 0x37, 0x71, 0xbb, 0xa5, 0x73, 0x41},
+ subYX: fp.Elt{0x8c, 0x91, 0x64, 0x03, 0x3f, 0x52, 0xd8, 0x53, 0x1c, 0x6b, 0xab, 0x3f, 0xf4, 0x04, 0xb4, 0xa2, 0xa4, 0xe5, 0x81, 0x66, 0x9e, 0x4a, 0x0b, 0x08, 0xa7, 0x7b, 0x25, 0xd0, 0x03, 0x5b, 0xa1, 0x0e},
+ dt2: fp.Elt{0x8a, 0x21, 0xf9, 0xf0, 0x31, 0x6e, 0xc5, 0x17, 0x08, 0x47, 0xfc, 0x1a, 0x2b, 0x6e, 0x69, 0x5a, 0x76, 0xf1, 0xb2, 0xf4, 0x68, 0x16, 0x93, 0xf7, 0x67, 0x3a, 0x4e, 0x4a, 0x61, 0x65, 0xc5, 0x5f},
+ },
+ { /* 51P */
+ addYX: fp.Elt{0x8e, 0x98, 0x90, 0x77, 0xe6, 0xe1, 0x92, 0x48, 0x22, 0xd7, 0x5c, 0x1c, 0x0f, 0x95, 0xd5, 0x01, 0xed, 0x3e, 0x92, 0xe5, 0x9a, 0x81, 0xb0, 0xe3, 0x1b, 0x65, 0x46, 0x9d, 0x40, 0xc7, 0x14, 0x32},
+ subYX: fp.Elt{0xe5, 0x7a, 0x6d, 0xc4, 0x0d, 0x57, 0x6e, 0x13, 0x8f, 0xdc, 0xf8, 0x54, 0xcc, 0xaa, 0xd0, 0x0f, 0x86, 0xad, 0x0d, 0x31, 0x03, 0x9f, 0x54, 0x59, 0xa1, 0x4a, 0x45, 0x4c, 0x41, 0x1c, 0x71, 0x62},
+ dt2: fp.Elt{0x70, 0x17, 0x65, 0x06, 0x74, 0x82, 0x29, 0x13, 0x36, 0x94, 0x27, 0x8a, 0x66, 0xa0, 0xa4, 0x3b, 0x3c, 0x22, 0x5d, 0x18, 0xec, 0xb8, 0xb6, 0xd9, 0x3c, 0x83, 0xcb, 0x3e, 0x07, 0x94, 0xea, 0x5b},
+ },
+ { /* 53P */
+ addYX: fp.Elt{0xf8, 0xd2, 0x43, 0xf3, 0x63, 0xce, 0x70, 0xb4, 0xf1, 0xe8, 0x43, 0x05, 0x8f, 0xba, 0x67, 0x00, 0x6f, 0x7b, 0x11, 0xa2, 0xa1, 0x51, 0xda, 0x35, 0x2f, 0xbd, 0xf1, 0x44, 0x59, 0x78, 0xd0, 0x4a},
+ subYX: fp.Elt{0xe4, 0x9b, 0xc8, 0x12, 0x09, 0xbf, 0x1d, 0x64, 0x9c, 0x57, 0x6e, 0x7d, 0x31, 0x8b, 0xf3, 0xac, 0x65, 0xb0, 0x97, 0xf6, 0x02, 0x9e, 0xfe, 0xab, 0xec, 0x1e, 0xf6, 0x48, 0xc1, 0xd5, 0xac, 0x3a},
+ dt2: fp.Elt{0x01, 0x83, 0x31, 0xc3, 0x34, 0x3b, 0x8e, 0x85, 0x26, 0x68, 0x31, 0x07, 0x47, 0xc0, 0x99, 0xdc, 0x8c, 0xa8, 0x9d, 0xd3, 0x2e, 0x5b, 0x08, 0x34, 0x3d, 0x85, 0x02, 0xd9, 0xb1, 0x0c, 0xff, 0x3a},
+ },
+ { /* 55P */
+ addYX: fp.Elt{0x05, 0x35, 0xc5, 0xf4, 0x0b, 0x43, 0x26, 0x92, 0x83, 0x22, 0x1f, 0x26, 0x13, 0x9c, 0xe4, 0x68, 0xc6, 0x27, 0xd3, 0x8f, 0x78, 0x33, 0xef, 0x09, 0x7f, 0x9e, 0xd9, 0x2b, 0x73, 0x9f, 0xcf, 0x2c},
+ subYX: fp.Elt{0x5e, 0x40, 0x20, 0x3a, 0xeb, 0xc7, 0xc5, 0x87, 0xc9, 0x56, 0xad, 0xed, 0xef, 0x11, 0xe3, 0x8e, 0xf9, 0xd5, 0x29, 0xad, 0x48, 0x2e, 0x25, 0x29, 0x1d, 0x25, 0xcd, 0xf4, 0x86, 0x7e, 0x0e, 0x11},
+ dt2: fp.Elt{0xe4, 0xf5, 0x03, 0xd6, 0x9e, 0xd8, 0xc0, 0x57, 0x0c, 0x20, 0xb0, 0xf0, 0x28, 0x86, 0x88, 0x12, 0xb7, 0x3b, 0x2e, 0xa0, 0x09, 0x27, 0x17, 0x53, 0x37, 0x3a, 0x69, 0xb9, 0xe0, 0x57, 0xc5, 0x05},
+ },
+ { /* 57P */
+ addYX: fp.Elt{0xb0, 0x0e, 0xc2, 0x89, 0xb0, 0xbb, 0x76, 0xf7, 0x5c, 0xd8, 0x0f, 0xfa, 0xf6, 0x5b, 0xf8, 0x61, 0xfb, 0x21, 0x44, 0x63, 0x4e, 0x3f, 0xb9, 0xb6, 0x05, 0x12, 0x86, 0x41, 0x08, 0xef, 0x9f, 0x28},
+ subYX: fp.Elt{0x6f, 0x7e, 0xc9, 0x1f, 0x31, 0xce, 0xf9, 0xd8, 0xae, 0xfd, 0xf9, 0x11, 0x30, 0x26, 0x3f, 0x7a, 0xdd, 0x25, 0xed, 0x8b, 0xa0, 0x7e, 0x5b, 0xe1, 0x5a, 0x87, 0xe9, 0x8f, 0x17, 0x4c, 0x15, 0x6e},
+ dt2: fp.Elt{0xbf, 0x9a, 0xd6, 0xfe, 0x36, 0x63, 0x61, 0xcf, 0x4f, 0xc9, 0x35, 0x83, 0xe7, 0xe4, 0x16, 0x9b, 0xe7, 0x7f, 0x3a, 0x75, 0x65, 0x97, 0x78, 0x13, 0x19, 0xa3, 0x5c, 0xa9, 0x42, 0xf6, 0xfb, 0x6a},
+ },
+ { /* 59P */
+ addYX: fp.Elt{0xcc, 0xa8, 0x13, 0xf9, 0x70, 0x50, 0xe5, 0x5d, 0x61, 0xf5, 0x0c, 0x2b, 0x7b, 0x16, 0x1d, 0x7d, 0x89, 0xd4, 0xea, 0x90, 0xb6, 0x56, 0x29, 0xda, 0xd9, 0x1e, 0x80, 0xdb, 0xce, 0x93, 0xc0, 0x12},
+ subYX: fp.Elt{0xc1, 0xd2, 0xf5, 0x62, 0x0c, 0xde, 0xa8, 0x7d, 0x9a, 0x7b, 0x0e, 0xb0, 0xa4, 0x3d, 0xfc, 0x98, 0xe0, 0x70, 0xad, 0x0d, 0xda, 0x6a, 0xeb, 0x7d, 0xc4, 0x38, 0x50, 0xb9, 0x51, 0xb8, 0xb4, 0x0d},
+ dt2: fp.Elt{0x0f, 0x19, 0xb8, 0x08, 0x93, 0x7f, 0x14, 0xfc, 0x10, 0xe3, 0x1a, 0xa1, 0xa0, 0x9d, 0x96, 0x06, 0xfd, 0xd7, 0xc7, 0xda, 0x72, 0x55, 0xe7, 0xce, 0xe6, 0x5c, 0x63, 0xc6, 0x99, 0x87, 0xaa, 0x33},
+ },
+ { /* 61P */
+ addYX: fp.Elt{0xb1, 0x6c, 0x15, 0xfc, 0x88, 0xf5, 0x48, 0x83, 0x27, 0x6d, 0x0a, 0x1a, 0x9b, 0xba, 0xa2, 0x6d, 0xb6, 0x5a, 0xca, 0x87, 0x5c, 0x2d, 0x26, 0xe2, 0xa6, 0x89, 0xd5, 0xc8, 0xc1, 0xd0, 0x2c, 0x21},
+ subYX: fp.Elt{0xf2, 0x5c, 0x08, 0xbd, 0x1e, 0xf5, 0x0f, 0xaf, 0x1f, 0x3f, 0xd3, 0x67, 0x89, 0x1a, 0xf5, 0x78, 0x3c, 0x03, 0x60, 0x50, 0xe1, 0xbf, 0xc2, 0x6e, 0x86, 0x1a, 0xe2, 0xe8, 0x29, 0x6f, 0x3c, 0x23},
+ dt2: fp.Elt{0x81, 0xc7, 0x18, 0x7f, 0x10, 0xd5, 0xf4, 0xd2, 0x28, 0x9d, 0x7e, 0x52, 0xf2, 0xcd, 0x2e, 0x12, 0x41, 0x33, 0x3d, 0x3d, 0x2a, 0x86, 0x0a, 0xa7, 0xe3, 0x4c, 0x91, 0x11, 0x89, 0x77, 0xb7, 0x1d},
+ },
+ { /* 63P */
+ addYX: fp.Elt{0xb6, 0x1a, 0x70, 0xdd, 0x69, 0x47, 0x39, 0xb3, 0xa5, 0x8d, 0xcf, 0x19, 0xd4, 0xde, 0xb8, 0xe2, 0x52, 0xc8, 0x2a, 0xfd, 0x61, 0x41, 0xdf, 0x15, 0xbe, 0x24, 0x7d, 0x01, 0x8a, 0xca, 0xe2, 0x7a},
+ subYX: fp.Elt{0x6f, 0xc2, 0x6b, 0x7c, 0x39, 0x52, 0xf3, 0xdd, 0x13, 0x01, 0xd5, 0x53, 0xcc, 0xe2, 0x97, 0x7a, 0x30, 0xa3, 0x79, 0xbf, 0x3a, 0xf4, 0x74, 0x7c, 0xfc, 0xad, 0xe2, 0x26, 0xad, 0x97, 0xad, 0x31},
+ dt2: fp.Elt{0x62, 0xb9, 0x20, 0x09, 0xed, 0x17, 0xe8, 0xb7, 0x9d, 0xda, 0x19, 0x3f, 0xcc, 0x18, 0x85, 0x1e, 0x64, 0x0a, 0x56, 0x25, 0x4f, 0xc1, 0x91, 0xe4, 0x83, 0x2c, 0x62, 0xa6, 0x53, 0xfc, 0xd1, 0x1e},
+ },
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
new file mode 100644
index 0000000..324bd8f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
@@ -0,0 +1,411 @@
+// Package ed448 implements Ed448 signature scheme as described in RFC-8032.
+//
+// This package implements two signature variants.
+//
+// | Scheme Name | Sign Function | Verification | Context |
+// |-------------|-------------------|---------------|-------------------|
+// | Ed448 | Sign | Verify | Yes, can be empty |
+// | Ed448Ph | SignPh | VerifyPh | Yes, can be empty |
+// | All above | (PrivateKey).Sign | VerifyAny | As above |
+//
+// Specific functions for sign and verify are defined. A generic signing
+// function for all schemes is available through the crypto.Signer interface,
+// which is implemented by the PrivateKey type. A correspond all-in-one
+// verification method is provided by the VerifyAny function.
+//
+// Both schemes require a context string for domain separation. This parameter
+// is passed using a SignerOptions struct defined in this package.
+//
+// References:
+//
+// - RFC8032: https://rfc-editor.org/rfc/rfc8032.txt
+// - EdDSA for more curves: https://eprint.iacr.org/2015/677
+// - High-speed high-security signatures: https://doi.org/10.1007/s13389-012-0027-1
+package ed448
+
+import (
+ "bytes"
+ "crypto"
+ cryptoRand "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+
+ "github.com/cloudflare/circl/ecc/goldilocks"
+ "github.com/cloudflare/circl/internal/sha3"
+ "github.com/cloudflare/circl/sign"
+)
+
+const (
+ // ContextMaxSize is the maximum length (in bytes) allowed for context.
+ ContextMaxSize = 255
+ // PublicKeySize is the length in bytes of Ed448 public keys.
+ PublicKeySize = 57
+ // PrivateKeySize is the length in bytes of Ed448 private keys.
+ PrivateKeySize = 114
+ // SignatureSize is the length in bytes of signatures.
+ SignatureSize = 114
+ // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
+ SeedSize = 57
+)
+
+const (
+ paramB = 456 / 8 // Size of keys in bytes.
+ hashSize = 2 * paramB // Size of the hash function's output.
+)
+
+// SignerOptions implements crypto.SignerOpts and augments with parameters
+// that are specific to the Ed448 signature schemes.
+type SignerOptions struct {
+ // Hash must be crypto.Hash(0) for both Ed448 and Ed448Ph.
+ crypto.Hash
+
+ // Context is an optional domain separation string for signing.
+ // Its length must be less or equal than 255 bytes.
+ Context string
+
+ // Scheme is an identifier for choosing a signature scheme.
+ Scheme SchemeID
+}
+
+// SchemeID is an identifier for each signature scheme.
+type SchemeID uint
+
+const (
+ ED448 SchemeID = iota
+ ED448Ph
+)
+
+// PublicKey is the type of Ed448 public keys.
+type PublicKey []byte
+
+// Equal reports whether pub and x have the same value.
+func (pub PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(PublicKey)
+ return ok && bytes.Equal(pub, xx)
+}
+
+// PrivateKey is the type of Ed448 private keys. It implements crypto.Signer.
+type PrivateKey []byte
+
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(PrivateKey)
+ return ok && subtle.ConstantTimeCompare(priv, xx) == 1
+}
+
+// Public returns the PublicKey corresponding to priv.
+func (priv PrivateKey) Public() crypto.PublicKey {
+ publicKey := make([]byte, PublicKeySize)
+ copy(publicKey, priv[SeedSize:])
+ return PublicKey(publicKey)
+}
+
+// Seed returns the private key seed corresponding to priv. It is provided for
+// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
+// in this package.
+func (priv PrivateKey) Seed() []byte {
+ seed := make([]byte, SeedSize)
+ copy(seed, priv[:SeedSize])
+ return seed
+}
+
+func (priv PrivateKey) Scheme() sign.Scheme { return sch }
+
+func (pub PublicKey) Scheme() sign.Scheme { return sch }
+
+func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
+ privateKey := make(PrivateKey, PrivateKeySize)
+ copy(privateKey, priv)
+ return privateKey, nil
+}
+
+func (pub PublicKey) MarshalBinary() (data []byte, err error) {
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, pub)
+ return publicKey, nil
+}
+
+// Sign creates a signature of a message given a key pair.
+// This function supports all the two signature variants defined in RFC-8032,
+// namely Ed448 (or pure EdDSA) and Ed448Ph.
+// The opts.HashFunc() must return zero to the specify Ed448 variant. This can
+// be achieved by passing crypto.Hash(0) as the value for opts.
+// Use an Options struct to pass a bool indicating that the ed448Ph variant
+// should be used.
+// The struct can also be optionally used to pass a context string for signing.
+func (priv PrivateKey) Sign(
+ rand io.Reader,
+ message []byte,
+ opts crypto.SignerOpts,
+) (signature []byte, err error) {
+ var ctx string
+ var scheme SchemeID
+
+ if o, ok := opts.(SignerOptions); ok {
+ ctx = o.Context
+ scheme = o.Scheme
+ }
+
+ switch true {
+ case scheme == ED448 && opts.HashFunc() == crypto.Hash(0):
+ return Sign(priv, message, ctx), nil
+ case scheme == ED448Ph && opts.HashFunc() == crypto.Hash(0):
+ return SignPh(priv, message, ctx), nil
+ default:
+ return nil, errors.New("ed448: bad hash algorithm")
+ }
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
+ if rand == nil {
+ rand = cryptoRand.Reader
+ }
+
+ seed := make(PrivateKey, SeedSize)
+ if _, err := io.ReadFull(rand, seed); err != nil {
+ return nil, nil, err
+ }
+
+ privateKey := NewKeyFromSeed(seed)
+ publicKey := make([]byte, PublicKeySize)
+ copy(publicKey, privateKey[SeedSize:])
+
+ return publicKey, privateKey, nil
+}
+
+// NewKeyFromSeed calculates a private key from a seed. It will panic if
+// len(seed) is not SeedSize. This function is provided for interoperability
+// with RFC 8032. RFC 8032's private keys correspond to seeds in this
+// package.
+func NewKeyFromSeed(seed []byte) PrivateKey {
+ privateKey := make([]byte, PrivateKeySize)
+ newKeyFromSeed(privateKey, seed)
+ return privateKey
+}
+
+func newKeyFromSeed(privateKey, seed []byte) {
+ if l := len(seed); l != SeedSize {
+ panic("ed448: bad seed length: " + strconv.Itoa(l))
+ }
+
+ var h [hashSize]byte
+ H := sha3.NewShake256()
+ _, _ = H.Write(seed)
+ _, _ = H.Read(h[:])
+ s := &goldilocks.Scalar{}
+ deriveSecretScalar(s, h[:paramB])
+
+ copy(privateKey[:SeedSize], seed)
+ _ = goldilocks.Curve{}.ScalarBaseMult(s).ToBytes(privateKey[SeedSize:])
+}
+
+func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
+ if len(ctx) > ContextMaxSize {
+ panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx))))
+ }
+
+ H := sha3.NewShake256()
+ var PHM []byte
+
+ if preHash {
+ var h [64]byte
+ _, _ = H.Write(message)
+ _, _ = H.Read(h[:])
+ PHM = h[:]
+ H.Reset()
+ } else {
+ PHM = message
+ }
+
+ // 1. Hash the 57-byte private key using SHAKE256(x, 114).
+ var h [hashSize]byte
+ _, _ = H.Write(privateKey[:SeedSize])
+ _, _ = H.Read(h[:])
+ s := &goldilocks.Scalar{}
+ deriveSecretScalar(s, h[:paramB])
+ prefix := h[paramB:]
+
+ // 2. Compute SHAKE256(dom4(F, C) || prefix || PH(M), 114).
+ var rPM [hashSize]byte
+ H.Reset()
+
+ writeDom(&H, ctx, preHash)
+
+ _, _ = H.Write(prefix)
+ _, _ = H.Write(PHM)
+ _, _ = H.Read(rPM[:])
+
+ // 3. Compute the point [r]B.
+ r := &goldilocks.Scalar{}
+ r.FromBytes(rPM[:])
+ R := (&[paramB]byte{})[:]
+ if err := (goldilocks.Curve{}.ScalarBaseMult(r).ToBytes(R)); err != nil {
+ panic(err)
+ }
+ // 4. Compute SHAKE256(dom4(F, C) || R || A || PH(M), 114)
+ var hRAM [hashSize]byte
+ H.Reset()
+
+ writeDom(&H, ctx, preHash)
+
+ _, _ = H.Write(R)
+ _, _ = H.Write(privateKey[SeedSize:])
+ _, _ = H.Write(PHM)
+ _, _ = H.Read(hRAM[:])
+
+ // 5. Compute S = (r + k * s) mod order.
+ k := &goldilocks.Scalar{}
+ k.FromBytes(hRAM[:])
+ S := &goldilocks.Scalar{}
+ S.Mul(k, s)
+ S.Add(S, r)
+
+ // 6. The signature is the concatenation of R and S.
+ copy(signature[:paramB], R[:])
+ copy(signature[paramB:], S[:])
+}
+
+// Sign signs the message with privateKey and returns a signature.
+// This function supports the signature variant defined in RFC-8032: Ed448,
+// also known as the pure version of EdDSA.
+// It will panic if len(privateKey) is not PrivateKeySize.
+func Sign(priv PrivateKey, message []byte, ctx string) []byte {
+ signature := make([]byte, SignatureSize)
+ signAll(signature, priv, message, []byte(ctx), false)
+ return signature
+}
+
+// SignPh creates a signature of a message given a keypair.
+// This function supports the signature variant defined in RFC-8032: Ed448ph,
+// meaning it internally hashes the message using SHAKE-256.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func SignPh(priv PrivateKey, message []byte, ctx string) []byte {
+ signature := make([]byte, SignatureSize)
+ signAll(signature, priv, message, []byte(ctx), true)
+ return signature
+}
+
+func verify(public PublicKey, message, signature, ctx []byte, preHash bool) bool {
+ if len(public) != PublicKeySize ||
+ len(signature) != SignatureSize ||
+ len(ctx) > ContextMaxSize ||
+ !isLessThanOrder(signature[paramB:]) {
+ return false
+ }
+
+ P, err := goldilocks.FromBytes(public)
+ if err != nil {
+ return false
+ }
+
+ H := sha3.NewShake256()
+ var PHM []byte
+
+ if preHash {
+ var h [64]byte
+ _, _ = H.Write(message)
+ _, _ = H.Read(h[:])
+ PHM = h[:]
+ H.Reset()
+ } else {
+ PHM = message
+ }
+
+ var hRAM [hashSize]byte
+ R := signature[:paramB]
+
+ writeDom(&H, ctx, preHash)
+
+ _, _ = H.Write(R)
+ _, _ = H.Write(public)
+ _, _ = H.Write(PHM)
+ _, _ = H.Read(hRAM[:])
+
+ k := &goldilocks.Scalar{}
+ k.FromBytes(hRAM[:])
+ S := &goldilocks.Scalar{}
+ S.FromBytes(signature[paramB:])
+
+ encR := (&[paramB]byte{})[:]
+ P.Neg()
+ _ = goldilocks.Curve{}.CombinedMult(S, k, P).ToBytes(encR)
+ return bytes.Equal(R, encR)
+}
+
+// VerifyAny returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports all the two signature variants defined in RFC-8032,
+// namely Ed448 (or pure EdDSA) and Ed448Ph.
+// The opts.HashFunc() must return zero, this can be achieved by passing
+// crypto.Hash(0) as the value for opts.
+// Use a SignerOptions struct to pass a context string for signing.
+func VerifyAny(public PublicKey, message, signature []byte, opts crypto.SignerOpts) bool {
+ var ctx string
+ var scheme SchemeID
+ if o, ok := opts.(SignerOptions); ok {
+ ctx = o.Context
+ scheme = o.Scheme
+ }
+
+ switch true {
+ case scheme == ED448 && opts.HashFunc() == crypto.Hash(0):
+ return Verify(public, message, signature, ctx)
+ case scheme == ED448Ph && opts.HashFunc() == crypto.Hash(0):
+ return VerifyPh(public, message, signature, ctx)
+ default:
+ return false
+ }
+}
+
+// Verify returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed448,
+// also known as the pure version of EdDSA.
+func Verify(public PublicKey, message, signature []byte, ctx string) bool {
+ return verify(public, message, signature, []byte(ctx), false)
+}
+
+// VerifyPh returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed448ph,
+// meaning it internally hashes the message using SHAKE-256.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func VerifyPh(public PublicKey, message, signature []byte, ctx string) bool {
+ return verify(public, message, signature, []byte(ctx), true)
+}
+
+func deriveSecretScalar(s *goldilocks.Scalar, h []byte) {
+ h[0] &= 0xFC // The two least significant bits of the first octet are cleared,
+ h[paramB-1] = 0x00 // all eight bits the last octet are cleared, and
+ h[paramB-2] |= 0x80 // the highest bit of the second to last octet is set.
+ s.FromBytes(h[:paramB])
+}
+
+// isLessThanOrder returns true if 0 <= x < order and if the last byte of x is zero.
+func isLessThanOrder(x []byte) bool {
+ order := goldilocks.Curve{}.Order()
+ i := len(order) - 1
+ for i > 0 && x[i] == order[i] {
+ i--
+ }
+ return x[paramB-1] == 0 && x[i] < order[i]
+}
+
+func writeDom(h io.Writer, ctx []byte, preHash bool) {
+ dom4 := "SigEd448"
+ _, _ = h.Write([]byte(dom4))
+
+ if preHash {
+ _, _ = h.Write([]byte{byte(0x01), byte(len(ctx))})
+ } else {
+ _, _ = h.Write([]byte{byte(0x00), byte(len(ctx))})
+ }
+ _, _ = h.Write(ctx)
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go b/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go
new file mode 100644
index 0000000..22da8bc
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go
@@ -0,0 +1,87 @@
+package ed448
+
+import (
+ "crypto/rand"
+ "encoding/asn1"
+
+ "github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string { return "Ed448" }
+func (*scheme) PublicKeySize() int { return PublicKeySize }
+func (*scheme) PrivateKeySize() int { return PrivateKeySize }
+func (*scheme) SignatureSize() int { return SignatureSize }
+func (*scheme) SeedSize() int { return SeedSize }
+func (*scheme) TLSIdentifier() uint { return 0x0808 }
+func (*scheme) SupportsContext() bool { return true }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+ return asn1.ObjectIdentifier{1, 3, 101, 113}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+ return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+ sk sign.PrivateKey,
+ message []byte,
+ opts *sign.SignatureOpts,
+) []byte {
+ priv, ok := sk.(PrivateKey)
+ if !ok {
+ panic(sign.ErrTypeMismatch)
+ }
+ ctx := ""
+ if opts != nil {
+ ctx = opts.Context
+ }
+ return Sign(priv, message, ctx)
+}
+
+func (*scheme) Verify(
+ pk sign.PublicKey,
+ message, signature []byte,
+ opts *sign.SignatureOpts,
+) bool {
+ pub, ok := pk.(PublicKey)
+ if !ok {
+ panic(sign.ErrTypeMismatch)
+ }
+ ctx := ""
+ if opts != nil {
+ ctx = opts.Context
+ }
+ return Verify(pub, message, signature, ctx)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+ privateKey := NewKeyFromSeed(seed)
+ publicKey := make(PublicKey, PublicKeySize)
+ copy(publicKey, privateKey[SeedSize:])
+ return publicKey, privateKey
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+ if len(buf) < PublicKeySize {
+ return nil, sign.ErrPubKeySize
+ }
+ pub := make(PublicKey, PublicKeySize)
+ copy(pub, buf[:PublicKeySize])
+ return pub, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+ if len(buf) < PrivateKeySize {
+ return nil, sign.ErrPrivKeySize
+ }
+ priv := make(PrivateKey, PrivateKeySize)
+ copy(priv, buf[:PrivateKeySize])
+ return priv, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/sign.go b/vendor/github.com/cloudflare/circl/sign/sign.go
new file mode 100644
index 0000000..13b20fa
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/sign.go
@@ -0,0 +1,110 @@
+// Package sign provides unified interfaces for signature schemes.
+//
+// A register of schemes is available in the package
+//
+// github.com/cloudflare/circl/sign/schemes
+package sign
+
+import (
+ "crypto"
+ "encoding"
+ "errors"
+)
+
+type SignatureOpts struct {
+ // If non-empty, includes the given context in the signature if supported
+ // and will cause an error during signing otherwise.
+ Context string
+}
+
+// A public key is used to verify a signature set by the corresponding private
+// key.
+type PublicKey interface {
+ // Returns the signature scheme for this public key.
+ Scheme() Scheme
+ Equal(crypto.PublicKey) bool
+ encoding.BinaryMarshaler
+ crypto.PublicKey
+}
+
+// A private key allows one to create signatures.
+type PrivateKey interface {
+ // Returns the signature scheme for this private key.
+ Scheme() Scheme
+ Equal(crypto.PrivateKey) bool
+ // For compatibility with Go standard library
+ crypto.Signer
+ crypto.PrivateKey
+ encoding.BinaryMarshaler
+}
+
+// A Scheme represents a specific instance of a signature scheme.
+type Scheme interface {
+ // Name of the scheme.
+ Name() string
+
+ // GenerateKey creates a new key-pair.
+ GenerateKey() (PublicKey, PrivateKey, error)
+
+ // Creates a signature using the PrivateKey on the given message and
+ // returns the signature. opts are additional options which can be nil.
+ //
+ // Panics if key is nil or wrong type or opts context is not supported.
+ Sign(sk PrivateKey, message []byte, opts *SignatureOpts) []byte
+
+ // Checks whether the given signature is a valid signature set by
+ // the private key corresponding to the given public key on the
+ // given message. opts are additional options which can be nil.
+ //
+ // Panics if key is nil or wrong type or opts context is not supported.
+ Verify(pk PublicKey, message []byte, signature []byte, opts *SignatureOpts) bool
+
+ // Deterministically derives a keypair from a seed. If you're unsure,
+ // you're better off using GenerateKey().
+ //
+ // Panics if seed is not of length SeedSize().
+ DeriveKey(seed []byte) (PublicKey, PrivateKey)
+
+ // Unmarshals a PublicKey from the provided buffer.
+ UnmarshalBinaryPublicKey([]byte) (PublicKey, error)
+
+ // Unmarshals a PublicKey from the provided buffer.
+ UnmarshalBinaryPrivateKey([]byte) (PrivateKey, error)
+
+ // Size of binary marshalled public keys.
+ PublicKeySize() int
+
+ // Size of binary marshalled public keys.
+ PrivateKeySize() int
+
+ // Size of signatures.
+ SignatureSize() int
+
+ // Size of seeds.
+ SeedSize() int
+
+ // Returns whether contexts are supported.
+ SupportsContext() bool
+}
+
+var (
+ // ErrTypeMismatch is the error used if types of, for instance, private
+ // and public keys don't match.
+ ErrTypeMismatch = errors.New("types mismatch")
+
+ // ErrSeedSize is the error used if the provided seed is of the wrong
+ // size.
+ ErrSeedSize = errors.New("wrong seed size")
+
+ // ErrPubKeySize is the error used if the provided public key is of
+ // the wrong size.
+ ErrPubKeySize = errors.New("wrong size for public key")
+
+ // ErrPrivKeySize is the error used if the provided private key is of
+ // the wrong size.
+ ErrPrivKeySize = errors.New("wrong size for private key")
+
+ // ErrContextNotSupported is the error used if a context is not
+ // supported.
+ ErrContextNotSupported = errors.New("context not supported")
+)
diff --git a/vendor/github.com/containerd/containerd/LICENSE b/vendor/github.com/containerd/containerd/LICENSE
new file mode 100644
index 0000000..584149b
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/LICENSE
@@ -0,0 +1,191 @@
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright The containerd Authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/containerd/containerd/NOTICE b/vendor/github.com/containerd/containerd/NOTICE
new file mode 100644
index 0000000..8915f02
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/NOTICE
@@ -0,0 +1,16 @@
+Docker
+Copyright 2012-2015 Docker, Inc.
+
+This product includes software developed at Docker, Inc. (https://www.docker.com).
+
+The following is courtesy of our legal counsel:
+
+
+Use and transfer of Docker may be subject to certain restrictions by the
+United States and other governments.
+It is your responsibility to ensure that your use and/or transfer does not
+violate applicable laws.
+
+For more information, please see https://www.bis.doc.gov
+
+See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.
diff --git a/vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go b/vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go
new file mode 100644
index 0000000..6656465
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go
@@ -0,0 +1,62 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package userns
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "sync"
+)
+
+var (
+ inUserNS bool
+ nsOnce sync.Once
+)
+
+// RunningInUserNS detects whether we are currently running in a user namespace.
+// Originally copied from github.com/lxc/lxd/shared/util.go
+func RunningInUserNS() bool {
+ nsOnce.Do(func() {
+ file, err := os.Open("/proc/self/uid_map")
+ if err != nil {
+ // This kernel-provided file only exists if user namespaces are supported
+ return
+ }
+ defer file.Close()
+
+ buf := bufio.NewReader(file)
+ l, _, err := buf.ReadLine()
+ if err != nil {
+ return
+ }
+
+ line := string(l)
+ var a, b, c int64
+ fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
+
+ /*
+ * We assume we are in the initial user namespace if we have a full
+ * range - 4294967295 uids starting at uid 0.
+ */
+ if a == 0 && b == 0 && c == 4294967295 {
+ return
+ }
+ inUserNS = true
+ })
+ return inUserNS
+}
diff --git a/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go b/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go
new file mode 100644
index 0000000..c67f773
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go
@@ -0,0 +1,25 @@
+//go:build !linux
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package userns
+
+// RunningInUserNS is a stub for non-Linux systems
+// Always returns false
+func RunningInUserNS() bool {
+ return false
+}
diff --git a/vendor/github.com/containerd/log/.golangci.yml b/vendor/github.com/containerd/log/.golangci.yml
new file mode 100644
index 0000000..a695775
--- /dev/null
+++ b/vendor/github.com/containerd/log/.golangci.yml
@@ -0,0 +1,30 @@
+linters:
+ enable:
+ - exportloopref # Checks for pointers to enclosing loop variables
+ - gofmt
+ - goimports
+ - gosec
+ - ineffassign
+ - misspell
+ - nolintlint
+ - revive
+ - staticcheck
+ - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17
+ - unconvert
+ - unused
+ - vet
+ - dupword # Checks for duplicate words in the source code
+ disable:
+ - errcheck
+
+run:
+ timeout: 5m
+ skip-dirs:
+ - api
+ - cluster
+ - design
+ - docs
+ - docs/man
+ - releases
+ - reports
+ - test # e2e scripts
diff --git a/vendor/github.com/containerd/log/LICENSE b/vendor/github.com/containerd/log/LICENSE
new file mode 100644
index 0000000..584149b
--- /dev/null
+++ b/vendor/github.com/containerd/log/LICENSE
@@ -0,0 +1,191 @@
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright The containerd Authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/containerd/log/README.md b/vendor/github.com/containerd/log/README.md
new file mode 100644
index 0000000..00e0849
--- /dev/null
+++ b/vendor/github.com/containerd/log/README.md
@@ -0,0 +1,17 @@
+# log
+
+A Go package providing a common logging interface across containerd repositories and a way for clients to use and configure logging in containerd packages.
+
+This package is not intended to be used as a standalone logging package outside of the containerd ecosystem and is intended as an interface wrapper around a logging implementation.
+In the future this package may be replaced with a common go logging interface.
+
+## Project details
+
+**log** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
+As a containerd sub-project, you will find the:
+ * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
+ * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),
+ * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
+
+information in our [`containerd/project`](https://github.com/containerd/project) repository.
+
diff --git a/vendor/github.com/containerd/log/context.go b/vendor/github.com/containerd/log/context.go
new file mode 100644
index 0000000..2015306
--- /dev/null
+++ b/vendor/github.com/containerd/log/context.go
@@ -0,0 +1,182 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+// Package log provides types and functions related to logging, passing
+// loggers through a context, and attaching context to the logger.
+//
+// # Transitional types
+//
+// This package contains various types that are aliases for types in [logrus].
+// These aliases are intended for transitioning away from hard-coding logrus
+// as logging implementation. Consumers of this package are encouraged to use
+// the type-aliases from this package instead of directly using their logrus
+// equivalent.
+//
+// The intent is to replace these aliases with locally defined types and
+// interfaces once all consumers are no longer directly importing logrus
+// types.
+//
+// IMPORTANT: due to the transitional purpose of this package, it is not
+// guaranteed for the full logrus API to be provided in the future. As
+// outlined, these aliases are provided as a step to transition away from
+// a specific implementation which, as a result, exposes the full logrus API.
+// While no decisions have been made on the ultimate design and interface
+// provided by this package, we do not expect carrying "less common" features.
+package log
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/sirupsen/logrus"
+)
+
+// G is a shorthand for [GetLogger].
+//
+// We may want to define this locally to a package to get package tagged log
+// messages.
+var G = GetLogger
+
+// L is an alias for the standard logger.
+var L = &Entry{
+ Logger: logrus.StandardLogger(),
+ // Default is three fields plus a little extra room.
+ Data: make(Fields, 6),
+}
+
+type loggerKey struct{}
+
+// Fields type to pass to "WithFields".
+type Fields = map[string]any
+
+// Entry is a logging entry. It contains all the fields passed with
+// [Entry.WithFields]. It's finally logged when Trace, Debug, Info, Warn,
+// Error, Fatal or Panic is called on it. These objects can be reused and
+// passed around as much as you wish to avoid field duplication.
+//
+// Entry is a transitional type, and currently an alias for [logrus.Entry].
+type Entry = logrus.Entry
+
+// RFC3339NanoFixed is [time.RFC3339Nano] with nanoseconds padded using
+// zeros to ensure the formatted time is always the same number of
+// characters.
+const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
+
+// Level is a logging level.
+type Level = logrus.Level
+
+// Supported log levels.
+const (
+ // TraceLevel level. Designates finer-grained informational events
+ // than [DebugLevel].
+ TraceLevel Level = logrus.TraceLevel
+
+ // DebugLevel level. Usually only enabled when debugging. Very verbose
+ // logging.
+ DebugLevel Level = logrus.DebugLevel
+
+ // InfoLevel level. General operational entries about what's going on
+ // inside the application.
+ InfoLevel Level = logrus.InfoLevel
+
+ // WarnLevel level. Non-critical entries that deserve eyes.
+ WarnLevel Level = logrus.WarnLevel
+
+ // ErrorLevel level. Logs errors that should definitely be noted.
+ // Commonly used for hooks to send errors to an error tracking service.
+ ErrorLevel Level = logrus.ErrorLevel
+
+ // FatalLevel level. Logs and then calls "logger.Exit(1)". It exits
+ // even if the logging level is set to Panic.
+ FatalLevel Level = logrus.FatalLevel
+
+ // PanicLevel level. This is the highest level of severity. Logs and
+ // then calls panic with the message passed to Debug, Info, ...
+ PanicLevel Level = logrus.PanicLevel
+)
+
+// SetLevel sets log level globally. It returns an error if the given
+// level is not supported.
+//
+// level can be one of:
+//
+// - "trace" ([TraceLevel])
+// - "debug" ([DebugLevel])
+// - "info" ([InfoLevel])
+// - "warn" ([WarnLevel])
+// - "error" ([ErrorLevel])
+// - "fatal" ([FatalLevel])
+// - "panic" ([PanicLevel])
+func SetLevel(level string) error {
+ lvl, err := logrus.ParseLevel(level)
+ if err != nil {
+ return err
+ }
+
+ L.Logger.SetLevel(lvl)
+ return nil
+}
+
+// GetLevel returns the current log level.
+func GetLevel() Level {
+ return L.Logger.GetLevel()
+}
+
+// OutputFormat specifies a log output format.
+type OutputFormat string
+
+// Supported log output formats.
+const (
+ // TextFormat represents the text logging format.
+ TextFormat OutputFormat = "text"
+
+ // JSONFormat represents the JSON logging format.
+ JSONFormat OutputFormat = "json"
+)
+
+// SetFormat sets the log output format ([TextFormat] or [JSONFormat]).
+func SetFormat(format OutputFormat) error {
+ switch format {
+ case TextFormat:
+ L.Logger.SetFormatter(&logrus.TextFormatter{
+ TimestampFormat: RFC3339NanoFixed,
+ FullTimestamp: true,
+ })
+ return nil
+ case JSONFormat:
+ L.Logger.SetFormatter(&logrus.JSONFormatter{
+ TimestampFormat: RFC3339NanoFixed,
+ })
+ return nil
+ default:
+ return fmt.Errorf("unknown log format: %s", format)
+ }
+}
+
+// WithLogger returns a new context with the provided logger. Use in
+// combination with logger.WithField(s) for great effect.
+func WithLogger(ctx context.Context, logger *Entry) context.Context {
+ return context.WithValue(ctx, loggerKey{}, logger.WithContext(ctx))
+}
+
+// GetLogger retrieves the current logger from the context. If no logger is
+// available, the default logger is returned.
+func GetLogger(ctx context.Context) *Entry {
+ if logger := ctx.Value(loggerKey{}); logger != nil {
+ return logger.(*Entry)
+ }
+ return L.WithContext(ctx)
+}
diff --git a/vendor/github.com/creack/pty/.editorconfig b/vendor/github.com/creack/pty/.editorconfig
new file mode 100644
index 0000000..349f67a
--- /dev/null
+++ b/vendor/github.com/creack/pty/.editorconfig
@@ -0,0 +1,54 @@
+root = true
+
+# Sane defaults.
+[*]
+# Always use unix end of line.
+end_of_line = lf
+# Always insert a new line at the end of files.
+insert_final_newline = true
+# Don't leave trailing whitespaces.
+trim_trailing_whitespace = true
+# Default to utf8 encoding.
+charset = utf-8
+# Space > tab for consistent aligns.
+indent_style = space
+# Default to 2 spaces for indent/tabs.
+indent_size = 2
+# Flag long lines.
+max_line_length = 140
+
+# Explicitly define settings for commonly used files.
+
+[*.go]
+indent_style = tab
+indent_size = 8
+
+[*.feature]
+indent_style = space
+indent_size = 2
+
+[*.json]
+indent_style = space
+indent_size = 2
+
+[*.{yml,yaml}]
+indent_style = space
+indent_size = 2
+
+[*.tf]
+indent_style = space
+indent_size = 2
+
+[*.md]
+# Don't check line lenghts in files.
+max_line_length = 0
+
+[{Makefile,*.mk}]
+indent_style = tab
+indent_size = 8
+
+[{Dockerfile,Dockerfile.*}]
+indent_size = 4
+
+[*.sql]
+indent_size = 2
diff --git a/vendor/github.com/creack/pty/.gitignore b/vendor/github.com/creack/pty/.gitignore
new file mode 100644
index 0000000..1f0a99f
--- /dev/null
+++ b/vendor/github.com/creack/pty/.gitignore
@@ -0,0 +1,4 @@
+[568].out
+_go*
+_test*
+_obj
diff --git a/vendor/github.com/creack/pty/.golangci.yml b/vendor/github.com/creack/pty/.golangci.yml
new file mode 100644
index 0000000..f023e0f
--- /dev/null
+++ b/vendor/github.com/creack/pty/.golangci.yml
@@ -0,0 +1,324 @@
+---
+# Reference: https://golangci-lint.run/usage/configuration/
+run:
+ timeout: 5m
+ # modules-download-mode: vendor
+
+ # Include test files.
+ tests: true
+
+ skip-dirs: []
+
+ skip-files: []
+
+output:
+ # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number".
+ format: colored-line-number
+ print-issued-lines: true
+ print-linter-name: true
+
+# Linter specific settings. See below in the `linter.enable` section for details on what each linter is doing.
+linters-settings:
+ dogsled:
+ # Checks assignments with too many blank identifiers. Default is 2.
+ max-blank-identifiers: 2
+
+ dupl:
+ # Tokens count to trigger issue.
+ threshold: 150
+
+ errcheck:
+ # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
+ # Enabled as this is often overlooked by developers.
+ check-type-assertions: true
+ # Report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
+ # Disabled as we consider that if the developer did type `_`, it was on purpose.
+ # Note that while this isn't enforced by the linter, each and every case of ignored error should
+ # be accompanied with a comment explaining why that error is being discarded.
+ check-blank: false
+
+ exhaustive:
+ # Indicates that switch statements are to be considered exhaustive if a
+ # 'default' case is present, even if all enum members aren't listed in the
+ # switch.
+ default-signifies-exhaustive: false
+
+ funlen:
+ # funlen checks the number of lines/statements in a function.
+ # While is is always best to keep functions short for readability, maintainability and testing,
+ # the default are a bit too strict (60 lines / 40 statements), increase it to be more flexible.
+ lines: 160
+ statements: 70
+
+ # NOTE: We don't set `gci` for import order as it supports only one prefix. Use `goimports.local-prefixes` instead.
+
+ gocognit:
+ # Minimal code complexity to report, defaults to 30 in gocognit, defaults 10 in golangci.
+ # Use 15 as it allows for some flexibility while preventing too much complexity.
+ # NOTE: Similar to gocyclo.
+ min-complexity: 35
+
+ nestif:
+ # Minimal complexity of if statements to report.
+ min-complexity: 8
+
+ goconst:
+ # Minimal length of string constant.
+ min-len: 4
+ # Minimal occurrences count to trigger.
+ # Increase the default from 3 to 5 as small number of const usage can reduce readability instead of improving it.
+ min-occurrences: 5
+
+ gocritic:
+ # Which checks should be disabled; can't be combined with 'enabled-checks'.
+ # See https://go-critic.github.io/overview#checks-overview
+ # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
+ disabled-checks:
+ - hugeParam # Very strict check on the size of variables being copied. Too strict for most developer.
+ # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
+ # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
+ enabled-tags:
+ - diagnostic
+ - style
+ - opinionated
+ - performance
+ settings:
+ rangeValCopy:
+ sizeThreshold: 1024 # Increase the allowed copied bytes in range.
+
+ cyclop:
+ max-complexity: 35
+
+ gocyclo:
+ # Similar check as gocognit.
+ # NOTE: We might be able to remove this linter as it is redundant with gocyclo. It is in golangci-lint, so we keep it for now.
+ min-complexity: 35
+
+ godot:
+ # Check all top-level comments, not only declarations.
+ check-all: true
+
+ gofmt:
+ # simplify code: gofmt with `-s` option.
+ simplify: true
+
+ # NOTE: the goheader settings are set per-project.
+
+ goimports:
+ # Put imports beginning with prefix after 3rd-party packages.
+ # It's a comma-separated list of prefixes.
+ local-prefixes: "github.com/creack/pty"
+
+ golint:
+ # Minimal confidence for issues, default is 0.8.
+ min-confidence: 0.8
+
+ gosimple:
+ # Select the Go version to target. The default is '1.13'.
+ go: "1.18"
+ # https://staticcheck.io/docs/options#checks
+ checks: ["all"]
+
+ gosec:
+
+ govet:
+ # Enable all available checks from go vet.
+ enable-all: false
+ # Report about shadowed variables.
+ check-shadowing: true
+
+ # NOTE: depguard is disabled as it is very slow and made redundant by gomodguard.
+
+ lll:
+ # Make sure everyone is on the same level, fix the tab width to go's default.
+ tab-width: 8
+ # Increase the default max line length to give more flexibility. Forcing newlines can reduce readability instead of improving it.
+ line-length: 180
+
+ misspell:
+ locale: US
+ ignore-words:
+
+ nakedret:
+ # Make an issue if func has more lines of code than this setting and it has naked returns; default is 30.
+ # NOTE: Consider setting this to 1 to prevent naked returns.
+ max-func-lines: 30
+
+ nolintlint:
+ # Prevent ununsed directive to avoid stale comments.
+ allow-unused: false
+ # Require an explanation of nonzero length after each nolint directive.
+ require-explanation: true
+ # Exclude following linters from requiring an explanation.
+ # NOTE: It is strongly discouraged to put anything in there.
+ allow-no-explanation: []
+ # Enable to require nolint directives to mention the specific linter being suppressed. This ensurce the developer understand the reason being the error.
+ require-specific: true
+
+ prealloc:
+ # NOTE: For most programs usage of prealloc will be a premature optimization.
+ # Keep thing simple, pre-alloc what is obvious and profile the program for more complex scenarios.
+ #
+ simple: true # Checkonly on simple loops that have no returns/breaks/continues/gotos in them.
+ range-loops: true # Check range loops, true by default
+ for-loops: false # Check suggestions on for loops, false by default
+
+ rowserrcheck:
+ packages: []
+
+ staticcheck:
+ # Select the Go version to target. The default is '1.13'.
+ go: "1.18"
+ # https://staticcheck.io/docs/options#checks
+ checks: ["all"]
+
+ stylecheck:
+ # Select the Go version to target. The default is '1.13'.
+ go: "1.18"
+ # https://staticcheck.io/docs/options#checks
+ checks: ["all"] # "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]
+
+ tagliatelle:
+ # Check the struck tag name case.
+ case:
+ # Use the struct field name to check the name of the struct tag.
+ use-field-name: false
+ rules:
+ # Any struct tag type can be used.
+ # support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`
+ json: snake
+ firestore: camel
+ yaml: camel
+ xml: camel
+ bson: camel
+ avro: snake
+ mapstructure: kebab
+ envconfig: upper
+
+ unparam:
+ # Don't create an error if an exported code have static params being used. It is often expected in libraries.
+ # NOTE: It would be nice if this linter would differentiate between a main package and a lib.
+ check-exported: true
+
+ unused: {}
+
+ whitespace:
+ multi-if: false # Enforces newlines (or comments) after every multi-line if statement
+ multi-func: false # Enforces newlines (or comments) after every multi-line function signature
+
+# Run `golangci-lint help linters` to get the full list of linter with their description.
+linters:
+ disable-all: true
+ # NOTE: enable-all is deprecated because too many people don't pin versions...
+ # We still require explicit documentation on why some linters are disabled.
+ # disable:
+ # - depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
+ # - exhaustivestruct # Checks if all struct's fields are initialized [fast: true, auto-fix: false]
+ # - forbidigo # Forbids identifiers [fast: true, auto-fix: false]
+ # - gci # Gci control golang package import order and make it always deterministic. [fast: true, auto-fix: true]
+ # - godox # Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]
+ # - goerr113 # Golang linter to check the errors handling expressions [fast: true, auto-fix: false]
+ # - golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: false, auto-fix: false]
+ # - gomnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
+ # - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false]
+ # - interfacer # Linter that suggests narrower interface types [fast: false, auto-fix: false]
+ # - maligned # Tool to detect Go structs that would take less memory if their fields were sorted [fast: false, auto-fix: false]
+ # - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]
+ # - scopelint # Scopelint checks for unpinned variables in go programs [fast: true, auto-fix: false]
+ # - wrapcheck # Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]
+ # - wsl # Whitespace Linter - Forces you to use empty lines! [fast: true, auto-fix: false]
+
+ # disable-reasons:
+ # - depguard # Checks whitelisted/blacklisted import path, but runs way too slow. Not that useful.
+ # - exhaustivestruct # Good concept, but not mature enough (errors on not assignable fields like locks) and too noisy when using AWS SDK as most fields are unused.
+ # - forbidigo # Great idea, but too strict out of the box. Probably will re-enable soon.
+ # - gci # Conflicts with goimports/gofumpt.
+ # - godox # Don't fail when finding TODO, FIXME, etc.
+ # - goerr113 # Too many false positives.
+ # - golint # Deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive.
+ # - gomnd # Checks for magic numbers. Disabled due to too many false positives not configurable (03/01/2020 v1.23.7).
+ # - gomoddirectives # Doesn't support //nolint to whitelist.
+ # - interfacer # Deprecated (since v1.38.0) due to: The repository of the linter has been archived by the owner.
+ # - maligned # Deprecated (since v1.38.0) due to: The repository of the linter has been archived by the owner. Replaced by govet 'fieldalignment'.
+ # - nlreturn # Actually reduces readability in most cases.
+ # - scopelint # Deprecated (since v1.39.0) due to: The repository of the linter has been deprecated by the owner. Replaced by exportloopref.
+ # - wrapcheck # Good concept, but always warns for http coded errors. Need to re-enable and whitelist our error package.
+ # - wsl # Forces to add newlines around blocks. Lots of false positives, not that useful.
+
+ enable:
+ - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers [fast: true, auto-fix: false]
+ - bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
+ - cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
+ - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
+ - dupl # Tool for code clone detection [fast: true, auto-fix: false]
+ - durationcheck # check for two durations multiplied together [fast: false, auto-fix: false]
+ - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]
+ - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]
+ - errorlint # go-errorlint is a source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]
+ - exhaustive # check exhaustiveness of enum switch statements [fast: false, auto-fix: false]
+ - exportloopref # checks for pointers to enclosing loop variables [fast: false, auto-fix: false]
+ - forcetypeassert # finds forced type assertions [fast: true, auto-fix: false]
+ - funlen # Tool for detection of long functions [fast: true, auto-fix: false]
+ - gochecknoglobals # check that no global variables exist [fast: true, auto-fix: false]
+ - gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
+ - gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
+ - goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
+ - gocritic # Provides many diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false]
+ - gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
+ - godot # Check if comments end in a period [fast: true, auto-fix: true]
+ - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
+ - gofumpt # Gofumpt checks whether code was gofumpt-ed. [fast: true, auto-fix: true]
+ - goheader # Checks is file header matches to pattern [fast: true, auto-fix: false]
+ - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true, auto-fix: true]
+ - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false]
+ - goprintffuncname # Checks that printf-like functions are named with `f` at the end [fast: true, auto-fix: false]
+ - gosec # (gas): Inspects source code for security problems [fast: false, auto-fix: false]
+ - gosimple # (megacheck): Linter for Go source code that specializes in simplifying a code [fast: false, auto-fix: false]
+ - govet # (vet, vetshadow): Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: false, auto-fix: false]
+ - importas # Enforces consistent import aliases [fast: false, auto-fix: false]
+ - ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
+ - lll # Reports long lines [fast: true, auto-fix: false]
+ - makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]
+ - misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
+ - nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
+ - nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
+ - nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]
+ - noctx # noctx finds sending http request without context.Context [fast: false, auto-fix: false]
+ - nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: false]
+ - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test [fast: true, auto-fix: false]
+ - prealloc # Finds slice declarations that could potentially be preallocated [fast: true, auto-fix: false]
+ - predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]
+ - promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]
+ - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false]
+ # Disabled due to generic. Work in progress upstream.
+ # - rowserrcheck # checks whether Err of rows is checked successfully [fast: false, auto-fix: false]
+ # Disabled due to generic. Work in progress upstream.
+ # - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. [fast: false, auto-fix: false]
+ - staticcheck # (megacheck): Staticcheck is a go vet on steroids, applying a ton of static analysis checks [fast: false, auto-fix: false]
+ - stylecheck # Stylecheck is a replacement for golint [fast: false, auto-fix: false]
+ # Disabled due to generic. Work in progress upstream.
+ # - tagliatelle # Checks the struct tags. [fast: true, auto-fix: false]
+ # - testpackage # linter that makes you use a separate _test package [fast: true, auto-fix: false]
+ - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers [fast: false, auto-fix: false]
+ - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes [fast: false, auto-fix: false]
+ - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code [fast: false, auto-fix: false]
+ - unconvert # Remove unnecessary type conversions [fast: false, auto-fix: false]
+ - unparam # Reports unused function parameters [fast: false, auto-fix: false]
+ # Disabled due to way too many false positive in go1.20.
+ # - unused # (megacheck): Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
+ # Disabled due to generic. Work in progress upstream.
+ # - wastedassign # wastedassign finds wasted assignment statements. [fast: false, auto-fix: false]
+ - whitespace # Tool for detection of leading and trailing whitespace [fast: true, auto-fix: true]
+
+issues:
+ exclude:
+ # Allow shadowing of 'err'.
+ - 'shadow: declaration of "err" shadows declaration'
+ # Allow shadowing of `ctx`.
+ - 'shadow: declaration of "ctx" shadows declaration'
+ # Maximum issues count per one linter. Set to 0 to disable. Default is 50.
+ max-per-linter: 10
+ # Disable default excludes. Always be explicit on what we exclude.
+ exclude-use-default: false
+ # Exclude some linters from running on tests files.
+ exclude-rules: []
diff --git a/vendor/github.com/creack/pty/Dockerfile.golang b/vendor/github.com/creack/pty/Dockerfile.golang
new file mode 100644
index 0000000..b615342
--- /dev/null
+++ b/vendor/github.com/creack/pty/Dockerfile.golang
@@ -0,0 +1,17 @@
+ARG GOVERSION=1.18.2
+FROM golang:${GOVERSION}
+
+# Set base env.
+ARG GOOS=linux
+ARG GOARCH=amd64
+ENV GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w'
+
+# Pre compile the stdlib for 386/arm (32bits).
+RUN go build -a std
+
+# Add the code to the image.
+WORKDIR pty
+ADD . .
+
+# Build the lib.
+RUN go build
diff --git a/vendor/github.com/creack/pty/LICENSE b/vendor/github.com/creack/pty/LICENSE
new file mode 100644
index 0000000..6b7558b
--- /dev/null
+++ b/vendor/github.com/creack/pty/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2011 Keith Rarick
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall
+be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/creack/pty/README.md b/vendor/github.com/creack/pty/README.md
new file mode 100644
index 0000000..a4fe767
--- /dev/null
+++ b/vendor/github.com/creack/pty/README.md
@@ -0,0 +1,107 @@
+# pty
+
+Pty is a Go package for using unix pseudo-terminals.
+
+## Install
+
+```sh
+go get github.com/creack/pty
+```
+
+## Examples
+
+Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment.
+
+### Command
+
+```go
+package main
+
+import (
+ "io"
+ "os"
+ "os/exec"
+
+ "github.com/creack/pty"
+)
+
+func main() {
+ c := exec.Command("grep", "--color=auto", "bar")
+ f, err := pty.Start(c)
+ if err != nil {
+ panic(err)
+ }
+
+ go func() {
+ f.Write([]byte("foo\n"))
+ f.Write([]byte("bar\n"))
+ f.Write([]byte("baz\n"))
+ f.Write([]byte{4}) // EOT
+ }()
+ io.Copy(os.Stdout, f)
+}
+```
+
+### Shell
+
+```go
+package main
+
+import (
+ "io"
+ "log"
+ "os"
+ "os/exec"
+ "os/signal"
+ "syscall"
+
+ "github.com/creack/pty"
+ "golang.org/x/term"
+)
+
+func test() error {
+ // Create arbitrary command.
+ c := exec.Command("bash")
+
+ // Start the command with a pty.
+ ptmx, err := pty.Start(c)
+ if err != nil {
+ return err
+ }
+ // Make sure to close the pty at the end.
+ defer func() { _ = ptmx.Close() }() // Best effort.
+
+ // Handle pty size.
+ ch := make(chan os.Signal, 1)
+ signal.Notify(ch, syscall.SIGWINCH)
+ go func() {
+ for range ch {
+ if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
+ log.Printf("error resizing pty: %s", err)
+ }
+ }
+ }()
+ ch <- syscall.SIGWINCH // Initial resize.
+ defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.
+
+ // Set stdin in raw mode.
+ oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
+ if err != nil {
+ panic(err)
+ }
+ defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
+
+ // Copy stdin to the pty and the pty to stdout.
+ // NOTE: The goroutine will keep reading until the next keystroke before returning.
+ go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
+ _, _ = io.Copy(os.Stdout, ptmx)
+
+ return nil
+}
+
+func main() {
+ if err := test(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
diff --git a/vendor/github.com/creack/pty/asm_solaris_amd64.s b/vendor/github.com/creack/pty/asm_solaris_amd64.s
new file mode 100644
index 0000000..7fbef8e
--- /dev/null
+++ b/vendor/github.com/creack/pty/asm_solaris_amd64.s
@@ -0,0 +1,18 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc
+//+build gc
+
+#include "textflag.h"
+
+//
+// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
+//
+
+TEXT ·sysvicall6(SB),NOSPLIT,$0-88
+ JMP syscall·sysvicall6(SB)
+
+TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
+ JMP syscall·rawSysvicall6(SB)
diff --git a/vendor/github.com/creack/pty/doc.go b/vendor/github.com/creack/pty/doc.go
new file mode 100644
index 0000000..3c8b324
--- /dev/null
+++ b/vendor/github.com/creack/pty/doc.go
@@ -0,0 +1,16 @@
+// Package pty provides functions for working with Unix terminals.
+package pty
+
+import (
+ "errors"
+ "os"
+)
+
+// ErrUnsupported is returned if a function is not
+// available on the current platform.
+var ErrUnsupported = errors.New("unsupported")
+
+// Open a pty and its corresponding tty.
+func Open() (pty, tty *os.File, err error) {
+ return open()
+}
diff --git a/vendor/github.com/creack/pty/ioctl.go b/vendor/github.com/creack/pty/ioctl.go
new file mode 100644
index 0000000..7b6b770
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl.go
@@ -0,0 +1,28 @@
+//go:build !windows && go1.12
+// +build !windows,go1.12
+
+package pty
+
+import "os"
+
+func ioctl(f *os.File, cmd, ptr uintptr) error {
+ return ioctlInner(f.Fd(), cmd, ptr) // Fall back to blocking io.
+}
+
+// NOTE: Unused. Keeping for reference.
+func ioctlNonblock(f *os.File, cmd, ptr uintptr) error {
+ sc, e := f.SyscallConn()
+ if e != nil {
+ return ioctlInner(f.Fd(), cmd, ptr) // Fall back to blocking io (old behavior).
+ }
+
+ ch := make(chan error, 1)
+ defer close(ch)
+
+ e = sc.Control(func(fd uintptr) { ch <- ioctlInner(fd, cmd, ptr) })
+ if e != nil {
+ return e
+ }
+ e = <-ch
+ return e
+}
diff --git a/vendor/github.com/creack/pty/ioctl_bsd.go b/vendor/github.com/creack/pty/ioctl_bsd.go
new file mode 100644
index 0000000..db3bf84
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl_bsd.go
@@ -0,0 +1,40 @@
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package pty
+
+// from
+const (
+ _IOC_VOID uintptr = 0x20000000
+ _IOC_OUT uintptr = 0x40000000
+ _IOC_IN uintptr = 0x80000000
+ _IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
+ _IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
+
+ _IOC_PARAM_SHIFT = 13
+ _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
+)
+
+func _IOC_PARM_LEN(ioctl uintptr) uintptr {
+ return (ioctl >> 16) & _IOC_PARAM_MASK
+}
+
+func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr {
+ return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num
+}
+
+func _IO(group byte, ioctl_num uintptr) uintptr {
+ return _IOC(_IOC_VOID, group, ioctl_num, 0)
+}
+
+func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
+ return _IOC(_IOC_OUT, group, ioctl_num, param_len)
+}
+
+func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
+ return _IOC(_IOC_IN, group, ioctl_num, param_len)
+}
+
+func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
+ return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len)
+}
diff --git a/vendor/github.com/creack/pty/ioctl_inner.go b/vendor/github.com/creack/pty/ioctl_inner.go
new file mode 100644
index 0000000..272b50b
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl_inner.go
@@ -0,0 +1,20 @@
+//go:build !windows && !solaris && !aix
+// +build !windows,!solaris,!aix
+
+package pty
+
+import "syscall"
+
+// Local syscall const values.
+const (
+ TIOCGWINSZ = syscall.TIOCGWINSZ
+ TIOCSWINSZ = syscall.TIOCSWINSZ
+)
+
+func ioctlInner(fd, cmd, ptr uintptr) error {
+ _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
+ if e != 0 {
+ return e
+ }
+ return nil
+}
diff --git a/vendor/github.com/creack/pty/ioctl_legacy.go b/vendor/github.com/creack/pty/ioctl_legacy.go
new file mode 100644
index 0000000..f7e923c
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl_legacy.go
@@ -0,0 +1,10 @@
+//go:build !windows && !go1.12
+// +build !windows,!go1.12
+
+package pty
+
+import "os"
+
+func ioctl(f *os.File, cmd, ptr uintptr) error {
+ return ioctlInner(f.Fd(), cmd, ptr) // fall back to blocking io (old behavior)
+}
diff --git a/vendor/github.com/creack/pty/ioctl_solaris.go b/vendor/github.com/creack/pty/ioctl_solaris.go
new file mode 100644
index 0000000..6fd8bfe
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl_solaris.go
@@ -0,0 +1,48 @@
+//go:build solaris
+// +build solaris
+
+package pty
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+//go:linkname procioctl libc_ioctl
+var procioctl uintptr
+
+const (
+ // see /usr/include/sys/stropts.h
+ I_PUSH = uintptr((int32('S')<<8 | 002))
+ I_STR = uintptr((int32('S')<<8 | 010))
+ I_FIND = uintptr((int32('S')<<8 | 013))
+
+ // see /usr/include/sys/ptms.h
+ ISPTM = (int32('P') << 8) | 1
+ UNLKPT = (int32('P') << 8) | 2
+ PTSSTTY = (int32('P') << 8) | 3
+ ZONEPT = (int32('P') << 8) | 4
+ OWNERPT = (int32('P') << 8) | 5
+
+ // see /usr/include/sys/termios.h
+ TIOCSWINSZ = (uint32('T') << 8) | 103
+ TIOCGWINSZ = (uint32('T') << 8) | 104
+)
+
+type strioctl struct {
+ icCmd int32
+ icTimeout int32
+ icLen int32
+ icDP unsafe.Pointer
+}
+
+// Defined in asm_solaris_amd64.s.
+func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+func ioctlInner(fd, cmd, ptr uintptr) error {
+ if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 {
+ return errno
+ }
+ return nil
+}
diff --git a/vendor/github.com/creack/pty/ioctl_unsupported.go b/vendor/github.com/creack/pty/ioctl_unsupported.go
new file mode 100644
index 0000000..e17908d
--- /dev/null
+++ b/vendor/github.com/creack/pty/ioctl_unsupported.go
@@ -0,0 +1,13 @@
+//go:build aix
+// +build aix
+
+package pty
+
+const (
+ TIOCGWINSZ = 0
+ TIOCSWINSZ = 0
+)
+
+func ioctlInner(fd, cmd, ptr uintptr) error {
+ return ErrUnsupported
+}
diff --git a/vendor/github.com/creack/pty/mktypes.bash b/vendor/github.com/creack/pty/mktypes.bash
new file mode 100644
index 0000000..7f71bda
--- /dev/null
+++ b/vendor/github.com/creack/pty/mktypes.bash
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+GOOSARCH="${GOOS}_${GOARCH}"
+case "$GOOSARCH" in
+_* | *_ | _)
+ echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+esac
+
+GODEFS="go tool cgo -godefs"
+
+$GODEFS types.go |gofmt > ztypes_$GOARCH.go
+
+case $GOOS in
+freebsd|dragonfly|netbsd|openbsd)
+ $GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go
+ ;;
+esac
diff --git a/vendor/github.com/creack/pty/pty_darwin.go b/vendor/github.com/creack/pty/pty_darwin.go
new file mode 100644
index 0000000..eadf6ab
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_darwin.go
@@ -0,0 +1,68 @@
+//go:build darwin
+// +build darwin
+
+package pty
+
+import (
+ "errors"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func open() (pty, tty *os.File, err error) {
+ pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ p := os.NewFile(uintptr(pFD), "/dev/ptmx")
+ // In case of error after this point, make sure we close the ptmx fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if err := grantpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ if err := unlockpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ return p, t, nil
+}
+
+func ptsname(f *os.File) (string, error) {
+ n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
+
+ err := ioctl(f, syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
+ if err != nil {
+ return "", err
+ }
+
+ for i, c := range n {
+ if c == 0 {
+ return string(n[:i]), nil
+ }
+ }
+ return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
+}
+
+func grantpt(f *os.File) error {
+ return ioctl(f, syscall.TIOCPTYGRANT, 0)
+}
+
+func unlockpt(f *os.File) error {
+ return ioctl(f, syscall.TIOCPTYUNLK, 0)
+}
diff --git a/vendor/github.com/creack/pty/pty_dragonfly.go b/vendor/github.com/creack/pty/pty_dragonfly.go
new file mode 100644
index 0000000..12803de
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_dragonfly.go
@@ -0,0 +1,83 @@
+//go:build dragonfly
+// +build dragonfly
+
+package pty
+
+import (
+ "errors"
+ "os"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+// same code as pty_darwin.go
+func open() (pty, tty *os.File, err error) {
+ p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ // In case of error after this point, make sure we close the ptmx fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if err := grantpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ if err := unlockpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ t, err := os.OpenFile(sname, os.O_RDWR, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ return p, t, nil
+}
+
+func grantpt(f *os.File) error {
+ _, err := isptmaster(f)
+ return err
+}
+
+func unlockpt(f *os.File) error {
+ _, err := isptmaster(f)
+ return err
+}
+
+func isptmaster(f *os.File) (bool, error) {
+ err := ioctl(f, syscall.TIOCISPTMASTER, 0)
+ return err == nil, err
+}
+
+var (
+ emptyFiodgnameArg fiodgnameArg
+ ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
+)
+
+func ptsname(f *os.File) (string, error) {
+ name := make([]byte, _C_SPECNAMELEN)
+ fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}}
+
+ err := ioctl(f, ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa)))
+ if err != nil {
+ return "", err
+ }
+
+ for i, c := range name {
+ if c == 0 {
+ s := "/dev/" + string(name[:i])
+ return strings.Replace(s, "ptm", "pts", -1), nil
+ }
+ }
+ return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
+}
diff --git a/vendor/github.com/creack/pty/pty_freebsd.go b/vendor/github.com/creack/pty/pty_freebsd.go
new file mode 100644
index 0000000..47afcfe
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_freebsd.go
@@ -0,0 +1,81 @@
+//go:build freebsd
+// +build freebsd
+
+package pty
+
+import (
+ "errors"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func posixOpenpt(oflag int) (fd int, err error) {
+ r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = e1
+ }
+ return fd, err
+}
+
+func open() (pty, tty *os.File, err error) {
+ fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC)
+ if err != nil {
+ return nil, nil, err
+ }
+ p := os.NewFile(uintptr(fd), "/dev/pts")
+ // In case of error after this point, make sure we close the pts fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ return p, t, nil
+}
+
+func isptmaster(f *os.File) (bool, error) {
+ err := ioctl(f, syscall.TIOCPTMASTER, 0)
+ return err == nil, err
+}
+
+var (
+ emptyFiodgnameArg fiodgnameArg
+ ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
+)
+
+func ptsname(f *os.File) (string, error) {
+ master, err := isptmaster(f)
+ if err != nil {
+ return "", err
+ }
+ if !master {
+ return "", syscall.EINVAL
+ }
+
+ const n = _C_SPECNAMELEN + 1
+ var (
+ buf = make([]byte, n)
+ arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))}
+ )
+ if err := ioctl(f, ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil {
+ return "", err
+ }
+
+ for i, c := range buf {
+ if c == 0 {
+ return string(buf[:i]), nil
+ }
+ }
+ return "", errors.New("FIODGNAME string not NUL-terminated")
+}
diff --git a/vendor/github.com/creack/pty/pty_linux.go b/vendor/github.com/creack/pty/pty_linux.go
new file mode 100644
index 0000000..e7e01c0
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_linux.go
@@ -0,0 +1,54 @@
+//go:build linux
+// +build linux
+
+package pty
+
+import (
+ "os"
+ "strconv"
+ "syscall"
+ "unsafe"
+)
+
+func open() (pty, tty *os.File, err error) {
+ p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ // In case of error after this point, make sure we close the ptmx fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if err := unlockpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) //nolint:gosec // Expected Open from a variable.
+ if err != nil {
+ return nil, nil, err
+ }
+ return p, t, nil
+}
+
+func ptsname(f *os.File) (string, error) {
+ var n _C_uint
+ err := ioctl(f, syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) //nolint:gosec // Expected unsafe pointer for Syscall call.
+ if err != nil {
+ return "", err
+ }
+ return "/dev/pts/" + strconv.Itoa(int(n)), nil
+}
+
+func unlockpt(f *os.File) error {
+ var u _C_int
+ // use TIOCSPTLCK with a pointer to zero to clear the lock.
+ return ioctl(f, syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) //nolint:gosec // Expected unsafe pointer for Syscall call.
+}
diff --git a/vendor/github.com/creack/pty/pty_netbsd.go b/vendor/github.com/creack/pty/pty_netbsd.go
new file mode 100644
index 0000000..dd5611d
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_netbsd.go
@@ -0,0 +1,69 @@
+//go:build netbsd
+// +build netbsd
+
+package pty
+
+import (
+ "errors"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func open() (pty, tty *os.File, err error) {
+ p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ // In case of error after this point, make sure we close the ptmx fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if err := grantpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ // In NetBSD unlockpt() does nothing, so it isn't called here.
+
+ t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ return p, t, nil
+}
+
+func ptsname(f *os.File) (string, error) {
+ /*
+ * from ptsname(3): The ptsname() function is equivalent to:
+ * struct ptmget pm;
+ * ioctl(fd, TIOCPTSNAME, &pm) == -1 ? NULL : pm.sn;
+ */
+ var ptm ptmget
+ if err := ioctl(f, uintptr(ioctl_TIOCPTSNAME), uintptr(unsafe.Pointer(&ptm))); err != nil {
+ return "", err
+ }
+ name := make([]byte, len(ptm.Sn))
+ for i, c := range ptm.Sn {
+ name[i] = byte(c)
+ if c == 0 {
+ return string(name[:i]), nil
+ }
+ }
+ return "", errors.New("TIOCPTSNAME string not NUL-terminated")
+}
+
+func grantpt(f *os.File) error {
+ /*
+ * from grantpt(3): Calling grantpt() is equivalent to:
+ * ioctl(fd, TIOCGRANTPT, 0);
+ */
+ return ioctl(f, uintptr(ioctl_TIOCGRANTPT), 0)
+}
diff --git a/vendor/github.com/creack/pty/pty_openbsd.go b/vendor/github.com/creack/pty/pty_openbsd.go
new file mode 100644
index 0000000..337c39f
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_openbsd.go
@@ -0,0 +1,47 @@
+//go:build openbsd
+// +build openbsd
+
+package pty
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func cInt8ToString(in []int8) string {
+ var s []byte
+ for _, v := range in {
+ if v == 0 {
+ break
+ }
+ s = append(s, byte(v))
+ }
+ return string(s)
+}
+
+func open() (pty, tty *os.File, err error) {
+ /*
+ * from ptm(4):
+ * The PTMGET command allocates a free pseudo terminal, changes its
+ * ownership to the caller, revokes the access privileges for all previous
+ * users, opens the file descriptors for the pty and tty devices and
+ * returns them to the caller in struct ptmget.
+ */
+
+ p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ defer p.Close()
+
+ var ptm ptmget
+ if err := ioctl(p, uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil {
+ return nil, nil, err
+ }
+
+ pty = os.NewFile(uintptr(ptm.Cfd), cInt8ToString(ptm.Cn[:]))
+ tty = os.NewFile(uintptr(ptm.Sfd), cInt8ToString(ptm.Sn[:]))
+
+ return pty, tty, nil
+}
diff --git a/vendor/github.com/creack/pty/pty_solaris.go b/vendor/github.com/creack/pty/pty_solaris.go
new file mode 100644
index 0000000..4e22416
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_solaris.go
@@ -0,0 +1,171 @@
+//go:build solaris
+// +build solaris
+
+package pty
+
+/* based on:
+http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/pt.c
+*/
+
+import (
+ "errors"
+ "os"
+ "strconv"
+ "syscall"
+ "unsafe"
+)
+
+func open() (pty, tty *os.File, err error) {
+ ptmxfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ p := os.NewFile(uintptr(ptmxfd), "/dev/ptmx")
+ // In case of error after this point, make sure we close the ptmx fd.
+ defer func() {
+ if err != nil {
+ _ = p.Close() // Best effort.
+ }
+ }()
+
+ sname, err := ptsname(p)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if err := grantpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ if err := unlockpt(p); err != nil {
+ return nil, nil, err
+ }
+
+ ptsfd, err := syscall.Open(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ t := os.NewFile(uintptr(ptsfd), sname)
+
+ // In case of error after this point, make sure we close the pts fd.
+ defer func() {
+ if err != nil {
+ _ = t.Close() // Best effort.
+ }
+ }()
+
+ // pushing terminal driver STREAMS modules as per pts(7)
+ for _, mod := range []string{"ptem", "ldterm", "ttcompat"} {
+ if err := streamsPush(t, mod); err != nil {
+ return nil, nil, err
+ }
+ }
+
+ return p, t, nil
+}
+
+func ptsname(f *os.File) (string, error) {
+ dev, err := ptsdev(f)
+ if err != nil {
+ return "", err
+ }
+ fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10)
+
+ if err := syscall.Access(fn, 0); err != nil {
+ return "", err
+ }
+ return fn, nil
+}
+
+func unlockpt(f *os.File) error {
+ istr := strioctl{
+ icCmd: UNLKPT,
+ icTimeout: 0,
+ icLen: 0,
+ icDP: nil,
+ }
+ return ioctl(f, I_STR, uintptr(unsafe.Pointer(&istr)))
+}
+
+func minor(x uint64) uint64 { return x & 0377 }
+
+func ptsdev(f *os.File) (uint64, error) {
+ istr := strioctl{
+ icCmd: ISPTM,
+ icTimeout: 0,
+ icLen: 0,
+ icDP: nil,
+ }
+
+ if err := ioctl(f, I_STR, uintptr(unsafe.Pointer(&istr))); err != nil {
+ return 0, err
+ }
+ var errors = make(chan error, 1)
+ var results = make(chan uint64, 1)
+ defer close(errors)
+ defer close(results)
+
+ var err error
+ var sc syscall.RawConn
+ sc, err = f.SyscallConn()
+ if err != nil {
+ return 0, err
+ }
+ err = sc.Control(func(fd uintptr) {
+ var status syscall.Stat_t
+ if err := syscall.Fstat(int(fd), &status); err != nil {
+ results <- 0
+ errors <- err
+ }
+ results <- uint64(minor(status.Rdev))
+ errors <- nil
+ })
+ if err != nil {
+ return 0, err
+ }
+ return <-results, <-errors
+}
+
+type ptOwn struct {
+ rUID int32
+ rGID int32
+}
+
+func grantpt(f *os.File) error {
+ if _, err := ptsdev(f); err != nil {
+ return err
+ }
+ pto := ptOwn{
+ rUID: int32(os.Getuid()),
+ // XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty"
+ rGID: int32(os.Getgid()),
+ }
+ istr := strioctl{
+ icCmd: OWNERPT,
+ icTimeout: 0,
+ icLen: int32(unsafe.Sizeof(strioctl{})),
+ icDP: unsafe.Pointer(&pto),
+ }
+ if err := ioctl(f, I_STR, uintptr(unsafe.Pointer(&istr))); err != nil {
+ return errors.New("access denied")
+ }
+ return nil
+}
+
+// streamsPush pushes STREAMS modules if not already done so.
+func streamsPush(f *os.File, mod string) error {
+ buf := []byte(mod)
+
+ // XXX I_FIND is not returning an error when the module
+ // is already pushed even though truss reports a return
+ // value of 1. A bug in the Go Solaris syscall interface?
+ // XXX without this we are at risk of the issue
+ // https://www.illumos.org/issues/9042
+ // but since we are not using libc or XPG4.2, we should not be
+ // double-pushing modules
+
+ if err := ioctl(f, I_FIND, uintptr(unsafe.Pointer(&buf[0]))); err != nil {
+ return nil
+ }
+ return ioctl(f, I_PUSH, uintptr(unsafe.Pointer(&buf[0])))
+}
diff --git a/vendor/github.com/creack/pty/pty_unsupported.go b/vendor/github.com/creack/pty/pty_unsupported.go
new file mode 100644
index 0000000..c771020
--- /dev/null
+++ b/vendor/github.com/creack/pty/pty_unsupported.go
@@ -0,0 +1,12 @@
+//go:build !linux && !darwin && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris
+// +build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris
+
+package pty
+
+import (
+ "os"
+)
+
+func open() (pty, tty *os.File, err error) {
+ return nil, nil, ErrUnsupported
+}
diff --git a/vendor/github.com/creack/pty/run.go b/vendor/github.com/creack/pty/run.go
new file mode 100644
index 0000000..4755366
--- /dev/null
+++ b/vendor/github.com/creack/pty/run.go
@@ -0,0 +1,57 @@
+package pty
+
+import (
+ "os"
+ "os/exec"
+ "syscall"
+)
+
+// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
+// and c.Stderr, calls c.Start, and returns the File of the tty's
+// corresponding pty.
+//
+// Starts the process in a new session and sets the controlling terminal.
+func Start(cmd *exec.Cmd) (*os.File, error) {
+ return StartWithSize(cmd, nil)
+}
+
+// StartWithAttrs assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
+// and c.Stderr, calls c.Start, and returns the File of the tty's
+// corresponding pty.
+//
+// This will resize the pty to the specified size before starting the command if a size is provided.
+// The `attrs` parameter overrides the one set in c.SysProcAttr.
+//
+// This should generally not be needed. Used in some edge cases where it is needed to create a pty
+// without a controlling terminal.
+func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (*os.File, error) {
+ pty, tty, err := Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() { _ = tty.Close() }() // Best effort.
+
+ if sz != nil {
+ if err := Setsize(pty, sz); err != nil {
+ _ = pty.Close() // Best effort.
+ return nil, err
+ }
+ }
+ if c.Stdout == nil {
+ c.Stdout = tty
+ }
+ if c.Stderr == nil {
+ c.Stderr = tty
+ }
+ if c.Stdin == nil {
+ c.Stdin = tty
+ }
+
+ c.SysProcAttr = attrs
+
+ if err := c.Start(); err != nil {
+ _ = pty.Close() // Best effort.
+ return nil, err
+ }
+ return pty, err
+}
diff --git a/vendor/github.com/creack/pty/start.go b/vendor/github.com/creack/pty/start.go
new file mode 100644
index 0000000..9b51635
--- /dev/null
+++ b/vendor/github.com/creack/pty/start.go
@@ -0,0 +1,25 @@
+//go:build !windows
+// +build !windows
+
+package pty
+
+import (
+ "os"
+ "os/exec"
+ "syscall"
+)
+
+// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
+// and c.Stderr, calls c.Start, and returns the File of the tty's
+// corresponding pty.
+//
+// This will resize the pty to the specified size before starting the command.
+// Starts the process in a new session and sets the controlling terminal.
+func StartWithSize(cmd *exec.Cmd, ws *Winsize) (*os.File, error) {
+ if cmd.SysProcAttr == nil {
+ cmd.SysProcAttr = &syscall.SysProcAttr{}
+ }
+ cmd.SysProcAttr.Setsid = true
+ cmd.SysProcAttr.Setctty = true
+ return StartWithAttrs(cmd, ws, cmd.SysProcAttr)
+}
diff --git a/vendor/github.com/creack/pty/start_windows.go b/vendor/github.com/creack/pty/start_windows.go
new file mode 100644
index 0000000..7e9530b
--- /dev/null
+++ b/vendor/github.com/creack/pty/start_windows.go
@@ -0,0 +1,19 @@
+//go:build windows
+// +build windows
+
+package pty
+
+import (
+ "os"
+ "os/exec"
+)
+
+// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
+// and c.Stderr, calls c.Start, and returns the File of the tty's
+// corresponding pty.
+//
+// This will resize the pty to the specified size before starting the command.
+// Starts the process in a new session and sets the controlling terminal.
+func StartWithSize(cmd *exec.Cmd, ws *Winsize) (*os.File, error) {
+ return nil, ErrUnsupported
+}
diff --git a/vendor/github.com/creack/pty/test_crosscompile.sh b/vendor/github.com/creack/pty/test_crosscompile.sh
new file mode 100644
index 0000000..40df89a
--- /dev/null
+++ b/vendor/github.com/creack/pty/test_crosscompile.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env sh
+
+# Test script checking that all expected os/arch compile properly.
+# Does not actually test the logic, just the compilation so we make sure we don't break code depending on the lib.
+
+echo2() {
+ echo $@ >&2
+}
+
+trap end 0
+end() {
+ [ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1)
+}
+
+cross() {
+ os=$1
+ shift
+ echo2 "Build for $os."
+ for arch in $@; do
+ echo2 " - $os/$arch"
+ GOOS=$os GOARCH=$arch go build
+ done
+ echo2
+}
+
+set -e
+
+cross linux amd64 386 arm arm64 ppc64 ppc64le s390x mips mipsle mips64 mips64le riscv64
+cross darwin amd64 arm64
+cross freebsd amd64 386 arm arm64 riscv64
+cross netbsd amd64 386 arm arm64
+cross openbsd amd64 386 arm arm64
+cross dragonfly amd64
+cross solaris amd64
+
+# Not expected to work but should still compile.
+cross windows amd64 386 arm
+
+# TODO: Fix compilation error on openbsd/arm.
+# TODO: Merge the solaris PR.
+
+# Some os/arch require a different compiler. Run in docker.
+if ! hash docker; then
+ # If docker is not present, stop here.
+ return
+fi
+
+# Golang dropped support for darwin 32bits since go1.15. Make sure the lib still compile with go1.14 on those archs.
+echo2 "Build for darwin (32bits)."
+echo2 " - darwin/386"
+docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=386 .
+echo2 " - darwin/arm"
+docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=arm .
+
+# Run a single test for an old go version. Would be best with go1.0, but not available on Dockerhub.
+# Using 1.6 as it is the base version for the RISCV compiler.
+# Would also be better to run all the tests, not just one, need to refactor this file to allow for specifc archs per version.
+echo2 "Build for linux - go1.6."
+echo2 " - linux/amd64"
+docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.6 --build-arg=GOOS=linux --build-arg=GOARCH=amd64 .
diff --git a/vendor/github.com/creack/pty/winsize.go b/vendor/github.com/creack/pty/winsize.go
new file mode 100644
index 0000000..cfa3e5f
--- /dev/null
+++ b/vendor/github.com/creack/pty/winsize.go
@@ -0,0 +1,24 @@
+package pty
+
+import "os"
+
+// InheritSize applies the terminal size of pty to tty. This should be run
+// in a signal handler for syscall.SIGWINCH to automatically resize the tty when
+// the pty receives a window size change notification.
+func InheritSize(pty, tty *os.File) error {
+ size, err := GetsizeFull(pty)
+ if err != nil {
+ return err
+ }
+ return Setsize(tty, size)
+}
+
+// Getsize returns the number of rows (lines) and cols (positions
+// in each line) in terminal t.
+func Getsize(t *os.File) (rows, cols int, err error) {
+ ws, err := GetsizeFull(t)
+ if err != nil {
+ return 0, 0, err
+ }
+ return int(ws.Rows), int(ws.Cols), nil
+}
diff --git a/vendor/github.com/creack/pty/winsize_unix.go b/vendor/github.com/creack/pty/winsize_unix.go
new file mode 100644
index 0000000..8dbbcda
--- /dev/null
+++ b/vendor/github.com/creack/pty/winsize_unix.go
@@ -0,0 +1,35 @@
+//go:build !windows
+// +build !windows
+
+package pty
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// Winsize describes the terminal size.
+type Winsize struct {
+ Rows uint16 // ws_row: Number of rows (in cells).
+ Cols uint16 // ws_col: Number of columns (in cells).
+ X uint16 // ws_xpixel: Width in pixels.
+ Y uint16 // ws_ypixel: Height in pixels.
+}
+
+// Setsize resizes t to s.
+func Setsize(t *os.File, ws *Winsize) error {
+ //nolint:gosec // Expected unsafe pointer for Syscall call.
+ return ioctl(t, syscall.TIOCSWINSZ, uintptr(unsafe.Pointer(ws)))
+}
+
+// GetsizeFull returns the full terminal size description.
+func GetsizeFull(t *os.File) (size *Winsize, err error) {
+ var ws Winsize
+
+ //nolint:gosec // Expected unsafe pointer for Syscall call.
+ if err := ioctl(t, syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws))); err != nil {
+ return nil, err
+ }
+ return &ws, nil
+}
diff --git a/vendor/github.com/creack/pty/winsize_unsupported.go b/vendor/github.com/creack/pty/winsize_unsupported.go
new file mode 100644
index 0000000..0d21099
--- /dev/null
+++ b/vendor/github.com/creack/pty/winsize_unsupported.go
@@ -0,0 +1,23 @@
+//go:build windows
+// +build windows
+
+package pty
+
+import (
+ "os"
+)
+
+// Winsize is a dummy struct to enable compilation on unsupported platforms.
+type Winsize struct {
+ Rows, Cols, X, Y uint16
+}
+
+// Setsize resizes t to s.
+func Setsize(*os.File, *Winsize) error {
+ return ErrUnsupported
+}
+
+// GetsizeFull returns the full terminal size description.
+func GetsizeFull(*os.File) (*Winsize, error) {
+ return nil, ErrUnsupported
+}
diff --git a/vendor/github.com/creack/pty/ztypes_386.go b/vendor/github.com/creack/pty/ztypes_386.go
new file mode 100644
index 0000000..d126f4a
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_386.go
@@ -0,0 +1,12 @@
+//go:build 386
+// +build 386
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_amd64.go b/vendor/github.com/creack/pty/ztypes_amd64.go
new file mode 100644
index 0000000..6c4a767
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_amd64.go
@@ -0,0 +1,12 @@
+//go:build amd64
+// +build amd64
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_arm.go b/vendor/github.com/creack/pty/ztypes_arm.go
new file mode 100644
index 0000000..de6fe16
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_arm.go
@@ -0,0 +1,12 @@
+//go:build arm
+// +build arm
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_arm64.go b/vendor/github.com/creack/pty/ztypes_arm64.go
new file mode 100644
index 0000000..c4f315c
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_arm64.go
@@ -0,0 +1,12 @@
+//go:build arm64
+// +build arm64
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go
new file mode 100644
index 0000000..183c421
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go
@@ -0,0 +1,17 @@
+//go:build amd64 && dragonfly
+// +build amd64,dragonfly
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_dragonfly.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Name *byte
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_386.go b/vendor/github.com/creack/pty/ztypes_freebsd_386.go
new file mode 100644
index 0000000..d80dbf7
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_386.go
@@ -0,0 +1,16 @@
+//go:build 386 && freebsd
+// +build 386,freebsd
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go
new file mode 100644
index 0000000..bfab4e4
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go
@@ -0,0 +1,17 @@
+//go:build amd64 && freebsd
+// +build amd64,freebsd
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Pad_cgo_0 [4]byte
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_arm.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go
new file mode 100644
index 0000000..3a8aeae
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go
@@ -0,0 +1,16 @@
+//go:build arm && freebsd
+// +build arm,freebsd
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go
new file mode 100644
index 0000000..a839249
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go
@@ -0,0 +1,16 @@
+//go:build arm64 && freebsd
+// +build arm64,freebsd
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0xff
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go b/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go
new file mode 100644
index 0000000..5fa102f
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go
@@ -0,0 +1,14 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Pad_cgo_0 [4]byte
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_riscv64.go b/vendor/github.com/creack/pty/ztypes_freebsd_riscv64.go
new file mode 100644
index 0000000..b3c5440
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_freebsd_riscv64.go
@@ -0,0 +1,13 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs types_freebsd.go
+
+package pty
+
+const (
+ _C_SPECNAMELEN = 0x3f
+)
+
+type fiodgnameArg struct {
+ Len int32
+ Buf *byte
+}
diff --git a/vendor/github.com/creack/pty/ztypes_loong64.go b/vendor/github.com/creack/pty/ztypes_loong64.go
new file mode 100644
index 0000000..3beb5c1
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_loong64.go
@@ -0,0 +1,12 @@
+//go:build loong64
+// +build loong64
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_mipsx.go b/vendor/github.com/creack/pty/ztypes_mipsx.go
new file mode 100644
index 0000000..2812779
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_mipsx.go
@@ -0,0 +1,13 @@
+//go:build (mips || mipsle || mips64 || mips64le) && linux
+// +build mips mipsle mips64 mips64le
+// +build linux
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go
new file mode 100644
index 0000000..2ab7c45
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go
@@ -0,0 +1,17 @@
+//go:build (386 || amd64 || arm || arm64) && netbsd
+// +build 386 amd64 arm arm64
+// +build netbsd
+
+package pty
+
+type ptmget struct {
+ Cfd int32
+ Sfd int32
+ Cn [1024]int8
+ Sn [1024]int8
+}
+
+var (
+ ioctl_TIOCPTSNAME = 0x48087448
+ ioctl_TIOCGRANTPT = 0x20007447
+)
diff --git a/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go
new file mode 100644
index 0000000..1eb0948
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go
@@ -0,0 +1,14 @@
+//go:build (386 || amd64 || arm || arm64 || mips64) && openbsd
+// +build 386 amd64 arm arm64 mips64
+// +build openbsd
+
+package pty
+
+type ptmget struct {
+ Cfd int32
+ Sfd int32
+ Cn [16]int8
+ Sn [16]int8
+}
+
+var ioctl_PTMGET = 0x40287401
diff --git a/vendor/github.com/creack/pty/ztypes_ppc.go b/vendor/github.com/creack/pty/ztypes_ppc.go
new file mode 100644
index 0000000..ff0b8fd
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_ppc.go
@@ -0,0 +1,9 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_ppc64.go b/vendor/github.com/creack/pty/ztypes_ppc64.go
new file mode 100644
index 0000000..bbb3da8
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_ppc64.go
@@ -0,0 +1,12 @@
+//go:build ppc64
+// +build ppc64
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_ppc64le.go b/vendor/github.com/creack/pty/ztypes_ppc64le.go
new file mode 100644
index 0000000..8a4fac3
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_ppc64le.go
@@ -0,0 +1,12 @@
+//go:build ppc64le
+// +build ppc64le
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_riscvx.go b/vendor/github.com/creack/pty/ztypes_riscvx.go
new file mode 100644
index 0000000..dc5da90
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_riscvx.go
@@ -0,0 +1,12 @@
+//go:build riscv || riscv64
+// +build riscv riscv64
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_s390x.go b/vendor/github.com/creack/pty/ztypes_s390x.go
new file mode 100644
index 0000000..3433be7
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_s390x.go
@@ -0,0 +1,12 @@
+//go:build s390x
+// +build s390x
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/creack/pty/ztypes_sparcx.go b/vendor/github.com/creack/pty/ztypes_sparcx.go
new file mode 100644
index 0000000..06e4431
--- /dev/null
+++ b/vendor/github.com/creack/pty/ztypes_sparcx.go
@@ -0,0 +1,12 @@
+//go:build sparc || sparc64
+// +build sparc sparc64
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs types.go
+
+package pty
+
+type (
+ _C_int int32
+ _C_uint uint32
+)
diff --git a/vendor/github.com/cyphar/filepath-securejoin/LICENSE b/vendor/github.com/cyphar/filepath-securejoin/LICENSE
new file mode 100644
index 0000000..cb1ab88
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/LICENSE
@@ -0,0 +1,28 @@
+Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
+Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md
new file mode 100644
index 0000000..253956f
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/README.md
@@ -0,0 +1,168 @@
+## `filepath-securejoin` ##
+
+[](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml)
+
+### Old API ###
+
+This library was originally just an implementation of `SecureJoin` which was
+[intended to be included in the Go standard library][go#20126] as a safer
+`filepath.Join` that would restrict the path lookup to be inside a root
+directory.
+
+The implementation was based on code that existed in several container
+runtimes. Unfortunately, this API is **fundamentally unsafe** against attackers
+that can modify path components after `SecureJoin` returns and before the
+caller uses the path, allowing for some fairly trivial TOCTOU attacks.
+
+`SecureJoin` (and `SecureJoinVFS`) are still provided by this library to
+support legacy users, but new users are strongly suggested to avoid using
+`SecureJoin` and instead use the [new api](#new-api) or switch to
+[libpathrs][libpathrs].
+
+With the above limitations in mind, this library guarantees the following:
+
+* If no error is set, the resulting string **must** be a child path of
+ `root` and will not contain any symlink path components (they will all be
+ expanded).
+
+* When expanding symlinks, all symlink path components **must** be resolved
+ relative to the provided root. In particular, this can be considered a
+ userspace implementation of how `chroot(2)` operates on file paths. Note that
+ these symlinks will **not** be expanded lexically (`filepath.Clean` is not
+ called on the input before processing).
+
+* Non-existent path components are unaffected by `SecureJoin` (similar to
+ `filepath.EvalSymlinks`'s semantics).
+
+* The returned path will always be `filepath.Clean`ed and thus not contain any
+ `..` components.
+
+A (trivial) implementation of this function on GNU/Linux systems could be done
+with the following (note that this requires root privileges and is far more
+opaque than the implementation in this library, and also requires that
+`readlink` is inside the `root` path and is trustworthy):
+
+```go
+package securejoin
+
+import (
+ "os/exec"
+ "path/filepath"
+)
+
+func SecureJoin(root, unsafePath string) (string, error) {
+ unsafePath = string(filepath.Separator) + unsafePath
+ cmd := exec.Command("chroot", root,
+ "readlink", "--canonicalize-missing", "--no-newline", unsafePath)
+ output, err := cmd.CombinedOutput()
+ if err != nil {
+ return "", err
+ }
+ expanded := string(output)
+ return filepath.Join(root, expanded), nil
+}
+```
+
+[libpathrs]: https://github.com/openSUSE/libpathrs
+[go#20126]: https://github.com/golang/go/issues/20126
+
+### New API ###
+
+While we recommend users switch to [libpathrs][libpathrs] as soon as it has a
+stable release, some methods implemented by libpathrs have been ported to this
+library to ease the transition. These APIs are only supported on Linux.
+
+These APIs are implemented such that `filepath-securejoin` will
+opportunistically use certain newer kernel APIs that make these operations far
+more secure. In particular:
+
+* All of the lookup operations will use [`openat2`][openat2.2] on new enough
+ kernels (Linux 5.6 or later) to restrict lookups through magic-links and
+ bind-mounts (for certain operations) and to make use of `RESOLVE_IN_ROOT` to
+ efficiently resolve symlinks within a rootfs.
+
+* The APIs provide hardening against a malicious `/proc` mount to either detect
+ or avoid being tricked by a `/proc` that is not legitimate. This is done
+ using [`openat2`][openat2.2] for all users, and privileged users will also be
+ further protected by using [`fsopen`][fsopen.2] and [`open_tree`][open_tree.2]
+ (Linux 4.18 or later).
+
+[openat2.2]: https://www.man7.org/linux/man-pages/man2/openat2.2.html
+[fsopen.2]: https://github.com/brauner/man-pages-md/blob/main/fsopen.md
+[open_tree.2]: https://github.com/brauner/man-pages-md/blob/main/open_tree.md
+
+#### `OpenInRoot` ####
+
+```go
+func OpenInRoot(root, unsafePath string) (*os.File, error)
+func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error)
+func Reopen(handle *os.File, flags int) (*os.File, error)
+```
+
+`OpenInRoot` is a much safer version of
+
+```go
+path, err := securejoin.SecureJoin(root, unsafePath)
+file, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC)
+```
+
+that protects against various race attacks that could lead to serious security
+issues, depending on the application. Note that the returned `*os.File` is an
+`O_PATH` file descriptor, which is quite restricted. Callers will probably need
+to use `Reopen` to get a more usable handle (this split is done to provide
+useful features like PTY spawning and to avoid users accidentally opening bad
+inodes that could cause a DoS).
+
+Callers need to be careful in how they use the returned `*os.File`. Usually it
+is only safe to operate on the handle directly, and it is very easy to create a
+security issue. [libpathrs][libpathrs] provides far more helpers to make using
+these handles safer -- there is currently no plan to port them to
+`filepath-securejoin`.
+
+`OpenatInRoot` is like `OpenInRoot` except that the root is provided using an
+`*os.File`. This allows you to ensure that multiple `OpenatInRoot` (or
+`MkdirAllHandle`) calls are operating on the same rootfs.
+
+> **NOTE**: Unlike `SecureJoin`, `OpenInRoot` will error out as soon as it hits
+> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
+> which treated non-existent components as though they were real directories,
+> and would allow for partial resolution of dangling symlinks. These behaviours
+> are at odds with how Linux treats non-existent paths and dangling symlinks,
+> and so these are no longer allowed.
+
+#### `MkdirAll` ####
+
+```go
+func MkdirAll(root, unsafePath string, mode int) error
+func MkdirAllHandle(root *os.File, unsafePath string, mode int) (*os.File, error)
+```
+
+`MkdirAll` is a much safer version of
+
+```go
+path, err := securejoin.SecureJoin(root, unsafePath)
+err = os.MkdirAll(path, mode)
+```
+
+that protects against the same kinds of races that `OpenInRoot` protects
+against.
+
+`MkdirAllHandle` is like `MkdirAll` except that the root is provided using an
+`*os.File` (the reason for this is the same as with `OpenatInRoot`) and an
+`*os.File` of the final created directory is returned (this directory is
+guaranteed to be effectively identical to the directory created by
+`MkdirAllHandle`, which is not possible to ensure by just using `OpenatInRoot`
+after `MkdirAll`).
+
+> **NOTE**: Unlike `SecureJoin`, `MkdirAll` will error out as soon as it hits
+> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
+> which treated non-existent components as though they were real directories,
+> and would allow for partial resolution of dangling symlinks. These behaviours
+> are at odds with how Linux treats non-existent paths and dangling symlinks,
+> and so these are no longer allowed. This means that `MkdirAll` will not
+> create non-existent directories referenced by a dangling symlink.
+
+### License ###
+
+The license of this project is the same as Go, which is a BSD 3-clause license
+available in the `LICENSE` file.
diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION
new file mode 100644
index 0000000..0d91a54
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION
@@ -0,0 +1 @@
+0.3.0
diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go
new file mode 100644
index 0000000..bd86a48
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/join.go
@@ -0,0 +1,130 @@
+// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package securejoin is an implementation of the hopefully-soon-to-be-included
+// SecureJoin helper that is meant to be part of the "path/filepath" package.
+// The purpose of this project is to provide a PoC implementation to make the
+// SecureJoin proposal (https://github.com/golang/go/issues/20126) more
+// tangible.
+package securejoin
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "strings"
+ "syscall"
+)
+
+const maxSymlinkLimit = 255
+
+// IsNotExist tells you if err is an error that implies that either the path
+// accessed does not exist (or path components don't exist). This is
+// effectively a more broad version of os.IsNotExist.
+func IsNotExist(err error) bool {
+ // Check that it's not actually an ENOTDIR, which in some cases is a more
+ // convoluted case of ENOENT (usually involving weird paths).
+ return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT)
+}
+
+// SecureJoinVFS joins the two given path components (similar to Join) except
+// that the returned path is guaranteed to be scoped inside the provided root
+// path (when evaluated). Any symbolic links in the path are evaluated with the
+// given root treated as the root of the filesystem, similar to a chroot. The
+// filesystem state is evaluated through the given VFS interface (if nil, the
+// standard os.* family of functions are used).
+//
+// Note that the guarantees provided by this function only apply if the path
+// components in the returned string are not modified (in other words are not
+// replaced with symlinks on the filesystem) after this function has returned.
+// Such a symlink race is necessarily out-of-scope of SecureJoin.
+//
+// NOTE: Due to the above limitation, Linux users are strongly encouraged to
+// use OpenInRoot instead, which does safely protect against these kinds of
+// attacks. There is no way to solve this problem with SecureJoinVFS because
+// the API is fundamentally wrong (you cannot return a "safe" path string and
+// guarantee it won't be modified afterwards).
+//
+// Volume names in unsafePath are always discarded, regardless if they are
+// provided via direct input or when evaluating symlinks. Therefore:
+//
+// "C:\Temp" + "D:\path\to\file.txt" results in "C:\Temp\path\to\file.txt"
+func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
+ // Use the os.* VFS implementation if none was specified.
+ if vfs == nil {
+ vfs = osVFS{}
+ }
+
+ unsafePath = filepath.FromSlash(unsafePath)
+ var (
+ currentPath string
+ remainingPath = unsafePath
+ linksWalked int
+ )
+ for remainingPath != "" {
+ if v := filepath.VolumeName(remainingPath); v != "" {
+ remainingPath = remainingPath[len(v):]
+ }
+
+ // Get the next path component.
+ var part string
+ if i := strings.IndexRune(remainingPath, filepath.Separator); i == -1 {
+ part, remainingPath = remainingPath, ""
+ } else {
+ part, remainingPath = remainingPath[:i], remainingPath[i+1:]
+ }
+
+ // Apply the component lexically to the path we are building.
+ // currentPath does not contain any symlinks, and we are lexically
+ // dealing with a single component, so it's okay to do a filepath.Clean
+ // here.
+ nextPath := filepath.Join(string(filepath.Separator), currentPath, part)
+ if nextPath == string(filepath.Separator) {
+ currentPath = ""
+ continue
+ }
+ fullPath := root + string(filepath.Separator) + nextPath
+
+ // Figure out whether the path is a symlink.
+ fi, err := vfs.Lstat(fullPath)
+ if err != nil && !IsNotExist(err) {
+ return "", err
+ }
+ // Treat non-existent path components the same as non-symlinks (we
+ // can't do any better here).
+ if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 {
+ currentPath = nextPath
+ continue
+ }
+
+ // It's a symlink, so get its contents and expand it by prepending it
+ // to the yet-unparsed path.
+ linksWalked++
+ if linksWalked > maxSymlinkLimit {
+ return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP}
+ }
+
+ dest, err := vfs.Readlink(fullPath)
+ if err != nil {
+ return "", err
+ }
+ remainingPath = dest + string(filepath.Separator) + remainingPath
+ // Absolute symlinks reset any work we've already done.
+ if filepath.IsAbs(dest) {
+ currentPath = ""
+ }
+ }
+
+ // There should be no lexical components like ".." left in the path here,
+ // but for safety clean up the path before joining it to the root.
+ finalPath := filepath.Join(string(filepath.Separator), currentPath)
+ return filepath.Join(root, finalPath), nil
+}
+
+// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library
+// of functions as the VFS. If in doubt, use this function over SecureJoinVFS.
+func SecureJoin(root, unsafePath string) (string, error) {
+ return SecureJoinVFS(root, unsafePath, nil)
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go
new file mode 100644
index 0000000..140ac18
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go
@@ -0,0 +1,380 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+type symlinkStackEntry struct {
+ // (dir, remainingPath) is what we would've returned if the link didn't
+ // exist. This matches what openat2(RESOLVE_IN_ROOT) would return in
+ // this case.
+ dir *os.File
+ remainingPath string
+ // linkUnwalked is the remaining path components from the original
+ // Readlink which we have yet to walk. When this slice is empty, we
+ // drop the link from the stack.
+ linkUnwalked []string
+}
+
+func (se symlinkStackEntry) String() string {
+ return fmt.Sprintf("<%s>/%s [->%s]", se.dir.Name(), se.remainingPath, strings.Join(se.linkUnwalked, "/"))
+}
+
+func (se symlinkStackEntry) Close() {
+ _ = se.dir.Close()
+}
+
+type symlinkStack []*symlinkStackEntry
+
+func (s symlinkStack) IsEmpty() bool {
+ return len(s) == 0
+}
+
+func (s *symlinkStack) Close() {
+ for _, link := range *s {
+ link.Close()
+ }
+ // TODO: Switch to clear once we switch to Go 1.21.
+ *s = nil
+}
+
+var (
+ errEmptyStack = errors.New("[internal] stack is empty")
+ errBrokenSymlinkStack = errors.New("[internal error] broken symlink stack")
+)
+
+func (s *symlinkStack) popPart(part string) error {
+ if s.IsEmpty() {
+ // If there is nothing in the symlink stack, then the part was from the
+ // real path provided by the user, and this is a no-op.
+ return errEmptyStack
+ }
+ tailEntry := (*s)[len(*s)-1]
+
+ // Double-check that we are popping the component we expect.
+ if len(tailEntry.linkUnwalked) == 0 {
+ return fmt.Errorf("%w: trying to pop component %q of empty stack entry %s", errBrokenSymlinkStack, part, tailEntry)
+ }
+ headPart := tailEntry.linkUnwalked[0]
+ if headPart != part {
+ return fmt.Errorf("%w: trying to pop component %q but the last stack entry is %s (%q)", errBrokenSymlinkStack, part, tailEntry, headPart)
+ }
+
+ // Drop the component, but keep the entry around in case we are dealing
+ // with a "tail-chained" symlink.
+ tailEntry.linkUnwalked = tailEntry.linkUnwalked[1:]
+ return nil
+}
+
+func (s *symlinkStack) PopPart(part string) error {
+ if err := s.popPart(part); err != nil {
+ if errors.Is(err, errEmptyStack) {
+ // Skip empty stacks.
+ err = nil
+ }
+ return err
+ }
+
+ // Clean up any of the trailing stack entries that are empty.
+ for lastGood := len(*s) - 1; lastGood >= 0; lastGood-- {
+ entry := (*s)[lastGood]
+ if len(entry.linkUnwalked) > 0 {
+ break
+ }
+ entry.Close()
+ (*s) = (*s)[:lastGood]
+ }
+ return nil
+}
+
+func (s *symlinkStack) push(dir *os.File, remainingPath, linkTarget string) error {
+ // Split the link target and clean up any "" parts.
+ linkTargetParts := slices.DeleteFunc(
+ strings.Split(linkTarget, "/"),
+ func(part string) bool { return part == "" })
+
+ // Don't add a no-op link to the stack. You can't create a no-op link
+ // symlink, but if the symlink is /, partialLookupInRoot has already jumped to the
+ // root and so there's nothing more to do.
+ if len(linkTargetParts) == 0 {
+ return nil
+ }
+
+ // Copy the directory so the caller doesn't close our copy.
+ dirCopy, err := dupFile(dir)
+ if err != nil {
+ return err
+ }
+
+ // Add to the stack.
+ *s = append(*s, &symlinkStackEntry{
+ dir: dirCopy,
+ remainingPath: remainingPath,
+ linkUnwalked: linkTargetParts,
+ })
+ return nil
+}
+
+func (s *symlinkStack) SwapLink(linkPart string, dir *os.File, remainingPath, linkTarget string) error {
+ // If we are currently inside a symlink resolution, remove the symlink
+ // component from the last symlink entry, but don't remove the entry even
+ // if it's empty. If we are a "tail-chained" symlink (a trailing symlink we
+ // hit during a symlink resolution) we need to keep the old symlink until
+ // we finish the resolution.
+ if err := s.popPart(linkPart); err != nil {
+ if !errors.Is(err, errEmptyStack) {
+ return err
+ }
+ // Push the component regardless of whether the stack was empty.
+ }
+ return s.push(dir, remainingPath, linkTarget)
+}
+
+func (s *symlinkStack) PopTopSymlink() (*os.File, string, bool) {
+ if s.IsEmpty() {
+ return nil, "", false
+ }
+ tailEntry := (*s)[0]
+ *s = (*s)[1:]
+ return tailEntry.dir, tailEntry.remainingPath, true
+}
+
+// partialLookupInRoot tries to lookup as much of the request path as possible
+// within the provided root (a-la RESOLVE_IN_ROOT) and opens the final existing
+// component of the requested path, returning a file handle to the final
+// existing component and a string containing the remaining path components.
+func partialLookupInRoot(root *os.File, unsafePath string) (_ *os.File, _ string, Err error) {
+ unsafePath = filepath.ToSlash(unsafePath) // noop
+
+ // This is very similar to SecureJoin, except that we operate on the
+ // components using file descriptors. We then return the last component we
+ // managed open, along with the remaining path components not opened.
+
+ // Try to use openat2 if possible.
+ if hasOpenat2() {
+ return partialLookupOpenat2(root, unsafePath)
+ }
+
+ // Get the "actual" root path from /proc/self/fd. This is necessary if the
+ // root is some magic-link like /proc/$pid/root, in which case we want to
+ // make sure when we do checkProcSelfFdPath that we are using the correct
+ // root path.
+ logicalRootPath, err := procSelfFdReadlink(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("get real root path: %w", err)
+ }
+
+ currentDir, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = currentDir.Close()
+ }
+ }()
+
+ // symlinkStack is used to emulate how openat2(RESOLVE_IN_ROOT) treats
+ // dangling symlinks. If we hit a non-existent path while resolving a
+ // symlink, we need to return the (dir, remainingPath) that we had when we
+ // hit the symlink (treating the symlink as though it were a regular file).
+ // The set of (dir, remainingPath) sets is stored within the symlinkStack
+ // and we add and remove parts when we hit symlink and non-symlink
+ // components respectively. We need a stack because of recursive symlinks
+ // (symlinks that contain symlink components in their target).
+ //
+ // Note that the stack is ONLY used for book-keeping. All of the actual
+ // path walking logic is still based on currentPath/remainingPath and
+ // currentDir (as in SecureJoin).
+ var symlinkStack symlinkStack
+ defer symlinkStack.Close()
+
+ var (
+ linksWalked int
+ currentPath string
+ remainingPath = unsafePath
+ )
+ for remainingPath != "" {
+ // Save the current remaining path so if the part is not real we can
+ // return the path including the component.
+ oldRemainingPath := remainingPath
+
+ // Get the next path component.
+ var part string
+ if i := strings.IndexByte(remainingPath, '/'); i == -1 {
+ part, remainingPath = remainingPath, ""
+ } else {
+ part, remainingPath = remainingPath[:i], remainingPath[i+1:]
+ }
+ // Skip any "//" components.
+ if part == "" {
+ continue
+ }
+
+ // Apply the component lexically to the path we are building.
+ // currentPath does not contain any symlinks, and we are lexically
+ // dealing with a single component, so it's okay to do a filepath.Clean
+ // here.
+ nextPath := path.Join("/", currentPath, part)
+ // If we logically hit the root, just clone the root rather than
+ // opening the part and doing all of the other checks.
+ if nextPath == "/" {
+ if err := symlinkStack.PopPart(part); err != nil {
+ return nil, "", fmt.Errorf("walking into root with part %q failed: %w", part, err)
+ }
+ // Jump to root.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ _ = currentDir.Close()
+ currentDir = rootClone
+ currentPath = nextPath
+ continue
+ }
+
+ // Try to open the next component.
+ nextDir, err := openatFile(currentDir, part, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
+ switch {
+ case err == nil:
+ st, err := nextDir.Stat()
+ if err != nil {
+ _ = nextDir.Close()
+ return nil, "", fmt.Errorf("stat component %q: %w", part, err)
+ }
+
+ switch st.Mode() & os.ModeType {
+ case os.ModeDir:
+ // If we are dealing with a directory, simply walk into it.
+ _ = currentDir.Close()
+ currentDir = nextDir
+ currentPath = nextPath
+
+ // The part was real, so drop it from the symlink stack.
+ if err := symlinkStack.PopPart(part); err != nil {
+ return nil, "", fmt.Errorf("walking into directory %q failed: %w", part, err)
+ }
+
+ // If we are operating on a .., make sure we haven't escaped.
+ // We only have to check for ".." here because walking down
+ // into a regular component component cannot cause you to
+ // escape. This mirrors the logic in RESOLVE_IN_ROOT, except we
+ // have to check every ".." rather than only checking after a
+ // rename or mount on the system.
+ if part == ".." {
+ // Make sure the root hasn't moved.
+ if err := checkProcSelfFdPath(logicalRootPath, root); err != nil {
+ return nil, "", fmt.Errorf("root path moved during lookup: %w", err)
+ }
+ // Make sure the path is what we expect.
+ fullPath := logicalRootPath + nextPath
+ if err := checkProcSelfFdPath(fullPath, currentDir); err != nil {
+ return nil, "", fmt.Errorf("walking into %q had unexpected result: %w", part, err)
+ }
+ }
+
+ case os.ModeSymlink:
+ // We don't need the handle anymore.
+ _ = nextDir.Close()
+
+ // Unfortunately, we cannot readlink through our handle and so
+ // we need to do a separate readlinkat (which could race to
+ // give us an error if the attacker swapped the symlink with a
+ // non-symlink).
+ linkDest, err := readlinkatFile(currentDir, part)
+ if err != nil {
+ if errors.Is(err, unix.EINVAL) {
+ // The part was not a symlink, so assume that it's a
+ // regular file. It is possible for it to be a
+ // directory (if an attacker is swapping a directory
+ // and non-directory at this subpath) but erroring out
+ // here is better anyway.
+ err = fmt.Errorf("%w: path component %q is invalid: %w", errPossibleAttack, part, unix.ENOTDIR)
+ }
+ return nil, "", err
+ }
+
+ linksWalked++
+ if linksWalked > maxSymlinkLimit {
+ return nil, "", &os.PathError{Op: "partialLookupInRoot", Path: logicalRootPath + "/" + unsafePath, Err: unix.ELOOP}
+ }
+
+ // Swap out the symlink's component for the link entry itself.
+ if err := symlinkStack.SwapLink(part, currentDir, oldRemainingPath, linkDest); err != nil {
+ return nil, "", fmt.Errorf("walking into symlink %q failed: push symlink: %w", part, err)
+ }
+
+ // Update our logical remaining path.
+ remainingPath = linkDest + "/" + remainingPath
+ // Absolute symlinks reset any work we've already done.
+ if path.IsAbs(linkDest) {
+ // Jump to root.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", fmt.Errorf("clone root fd: %w", err)
+ }
+ _ = currentDir.Close()
+ currentDir = rootClone
+ currentPath = "/"
+ }
+ default:
+ // For any other file type, we can't walk further and so we've
+ // hit the end of the lookup. The handling is very similar to
+ // ENOENT from openat(2), except that we return a handle to the
+ // component we just walked into (and we drop the component
+ // from the symlink stack).
+ _ = currentDir.Close()
+
+ // The part existed, so drop it from the symlink stack.
+ if err := symlinkStack.PopPart(part); err != nil {
+ return nil, "", fmt.Errorf("walking into non-directory %q failed: %w", part, err)
+ }
+
+ // If there are any remaining components in the symlink stack,
+ // we are still within a symlink resolution and thus we hit a
+ // dangling symlink. So pretend that the first symlink in the
+ // stack we hit was an ENOENT (to match openat2).
+ if oldDir, remainingPath, ok := symlinkStack.PopTopSymlink(); ok {
+ _ = nextDir.Close()
+ return oldDir, remainingPath, nil
+ }
+
+ // The current component exists, so return it.
+ return nextDir, remainingPath, nil
+ }
+
+ case errors.Is(err, os.ErrNotExist):
+ // If there are any remaining components in the symlink stack, we
+ // are still within a symlink resolution and thus we hit a dangling
+ // symlink. So pretend that the first symlink in the stack we hit
+ // was an ENOENT (to match openat2).
+ if oldDir, remainingPath, ok := symlinkStack.PopTopSymlink(); ok {
+ _ = currentDir.Close()
+ return oldDir, remainingPath, nil
+ }
+ // We have hit a final component that doesn't exist, so we have our
+ // partial open result. Note that we have to use the OLD remaining
+ // path, since the lookup failed.
+ return currentDir, oldRemainingPath, nil
+
+ default:
+ return nil, "", err
+ }
+ }
+ // All of the components existed!
+ return currentDir, "", nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
new file mode 100644
index 0000000..05e0bde
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
@@ -0,0 +1,228 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ errInvalidMode = errors.New("invalid permission mode")
+ errPossibleAttack = errors.New("possible attack detected")
+)
+
+// MkdirAllHandle is equivalent to MkdirAll, except that it is safer to use in
+// two respects:
+//
+// - The caller provides the root directory as an *os.File (preferably O_PATH)
+// handle. This means that the caller can be sure which root directory is
+// being used. Note that this can be emulated by using /proc/self/fd/... as
+// the root path with MkdirAll.
+//
+// - Once all of the directories have been created, an *os.File (O_PATH) handle
+// to the directory at unsafePath is returned to the caller. This is done in
+// an effectively-race-free way (an attacker would only be able to swap the
+// final directory component), which is not possible to emulate with
+// MkdirAll.
+//
+// In addition, the returned handle is obtained far more efficiently than doing
+// a brand new lookup of unsafePath (such as with SecureJoin or openat2) after
+// doing MkdirAll. If you intend to open the directory after creating it, you
+// should use MkdirAllHandle.
+func MkdirAllHandle(root *os.File, unsafePath string, mode int) (_ *os.File, Err error) {
+ // Make sure there are no os.FileMode bits set.
+ if mode&^0o7777 != 0 {
+ return nil, fmt.Errorf("%w for mkdir 0o%.3o", errInvalidMode, mode)
+ }
+
+ // Try to open as much of the path as possible.
+ currentDir, remainingPath, err := partialLookupInRoot(root, unsafePath)
+ if err != nil {
+ return nil, fmt.Errorf("find existing subpath of %q: %w", unsafePath, err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = currentDir.Close()
+ }
+ }()
+
+ // If there is an attacker deleting directories as we walk into them,
+ // detect this proactively. Note this is guaranteed to detect if the
+ // attacker deleted any part of the tree up to currentDir.
+ //
+ // Once we walk into a dead directory, partialLookupInRoot would not be
+ // able to walk further down the tree (directories must be empty before
+ // they are deleted), and if the attacker has removed the entire tree we
+ // can be sure that anything that was originally inside a dead directory
+ // must also be deleted and thus is a dead directory in its own right.
+ //
+ // This is mostly a quality-of-life check, because mkdir will simply fail
+ // later if the attacker deletes the tree after this check.
+ if err := isDeadInode(currentDir); err != nil {
+ return nil, fmt.Errorf("finding existing subpath of %q: %w", unsafePath, err)
+ }
+
+ // Re-open the path to match the O_DIRECTORY reopen loop later (so that we
+ // always return a non-O_PATH handle). We also check that we actually got a
+ // directory.
+ if reopenDir, err := Reopen(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) {
+ return nil, fmt.Errorf("cannot create subdirectories in %q: %w", currentDir.Name(), unix.ENOTDIR)
+ } else if err != nil {
+ return nil, fmt.Errorf("re-opening handle to %q: %w", currentDir.Name(), err)
+ } else {
+ currentDir = reopenDir
+ }
+
+ remainingParts := strings.Split(remainingPath, string(filepath.Separator))
+ if slices.Contains(remainingParts, "..") {
+ // The path contained ".." components after the end of the "real"
+ // components. We could try to safely resolve ".." here but that would
+ // add a bunch of extra logic for something that it's not clear even
+ // needs to be supported. So just return an error.
+ //
+ // If we do filepath.Clean(remainingPath) then we end up with the
+ // problem that ".." can erase a trailing dangling symlink and produce
+ // a path that doesn't quite match what the user asked for.
+ return nil, fmt.Errorf("%w: yet-to-be-created path %q contains '..' components", unix.ENOENT, remainingPath)
+ }
+
+ // Make sure the mode doesn't have any type bits.
+ mode &^= unix.S_IFMT
+ // What properties do we expect any newly created directories to have?
+ var (
+ // While umask(2) is a per-thread property, and thus this value could
+ // vary between threads, a functioning Go program would LockOSThread
+ // threads with different umasks and so we don't need to LockOSThread
+ // for this entire mkdirat loop (if we are in the locked thread with a
+ // different umask, we are already locked and there's nothing for us to
+ // do -- and if not then it doesn't matter which thread we run on and
+ // there's nothing for us to do).
+ expectedMode = uint32(unix.S_IFDIR | (mode &^ getUmask()))
+
+ // We would want to get the fs[ug]id here, but we can't access those
+ // from userspace. In practice, nobody uses setfs[ug]id() anymore, so
+ // just use the effective [ug]id (which is equivalent to the fs[ug]id
+ // for programs that don't use setfs[ug]id).
+ expectedUid = uint32(unix.Geteuid())
+ expectedGid = uint32(unix.Getegid())
+ )
+
+ // Create the remaining components.
+ for _, part := range remainingParts {
+ switch part {
+ case "", ".":
+ // Skip over no-op paths.
+ continue
+ }
+
+ // NOTE: mkdir(2) will not follow trailing symlinks, so we can safely
+ // create the finaly component without worrying about symlink-exchange
+ // attacks.
+ if err := unix.Mkdirat(int(currentDir.Fd()), part, uint32(mode)); err != nil {
+ err = &os.PathError{Op: "mkdirat", Path: currentDir.Name() + "/" + part, Err: err}
+ // Make the error a bit nicer if the directory is dead.
+ if err2 := isDeadInode(currentDir); err2 != nil {
+ err = fmt.Errorf("%w (%w)", err, err2)
+ }
+ return nil, err
+ }
+
+ // Get a handle to the next component. O_DIRECTORY means we don't need
+ // to use O_PATH.
+ var nextDir *os.File
+ if hasOpenat2() {
+ nextDir, err = openat2File(currentDir, part, &unix.OpenHow{
+ Flags: unix.O_NOFOLLOW | unix.O_DIRECTORY | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_NO_XDEV,
+ })
+ } else {
+ nextDir, err = openatFile(currentDir, part, unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ }
+ if err != nil {
+ return nil, err
+ }
+ _ = currentDir.Close()
+ currentDir = nextDir
+
+ // Make sure that the directory matches what we expect. An attacker
+ // could have swapped the directory between us making it and opening
+ // it. There's no way for us to be sure that the directory is
+ // _precisely_ the same as the directory we created, but if we are in
+ // an empty directory with the same owner and mode as the one we
+ // created then there is nothing the attacker could do with this new
+ // directory that they couldn't do with the old one.
+ if stat, err := fstat(currentDir); err != nil {
+ return nil, fmt.Errorf("check newly created directory: %w", err)
+ } else {
+ if stat.Mode != expectedMode {
+ return nil, fmt.Errorf("%w: newly created directory %q has incorrect mode 0o%.3o (expected 0o%.3o)", errPossibleAttack, currentDir.Name(), stat.Mode, expectedMode)
+ }
+ if stat.Uid != expectedUid || stat.Gid != expectedGid {
+ return nil, fmt.Errorf("%w: newly created directory %q has incorrect owner %d:%d (expected %d:%d)", errPossibleAttack, currentDir.Name(), stat.Uid, stat.Gid, expectedUid, expectedGid)
+ }
+ // Check that the directory is empty. We only need to check for
+ // a single entry, and we should get EOF if the directory is
+ // empty.
+ _, err := currentDir.Readdirnames(1)
+ if !errors.Is(err, io.EOF) {
+ if err == nil {
+ err = fmt.Errorf("%w: newly created directory %q is non-empty", errPossibleAttack, currentDir.Name())
+ }
+ return nil, fmt.Errorf("check if newly created directory %q is empty: %w", currentDir.Name(), err)
+ }
+ // Reset the offset.
+ _, _ = currentDir.Seek(0, unix.SEEK_SET)
+ }
+ }
+ return currentDir, nil
+}
+
+// MkdirAll is a race-safe alternative to the Go stdlib's os.MkdirAll function,
+// where the new directory is guaranteed to be within the root directory (if an
+// attacker can move directories from inside the root to outside the root, the
+// created directory tree might be outside of the root but the key constraint
+// is that at no point will we walk outside of the directory tree we are
+// creating).
+//
+// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to
+//
+// path, _ := securejoin.SecureJoin(root, unsafePath)
+// err := os.MkdirAll(path, mode)
+//
+// But is much safer. The above implementation is unsafe because if an attacker
+// can modify the filesystem tree between SecureJoin and MkdirAll, it is
+// possible for MkdirAll to resolve unsafe symlink components and create
+// directories outside of the root.
+//
+// If you plan to open the directory after you have created it or want to use
+// an open directory handle as the root, you should use MkdirAllHandle instead.
+// This function is a wrapper around MkdirAllHandle.
+//
+// NOTE: The mode argument must be set the unix mode bits (unix.S_I...), not
+// the Go generic mode bits (os.Mode...).
+func MkdirAll(root, unsafePath string, mode int) error {
+ rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return err
+ }
+ defer rootDir.Close()
+
+ f, err := MkdirAllHandle(rootDir, unsafePath, mode)
+ if err != nil {
+ return err
+ }
+ _ = f.Close()
+ return nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go
new file mode 100644
index 0000000..2170061
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go
@@ -0,0 +1,83 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "fmt"
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+// OpenatInRoot is equivalent to OpenInRoot, except that the root is provided
+// using an *os.File handle, to ensure that the correct root directory is used.
+func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) {
+ handle, remainingPath, err := partialLookupInRoot(root, unsafePath)
+ if err != nil {
+ return nil, err
+ }
+ if remainingPath != "" {
+ _ = handle.Close()
+ return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: unix.ENOENT}
+ }
+ return handle, nil
+}
+
+// OpenInRoot safely opens the provided unsafePath within the root.
+// Effectively, OpenInRoot(root, unsafePath) is equivalent to
+//
+// path, _ := securejoin.SecureJoin(root, unsafePath)
+// handle, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC)
+//
+// But is much safer. The above implementation is unsafe because if an attacker
+// can modify the filesystem tree between SecureJoin and OpenFile, it is
+// possible for the returned file to be outside of the root.
+//
+// Note that the returned handle is an O_PATH handle, meaning that only a very
+// limited set of operations will work on the handle. This is done to avoid
+// accidentally opening an untrusted file that could cause issues (such as a
+// disconnected TTY that could cause a DoS, or some other issue). In order to
+// use the returned handle, you can "upgrade" it to a proper handle using
+// Reopen.
+func OpenInRoot(root, unsafePath string) (*os.File, error) {
+ rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer rootDir.Close()
+ return OpenatInRoot(rootDir, unsafePath)
+}
+
+// Reopen takes an *os.File handle and re-opens it through /proc/self/fd.
+// Reopen(file, flags) is effectively equivalent to
+//
+// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd())
+// os.OpenFile(fdPath, flags|unix.O_CLOEXEC)
+//
+// But with some extra hardenings to ensure that we are not tricked by a
+// maliciously-configured /proc mount. While this attack scenario is not
+// common, in container runtimes it is possible for higher-level runtimes to be
+// tricked into configuring an unsafe /proc that can be used to attack file
+// operations. See CVE-2019-19921 for more details.
+func Reopen(handle *os.File, flags int) (*os.File, error) {
+ procRoot, err := getProcRoot()
+ if err != nil {
+ return nil, err
+ }
+
+ flags |= unix.O_CLOEXEC
+ fdPath := fmt.Sprintf("fd/%d", handle.Fd())
+ return doProcSelfMagiclink(procRoot, fdPath, func(procDirHandle *os.File, base string) (*os.File, error) {
+ // Rather than just wrapping openatFile, open-code it so we can copy
+ // handle.Name().
+ reopenFd, err := unix.Openat(int(procDirHandle.Fd()), base, flags, 0)
+ if err != nil {
+ return nil, fmt.Errorf("reopen fd %d: %w", handle.Fd(), err)
+ }
+ return os.NewFile(uintptr(reopenFd), handle.Name()), nil
+ })
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go
new file mode 100644
index 0000000..fc93db8
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go
@@ -0,0 +1,128 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "testing"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ hasOpenat2Bool bool
+ hasOpenat2Once sync.Once
+
+ testingForceHasOpenat2 *bool
+)
+
+func hasOpenat2() bool {
+ if testing.Testing() && testingForceHasOpenat2 != nil {
+ return *testingForceHasOpenat2
+ }
+ hasOpenat2Once.Do(func() {
+ fd, err := unix.Openat2(unix.AT_FDCWD, ".", &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_IN_ROOT,
+ })
+ if err == nil {
+ hasOpenat2Bool = true
+ _ = unix.Close(fd)
+ }
+ })
+ return hasOpenat2Bool
+}
+
+func scopedLookupShouldRetry(how *unix.OpenHow, err error) bool {
+ // RESOLVE_IN_ROOT (and RESOLVE_BENEATH) can return -EAGAIN if we resolve
+ // ".." while a mount or rename occurs anywhere on the system. This could
+ // happen spuriously, or as the result of an attacker trying to mess with
+ // us during lookup.
+ //
+ // In addition, scoped lookups have a "safety check" at the end of
+ // complete_walk which will return -EXDEV if the final path is not in the
+ // root.
+ return how.Resolve&(unix.RESOLVE_IN_ROOT|unix.RESOLVE_BENEATH) != 0 &&
+ (errors.Is(err, unix.EAGAIN) || errors.Is(err, unix.EXDEV))
+}
+
+const scopedLookupMaxRetries = 10
+
+func openat2File(dir *os.File, path string, how *unix.OpenHow) (*os.File, error) {
+ fullPath := dir.Name() + "/" + path
+ // Make sure we always set O_CLOEXEC.
+ how.Flags |= unix.O_CLOEXEC
+ var tries int
+ for tries < scopedLookupMaxRetries {
+ fd, err := unix.Openat2(int(dir.Fd()), path, how)
+ if err != nil {
+ if scopedLookupShouldRetry(how, err) {
+ // We retry a couple of times to avoid the spurious errors, and
+ // if we are being attacked then returning -EAGAIN is the best
+ // we can do.
+ tries++
+ continue
+ }
+ return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: err}
+ }
+ // If we are using RESOLVE_IN_ROOT, the name we generated may be wrong.
+ // NOTE: The procRoot code MUST NOT use RESOLVE_IN_ROOT, otherwise
+ // you'll get infinite recursion here.
+ if how.Resolve&unix.RESOLVE_IN_ROOT == unix.RESOLVE_IN_ROOT {
+ if actualPath, err := rawProcSelfFdReadlink(fd); err == nil {
+ fullPath = actualPath
+ }
+ }
+ return os.NewFile(uintptr(fd), fullPath), nil
+ }
+ return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: errPossibleAttack}
+}
+
+// partialLookupOpenat2 is an alternative implementation of
+// partialLookupInRoot, using openat2(RESOLVE_IN_ROOT) to more safely get a
+// handle to the deepest existing child of the requested path within the root.
+func partialLookupOpenat2(root *os.File, unsafePath string) (*os.File, string, error) {
+ // TODO: Implement this as a git-bisect-like binary search.
+
+ unsafePath = filepath.ToSlash(unsafePath) // noop
+ endIdx := len(unsafePath)
+ for endIdx > 0 {
+ subpath := unsafePath[:endIdx]
+
+ handle, err := openat2File(root, subpath, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS,
+ })
+ if err == nil {
+ // Jump over the slash if we have a non-"" remainingPath.
+ if endIdx < len(unsafePath) {
+ endIdx += 1
+ }
+ // We found a subpath!
+ return handle, unsafePath[endIdx:], nil
+ }
+ if errors.Is(err, unix.ENOENT) || errors.Is(err, unix.ENOTDIR) {
+ // That path doesn't exist, let's try the next directory up.
+ endIdx = strings.LastIndexByte(subpath, '/')
+ continue
+ }
+ return nil, "", fmt.Errorf("open subpath: %w", err)
+ }
+ // If we couldn't open anything, the whole subpath is missing. Return a
+ // copy of the root fd so that the caller doesn't close this one by
+ // accident.
+ rootClone, err := dupFile(root)
+ if err != nil {
+ return nil, "", err
+ }
+ return rootClone, unsafePath, nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
new file mode 100644
index 0000000..949fb5f
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
@@ -0,0 +1,59 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "os"
+ "path/filepath"
+
+ "golang.org/x/sys/unix"
+)
+
+func dupFile(f *os.File) (*os.File, error) {
+ fd, err := unix.FcntlInt(f.Fd(), unix.F_DUPFD_CLOEXEC, 0)
+ if err != nil {
+ return nil, os.NewSyscallError("fcntl(F_DUPFD_CLOEXEC)", err)
+ }
+ return os.NewFile(uintptr(fd), f.Name()), nil
+}
+
+func openatFile(dir *os.File, path string, flags int, mode int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.O_CLOEXEC
+ fd, err := unix.Openat(int(dir.Fd()), path, flags, uint32(mode))
+ if err != nil {
+ return nil, &os.PathError{Op: "openat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ // All of the paths we use with openatFile(2) are guaranteed to be
+ // lexically safe, so we can use path.Join here.
+ fullPath := filepath.Join(dir.Name(), path)
+ return os.NewFile(uintptr(fd), fullPath), nil
+}
+
+func fstatatFile(dir *os.File, path string, flags int) (unix.Stat_t, error) {
+ var stat unix.Stat_t
+ if err := unix.Fstatat(int(dir.Fd()), path, &stat, flags); err != nil {
+ return stat, &os.PathError{Op: "fstatat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ return stat, nil
+}
+
+func readlinkatFile(dir *os.File, path string) (string, error) {
+ size := 4096
+ for {
+ linkBuf := make([]byte, size)
+ n, err := unix.Readlinkat(int(dir.Fd()), path, linkBuf)
+ if err != nil {
+ return "", &os.PathError{Op: "readlinkat", Path: dir.Name() + "/" + path, Err: err}
+ }
+ if n != size {
+ return string(linkBuf[:n]), nil
+ }
+ // Possible truncation, resize the buffer.
+ size *= 2
+ }
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
new file mode 100644
index 0000000..daac3f0
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
@@ -0,0 +1,481 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "sync"
+
+ "golang.org/x/sys/unix"
+)
+
+func fstat(f *os.File) (unix.Stat_t, error) {
+ var stat unix.Stat_t
+ if err := unix.Fstat(int(f.Fd()), &stat); err != nil {
+ return stat, &os.PathError{Op: "fstat", Path: f.Name(), Err: err}
+ }
+ return stat, nil
+}
+
+func fstatfs(f *os.File) (unix.Statfs_t, error) {
+ var statfs unix.Statfs_t
+ if err := unix.Fstatfs(int(f.Fd()), &statfs); err != nil {
+ return statfs, &os.PathError{Op: "fstatfs", Path: f.Name(), Err: err}
+ }
+ return statfs, nil
+}
+
+// The kernel guarantees that the root inode of a procfs mount has an
+// f_type of PROC_SUPER_MAGIC and st_ino of PROC_ROOT_INO.
+const (
+ procSuperMagic = 0x9fa0 // PROC_SUPER_MAGIC
+ procRootIno = 1 // PROC_ROOT_INO
+)
+
+func verifyProcRoot(procRoot *os.File) error {
+ if statfs, err := fstatfs(procRoot); err != nil {
+ return err
+ } else if statfs.Type != procSuperMagic {
+ return fmt.Errorf("%w: incorrect procfs root filesystem type 0x%x", errUnsafeProcfs, statfs.Type)
+ }
+ if stat, err := fstat(procRoot); err != nil {
+ return err
+ } else if stat.Ino != procRootIno {
+ return fmt.Errorf("%w: incorrect procfs root inode number %d", errUnsafeProcfs, stat.Ino)
+ }
+ return nil
+}
+
+var (
+ hasNewMountApiBool bool
+ hasNewMountApiOnce sync.Once
+)
+
+func hasNewMountApi() bool {
+ hasNewMountApiOnce.Do(func() {
+ // All of the pieces of the new mount API we use (fsopen, fsconfig,
+ // fsmount, open_tree) were added together in Linux 5.1[1,2], so we can
+ // just check for one of the syscalls and the others should also be
+ // available.
+ //
+ // Just try to use open_tree(2) to open a file without OPEN_TREE_CLONE.
+ // This is equivalent to openat(2), but tells us if open_tree is
+ // available (and thus all of the other basic new mount API syscalls).
+ // open_tree(2) is most light-weight syscall to test here.
+ //
+ // [1]: merge commit 400913252d09
+ // [2]:
+ fd, err := unix.OpenTree(-int(unix.EBADF), "/", unix.OPEN_TREE_CLOEXEC)
+ if err == nil {
+ hasNewMountApiBool = true
+ _ = unix.Close(fd)
+ }
+ })
+ return hasNewMountApiBool
+}
+
+func fsopen(fsName string, flags int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.FSOPEN_CLOEXEC
+ fd, err := unix.Fsopen(fsName, flags)
+ if err != nil {
+ return nil, os.NewSyscallError("fsopen "+fsName, err)
+ }
+ return os.NewFile(uintptr(fd), "fscontext:"+fsName), nil
+}
+
+func fsmount(ctx *os.File, flags, mountAttrs int) (*os.File, error) {
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.FSMOUNT_CLOEXEC
+ fd, err := unix.Fsmount(int(ctx.Fd()), flags, mountAttrs)
+ if err != nil {
+ return nil, os.NewSyscallError("fsmount "+ctx.Name(), err)
+ }
+ return os.NewFile(uintptr(fd), "fsmount:"+ctx.Name()), nil
+}
+
+func newPrivateProcMount() (*os.File, error) {
+ procfsCtx, err := fsopen("proc", unix.FSOPEN_CLOEXEC)
+ if err != nil {
+ return nil, err
+ }
+ defer procfsCtx.Close()
+
+ // Try to configure hidepid=ptraceable,subset=pid if possible, but ignore errors.
+ _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "hidepid", "ptraceable")
+ _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "subset", "pid")
+
+ // Get an actual handle.
+ if err := unix.FsconfigCreate(int(procfsCtx.Fd())); err != nil {
+ return nil, os.NewSyscallError("fsconfig create procfs", err)
+ }
+ return fsmount(procfsCtx, unix.FSMOUNT_CLOEXEC, unix.MS_RDONLY|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_NOSUID)
+}
+
+func openTree(dir *os.File, path string, flags uint) (*os.File, error) {
+ dirFd := -int(unix.EBADF)
+ dirName := "."
+ if dir != nil {
+ dirFd = int(dir.Fd())
+ dirName = dir.Name()
+ }
+ // Make sure we always set O_CLOEXEC.
+ flags |= unix.OPEN_TREE_CLOEXEC
+ fd, err := unix.OpenTree(dirFd, path, flags)
+ if err != nil {
+ return nil, &os.PathError{Op: "open_tree", Path: path, Err: err}
+ }
+ return os.NewFile(uintptr(fd), dirName+"/"+path), nil
+}
+
+func clonePrivateProcMount() (_ *os.File, Err error) {
+ // Try to make a clone without using AT_RECURSIVE if we can. If this works,
+ // we can be sure there are no over-mounts and so if the root is valid then
+ // we're golden. Otherwise, we have to deal with over-mounts.
+ procfsHandle, err := openTree(nil, "/proc", unix.OPEN_TREE_CLONE)
+ if err != nil || testingForcePrivateProcRootOpenTreeAtRecursive(procfsHandle) {
+ procfsHandle, err = openTree(nil, "/proc", unix.OPEN_TREE_CLONE|unix.AT_RECURSIVE)
+ }
+ if err != nil {
+ return nil, fmt.Errorf("creating a detached procfs clone: %w", err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = procfsHandle.Close()
+ }
+ }()
+ if err := verifyProcRoot(procfsHandle); err != nil {
+ return nil, err
+ }
+ return procfsHandle, nil
+}
+
+func privateProcRoot() (*os.File, error) {
+ if !hasNewMountApi() {
+ return nil, fmt.Errorf("new mount api: %w", unix.ENOTSUP)
+ }
+ // Try to create a new procfs mount from scratch if we can. This ensures we
+ // can get a procfs mount even if /proc is fake (for whatever reason).
+ procRoot, err := newPrivateProcMount()
+ if err != nil || testingForcePrivateProcRootOpenTree(procRoot) {
+ // Try to clone /proc then...
+ procRoot, err = clonePrivateProcMount()
+ }
+ return procRoot, err
+}
+
+var (
+ procRootHandle *os.File
+ procRootError error
+ procRootOnce sync.Once
+
+ errUnsafeProcfs = errors.New("unsafe procfs detected")
+)
+
+func unsafeHostProcRoot() (_ *os.File, Err error) {
+ procRoot, err := os.OpenFile("/proc", unix.O_PATH|unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if Err != nil {
+ _ = procRoot.Close()
+ }
+ }()
+ if err := verifyProcRoot(procRoot); err != nil {
+ return nil, err
+ }
+ return procRoot, nil
+}
+
+func doGetProcRoot() (*os.File, error) {
+ procRoot, err := privateProcRoot()
+ if err != nil || testingForceGetProcRootUnsafe(procRoot) {
+ // Fall back to using a /proc handle if making a private mount failed.
+ // If we have openat2, at least we can avoid some kinds of over-mount
+ // attacks, but without openat2 there's not much we can do.
+ procRoot, err = unsafeHostProcRoot()
+ }
+ return procRoot, err
+}
+
+func getProcRoot() (*os.File, error) {
+ procRootOnce.Do(func() {
+ procRootHandle, procRootError = doGetProcRoot()
+ })
+ return procRootHandle, procRootError
+}
+
+var (
+ haveProcThreadSelf bool
+ haveProcThreadSelfOnce sync.Once
+)
+
+type procThreadSelfCloser func()
+
+// procThreadSelf returns a handle to /proc/thread-self/ (or an
+// equivalent handle on older kernels where /proc/thread-self doesn't exist).
+// Once finished with the handle, you must call the returned closer function
+// (runtime.UnlockOSThread). You must not pass the returned *os.File to other
+// Go threads or use the handle after calling the closer.
+//
+// This is similar to ProcThreadSelf from runc, but with extra hardening
+// applied and using *os.File.
+func procThreadSelf(procRoot *os.File, subpath string) (_ *os.File, _ procThreadSelfCloser, Err error) {
+ haveProcThreadSelfOnce.Do(func() {
+ // If the kernel doesn't support thread-self, it doesn't matter which
+ // /proc handle we use.
+ _, err := fstatatFile(procRoot, "thread-self", unix.AT_SYMLINK_NOFOLLOW)
+ haveProcThreadSelf = (err == nil)
+ })
+
+ // We need to lock our thread until the caller is done with the handle
+ // because between getting the handle and using it we could get interrupted
+ // by the Go runtime and hit the case where the underlying thread is
+ // swapped out and the original thread is killed, resulting in
+ // pull-your-hair-out-hard-to-debug issues in the caller.
+ runtime.LockOSThread()
+ defer func() {
+ if Err != nil {
+ runtime.UnlockOSThread()
+ }
+ }()
+
+ // Figure out what prefix we want to use.
+ threadSelf := "thread-self/"
+ if !haveProcThreadSelf || testingForceProcSelfTask() {
+ /// Pre-3.17 kernels don't have /proc/thread-self, so do it manually.
+ threadSelf = "self/task/" + strconv.Itoa(unix.Gettid()) + "/"
+ if _, err := fstatatFile(procRoot, threadSelf, unix.AT_SYMLINK_NOFOLLOW); err != nil || testingForceProcSelf() {
+ // In this case, we running in a pid namespace that doesn't match
+ // the /proc mount we have. This can happen inside runc.
+ //
+ // Unfortunately, there is no nice way to get the correct TID to
+ // use here because of the age of the kernel, so we have to just
+ // use /proc/self and hope that it works.
+ threadSelf = "self/"
+ }
+ }
+
+ // Grab the handle.
+ var (
+ handle *os.File
+ err error
+ )
+ if hasOpenat2() {
+ // We prefer being able to use RESOLVE_NO_XDEV if we can, to be
+ // absolutely sure we are operating on a clean /proc handle that
+ // doesn't have any cheeky overmounts that could trick us (including
+ // symlink mounts on top of /proc/thread-self). RESOLVE_BENEATH isn't
+ // stricly needed, but just use it since we have it.
+ //
+ // NOTE: /proc/self is technically a magic-link (the contents of the
+ // symlink are generated dynamically), but it doesn't use
+ // nd_jump_link() so RESOLVE_NO_MAGICLINKS allows it.
+ //
+ // NOTE: We MUST NOT use RESOLVE_IN_ROOT here, as openat2File uses
+ // procSelfFdReadlink to clean up the returned f.Name() if we use
+ // RESOLVE_IN_ROOT (which would lead to an infinite recursion).
+ handle, err = openat2File(procRoot, threadSelf+subpath, &unix.OpenHow{
+ Flags: unix.O_PATH | unix.O_CLOEXEC,
+ Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_MAGICLINKS,
+ })
+ if err != nil {
+ return nil, nil, fmt.Errorf("%w: %w", errUnsafeProcfs, err)
+ }
+ } else {
+ handle, err = openatFile(procRoot, threadSelf+subpath, unix.O_PATH|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return nil, nil, fmt.Errorf("%w: %w", errUnsafeProcfs, err)
+ }
+ defer func() {
+ if Err != nil {
+ _ = handle.Close()
+ }
+ }()
+ // We can't detect bind-mounts of different parts of procfs on top of
+ // /proc (a-la RESOLVE_NO_XDEV), but we can at least be sure that we
+ // aren't on the wrong filesystem here.
+ if statfs, err := fstatfs(handle); err != nil {
+ return nil, nil, err
+ } else if statfs.Type != procSuperMagic {
+ return nil, nil, fmt.Errorf("%w: incorrect /proc/self/fd filesystem type 0x%x", errUnsafeProcfs, statfs.Type)
+ }
+ }
+ return handle, runtime.UnlockOSThread, nil
+}
+
+var (
+ hasStatxMountIdBool bool
+ hasStatxMountIdOnce sync.Once
+)
+
+func hasStatxMountId() bool {
+ hasStatxMountIdOnce.Do(func() {
+ var (
+ stx unix.Statx_t
+ // We don't care which mount ID we get. The kernel will give us the
+ // unique one if it is supported.
+ wantStxMask uint32 = unix.STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID
+ )
+ err := unix.Statx(-int(unix.EBADF), "/", 0, int(wantStxMask), &stx)
+ hasStatxMountIdBool = (err == nil && (stx.Mask&wantStxMask != 0))
+ })
+ return hasStatxMountIdBool
+}
+
+func checkSymlinkOvermount(dir *os.File, path string) error {
+ // If we don't have statx(STATX_MNT_ID*) support, we can't do anything.
+ if !hasStatxMountId() {
+ return nil
+ }
+
+ var (
+ stx unix.Statx_t
+ // We don't care which mount ID we get. The kernel will give us the
+ // unique one if it is supported.
+ wantStxMask uint32 = unix.STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID
+ )
+
+ // Get the mntId of our procfs handle.
+ err := unix.Statx(int(dir.Fd()), "", unix.AT_EMPTY_PATH, int(wantStxMask), &stx)
+ if err != nil {
+ return &os.PathError{Op: "statx", Path: dir.Name(), Err: err}
+ }
+ if stx.Mask&wantStxMask == 0 {
+ // It's not a kernel limitation, for some reason we couldn't get a
+ // mount ID. Assume it's some kind of attack.
+ return fmt.Errorf("%w: could not get mnt id of dir %s", errUnsafeProcfs, dir.Name())
+ }
+ expectedMountId := stx.Mnt_id
+
+ // Get the mntId of the target symlink.
+ stx = unix.Statx_t{}
+ err = unix.Statx(int(dir.Fd()), path, unix.AT_SYMLINK_NOFOLLOW, int(wantStxMask), &stx)
+ if err != nil {
+ return &os.PathError{Op: "statx", Path: dir.Name() + "/" + path, Err: err}
+ }
+ if stx.Mask&wantStxMask == 0 {
+ // It's not a kernel limitation, for some reason we couldn't get a
+ // mount ID. Assume it's some kind of attack.
+ return fmt.Errorf("%w: could not get mnt id of symlink %s", errUnsafeProcfs, path)
+ }
+ gotMountId := stx.Mnt_id
+
+ // As long as the directory mount is alive, even with wrapping mount IDs,
+ // we would expect to see a different mount ID here. (Of course, if we're
+ // using unsafeHostProcRoot() then an attaker could change this after we
+ // did this check.)
+ if expectedMountId != gotMountId {
+ return fmt.Errorf("%w: symlink %s/%s has an overmount obscuring the real link (mount ids do not match %d != %d)", errUnsafeProcfs, dir.Name(), path, expectedMountId, gotMountId)
+ }
+ return nil
+}
+
+func doProcSelfMagiclink[T any](procRoot *os.File, subPath string, fn func(procDirHandle *os.File, base string) (T, error)) (T, error) {
+ // We cannot operate on the magic-link directly with a handle, we need to
+ // create a handle to the parent of the magic-link and then do
+ // single-component operations on it.
+ dir, base := filepath.Dir(subPath), filepath.Base(subPath)
+
+ procDirHandle, closer, err := procThreadSelf(procRoot, dir)
+ if err != nil {
+ return *new(T), fmt.Errorf("get safe /proc/thread-self/%s handle: %w", dir, err)
+ }
+ defer procDirHandle.Close()
+ defer closer()
+
+ // Try to detect if there is a mount on top of the symlink we are about to
+ // read. If we are using unsafeHostProcRoot(), this could change after we
+ // check it (and there's nothing we can do about that) but for
+ // privateProcRoot() this should be guaranteed to be safe (at least since
+ // Linux 5.12[1], when anonymous mount namespaces were completely isolated
+ // from external mounts including mount propagation events).
+ //
+ // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts
+ // onto targets that reside on shared mounts").
+ if err := checkSymlinkOvermount(procDirHandle, base); err != nil {
+ return *new(T), fmt.Errorf("check safety of %s proc magiclink: %w", subPath, err)
+ }
+ return fn(procDirHandle, base)
+}
+
+func doRawProcSelfFdReadlink(procRoot *os.File, fd int) (string, error) {
+ fdPath := fmt.Sprintf("fd/%d", fd)
+ return doProcSelfMagiclink(procRoot, fdPath, readlinkatFile)
+}
+
+func rawProcSelfFdReadlink(fd int) (string, error) {
+ procRoot, err := getProcRoot()
+ if err != nil {
+ return "", err
+ }
+ return doRawProcSelfFdReadlink(procRoot, fd)
+}
+
+func procSelfFdReadlink(f *os.File) (string, error) {
+ return rawProcSelfFdReadlink(int(f.Fd()))
+}
+
+var (
+ errPossibleBreakout = errors.New("possible breakout detected")
+ errInvalidDirectory = errors.New("wandered into deleted directory")
+ errDeletedInode = errors.New("cannot verify path of deleted inode")
+)
+
+func isDeadInode(file *os.File) error {
+ // If the nlink of a file drops to 0, there is an attacker deleting
+ // directories during our walk, which could result in weird /proc values.
+ // It's better to error out in this case.
+ stat, err := fstat(file)
+ if err != nil {
+ return fmt.Errorf("check for dead inode: %w", err)
+ }
+ if stat.Nlink == 0 {
+ err := errDeletedInode
+ if stat.Mode&unix.S_IFMT == unix.S_IFDIR {
+ err = errInvalidDirectory
+ }
+ return fmt.Errorf("%w %q", err, file.Name())
+ }
+ return nil
+}
+
+func getUmask() int {
+ // umask is a per-thread property, but it is inherited by children, so we
+ // need to lock our OS thread to make sure that no other goroutine runs in
+ // this thread and no goroutines are spawned from this thread until we
+ // revert to the old umask.
+ //
+ // We could parse /proc/self/status to avoid this get-set problem, but
+ // /proc/thread-self requires LockOSThread anyway, so there's no real
+ // benefit over just using umask(2).
+ runtime.LockOSThread()
+ umask := unix.Umask(0)
+ unix.Umask(umask)
+ runtime.UnlockOSThread()
+ return umask
+}
+
+func checkProcSelfFdPath(path string, file *os.File) error {
+ if err := isDeadInode(file); err != nil {
+ return err
+ }
+ actualPath, err := procSelfFdReadlink(file)
+ if err != nil {
+ return fmt.Errorf("get path of handle: %w", err)
+ }
+ if actualPath != path {
+ return fmt.Errorf("%w: handle path %q doesn't match expected path %q", errPossibleBreakout, actualPath, path)
+ }
+ return nil
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go b/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go
new file mode 100644
index 0000000..2a25d08
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go
@@ -0,0 +1,68 @@
+//go:build linux
+
+// Copyright (C) 2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import (
+ "os"
+ "testing"
+)
+
+type forceGetProcRootLevel int
+
+const (
+ forceGetProcRootDefault forceGetProcRootLevel = iota
+ forceGetProcRootOpenTree // force open_tree()
+ forceGetProcRootOpenTreeAtRecursive // force open_tree(AT_RECURSIVE)
+ forceGetProcRootUnsafe // force open()
+)
+
+var testingForceGetProcRoot *forceGetProcRootLevel
+
+func testingCheckClose(check bool, f *os.File) bool {
+ if check {
+ if f != nil {
+ _ = f.Close()
+ }
+ return true
+ }
+ return false
+}
+
+func testingForcePrivateProcRootOpenTree(f *os.File) bool {
+ return testing.Testing() && testingForceGetProcRoot != nil &&
+ testingCheckClose(*testingForceGetProcRoot >= forceGetProcRootOpenTree, f)
+}
+
+func testingForcePrivateProcRootOpenTreeAtRecursive(f *os.File) bool {
+ return testing.Testing() && testingForceGetProcRoot != nil &&
+ testingCheckClose(*testingForceGetProcRoot >= forceGetProcRootOpenTreeAtRecursive, f)
+}
+
+func testingForceGetProcRootUnsafe(f *os.File) bool {
+ return testing.Testing() && testingForceGetProcRoot != nil &&
+ testingCheckClose(*testingForceGetProcRoot >= forceGetProcRootUnsafe, f)
+}
+
+type forceProcThreadSelfLevel int
+
+const (
+ forceProcThreadSelfDefault forceProcThreadSelfLevel = iota
+ forceProcSelfTask
+ forceProcSelf
+)
+
+var testingForceProcThreadSelf *forceProcThreadSelfLevel
+
+func testingForceProcSelfTask() bool {
+ return testing.Testing() && testingForceProcThreadSelf != nil &&
+ *testingForceProcThreadSelf >= forceProcSelfTask
+}
+
+func testingForceProcSelf() bool {
+ return testing.Testing() && testingForceProcThreadSelf != nil &&
+ *testingForceProcThreadSelf >= forceProcSelf
+}
diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go
new file mode 100644
index 0000000..6e27c7d
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/vfs.go
@@ -0,0 +1,41 @@
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package securejoin
+
+import "os"
+
+// In future this should be moved into a separate package, because now there
+// are several projects (umoci and go-mtree) that are using this sort of
+// interface.
+
+// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is
+// equivalent to using the standard os.* family of functions. This is mainly
+// used for the purposes of mock testing, but also can be used to otherwise use
+// SecureJoin with VFS-like system.
+type VFS interface {
+ // Lstat returns a FileInfo describing the named file. If the file is a
+ // symbolic link, the returned FileInfo describes the symbolic link. Lstat
+ // makes no attempt to follow the link. These semantics are identical to
+ // os.Lstat.
+ Lstat(name string) (os.FileInfo, error)
+
+ // Readlink returns the destination of the named symbolic link. These
+ // semantics are identical to os.Readlink.
+ Readlink(name string) (string, error)
+}
+
+// osVFS is the "nil" VFS, in that it just passes everything through to the os
+// module.
+type osVFS struct{}
+
+// Lstat returns a FileInfo describing the named file. If the file is a
+// symbolic link, the returned FileInfo describes the symbolic link. Lstat
+// makes no attempt to follow the link. These semantics are identical to
+// os.Lstat.
+func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }
+
+// Readlink returns the destination of the named symbolic link. These
+// semantics are identical to os.Readlink.
+func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) }
diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE
new file mode 100644
index 0000000..bc52e96
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2012-2016 Dave Collins
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go
new file mode 100644
index 0000000..7929947
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go
@@ -0,0 +1,145 @@
+// Copyright (c) 2015-2016 Dave Collins
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when the code is not running on Google App Engine, compiled by GopherJS, and
+// "-tags safe" is not added to the go build command line. The "disableunsafe"
+// tag is deprecated and thus should not be used.
+// Go versions prior to 1.4 are disabled because they use a different layout
+// for interfaces which make the implementation of unsafeReflectValue more complex.
+// +build !js,!appengine,!safe,!disableunsafe,go1.4
+
+package spew
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+const (
+ // UnsafeDisabled is a build-time constant which specifies whether or
+ // not access to the unsafe package is available.
+ UnsafeDisabled = false
+
+ // ptrSize is the size of a pointer on the current arch.
+ ptrSize = unsafe.Sizeof((*byte)(nil))
+)
+
+type flag uintptr
+
+var (
+ // flagRO indicates whether the value field of a reflect.Value
+ // is read-only.
+ flagRO flag
+
+ // flagAddr indicates whether the address of the reflect.Value's
+ // value may be taken.
+ flagAddr flag
+)
+
+// flagKindMask holds the bits that make up the kind
+// part of the flags field. In all the supported versions,
+// it is in the lower 5 bits.
+const flagKindMask = flag(0x1f)
+
+// Different versions of Go have used different
+// bit layouts for the flags type. This table
+// records the known combinations.
+var okFlags = []struct {
+ ro, addr flag
+}{{
+ // From Go 1.4 to 1.5
+ ro: 1 << 5,
+ addr: 1 << 7,
+}, {
+ // Up to Go tip.
+ ro: 1<<5 | 1<<6,
+ addr: 1 << 8,
+}}
+
+var flagValOffset = func() uintptr {
+ field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
+ if !ok {
+ panic("reflect.Value has no flag field")
+ }
+ return field.Offset
+}()
+
+// flagField returns a pointer to the flag field of a reflect.Value.
+func flagField(v *reflect.Value) *flag {
+ return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
+}
+
+// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
+// the typical safety restrictions preventing access to unaddressable and
+// unexported data. It works by digging the raw pointer to the underlying
+// value out of the protected value and generating a new unprotected (unsafe)
+// reflect.Value to it.
+//
+// This allows us to check for implementations of the Stringer and error
+// interfaces to be used for pretty printing ordinarily unaddressable and
+// inaccessible values such as unexported struct fields.
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+ if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
+ return v
+ }
+ flagFieldPtr := flagField(&v)
+ *flagFieldPtr &^= flagRO
+ *flagFieldPtr |= flagAddr
+ return v
+}
+
+// Sanity checks against future reflect package changes
+// to the type or semantics of the Value.flag field.
+func init() {
+ field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
+ if !ok {
+ panic("reflect.Value has no flag field")
+ }
+ if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
+ panic("reflect.Value flag field has changed kind")
+ }
+ type t0 int
+ var t struct {
+ A t0
+ // t0 will have flagEmbedRO set.
+ t0
+ // a will have flagStickyRO set
+ a t0
+ }
+ vA := reflect.ValueOf(t).FieldByName("A")
+ va := reflect.ValueOf(t).FieldByName("a")
+ vt0 := reflect.ValueOf(t).FieldByName("t0")
+
+ // Infer flagRO from the difference between the flags
+ // for the (otherwise identical) fields in t.
+ flagPublic := *flagField(&vA)
+ flagWithRO := *flagField(&va) | *flagField(&vt0)
+ flagRO = flagPublic ^ flagWithRO
+
+ // Infer flagAddr from the difference between a value
+ // taken from a pointer and not.
+ vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
+ flagNoPtr := *flagField(&vA)
+ flagPtr := *flagField(&vPtrA)
+ flagAddr = flagNoPtr ^ flagPtr
+
+ // Check that the inferred flags tally with one of the known versions.
+ for _, f := range okFlags {
+ if flagRO == f.ro && flagAddr == f.addr {
+ return
+ }
+ }
+ panic("reflect.Value read-only flag has changed semantics")
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
new file mode 100644
index 0000000..205c28d
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
@@ -0,0 +1,38 @@
+// Copyright (c) 2015-2016 Dave Collins
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when the code is running on Google App Engine, compiled by GopherJS, or
+// "-tags safe" is added to the go build command line. The "disableunsafe"
+// tag is deprecated and thus should not be used.
+// +build js appengine safe disableunsafe !go1.4
+
+package spew
+
+import "reflect"
+
+const (
+ // UnsafeDisabled is a build-time constant which specifies whether or
+ // not access to the unsafe package is available.
+ UnsafeDisabled = true
+)
+
+// unsafeReflectValue typically converts the passed reflect.Value into a one
+// that bypasses the typical safety restrictions preventing access to
+// unaddressable and unexported data. However, doing this relies on access to
+// the unsafe package. This is a stub version which simply returns the passed
+// reflect.Value when the unsafe package is not available.
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+ return v
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go
new file mode 100644
index 0000000..1be8ce9
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/common.go
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+ "sort"
+ "strconv"
+)
+
+// Some constants in the form of bytes to avoid string overhead. This mirrors
+// the technique used in the fmt package.
+var (
+ panicBytes = []byte("(PANIC=")
+ plusBytes = []byte("+")
+ iBytes = []byte("i")
+ trueBytes = []byte("true")
+ falseBytes = []byte("false")
+ interfaceBytes = []byte("(interface {})")
+ commaNewlineBytes = []byte(",\n")
+ newlineBytes = []byte("\n")
+ openBraceBytes = []byte("{")
+ openBraceNewlineBytes = []byte("{\n")
+ closeBraceBytes = []byte("}")
+ asteriskBytes = []byte("*")
+ colonBytes = []byte(":")
+ colonSpaceBytes = []byte(": ")
+ openParenBytes = []byte("(")
+ closeParenBytes = []byte(")")
+ spaceBytes = []byte(" ")
+ pointerChainBytes = []byte("->")
+ nilAngleBytes = []byte("")
+ maxNewlineBytes = []byte("\n")
+ maxShortBytes = []byte("")
+ circularBytes = []byte("")
+ circularShortBytes = []byte("")
+ invalidAngleBytes = []byte("")
+ openBracketBytes = []byte("[")
+ closeBracketBytes = []byte("]")
+ percentBytes = []byte("%")
+ precisionBytes = []byte(".")
+ openAngleBytes = []byte("<")
+ closeAngleBytes = []byte(">")
+ openMapBytes = []byte("map[")
+ closeMapBytes = []byte("]")
+ lenEqualsBytes = []byte("len=")
+ capEqualsBytes = []byte("cap=")
+)
+
+// hexDigits is used to map a decimal value to a hex digit.
+var hexDigits = "0123456789abcdef"
+
+// catchPanic handles any panics that might occur during the handleMethods
+// calls.
+func catchPanic(w io.Writer, v reflect.Value) {
+ if err := recover(); err != nil {
+ w.Write(panicBytes)
+ fmt.Fprintf(w, "%v", err)
+ w.Write(closeParenBytes)
+ }
+}
+
+// handleMethods attempts to call the Error and String methods on the underlying
+// type the passed reflect.Value represents and outputes the result to Writer w.
+//
+// It handles panics in any called methods by catching and displaying the error
+// as the formatted value.
+func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
+ // We need an interface to check if the type implements the error or
+ // Stringer interface. However, the reflect package won't give us an
+ // interface on certain things like unexported struct fields in order
+ // to enforce visibility rules. We use unsafe, when it's available,
+ // to bypass these restrictions since this package does not mutate the
+ // values.
+ if !v.CanInterface() {
+ if UnsafeDisabled {
+ return false
+ }
+
+ v = unsafeReflectValue(v)
+ }
+
+ // Choose whether or not to do error and Stringer interface lookups against
+ // the base type or a pointer to the base type depending on settings.
+ // Technically calling one of these methods with a pointer receiver can
+ // mutate the value, however, types which choose to satisify an error or
+ // Stringer interface with a pointer receiver should not be mutating their
+ // state inside these interface methods.
+ if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
+ v = unsafeReflectValue(v)
+ }
+ if v.CanAddr() {
+ v = v.Addr()
+ }
+
+ // Is it an error or Stringer?
+ switch iface := v.Interface().(type) {
+ case error:
+ defer catchPanic(w, v)
+ if cs.ContinueOnMethod {
+ w.Write(openParenBytes)
+ w.Write([]byte(iface.Error()))
+ w.Write(closeParenBytes)
+ w.Write(spaceBytes)
+ return false
+ }
+
+ w.Write([]byte(iface.Error()))
+ return true
+
+ case fmt.Stringer:
+ defer catchPanic(w, v)
+ if cs.ContinueOnMethod {
+ w.Write(openParenBytes)
+ w.Write([]byte(iface.String()))
+ w.Write(closeParenBytes)
+ w.Write(spaceBytes)
+ return false
+ }
+ w.Write([]byte(iface.String()))
+ return true
+ }
+ return false
+}
+
+// printBool outputs a boolean value as true or false to Writer w.
+func printBool(w io.Writer, val bool) {
+ if val {
+ w.Write(trueBytes)
+ } else {
+ w.Write(falseBytes)
+ }
+}
+
+// printInt outputs a signed integer value to Writer w.
+func printInt(w io.Writer, val int64, base int) {
+ w.Write([]byte(strconv.FormatInt(val, base)))
+}
+
+// printUint outputs an unsigned integer value to Writer w.
+func printUint(w io.Writer, val uint64, base int) {
+ w.Write([]byte(strconv.FormatUint(val, base)))
+}
+
+// printFloat outputs a floating point value using the specified precision,
+// which is expected to be 32 or 64bit, to Writer w.
+func printFloat(w io.Writer, val float64, precision int) {
+ w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
+}
+
+// printComplex outputs a complex value using the specified float precision
+// for the real and imaginary parts to Writer w.
+func printComplex(w io.Writer, c complex128, floatPrecision int) {
+ r := real(c)
+ w.Write(openParenBytes)
+ w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
+ i := imag(c)
+ if i >= 0 {
+ w.Write(plusBytes)
+ }
+ w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
+ w.Write(iBytes)
+ w.Write(closeParenBytes)
+}
+
+// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
+// prefix to Writer w.
+func printHexPtr(w io.Writer, p uintptr) {
+ // Null pointer.
+ num := uint64(p)
+ if num == 0 {
+ w.Write(nilAngleBytes)
+ return
+ }
+
+ // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
+ buf := make([]byte, 18)
+
+ // It's simpler to construct the hex string right to left.
+ base := uint64(16)
+ i := len(buf) - 1
+ for num >= base {
+ buf[i] = hexDigits[num%base]
+ num /= base
+ i--
+ }
+ buf[i] = hexDigits[num]
+
+ // Add '0x' prefix.
+ i--
+ buf[i] = 'x'
+ i--
+ buf[i] = '0'
+
+ // Strip unused leading bytes.
+ buf = buf[i:]
+ w.Write(buf)
+}
+
+// valuesSorter implements sort.Interface to allow a slice of reflect.Value
+// elements to be sorted.
+type valuesSorter struct {
+ values []reflect.Value
+ strings []string // either nil or same len and values
+ cs *ConfigState
+}
+
+// newValuesSorter initializes a valuesSorter instance, which holds a set of
+// surrogate keys on which the data should be sorted. It uses flags in
+// ConfigState to decide if and how to populate those surrogate keys.
+func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
+ vs := &valuesSorter{values: values, cs: cs}
+ if canSortSimply(vs.values[0].Kind()) {
+ return vs
+ }
+ if !cs.DisableMethods {
+ vs.strings = make([]string, len(values))
+ for i := range vs.values {
+ b := bytes.Buffer{}
+ if !handleMethods(cs, &b, vs.values[i]) {
+ vs.strings = nil
+ break
+ }
+ vs.strings[i] = b.String()
+ }
+ }
+ if vs.strings == nil && cs.SpewKeys {
+ vs.strings = make([]string, len(values))
+ for i := range vs.values {
+ vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
+ }
+ }
+ return vs
+}
+
+// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
+// directly, or whether it should be considered for sorting by surrogate keys
+// (if the ConfigState allows it).
+func canSortSimply(kind reflect.Kind) bool {
+ // This switch parallels valueSortLess, except for the default case.
+ switch kind {
+ case reflect.Bool:
+ return true
+ case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+ return true
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+ return true
+ case reflect.Float32, reflect.Float64:
+ return true
+ case reflect.String:
+ return true
+ case reflect.Uintptr:
+ return true
+ case reflect.Array:
+ return true
+ }
+ return false
+}
+
+// Len returns the number of values in the slice. It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Len() int {
+ return len(s.values)
+}
+
+// Swap swaps the values at the passed indices. It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Swap(i, j int) {
+ s.values[i], s.values[j] = s.values[j], s.values[i]
+ if s.strings != nil {
+ s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
+ }
+}
+
+// valueSortLess returns whether the first value should sort before the second
+// value. It is used by valueSorter.Less as part of the sort.Interface
+// implementation.
+func valueSortLess(a, b reflect.Value) bool {
+ switch a.Kind() {
+ case reflect.Bool:
+ return !a.Bool() && b.Bool()
+ case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+ return a.Int() < b.Int()
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+ return a.Uint() < b.Uint()
+ case reflect.Float32, reflect.Float64:
+ return a.Float() < b.Float()
+ case reflect.String:
+ return a.String() < b.String()
+ case reflect.Uintptr:
+ return a.Uint() < b.Uint()
+ case reflect.Array:
+ // Compare the contents of both arrays.
+ l := a.Len()
+ for i := 0; i < l; i++ {
+ av := a.Index(i)
+ bv := b.Index(i)
+ if av.Interface() == bv.Interface() {
+ continue
+ }
+ return valueSortLess(av, bv)
+ }
+ }
+ return a.String() < b.String()
+}
+
+// Less returns whether the value at index i should sort before the
+// value at index j. It is part of the sort.Interface implementation.
+func (s *valuesSorter) Less(i, j int) bool {
+ if s.strings == nil {
+ return valueSortLess(s.values[i], s.values[j])
+ }
+ return s.strings[i] < s.strings[j]
+}
+
+// sortValues is a sort function that handles both native types and any type that
+// can be converted to error or Stringer. Other inputs are sorted according to
+// their Value.String() value to ensure display stability.
+func sortValues(values []reflect.Value, cs *ConfigState) {
+ if len(values) == 0 {
+ return
+ }
+ sort.Sort(newValuesSorter(values, cs))
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go
new file mode 100644
index 0000000..2e3d22f
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/config.go
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+)
+
+// ConfigState houses the configuration options used by spew to format and
+// display values. There is a global instance, Config, that is used to control
+// all top-level Formatter and Dump functionality. Each ConfigState instance
+// provides methods equivalent to the top-level functions.
+//
+// The zero value for ConfigState provides no indentation. You would typically
+// want to set it to a space or a tab.
+//
+// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
+// with default settings. See the documentation of NewDefaultConfig for default
+// values.
+type ConfigState struct {
+ // Indent specifies the string to use for each indentation level. The
+ // global config instance that all top-level functions use set this to a
+ // single space by default. If you would like more indentation, you might
+ // set this to a tab with "\t" or perhaps two spaces with " ".
+ Indent string
+
+ // MaxDepth controls the maximum number of levels to descend into nested
+ // data structures. The default, 0, means there is no limit.
+ //
+ // NOTE: Circular data structures are properly detected, so it is not
+ // necessary to set this value unless you specifically want to limit deeply
+ // nested data structures.
+ MaxDepth int
+
+ // DisableMethods specifies whether or not error and Stringer interfaces are
+ // invoked for types that implement them.
+ DisableMethods bool
+
+ // DisablePointerMethods specifies whether or not to check for and invoke
+ // error and Stringer interfaces on types which only accept a pointer
+ // receiver when the current type is not a pointer.
+ //
+ // NOTE: This might be an unsafe action since calling one of these methods
+ // with a pointer receiver could technically mutate the value, however,
+ // in practice, types which choose to satisify an error or Stringer
+ // interface with a pointer receiver should not be mutating their state
+ // inside these interface methods. As a result, this option relies on
+ // access to the unsafe package, so it will not have any effect when
+ // running in environments without access to the unsafe package such as
+ // Google App Engine or with the "safe" build tag specified.
+ DisablePointerMethods bool
+
+ // DisablePointerAddresses specifies whether to disable the printing of
+ // pointer addresses. This is useful when diffing data structures in tests.
+ DisablePointerAddresses bool
+
+ // DisableCapacities specifies whether to disable the printing of capacities
+ // for arrays, slices, maps and channels. This is useful when diffing
+ // data structures in tests.
+ DisableCapacities bool
+
+ // ContinueOnMethod specifies whether or not recursion should continue once
+ // a custom error or Stringer interface is invoked. The default, false,
+ // means it will print the results of invoking the custom error or Stringer
+ // interface and return immediately instead of continuing to recurse into
+ // the internals of the data type.
+ //
+ // NOTE: This flag does not have any effect if method invocation is disabled
+ // via the DisableMethods or DisablePointerMethods options.
+ ContinueOnMethod bool
+
+ // SortKeys specifies map keys should be sorted before being printed. Use
+ // this to have a more deterministic, diffable output. Note that only
+ // native types (bool, int, uint, floats, uintptr and string) and types
+ // that support the error or Stringer interfaces (if methods are
+ // enabled) are supported, with other types sorted according to the
+ // reflect.Value.String() output which guarantees display stability.
+ SortKeys bool
+
+ // SpewKeys specifies that, as a last resort attempt, map keys should
+ // be spewed to strings and sorted by those strings. This is only
+ // considered if SortKeys is true.
+ SpewKeys bool
+}
+
+// Config is the active configuration of the top-level functions.
+// The configuration can be changed by modifying the contents of spew.Config.
+var Config = ConfigState{Indent: " "}
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the formatted string as a value that satisfies error. See NewFormatter
+// for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
+ return fmt.Errorf(format, c.convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+ return fmt.Fprint(w, c.convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+ return fmt.Fprintf(w, format, c.convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a Formatter interface returned by c.NewFormatter. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+ return fmt.Fprintln(w, c.convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
+ return fmt.Print(c.convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
+ return fmt.Printf(format, c.convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
+ return fmt.Println(c.convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprint(a ...interface{}) string {
+ return fmt.Sprint(c.convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter. It returns
+// the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
+ return fmt.Sprintf(format, c.convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a Formatter interface returned by c.NewFormatter. It
+// returns the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintln(a ...interface{}) string {
+ return fmt.Sprintln(c.convertArgs(a)...)
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface. As a result, it integrates cleanly with standard fmt package
+printing functions. The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
+combinations. Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting. In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly. It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+c.Printf, c.Println, or c.Printf.
+*/
+func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
+ return newFormatter(c, v)
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w. It formats
+// exactly the same as Dump.
+func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
+ fdump(c, w, a...)
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value. It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+ * Pointers are dereferenced and followed
+ * Circular data structures are detected and handled properly
+ * Custom Stringer/error interfaces are optionally invoked, including
+ on unexported types
+ * Custom types which only implement the Stringer/error interfaces via
+ a pointer receiver are optionally invoked when passing non-pointer
+ variables
+ * Byte arrays and slices are dumped like the hexdump -C command which
+ includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by modifying the public members
+of c. See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func (c *ConfigState) Dump(a ...interface{}) {
+ fdump(c, os.Stdout, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func (c *ConfigState) Sdump(a ...interface{}) string {
+ var buf bytes.Buffer
+ fdump(c, &buf, a...)
+ return buf.String()
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a spew Formatter interface using
+// the ConfigState associated with s.
+func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
+ formatters = make([]interface{}, len(args))
+ for index, arg := range args {
+ formatters[index] = newFormatter(c, arg)
+ }
+ return formatters
+}
+
+// NewDefaultConfig returns a ConfigState with the following default settings.
+//
+// Indent: " "
+// MaxDepth: 0
+// DisableMethods: false
+// DisablePointerMethods: false
+// ContinueOnMethod: false
+// SortKeys: false
+func NewDefaultConfig() *ConfigState {
+ return &ConfigState{Indent: " "}
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go
new file mode 100644
index 0000000..aacaac6
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/doc.go
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Package spew implements a deep pretty printer for Go data structures to aid in
+debugging.
+
+A quick overview of the additional features spew provides over the built-in
+printing facilities for Go data types are as follows:
+
+ * Pointers are dereferenced and followed
+ * Circular data structures are detected and handled properly
+ * Custom Stringer/error interfaces are optionally invoked, including
+ on unexported types
+ * Custom types which only implement the Stringer/error interfaces via
+ a pointer receiver are optionally invoked when passing non-pointer
+ variables
+ * Byte arrays and slices are dumped like the hexdump -C command which
+ includes offsets, byte values in hex, and ASCII output (only when using
+ Dump style)
+
+There are two different approaches spew allows for dumping Go data structures:
+
+ * Dump style which prints with newlines, customizable indentation,
+ and additional debug information such as types and all pointer addresses
+ used to indirect to the final value
+ * A custom Formatter interface that integrates cleanly with the standard fmt
+ package and replaces %v, %+v, %#v, and %#+v to provide inline printing
+ similar to the default %v while providing the additional functionality
+ outlined above and passing unsupported format verbs such as %x and %q
+ along to fmt
+
+Quick Start
+
+This section demonstrates how to quickly get started with spew. See the
+sections below for further details on formatting and configuration options.
+
+To dump a variable with full newlines, indentation, type, and pointer
+information use Dump, Fdump, or Sdump:
+ spew.Dump(myVar1, myVar2, ...)
+ spew.Fdump(someWriter, myVar1, myVar2, ...)
+ str := spew.Sdump(myVar1, myVar2, ...)
+
+Alternatively, if you would prefer to use format strings with a compacted inline
+printing style, use the convenience wrappers Printf, Fprintf, etc with
+%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
+%#+v (adds types and pointer addresses):
+ spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+ spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+ spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+ spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+Configuration Options
+
+Configuration of spew is handled by fields in the ConfigState type. For
+convenience, all of the top-level functions use a global state available
+via the spew.Config global.
+
+It is also possible to create a ConfigState instance that provides methods
+equivalent to the top-level functions. This allows concurrent configuration
+options. See the ConfigState documentation for more details.
+
+The following configuration options are available:
+ * Indent
+ String to use for each indentation level for Dump functions.
+ It is a single space by default. A popular alternative is "\t".
+
+ * MaxDepth
+ Maximum number of levels to descend into nested data structures.
+ There is no limit by default.
+
+ * DisableMethods
+ Disables invocation of error and Stringer interface methods.
+ Method invocation is enabled by default.
+
+ * DisablePointerMethods
+ Disables invocation of error and Stringer interface methods on types
+ which only accept pointer receivers from non-pointer variables.
+ Pointer method invocation is enabled by default.
+
+ * DisablePointerAddresses
+ DisablePointerAddresses specifies whether to disable the printing of
+ pointer addresses. This is useful when diffing data structures in tests.
+
+ * DisableCapacities
+ DisableCapacities specifies whether to disable the printing of
+ capacities for arrays, slices, maps and channels. This is useful when
+ diffing data structures in tests.
+
+ * ContinueOnMethod
+ Enables recursion into types after invoking error and Stringer interface
+ methods. Recursion after method invocation is disabled by default.
+
+ * SortKeys
+ Specifies map keys should be sorted before being printed. Use
+ this to have a more deterministic, diffable output. Note that
+ only native types (bool, int, uint, floats, uintptr and string)
+ and types which implement error or Stringer interfaces are
+ supported with other types sorted according to the
+ reflect.Value.String() output which guarantees display
+ stability. Natural map order is used by default.
+
+ * SpewKeys
+ Specifies that, as a last resort attempt, map keys should be
+ spewed to strings and sorted by those strings. This is only
+ considered if SortKeys is true.
+
+Dump Usage
+
+Simply call spew.Dump with a list of variables you want to dump:
+
+ spew.Dump(myVar1, myVar2, ...)
+
+You may also call spew.Fdump if you would prefer to output to an arbitrary
+io.Writer. For example, to dump to standard error:
+
+ spew.Fdump(os.Stderr, myVar1, myVar2, ...)
+
+A third option is to call spew.Sdump to get the formatted output as a string:
+
+ str := spew.Sdump(myVar1, myVar2, ...)
+
+Sample Dump Output
+
+See the Dump example for details on the setup of the types and variables being
+shown here.
+
+ (main.Foo) {
+ unexportedField: (*main.Bar)(0xf84002e210)({
+ flag: (main.Flag) flagTwo,
+ data: (uintptr)
+ }),
+ ExportedField: (map[interface {}]interface {}) (len=1) {
+ (string) (len=3) "one": (bool) true
+ }
+ }
+
+Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
+command as shown.
+ ([]uint8) (len=32 cap=32) {
+ 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
+ 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
+ 00000020 31 32 |12|
+ }
+
+Custom Formatter
+
+Spew provides a custom formatter that implements the fmt.Formatter interface
+so that it integrates cleanly with standard fmt package printing functions. The
+formatter is useful for inline printing of smaller data types similar to the
+standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations. Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting. In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Custom Formatter Usage
+
+The simplest way to make use of the spew custom formatter is to call one of the
+convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
+functions have syntax you are most likely already familiar with:
+
+ spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+ spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+ spew.Println(myVar, myVar2)
+ spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+ spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+See the Index for the full list convenience functions.
+
+Sample Formatter Output
+
+Double pointer to a uint8:
+ %v: <**>5
+ %+v: <**>(0xf8400420d0->0xf8400420c8)5
+ %#v: (**uint8)5
+ %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
+
+Pointer to circular struct with a uint8 field and a pointer to itself:
+ %v: <*>{1 <*>}
+ %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)}
+ %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)}
+ %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)}
+
+See the Printf example for details on the setup of variables being shown
+here.
+
+Errors
+
+Since it is possible for custom Stringer/error interfaces to panic, spew
+detects them and handles them internally by printing the panic information
+inline with the output. Since spew is intended to provide deep pretty printing
+capabilities on structures, it intentionally does not return any errors.
+*/
+package spew
diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go
new file mode 100644
index 0000000..f78d89f
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/dump.go
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+ "bytes"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+var (
+ // uint8Type is a reflect.Type representing a uint8. It is used to
+ // convert cgo types to uint8 slices for hexdumping.
+ uint8Type = reflect.TypeOf(uint8(0))
+
+ // cCharRE is a regular expression that matches a cgo char.
+ // It is used to detect character arrays to hexdump them.
+ cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
+
+ // cUnsignedCharRE is a regular expression that matches a cgo unsigned
+ // char. It is used to detect unsigned character arrays to hexdump
+ // them.
+ cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
+
+ // cUint8tCharRE is a regular expression that matches a cgo uint8_t.
+ // It is used to detect uint8_t arrays to hexdump them.
+ cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
+)
+
+// dumpState contains information about the state of a dump operation.
+type dumpState struct {
+ w io.Writer
+ depth int
+ pointers map[uintptr]int
+ ignoreNextType bool
+ ignoreNextIndent bool
+ cs *ConfigState
+}
+
+// indent performs indentation according to the depth level and cs.Indent
+// option.
+func (d *dumpState) indent() {
+ if d.ignoreNextIndent {
+ d.ignoreNextIndent = false
+ return
+ }
+ d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
+ if v.Kind() == reflect.Interface && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v
+}
+
+// dumpPtr handles formatting of pointers by indirecting them as necessary.
+func (d *dumpState) dumpPtr(v reflect.Value) {
+ // Remove pointers at or below the current depth from map used to detect
+ // circular refs.
+ for k, depth := range d.pointers {
+ if depth >= d.depth {
+ delete(d.pointers, k)
+ }
+ }
+
+ // Keep list of all dereferenced pointers to show later.
+ pointerChain := make([]uintptr, 0)
+
+ // Figure out how many levels of indirection there are by dereferencing
+ // pointers and unpacking interfaces down the chain while detecting circular
+ // references.
+ nilFound := false
+ cycleFound := false
+ indirects := 0
+ ve := v
+ for ve.Kind() == reflect.Ptr {
+ if ve.IsNil() {
+ nilFound = true
+ break
+ }
+ indirects++
+ addr := ve.Pointer()
+ pointerChain = append(pointerChain, addr)
+ if pd, ok := d.pointers[addr]; ok && pd < d.depth {
+ cycleFound = true
+ indirects--
+ break
+ }
+ d.pointers[addr] = d.depth
+
+ ve = ve.Elem()
+ if ve.Kind() == reflect.Interface {
+ if ve.IsNil() {
+ nilFound = true
+ break
+ }
+ ve = ve.Elem()
+ }
+ }
+
+ // Display type information.
+ d.w.Write(openParenBytes)
+ d.w.Write(bytes.Repeat(asteriskBytes, indirects))
+ d.w.Write([]byte(ve.Type().String()))
+ d.w.Write(closeParenBytes)
+
+ // Display pointer information.
+ if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 {
+ d.w.Write(openParenBytes)
+ for i, addr := range pointerChain {
+ if i > 0 {
+ d.w.Write(pointerChainBytes)
+ }
+ printHexPtr(d.w, addr)
+ }
+ d.w.Write(closeParenBytes)
+ }
+
+ // Display dereferenced value.
+ d.w.Write(openParenBytes)
+ switch {
+ case nilFound:
+ d.w.Write(nilAngleBytes)
+
+ case cycleFound:
+ d.w.Write(circularBytes)
+
+ default:
+ d.ignoreNextType = true
+ d.dump(ve)
+ }
+ d.w.Write(closeParenBytes)
+}
+
+// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
+// reflection) arrays and slices are dumped in hexdump -C fashion.
+func (d *dumpState) dumpSlice(v reflect.Value) {
+ // Determine whether this type should be hex dumped or not. Also,
+ // for types which should be hexdumped, try to use the underlying data
+ // first, then fall back to trying to convert them to a uint8 slice.
+ var buf []uint8
+ doConvert := false
+ doHexDump := false
+ numEntries := v.Len()
+ if numEntries > 0 {
+ vt := v.Index(0).Type()
+ vts := vt.String()
+ switch {
+ // C types that need to be converted.
+ case cCharRE.MatchString(vts):
+ fallthrough
+ case cUnsignedCharRE.MatchString(vts):
+ fallthrough
+ case cUint8tCharRE.MatchString(vts):
+ doConvert = true
+
+ // Try to use existing uint8 slices and fall back to converting
+ // and copying if that fails.
+ case vt.Kind() == reflect.Uint8:
+ // We need an addressable interface to convert the type
+ // to a byte slice. However, the reflect package won't
+ // give us an interface on certain things like
+ // unexported struct fields in order to enforce
+ // visibility rules. We use unsafe, when available, to
+ // bypass these restrictions since this package does not
+ // mutate the values.
+ vs := v
+ if !vs.CanInterface() || !vs.CanAddr() {
+ vs = unsafeReflectValue(vs)
+ }
+ if !UnsafeDisabled {
+ vs = vs.Slice(0, numEntries)
+
+ // Use the existing uint8 slice if it can be
+ // type asserted.
+ iface := vs.Interface()
+ if slice, ok := iface.([]uint8); ok {
+ buf = slice
+ doHexDump = true
+ break
+ }
+ }
+
+ // The underlying data needs to be converted if it can't
+ // be type asserted to a uint8 slice.
+ doConvert = true
+ }
+
+ // Copy and convert the underlying type if needed.
+ if doConvert && vt.ConvertibleTo(uint8Type) {
+ // Convert and copy each element into a uint8 byte
+ // slice.
+ buf = make([]uint8, numEntries)
+ for i := 0; i < numEntries; i++ {
+ vv := v.Index(i)
+ buf[i] = uint8(vv.Convert(uint8Type).Uint())
+ }
+ doHexDump = true
+ }
+ }
+
+ // Hexdump the entire slice as needed.
+ if doHexDump {
+ indent := strings.Repeat(d.cs.Indent, d.depth)
+ str := indent + hex.Dump(buf)
+ str = strings.Replace(str, "\n", "\n"+indent, -1)
+ str = strings.TrimRight(str, d.cs.Indent)
+ d.w.Write([]byte(str))
+ return
+ }
+
+ // Recursively call dump for each item.
+ for i := 0; i < numEntries; i++ {
+ d.dump(d.unpackValue(v.Index(i)))
+ if i < (numEntries - 1) {
+ d.w.Write(commaNewlineBytes)
+ } else {
+ d.w.Write(newlineBytes)
+ }
+ }
+}
+
+// dump is the main workhorse for dumping a value. It uses the passed reflect
+// value to figure out what kind of object we are dealing with and formats it
+// appropriately. It is a recursive function, however circular data structures
+// are detected and handled properly.
+func (d *dumpState) dump(v reflect.Value) {
+ // Handle invalid reflect values immediately.
+ kind := v.Kind()
+ if kind == reflect.Invalid {
+ d.w.Write(invalidAngleBytes)
+ return
+ }
+
+ // Handle pointers specially.
+ if kind == reflect.Ptr {
+ d.indent()
+ d.dumpPtr(v)
+ return
+ }
+
+ // Print type information unless already handled elsewhere.
+ if !d.ignoreNextType {
+ d.indent()
+ d.w.Write(openParenBytes)
+ d.w.Write([]byte(v.Type().String()))
+ d.w.Write(closeParenBytes)
+ d.w.Write(spaceBytes)
+ }
+ d.ignoreNextType = false
+
+ // Display length and capacity if the built-in len and cap functions
+ // work with the value's kind and the len/cap itself is non-zero.
+ valueLen, valueCap := 0, 0
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice, reflect.Chan:
+ valueLen, valueCap = v.Len(), v.Cap()
+ case reflect.Map, reflect.String:
+ valueLen = v.Len()
+ }
+ if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {
+ d.w.Write(openParenBytes)
+ if valueLen != 0 {
+ d.w.Write(lenEqualsBytes)
+ printInt(d.w, int64(valueLen), 10)
+ }
+ if !d.cs.DisableCapacities && valueCap != 0 {
+ if valueLen != 0 {
+ d.w.Write(spaceBytes)
+ }
+ d.w.Write(capEqualsBytes)
+ printInt(d.w, int64(valueCap), 10)
+ }
+ d.w.Write(closeParenBytes)
+ d.w.Write(spaceBytes)
+ }
+
+ // Call Stringer/error interfaces if they exist and the handle methods flag
+ // is enabled
+ if !d.cs.DisableMethods {
+ if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+ if handled := handleMethods(d.cs, d.w, v); handled {
+ return
+ }
+ }
+ }
+
+ switch kind {
+ case reflect.Invalid:
+ // Do nothing. We should never get here since invalid has already
+ // been handled above.
+
+ case reflect.Bool:
+ printBool(d.w, v.Bool())
+
+ case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+ printInt(d.w, v.Int(), 10)
+
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+ printUint(d.w, v.Uint(), 10)
+
+ case reflect.Float32:
+ printFloat(d.w, v.Float(), 32)
+
+ case reflect.Float64:
+ printFloat(d.w, v.Float(), 64)
+
+ case reflect.Complex64:
+ printComplex(d.w, v.Complex(), 32)
+
+ case reflect.Complex128:
+ printComplex(d.w, v.Complex(), 64)
+
+ case reflect.Slice:
+ if v.IsNil() {
+ d.w.Write(nilAngleBytes)
+ break
+ }
+ fallthrough
+
+ case reflect.Array:
+ d.w.Write(openBraceNewlineBytes)
+ d.depth++
+ if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+ d.indent()
+ d.w.Write(maxNewlineBytes)
+ } else {
+ d.dumpSlice(v)
+ }
+ d.depth--
+ d.indent()
+ d.w.Write(closeBraceBytes)
+
+ case reflect.String:
+ d.w.Write([]byte(strconv.Quote(v.String())))
+
+ case reflect.Interface:
+ // The only time we should get here is for nil interfaces due to
+ // unpackValue calls.
+ if v.IsNil() {
+ d.w.Write(nilAngleBytes)
+ }
+
+ case reflect.Ptr:
+ // Do nothing. We should never get here since pointers have already
+ // been handled above.
+
+ case reflect.Map:
+ // nil maps should be indicated as different than empty maps
+ if v.IsNil() {
+ d.w.Write(nilAngleBytes)
+ break
+ }
+
+ d.w.Write(openBraceNewlineBytes)
+ d.depth++
+ if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+ d.indent()
+ d.w.Write(maxNewlineBytes)
+ } else {
+ numEntries := v.Len()
+ keys := v.MapKeys()
+ if d.cs.SortKeys {
+ sortValues(keys, d.cs)
+ }
+ for i, key := range keys {
+ d.dump(d.unpackValue(key))
+ d.w.Write(colonSpaceBytes)
+ d.ignoreNextIndent = true
+ d.dump(d.unpackValue(v.MapIndex(key)))
+ if i < (numEntries - 1) {
+ d.w.Write(commaNewlineBytes)
+ } else {
+ d.w.Write(newlineBytes)
+ }
+ }
+ }
+ d.depth--
+ d.indent()
+ d.w.Write(closeBraceBytes)
+
+ case reflect.Struct:
+ d.w.Write(openBraceNewlineBytes)
+ d.depth++
+ if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+ d.indent()
+ d.w.Write(maxNewlineBytes)
+ } else {
+ vt := v.Type()
+ numFields := v.NumField()
+ for i := 0; i < numFields; i++ {
+ d.indent()
+ vtf := vt.Field(i)
+ d.w.Write([]byte(vtf.Name))
+ d.w.Write(colonSpaceBytes)
+ d.ignoreNextIndent = true
+ d.dump(d.unpackValue(v.Field(i)))
+ if i < (numFields - 1) {
+ d.w.Write(commaNewlineBytes)
+ } else {
+ d.w.Write(newlineBytes)
+ }
+ }
+ }
+ d.depth--
+ d.indent()
+ d.w.Write(closeBraceBytes)
+
+ case reflect.Uintptr:
+ printHexPtr(d.w, uintptr(v.Uint()))
+
+ case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+ printHexPtr(d.w, v.Pointer())
+
+ // There were not any other types at the time this code was written, but
+ // fall back to letting the default fmt package handle it in case any new
+ // types are added.
+ default:
+ if v.CanInterface() {
+ fmt.Fprintf(d.w, "%v", v.Interface())
+ } else {
+ fmt.Fprintf(d.w, "%v", v.String())
+ }
+ }
+}
+
+// fdump is a helper function to consolidate the logic from the various public
+// methods which take varying writers and config states.
+func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
+ for _, arg := range a {
+ if arg == nil {
+ w.Write(interfaceBytes)
+ w.Write(spaceBytes)
+ w.Write(nilAngleBytes)
+ w.Write(newlineBytes)
+ continue
+ }
+
+ d := dumpState{w: w, cs: cs}
+ d.pointers = make(map[uintptr]int)
+ d.dump(reflect.ValueOf(arg))
+ d.w.Write(newlineBytes)
+ }
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w. It formats
+// exactly the same as Dump.
+func Fdump(w io.Writer, a ...interface{}) {
+ fdump(&Config, w, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func Sdump(a ...interface{}) string {
+ var buf bytes.Buffer
+ fdump(&Config, &buf, a...)
+ return buf.String()
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value. It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+ * Pointers are dereferenced and followed
+ * Circular data structures are detected and handled properly
+ * Custom Stringer/error interfaces are optionally invoked, including
+ on unexported types
+ * Custom types which only implement the Stringer/error interfaces via
+ a pointer receiver are optionally invoked when passing non-pointer
+ variables
+ * Byte arrays and slices are dumped like the hexdump -C command which
+ includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by an exported package global,
+spew.Config. See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func Dump(a ...interface{}) {
+ fdump(&Config, os.Stdout, a...)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go
new file mode 100644
index 0000000..b04edb7
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/format.go
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// supportedFlags is a list of all the character flags supported by fmt package.
+const supportedFlags = "0-+# "
+
+// formatState implements the fmt.Formatter interface and contains information
+// about the state of a formatting operation. The NewFormatter function can
+// be used to get a new Formatter which can be used directly as arguments
+// in standard fmt package printing calls.
+type formatState struct {
+ value interface{}
+ fs fmt.State
+ depth int
+ pointers map[uintptr]int
+ ignoreNextType bool
+ cs *ConfigState
+}
+
+// buildDefaultFormat recreates the original format string without precision
+// and width information to pass in to fmt.Sprintf in the case of an
+// unrecognized type. Unless new types are added to the language, this
+// function won't ever be called.
+func (f *formatState) buildDefaultFormat() (format string) {
+ buf := bytes.NewBuffer(percentBytes)
+
+ for _, flag := range supportedFlags {
+ if f.fs.Flag(int(flag)) {
+ buf.WriteRune(flag)
+ }
+ }
+
+ buf.WriteRune('v')
+
+ format = buf.String()
+ return format
+}
+
+// constructOrigFormat recreates the original format string including precision
+// and width information to pass along to the standard fmt package. This allows
+// automatic deferral of all format strings this package doesn't support.
+func (f *formatState) constructOrigFormat(verb rune) (format string) {
+ buf := bytes.NewBuffer(percentBytes)
+
+ for _, flag := range supportedFlags {
+ if f.fs.Flag(int(flag)) {
+ buf.WriteRune(flag)
+ }
+ }
+
+ if width, ok := f.fs.Width(); ok {
+ buf.WriteString(strconv.Itoa(width))
+ }
+
+ if precision, ok := f.fs.Precision(); ok {
+ buf.Write(precisionBytes)
+ buf.WriteString(strconv.Itoa(precision))
+ }
+
+ buf.WriteRune(verb)
+
+ format = buf.String()
+ return format
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible and
+// ensures that types for values which have been unpacked from an interface
+// are displayed when the show types flag is also set.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
+ if v.Kind() == reflect.Interface {
+ f.ignoreNextType = false
+ if !v.IsNil() {
+ v = v.Elem()
+ }
+ }
+ return v
+}
+
+// formatPtr handles formatting of pointers by indirecting them as necessary.
+func (f *formatState) formatPtr(v reflect.Value) {
+ // Display nil if top level pointer is nil.
+ showTypes := f.fs.Flag('#')
+ if v.IsNil() && (!showTypes || f.ignoreNextType) {
+ f.fs.Write(nilAngleBytes)
+ return
+ }
+
+ // Remove pointers at or below the current depth from map used to detect
+ // circular refs.
+ for k, depth := range f.pointers {
+ if depth >= f.depth {
+ delete(f.pointers, k)
+ }
+ }
+
+ // Keep list of all dereferenced pointers to possibly show later.
+ pointerChain := make([]uintptr, 0)
+
+ // Figure out how many levels of indirection there are by derferencing
+ // pointers and unpacking interfaces down the chain while detecting circular
+ // references.
+ nilFound := false
+ cycleFound := false
+ indirects := 0
+ ve := v
+ for ve.Kind() == reflect.Ptr {
+ if ve.IsNil() {
+ nilFound = true
+ break
+ }
+ indirects++
+ addr := ve.Pointer()
+ pointerChain = append(pointerChain, addr)
+ if pd, ok := f.pointers[addr]; ok && pd < f.depth {
+ cycleFound = true
+ indirects--
+ break
+ }
+ f.pointers[addr] = f.depth
+
+ ve = ve.Elem()
+ if ve.Kind() == reflect.Interface {
+ if ve.IsNil() {
+ nilFound = true
+ break
+ }
+ ve = ve.Elem()
+ }
+ }
+
+ // Display type or indirection level depending on flags.
+ if showTypes && !f.ignoreNextType {
+ f.fs.Write(openParenBytes)
+ f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
+ f.fs.Write([]byte(ve.Type().String()))
+ f.fs.Write(closeParenBytes)
+ } else {
+ if nilFound || cycleFound {
+ indirects += strings.Count(ve.Type().String(), "*")
+ }
+ f.fs.Write(openAngleBytes)
+ f.fs.Write([]byte(strings.Repeat("*", indirects)))
+ f.fs.Write(closeAngleBytes)
+ }
+
+ // Display pointer information depending on flags.
+ if f.fs.Flag('+') && (len(pointerChain) > 0) {
+ f.fs.Write(openParenBytes)
+ for i, addr := range pointerChain {
+ if i > 0 {
+ f.fs.Write(pointerChainBytes)
+ }
+ printHexPtr(f.fs, addr)
+ }
+ f.fs.Write(closeParenBytes)
+ }
+
+ // Display dereferenced value.
+ switch {
+ case nilFound:
+ f.fs.Write(nilAngleBytes)
+
+ case cycleFound:
+ f.fs.Write(circularShortBytes)
+
+ default:
+ f.ignoreNextType = true
+ f.format(ve)
+ }
+}
+
+// format is the main workhorse for providing the Formatter interface. It
+// uses the passed reflect value to figure out what kind of object we are
+// dealing with and formats it appropriately. It is a recursive function,
+// however circular data structures are detected and handled properly.
+func (f *formatState) format(v reflect.Value) {
+ // Handle invalid reflect values immediately.
+ kind := v.Kind()
+ if kind == reflect.Invalid {
+ f.fs.Write(invalidAngleBytes)
+ return
+ }
+
+ // Handle pointers specially.
+ if kind == reflect.Ptr {
+ f.formatPtr(v)
+ return
+ }
+
+ // Print type information unless already handled elsewhere.
+ if !f.ignoreNextType && f.fs.Flag('#') {
+ f.fs.Write(openParenBytes)
+ f.fs.Write([]byte(v.Type().String()))
+ f.fs.Write(closeParenBytes)
+ }
+ f.ignoreNextType = false
+
+ // Call Stringer/error interfaces if they exist and the handle methods
+ // flag is enabled.
+ if !f.cs.DisableMethods {
+ if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+ if handled := handleMethods(f.cs, f.fs, v); handled {
+ return
+ }
+ }
+ }
+
+ switch kind {
+ case reflect.Invalid:
+ // Do nothing. We should never get here since invalid has already
+ // been handled above.
+
+ case reflect.Bool:
+ printBool(f.fs, v.Bool())
+
+ case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+ printInt(f.fs, v.Int(), 10)
+
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+ printUint(f.fs, v.Uint(), 10)
+
+ case reflect.Float32:
+ printFloat(f.fs, v.Float(), 32)
+
+ case reflect.Float64:
+ printFloat(f.fs, v.Float(), 64)
+
+ case reflect.Complex64:
+ printComplex(f.fs, v.Complex(), 32)
+
+ case reflect.Complex128:
+ printComplex(f.fs, v.Complex(), 64)
+
+ case reflect.Slice:
+ if v.IsNil() {
+ f.fs.Write(nilAngleBytes)
+ break
+ }
+ fallthrough
+
+ case reflect.Array:
+ f.fs.Write(openBracketBytes)
+ f.depth++
+ if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+ f.fs.Write(maxShortBytes)
+ } else {
+ numEntries := v.Len()
+ for i := 0; i < numEntries; i++ {
+ if i > 0 {
+ f.fs.Write(spaceBytes)
+ }
+ f.ignoreNextType = true
+ f.format(f.unpackValue(v.Index(i)))
+ }
+ }
+ f.depth--
+ f.fs.Write(closeBracketBytes)
+
+ case reflect.String:
+ f.fs.Write([]byte(v.String()))
+
+ case reflect.Interface:
+ // The only time we should get here is for nil interfaces due to
+ // unpackValue calls.
+ if v.IsNil() {
+ f.fs.Write(nilAngleBytes)
+ }
+
+ case reflect.Ptr:
+ // Do nothing. We should never get here since pointers have already
+ // been handled above.
+
+ case reflect.Map:
+ // nil maps should be indicated as different than empty maps
+ if v.IsNil() {
+ f.fs.Write(nilAngleBytes)
+ break
+ }
+
+ f.fs.Write(openMapBytes)
+ f.depth++
+ if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+ f.fs.Write(maxShortBytes)
+ } else {
+ keys := v.MapKeys()
+ if f.cs.SortKeys {
+ sortValues(keys, f.cs)
+ }
+ for i, key := range keys {
+ if i > 0 {
+ f.fs.Write(spaceBytes)
+ }
+ f.ignoreNextType = true
+ f.format(f.unpackValue(key))
+ f.fs.Write(colonBytes)
+ f.ignoreNextType = true
+ f.format(f.unpackValue(v.MapIndex(key)))
+ }
+ }
+ f.depth--
+ f.fs.Write(closeMapBytes)
+
+ case reflect.Struct:
+ numFields := v.NumField()
+ f.fs.Write(openBraceBytes)
+ f.depth++
+ if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+ f.fs.Write(maxShortBytes)
+ } else {
+ vt := v.Type()
+ for i := 0; i < numFields; i++ {
+ if i > 0 {
+ f.fs.Write(spaceBytes)
+ }
+ vtf := vt.Field(i)
+ if f.fs.Flag('+') || f.fs.Flag('#') {
+ f.fs.Write([]byte(vtf.Name))
+ f.fs.Write(colonBytes)
+ }
+ f.format(f.unpackValue(v.Field(i)))
+ }
+ }
+ f.depth--
+ f.fs.Write(closeBraceBytes)
+
+ case reflect.Uintptr:
+ printHexPtr(f.fs, uintptr(v.Uint()))
+
+ case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+ printHexPtr(f.fs, v.Pointer())
+
+ // There were not any other types at the time this code was written, but
+ // fall back to letting the default fmt package handle it if any get added.
+ default:
+ format := f.buildDefaultFormat()
+ if v.CanInterface() {
+ fmt.Fprintf(f.fs, format, v.Interface())
+ } else {
+ fmt.Fprintf(f.fs, format, v.String())
+ }
+ }
+}
+
+// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
+// details.
+func (f *formatState) Format(fs fmt.State, verb rune) {
+ f.fs = fs
+
+ // Use standard formatting for verbs that are not v.
+ if verb != 'v' {
+ format := f.constructOrigFormat(verb)
+ fmt.Fprintf(fs, format, f.value)
+ return
+ }
+
+ if f.value == nil {
+ if fs.Flag('#') {
+ fs.Write(interfaceBytes)
+ }
+ fs.Write(nilAngleBytes)
+ return
+ }
+
+ f.format(reflect.ValueOf(f.value))
+}
+
+// newFormatter is a helper function to consolidate the logic from the various
+// public methods which take varying config states.
+func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
+ fs := &formatState{value: v, cs: cs}
+ fs.pointers = make(map[uintptr]int)
+ return fs
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface. As a result, it integrates cleanly with standard fmt package
+printing functions. The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations. Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting. In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly. It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+Printf, Println, or Fprintf.
+*/
+func NewFormatter(v interface{}) fmt.Formatter {
+ return newFormatter(&Config, v)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go
new file mode 100644
index 0000000..32c0e33
--- /dev/null
+++ b/vendor/github.com/davecgh/go-spew/spew/spew.go
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013-2016 Dave Collins
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+ "fmt"
+ "io"
+)
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the formatted string as a value that satisfies error. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Errorf(format string, a ...interface{}) (err error) {
+ return fmt.Errorf(format, convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+ return fmt.Fprint(w, convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+ return fmt.Fprintf(w, format, convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a default Formatter interface returned by NewFormatter. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+ return fmt.Fprintln(w, convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
+func Print(a ...interface{}) (n int, err error) {
+ return fmt.Print(convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Printf(format string, a ...interface{}) (n int, err error) {
+ return fmt.Printf(format, convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the number of bytes written and any write error encountered. See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
+func Println(a ...interface{}) (n int, err error) {
+ return fmt.Println(convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprint(a ...interface{}) string {
+ return fmt.Sprint(convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter. It
+// returns the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintf(format string, a ...interface{}) string {
+ return fmt.Sprintf(format, convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a default Formatter interface returned by NewFormatter. It
+// returns the resulting string. See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintln(a ...interface{}) string {
+ return fmt.Sprintln(convertArgs(a)...)
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a default spew Formatter interface.
+func convertArgs(args []interface{}) (formatters []interface{}) {
+ formatters = make([]interface{}, len(args))
+ for index, arg := range args {
+ formatters[index] = NewFormatter(arg)
+ }
+ return formatters
+}
diff --git a/vendor/github.com/distribution/reference/.gitattributes b/vendor/github.com/distribution/reference/.gitattributes
new file mode 100644
index 0000000..d207b18
--- /dev/null
+++ b/vendor/github.com/distribution/reference/.gitattributes
@@ -0,0 +1 @@
+*.go text eol=lf
diff --git a/vendor/github.com/distribution/reference/.gitignore b/vendor/github.com/distribution/reference/.gitignore
new file mode 100644
index 0000000..dc07e6b
--- /dev/null
+++ b/vendor/github.com/distribution/reference/.gitignore
@@ -0,0 +1,2 @@
+# Cover profiles
+*.out
diff --git a/vendor/github.com/distribution/reference/.golangci.yml b/vendor/github.com/distribution/reference/.golangci.yml
new file mode 100644
index 0000000..793f0bb
--- /dev/null
+++ b/vendor/github.com/distribution/reference/.golangci.yml
@@ -0,0 +1,18 @@
+linters:
+ enable:
+ - bodyclose
+ - dupword # Checks for duplicate words in the source code
+ - gofmt
+ - goimports
+ - ineffassign
+ - misspell
+ - revive
+ - staticcheck
+ - unconvert
+ - unused
+ - vet
+ disable:
+ - errcheck
+
+run:
+ deadline: 2m
diff --git a/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md b/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md
new file mode 100644
index 0000000..48f6704
--- /dev/null
+++ b/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md
@@ -0,0 +1,5 @@
+# Code of Conduct
+
+We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
+
+Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct.
diff --git a/vendor/github.com/distribution/reference/CONTRIBUTING.md b/vendor/github.com/distribution/reference/CONTRIBUTING.md
new file mode 100644
index 0000000..ab21946
--- /dev/null
+++ b/vendor/github.com/distribution/reference/CONTRIBUTING.md
@@ -0,0 +1,114 @@
+# Contributing to the reference library
+
+## Community help
+
+If you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack.
+[Click here for an invite to the CNCF community slack](https://slack.cncf.io/)
+
+## Reporting security issues
+
+The maintainers take security seriously. If you discover a security
+issue, please bring it to their attention right away!
+
+Please **DO NOT** file a public issue, instead send your report privately to
+[cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io).
+
+## Reporting an issue properly
+
+By following these simple rules you will get better and faster feedback on your issue.
+
+ - search the bugtracker for an already reported issue
+
+### If you found an issue that describes your problem:
+
+ - please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments
+ - please refrain from adding "same thing here" or "+1" comments
+ - you don't need to comment on an issue to get notified of updates: just hit the "subscribe" button
+ - comment if you have some new, technical and relevant information to add to the case
+ - __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue.
+
+### If you have not found an existing issue that describes your problem:
+
+ 1. create a new issue, with a succinct title that describes your issue:
+ - bad title: "It doesn't work with my docker"
+ - good title: "Private registry push fail: 400 error with E_INVALID_DIGEST"
+ 2. copy the output of (or similar for other container tools):
+ - `docker version`
+ - `docker info`
+ - `docker exec registry --version`
+ 3. copy the command line you used to launch your Registry
+ 4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments)
+ 5. reproduce your problem and get your docker daemon logs showing the error
+ 6. if relevant, copy your registry logs that show the error
+ 7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used)
+ 8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry
+
+## Contributing Code
+
+Contributions should be made via pull requests. Pull requests will be reviewed
+by one or more maintainers or reviewers and merged when acceptable.
+
+You should follow the basic GitHub workflow:
+
+ 1. Use your own [fork](https://help.github.com/en/articles/about-forks)
+ 2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
+ 3. Test your code
+ 4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages)
+ 5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
+
+Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
+for tips on creating a successful contribution.
+
+## Sign your work
+
+The sign-off is a simple line at the end of the explanation for the patch. Your
+signature certifies that you wrote the patch or otherwise have the right to pass
+it on as an open-source patch. The rules are pretty simple: if you can certify
+the below (from [developercertificate.org](http://developercertificate.org/)):
+
+```
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+660 York Street, Suite 102,
+San Francisco, CA 94110 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+Then you just add a line to every git commit message:
+
+ Signed-off-by: Joe Smith
+
+Use your real name (sorry, no pseudonyms or anonymous contributions.)
+
+If you set your `user.name` and `user.email` git configs, you can sign your
+commit automatically with `git commit -s`.
diff --git a/vendor/github.com/distribution/reference/GOVERNANCE.md b/vendor/github.com/distribution/reference/GOVERNANCE.md
new file mode 100644
index 0000000..200045b
--- /dev/null
+++ b/vendor/github.com/distribution/reference/GOVERNANCE.md
@@ -0,0 +1,144 @@
+# distribution/reference Project Governance
+
+Distribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here.
+
+For specific guidance on practical contribution steps please
+see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide.
+
+## Maintainership
+
+There are different types of maintainers, with different responsibilities, but
+all maintainers have 3 things in common:
+
+1) They share responsibility in the project's success.
+2) They have made a long-term, recurring time investment to improve the project.
+3) They spend that time doing whatever needs to be done, not necessarily what
+is the most interesting or fun.
+
+Maintainers are often under-appreciated, because their work is harder to appreciate.
+It's easy to appreciate a really cool and technically advanced feature. It's harder
+to appreciate the absence of bugs, the slow but steady improvement in stability,
+or the reliability of a release process. But those things distinguish a good
+project from a great one.
+
+## Reviewers
+
+A reviewer is a core role within the project.
+They share in reviewing issues and pull requests and their LGTM counts towards the
+required LGTM count to merge a code change into the project.
+
+Reviewers are part of the organization but do not have write access.
+Becoming a reviewer is a core aspect in the journey to becoming a maintainer.
+
+## Adding maintainers
+
+Maintainers are first and foremost contributors that have shown they are
+committed to the long term success of a project. Contributors wanting to become
+maintainers are expected to be deeply involved in contributing code, pull
+request review, and triage of issues in the project for more than three months.
+
+Just contributing does not make you a maintainer, it is about building trust
+with the current maintainers of the project and being a person that they can
+depend on and trust to make decisions in the best interest of the project.
+
+Periodically, the existing maintainers curate a list of contributors that have
+shown regular activity on the project over the prior months. From this list,
+maintainer candidates are selected and proposed in a pull request or a
+maintainers communication channel.
+
+After a candidate has been announced to the maintainers, the existing
+maintainers are given five business days to discuss the candidate, raise
+objections and cast their vote. Votes may take place on the communication
+channel or via pull request comment. Candidates must be approved by at least 66%
+of the current maintainers by adding their vote on the mailing list. The
+reviewer role has the same process but only requires 33% of current maintainers.
+Only maintainers of the repository that the candidate is proposed for are
+allowed to vote.
+
+If a candidate is approved, a maintainer will contact the candidate to invite
+the candidate to open a pull request that adds the contributor to the
+MAINTAINERS file. The voting process may take place inside a pull request if a
+maintainer has already discussed the candidacy with the candidate and a
+maintainer is willing to be a sponsor by opening the pull request. The candidate
+becomes a maintainer once the pull request is merged.
+
+## Stepping down policy
+
+Life priorities, interests, and passions can change. If you're a maintainer but
+feel you must remove yourself from the list, inform other maintainers that you
+intend to step down, and if possible, help find someone to pick up your work.
+At the very least, ensure your work can be continued where you left off.
+
+After you've informed other maintainers, create a pull request to remove
+yourself from the MAINTAINERS file.
+
+## Removal of inactive maintainers
+
+Similar to the procedure for adding new maintainers, existing maintainers can
+be removed from the list if they do not show significant activity on the
+project. Periodically, the maintainers review the list of maintainers and their
+activity over the last three months.
+
+If a maintainer has shown insufficient activity over this period, a neutral
+person will contact the maintainer to ask if they want to continue being
+a maintainer. If the maintainer decides to step down as a maintainer, they
+open a pull request to be removed from the MAINTAINERS file.
+
+If the maintainer wants to remain a maintainer, but is unable to perform the
+required duties they can be removed with a vote of at least 66% of the current
+maintainers. In this case, maintainers should first propose the change to
+maintainers via the maintainers communication channel, then open a pull request
+for voting. The voting period is five business days. The voting pull request
+should not come as a surpise to any maintainer and any discussion related to
+performance must not be discussed on the pull request.
+
+## How are decisions made?
+
+Docker distribution is an open-source project with an open design philosophy.
+This means that the repository is the source of truth for EVERY aspect of the
+project, including its philosophy, design, road map, and APIs. *If it's part of
+the project, it's in the repo. If it's in the repo, it's part of the project.*
+
+As a result, all decisions can be expressed as changes to the repository. An
+implementation change is a change to the source code. An API change is a change
+to the API specification. A philosophy change is a change to the philosophy
+manifesto, and so on.
+
+All decisions affecting distribution, big and small, follow the same 3 steps:
+
+* Step 1: Open a pull request. Anyone can do this.
+
+* Step 2: Discuss the pull request. Anyone can do this.
+
+* Step 3: Merge or refuse the pull request. Who does this depends on the nature
+of the pull request and which areas of the project it affects.
+
+## Helping contributors with the DCO
+
+The [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work)
+requirement is not intended as a roadblock or speed bump.
+
+Some contributors are not as familiar with `git`, or have used a web
+based editor, and thus asking them to `git commit --amend -s` is not the best
+way forward.
+
+In this case, maintainers can update the commits based on clause (c) of the DCO.
+The most trivial way for a contributor to allow the maintainer to do this, is to
+add a DCO signature in a pull requests's comment, or a maintainer can simply
+note that the change is sufficiently trivial that it does not substantially
+change the existing contribution - i.e., a spelling change.
+
+When you add someone's DCO, please also add your own to keep a log.
+
+## I'm a maintainer. Should I make pull requests too?
+
+Yes. Nobody should ever push to master directly. All changes should be
+made through a pull request.
+
+## Conflict Resolution
+
+If you have a technical dispute that you feel has reached an impasse with a
+subset of the community, any contributor may open an issue, specifically
+calling for a resolution vote of the current core maintainers to resolve the
+dispute. The same voting quorums required (2/3) for adding and removing
+maintainers will apply to conflict resolution.
diff --git a/vendor/github.com/distribution/reference/LICENSE b/vendor/github.com/distribution/reference/LICENSE
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/vendor/github.com/distribution/reference/LICENSE
@@ -0,0 +1,202 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/vendor/github.com/distribution/reference/MAINTAINERS b/vendor/github.com/distribution/reference/MAINTAINERS
new file mode 100644
index 0000000..9e0a60c
--- /dev/null
+++ b/vendor/github.com/distribution/reference/MAINTAINERS
@@ -0,0 +1,26 @@
+# Distribution project maintainers & reviewers
+#
+# See GOVERNANCE.md for maintainer versus reviewer roles
+#
+# MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io)
+# GitHub ID, Name, Email address
+"chrispat","Chris Patterson","chrispat@github.com"
+"clarkbw","Bryan Clark","clarkbw@github.com"
+"corhere","Cory Snider","csnider@mirantis.com"
+"deleteriousEffect","Hayley Swimelar","hswimelar@gitlab.com"
+"heww","He Weiwei","hweiwei@vmware.com"
+"joaodrp","João Pereira","jpereira@gitlab.com"
+"justincormack","Justin Cormack","justin.cormack@docker.com"
+"squizzi","Kyle Squizzato","ksquizzato@mirantis.com"
+"milosgajdos","Milos Gajdos","milosthegajdos@gmail.com"
+"sargun","Sargun Dhillon","sargun@sargun.me"
+"wy65701436","Wang Yan","wangyan@vmware.com"
+"stevelasker","Steve Lasker","steve.lasker@microsoft.com"
+#
+# REVIEWERS
+# GitHub ID, Name, Email address
+"dmcgowan","Derek McGowan","derek@mcgstyle.net"
+"stevvooe","Stephen Day","stevvooe@gmail.com"
+"thajeztah","Sebastiaan van Stijn","github@gone.nl"
+"DavidSpek", "David van der Spek", "vanderspek.david@gmail.com"
+"Jamstah", "James Hewitt", "james.hewitt@gmail.com"
diff --git a/vendor/github.com/distribution/reference/Makefile b/vendor/github.com/distribution/reference/Makefile
new file mode 100644
index 0000000..c78576b
--- /dev/null
+++ b/vendor/github.com/distribution/reference/Makefile
@@ -0,0 +1,25 @@
+# Project packages.
+PACKAGES=$(shell go list ./...)
+
+# Flags passed to `go test`
+BUILDFLAGS ?=
+TESTFLAGS ?=
+
+.PHONY: all build test coverage
+.DEFAULT: all
+
+all: build
+
+build: ## no binaries to build, so just check compilation suceeds
+ go build ${BUILDFLAGS} ./...
+
+test: ## run tests
+ go test ${TESTFLAGS} ./...
+
+coverage: ## generate coverprofiles from the unit tests
+ rm -f coverage.txt
+ go test ${TESTFLAGS} -cover -coverprofile=cover.out ./...
+
+.PHONY: help
+help:
+ @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_\/%-]+:.*?##/ { printf " \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
diff --git a/vendor/github.com/distribution/reference/README.md b/vendor/github.com/distribution/reference/README.md
new file mode 100644
index 0000000..e2531e4
--- /dev/null
+++ b/vendor/github.com/distribution/reference/README.md
@@ -0,0 +1,30 @@
+# Distribution reference
+
+Go library to handle references to container images.
+
+
+
+[](https://github.com/distribution/reference/actions?query=workflow%3ACI)
+[](https://pkg.go.dev/github.com/distribution/reference)
+[](LICENSE)
+[](https://codecov.io/gh/distribution/reference)
+[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield)
+
+This repository contains a library for handling refrences to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details.
+
+## Contribution
+
+Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute
+issues, fixes, and patches to this project.
+
+## Communication
+
+For async communication and long running discussions please use issues and pull requests on the github repo.
+This will be the best place to discuss design and implementation.
+
+For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/)
+that everyone is welcome to join and chat about development.
+
+## Licenses
+
+The distribution codebase is released under the [Apache 2.0 license](LICENSE).
diff --git a/vendor/github.com/distribution/reference/SECURITY.md b/vendor/github.com/distribution/reference/SECURITY.md
new file mode 100644
index 0000000..aaf983c
--- /dev/null
+++ b/vendor/github.com/distribution/reference/SECURITY.md
@@ -0,0 +1,7 @@
+# Security Policy
+
+## Reporting a Vulnerability
+
+The maintainers take security seriously. If you discover a security issue, please bring it to their attention right away!
+
+Please DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io.
diff --git a/vendor/github.com/distribution/reference/distribution-logo.svg b/vendor/github.com/distribution/reference/distribution-logo.svg
new file mode 100644
index 0000000..cc9f407
--- /dev/null
+++ b/vendor/github.com/distribution/reference/distribution-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/distribution/reference/helpers.go b/vendor/github.com/distribution/reference/helpers.go
new file mode 100644
index 0000000..d10c7ef
--- /dev/null
+++ b/vendor/github.com/distribution/reference/helpers.go
@@ -0,0 +1,42 @@
+package reference
+
+import "path"
+
+// IsNameOnly returns true if reference only contains a repo name.
+func IsNameOnly(ref Named) bool {
+ if _, ok := ref.(NamedTagged); ok {
+ return false
+ }
+ if _, ok := ref.(Canonical); ok {
+ return false
+ }
+ return true
+}
+
+// FamiliarName returns the familiar name string
+// for the given named, familiarizing if needed.
+func FamiliarName(ref Named) string {
+ if nn, ok := ref.(normalizedNamed); ok {
+ return nn.Familiar().Name()
+ }
+ return ref.Name()
+}
+
+// FamiliarString returns the familiar string representation
+// for the given reference, familiarizing if needed.
+func FamiliarString(ref Reference) string {
+ if nn, ok := ref.(normalizedNamed); ok {
+ return nn.Familiar().String()
+ }
+ return ref.String()
+}
+
+// FamiliarMatch reports whether ref matches the specified pattern.
+// See [path.Match] for supported patterns.
+func FamiliarMatch(pattern string, ref Reference) (bool, error) {
+ matched, err := path.Match(pattern, FamiliarString(ref))
+ if namedRef, isNamed := ref.(Named); isNamed && !matched {
+ matched, _ = path.Match(pattern, FamiliarName(namedRef))
+ }
+ return matched, err
+}
diff --git a/vendor/github.com/distribution/reference/normalize.go b/vendor/github.com/distribution/reference/normalize.go
new file mode 100644
index 0000000..a30229d
--- /dev/null
+++ b/vendor/github.com/distribution/reference/normalize.go
@@ -0,0 +1,224 @@
+package reference
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/opencontainers/go-digest"
+)
+
+const (
+ // legacyDefaultDomain is the legacy domain for Docker Hub (which was
+ // originally named "the Docker Index"). This domain is still used for
+ // authentication and image search, which were part of the "v1" Docker
+ // registry specification.
+ //
+ // This domain will continue to be supported, but there are plans to consolidate
+ // legacy domains to new "canonical" domains. Once those domains are decided
+ // on, we must update the normalization functions, but preserve compatibility
+ // with existing installs, clients, and user configuration.
+ legacyDefaultDomain = "index.docker.io"
+
+ // defaultDomain is the default domain used for images on Docker Hub.
+ // It is used to normalize "familiar" names to canonical names, for example,
+ // to convert "ubuntu" to "docker.io/library/ubuntu:latest".
+ //
+ // Note that actual domain of Docker Hub's registry is registry-1.docker.io.
+ // This domain will continue to be supported, but there are plans to consolidate
+ // legacy domains to new "canonical" domains. Once those domains are decided
+ // on, we must update the normalization functions, but preserve compatibility
+ // with existing installs, clients, and user configuration.
+ defaultDomain = "docker.io"
+
+ // officialRepoPrefix is the namespace used for official images on Docker Hub.
+ // It is used to normalize "familiar" names to canonical names, for example,
+ // to convert "ubuntu" to "docker.io/library/ubuntu:latest".
+ officialRepoPrefix = "library/"
+
+ // defaultTag is the default tag if no tag is provided.
+ defaultTag = "latest"
+)
+
+// normalizedNamed represents a name which has been
+// normalized and has a familiar form. A familiar name
+// is what is used in Docker UI. An example normalized
+// name is "docker.io/library/ubuntu" and corresponding
+// familiar name of "ubuntu".
+type normalizedNamed interface {
+ Named
+ Familiar() Named
+}
+
+// ParseNormalizedNamed parses a string into a named reference
+// transforming a familiar name from Docker UI to a fully
+// qualified reference. If the value may be an identifier
+// use ParseAnyReference.
+func ParseNormalizedNamed(s string) (Named, error) {
+ if ok := anchoredIdentifierRegexp.MatchString(s); ok {
+ return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
+ }
+ domain, remainder := splitDockerDomain(s)
+ var remote string
+ if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
+ remote = remainder[:tagSep]
+ } else {
+ remote = remainder
+ }
+ if strings.ToLower(remote) != remote {
+ return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote)
+ }
+
+ ref, err := Parse(domain + "/" + remainder)
+ if err != nil {
+ return nil, err
+ }
+ named, isNamed := ref.(Named)
+ if !isNamed {
+ return nil, fmt.Errorf("reference %s has no name", ref.String())
+ }
+ return named, nil
+}
+
+// namedTaggedDigested is a reference that has both a tag and a digest.
+type namedTaggedDigested interface {
+ NamedTagged
+ Digested
+}
+
+// ParseDockerRef normalizes the image reference following the docker convention,
+// which allows for references to contain both a tag and a digest. It returns a
+// reference that is either tagged or digested. For references containing both
+// a tag and a digest, it returns a digested reference. For example, the following
+// reference:
+//
+// docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
+//
+// Is returned as a digested reference (with the ":latest" tag removed):
+//
+// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
+//
+// References that are already "tagged" or "digested" are returned unmodified:
+//
+// // Already a digested reference
+// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
+//
+// // Already a named reference
+// docker.io/library/busybox:latest
+func ParseDockerRef(ref string) (Named, error) {
+ named, err := ParseNormalizedNamed(ref)
+ if err != nil {
+ return nil, err
+ }
+ if canonical, ok := named.(namedTaggedDigested); ok {
+ // The reference is both tagged and digested; only return digested.
+ newNamed, err := WithName(canonical.Name())
+ if err != nil {
+ return nil, err
+ }
+ return WithDigest(newNamed, canonical.Digest())
+ }
+ return TagNameOnly(named), nil
+}
+
+// splitDockerDomain splits a repository name to domain and remote-name.
+// If no valid domain is found, the default domain is used. Repository name
+// needs to be already validated before.
+func splitDockerDomain(name string) (domain, remainder string) {
+ i := strings.IndexRune(name, '/')
+ if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) {
+ domain, remainder = defaultDomain, name
+ } else {
+ domain, remainder = name[:i], name[i+1:]
+ }
+ if domain == legacyDefaultDomain {
+ domain = defaultDomain
+ }
+ if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
+ remainder = officialRepoPrefix + remainder
+ }
+ return
+}
+
+// familiarizeName returns a shortened version of the name familiar
+// to the Docker UI. Familiar names have the default domain
+// "docker.io" and "library/" repository prefix removed.
+// For example, "docker.io/library/redis" will have the familiar
+// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
+// Returns a familiarized named only reference.
+func familiarizeName(named namedRepository) repository {
+ repo := repository{
+ domain: named.Domain(),
+ path: named.Path(),
+ }
+
+ if repo.domain == defaultDomain {
+ repo.domain = ""
+ // Handle official repositories which have the pattern "library/"
+ if strings.HasPrefix(repo.path, officialRepoPrefix) {
+ // TODO(thaJeztah): this check may be too strict, as it assumes the
+ // "library/" namespace does not have nested namespaces. While this
+ // is true (currently), technically it would be possible for Docker
+ // Hub to use those (e.g. "library/distros/ubuntu:latest").
+ // See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.
+ if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') {
+ repo.path = remainder
+ }
+ }
+ }
+ return repo
+}
+
+func (r reference) Familiar() Named {
+ return reference{
+ namedRepository: familiarizeName(r.namedRepository),
+ tag: r.tag,
+ digest: r.digest,
+ }
+}
+
+func (r repository) Familiar() Named {
+ return familiarizeName(r)
+}
+
+func (t taggedReference) Familiar() Named {
+ return taggedReference{
+ namedRepository: familiarizeName(t.namedRepository),
+ tag: t.tag,
+ }
+}
+
+func (c canonicalReference) Familiar() Named {
+ return canonicalReference{
+ namedRepository: familiarizeName(c.namedRepository),
+ digest: c.digest,
+ }
+}
+
+// TagNameOnly adds the default tag "latest" to a reference if it only has
+// a repo name.
+func TagNameOnly(ref Named) Named {
+ if IsNameOnly(ref) {
+ namedTagged, err := WithTag(ref, defaultTag)
+ if err != nil {
+ // Default tag must be valid, to create a NamedTagged
+ // type with non-validated input the WithTag function
+ // should be used instead
+ panic(err)
+ }
+ return namedTagged
+ }
+ return ref
+}
+
+// ParseAnyReference parses a reference string as a possible identifier,
+// full digest, or familiar name.
+func ParseAnyReference(ref string) (Reference, error) {
+ if ok := anchoredIdentifierRegexp.MatchString(ref); ok {
+ return digestReference("sha256:" + ref), nil
+ }
+ if dgst, err := digest.Parse(ref); err == nil {
+ return digestReference(dgst), nil
+ }
+
+ return ParseNormalizedNamed(ref)
+}
diff --git a/vendor/github.com/distribution/reference/reference.go b/vendor/github.com/distribution/reference/reference.go
new file mode 100644
index 0000000..e98c44d
--- /dev/null
+++ b/vendor/github.com/distribution/reference/reference.go
@@ -0,0 +1,436 @@
+// Package reference provides a general type to represent any way of referencing images within the registry.
+// Its main purpose is to abstract tags and digests (content-addressable hash).
+//
+// Grammar
+//
+// reference := name [ ":" tag ] [ "@" digest ]
+// name := [domain '/'] remote-name
+// domain := host [':' port-number]
+// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A
+// domain-name := domain-component ['.' domain-component]*
+// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
+// port-number := /[0-9]+/
+// path-component := alpha-numeric [separator alpha-numeric]*
+// path (or "remote-name") := path-component ['/' path-component]*
+// alpha-numeric := /[a-z0-9]+/
+// separator := /[_.]|__|[-]*/
+//
+// tag := /[\w][\w.-]{0,127}/
+//
+// digest := digest-algorithm ":" digest-hex
+// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
+// digest-algorithm-separator := /[+.-_]/
+// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
+// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
+//
+// identifier := /[a-f0-9]{64}/
+package reference
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/opencontainers/go-digest"
+)
+
+const (
+ // NameTotalLengthMax is the maximum total number of characters in a repository name.
+ NameTotalLengthMax = 255
+)
+
+var (
+ // ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
+ ErrReferenceInvalidFormat = errors.New("invalid reference format")
+
+ // ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
+ ErrTagInvalidFormat = errors.New("invalid tag format")
+
+ // ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
+ ErrDigestInvalidFormat = errors.New("invalid digest format")
+
+ // ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
+ ErrNameContainsUppercase = errors.New("repository name must be lowercase")
+
+ // ErrNameEmpty is returned for empty, invalid repository names.
+ ErrNameEmpty = errors.New("repository name must have at least one component")
+
+ // ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
+ ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
+
+ // ErrNameNotCanonical is returned when a name is not canonical.
+ ErrNameNotCanonical = errors.New("repository name must be canonical")
+)
+
+// Reference is an opaque object reference identifier that may include
+// modifiers such as a hostname, name, tag, and digest.
+type Reference interface {
+ // String returns the full reference
+ String() string
+}
+
+// Field provides a wrapper type for resolving correct reference types when
+// working with encoding.
+type Field struct {
+ reference Reference
+}
+
+// AsField wraps a reference in a Field for encoding.
+func AsField(reference Reference) Field {
+ return Field{reference}
+}
+
+// Reference unwraps the reference type from the field to
+// return the Reference object. This object should be
+// of the appropriate type to further check for different
+// reference types.
+func (f Field) Reference() Reference {
+ return f.reference
+}
+
+// MarshalText serializes the field to byte text which
+// is the string of the reference.
+func (f Field) MarshalText() (p []byte, err error) {
+ return []byte(f.reference.String()), nil
+}
+
+// UnmarshalText parses text bytes by invoking the
+// reference parser to ensure the appropriately
+// typed reference object is wrapped by field.
+func (f *Field) UnmarshalText(p []byte) error {
+ r, err := Parse(string(p))
+ if err != nil {
+ return err
+ }
+
+ f.reference = r
+ return nil
+}
+
+// Named is an object with a full name
+type Named interface {
+ Reference
+ Name() string
+}
+
+// Tagged is an object which has a tag
+type Tagged interface {
+ Reference
+ Tag() string
+}
+
+// NamedTagged is an object including a name and tag.
+type NamedTagged interface {
+ Named
+ Tag() string
+}
+
+// Digested is an object which has a digest
+// in which it can be referenced by
+type Digested interface {
+ Reference
+ Digest() digest.Digest
+}
+
+// Canonical reference is an object with a fully unique
+// name including a name with domain and digest
+type Canonical interface {
+ Named
+ Digest() digest.Digest
+}
+
+// namedRepository is a reference to a repository with a name.
+// A namedRepository has both domain and path components.
+type namedRepository interface {
+ Named
+ Domain() string
+ Path() string
+}
+
+// Domain returns the domain part of the [Named] reference.
+func Domain(named Named) string {
+ if r, ok := named.(namedRepository); ok {
+ return r.Domain()
+ }
+ domain, _ := splitDomain(named.Name())
+ return domain
+}
+
+// Path returns the name without the domain part of the [Named] reference.
+func Path(named Named) (name string) {
+ if r, ok := named.(namedRepository); ok {
+ return r.Path()
+ }
+ _, path := splitDomain(named.Name())
+ return path
+}
+
+func splitDomain(name string) (string, string) {
+ match := anchoredNameRegexp.FindStringSubmatch(name)
+ if len(match) != 3 {
+ return "", name
+ }
+ return match[1], match[2]
+}
+
+// SplitHostname splits a named reference into a
+// hostname and name string. If no valid hostname is
+// found, the hostname is empty and the full value
+// is returned as name
+//
+// Deprecated: Use [Domain] or [Path].
+func SplitHostname(named Named) (string, string) {
+ if r, ok := named.(namedRepository); ok {
+ return r.Domain(), r.Path()
+ }
+ return splitDomain(named.Name())
+}
+
+// Parse parses s and returns a syntactically valid Reference.
+// If an error was encountered it is returned, along with a nil Reference.
+func Parse(s string) (Reference, error) {
+ matches := ReferenceRegexp.FindStringSubmatch(s)
+ if matches == nil {
+ if s == "" {
+ return nil, ErrNameEmpty
+ }
+ if ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {
+ return nil, ErrNameContainsUppercase
+ }
+ return nil, ErrReferenceInvalidFormat
+ }
+
+ if len(matches[1]) > NameTotalLengthMax {
+ return nil, ErrNameTooLong
+ }
+
+ var repo repository
+
+ nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
+ if len(nameMatch) == 3 {
+ repo.domain = nameMatch[1]
+ repo.path = nameMatch[2]
+ } else {
+ repo.domain = ""
+ repo.path = matches[1]
+ }
+
+ ref := reference{
+ namedRepository: repo,
+ tag: matches[2],
+ }
+ if matches[3] != "" {
+ var err error
+ ref.digest, err = digest.Parse(matches[3])
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ r := getBestReferenceType(ref)
+ if r == nil {
+ return nil, ErrNameEmpty
+ }
+
+ return r, nil
+}
+
+// ParseNamed parses s and returns a syntactically valid reference implementing
+// the Named interface. The reference must have a name and be in the canonical
+// form, otherwise an error is returned.
+// If an error was encountered it is returned, along with a nil Reference.
+func ParseNamed(s string) (Named, error) {
+ named, err := ParseNormalizedNamed(s)
+ if err != nil {
+ return nil, err
+ }
+ if named.String() != s {
+ return nil, ErrNameNotCanonical
+ }
+ return named, nil
+}
+
+// WithName returns a named object representing the given string. If the input
+// is invalid ErrReferenceInvalidFormat will be returned.
+func WithName(name string) (Named, error) {
+ if len(name) > NameTotalLengthMax {
+ return nil, ErrNameTooLong
+ }
+
+ match := anchoredNameRegexp.FindStringSubmatch(name)
+ if match == nil || len(match) != 3 {
+ return nil, ErrReferenceInvalidFormat
+ }
+ return repository{
+ domain: match[1],
+ path: match[2],
+ }, nil
+}
+
+// WithTag combines the name from "name" and the tag from "tag" to form a
+// reference incorporating both the name and the tag.
+func WithTag(name Named, tag string) (NamedTagged, error) {
+ if !anchoredTagRegexp.MatchString(tag) {
+ return nil, ErrTagInvalidFormat
+ }
+ var repo repository
+ if r, ok := name.(namedRepository); ok {
+ repo.domain = r.Domain()
+ repo.path = r.Path()
+ } else {
+ repo.path = name.Name()
+ }
+ if canonical, ok := name.(Canonical); ok {
+ return reference{
+ namedRepository: repo,
+ tag: tag,
+ digest: canonical.Digest(),
+ }, nil
+ }
+ return taggedReference{
+ namedRepository: repo,
+ tag: tag,
+ }, nil
+}
+
+// WithDigest combines the name from "name" and the digest from "digest" to form
+// a reference incorporating both the name and the digest.
+func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
+ if !anchoredDigestRegexp.MatchString(digest.String()) {
+ return nil, ErrDigestInvalidFormat
+ }
+ var repo repository
+ if r, ok := name.(namedRepository); ok {
+ repo.domain = r.Domain()
+ repo.path = r.Path()
+ } else {
+ repo.path = name.Name()
+ }
+ if tagged, ok := name.(Tagged); ok {
+ return reference{
+ namedRepository: repo,
+ tag: tagged.Tag(),
+ digest: digest,
+ }, nil
+ }
+ return canonicalReference{
+ namedRepository: repo,
+ digest: digest,
+ }, nil
+}
+
+// TrimNamed removes any tag or digest from the named reference.
+func TrimNamed(ref Named) Named {
+ repo := repository{}
+ if r, ok := ref.(namedRepository); ok {
+ repo.domain, repo.path = r.Domain(), r.Path()
+ } else {
+ repo.domain, repo.path = splitDomain(ref.Name())
+ }
+ return repo
+}
+
+func getBestReferenceType(ref reference) Reference {
+ if ref.Name() == "" {
+ // Allow digest only references
+ if ref.digest != "" {
+ return digestReference(ref.digest)
+ }
+ return nil
+ }
+ if ref.tag == "" {
+ if ref.digest != "" {
+ return canonicalReference{
+ namedRepository: ref.namedRepository,
+ digest: ref.digest,
+ }
+ }
+ return ref.namedRepository
+ }
+ if ref.digest == "" {
+ return taggedReference{
+ namedRepository: ref.namedRepository,
+ tag: ref.tag,
+ }
+ }
+
+ return ref
+}
+
+type reference struct {
+ namedRepository
+ tag string
+ digest digest.Digest
+}
+
+func (r reference) String() string {
+ return r.Name() + ":" + r.tag + "@" + r.digest.String()
+}
+
+func (r reference) Tag() string {
+ return r.tag
+}
+
+func (r reference) Digest() digest.Digest {
+ return r.digest
+}
+
+type repository struct {
+ domain string
+ path string
+}
+
+func (r repository) String() string {
+ return r.Name()
+}
+
+func (r repository) Name() string {
+ if r.domain == "" {
+ return r.path
+ }
+ return r.domain + "/" + r.path
+}
+
+func (r repository) Domain() string {
+ return r.domain
+}
+
+func (r repository) Path() string {
+ return r.path
+}
+
+type digestReference digest.Digest
+
+func (d digestReference) String() string {
+ return digest.Digest(d).String()
+}
+
+func (d digestReference) Digest() digest.Digest {
+ return digest.Digest(d)
+}
+
+type taggedReference struct {
+ namedRepository
+ tag string
+}
+
+func (t taggedReference) String() string {
+ return t.Name() + ":" + t.tag
+}
+
+func (t taggedReference) Tag() string {
+ return t.tag
+}
+
+type canonicalReference struct {
+ namedRepository
+ digest digest.Digest
+}
+
+func (c canonicalReference) String() string {
+ return c.Name() + "@" + c.digest.String()
+}
+
+func (c canonicalReference) Digest() digest.Digest {
+ return c.digest
+}
diff --git a/vendor/github.com/distribution/reference/regexp.go b/vendor/github.com/distribution/reference/regexp.go
new file mode 100644
index 0000000..65bc49d
--- /dev/null
+++ b/vendor/github.com/distribution/reference/regexp.go
@@ -0,0 +1,163 @@
+package reference
+
+import (
+ "regexp"
+ "strings"
+)
+
+// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:").
+var DigestRegexp = regexp.MustCompile(digestPat)
+
+// DomainRegexp matches hostname or IP-addresses, optionally including a port
+// number. It defines the structure of potential domain components that may be
+// part of image names. This is purposely a subset of what is allowed by DNS to
+// ensure backwards compatibility with Docker image names. It may be a subset of
+// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
+// square brackets (excluding zone identifiers as defined by [RFC 6874] or special
+// addresses such as IPv4-Mapped).
+//
+// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
+var DomainRegexp = regexp.MustCompile(domainAndPort)
+
+// IdentifierRegexp is the format for string identifier used as a
+// content addressable identifier using sha256. These identifiers
+// are like digests without the algorithm, since sha256 is used.
+var IdentifierRegexp = regexp.MustCompile(identifier)
+
+// NameRegexp is the format for the name component of references, including
+// an optional domain and port, but without tag or digest suffix.
+var NameRegexp = regexp.MustCompile(namePat)
+
+// ReferenceRegexp is the full supported format of a reference. The regexp
+// is anchored and has capturing groups for name, tag, and digest
+// components.
+var ReferenceRegexp = regexp.MustCompile(referencePat)
+
+// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
+//
+// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
+var TagRegexp = regexp.MustCompile(tag)
+
+const (
+ // alphanumeric defines the alphanumeric atom, typically a
+ // component of names. This only allows lower case characters and digits.
+ alphanumeric = `[a-z0-9]+`
+
+ // separator defines the separators allowed to be embedded in name
+ // components. This allows one period, one or two underscore and multiple
+ // dashes. Repeated dashes and underscores are intentionally treated
+ // differently. In order to support valid hostnames as name components,
+ // supporting repeated dash was added. Additionally double underscore is
+ // now allowed as a separator to loosen the restriction for previously
+ // supported names.
+ separator = `(?:[._]|__|[-]+)`
+
+ // localhost is treated as a special value for domain-name. Any other
+ // domain-name without a "." or a ":port" are considered a path component.
+ localhost = `localhost`
+
+ // domainNameComponent restricts the registry domain component of a
+ // repository name to start with a component as defined by DomainRegexp.
+ domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`
+
+ // optionalPort matches an optional port-number including the port separator
+ // (e.g. ":80").
+ optionalPort = `(?::[0-9]+)?`
+
+ // tag matches valid tag names. From docker/docker:graph/tags.go.
+ tag = `[\w][\w.-]{0,127}`
+
+ // digestPat matches well-formed digests, including algorithm (e.g. "sha256:").
+ //
+ // TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp
+ // so that go-digest defines the canonical format. Note that the go-digest is
+ // more relaxed:
+ // - it allows multiple algorithms (e.g. "sha256+b64:") to allow
+ // future expansion of supported algorithms.
+ // - it allows the "" value to use urlsafe base64 encoding as defined
+ // in [rfc4648, section 5].
+ //
+ // [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.
+ digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`
+
+ // identifier is the format for a content addressable identifier using sha256.
+ // These identifiers are like digests without the algorithm, since sha256 is used.
+ identifier = `([a-f0-9]{64})`
+
+ // ipv6address are enclosed between square brackets and may be represented
+ // in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format
+ // are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as
+ // IPv4-Mapped are deliberately excluded.
+ ipv6address = `\[(?:[a-fA-F0-9:]+)\]`
+)
+
+var (
+ // domainName defines the structure of potential domain components
+ // that may be part of image names. This is purposely a subset of what is
+ // allowed by DNS to ensure backwards compatibility with Docker image
+ // names. This includes IPv4 addresses on decimal format.
+ domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent)
+
+ // host defines the structure of potential domains based on the URI
+ // Host subcomponent on rfc3986. It may be a subset of DNS domain name,
+ // or an IPv4 address in decimal format, or an IPv6 address between square
+ // brackets (excluding zone identifiers as defined by rfc6874 or special
+ // addresses such as IPv4-Mapped).
+ host = `(?:` + domainName + `|` + ipv6address + `)`
+
+ // allowed by the URI Host subcomponent on rfc3986 to ensure backwards
+ // compatibility with Docker image names.
+ domainAndPort = host + optionalPort
+
+ // anchoredTagRegexp matches valid tag names, anchored at the start and
+ // end of the matched string.
+ anchoredTagRegexp = regexp.MustCompile(anchored(tag))
+
+ // anchoredDigestRegexp matches valid digests, anchored at the start and
+ // end of the matched string.
+ anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat))
+
+ // pathComponent restricts path-components to start with an alphanumeric
+ // character, with following parts able to be separated by a separator
+ // (one period, one or two underscore and multiple dashes).
+ pathComponent = alphanumeric + anyTimes(separator+alphanumeric)
+
+ // remoteName matches the remote-name of a repository. It consists of one
+ // or more forward slash (/) delimited path-components:
+ //
+ // pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
+ remoteName = pathComponent + anyTimes(`/`+pathComponent)
+ namePat = optional(domainAndPort+`/`) + remoteName
+
+ // anchoredNameRegexp is used to parse a name value, capturing the
+ // domain and trailing components.
+ anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))
+
+ referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))
+
+ // anchoredIdentifierRegexp is used to check or match an
+ // identifier value, anchored at start and end of string.
+ anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier))
+)
+
+// optional wraps the expression in a non-capturing group and makes the
+// production optional.
+func optional(res ...string) string {
+ return `(?:` + strings.Join(res, "") + `)?`
+}
+
+// anyTimes wraps the expression in a non-capturing group that can occur
+// any number of times.
+func anyTimes(res ...string) string {
+ return `(?:` + strings.Join(res, "") + `)*`
+}
+
+// capture wraps the expression in a capturing group.
+func capture(res ...string) string {
+ return `(` + strings.Join(res, "") + `)`
+}
+
+// anchored anchors the regular expression by adding start and end delimiters.
+func anchored(res ...string) string {
+ return `^` + strings.Join(res, "") + `$`
+}
diff --git a/vendor/github.com/distribution/reference/sort.go b/vendor/github.com/distribution/reference/sort.go
new file mode 100644
index 0000000..416c37b
--- /dev/null
+++ b/vendor/github.com/distribution/reference/sort.go
@@ -0,0 +1,75 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package reference
+
+import (
+ "sort"
+)
+
+// Sort sorts string references preferring higher information references.
+//
+// The precedence is as follows:
+//
+// 1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:")
+// 2. [Named] + [Tagged] (e.g., "docker.io/library/busybox:latest")
+// 3. [Named] + [Digested] (e.g., "docker.io/library/busybo@sha256:")
+// 4. [Named] (e.g., "docker.io/library/busybox")
+// 5. [Digested] (e.g., "docker.io@sha256:")
+// 6. Parse error
+func Sort(references []string) []string {
+ var prefs []Reference
+ var bad []string
+
+ for _, ref := range references {
+ pref, err := ParseAnyReference(ref)
+ if err != nil {
+ bad = append(bad, ref)
+ } else {
+ prefs = append(prefs, pref)
+ }
+ }
+ sort.Slice(prefs, func(a, b int) bool {
+ ar := refRank(prefs[a])
+ br := refRank(prefs[b])
+ if ar == br {
+ return prefs[a].String() < prefs[b].String()
+ }
+ return ar < br
+ })
+ sort.Strings(bad)
+ var refs []string
+ for _, pref := range prefs {
+ refs = append(refs, pref.String())
+ }
+ return append(refs, bad...)
+}
+
+func refRank(ref Reference) uint8 {
+ if _, ok := ref.(Named); ok {
+ if _, ok = ref.(Tagged); ok {
+ if _, ok = ref.(Digested); ok {
+ return 1
+ }
+ return 2
+ }
+ if _, ok = ref.(Digested); ok {
+ return 3
+ }
+ return 4
+ }
+ return 5
+}
diff --git a/vendor/github.com/docker/cli/AUTHORS b/vendor/github.com/docker/cli/AUTHORS
new file mode 100644
index 0000000..d6d23b3
--- /dev/null
+++ b/vendor/github.com/docker/cli/AUTHORS
@@ -0,0 +1,890 @@
+# File @generated by scripts/docs/generate-authors.sh. DO NOT EDIT.
+# This file lists all contributors to the repository.
+# See scripts/docs/generate-authors.sh to make modifications.
+
+A. Lester Buck III
+Aanand Prasad
+Aaron L. Xu
+Aaron Lehmann
+Aaron.L.Xu
+Abdur Rehman
+Abhinandan Prativadi
+Abin Shahab
+Abreto FU
+Ace Tang
+Addam Hardy
+Adolfo Ochagavía
+Adrian Plata
+Adrien Duermael
+Adrien Folie
+Adyanth Hosavalike
+Ahmet Alp Balkan
+Aidan Feldman
+Aidan Hobson Sayers
+AJ Bowen
+Akhil Mohan
+Akihiro Suda
+Akim Demaille
+Alan Thompson
+Albert Callarisa
+Alberto Roura
+Albin Kerouanton
+Aleksa Sarai
+Aleksander Piotrowski
+Alessandro Boch
+Alex Couture-Beil
+Alex Mavrogiannis
+Alex Mayer
+Alexander Boyd
+Alexander Chneerov
+Alexander Larsson
+Alexander Morozov
+Alexander Ryabov
+Alexandre González
+Alexey Igrychev
+Alexis Couvreur
+Alfred Landrum
+Ali Rostami
+Alicia Lauerman
+Allen Sun
+Alvin Deng
+Amen Belayneh
+Amey Shrivastava <72866602+AmeyShrivastava@users.noreply.github.com>
+Amir Goldstein
+Amit Krishnan
+Amit Shukla
+Amy Lindburg
+Anca Iordache
+Anda Xu
+Andrea Luzzardi
+Andreas Köhler
+Andres G. Aragoneses
+Andres Leon Rangel
+Andrew France
+Andrew Hsu
+Andrew Macpherson
+Andrew McDonnell
+Andrew Po
+Andrey Petrov
+Andrii Berehuliak
+André Martins
+Andy Goldstein
+Andy Rothfusz
+Anil Madhavapeddy
+Ankush Agarwal
+Anne Henmi
+Anton Polonskiy
+Antonio Murdaca
+Antonis Kalipetis
+Anusha Ragunathan
+Ao Li
+Arash Deshmeh
+Arko Dasgupta
+Arnaud Porterie
+Arnaud Rebillout
+Arthur Peka
+Ashly Mathew
+Ashwini Oruganti
+Aslam Ahemad
+Azat Khuyiyakhmetov
+Bardia Keyoumarsi
+Barnaby Gray
+Bastiaan Bakker
+BastianHofmann
+Ben Bodenmiller
+Ben Bonnefoy
+Ben Creasy
+Ben Firshman
+Benjamin Boudreau
+Benjamin Böhmke
+Benjamin Nater
+Benoit Sigoure
+Bhumika Bayani
+Bill Wang
+Bin Liu
+Bingshen Wang
+Bishal Das
+Bjorn Neergaard
+Boaz Shuster
+Boban Acimovic
+Bogdan Anton
+Boris Pruessmann
+Brad Baker
+Bradley Cicenas
+Brandon Mitchell
+Brandon Philips
+Brent Salisbury
+Bret Fisher
+Brian (bex) Exelbierd
+Brian Goff
+Brian Tracy
+Brian Wieder
+Bruno Sousa
+Bryan Bess
+Bryan Boreham
+Bryan Murphy
+bryfry
+Cameron Spear
+Cao Weiwei
+Carlo Mion
+Carlos Alexandro Becker
+Carlos de Paula
+Ce Gao
+Cedric Davies
+Cezar Sa Espinola
+Chad Faragher
+Chao Wang
+Charles Chan
+Charles Law
+Charles Smith
+Charlie Drage
+Charlotte Mach
+ChaYoung You
+Chee Hau Lim
+Chen Chuanliang
+Chen Hanxiao
+Chen Mingjie
+Chen Qiu
+Chris Chinchilla
+Chris Couzens
+Chris Gavin
+Chris Gibson
+Chris McKinnel
+Chris Snow
+Chris Vermilion
+Chris Weyl
+Christian Persson
+Christian Stefanescu
+Christophe Robin
+Christophe Vidal
+Christopher Biscardi
+Christopher Crone
+Christopher Jones
+Christopher Svensson
+Christy Norman
+Chun Chen
+Clinton Kitson
+Coenraad Loubser
+Colin Hebert
+Collin Guarino
+Colm Hally
+Comical Derskeal <27731088+derskeal@users.noreply.github.com>
+Conner Crosby
+Corey Farrell
+Corey Quon
+Cory Bennet
+Cory Snider
+Craig Osterhout
+Craig Wilhite
+Cristian Staretu
+Daehyeok Mun
+Dafydd Crosby
+Daisuke Ito
+dalanlan
+Damien Nadé
+Dan Cotora
+Danial Gharib
+Daniel Artine
+Daniel Cassidy
+Daniel Dao
+Daniel Farrell
+Daniel Gasienica
+Daniel Goosen
+Daniel Helfand
+Daniel Hiltgen
+Daniel J Walsh
+Daniel Nephin
+Daniel Norberg
+Daniel Watkins
+Daniel Zhang
+Daniil Nikolenko
+Danny Berger
+Darren Shepherd
+Darren Stahl
+Dattatraya Kumbhar
+Dave Goodchild
+Dave Henderson
+Dave Tucker
+David Alvarez
+David Beitey
+David Calavera
+David Cramer
+David Dooling
+David Gageot
+David Karlsson
+David Lechner
+David Scott
+David Sheets
+David Williamson
+David Xia
+David Young
+Deng Guangxing
+Denis Defreyne