RTG-1339 Support post-quantum hybrid key exchange
Func spec: https://wiki.cfops.it/x/ZcBKHw
This commit is contained in:
parent
3e0ff3a771
commit
11cbff4ff7
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
mathRand "math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -220,6 +221,19 @@ func prepareTunnelConfig(
|
||||||
)
|
)
|
||||||
|
|
||||||
transportProtocol := c.String("protocol")
|
transportProtocol := c.String("protocol")
|
||||||
|
|
||||||
|
needPQ := c.Bool("post-quantum")
|
||||||
|
if needPQ {
|
||||||
|
if FipsEnabled {
|
||||||
|
return nil, nil, fmt.Errorf("post-quantum not supported in FIPS mode")
|
||||||
|
}
|
||||||
|
// Error if the user tries to force a non-quic transport protocol
|
||||||
|
if transportProtocol != connection.AutoSelectFlag && transportProtocol != connection.QUIC.String() {
|
||||||
|
return nil, nil, fmt.Errorf("post-quantum is only supported with the quic transport")
|
||||||
|
}
|
||||||
|
transportProtocol = connection.QUIC.String()
|
||||||
|
}
|
||||||
|
|
||||||
protocolFetcher := edgediscovery.ProtocolPercentage
|
protocolFetcher := edgediscovery.ProtocolPercentage
|
||||||
|
|
||||||
cfg := config.GetConfiguration()
|
cfg := config.GetConfiguration()
|
||||||
|
@ -230,6 +244,9 @@ func prepareTunnelConfig(
|
||||||
}
|
}
|
||||||
log.Info().Msgf("Generated Connector ID: %s", clientUUID)
|
log.Info().Msgf("Generated Connector ID: %s", clientUUID)
|
||||||
features := append(c.StringSlice("features"), defaultFeatures...)
|
features := append(c.StringSlice("features"), defaultFeatures...)
|
||||||
|
if needPQ {
|
||||||
|
features = append(features, supervisor.FeaturePostQuantum)
|
||||||
|
}
|
||||||
if c.IsSet(TunnelTokenFlag) {
|
if c.IsSet(TunnelTokenFlag) {
|
||||||
if transportProtocol == connection.AutoSelectFlag {
|
if transportProtocol == connection.AutoSelectFlag {
|
||||||
protocolFetcher = func() (edgediscovery.ProtocolPercents, error) {
|
protocolFetcher = func() (edgediscovery.ProtocolPercents, error) {
|
||||||
|
@ -291,7 +308,7 @@ func prepareTunnelConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
warpRoutingEnabled := isWarpRoutingEnabled(cfg.WarpRouting, isNamedTunnel)
|
warpRoutingEnabled := isWarpRoutingEnabled(cfg.WarpRouting, isNamedTunnel)
|
||||||
protocolSelector, err := connection.NewProtocolSelector(transportProtocol, warpRoutingEnabled, namedTunnel, protocolFetcher, supervisor.ResolveTTL, log)
|
protocolSelector, err := connection.NewProtocolSelector(transportProtocol, warpRoutingEnabled, namedTunnel, protocolFetcher, supervisor.ResolveTTL, log, c.Bool("post-quantum"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -330,6 +347,15 @@ func prepareTunnelConfig(
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pqKexIdx int
|
||||||
|
if needPQ {
|
||||||
|
pqKexIdx = mathRand.Intn(len(supervisor.PQKexes))
|
||||||
|
log.Info().Msgf(
|
||||||
|
"Using experimental hybrid post-quantum key agreement %s",
|
||||||
|
supervisor.PQKexNames[supervisor.PQKexes[pqKexIdx]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
tunnelConfig := &supervisor.TunnelConfig{
|
tunnelConfig := &supervisor.TunnelConfig{
|
||||||
GracePeriod: gracePeriod,
|
GracePeriod: gracePeriod,
|
||||||
ReplaceExisting: c.Bool("force"),
|
ReplaceExisting: c.Bool("force"),
|
||||||
|
@ -355,6 +381,8 @@ func prepareTunnelConfig(
|
||||||
MuxerConfig: muxerConfig,
|
MuxerConfig: muxerConfig,
|
||||||
ProtocolSelector: protocolSelector,
|
ProtocolSelector: protocolSelector,
|
||||||
EdgeTLSConfigs: edgeTLSConfigs,
|
EdgeTLSConfigs: edgeTLSConfigs,
|
||||||
|
NeedPQ: needPQ,
|
||||||
|
PQKexIdx: pqKexIdx,
|
||||||
}
|
}
|
||||||
orchestratorConfig := &orchestration.Config{
|
orchestratorConfig := &orchestration.Config{
|
||||||
Ingress: &ingressRules,
|
Ingress: &ingressRules,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package tunnel
|
||||||
|
|
||||||
|
var FipsEnabled bool
|
|
@ -140,6 +140,13 @@ var (
|
||||||
EnvVars: []string{"TUNNEL_TRANSPORT_PROTOCOL"},
|
EnvVars: []string{"TUNNEL_TRANSPORT_PROTOCOL"},
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
})
|
})
|
||||||
|
postQuantumFlag = altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||||
|
Name: "post-quantum",
|
||||||
|
Usage: "When given creates an experimental post-quantum secure tunnel",
|
||||||
|
Aliases: []string{"pq"},
|
||||||
|
EnvVars: []string{"TUNNEL_POST_QUANTUM"},
|
||||||
|
Hidden: FipsEnabled,
|
||||||
|
})
|
||||||
sortInfoByFlag = &cli.StringFlag{
|
sortInfoByFlag = &cli.StringFlag{
|
||||||
Name: "sort-by",
|
Name: "sort-by",
|
||||||
Value: "createdAt",
|
Value: "createdAt",
|
||||||
|
@ -602,6 +609,7 @@ func buildRunCommand() *cli.Command {
|
||||||
forceFlag,
|
forceFlag,
|
||||||
credentialsFileFlag,
|
credentialsFileFlag,
|
||||||
credentialsContentsFlag,
|
credentialsContentsFlag,
|
||||||
|
postQuantumFlag,
|
||||||
selectProtocolFlag,
|
selectProtocolFlag,
|
||||||
featuresFlag,
|
featuresFlag,
|
||||||
tunnelTokenFlag,
|
tunnelTokenFlag,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package connection
|
package connection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -130,6 +131,7 @@ type autoProtocolSelector struct {
|
||||||
refreshAfter time.Time
|
refreshAfter time.Time
|
||||||
ttl time.Duration
|
ttl time.Duration
|
||||||
log *zerolog.Logger
|
log *zerolog.Logger
|
||||||
|
needPQ bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAutoProtocolSelector(
|
func newAutoProtocolSelector(
|
||||||
|
@ -139,6 +141,7 @@ func newAutoProtocolSelector(
|
||||||
fetchFunc PercentageFetcher,
|
fetchFunc PercentageFetcher,
|
||||||
ttl time.Duration,
|
ttl time.Duration,
|
||||||
log *zerolog.Logger,
|
log *zerolog.Logger,
|
||||||
|
needPQ bool,
|
||||||
) *autoProtocolSelector {
|
) *autoProtocolSelector {
|
||||||
return &autoProtocolSelector{
|
return &autoProtocolSelector{
|
||||||
current: current,
|
current: current,
|
||||||
|
@ -148,6 +151,7 @@ func newAutoProtocolSelector(
|
||||||
refreshAfter: time.Now().Add(ttl),
|
refreshAfter: time.Now().Add(ttl),
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
log: log,
|
log: log,
|
||||||
|
needPQ: needPQ,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +191,9 @@ func getProtocol(protocolPool []Protocol, fetchFunc PercentageFetcher, switchThr
|
||||||
func (s *autoProtocolSelector) Fallback() (Protocol, bool) {
|
func (s *autoProtocolSelector) Fallback() (Protocol, bool) {
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
defer s.lock.RUnlock()
|
defer s.lock.RUnlock()
|
||||||
|
if s.needPQ {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
return s.current.fallback()
|
return s.current.fallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,9 +206,14 @@ func NewProtocolSelector(
|
||||||
fetchFunc PercentageFetcher,
|
fetchFunc PercentageFetcher,
|
||||||
ttl time.Duration,
|
ttl time.Duration,
|
||||||
log *zerolog.Logger,
|
log *zerolog.Logger,
|
||||||
|
needPQ bool,
|
||||||
) (ProtocolSelector, error) {
|
) (ProtocolSelector, error) {
|
||||||
// Classic tunnel is only supported with h2mux
|
// Classic tunnel is only supported with h2mux
|
||||||
if namedTunnel == nil {
|
if namedTunnel == nil {
|
||||||
|
if needPQ {
|
||||||
|
return nil, errors.New("Classic tunnel does not support post-quantum")
|
||||||
|
}
|
||||||
|
|
||||||
return &staticProtocolSelector{
|
return &staticProtocolSelector{
|
||||||
current: H2mux,
|
current: H2mux,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -211,6 +223,9 @@ func NewProtocolSelector(
|
||||||
fetchedProtocol, err := getProtocol([]Protocol{QUIC, HTTP2}, fetchFunc, threshold)
|
fetchedProtocol, err := getProtocol([]Protocol{QUIC, HTTP2}, fetchFunc, threshold)
|
||||||
if err != nil && protocolFlag == "auto" {
|
if err != nil && protocolFlag == "auto" {
|
||||||
log.Err(err).Msg("Unable to lookup protocol. Defaulting to `http2`. If this fails, you can attempt `--protocol quic` instead.")
|
log.Err(err).Msg("Unable to lookup protocol. Defaulting to `http2`. If this fails, you can attempt `--protocol quic` instead.")
|
||||||
|
if needPQ {
|
||||||
|
return nil, errors.New("http2 does not support post-quantum")
|
||||||
|
}
|
||||||
return &staticProtocolSelector{
|
return &staticProtocolSelector{
|
||||||
current: HTTP2,
|
current: HTTP2,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -221,10 +236,10 @@ func NewProtocolSelector(
|
||||||
protocolFlag = HTTP2.String()
|
protocolFlag = HTTP2.String()
|
||||||
fetchedProtocol = HTTP2Warp
|
fetchedProtocol = HTTP2Warp
|
||||||
}
|
}
|
||||||
return selectWarpRoutingProtocols(protocolFlag, fetchFunc, ttl, log, threshold, fetchedProtocol)
|
return selectWarpRoutingProtocols(protocolFlag, fetchFunc, ttl, log, threshold, fetchedProtocol, needPQ)
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectNamedTunnelProtocols(protocolFlag, fetchFunc, ttl, log, threshold, fetchedProtocol)
|
return selectNamedTunnelProtocols(protocolFlag, fetchFunc, ttl, log, threshold, fetchedProtocol, needPQ)
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectNamedTunnelProtocols(
|
func selectNamedTunnelProtocols(
|
||||||
|
@ -234,6 +249,7 @@ func selectNamedTunnelProtocols(
|
||||||
log *zerolog.Logger,
|
log *zerolog.Logger,
|
||||||
threshold int32,
|
threshold int32,
|
||||||
protocol Protocol,
|
protocol Protocol,
|
||||||
|
needPQ bool,
|
||||||
) (ProtocolSelector, error) {
|
) (ProtocolSelector, error) {
|
||||||
// If the user picks a protocol, then we stick to it no matter what.
|
// If the user picks a protocol, then we stick to it no matter what.
|
||||||
switch protocolFlag {
|
switch protocolFlag {
|
||||||
|
@ -248,7 +264,7 @@ func selectNamedTunnelProtocols(
|
||||||
// If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and
|
// If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and
|
||||||
// fallback on failures.
|
// fallback on failures.
|
||||||
if protocolFlag == AutoSelectFlag {
|
if protocolFlag == AutoSelectFlag {
|
||||||
return newAutoProtocolSelector(protocol, []Protocol{QUIC, HTTP2, H2mux}, threshold, fetchFunc, ttl, log), nil
|
return newAutoProtocolSelector(protocol, []Protocol{QUIC, HTTP2, H2mux}, threshold, fetchFunc, ttl, log, needPQ), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Unknown protocol %s, %s", protocolFlag, AvailableProtocolFlagMessage)
|
return nil, fmt.Errorf("Unknown protocol %s, %s", protocolFlag, AvailableProtocolFlagMessage)
|
||||||
|
@ -261,6 +277,7 @@ func selectWarpRoutingProtocols(
|
||||||
log *zerolog.Logger,
|
log *zerolog.Logger,
|
||||||
threshold int32,
|
threshold int32,
|
||||||
protocol Protocol,
|
protocol Protocol,
|
||||||
|
needPQ bool,
|
||||||
) (ProtocolSelector, error) {
|
) (ProtocolSelector, error) {
|
||||||
// If the user picks a protocol, then we stick to it no matter what.
|
// If the user picks a protocol, then we stick to it no matter what.
|
||||||
switch protocolFlag {
|
switch protocolFlag {
|
||||||
|
@ -273,7 +290,7 @@ func selectWarpRoutingProtocols(
|
||||||
// If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and
|
// If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and
|
||||||
// fallback on failures.
|
// fallback on failures.
|
||||||
if protocolFlag == AutoSelectFlag {
|
if protocolFlag == AutoSelectFlag {
|
||||||
return newAutoProtocolSelector(protocol, []Protocol{QUICWarp, HTTP2Warp}, threshold, fetchFunc, ttl, log), nil
|
return newAutoProtocolSelector(protocol, []Protocol{QUICWarp, HTTP2Warp}, threshold, fetchFunc, ttl, log, needPQ), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Unknown protocol %s, %s", protocolFlag, AvailableProtocolFlagMessage)
|
return nil, fmt.Errorf("Unknown protocol %s, %s", protocolFlag, AvailableProtocolFlagMessage)
|
||||||
|
|
|
@ -219,7 +219,7 @@ func TestNewProtocolSelector(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
selector, err := NewProtocolSelector(test.protocol, test.warpRoutingEnabled, test.namedTunnelConfig, test.fetchFunc, testNoTTL, &log)
|
selector, err := NewProtocolSelector(test.protocol, test.warpRoutingEnabled, test.namedTunnelConfig, test.fetchFunc, testNoTTL, &log, false)
|
||||||
if test.wantErr {
|
if test.wantErr {
|
||||||
assert.Error(t, err, fmt.Sprintf("test %s failed", test.name))
|
assert.Error(t, err, fmt.Sprintf("test %s failed", test.name))
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,7 +237,7 @@ func TestNewProtocolSelector(t *testing.T) {
|
||||||
|
|
||||||
func TestAutoProtocolSelectorRefresh(t *testing.T) {
|
func TestAutoProtocolSelectorRefresh(t *testing.T) {
|
||||||
fetcher := dynamicMockFetcher{}
|
fetcher := dynamicMockFetcher{}
|
||||||
selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log)
|
selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, H2mux, selector.Current())
|
assert.Equal(t, H2mux, selector.Current())
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ func TestAutoProtocolSelectorRefresh(t *testing.T) {
|
||||||
func TestHTTP2ProtocolSelectorRefresh(t *testing.T) {
|
func TestHTTP2ProtocolSelectorRefresh(t *testing.T) {
|
||||||
fetcher := dynamicMockFetcher{}
|
fetcher := dynamicMockFetcher{}
|
||||||
// Since the user chooses http2 on purpose, we always stick to it.
|
// Since the user chooses http2 on purpose, we always stick to it.
|
||||||
selector, err := NewProtocolSelector("http2", noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log)
|
selector, err := NewProtocolSelector("http2", noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, HTTP2, selector.Current())
|
assert.Equal(t, HTTP2, selector.Current())
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ func TestHTTP2ProtocolSelectorRefresh(t *testing.T) {
|
||||||
func TestProtocolSelectorRefreshTTL(t *testing.T) {
|
func TestProtocolSelectorRefreshTTL(t *testing.T) {
|
||||||
fetcher := dynamicMockFetcher{}
|
fetcher := dynamicMockFetcher{}
|
||||||
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "quic", Percentage: 100}}
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "quic", Percentage: 100}}
|
||||||
selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), time.Hour, &log)
|
selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), time.Hour, &log, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, QUIC, selector.Current())
|
assert.Equal(t, QUIC, selector.Current())
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,11 @@
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import _ "crypto/tls/fipsonly"
|
import (
|
||||||
|
_ "crypto/tls/fipsonly"
|
||||||
|
"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init () {
|
||||||
|
tunnel.FipsEnabled = true
|
||||||
|
}
|
||||||
|
|
16
go.mod
16
go.mod
|
@ -12,6 +12,7 @@ require (
|
||||||
github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10
|
github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10
|
||||||
github.com/gobwas/ws v1.0.4
|
github.com/gobwas/ws v1.0.4
|
||||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
|
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
|
||||||
|
github.com/google/gopacket v1.1.19
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
|
@ -33,10 +34,10 @@ require (
|
||||||
go.opentelemetry.io/otel/trace v1.6.3
|
go.opentelemetry.io/otel/trace v1.6.3
|
||||||
go.opentelemetry.io/proto/otlp v0.15.0
|
go.opentelemetry.io/proto/otlp v0.15.0
|
||||||
go.uber.org/automaxprocs v1.4.0
|
go.uber.org/automaxprocs v1.4.0
|
||||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
|
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||||
google.golang.org/protobuf v1.28.0
|
google.golang.org/protobuf v1.28.0
|
||||||
gopkg.in/coreos/go-oidc.v2 v2.2.1
|
gopkg.in/coreos/go-oidc.v2 v2.2.1
|
||||||
|
@ -53,6 +54,7 @@ require (
|
||||||
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 // indirect
|
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/cheekybits/genny v1.0.0 // indirect
|
github.com/cheekybits/genny v1.0.0 // indirect
|
||||||
|
github.com/cloudflare/circl v1.2.1-0.20220809205628-0a9554f37a47 // indirect
|
||||||
github.com/coredns/caddy v1.1.1 // indirect
|
github.com/coredns/caddy v1.1.1 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
@ -67,7 +69,6 @@ require (
|
||||||
github.com/gobwas/httphead v0.0.0-20200921212729-da3d93bc3c58 // indirect
|
github.com/gobwas/httphead v0.0.0-20200921212729-da3d93bc3c58 // indirect
|
||||||
github.com/gobwas/pool v0.2.1 // indirect
|
github.com/gobwas/pool v0.2.1 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/google/gopacket v1.1.19 // indirect
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
|
@ -107,3 +108,12 @@ replace github.com/lucas-clemente/quic-go => github.com/chungthuang/quic-go v0.2
|
||||||
replace github.com/prometheus/golang_client => github.com/prometheus/golang_client v1.12.1
|
replace github.com/prometheus/golang_client => github.com/prometheus/golang_client v1.12.1
|
||||||
|
|
||||||
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
||||||
|
|
||||||
|
// Post-quantum tunnel RTG-1339
|
||||||
|
replace (
|
||||||
|
// branch go1.18
|
||||||
|
github.com/marten-seemann/qtls-go1-18 => github.com/cloudflare/qtls-pq v0.0.0-20220824105406-fb955667e0af
|
||||||
|
|
||||||
|
// branch go1.19
|
||||||
|
github.com/marten-seemann/qtls-go1-19 => github.com/cloudflare/qtls-pq v0.0.0-20220824104809-96561a41e0af
|
||||||
|
)
|
||||||
|
|
22
go.sum
22
go.sum
|
@ -99,6 +99,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
|
github.com/bwesterb/go-ristretto v1.2.2/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 h1:JLaf/iINcLyjwbtTsCJjc6rtlASgHeIJPrB6QmwURnA=
|
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 h1:JLaf/iINcLyjwbtTsCJjc6rtlASgHeIJPrB6QmwURnA=
|
||||||
|
@ -117,8 +118,14 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93 h1:QrGfkZDnMxcWHaYDdB7CmqS9i26OAnUj/xcus/abYkY=
|
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93 h1:QrGfkZDnMxcWHaYDdB7CmqS9i26OAnUj/xcus/abYkY=
|
||||||
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93/go.mod h1:QiTe66jFdP7cUKMCCf/WrvDyYdtdmdZfVcdoLbzaKVY=
|
github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93/go.mod h1:QiTe66jFdP7cUKMCCf/WrvDyYdtdmdZfVcdoLbzaKVY=
|
||||||
|
github.com/cloudflare/circl v1.2.1-0.20220809205628-0a9554f37a47 h1:YzpECHxZ9TzO7LpnKmPxItSd79lLgrR5heIlnqU4dTU=
|
||||||
|
github.com/cloudflare/circl v1.2.1-0.20220809205628-0a9554f37a47/go.mod h1:qhx8gBILsYlbam7h09SvHDSkjpe3TfLA7b/z4rxJvkE=
|
||||||
github.com/cloudflare/golibs v0.0.0-20170913112048-333127dbecfc h1:Dvk3ySBsOm5EviLx6VCyILnafPcQinXGP5jbTdHUJgE=
|
github.com/cloudflare/golibs v0.0.0-20170913112048-333127dbecfc h1:Dvk3ySBsOm5EviLx6VCyILnafPcQinXGP5jbTdHUJgE=
|
||||||
github.com/cloudflare/golibs v0.0.0-20170913112048-333127dbecfc/go.mod h1:HlgKKR8V5a1wroIDDIz3/A+T+9Janfq+7n1P5sEFdi0=
|
github.com/cloudflare/golibs v0.0.0-20170913112048-333127dbecfc/go.mod h1:HlgKKR8V5a1wroIDDIz3/A+T+9Janfq+7n1P5sEFdi0=
|
||||||
|
github.com/cloudflare/qtls-pq v0.0.0-20220824104809-96561a41e0af h1:JMpOQAaXjRRBkUX73fTNe9mConJLFl6FsIp9fHdLm7Y=
|
||||||
|
github.com/cloudflare/qtls-pq v0.0.0-20220824104809-96561a41e0af/go.mod h1:aIsWqC0WXyUiUxBl/RfxAjDyWE9CCLqvSMnCMTd/+bc=
|
||||||
|
github.com/cloudflare/qtls-pq v0.0.0-20220824105406-fb955667e0af h1:bhCmedjwrOSyzLtHVeQ+KhimcNTSfs0P5T7kbRQS+gA=
|
||||||
|
github.com/cloudflare/qtls-pq v0.0.0-20220824105406-fb955667e0af/go.mod h1:mW0BgKFFDAiSmOdUwoORtjo0V2vqw5QzVYRtKQqw/Jg=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
|
@ -401,10 +408,6 @@ github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtU
|
||||||
github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
||||||
github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ=
|
github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ=
|
||||||
github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s=
|
github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s=
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM=
|
|
||||||
github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 h1:7m/WlWcSROrcK5NxuXaxYD32BZqe/LEEnBrWcH/cOqQ=
|
|
||||||
github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
|
|
||||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
@ -621,8 +624,8 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE8+RX+uXZyGhUy/ksMGJoc=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -708,9 +711,9 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
|
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
@ -818,10 +821,9 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package supervisor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// When experimental post-quantum tunnels are enabled, and we're hitting an
|
||||||
|
// issue creating the tunnel, we'll report the first error
|
||||||
|
// to https://pqtunnels.cloudflareresearch.com.
|
||||||
|
|
||||||
|
var (
|
||||||
|
PQKexes = [...]tls.CurveID{
|
||||||
|
tls.CurveID(0xfe30), // X25519Kyber512Draft00
|
||||||
|
tls.CurveID(0xfe31), // X25519Kyber768Draft00
|
||||||
|
}
|
||||||
|
PQKexNames map[tls.CurveID]string = map[tls.CurveID]string{
|
||||||
|
tls.CurveID(0xfe30): "X25519Kyber512Draft00",
|
||||||
|
tls.CurveID(0xfe31): "X25519Kyber768Draft00",
|
||||||
|
}
|
||||||
|
|
||||||
|
pqtMux sync.Mutex // protects pqtSubmitted and pqtWaitForMessage
|
||||||
|
pqtSubmitted bool // whether an error has already been submitted
|
||||||
|
|
||||||
|
// Number of errors to ignore before printing elaborate instructions.
|
||||||
|
pqtWaitForMessage int
|
||||||
|
)
|
||||||
|
|
||||||
|
func handlePQTunnelError(rep error, config *TunnelConfig) {
|
||||||
|
needToMessage := false
|
||||||
|
|
||||||
|
pqtMux.Lock()
|
||||||
|
needToSubmit := !pqtSubmitted
|
||||||
|
if needToSubmit {
|
||||||
|
pqtSubmitted = true
|
||||||
|
}
|
||||||
|
pqtWaitForMessage--
|
||||||
|
if pqtWaitForMessage < 0 {
|
||||||
|
pqtWaitForMessage = 5
|
||||||
|
needToMessage = true
|
||||||
|
}
|
||||||
|
pqtMux.Unlock()
|
||||||
|
|
||||||
|
if needToMessage {
|
||||||
|
config.Log.Info().Msgf(
|
||||||
|
"\n\n" +
|
||||||
|
"===================================================================================\n" +
|
||||||
|
"You are hitting an error while using the experimental post-quantum tunnels feature.\n" +
|
||||||
|
"\n" +
|
||||||
|
"Please check:\n" +
|
||||||
|
"\n" +
|
||||||
|
" https://pqtunnels.cloudflareresearch.com\n" +
|
||||||
|
"\n" +
|
||||||
|
"for known problems.\n" +
|
||||||
|
"===================================================================================\n\n",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if needToSubmit {
|
||||||
|
go submitPQTunnelError(rep, config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func submitPQTunnelError(rep error, config *TunnelConfig) {
|
||||||
|
body, err := json.Marshal(struct {
|
||||||
|
Group int `json:"g"`
|
||||||
|
Message string `json:"m"`
|
||||||
|
Version string `json:"v"`
|
||||||
|
}{
|
||||||
|
Group: int(PQKexes[config.PQKexIdx]),
|
||||||
|
Message: rep.Error(),
|
||||||
|
Version: config.ReportedVersion,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
config.Log.Err(err).Msg("Failed to create error report")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(
|
||||||
|
"https://pqtunnels.cloudflareresearch.com",
|
||||||
|
"application/json",
|
||||||
|
bytes.NewBuffer(body),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
config.Log.Err(err).Msg(
|
||||||
|
"Failed to submit post-quantum tunnel error report",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
config.Log.Error().Msgf(
|
||||||
|
"Failed to submit post-quantum tunnel error report: status %d",
|
||||||
|
resp.StatusCode,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ const (
|
||||||
FeatureQuickReconnects = "quick_reconnects"
|
FeatureQuickReconnects = "quick_reconnects"
|
||||||
FeatureAllowRemoteConfig = "allow_remote_config"
|
FeatureAllowRemoteConfig = "allow_remote_config"
|
||||||
FeatureDatagramV2 = "support_datagram_v2"
|
FeatureDatagramV2 = "support_datagram_v2"
|
||||||
|
FeaturePostQuantum = "postquantum"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TunnelConfig struct {
|
type TunnelConfig struct {
|
||||||
|
@ -59,6 +60,11 @@ type TunnelConfig struct {
|
||||||
Retries uint
|
Retries uint
|
||||||
RunFromTerminal bool
|
RunFromTerminal bool
|
||||||
|
|
||||||
|
NeedPQ bool
|
||||||
|
|
||||||
|
// Index into PQKexes of post-quantum kex to use if NeedPQ is set.
|
||||||
|
PQKexIdx int
|
||||||
|
|
||||||
NamedTunnel *connection.NamedTunnelProperties
|
NamedTunnel *connection.NamedTunnelProperties
|
||||||
ClassicTunnel *connection.ClassicTunnelProperties
|
ClassicTunnel *connection.ClassicTunnelProperties
|
||||||
MuxerConfig *connection.MuxerConfig
|
MuxerConfig *connection.MuxerConfig
|
||||||
|
@ -524,6 +530,9 @@ func (e *EdgeTunnelServer) serveH2mux(
|
||||||
connIndex uint8,
|
connIndex uint8,
|
||||||
connectedFuse *connectedFuse,
|
connectedFuse *connectedFuse,
|
||||||
) error {
|
) error {
|
||||||
|
if e.config.NeedPQ {
|
||||||
|
return unrecoverableError{errors.New("H2Mux transport does not support post-quantum")}
|
||||||
|
}
|
||||||
connLog.Logger().Debug().Msgf("Connecting via h2mux")
|
connLog.Logger().Debug().Msgf("Connecting via h2mux")
|
||||||
// Returns error from parsing the origin URL or handshake errors
|
// Returns error from parsing the origin URL or handshake errors
|
||||||
handler, err, recoverable := connection.NewH2muxConnection(
|
handler, err, recoverable := connection.NewH2muxConnection(
|
||||||
|
@ -575,6 +584,10 @@ func (e *EdgeTunnelServer) serveHTTP2(
|
||||||
controlStreamHandler connection.ControlStreamHandler,
|
controlStreamHandler connection.ControlStreamHandler,
|
||||||
connIndex uint8,
|
connIndex uint8,
|
||||||
) error {
|
) error {
|
||||||
|
if e.config.NeedPQ {
|
||||||
|
return unrecoverableError{errors.New("HTTP/2 transport does not support post-quantum")}
|
||||||
|
}
|
||||||
|
|
||||||
connLog.Logger().Debug().Msgf("Connecting via http2")
|
connLog.Logger().Debug().Msgf("Connecting via http2")
|
||||||
h2conn := connection.NewHTTP2Connection(
|
h2conn := connection.NewHTTP2Connection(
|
||||||
tlsServerConn,
|
tlsServerConn,
|
||||||
|
@ -613,6 +626,22 @@ func (e *EdgeTunnelServer) serveQUIC(
|
||||||
connIndex uint8,
|
connIndex uint8,
|
||||||
) (err error, recoverable bool) {
|
) (err error, recoverable bool) {
|
||||||
tlsConfig := e.config.EdgeTLSConfigs[connection.QUIC]
|
tlsConfig := e.config.EdgeTLSConfigs[connection.QUIC]
|
||||||
|
|
||||||
|
if e.config.NeedPQ {
|
||||||
|
// If the user passes the -post-quantum flag, we override
|
||||||
|
// CurvePreferences to only support hybrid post-quantum key agreements.
|
||||||
|
cs := make([]tls.CurveID, len(PQKexes))
|
||||||
|
copy(cs, PQKexes[:])
|
||||||
|
|
||||||
|
// It is unclear whether Kyber512 or Kyber768 will become the standard.
|
||||||
|
// Kyber768 is a bit bigger (and doesn't fit in one initial
|
||||||
|
// datagram anymore). We're enabling both, but pick randomly which
|
||||||
|
// one to put first. (TLS will use the first one in the list
|
||||||
|
// and allows a fallback to the second.)
|
||||||
|
cs[0], cs[e.config.PQKexIdx] = cs[e.config.PQKexIdx], cs[0]
|
||||||
|
tlsConfig.CurvePreferences = cs
|
||||||
|
}
|
||||||
|
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
HandshakeIdleTimeout: quicpogs.HandshakeIdleTimeout,
|
HandshakeIdleTimeout: quicpogs.HandshakeIdleTimeout,
|
||||||
MaxIdleTimeout: quicpogs.MaxIdleTimeout,
|
MaxIdleTimeout: quicpogs.MaxIdleTimeout,
|
||||||
|
@ -634,6 +663,10 @@ func (e *EdgeTunnelServer) serveQUIC(
|
||||||
connLogger.Logger(),
|
connLogger.Logger(),
|
||||||
e.icmpProxy)
|
e.icmpProxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e.config.NeedPQ {
|
||||||
|
handlePQTunnelError(err, e.config)
|
||||||
|
}
|
||||||
|
|
||||||
connLogger.ConnAwareLogger().Err(err).Msgf("Failed to create new quic connection")
|
connLogger.ConnAwareLogger().Err(err).Msgf("Failed to create new quic connection")
|
||||||
return err, true
|
return err, true
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ func TestWaitForBackoffFallback(t *testing.T) {
|
||||||
mockFetcher.fetch(),
|
mockFetcher.fetch(),
|
||||||
resolveTTL,
|
resolveTTL,
|
||||||
&log,
|
&log,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
@ -104,6 +105,7 @@ func TestWaitForBackoffFallback(t *testing.T) {
|
||||||
mockFetcher.fetch(),
|
mockFetcher.fetch(),
|
||||||
resolveTTL,
|
resolveTTL,
|
||||||
&log,
|
&log,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
protoFallback = &protocolFallback{backoff, protocolSelector.Current(), false}
|
protoFallback = &protocolFallback{backoff, protocolSelector.Current(), false}
|
||||||
|
|
|
@ -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.
|
|
@ -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,
|
||||||
|
},
|
||||||
|
}
|
|
@ -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)
|
|
@ -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)
|
|
@ -0,0 +1,156 @@
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Depends on circl/math/fp25519 package
|
||||||
|
#include "../../math/fp25519/fp_amd64.h"
|
||||||
|
#include "curve_amd64.h"
|
||||||
|
|
||||||
|
// CTE_A24 is (A+2)/4 from Curve25519
|
||||||
|
#define CTE_A24 121666
|
||||||
|
|
||||||
|
#define Size 32
|
||||||
|
|
||||||
|
// multiplyA24Leg multiplies x times CTE_A24 and stores in z
|
||||||
|
// Uses: AX, DX, R8-R13, FLAGS
|
||||||
|
// Instr: x86_64, cmov
|
||||||
|
#define multiplyA24Leg(z,x) \
|
||||||
|
MOVL $CTE_A24, AX; MULQ 0+x; MOVQ AX, R8; MOVQ DX, R9; \
|
||||||
|
MOVL $CTE_A24, AX; MULQ 8+x; MOVQ AX, R12; MOVQ DX, R10; \
|
||||||
|
MOVL $CTE_A24, AX; MULQ 16+x; MOVQ AX, R13; MOVQ DX, R11; \
|
||||||
|
MOVL $CTE_A24, AX; MULQ 24+x; \
|
||||||
|
ADDQ R12, R9; \
|
||||||
|
ADCQ R13, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
MOVL $38, AX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
|
||||||
|
IMULQ AX, DX; \
|
||||||
|
ADDQ DX, R8; \
|
||||||
|
ADCQ $0, R9; MOVQ R9, 8+z; \
|
||||||
|
ADCQ $0, R10; MOVQ R10, 16+z; \
|
||||||
|
ADCQ $0, R11; MOVQ R11, 24+z; \
|
||||||
|
MOVQ $0, DX; \
|
||||||
|
CMOVQCS AX, DX; \
|
||||||
|
ADDQ DX, R8; MOVQ R8, 0+z;
|
||||||
|
|
||||||
|
// multiplyA24Adx multiplies x times CTE_A24 and stores in z
|
||||||
|
// Uses: AX, DX, R8-R12, FLAGS
|
||||||
|
// Instr: x86_64, cmov, bmi2
|
||||||
|
#define multiplyA24Adx(z,x) \
|
||||||
|
MOVQ $CTE_A24, DX; \
|
||||||
|
MULXQ 0+x, R8, R10; \
|
||||||
|
MULXQ 8+x, R9, R11; ADDQ R10, R9; \
|
||||||
|
MULXQ 16+x, R10, AX; ADCQ R11, R10; \
|
||||||
|
MULXQ 24+x, R11, R12; ADCQ AX, R11; \
|
||||||
|
;;;;;;;;;;;;;;;;;;;;; ADCQ $0, R12; \
|
||||||
|
MOVL $38, DX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
|
||||||
|
IMULQ DX, R12; \
|
||||||
|
ADDQ R12, R8; \
|
||||||
|
ADCQ $0, R9; MOVQ R9, 8+z; \
|
||||||
|
ADCQ $0, R10; MOVQ R10, 16+z; \
|
||||||
|
ADCQ $0, R11; MOVQ R11, 24+z; \
|
||||||
|
MOVQ $0, R12; \
|
||||||
|
CMOVQCS DX, R12; \
|
||||||
|
ADDQ R12, R8; MOVQ R8, 0+z;
|
||||||
|
|
||||||
|
#define mulA24Legacy \
|
||||||
|
multiplyA24Leg(0(DI),0(SI))
|
||||||
|
#define mulA24Bmi2Adx \
|
||||||
|
multiplyA24Adx(0(DI),0(SI))
|
||||||
|
|
||||||
|
// func mulA24Amd64(z, x *fp255.Elt)
|
||||||
|
TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
|
||||||
|
|
||||||
|
|
||||||
|
// func ladderStepAmd64(w *[5]fp255.Elt, b uint)
|
||||||
|
// ladderStepAmd64 calculates a point addition and doubling as follows:
|
||||||
|
// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
|
||||||
|
// work = (x1,x2,z2,x3,z3) are five fp255.Elt of 32 bytes.
|
||||||
|
// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
|
||||||
|
// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
TEXT ·ladderStepAmd64(SB),NOSPLIT,$192-16
|
||||||
|
// Parameters
|
||||||
|
#define regWork DI
|
||||||
|
#define regMove SI
|
||||||
|
#define x1 0*Size(regWork)
|
||||||
|
#define x2 1*Size(regWork)
|
||||||
|
#define z2 2*Size(regWork)
|
||||||
|
#define x3 3*Size(regWork)
|
||||||
|
#define z3 4*Size(regWork)
|
||||||
|
// Local variables
|
||||||
|
#define t0 0*Size(SP)
|
||||||
|
#define t1 1*Size(SP)
|
||||||
|
#define b0 2*Size(SP)
|
||||||
|
#define b1 4*Size(SP)
|
||||||
|
MOVQ w+0(FP), regWork
|
||||||
|
MOVQ b+8(FP), regMove
|
||||||
|
CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
|
||||||
|
#undef regWork
|
||||||
|
#undef regMove
|
||||||
|
#undef x1
|
||||||
|
#undef x2
|
||||||
|
#undef z2
|
||||||
|
#undef x3
|
||||||
|
#undef z3
|
||||||
|
#undef t0
|
||||||
|
#undef t1
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
||||||
|
|
||||||
|
// func diffAddAmd64(w *[5]fp255.Elt, b uint)
|
||||||
|
// diffAddAmd64 calculates a differential point addition using a precomputed point.
|
||||||
|
// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
|
||||||
|
// w = (mu,x1,z1,x2,z2) are five fp.Elt, and
|
||||||
|
// stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
TEXT ·diffAddAmd64(SB),NOSPLIT,$128-16
|
||||||
|
// Parameters
|
||||||
|
#define regWork DI
|
||||||
|
#define regSwap SI
|
||||||
|
#define ui 0*Size(regWork)
|
||||||
|
#define x1 1*Size(regWork)
|
||||||
|
#define z1 2*Size(regWork)
|
||||||
|
#define x2 3*Size(regWork)
|
||||||
|
#define z2 4*Size(regWork)
|
||||||
|
// Local variables
|
||||||
|
#define b0 0*Size(SP)
|
||||||
|
#define b1 2*Size(SP)
|
||||||
|
MOVQ w+0(FP), regWork
|
||||||
|
MOVQ b+8(FP), regSwap
|
||||||
|
cswap(x1,x2,regSwap)
|
||||||
|
cswap(z1,z2,regSwap)
|
||||||
|
CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
|
||||||
|
#undef regWork
|
||||||
|
#undef regSwap
|
||||||
|
#undef ui
|
||||||
|
#undef x1
|
||||||
|
#undef z1
|
||||||
|
#undef x2
|
||||||
|
#undef z2
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
||||||
|
|
||||||
|
// func doubleAmd64(x, z *fp255.Elt)
|
||||||
|
// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
|
||||||
|
// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
|
||||||
|
// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
TEXT ·doubleAmd64(SB),NOSPLIT,$192-16
|
||||||
|
// Parameters
|
||||||
|
#define x1 0(DI)
|
||||||
|
#define z1 0(SI)
|
||||||
|
// Local variables
|
||||||
|
#define t0 0*Size(SP)
|
||||||
|
#define t1 1*Size(SP)
|
||||||
|
#define b0 2*Size(SP)
|
||||||
|
#define b1 4*Size(SP)
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ z+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
|
||||||
|
#undef x1
|
||||||
|
#undef z1
|
||||||
|
#undef t0
|
||||||
|
#undef t1
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
|
@ -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])
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) }
|
|
@ -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
|
|
@ -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))
|
||||||
|
isLowOrder := false
|
||||||
|
for _, P := range lowOrderPoints {
|
||||||
|
isLowOrder = isLowOrder || subtle.ConstantTimeCompare(P[:], k[:]) != 0
|
||||||
|
}
|
||||||
|
return !isLowOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
|
@ -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,
|
||||||
|
}
|
|
@ -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,
|
||||||
|
},
|
||||||
|
}
|
|
@ -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)
|
|
@ -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)
|
|
@ -0,0 +1,193 @@
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Depends on circl/math/fp448 package
|
||||||
|
#include "../../math/fp448/fp_amd64.h"
|
||||||
|
#include "curve_amd64.h"
|
||||||
|
|
||||||
|
// CTE_A24 is (A+2)/4 from Curve448
|
||||||
|
#define CTE_A24 39082
|
||||||
|
|
||||||
|
#define Size 56
|
||||||
|
|
||||||
|
// multiplyA24Leg multiplies x times CTE_A24 and stores in z
|
||||||
|
// Uses: AX, DX, R8-R15, FLAGS
|
||||||
|
// Instr: x86_64, cmov, adx
|
||||||
|
#define multiplyA24Leg(z,x) \
|
||||||
|
MOVQ $CTE_A24, R15; \
|
||||||
|
MOVQ 0+x, AX; MULQ R15; MOVQ AX, R8; ;;;;;;;;;;;; MOVQ DX, R9; \
|
||||||
|
MOVQ 8+x, AX; MULQ R15; ADDQ AX, R9; ADCQ $0, DX; MOVQ DX, R10; \
|
||||||
|
MOVQ 16+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
|
||||||
|
MOVQ 24+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
|
||||||
|
MOVQ 32+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
|
||||||
|
MOVQ 40+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
|
||||||
|
MOVQ 48+x, AX; MULQ R15; ADDQ AX, R14; ADCQ $0, DX; \
|
||||||
|
MOVQ DX, AX; \
|
||||||
|
SHLQ $32, AX; \
|
||||||
|
ADDQ DX, R8; MOVQ $0, DX; \
|
||||||
|
ADCQ $0, R9; \
|
||||||
|
ADCQ $0, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, R12; \
|
||||||
|
ADCQ $0, R13; \
|
||||||
|
ADCQ $0, R14; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
MOVQ DX, AX; \
|
||||||
|
SHLQ $32, AX; \
|
||||||
|
ADDQ DX, R8; \
|
||||||
|
ADCQ $0, R9; \
|
||||||
|
ADCQ $0, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, R12; \
|
||||||
|
ADCQ $0, R13; \
|
||||||
|
ADCQ $0, R14; \
|
||||||
|
MOVQ R8, 0+z; \
|
||||||
|
MOVQ R9, 8+z; \
|
||||||
|
MOVQ R10, 16+z; \
|
||||||
|
MOVQ R11, 24+z; \
|
||||||
|
MOVQ R12, 32+z; \
|
||||||
|
MOVQ R13, 40+z; \
|
||||||
|
MOVQ R14, 48+z;
|
||||||
|
|
||||||
|
// multiplyA24Adx multiplies x times CTE_A24 and stores in z
|
||||||
|
// Uses: AX, DX, R8-R14, FLAGS
|
||||||
|
// Instr: x86_64, bmi2
|
||||||
|
#define multiplyA24Adx(z,x) \
|
||||||
|
MOVQ $CTE_A24, DX; \
|
||||||
|
MULXQ 0+x, R8, R9; \
|
||||||
|
MULXQ 8+x, AX, R10; ADDQ AX, R9; \
|
||||||
|
MULXQ 16+x, AX, R11; ADCQ AX, R10; \
|
||||||
|
MULXQ 24+x, AX, R12; ADCQ AX, R11; \
|
||||||
|
MULXQ 32+x, AX, R13; ADCQ AX, R12; \
|
||||||
|
MULXQ 40+x, AX, R14; ADCQ AX, R13; \
|
||||||
|
MULXQ 48+x, AX, DX; ADCQ AX, R14; \
|
||||||
|
;;;;;;;;;;;;;;;;;;;; ADCQ $0, DX; \
|
||||||
|
MOVQ DX, AX; \
|
||||||
|
SHLQ $32, AX; \
|
||||||
|
ADDQ DX, R8; MOVQ $0, DX; \
|
||||||
|
ADCQ $0, R9; \
|
||||||
|
ADCQ $0, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, R12; \
|
||||||
|
ADCQ $0, R13; \
|
||||||
|
ADCQ $0, R14; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
MOVQ DX, AX; \
|
||||||
|
SHLQ $32, AX; \
|
||||||
|
ADDQ DX, R8; \
|
||||||
|
ADCQ $0, R9; \
|
||||||
|
ADCQ $0, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, R12; \
|
||||||
|
ADCQ $0, R13; \
|
||||||
|
ADCQ $0, R14; \
|
||||||
|
MOVQ R8, 0+z; \
|
||||||
|
MOVQ R9, 8+z; \
|
||||||
|
MOVQ R10, 16+z; \
|
||||||
|
MOVQ R11, 24+z; \
|
||||||
|
MOVQ R12, 32+z; \
|
||||||
|
MOVQ R13, 40+z; \
|
||||||
|
MOVQ R14, 48+z;
|
||||||
|
|
||||||
|
#define mulA24Legacy \
|
||||||
|
multiplyA24Leg(0(DI),0(SI))
|
||||||
|
#define mulA24Bmi2Adx \
|
||||||
|
multiplyA24Adx(0(DI),0(SI))
|
||||||
|
|
||||||
|
// func mulA24Amd64(z, x *fp448.Elt)
|
||||||
|
TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
|
||||||
|
|
||||||
|
// func ladderStepAmd64(w *[5]fp448.Elt, b uint)
|
||||||
|
// ladderStepAmd64 calculates a point addition and doubling as follows:
|
||||||
|
// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
|
||||||
|
// w = {x1,x2,z2,x3,z4} are five fp255.Elt of 56 bytes.
|
||||||
|
// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
|
||||||
|
// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
TEXT ·ladderStepAmd64(SB),NOSPLIT,$336-16
|
||||||
|
// Parameters
|
||||||
|
#define regWork DI
|
||||||
|
#define regMove SI
|
||||||
|
#define x1 0*Size(regWork)
|
||||||
|
#define x2 1*Size(regWork)
|
||||||
|
#define z2 2*Size(regWork)
|
||||||
|
#define x3 3*Size(regWork)
|
||||||
|
#define z3 4*Size(regWork)
|
||||||
|
// Local variables
|
||||||
|
#define t0 0*Size(SP)
|
||||||
|
#define t1 1*Size(SP)
|
||||||
|
#define b0 2*Size(SP)
|
||||||
|
#define b1 4*Size(SP)
|
||||||
|
MOVQ w+0(FP), regWork
|
||||||
|
MOVQ b+8(FP), regMove
|
||||||
|
CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
|
||||||
|
#undef regWork
|
||||||
|
#undef regMove
|
||||||
|
#undef x1
|
||||||
|
#undef x2
|
||||||
|
#undef z2
|
||||||
|
#undef x3
|
||||||
|
#undef z3
|
||||||
|
#undef t0
|
||||||
|
#undef t1
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
||||||
|
|
||||||
|
// func diffAddAmd64(work *[5]fp.Elt, swap uint)
|
||||||
|
// diffAddAmd64 calculates a differential point addition using a precomputed point.
|
||||||
|
// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
|
||||||
|
// work = {mu,x1,z1,x2,z2} are five fp448.Elt of 56 bytes, and
|
||||||
|
// stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
// This is Equation 7 at https://eprint.iacr.org/2017/264.
|
||||||
|
TEXT ·diffAddAmd64(SB),NOSPLIT,$224-16
|
||||||
|
// Parameters
|
||||||
|
#define regWork DI
|
||||||
|
#define regSwap SI
|
||||||
|
#define ui 0*Size(regWork)
|
||||||
|
#define x1 1*Size(regWork)
|
||||||
|
#define z1 2*Size(regWork)
|
||||||
|
#define x2 3*Size(regWork)
|
||||||
|
#define z2 4*Size(regWork)
|
||||||
|
// Local variables
|
||||||
|
#define b0 0*Size(SP)
|
||||||
|
#define b1 2*Size(SP)
|
||||||
|
MOVQ w+0(FP), regWork
|
||||||
|
MOVQ b+8(FP), regSwap
|
||||||
|
cswap(x1,x2,regSwap)
|
||||||
|
cswap(z1,z2,regSwap)
|
||||||
|
CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
|
||||||
|
#undef regWork
|
||||||
|
#undef regSwap
|
||||||
|
#undef ui
|
||||||
|
#undef x1
|
||||||
|
#undef z1
|
||||||
|
#undef x2
|
||||||
|
#undef z2
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
||||||
|
|
||||||
|
// func doubleAmd64(x, z *fp448.Elt)
|
||||||
|
// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
|
||||||
|
// stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
|
||||||
|
// (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
|
||||||
|
TEXT ·doubleAmd64(SB),NOSPLIT,$336-16
|
||||||
|
// Parameters
|
||||||
|
#define x1 0(DI)
|
||||||
|
#define z1 0(SI)
|
||||||
|
// Local variables
|
||||||
|
#define t0 0*Size(SP)
|
||||||
|
#define t1 1*Size(SP)
|
||||||
|
#define b0 2*Size(SP)
|
||||||
|
#define b1 4*Size(SP)
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ z+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
|
||||||
|
#undef x1
|
||||||
|
#undef z1
|
||||||
|
#undef t0
|
||||||
|
#undef t1
|
||||||
|
#undef b0
|
||||||
|
#undef b1
|
|
@ -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])
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) }
|
|
@ -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
|
|
@ -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))
|
||||||
|
isLowOrder := false
|
||||||
|
for _, P := range lowOrderPoints {
|
||||||
|
isLowOrder = isLowOrder || subtle.ConstantTimeCompare(P[:], k[:]) != 0
|
||||||
|
}
|
||||||
|
return !isLowOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
|
@ -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,
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1,385 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !amd64 || appengine || gccgo
|
||||||
|
// +build !amd64 appengine gccgo
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// KeccakF1600 applies the Keccak permutation to a 1600b-wide
|
||||||
|
// state represented as a slice of 25 uint64s.
|
||||||
|
func KeccakF1600(a *[25]uint64) {
|
||||||
|
// Implementation translated from Keccak-inplace.c
|
||||||
|
// in the keccak reference code.
|
||||||
|
var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
|
||||||
|
|
||||||
|
for i := 0; i < 24; i += 4 {
|
||||||
|
// Combines the 5 steps in each round into 2 steps.
|
||||||
|
// Unrolls 4 rounds per loop and spreads some steps across rounds.
|
||||||
|
|
||||||
|
// Round 1
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc1 = 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// 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 && !gccgo
|
||||||
|
// +build amd64,!appengine,!gccgo
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This function is implemented in keccakf_amd64.s.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func KeccakF1600(state *[25]uint64)
|
|
@ -0,0 +1,390 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64,!appengine,!gccgo
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources at https://github.com/gvanas/KeccakCodePackage
|
||||||
|
|
||||||
|
// Offsets in state
|
||||||
|
#define _ba (0*8)
|
||||||
|
#define _be (1*8)
|
||||||
|
#define _bi (2*8)
|
||||||
|
#define _bo (3*8)
|
||||||
|
#define _bu (4*8)
|
||||||
|
#define _ga (5*8)
|
||||||
|
#define _ge (6*8)
|
||||||
|
#define _gi (7*8)
|
||||||
|
#define _go (8*8)
|
||||||
|
#define _gu (9*8)
|
||||||
|
#define _ka (10*8)
|
||||||
|
#define _ke (11*8)
|
||||||
|
#define _ki (12*8)
|
||||||
|
#define _ko (13*8)
|
||||||
|
#define _ku (14*8)
|
||||||
|
#define _ma (15*8)
|
||||||
|
#define _me (16*8)
|
||||||
|
#define _mi (17*8)
|
||||||
|
#define _mo (18*8)
|
||||||
|
#define _mu (19*8)
|
||||||
|
#define _sa (20*8)
|
||||||
|
#define _se (21*8)
|
||||||
|
#define _si (22*8)
|
||||||
|
#define _so (23*8)
|
||||||
|
#define _su (24*8)
|
||||||
|
|
||||||
|
// Temporary registers
|
||||||
|
#define rT1 AX
|
||||||
|
|
||||||
|
// Round vars
|
||||||
|
#define rpState DI
|
||||||
|
#define rpStack SP
|
||||||
|
|
||||||
|
#define rDa BX
|
||||||
|
#define rDe CX
|
||||||
|
#define rDi DX
|
||||||
|
#define rDo R8
|
||||||
|
#define rDu R9
|
||||||
|
|
||||||
|
#define rBa R10
|
||||||
|
#define rBe R11
|
||||||
|
#define rBi R12
|
||||||
|
#define rBo R13
|
||||||
|
#define rBu R14
|
||||||
|
|
||||||
|
#define rCa SI
|
||||||
|
#define rCe BP
|
||||||
|
#define rCi rBi
|
||||||
|
#define rCo rBo
|
||||||
|
#define rCu R15
|
||||||
|
|
||||||
|
#define MOVQ_RBI_RCE MOVQ rBi, rCe
|
||||||
|
#define XORQ_RT1_RCA XORQ rT1, rCa
|
||||||
|
#define XORQ_RT1_RCE XORQ rT1, rCe
|
||||||
|
#define XORQ_RBA_RCU XORQ rBa, rCu
|
||||||
|
#define XORQ_RBE_RCU XORQ rBe, rCu
|
||||||
|
#define XORQ_RDU_RCU XORQ rDu, rCu
|
||||||
|
#define XORQ_RDA_RCA XORQ rDa, rCa
|
||||||
|
#define XORQ_RDE_RCE XORQ rDe, rCe
|
||||||
|
|
||||||
|
#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
|
||||||
|
/* Prepare round */ \
|
||||||
|
MOVQ rCe, rDa; \
|
||||||
|
ROLQ $1, rDa; \
|
||||||
|
\
|
||||||
|
MOVQ _bi(iState), rCi; \
|
||||||
|
XORQ _gi(iState), rDi; \
|
||||||
|
XORQ rCu, rDa; \
|
||||||
|
XORQ _ki(iState), rCi; \
|
||||||
|
XORQ _mi(iState), rDi; \
|
||||||
|
XORQ rDi, rCi; \
|
||||||
|
\
|
||||||
|
MOVQ rCi, rDe; \
|
||||||
|
ROLQ $1, rDe; \
|
||||||
|
\
|
||||||
|
MOVQ _bo(iState), rCo; \
|
||||||
|
XORQ _go(iState), rDo; \
|
||||||
|
XORQ rCa, rDe; \
|
||||||
|
XORQ _ko(iState), rCo; \
|
||||||
|
XORQ _mo(iState), rDo; \
|
||||||
|
XORQ rDo, rCo; \
|
||||||
|
\
|
||||||
|
MOVQ rCo, rDi; \
|
||||||
|
ROLQ $1, rDi; \
|
||||||
|
\
|
||||||
|
MOVQ rCu, rDo; \
|
||||||
|
XORQ rCe, rDi; \
|
||||||
|
ROLQ $1, rDo; \
|
||||||
|
\
|
||||||
|
MOVQ rCa, rDu; \
|
||||||
|
XORQ rCi, rDo; \
|
||||||
|
ROLQ $1, rDu; \
|
||||||
|
\
|
||||||
|
/* Result b */ \
|
||||||
|
MOVQ _ba(iState), rBa; \
|
||||||
|
MOVQ _ge(iState), rBe; \
|
||||||
|
XORQ rCo, rDu; \
|
||||||
|
MOVQ _ki(iState), rBi; \
|
||||||
|
MOVQ _mo(iState), rBo; \
|
||||||
|
MOVQ _su(iState), rBu; \
|
||||||
|
XORQ rDe, rBe; \
|
||||||
|
ROLQ $44, rBe; \
|
||||||
|
XORQ rDi, rBi; \
|
||||||
|
XORQ rDa, rBa; \
|
||||||
|
ROLQ $43, rBi; \
|
||||||
|
\
|
||||||
|
MOVQ rBe, rCa; \
|
||||||
|
MOVQ rc, rT1; \
|
||||||
|
ORQ rBi, rCa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
XORQ rT1, rCa; \
|
||||||
|
MOVQ rCa, _ba(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBu; \
|
||||||
|
ROLQ $14, rBu; \
|
||||||
|
MOVQ rBa, rCu; \
|
||||||
|
ANDQ rBe, rCu; \
|
||||||
|
XORQ rBu, rCu; \
|
||||||
|
MOVQ rCu, _bu(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBo; \
|
||||||
|
ROLQ $21, rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _bi(oState); \
|
||||||
|
\
|
||||||
|
NOTQ rBi; \
|
||||||
|
ORQ rBa, rBu; \
|
||||||
|
ORQ rBo, rBi; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
XORQ rBe, rBi; \
|
||||||
|
MOVQ rBu, _bo(oState); \
|
||||||
|
MOVQ rBi, _be(oState); \
|
||||||
|
B_RBI_RCE; \
|
||||||
|
\
|
||||||
|
/* Result g */ \
|
||||||
|
MOVQ _gu(iState), rBe; \
|
||||||
|
XORQ rDu, rBe; \
|
||||||
|
MOVQ _ka(iState), rBi; \
|
||||||
|
ROLQ $20, rBe; \
|
||||||
|
XORQ rDa, rBi; \
|
||||||
|
ROLQ $3, rBi; \
|
||||||
|
MOVQ _bo(iState), rBa; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDo, rBa; \
|
||||||
|
MOVQ _me(iState), rBo; \
|
||||||
|
MOVQ _si(iState), rBu; \
|
||||||
|
ROLQ $28, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ga(oState); \
|
||||||
|
G_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDe, rBo; \
|
||||||
|
ROLQ $45, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ge(oState); \
|
||||||
|
G_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBu; \
|
||||||
|
ROLQ $61, rBu; \
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _go(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _gu(oState); \
|
||||||
|
NOTQ rBu; \
|
||||||
|
G_RBA_RCU; \
|
||||||
|
\
|
||||||
|
ORQ rBu, rBo; \
|
||||||
|
XORQ rBi, rBo; \
|
||||||
|
MOVQ rBo, _gi(oState); \
|
||||||
|
\
|
||||||
|
/* Result k */ \
|
||||||
|
MOVQ _be(iState), rBa; \
|
||||||
|
MOVQ _gi(iState), rBe; \
|
||||||
|
MOVQ _ko(iState), rBi; \
|
||||||
|
MOVQ _mu(iState), rBo; \
|
||||||
|
MOVQ _sa(iState), rBu; \
|
||||||
|
XORQ rDi, rBe; \
|
||||||
|
ROLQ $6, rBe; \
|
||||||
|
XORQ rDo, rBi; \
|
||||||
|
ROLQ $25, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDe, rBa; \
|
||||||
|
ROLQ $1, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ka(oState); \
|
||||||
|
K_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBo; \
|
||||||
|
ROLQ $8, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ke(oState); \
|
||||||
|
K_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDa, rBu; \
|
||||||
|
ROLQ $18, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _ki(oState); \
|
||||||
|
\
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _ko(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _ku(oState); \
|
||||||
|
K_RBA_RCU; \
|
||||||
|
\
|
||||||
|
/* Result m */ \
|
||||||
|
MOVQ _ga(iState), rBe; \
|
||||||
|
XORQ rDa, rBe; \
|
||||||
|
MOVQ _ke(iState), rBi; \
|
||||||
|
ROLQ $36, rBe; \
|
||||||
|
XORQ rDe, rBi; \
|
||||||
|
MOVQ _bu(iState), rBa; \
|
||||||
|
ROLQ $10, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
MOVQ _mi(iState), rBo; \
|
||||||
|
ANDQ rBi, rT1; \
|
||||||
|
XORQ rDu, rBa; \
|
||||||
|
MOVQ _so(iState), rBu; \
|
||||||
|
ROLQ $27, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ma(oState); \
|
||||||
|
M_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBo; \
|
||||||
|
ROLQ $15, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ORQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _me(oState); \
|
||||||
|
M_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBu; \
|
||||||
|
ROLQ $56, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ORQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _mi(oState); \
|
||||||
|
\
|
||||||
|
ORQ rBa, rBe; \
|
||||||
|
XORQ rBu, rBe; \
|
||||||
|
MOVQ rBe, _mu(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBa, rBu; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
MOVQ rBu, _mo(oState); \
|
||||||
|
M_RBE_RCU; \
|
||||||
|
\
|
||||||
|
/* Result s */ \
|
||||||
|
MOVQ _bi(iState), rBa; \
|
||||||
|
MOVQ _go(iState), rBe; \
|
||||||
|
MOVQ _ku(iState), rBi; \
|
||||||
|
XORQ rDi, rBa; \
|
||||||
|
MOVQ _ma(iState), rBo; \
|
||||||
|
ROLQ $62, rBa; \
|
||||||
|
XORQ rDo, rBe; \
|
||||||
|
MOVQ _se(iState), rBu; \
|
||||||
|
ROLQ $55, rBe; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBi; \
|
||||||
|
MOVQ rBa, rDu; \
|
||||||
|
XORQ rDe, rBu; \
|
||||||
|
ROLQ $2, rBu; \
|
||||||
|
ANDQ rBe, rDu; \
|
||||||
|
XORQ rBu, rDu; \
|
||||||
|
MOVQ rDu, _su(oState); \
|
||||||
|
\
|
||||||
|
ROLQ $39, rBi; \
|
||||||
|
S_RDU_RCU; \
|
||||||
|
NOTQ rBe; \
|
||||||
|
XORQ rDa, rBo; \
|
||||||
|
MOVQ rBe, rDa; \
|
||||||
|
ANDQ rBi, rDa; \
|
||||||
|
XORQ rBa, rDa; \
|
||||||
|
MOVQ rDa, _sa(oState); \
|
||||||
|
S_RDA_RCA; \
|
||||||
|
\
|
||||||
|
ROLQ $41, rBo; \
|
||||||
|
MOVQ rBi, rDe; \
|
||||||
|
ORQ rBo, rDe; \
|
||||||
|
XORQ rBe, rDe; \
|
||||||
|
MOVQ rDe, _se(oState); \
|
||||||
|
S_RDE_RCE; \
|
||||||
|
\
|
||||||
|
MOVQ rBo, rDi; \
|
||||||
|
MOVQ rBu, rDo; \
|
||||||
|
ANDQ rBu, rDi; \
|
||||||
|
ORQ rBa, rDo; \
|
||||||
|
XORQ rBi, rDi; \
|
||||||
|
XORQ rBo, rDo; \
|
||||||
|
MOVQ rDi, _si(oState); \
|
||||||
|
MOVQ rDo, _so(oState) \
|
||||||
|
|
||||||
|
// func KeccakF1600(state *[25]uint64)
|
||||||
|
TEXT ·KeccakF1600(SB), 0, $200-8
|
||||||
|
MOVQ state+0(FP), rpState
|
||||||
|
|
||||||
|
// Convert the user state into an internal state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
// Execute the KeccakF permutation
|
||||||
|
MOVQ _ba(rpState), rCa
|
||||||
|
MOVQ _be(rpState), rCe
|
||||||
|
MOVQ _bu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ga(rpState), rCa
|
||||||
|
XORQ _ge(rpState), rCe
|
||||||
|
XORQ _gu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ka(rpState), rCa
|
||||||
|
XORQ _ke(rpState), rCe
|
||||||
|
XORQ _ku(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ma(rpState), rCa
|
||||||
|
XORQ _me(rpState), rCe
|
||||||
|
XORQ _mu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _sa(rpState), rCa
|
||||||
|
XORQ _se(rpState), rCe
|
||||||
|
MOVQ _si(rpState), rDi
|
||||||
|
MOVQ _so(rpState), rDo
|
||||||
|
XORQ _su(rpState), rCu
|
||||||
|
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
|
||||||
|
|
||||||
|
// Revert the internal state to the user state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
RET
|
|
@ -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,
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
case spongeSqueezing:
|
||||||
|
// If we're squeezing, we need to apply the permutation before
|
||||||
|
// copying more output.
|
||||||
|
KeccakF1600(&d.a)
|
||||||
|
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)
|
||||||
|
} 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...)
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,79 @@
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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:]
|
||||||
|
}
|
||||||
|
}
|
|
@ -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[:])
|
||||||
|
}
|
|
@ -0,0 +1,335 @@
|
||||||
|
// Package hybrid defines several hybrid classical/quantum KEMs.
|
||||||
|
//
|
||||||
|
// KEMs are combined by simple concatenation of shared secrets, cipher texts,
|
||||||
|
// public keys, etc, see
|
||||||
|
//
|
||||||
|
// https://datatracker.ietf.org/doc/draft-ietf-tls-hybrid-design/
|
||||||
|
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf
|
||||||
|
//
|
||||||
|
// Note that this is only fine if the shared secret is used in its entirety
|
||||||
|
// in a next step, such as being hashed or used as key.
|
||||||
|
//
|
||||||
|
// For deriving a KEM keypair deterministically and encapsulating
|
||||||
|
// deterministically, we expand a single seed to both using SHAKE256,
|
||||||
|
// so that a non-uniform seed (such as a shared secret generated by a hybrid
|
||||||
|
// KEM where one of the KEMs is weak) doesn't impact just one of the KEMs.
|
||||||
|
//
|
||||||
|
// Of our XOF (SHAKE256), we desire two security properties:
|
||||||
|
//
|
||||||
|
// 1. The internal state of the XOF should be big enough so that we
|
||||||
|
// do not loose entropy.
|
||||||
|
// 2. From one of the new seeds, we shouldn't be able to derive
|
||||||
|
// the other or the original seed.
|
||||||
|
//
|
||||||
|
// SHAKE256, and all siblings in the SHA3 family, have a 200B internal
|
||||||
|
// state, so (1) is fine if our seeds are less than 200B.
|
||||||
|
// If SHAKE256 is computationally indistinguishable from a random
|
||||||
|
// sponge, then it affords us 256b security against (2) by the
|
||||||
|
// flat sponge claim [https://keccak.team/files/SpongeFunctions.pdf].
|
||||||
|
// None of the implemented schemes claim more than 256b security
|
||||||
|
// and so SHAKE256 will do fine.
|
||||||
|
package hybrid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
"github.com/cloudflare/circl/kem/kyber/kyber1024"
|
||||||
|
"github.com/cloudflare/circl/kem/kyber/kyber512"
|
||||||
|
"github.com/cloudflare/circl/kem/kyber/kyber768"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrUninitialized = errors.New("public or private key not initialized")
|
||||||
|
|
||||||
|
// Returns the hybrid KEM of Kyber512 and X25519.
|
||||||
|
func Kyber512X25519() kem.Scheme { return kyber512X }
|
||||||
|
|
||||||
|
// Returns the hybrid KEM of Kyber768 and X25519.
|
||||||
|
func Kyber768X25519() kem.Scheme { return kyber768X }
|
||||||
|
|
||||||
|
// Returns the hybrid KEM of Kyber768 and X448.
|
||||||
|
func Kyber768X448() kem.Scheme { return kyber768X4 }
|
||||||
|
|
||||||
|
// Returns the hybrid KEM of Kyber1024 and X448.
|
||||||
|
func Kyber1024X448() kem.Scheme { return kyber1024X }
|
||||||
|
|
||||||
|
var kyber512X kem.Scheme = &scheme{
|
||||||
|
"Kyber512-X25519",
|
||||||
|
x25519Kem,
|
||||||
|
kyber512.Scheme(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var kyber768X kem.Scheme = &scheme{
|
||||||
|
"Kyber768-X25519",
|
||||||
|
x25519Kem,
|
||||||
|
kyber768.Scheme(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var kyber768X4 kem.Scheme = &scheme{
|
||||||
|
"Kyber768-X448",
|
||||||
|
x448Kem,
|
||||||
|
kyber768.Scheme(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var kyber1024X kem.Scheme = &scheme{
|
||||||
|
"Kyber1024-X448",
|
||||||
|
x448Kem,
|
||||||
|
kyber1024.Scheme(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public key of a hybrid KEM.
|
||||||
|
type publicKey struct {
|
||||||
|
scheme *scheme
|
||||||
|
first kem.PublicKey
|
||||||
|
second kem.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private key of a hybrid KEM.
|
||||||
|
type privateKey struct {
|
||||||
|
scheme *scheme
|
||||||
|
first kem.PrivateKey
|
||||||
|
second kem.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scheme for a hybrid KEM.
|
||||||
|
type scheme struct {
|
||||||
|
name string
|
||||||
|
first kem.Scheme
|
||||||
|
second kem.Scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) Name() string { return sch.name }
|
||||||
|
func (sch *scheme) PublicKeySize() int {
|
||||||
|
return sch.first.PublicKeySize() + sch.second.PublicKeySize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) PrivateKeySize() int {
|
||||||
|
return sch.first.PrivateKeySize() + sch.second.PrivateKeySize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) SeedSize() int {
|
||||||
|
first := sch.first.SeedSize()
|
||||||
|
second := sch.second.SeedSize()
|
||||||
|
ret := second
|
||||||
|
if first > second {
|
||||||
|
ret = first
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) SharedKeySize() int {
|
||||||
|
return sch.first.SharedKeySize() + sch.second.SharedKeySize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) CiphertextSize() int {
|
||||||
|
return sch.first.CiphertextSize() + sch.second.CiphertextSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) EncapsulationSeedSize() int {
|
||||||
|
first := sch.first.EncapsulationSeedSize()
|
||||||
|
second := sch.second.EncapsulationSeedSize()
|
||||||
|
ret := second
|
||||||
|
if first > second {
|
||||||
|
ret = first
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *privateKey) Scheme() kem.Scheme { return sk.scheme }
|
||||||
|
func (pk *publicKey) Scheme() kem.Scheme { return pk.scheme }
|
||||||
|
|
||||||
|
func (sk *privateKey) MarshalBinary() ([]byte, error) {
|
||||||
|
if sk.first == nil || sk.second == nil {
|
||||||
|
return nil, ErrUninitialized
|
||||||
|
}
|
||||||
|
first, err := sk.first.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
second, err := sk.second.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append(first, second...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *privateKey) Equal(other kem.PrivateKey) bool {
|
||||||
|
oth, ok := other.(*privateKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if sk.first == nil && sk.second == nil && oth.first == nil && oth.second == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if sk.first == nil || sk.second == nil || oth.first == nil || oth.second == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return sk.first.Equal(oth.first) && sk.second.Equal(oth.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *privateKey) Public() kem.PublicKey {
|
||||||
|
return &publicKey{sk.scheme, sk.first.Public(), sk.second.Public()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *publicKey) Equal(other kem.PublicKey) bool {
|
||||||
|
oth, ok := other.(*publicKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pk.first == nil && pk.second == nil && oth.first == nil && oth.second == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if pk.first == nil || pk.second == nil || oth.first == nil || oth.second == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return pk.first.Equal(oth.first) && pk.second.Equal(oth.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *publicKey) MarshalBinary() ([]byte, error) {
|
||||||
|
if pk.first == nil || pk.second == nil {
|
||||||
|
return nil, ErrUninitialized
|
||||||
|
}
|
||||||
|
first, err := pk.first.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
second, err := pk.second.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append(first, second...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
pk1, sk1, err := sch.first.GenerateKeyPair()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk2, sk2, err := sch.second.GenerateKeyPair()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
|
||||||
|
if len(seed) != sch.SeedSize() {
|
||||||
|
panic(kem.ErrSeedSize)
|
||||||
|
}
|
||||||
|
h := sha3.NewShake256()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
first := make([]byte, sch.first.SeedSize())
|
||||||
|
second := make([]byte, sch.second.SeedSize())
|
||||||
|
_, _ = h.Read(first)
|
||||||
|
_, _ = h.Read(second)
|
||||||
|
|
||||||
|
pk1, sk1 := sch.first.DeriveKeyPair(first)
|
||||||
|
pk2, sk2 := sch.second.DeriveKeyPair(second)
|
||||||
|
|
||||||
|
return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
|
||||||
|
pub, ok := pk.(*publicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
ct1, ss1, err := sch.first.Encapsulate(pub.first)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ct2, ss2, err := sch.second.Encapsulate(pub.second)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(ct1, ct2...), append(ss1, ss2...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) EncapsulateDeterministically(
|
||||||
|
pk kem.PublicKey, seed []byte,
|
||||||
|
) (ct, ss []byte, err error) {
|
||||||
|
if len(seed) != sch.EncapsulationSeedSize() {
|
||||||
|
return nil, nil, kem.ErrSeedSize
|
||||||
|
}
|
||||||
|
|
||||||
|
h := sha3.NewShake256()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
first := make([]byte, sch.first.EncapsulationSeedSize())
|
||||||
|
second := make([]byte, sch.second.EncapsulationSeedSize())
|
||||||
|
_, _ = h.Read(first)
|
||||||
|
_, _ = h.Read(second)
|
||||||
|
|
||||||
|
pub, ok := pk.(*publicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
ct1, ss1, err := sch.first.EncapsulateDeterministically(pub.first, first)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ct2, ss2, err := sch.second.EncapsulateDeterministically(pub.second, second)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return append(ct1, ct2...), append(ss1, ss2...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
|
||||||
|
if len(ct) != sch.CiphertextSize() {
|
||||||
|
return nil, kem.ErrCiphertextSize
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, ok := sk.(*privateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
firstSize := sch.first.CiphertextSize()
|
||||||
|
ss1, err := sch.first.Decapsulate(priv.first, ct[:firstSize])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ss2, err := sch.second.Decapsulate(priv.second, ct[firstSize:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append(ss1, ss2...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
|
||||||
|
if len(buf) != sch.PublicKeySize() {
|
||||||
|
return nil, kem.ErrPubKeySize
|
||||||
|
}
|
||||||
|
firstSize := sch.first.PublicKeySize()
|
||||||
|
pk1, err := sch.first.UnmarshalBinaryPublicKey(buf[:firstSize])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pk2, err := sch.second.UnmarshalBinaryPublicKey(buf[firstSize:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &publicKey{sch, pk1, pk2}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
|
||||||
|
if len(buf) != sch.PrivateKeySize() {
|
||||||
|
return nil, kem.ErrPrivKeySize
|
||||||
|
}
|
||||||
|
firstSize := sch.first.PrivateKeySize()
|
||||||
|
sk1, err := sch.first.UnmarshalBinaryPrivateKey(buf[:firstSize])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sk2, err := sch.second.UnmarshalBinaryPrivateKey(buf[firstSize:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &privateKey{sch, sk1, sk2}, nil
|
||||||
|
}
|
|
@ -0,0 +1,208 @@
|
||||||
|
package hybrid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"crypto/subtle"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/dh/x25519"
|
||||||
|
"github.com/cloudflare/circl/dh/x448"
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
)
|
||||||
|
|
||||||
|
type xPublicKey struct {
|
||||||
|
scheme *xScheme
|
||||||
|
key []byte
|
||||||
|
}
|
||||||
|
type xPrivateKey struct {
|
||||||
|
scheme *xScheme
|
||||||
|
key []byte
|
||||||
|
}
|
||||||
|
type xScheme struct {
|
||||||
|
size int
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
x25519Kem = &xScheme{x25519.Size}
|
||||||
|
x448Kem = &xScheme{x448.Size}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (sch *xScheme) Name() string {
|
||||||
|
switch sch.size {
|
||||||
|
case x25519.Size:
|
||||||
|
return "X25519"
|
||||||
|
case x448.Size:
|
||||||
|
return "X448"
|
||||||
|
}
|
||||||
|
panic(kem.ErrTypeMismatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) PublicKeySize() int { return sch.size }
|
||||||
|
func (sch *xScheme) PrivateKeySize() int { return sch.size }
|
||||||
|
func (sch *xScheme) SeedSize() int { return sch.size }
|
||||||
|
func (sch *xScheme) SharedKeySize() int { return sch.size }
|
||||||
|
func (sch *xScheme) CiphertextSize() int { return sch.size }
|
||||||
|
func (sch *xScheme) EncapsulationSeedSize() int { return sch.size }
|
||||||
|
|
||||||
|
func (sk *xPrivateKey) Scheme() kem.Scheme { return sk.scheme }
|
||||||
|
func (pk *xPublicKey) Scheme() kem.Scheme { return pk.scheme }
|
||||||
|
|
||||||
|
func (sk *xPrivateKey) MarshalBinary() ([]byte, error) {
|
||||||
|
ret := make([]byte, len(sk.key))
|
||||||
|
copy(ret, sk.key)
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *xPrivateKey) Equal(other kem.PrivateKey) bool {
|
||||||
|
oth, ok := other.(*xPrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if oth.scheme != sk.scheme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return subtle.ConstantTimeCompare(oth.key, sk.key) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *xPrivateKey) Public() kem.PublicKey {
|
||||||
|
pk := xPublicKey{sk.scheme, make([]byte, sk.scheme.size)}
|
||||||
|
switch sk.scheme.size {
|
||||||
|
case x25519.Size:
|
||||||
|
var sk2, pk2 x25519.Key
|
||||||
|
copy(sk2[:], sk.key)
|
||||||
|
x25519.KeyGen(&pk2, &sk2)
|
||||||
|
copy(pk.key, pk2[:])
|
||||||
|
case x448.Size:
|
||||||
|
var sk2, pk2 x448.Key
|
||||||
|
copy(sk2[:], sk.key)
|
||||||
|
x448.KeyGen(&pk2, &sk2)
|
||||||
|
copy(pk.key, pk2[:])
|
||||||
|
}
|
||||||
|
return &pk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *xPublicKey) Equal(other kem.PublicKey) bool {
|
||||||
|
oth, ok := other.(*xPublicKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if oth.scheme != pk.scheme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(oth.key, pk.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *xPublicKey) MarshalBinary() ([]byte, error) {
|
||||||
|
ret := make([]byte, pk.scheme.size)
|
||||||
|
copy(ret, pk.key)
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
seed := make([]byte, sch.SeedSize())
|
||||||
|
_, err := cryptoRand.Read(seed)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := sch.DeriveKeyPair(seed)
|
||||||
|
return pk, sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
|
||||||
|
if len(seed) != sch.SeedSize() {
|
||||||
|
panic(kem.ErrSeedSize)
|
||||||
|
}
|
||||||
|
sk := xPrivateKey{scheme: sch, key: make([]byte, sch.size)}
|
||||||
|
|
||||||
|
h := sha3.NewShake256()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
_, _ = h.Read(sk.key)
|
||||||
|
|
||||||
|
return sk.Public(), &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
|
||||||
|
seed := make([]byte, sch.EncapsulationSeedSize())
|
||||||
|
_, err = cryptoRand.Read(seed)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return sch.EncapsulateDeterministically(pk, seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *xPublicKey) X(sk *xPrivateKey) []byte {
|
||||||
|
if pk.scheme != sk.scheme {
|
||||||
|
panic(kem.ErrTypeMismatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pk.scheme.size {
|
||||||
|
case x25519.Size:
|
||||||
|
var ss2, pk2, sk2 x25519.Key
|
||||||
|
copy(pk2[:], pk.key)
|
||||||
|
copy(sk2[:], sk.key)
|
||||||
|
x25519.Shared(&ss2, &sk2, &pk2)
|
||||||
|
return ss2[:]
|
||||||
|
case x448.Size:
|
||||||
|
var ss2, pk2, sk2 x448.Key
|
||||||
|
copy(pk2[:], pk.key)
|
||||||
|
copy(sk2[:], sk.key)
|
||||||
|
x448.Shared(&ss2, &sk2, &pk2)
|
||||||
|
return ss2[:]
|
||||||
|
}
|
||||||
|
panic(kem.ErrTypeMismatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) EncapsulateDeterministically(
|
||||||
|
pk kem.PublicKey, seed []byte,
|
||||||
|
) (ct, ss []byte, err error) {
|
||||||
|
if len(seed) != sch.EncapsulationSeedSize() {
|
||||||
|
return nil, nil, kem.ErrSeedSize
|
||||||
|
}
|
||||||
|
pub, ok := pk.(*xPublicKey)
|
||||||
|
if !ok || pub.scheme != sch {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
pk2, sk2 := sch.DeriveKeyPair(seed)
|
||||||
|
ss = pub.X(sk2.(*xPrivateKey))
|
||||||
|
ct, _ = pk2.MarshalBinary()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
|
||||||
|
if len(ct) != sch.CiphertextSize() {
|
||||||
|
return nil, kem.ErrCiphertextSize
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, ok := sk.(*xPrivateKey)
|
||||||
|
if !ok || priv.scheme != sch {
|
||||||
|
return nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
pk, err := sch.UnmarshalBinaryPublicKey(ct)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ss := pk.(*xPublicKey).X(priv)
|
||||||
|
return ss, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
|
||||||
|
if len(buf) != sch.PublicKeySize() {
|
||||||
|
return nil, kem.ErrPubKeySize
|
||||||
|
}
|
||||||
|
ret := xPublicKey{sch, make([]byte, sch.size)}
|
||||||
|
copy(ret.key, buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sch *xScheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
|
||||||
|
if len(buf) != sch.PrivateKeySize() {
|
||||||
|
return nil, kem.ErrPrivKeySize
|
||||||
|
}
|
||||||
|
ret := xPrivateKey{sch, make([]byte, sch.size)}
|
||||||
|
copy(ret.key, buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
// Package kem provides a unified interface for KEM schemes.
|
||||||
|
//
|
||||||
|
// A register of schemes is available in the package
|
||||||
|
//
|
||||||
|
// github.com/cloudflare/circl/kem/schemes
|
||||||
|
package kem
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A KEM public key
|
||||||
|
type PublicKey interface {
|
||||||
|
// Returns the scheme for this public key
|
||||||
|
Scheme() Scheme
|
||||||
|
|
||||||
|
encoding.BinaryMarshaler
|
||||||
|
Equal(PublicKey) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// A KEM private key
|
||||||
|
type PrivateKey interface {
|
||||||
|
// Returns the scheme for this private key
|
||||||
|
Scheme() Scheme
|
||||||
|
|
||||||
|
encoding.BinaryMarshaler
|
||||||
|
Equal(PrivateKey) bool
|
||||||
|
Public() PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Scheme represents a specific instance of a KEM.
|
||||||
|
type Scheme interface {
|
||||||
|
// Name of the scheme
|
||||||
|
Name() string
|
||||||
|
|
||||||
|
// GenerateKeyPair creates a new key pair.
|
||||||
|
GenerateKeyPair() (PublicKey, PrivateKey, error)
|
||||||
|
|
||||||
|
// Encapsulate generates a shared key ss for the public key and
|
||||||
|
// encapsulates it into a ciphertext ct.
|
||||||
|
Encapsulate(pk PublicKey) (ct, ss []byte, err error)
|
||||||
|
|
||||||
|
// Returns the shared key encapsulated in ciphertext ct for the
|
||||||
|
// private key sk.
|
||||||
|
Decapsulate(sk PrivateKey, ct []byte) ([]byte, error)
|
||||||
|
|
||||||
|
// Unmarshals a PublicKey from the provided buffer.
|
||||||
|
UnmarshalBinaryPublicKey([]byte) (PublicKey, error)
|
||||||
|
|
||||||
|
// Unmarshals a PrivateKey from the provided buffer.
|
||||||
|
UnmarshalBinaryPrivateKey([]byte) (PrivateKey, error)
|
||||||
|
|
||||||
|
// Size of encapsulated keys.
|
||||||
|
CiphertextSize() int
|
||||||
|
|
||||||
|
// Size of established shared keys.
|
||||||
|
SharedKeySize() int
|
||||||
|
|
||||||
|
// Size of packed private keys.
|
||||||
|
PrivateKeySize() int
|
||||||
|
|
||||||
|
// Size of packed public keys.
|
||||||
|
PublicKeySize() int
|
||||||
|
|
||||||
|
// DeriveKeyPair deterministicallly derives a pair of keys from a seed.
|
||||||
|
// Panics if the length of seed is not equal to the value returned by
|
||||||
|
// SeedSize.
|
||||||
|
DeriveKeyPair(seed []byte) (PublicKey, PrivateKey)
|
||||||
|
|
||||||
|
// Size of seed used in DeriveKey
|
||||||
|
SeedSize() int
|
||||||
|
|
||||||
|
// EncapsulateDeterministically generates a shared key ss for the public
|
||||||
|
// key deterministically from the given seed and encapsulates it into
|
||||||
|
// a ciphertext ct. If unsure, you're better off using Encapsulate().
|
||||||
|
EncapsulateDeterministically(pk PublicKey, seed []byte) (
|
||||||
|
ct, ss []byte, err error)
|
||||||
|
|
||||||
|
// Size of seed used in EncapsulateDeterministically().
|
||||||
|
EncapsulationSeedSize() int
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthScheme represents a KEM that supports authenticated key encapsulation.
|
||||||
|
type AuthScheme interface {
|
||||||
|
Scheme
|
||||||
|
AuthEncapsulate(pkr PublicKey, sks PrivateKey) (ct, ss []byte, err error)
|
||||||
|
AuthEncapsulateDeterministically(pkr PublicKey, sks PrivateKey, seed []byte) (ct, ss []byte, err error)
|
||||||
|
AuthDecapsulate(skr PrivateKey, ct []byte, pks PublicKey) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrTypeMismatch is the error used if types of, for instance, private
|
||||||
|
// and public keys don't match
|
||||||
|
ErrTypeMismatch = errors.New("types mismatch")
|
||||||
|
|
||||||
|
// ErrSeedSize is the error used if the provided seed is of the wrong
|
||||||
|
// size.
|
||||||
|
ErrSeedSize = errors.New("wrong seed size")
|
||||||
|
|
||||||
|
// ErrPubKeySize is the error used if the provided public key is of
|
||||||
|
// the wrong size.
|
||||||
|
ErrPubKeySize = errors.New("wrong size for public key")
|
||||||
|
|
||||||
|
// ErrCiphertextSize is the error used if the provided ciphertext
|
||||||
|
// is of the wrong size.
|
||||||
|
ErrCiphertextSize = errors.New("wrong size for ciphertext")
|
||||||
|
|
||||||
|
// ErrPrivKeySize is the error used if the provided private key is of
|
||||||
|
// the wrong size.
|
||||||
|
ErrPrivKeySize = errors.New("wrong size for private key")
|
||||||
|
|
||||||
|
// ErrPubKey is the error used if the provided public key is invalid.
|
||||||
|
ErrPubKey = errors.New("invalid public key")
|
||||||
|
|
||||||
|
// ErrCipherText is the error used if the provided ciphertext is invalid.
|
||||||
|
ErrCipherText = errors.New("invalid ciphertext")
|
||||||
|
)
|
|
@ -0,0 +1,402 @@
|
||||||
|
// Code generated from pkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package kyber1024 implements the IND-CCA2 secure key encapsulation mechanism
|
||||||
|
// Kyber1024.CCAKEM as submitted to round 3 of the NIST PQC competition and
|
||||||
|
// described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber1024
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/subtle"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
cpapke "github.com/cloudflare/circl/pke/kyber/kyber1024"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = cpapke.KeySeedSize + 32
|
||||||
|
|
||||||
|
// Size of seed for EncapsulateTo.
|
||||||
|
EncapsulationSeedSize = 32
|
||||||
|
|
||||||
|
// Size of the established shared key.
|
||||||
|
SharedKeySize = 32
|
||||||
|
|
||||||
|
// Size of the encapsulated shared key.
|
||||||
|
CiphertextSize = cpapke.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a packed public key.
|
||||||
|
PublicKeySize = cpapke.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed private key.
|
||||||
|
PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// Type of a Kyber1024.CCAKEM public key
|
||||||
|
type PublicKey struct {
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type of a Kyber1024.CCAKEM private key
|
||||||
|
type PrivateKey struct {
|
||||||
|
sk *cpapke.PrivateKey
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
z [32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private keypair deterministically
|
||||||
|
// from the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var sk PrivateKey
|
||||||
|
var pk PublicKey
|
||||||
|
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
|
||||||
|
sk.pk = pk.pk
|
||||||
|
copy(sk.z[:], seed[cpapke.KeySeedSize:])
|
||||||
|
|
||||||
|
// Compute H(pk)
|
||||||
|
var ppk [cpapke.PublicKeySize]byte
|
||||||
|
sk.pk.Pack(ppk[:])
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ppk[:])
|
||||||
|
h.Read(sk.hpk[:])
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKeyPair generates public and private keys using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := NewKeyFromSeed(seed[:])
|
||||||
|
return pk, sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncapsulateTo generates a shared key and ciphertext that contains it
|
||||||
|
// for the public key using randomness from seed and writes the shared key
|
||||||
|
// to ss and ciphertext to ct.
|
||||||
|
//
|
||||||
|
// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
|
||||||
|
// and EncapsulationSeedSize respectively.
|
||||||
|
//
|
||||||
|
// seed may be nil, in which case crypto/rand.Reader is used to generate one.
|
||||||
|
func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
|
||||||
|
if seed == nil {
|
||||||
|
seed = make([]byte, EncapsulationSeedSize)
|
||||||
|
cryptoRand.Read(seed[:])
|
||||||
|
} else {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
panic("seed must be of length EncapsulationSeedSize")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m = H(seed)
|
||||||
|
var m [32]byte
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(seed[:])
|
||||||
|
h.Read(m[:])
|
||||||
|
|
||||||
|
// (K', r) = G(m ‖ H(pk))
|
||||||
|
var kr [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m[:])
|
||||||
|
g.Write(pk.hpk[:])
|
||||||
|
g.Read(kr[:])
|
||||||
|
|
||||||
|
// c = Kyber.CPAPKE.Enc(pk, m, r)
|
||||||
|
pk.pk.EncryptTo(ct, m[:], kr[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
|
||||||
|
h.Reset()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr[32:])
|
||||||
|
|
||||||
|
// K = KDF(K' ‖ H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecapsulateTo computes the shared key which is encapsulated in ct
|
||||||
|
// for the private key.
|
||||||
|
//
|
||||||
|
// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
|
||||||
|
// respectively.
|
||||||
|
func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m' = Kyber.CPAPKE.Dec(sk, ct)
|
||||||
|
var m2 [32]byte
|
||||||
|
sk.sk.DecryptTo(m2[:], ct)
|
||||||
|
|
||||||
|
// (K'', r') = G(m' ‖ H(pk))
|
||||||
|
var kr2 [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m2[:])
|
||||||
|
g.Write(sk.hpk[:])
|
||||||
|
g.Read(kr2[:])
|
||||||
|
|
||||||
|
// c' = Kyber.CPAPKE.Enc(pk, m', r')
|
||||||
|
var ct2 [CiphertextSize]byte
|
||||||
|
sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr2[32:])
|
||||||
|
|
||||||
|
// Replace K'' by z in the first slot of kr2 if c ≠ c'.
|
||||||
|
subtle.ConstantTimeCopy(
|
||||||
|
1-subtle.ConstantTimeCompare(ct, ct2[:]),
|
||||||
|
kr2[:32],
|
||||||
|
sk.z[:],
|
||||||
|
)
|
||||||
|
|
||||||
|
// K = KDF(K''/z, H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr2[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk.Pack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk.Pack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(buf, sk.hpk[:])
|
||||||
|
buf = buf[32:]
|
||||||
|
copy(buf, sk.z[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk = new(cpapke.PrivateKey)
|
||||||
|
sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk = new(cpapke.PublicKey)
|
||||||
|
sk.pk.Unpack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(sk.hpk[:], buf[:32])
|
||||||
|
copy(sk.z[:], buf[32:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk = new(cpapke.PublicKey)
|
||||||
|
pk.pk.Unpack(buf)
|
||||||
|
|
||||||
|
// Compute cached H(pk)
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(buf)
|
||||||
|
h.Read(pk.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boilerplate down below for the KEM scheme API.
|
||||||
|
|
||||||
|
type scheme struct{}
|
||||||
|
|
||||||
|
var sch kem.Scheme = &scheme{}
|
||||||
|
|
||||||
|
// Scheme returns a KEM interface.
|
||||||
|
func Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (*scheme) Name() string { return "Kyber1024" }
|
||||||
|
func (*scheme) PublicKeySize() int { return PublicKeySize }
|
||||||
|
func (*scheme) PrivateKeySize() int { return PrivateKeySize }
|
||||||
|
func (*scheme) SeedSize() int { return KeySeedSize }
|
||||||
|
func (*scheme) SharedKeySize() int { return SharedKeySize }
|
||||||
|
func (*scheme) CiphertextSize() int { return CiphertextSize }
|
||||||
|
func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
|
||||||
|
func (pk *PublicKey) Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PrivateKeySize]byte
|
||||||
|
sk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
|
||||||
|
oth, ok := other.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if sk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if sk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
|
||||||
|
!bytes.Equal(sk.z[:], oth.z[:]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return sk.sk.Equal(oth.sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) Equal(other kem.PublicKey) bool {
|
||||||
|
oth, ok := other.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if pk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(pk.hpk[:], oth.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Public() kem.PublicKey {
|
||||||
|
pk := new(PublicKey)
|
||||||
|
pk.pk = sk.pk
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
return pk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PublicKeySize]byte
|
||||||
|
pk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
return GenerateKeyPair(cryptoRand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic(kem.ErrSeedSize)
|
||||||
|
}
|
||||||
|
return NewKeyFromSeed(seed[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
|
||||||
|
ct, ss []byte, err error) {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
return nil, nil, kem.ErrSeedSize
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
return nil, kem.ErrCiphertextSize
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, ok := sk.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
ss := make([]byte, SharedKeySize)
|
||||||
|
priv.DecapsulateTo(ss, ct)
|
||||||
|
return ss, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
return nil, kem.ErrPubKeySize
|
||||||
|
}
|
||||||
|
var ret PublicKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
return nil, kem.ErrPrivKeySize
|
||||||
|
}
|
||||||
|
var ret PrivateKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,402 @@
|
||||||
|
// Code generated from pkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package kyber512 implements the IND-CCA2 secure key encapsulation mechanism
|
||||||
|
// Kyber512.CCAKEM as submitted to round 3 of the NIST PQC competition and
|
||||||
|
// described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber512
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/subtle"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
cpapke "github.com/cloudflare/circl/pke/kyber/kyber512"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = cpapke.KeySeedSize + 32
|
||||||
|
|
||||||
|
// Size of seed for EncapsulateTo.
|
||||||
|
EncapsulationSeedSize = 32
|
||||||
|
|
||||||
|
// Size of the established shared key.
|
||||||
|
SharedKeySize = 32
|
||||||
|
|
||||||
|
// Size of the encapsulated shared key.
|
||||||
|
CiphertextSize = cpapke.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a packed public key.
|
||||||
|
PublicKeySize = cpapke.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed private key.
|
||||||
|
PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// Type of a Kyber512.CCAKEM public key
|
||||||
|
type PublicKey struct {
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type of a Kyber512.CCAKEM private key
|
||||||
|
type PrivateKey struct {
|
||||||
|
sk *cpapke.PrivateKey
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
z [32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private keypair deterministically
|
||||||
|
// from the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var sk PrivateKey
|
||||||
|
var pk PublicKey
|
||||||
|
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
|
||||||
|
sk.pk = pk.pk
|
||||||
|
copy(sk.z[:], seed[cpapke.KeySeedSize:])
|
||||||
|
|
||||||
|
// Compute H(pk)
|
||||||
|
var ppk [cpapke.PublicKeySize]byte
|
||||||
|
sk.pk.Pack(ppk[:])
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ppk[:])
|
||||||
|
h.Read(sk.hpk[:])
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKeyPair generates public and private keys using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := NewKeyFromSeed(seed[:])
|
||||||
|
return pk, sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncapsulateTo generates a shared key and ciphertext that contains it
|
||||||
|
// for the public key using randomness from seed and writes the shared key
|
||||||
|
// to ss and ciphertext to ct.
|
||||||
|
//
|
||||||
|
// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
|
||||||
|
// and EncapsulationSeedSize respectively.
|
||||||
|
//
|
||||||
|
// seed may be nil, in which case crypto/rand.Reader is used to generate one.
|
||||||
|
func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
|
||||||
|
if seed == nil {
|
||||||
|
seed = make([]byte, EncapsulationSeedSize)
|
||||||
|
cryptoRand.Read(seed[:])
|
||||||
|
} else {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
panic("seed must be of length EncapsulationSeedSize")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m = H(seed)
|
||||||
|
var m [32]byte
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(seed[:])
|
||||||
|
h.Read(m[:])
|
||||||
|
|
||||||
|
// (K', r) = G(m ‖ H(pk))
|
||||||
|
var kr [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m[:])
|
||||||
|
g.Write(pk.hpk[:])
|
||||||
|
g.Read(kr[:])
|
||||||
|
|
||||||
|
// c = Kyber.CPAPKE.Enc(pk, m, r)
|
||||||
|
pk.pk.EncryptTo(ct, m[:], kr[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
|
||||||
|
h.Reset()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr[32:])
|
||||||
|
|
||||||
|
// K = KDF(K' ‖ H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecapsulateTo computes the shared key which is encapsulated in ct
|
||||||
|
// for the private key.
|
||||||
|
//
|
||||||
|
// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
|
||||||
|
// respectively.
|
||||||
|
func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m' = Kyber.CPAPKE.Dec(sk, ct)
|
||||||
|
var m2 [32]byte
|
||||||
|
sk.sk.DecryptTo(m2[:], ct)
|
||||||
|
|
||||||
|
// (K'', r') = G(m' ‖ H(pk))
|
||||||
|
var kr2 [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m2[:])
|
||||||
|
g.Write(sk.hpk[:])
|
||||||
|
g.Read(kr2[:])
|
||||||
|
|
||||||
|
// c' = Kyber.CPAPKE.Enc(pk, m', r')
|
||||||
|
var ct2 [CiphertextSize]byte
|
||||||
|
sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr2[32:])
|
||||||
|
|
||||||
|
// Replace K'' by z in the first slot of kr2 if c ≠ c'.
|
||||||
|
subtle.ConstantTimeCopy(
|
||||||
|
1-subtle.ConstantTimeCompare(ct, ct2[:]),
|
||||||
|
kr2[:32],
|
||||||
|
sk.z[:],
|
||||||
|
)
|
||||||
|
|
||||||
|
// K = KDF(K''/z, H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr2[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk.Pack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk.Pack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(buf, sk.hpk[:])
|
||||||
|
buf = buf[32:]
|
||||||
|
copy(buf, sk.z[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk = new(cpapke.PrivateKey)
|
||||||
|
sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk = new(cpapke.PublicKey)
|
||||||
|
sk.pk.Unpack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(sk.hpk[:], buf[:32])
|
||||||
|
copy(sk.z[:], buf[32:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk = new(cpapke.PublicKey)
|
||||||
|
pk.pk.Unpack(buf)
|
||||||
|
|
||||||
|
// Compute cached H(pk)
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(buf)
|
||||||
|
h.Read(pk.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boilerplate down below for the KEM scheme API.
|
||||||
|
|
||||||
|
type scheme struct{}
|
||||||
|
|
||||||
|
var sch kem.Scheme = &scheme{}
|
||||||
|
|
||||||
|
// Scheme returns a KEM interface.
|
||||||
|
func Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (*scheme) Name() string { return "Kyber512" }
|
||||||
|
func (*scheme) PublicKeySize() int { return PublicKeySize }
|
||||||
|
func (*scheme) PrivateKeySize() int { return PrivateKeySize }
|
||||||
|
func (*scheme) SeedSize() int { return KeySeedSize }
|
||||||
|
func (*scheme) SharedKeySize() int { return SharedKeySize }
|
||||||
|
func (*scheme) CiphertextSize() int { return CiphertextSize }
|
||||||
|
func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
|
||||||
|
func (pk *PublicKey) Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PrivateKeySize]byte
|
||||||
|
sk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
|
||||||
|
oth, ok := other.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if sk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if sk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
|
||||||
|
!bytes.Equal(sk.z[:], oth.z[:]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return sk.sk.Equal(oth.sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) Equal(other kem.PublicKey) bool {
|
||||||
|
oth, ok := other.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if pk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(pk.hpk[:], oth.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Public() kem.PublicKey {
|
||||||
|
pk := new(PublicKey)
|
||||||
|
pk.pk = sk.pk
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
return pk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PublicKeySize]byte
|
||||||
|
pk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
return GenerateKeyPair(cryptoRand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic(kem.ErrSeedSize)
|
||||||
|
}
|
||||||
|
return NewKeyFromSeed(seed[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
|
||||||
|
ct, ss []byte, err error) {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
return nil, nil, kem.ErrSeedSize
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
return nil, kem.ErrCiphertextSize
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, ok := sk.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
ss := make([]byte, SharedKeySize)
|
||||||
|
priv.DecapsulateTo(ss, ct)
|
||||||
|
return ss, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
return nil, kem.ErrPubKeySize
|
||||||
|
}
|
||||||
|
var ret PublicKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
return nil, kem.ErrPrivKeySize
|
||||||
|
}
|
||||||
|
var ret PrivateKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,402 @@
|
||||||
|
// Code generated from pkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package kyber768 implements the IND-CCA2 secure key encapsulation mechanism
|
||||||
|
// Kyber768.CCAKEM as submitted to round 3 of the NIST PQC competition and
|
||||||
|
// described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber768
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/subtle"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
cpapke "github.com/cloudflare/circl/pke/kyber/kyber768"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = cpapke.KeySeedSize + 32
|
||||||
|
|
||||||
|
// Size of seed for EncapsulateTo.
|
||||||
|
EncapsulationSeedSize = 32
|
||||||
|
|
||||||
|
// Size of the established shared key.
|
||||||
|
SharedKeySize = 32
|
||||||
|
|
||||||
|
// Size of the encapsulated shared key.
|
||||||
|
CiphertextSize = cpapke.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a packed public key.
|
||||||
|
PublicKeySize = cpapke.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed private key.
|
||||||
|
PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// Type of a Kyber768.CCAKEM public key
|
||||||
|
type PublicKey struct {
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type of a Kyber768.CCAKEM private key
|
||||||
|
type PrivateKey struct {
|
||||||
|
sk *cpapke.PrivateKey
|
||||||
|
pk *cpapke.PublicKey
|
||||||
|
hpk [32]byte // H(pk)
|
||||||
|
z [32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private keypair deterministically
|
||||||
|
// from the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var sk PrivateKey
|
||||||
|
var pk PublicKey
|
||||||
|
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
|
||||||
|
sk.pk = pk.pk
|
||||||
|
copy(sk.z[:], seed[cpapke.KeySeedSize:])
|
||||||
|
|
||||||
|
// Compute H(pk)
|
||||||
|
var ppk [cpapke.PublicKeySize]byte
|
||||||
|
sk.pk.Pack(ppk[:])
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ppk[:])
|
||||||
|
h.Read(sk.hpk[:])
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKeyPair generates public and private keys using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := NewKeyFromSeed(seed[:])
|
||||||
|
return pk, sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncapsulateTo generates a shared key and ciphertext that contains it
|
||||||
|
// for the public key using randomness from seed and writes the shared key
|
||||||
|
// to ss and ciphertext to ct.
|
||||||
|
//
|
||||||
|
// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
|
||||||
|
// and EncapsulationSeedSize respectively.
|
||||||
|
//
|
||||||
|
// seed may be nil, in which case crypto/rand.Reader is used to generate one.
|
||||||
|
func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
|
||||||
|
if seed == nil {
|
||||||
|
seed = make([]byte, EncapsulationSeedSize)
|
||||||
|
cryptoRand.Read(seed[:])
|
||||||
|
} else {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
panic("seed must be of length EncapsulationSeedSize")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m = H(seed)
|
||||||
|
var m [32]byte
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(seed[:])
|
||||||
|
h.Read(m[:])
|
||||||
|
|
||||||
|
// (K', r) = G(m ‖ H(pk))
|
||||||
|
var kr [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m[:])
|
||||||
|
g.Write(pk.hpk[:])
|
||||||
|
g.Read(kr[:])
|
||||||
|
|
||||||
|
// c = Kyber.CPAPKE.Enc(pk, m, r)
|
||||||
|
pk.pk.EncryptTo(ct, m[:], kr[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
|
||||||
|
h.Reset()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr[32:])
|
||||||
|
|
||||||
|
// K = KDF(K' ‖ H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecapsulateTo computes the shared key which is encapsulated in ct
|
||||||
|
// for the private key.
|
||||||
|
//
|
||||||
|
// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
|
||||||
|
// respectively.
|
||||||
|
func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ss) != SharedKeySize {
|
||||||
|
panic("ss must be of length SharedKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
// m' = Kyber.CPAPKE.Dec(sk, ct)
|
||||||
|
var m2 [32]byte
|
||||||
|
sk.sk.DecryptTo(m2[:], ct)
|
||||||
|
|
||||||
|
// (K'', r') = G(m' ‖ H(pk))
|
||||||
|
var kr2 [64]byte
|
||||||
|
g := sha3.New512()
|
||||||
|
g.Write(m2[:])
|
||||||
|
g.Write(sk.hpk[:])
|
||||||
|
g.Read(kr2[:])
|
||||||
|
|
||||||
|
// c' = Kyber.CPAPKE.Enc(pk, m', r')
|
||||||
|
var ct2 [CiphertextSize]byte
|
||||||
|
sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
|
||||||
|
|
||||||
|
// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(ct[:CiphertextSize])
|
||||||
|
h.Read(kr2[32:])
|
||||||
|
|
||||||
|
// Replace K'' by z in the first slot of kr2 if c ≠ c'.
|
||||||
|
subtle.ConstantTimeCopy(
|
||||||
|
1-subtle.ConstantTimeCompare(ct, ct2[:]),
|
||||||
|
kr2[:32],
|
||||||
|
sk.z[:],
|
||||||
|
)
|
||||||
|
|
||||||
|
// K = KDF(K''/z, H(c))
|
||||||
|
kdf := sha3.NewShake256()
|
||||||
|
kdf.Write(kr2[:])
|
||||||
|
kdf.Read(ss[:SharedKeySize])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk.Pack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk.Pack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(buf, sk.hpk[:])
|
||||||
|
buf = buf[32:]
|
||||||
|
copy(buf, sk.z[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of length PrivateKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
sk.sk = new(cpapke.PrivateKey)
|
||||||
|
sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
|
||||||
|
buf = buf[cpapke.PrivateKeySize:]
|
||||||
|
sk.pk = new(cpapke.PublicKey)
|
||||||
|
sk.pk.Unpack(buf[:cpapke.PublicKeySize])
|
||||||
|
buf = buf[cpapke.PublicKeySize:]
|
||||||
|
copy(sk.hpk[:], buf[:32])
|
||||||
|
copy(sk.z[:], buf[32:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk to buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from buf.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of size PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of length PublicKeySize")
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.pk = new(cpapke.PublicKey)
|
||||||
|
pk.pk.Unpack(buf)
|
||||||
|
|
||||||
|
// Compute cached H(pk)
|
||||||
|
h := sha3.New256()
|
||||||
|
h.Write(buf)
|
||||||
|
h.Read(pk.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boilerplate down below for the KEM scheme API.
|
||||||
|
|
||||||
|
type scheme struct{}
|
||||||
|
|
||||||
|
var sch kem.Scheme = &scheme{}
|
||||||
|
|
||||||
|
// Scheme returns a KEM interface.
|
||||||
|
func Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (*scheme) Name() string { return "Kyber768" }
|
||||||
|
func (*scheme) PublicKeySize() int { return PublicKeySize }
|
||||||
|
func (*scheme) PrivateKeySize() int { return PrivateKeySize }
|
||||||
|
func (*scheme) SeedSize() int { return KeySeedSize }
|
||||||
|
func (*scheme) SharedKeySize() int { return SharedKeySize }
|
||||||
|
func (*scheme) CiphertextSize() int { return CiphertextSize }
|
||||||
|
func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
|
||||||
|
func (pk *PublicKey) Scheme() kem.Scheme { return sch }
|
||||||
|
|
||||||
|
func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PrivateKeySize]byte
|
||||||
|
sk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
|
||||||
|
oth, ok := other.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if sk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if sk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
|
||||||
|
!bytes.Equal(sk.z[:], oth.z[:]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return sk.sk.Equal(oth.sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) Equal(other kem.PublicKey) bool {
|
||||||
|
oth, ok := other.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pk.pk == nil && oth.pk == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if pk.pk == nil || oth.pk == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(pk.hpk[:], oth.hpk[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk *PrivateKey) Public() kem.PublicKey {
|
||||||
|
pk := new(PublicKey)
|
||||||
|
pk.pk = sk.pk
|
||||||
|
copy(pk.hpk[:], sk.hpk[:])
|
||||||
|
return pk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pk *PublicKey) MarshalBinary() ([]byte, error) {
|
||||||
|
var ret [PublicKeySize]byte
|
||||||
|
pk.Pack(ret[:])
|
||||||
|
return ret[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
return GenerateKeyPair(cryptoRand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic(kem.ErrSeedSize)
|
||||||
|
}
|
||||||
|
return NewKeyFromSeed(seed[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
|
||||||
|
ct, ss []byte, err error) {
|
||||||
|
if len(seed) != EncapsulationSeedSize {
|
||||||
|
return nil, nil, kem.ErrSeedSize
|
||||||
|
}
|
||||||
|
|
||||||
|
ct = make([]byte, CiphertextSize)
|
||||||
|
ss = make([]byte, SharedKeySize)
|
||||||
|
|
||||||
|
pub, ok := pk.(*PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
pub.EncapsulateTo(ct, ss, seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
return nil, kem.ErrCiphertextSize
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, ok := sk.(*PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, kem.ErrTypeMismatch
|
||||||
|
}
|
||||||
|
ss := make([]byte, SharedKeySize)
|
||||||
|
priv.DecapsulateTo(ss, ct)
|
||||||
|
return ss, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
return nil, kem.ErrPubKeySize
|
||||||
|
}
|
||||||
|
var ret PublicKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
return nil, kem.ErrPrivKeySize
|
||||||
|
}
|
||||||
|
var ret PrivateKey
|
||||||
|
ret.Unpack(buf)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
|
@ -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) }
|
|
@ -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)
|
|
@ -0,0 +1,350 @@
|
||||||
|
// 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) \
|
||||||
|
MOVQ 0+y, DX; XORL AX, AX; \
|
||||||
|
MULXQ 0+x, AX, R8; MOVQ AX, 0+z; \
|
||||||
|
MULXQ 8+x, AX, R9; ADCXQ AX, R8; \
|
||||||
|
MULXQ 16+x, AX, R10; ADCXQ AX, R9; \
|
||||||
|
MULXQ 24+x, AX, R11; ADCXQ AX, R10; \
|
||||||
|
MOVL $0, AX;;;;;;;;; ADCXQ AX, R11; \
|
||||||
|
MOVQ 8+y, DX; XORL AX, AX; \
|
||||||
|
MULXQ 0+x, AX, R12; ADCXQ R8, AX; MOVQ AX, 8+z; \
|
||||||
|
MULXQ 8+x, AX, R13; ADCXQ R9, R12; ADOXQ AX, R12; \
|
||||||
|
MULXQ 16+x, AX, R14; ADCXQ R10, R13; ADOXQ AX, R13; \
|
||||||
|
MULXQ 24+x, AX, R15; ADCXQ R11, R14; ADOXQ AX, R14; \
|
||||||
|
MOVL $0, AX;;;;;;;;; ADCXQ AX, R15; ADOXQ AX, R15; \
|
||||||
|
MOVQ 16+y, DX; XORL AX, AX; \
|
||||||
|
MULXQ 0+x, AX, R8; ADCXQ R12, AX; MOVQ AX, 16+z; \
|
||||||
|
MULXQ 8+x, AX, R9; ADCXQ R13, R8; ADOXQ AX, R8; \
|
||||||
|
MULXQ 16+x, AX, R10; ADCXQ R14, R9; ADOXQ AX, R9; \
|
||||||
|
MULXQ 24+x, AX, R11; ADCXQ R15, R10; ADOXQ AX, R10; \
|
||||||
|
MOVL $0, AX;;;;;;;;; ADCXQ AX, R11; ADOXQ AX, R11; \
|
||||||
|
MOVQ 24+y, DX; XORL AX, AX; \
|
||||||
|
MULXQ 0+x, AX, R12; ADCXQ R8, AX; MOVQ AX, 24+z; \
|
||||||
|
MULXQ 8+x, AX, R13; ADCXQ R9, R12; ADOXQ AX, R12; MOVQ R12, 32+z; \
|
||||||
|
MULXQ 16+x, AX, R14; ADCXQ R10, R13; ADOXQ AX, R13; MOVQ R13, 40+z; \
|
||||||
|
MULXQ 24+x, AX, R15; ADCXQ R11, R14; ADOXQ AX, R14; MOVQ R14, 48+z; \
|
||||||
|
MOVL $0, AX;;;;;;;;; ADCXQ AX, R15; ADOXQ AX, R15; MOVQ R15, 56+z;
|
||||||
|
|
||||||
|
// integerMulLeg multiplies x and y and stores in z
|
||||||
|
// Uses: AX, DX, R8-R15, FLAGS
|
||||||
|
// Instr: x86_64
|
||||||
|
#define integerMulLeg(z,x,y) \
|
||||||
|
MOVQ 0+y, R8; \
|
||||||
|
MOVQ 0+x, AX; MULQ R8; MOVQ AX, 0+z; MOVQ DX, R15; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
|
||||||
|
MOVQ 24+x, AX; MULQ R8; \
|
||||||
|
ADDQ R13, R15; \
|
||||||
|
ADCQ R14, R10; MOVQ R10, 16+z; \
|
||||||
|
ADCQ AX, R11; MOVQ R11, 24+z; \
|
||||||
|
ADCQ $0, DX; MOVQ DX, 32+z; \
|
||||||
|
MOVQ 8+y, R8; \
|
||||||
|
MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
|
||||||
|
MOVQ 24+x, AX; MULQ R8; \
|
||||||
|
ADDQ R12, R15; MOVQ R15, 8+z; \
|
||||||
|
ADCQ R13, R9; \
|
||||||
|
ADCQ R14, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
ADCQ 16+z, R9; MOVQ R9, R15; \
|
||||||
|
ADCQ 24+z, R10; MOVQ R10, 24+z; \
|
||||||
|
ADCQ 32+z, R11; MOVQ R11, 32+z; \
|
||||||
|
ADCQ $0, DX; MOVQ DX, 40+z; \
|
||||||
|
MOVQ 16+y, R8; \
|
||||||
|
MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
|
||||||
|
MOVQ 24+x, AX; MULQ R8; \
|
||||||
|
ADDQ R12, R15; MOVQ R15, 16+z; \
|
||||||
|
ADCQ R13, R9; \
|
||||||
|
ADCQ R14, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
ADCQ 24+z, R9; MOVQ R9, R15; \
|
||||||
|
ADCQ 32+z, R10; MOVQ R10, 32+z; \
|
||||||
|
ADCQ 40+z, R11; MOVQ R11, 40+z; \
|
||||||
|
ADCQ $0, DX; MOVQ DX, 48+z; \
|
||||||
|
MOVQ 24+y, R8; \
|
||||||
|
MOVQ 0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX, R9; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
|
||||||
|
MOVQ 24+x, AX; MULQ R8; \
|
||||||
|
ADDQ R12, R15; MOVQ R15, 24+z; \
|
||||||
|
ADCQ R13, R9; \
|
||||||
|
ADCQ R14, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
ADCQ 32+z, R9; MOVQ R9, 32+z; \
|
||||||
|
ADCQ 40+z, R10; MOVQ R10, 40+z; \
|
||||||
|
ADCQ 48+z, R11; MOVQ R11, 48+z; \
|
||||||
|
ADCQ $0, DX; MOVQ DX, 56+z;
|
||||||
|
|
||||||
|
// integerSqrLeg squares x and stores in z
|
||||||
|
// Uses: AX, CX, DX, R8-R15, FLAGS
|
||||||
|
// Instr: x86_64
|
||||||
|
#define integerSqrLeg(z,x) \
|
||||||
|
MOVQ 0+x, R8; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, R9; MOVQ DX, R10; /* A[0]*A[1] */ \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; /* A[0]*A[2] */ \
|
||||||
|
MOVQ 24+x, AX; MULQ R8; MOVQ AX, R15; MOVQ DX, R12; /* A[0]*A[3] */ \
|
||||||
|
MOVQ 24+x, R8; \
|
||||||
|
MOVQ 8+x, AX; MULQ R8; MOVQ AX, CX; MOVQ DX, R13; /* A[3]*A[1] */ \
|
||||||
|
MOVQ 16+x, AX; MULQ R8; /* A[3]*A[2] */ \
|
||||||
|
\
|
||||||
|
ADDQ R14, R10;\
|
||||||
|
ADCQ R15, R11; MOVL $0, R15;\
|
||||||
|
ADCQ CX, R12;\
|
||||||
|
ADCQ AX, R13;\
|
||||||
|
ADCQ $0, DX; MOVQ DX, R14;\
|
||||||
|
MOVQ 8+x, AX; MULQ 16+x;\
|
||||||
|
\
|
||||||
|
ADDQ AX, R11;\
|
||||||
|
ADCQ DX, R12;\
|
||||||
|
ADCQ $0, R13;\
|
||||||
|
ADCQ $0, R14;\
|
||||||
|
ADCQ $0, R15;\
|
||||||
|
\
|
||||||
|
SHLQ $1, R14, R15; MOVQ R15, 56+z;\
|
||||||
|
SHLQ $1, R13, R14; MOVQ R14, 48+z;\
|
||||||
|
SHLQ $1, R12, R13; MOVQ R13, 40+z;\
|
||||||
|
SHLQ $1, R11, R12; MOVQ R12, 32+z;\
|
||||||
|
SHLQ $1, R10, R11; MOVQ R11, 24+z;\
|
||||||
|
SHLQ $1, R9, R10; MOVQ R10, 16+z;\
|
||||||
|
SHLQ $1, R9; MOVQ R9, 8+z;\
|
||||||
|
\
|
||||||
|
MOVQ 0+x,AX; MULQ AX; MOVQ AX, 0+z; MOVQ DX, R9;\
|
||||||
|
MOVQ 8+x,AX; MULQ AX; MOVQ AX, R10; MOVQ DX, R11;\
|
||||||
|
MOVQ 16+x,AX; MULQ AX; MOVQ AX, R12; MOVQ DX, R13;\
|
||||||
|
MOVQ 24+x,AX; MULQ AX; MOVQ AX, R14; MOVQ DX, R15;\
|
||||||
|
\
|
||||||
|
ADDQ 8+z, R9; MOVQ R9, 8+z;\
|
||||||
|
ADCQ 16+z, R10; MOVQ R10, 16+z;\
|
||||||
|
ADCQ 24+z, R11; MOVQ R11, 24+z;\
|
||||||
|
ADCQ 32+z, R12; MOVQ R12, 32+z;\
|
||||||
|
ADCQ 40+z, R13; MOVQ R13, 40+z;\
|
||||||
|
ADCQ 48+z, R14; MOVQ R14, 48+z;\
|
||||||
|
ADCQ 56+z, R15; MOVQ R15, 56+z;
|
||||||
|
|
||||||
|
// integerSqrAdx squares x and stores in z
|
||||||
|
// Uses: AX, CX, DX, R8-R15, FLAGS
|
||||||
|
// Instr: x86_64, bmi2, adx
|
||||||
|
#define integerSqrAdx(z,x) \
|
||||||
|
MOVQ 0+x, DX; /* A[0] */ \
|
||||||
|
MULXQ 8+x, R8, R14; /* A[1]*A[0] */ XORL R15, R15; \
|
||||||
|
MULXQ 16+x, R9, R10; /* A[2]*A[0] */ ADCXQ R14, R9; \
|
||||||
|
MULXQ 24+x, AX, CX; /* A[3]*A[0] */ ADCXQ AX, R10; \
|
||||||
|
MOVQ 24+x, DX; /* A[3] */ \
|
||||||
|
MULXQ 8+x, R11, R12; /* A[1]*A[3] */ ADCXQ CX, R11; \
|
||||||
|
MULXQ 16+x, AX, R13; /* A[2]*A[3] */ ADCXQ AX, R12; \
|
||||||
|
MOVQ 8+x, DX; /* A[1] */ ADCXQ R15, R13; \
|
||||||
|
MULXQ 16+x, AX, CX; /* A[2]*A[1] */ MOVL $0, R14; \
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADCXQ R15, R14; \
|
||||||
|
XORL R15, R15; \
|
||||||
|
ADOXQ AX, R10; ADCXQ R8, R8; \
|
||||||
|
ADOXQ CX, R11; ADCXQ R9, R9; \
|
||||||
|
ADOXQ R15, R12; ADCXQ R10, R10; \
|
||||||
|
ADOXQ R15, R13; ADCXQ R11, R11; \
|
||||||
|
ADOXQ R15, R14; ADCXQ R12, R12; \
|
||||||
|
;;;;;;;;;;;;;;; ADCXQ R13, R13; \
|
||||||
|
;;;;;;;;;;;;;;; ADCXQ R14, R14; \
|
||||||
|
MOVQ 0+x, DX; MULXQ DX, AX, CX; /* A[0]^2 */ \
|
||||||
|
;;;;;;;;;;;;;;; MOVQ AX, 0+z; \
|
||||||
|
ADDQ CX, R8; MOVQ R8, 8+z; \
|
||||||
|
MOVQ 8+x, DX; MULXQ DX, AX, CX; /* A[1]^2 */ \
|
||||||
|
ADCQ AX, R9; MOVQ R9, 16+z; \
|
||||||
|
ADCQ CX, R10; MOVQ R10, 24+z; \
|
||||||
|
MOVQ 16+x, DX; MULXQ DX, AX, CX; /* A[2]^2 */ \
|
||||||
|
ADCQ AX, R11; MOVQ R11, 32+z; \
|
||||||
|
ADCQ CX, R12; MOVQ R12, 40+z; \
|
||||||
|
MOVQ 24+x, DX; MULXQ DX, AX, CX; /* A[3]^2 */ \
|
||||||
|
ADCQ AX, R13; MOVQ R13, 48+z; \
|
||||||
|
ADCQ CX, R14; MOVQ R14, 56+z;
|
||||||
|
|
||||||
|
// reduceFromDouble finds z congruent to x modulo p such that 0<z<2^256
|
||||||
|
// Uses: AX, DX, R8-R13, FLAGS
|
||||||
|
// Instr: x86_64
|
||||||
|
#define reduceFromDoubleLeg(z,x) \
|
||||||
|
/* 2*C = 38 = 2^256 */ \
|
||||||
|
MOVL $38, AX; MULQ 32+x; MOVQ AX, R8; MOVQ DX, R9; /* C*C[4] */ \
|
||||||
|
MOVL $38, AX; MULQ 40+x; MOVQ AX, R12; MOVQ DX, R10; /* C*C[5] */ \
|
||||||
|
MOVL $38, AX; MULQ 48+x; MOVQ AX, R13; MOVQ DX, R11; /* C*C[6] */ \
|
||||||
|
MOVL $38, AX; MULQ 56+x; /* C*C[7] */ \
|
||||||
|
ADDQ R12, R9; \
|
||||||
|
ADCQ R13, R10; \
|
||||||
|
ADCQ AX, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
ADDQ 0+x, R8; \
|
||||||
|
ADCQ 8+x, R9; \
|
||||||
|
ADCQ 16+x, R10; \
|
||||||
|
ADCQ 24+x, R11; \
|
||||||
|
ADCQ $0, DX; \
|
||||||
|
MOVL $38, AX; \
|
||||||
|
IMULQ AX, DX; /* C*C[4], CF=0, OF=0 */ \
|
||||||
|
ADDQ DX, R8; \
|
||||||
|
ADCQ $0, R9; MOVQ R9, 8+z; \
|
||||||
|
ADCQ $0, R10; MOVQ R10, 16+z; \
|
||||||
|
ADCQ $0, R11; MOVQ R11, 24+z; \
|
||||||
|
MOVL $0, DX; \
|
||||||
|
CMOVQCS AX, DX; \
|
||||||
|
ADDQ DX, R8; MOVQ R8, 0+z;
|
||||||
|
|
||||||
|
// reduceFromDoubleAdx finds z congruent to x modulo p such that 0<z<2^256
|
||||||
|
// Uses: AX, DX, R8-R13, FLAGS
|
||||||
|
// Instr: x86_64, bmi2, adx
|
||||||
|
#define reduceFromDoubleAdx(z,x) \
|
||||||
|
MOVL $38, DX; /* 2*C = 38 = 2^256 */ \
|
||||||
|
MULXQ 32+x, R8, R10; /* C*C[4] */ XORL AX, AX; ADOXQ 0+x, R8; \
|
||||||
|
MULXQ 40+x, R9, R11; /* C*C[5] */ ADCXQ R10, R9; ADOXQ 8+x, R9; \
|
||||||
|
MULXQ 48+x, R10, R13; /* C*C[6] */ ADCXQ R11, R10; ADOXQ 16+x, R10; \
|
||||||
|
MULXQ 56+x, R11, R12; /* C*C[7] */ ADCXQ R13, R11; ADOXQ 24+x, R11; \
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADCXQ AX, R12; ADOXQ AX, R12; \
|
||||||
|
IMULQ DX, R12; /* C*C[4], CF=0, OF=0 */ \
|
||||||
|
ADCXQ R12, R8; \
|
||||||
|
ADCXQ AX, R9; MOVQ R9, 8+z; \
|
||||||
|
ADCXQ AX, R10; MOVQ R10, 16+z; \
|
||||||
|
ADCXQ AX, R11; MOVQ R11, 24+z; \
|
||||||
|
MOVL $0, R12; \
|
||||||
|
CMOVQCS DX, R12; \
|
||||||
|
ADDQ R12, R8; MOVQ R8, 0+z;
|
||||||
|
|
||||||
|
// addSub calculates two operations: x,y = x+y,x-y
|
||||||
|
// Uses: AX, DX, R8-R15, FLAGS
|
||||||
|
#define addSub(x,y) \
|
||||||
|
MOVL $38, AX; \
|
||||||
|
XORL DX, DX; \
|
||||||
|
MOVQ 0+x, R8; MOVQ R8, R12; ADDQ 0+y, R8; \
|
||||||
|
MOVQ 8+x, R9; MOVQ R9, R13; ADCQ 8+y, R9; \
|
||||||
|
MOVQ 16+x, R10; MOVQ R10, R14; ADCQ 16+y, R10; \
|
||||||
|
MOVQ 24+x, R11; MOVQ R11, R15; ADCQ 24+y, R11; \
|
||||||
|
CMOVQCS AX, DX; \
|
||||||
|
XORL AX, AX; \
|
||||||
|
ADDQ DX, R8; \
|
||||||
|
ADCQ $0, R9; \
|
||||||
|
ADCQ $0, R10; \
|
||||||
|
ADCQ $0, R11; \
|
||||||
|
MOVL $38, DX; \
|
||||||
|
CMOVQCS DX, AX; \
|
||||||
|
ADDQ AX, R8; \
|
||||||
|
MOVL $38, AX; \
|
||||||
|
SUBQ 0+y, R12; \
|
||||||
|
SBBQ 8+y, R13; \
|
||||||
|
SBBQ 16+y, R14; \
|
||||||
|
SBBQ 24+y, R15; \
|
||||||
|
MOVL $0, DX; \
|
||||||
|
CMOVQCS AX, DX; \
|
||||||
|
SUBQ DX, R12; \
|
||||||
|
SBBQ $0, R13; \
|
||||||
|
SBBQ $0, R14; \
|
||||||
|
SBBQ $0, R15; \
|
||||||
|
MOVL $0, DX; \
|
||||||
|
CMOVQCS AX, DX; \
|
||||||
|
SUBQ DX, R12; \
|
||||||
|
MOVQ R8, 0+x; \
|
||||||
|
MOVQ R9, 8+x; \
|
||||||
|
MOVQ R10, 16+x; \
|
||||||
|
MOVQ R11, 24+x; \
|
||||||
|
MOVQ R12, 0+y; \
|
||||||
|
MOVQ R13, 8+y; \
|
||||||
|
MOVQ R14, 16+y; \
|
||||||
|
MOVQ R15, 24+y;
|
|
@ -0,0 +1,111 @@
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
#include "fp_amd64.h"
|
||||||
|
|
||||||
|
// func cmovAmd64(x, y *Elt, n uint)
|
||||||
|
TEXT ·cmovAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
MOVQ n+16(FP), BX
|
||||||
|
cselect(0(DI),0(SI),BX)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func cswapAmd64(x, y *Elt, n uint)
|
||||||
|
TEXT ·cswapAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
MOVQ n+16(FP), BX
|
||||||
|
cswap(0(DI),0(SI),BX)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func subAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·subAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
subtraction(0(DI),0(SI),0(BX))
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func addsubAmd64(x, y *Elt)
|
||||||
|
TEXT ·addsubAmd64(SB),NOSPLIT,$0-16
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
addSub(0(DI),0(SI))
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define addLegacy \
|
||||||
|
additionLeg(0(DI),0(SI),0(BX))
|
||||||
|
#define addBmi2Adx \
|
||||||
|
additionAdx(0(DI),0(SI),0(BX))
|
||||||
|
|
||||||
|
#define mulLegacy \
|
||||||
|
integerMulLeg(0(SP),0(SI),0(BX)) \
|
||||||
|
reduceFromDoubleLeg(0(DI),0(SP))
|
||||||
|
#define mulBmi2Adx \
|
||||||
|
integerMulAdx(0(SP),0(SI),0(BX)) \
|
||||||
|
reduceFromDoubleAdx(0(DI),0(SP))
|
||||||
|
|
||||||
|
#define sqrLegacy \
|
||||||
|
integerSqrLeg(0(SP),0(SI)) \
|
||||||
|
reduceFromDoubleLeg(0(DI),0(SP))
|
||||||
|
#define sqrBmi2Adx \
|
||||||
|
integerSqrAdx(0(SP),0(SI)) \
|
||||||
|
reduceFromDoubleAdx(0(DI),0(SP))
|
||||||
|
|
||||||
|
// func addAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·addAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
CHECK_BMI2ADX(LADD, addLegacy, addBmi2Adx)
|
||||||
|
|
||||||
|
// func mulAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·mulAmd64(SB),NOSPLIT,$64-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
CHECK_BMI2ADX(LMUL, mulLegacy, mulBmi2Adx)
|
||||||
|
|
||||||
|
// func sqrAmd64(z, x *Elt)
|
||||||
|
TEXT ·sqrAmd64(SB),NOSPLIT,$64-16
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LSQR, sqrLegacy, sqrBmi2Adx)
|
||||||
|
|
||||||
|
// func modpAmd64(z *Elt)
|
||||||
|
TEXT ·modpAmd64(SB),NOSPLIT,$0-8
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
|
||||||
|
MOVQ (DI), R8
|
||||||
|
MOVQ 8(DI), R9
|
||||||
|
MOVQ 16(DI), R10
|
||||||
|
MOVQ 24(DI), R11
|
||||||
|
|
||||||
|
MOVL $19, AX
|
||||||
|
MOVL $38, CX
|
||||||
|
|
||||||
|
BTRQ $63, R11 // PUT BIT 255 IN CARRY FLAG AND CLEAR
|
||||||
|
CMOVLCC AX, CX // C[255] ? 38 : 19
|
||||||
|
|
||||||
|
// ADD EITHER 19 OR 38 TO C
|
||||||
|
ADDQ CX, R8
|
||||||
|
ADCQ $0, R9
|
||||||
|
ADCQ $0, R10
|
||||||
|
ADCQ $0, R11
|
||||||
|
|
||||||
|
// TEST FOR BIT 255 AGAIN; ONLY TRIGGERED ON OVERFLOW MODULO 2^255-19
|
||||||
|
MOVL $0, CX
|
||||||
|
CMOVLPL AX, CX // C[255] ? 0 : 19
|
||||||
|
BTRQ $63, R11 // CLEAR BIT 255
|
||||||
|
|
||||||
|
// SUBTRACT 19 IF NECESSARY
|
||||||
|
SUBQ CX, R8
|
||||||
|
MOVQ R8, (DI)
|
||||||
|
SBBQ $0, R9
|
||||||
|
MOVQ R9, 8(DI)
|
||||||
|
SBBQ $0, R10
|
||||||
|
MOVQ R10, 16(DI)
|
||||||
|
SBBQ $0, R11
|
||||||
|
MOVQ R11, 24(DI)
|
||||||
|
RET
|
|
@ -0,0 +1,317 @@
|
||||||
|
package fp25519
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"math/bits"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cmovGeneric(x, y *Elt, n uint) {
|
||||||
|
m := -uint64(n & 0x1)
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
|
||||||
|
y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
|
||||||
|
y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
|
||||||
|
y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
|
||||||
|
|
||||||
|
x0 = (x0 &^ m) | (y0 & m)
|
||||||
|
x1 = (x1 &^ m) | (y1 & m)
|
||||||
|
x2 = (x2 &^ m) | (y2 & m)
|
||||||
|
x3 = (x3 &^ m) | (y3 & m)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
|
||||||
|
binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
|
||||||
|
binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
|
||||||
|
binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cswapGeneric(x, y *Elt, n uint) {
|
||||||
|
m := -uint64(n & 0x1)
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
|
||||||
|
y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
|
||||||
|
y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
|
||||||
|
y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
|
||||||
|
|
||||||
|
t0 := m & (x0 ^ y0)
|
||||||
|
t1 := m & (x1 ^ y1)
|
||||||
|
t2 := m & (x2 ^ y2)
|
||||||
|
t3 := m & (x3 ^ y3)
|
||||||
|
x0 ^= t0
|
||||||
|
x1 ^= t1
|
||||||
|
x2 ^= t2
|
||||||
|
x3 ^= t3
|
||||||
|
y0 ^= t0
|
||||||
|
y1 ^= t1
|
||||||
|
y2 ^= t2
|
||||||
|
y3 ^= t3
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
|
||||||
|
binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
|
||||||
|
binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
|
||||||
|
binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
|
||||||
|
binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
|
||||||
|
binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
|
||||||
|
binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addGeneric(z, x, y *Elt) {
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
|
||||||
|
y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
|
||||||
|
y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
|
||||||
|
y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
|
||||||
|
|
||||||
|
z0, c0 := bits.Add64(x0, y0, 0)
|
||||||
|
z1, c1 := bits.Add64(x1, y1, c0)
|
||||||
|
z2, c2 := bits.Add64(x2, y2, c1)
|
||||||
|
z3, c3 := bits.Add64(x3, y3, c2)
|
||||||
|
|
||||||
|
z0, c0 = bits.Add64(z0, (-c3)&38, 0)
|
||||||
|
z1, c1 = bits.Add64(z1, 0, c0)
|
||||||
|
z2, c2 = bits.Add64(z2, 0, c1)
|
||||||
|
z3, c3 = bits.Add64(z3, 0, c2)
|
||||||
|
z0, _ = bits.Add64(z0, (-c3)&38, 0)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
|
||||||
|
binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
|
||||||
|
binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
|
||||||
|
binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func subGeneric(z, x, y *Elt) {
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
|
||||||
|
y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
|
||||||
|
y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
|
||||||
|
y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
|
||||||
|
|
||||||
|
z0, c0 := bits.Sub64(x0, y0, 0)
|
||||||
|
z1, c1 := bits.Sub64(x1, y1, c0)
|
||||||
|
z2, c2 := bits.Sub64(x2, y2, c1)
|
||||||
|
z3, c3 := bits.Sub64(x3, y3, c2)
|
||||||
|
|
||||||
|
z0, c0 = bits.Sub64(z0, (-c3)&38, 0)
|
||||||
|
z1, c1 = bits.Sub64(z1, 0, c0)
|
||||||
|
z2, c2 = bits.Sub64(z2, 0, c1)
|
||||||
|
z3, c3 = bits.Sub64(z3, 0, c2)
|
||||||
|
z0, _ = bits.Sub64(z0, (-c3)&38, 0)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
|
||||||
|
binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
|
||||||
|
binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
|
||||||
|
binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addsubGeneric(x, y *Elt) {
|
||||||
|
z := &Elt{}
|
||||||
|
addGeneric(z, x, y)
|
||||||
|
subGeneric(y, x, y)
|
||||||
|
*x = *z
|
||||||
|
}
|
||||||
|
|
||||||
|
func mulGeneric(z, x, y *Elt) {
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
|
||||||
|
y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
|
||||||
|
y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
|
||||||
|
y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
|
||||||
|
|
||||||
|
yi := y0
|
||||||
|
h0, l0 := bits.Mul64(x0, yi)
|
||||||
|
h1, l1 := bits.Mul64(x1, yi)
|
||||||
|
h2, l2 := bits.Mul64(x2, yi)
|
||||||
|
h3, l3 := bits.Mul64(x3, yi)
|
||||||
|
|
||||||
|
z0 := l0
|
||||||
|
a0, c0 := bits.Add64(h0, l1, 0)
|
||||||
|
a1, c1 := bits.Add64(h1, l2, c0)
|
||||||
|
a2, c2 := bits.Add64(h2, l3, c1)
|
||||||
|
a3, _ := bits.Add64(h3, 0, c2)
|
||||||
|
|
||||||
|
yi = y1
|
||||||
|
h0, l0 = bits.Mul64(x0, yi)
|
||||||
|
h1, l1 = bits.Mul64(x1, yi)
|
||||||
|
h2, l2 = bits.Mul64(x2, yi)
|
||||||
|
h3, l3 = bits.Mul64(x3, yi)
|
||||||
|
|
||||||
|
z1, c0 := bits.Add64(a0, l0, 0)
|
||||||
|
h0, c1 = bits.Add64(h0, l1, c0)
|
||||||
|
h1, c2 = bits.Add64(h1, l2, c1)
|
||||||
|
h2, c3 := bits.Add64(h2, l3, c2)
|
||||||
|
h3, _ = bits.Add64(h3, 0, c3)
|
||||||
|
|
||||||
|
a0, c0 = bits.Add64(a1, h0, 0)
|
||||||
|
a1, c1 = bits.Add64(a2, h1, c0)
|
||||||
|
a2, c2 = bits.Add64(a3, h2, c1)
|
||||||
|
a3, _ = bits.Add64(0, h3, c2)
|
||||||
|
|
||||||
|
yi = y2
|
||||||
|
h0, l0 = bits.Mul64(x0, yi)
|
||||||
|
h1, l1 = bits.Mul64(x1, yi)
|
||||||
|
h2, l2 = bits.Mul64(x2, yi)
|
||||||
|
h3, l3 = bits.Mul64(x3, yi)
|
||||||
|
|
||||||
|
z2, c0 := bits.Add64(a0, l0, 0)
|
||||||
|
h0, c1 = bits.Add64(h0, l1, c0)
|
||||||
|
h1, c2 = bits.Add64(h1, l2, c1)
|
||||||
|
h2, c3 = bits.Add64(h2, l3, c2)
|
||||||
|
h3, _ = bits.Add64(h3, 0, c3)
|
||||||
|
|
||||||
|
a0, c0 = bits.Add64(a1, h0, 0)
|
||||||
|
a1, c1 = bits.Add64(a2, h1, c0)
|
||||||
|
a2, c2 = bits.Add64(a3, h2, c1)
|
||||||
|
a3, _ = bits.Add64(0, h3, c2)
|
||||||
|
|
||||||
|
yi = y3
|
||||||
|
h0, l0 = bits.Mul64(x0, yi)
|
||||||
|
h1, l1 = bits.Mul64(x1, yi)
|
||||||
|
h2, l2 = bits.Mul64(x2, yi)
|
||||||
|
h3, l3 = bits.Mul64(x3, yi)
|
||||||
|
|
||||||
|
z3, c0 := bits.Add64(a0, l0, 0)
|
||||||
|
h0, c1 = bits.Add64(h0, l1, c0)
|
||||||
|
h1, c2 = bits.Add64(h1, l2, c1)
|
||||||
|
h2, c3 = bits.Add64(h2, l3, c2)
|
||||||
|
h3, _ = bits.Add64(h3, 0, c3)
|
||||||
|
|
||||||
|
z4, c0 := bits.Add64(a1, h0, 0)
|
||||||
|
z5, c1 := bits.Add64(a2, h1, c0)
|
||||||
|
z6, c2 := bits.Add64(a3, h2, c1)
|
||||||
|
z7, _ := bits.Add64(0, h3, c2)
|
||||||
|
|
||||||
|
red64(z, z0, z1, z2, z3, z4, z5, z6, z7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sqrGeneric(z, x *Elt) {
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
h0, a0 := bits.Mul64(x0, x1)
|
||||||
|
h1, l1 := bits.Mul64(x0, x2)
|
||||||
|
h2, l2 := bits.Mul64(x0, x3)
|
||||||
|
h3, l3 := bits.Mul64(x3, x1)
|
||||||
|
h4, l4 := bits.Mul64(x3, x2)
|
||||||
|
h, l := bits.Mul64(x1, x2)
|
||||||
|
|
||||||
|
a1, c0 := bits.Add64(l1, h0, 0)
|
||||||
|
a2, c1 := bits.Add64(l2, h1, c0)
|
||||||
|
a3, c2 := bits.Add64(l3, h2, c1)
|
||||||
|
a4, c3 := bits.Add64(l4, h3, c2)
|
||||||
|
a5, _ := bits.Add64(h4, 0, c3)
|
||||||
|
|
||||||
|
a2, c0 = bits.Add64(a2, l, 0)
|
||||||
|
a3, c1 = bits.Add64(a3, h, c0)
|
||||||
|
a4, c2 = bits.Add64(a4, 0, c1)
|
||||||
|
a5, c3 = bits.Add64(a5, 0, c2)
|
||||||
|
a6, _ := bits.Add64(0, 0, c3)
|
||||||
|
|
||||||
|
a0, c0 = bits.Add64(a0, a0, 0)
|
||||||
|
a1, c1 = bits.Add64(a1, a1, c0)
|
||||||
|
a2, c2 = bits.Add64(a2, a2, c1)
|
||||||
|
a3, c3 = bits.Add64(a3, a3, c2)
|
||||||
|
a4, c4 := bits.Add64(a4, a4, c3)
|
||||||
|
a5, c5 := bits.Add64(a5, a5, c4)
|
||||||
|
a6, _ = bits.Add64(a6, a6, c5)
|
||||||
|
|
||||||
|
b1, b0 := bits.Mul64(x0, x0)
|
||||||
|
b3, b2 := bits.Mul64(x1, x1)
|
||||||
|
b5, b4 := bits.Mul64(x2, x2)
|
||||||
|
b7, b6 := bits.Mul64(x3, x3)
|
||||||
|
|
||||||
|
b1, c0 = bits.Add64(b1, a0, 0)
|
||||||
|
b2, c1 = bits.Add64(b2, a1, c0)
|
||||||
|
b3, c2 = bits.Add64(b3, a2, c1)
|
||||||
|
b4, c3 = bits.Add64(b4, a3, c2)
|
||||||
|
b5, c4 = bits.Add64(b5, a4, c3)
|
||||||
|
b6, c5 = bits.Add64(b6, a5, c4)
|
||||||
|
b7, _ = bits.Add64(b7, a6, c5)
|
||||||
|
|
||||||
|
red64(z, b0, b1, b2, b3, b4, b5, b6, b7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func modpGeneric(x *Elt) {
|
||||||
|
x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
|
||||||
|
x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
|
||||||
|
x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
|
||||||
|
x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
|
||||||
|
|
||||||
|
// CX = C[255] ? 38 : 19
|
||||||
|
cx := uint64(19) << (x3 >> 63)
|
||||||
|
// PUT BIT 255 IN CARRY FLAG AND CLEAR
|
||||||
|
x3 &^= 1 << 63
|
||||||
|
|
||||||
|
x0, c0 := bits.Add64(x0, cx, 0)
|
||||||
|
x1, c1 := bits.Add64(x1, 0, c0)
|
||||||
|
x2, c2 := bits.Add64(x2, 0, c1)
|
||||||
|
x3, _ = bits.Add64(x3, 0, c2)
|
||||||
|
|
||||||
|
// TEST FOR BIT 255 AGAIN; ONLY TRIGGERED ON OVERFLOW MODULO 2^255-19
|
||||||
|
// cx = C[255] ? 0 : 19
|
||||||
|
cx = uint64(19) &^ (-(x3 >> 63))
|
||||||
|
// CLEAR BIT 255
|
||||||
|
x3 &^= 1 << 63
|
||||||
|
|
||||||
|
x0, c0 = bits.Sub64(x0, cx, 0)
|
||||||
|
x1, c1 = bits.Sub64(x1, 0, c0)
|
||||||
|
x2, c2 = bits.Sub64(x2, 0, c1)
|
||||||
|
x3, _ = bits.Sub64(x3, 0, c2)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
|
||||||
|
binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
|
||||||
|
binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
|
||||||
|
binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func red64(z *Elt, x0, x1, x2, x3, x4, x5, x6, x7 uint64) {
|
||||||
|
h0, l0 := bits.Mul64(x4, 38)
|
||||||
|
h1, l1 := bits.Mul64(x5, 38)
|
||||||
|
h2, l2 := bits.Mul64(x6, 38)
|
||||||
|
h3, l3 := bits.Mul64(x7, 38)
|
||||||
|
|
||||||
|
l1, c0 := bits.Add64(h0, l1, 0)
|
||||||
|
l2, c1 := bits.Add64(h1, l2, c0)
|
||||||
|
l3, c2 := bits.Add64(h2, l3, c1)
|
||||||
|
l4, _ := bits.Add64(h3, 0, c2)
|
||||||
|
|
||||||
|
l0, c0 = bits.Add64(l0, x0, 0)
|
||||||
|
l1, c1 = bits.Add64(l1, x1, c0)
|
||||||
|
l2, c2 = bits.Add64(l2, x2, c1)
|
||||||
|
l3, c3 := bits.Add64(l3, x3, c2)
|
||||||
|
l4, _ = bits.Add64(l4, 0, c3)
|
||||||
|
|
||||||
|
_, l4 = bits.Mul64(l4, 38)
|
||||||
|
l0, c0 = bits.Add64(l0, l4, 0)
|
||||||
|
z1, c1 := bits.Add64(l1, 0, c0)
|
||||||
|
z2, c2 := bits.Add64(l2, 0, c1)
|
||||||
|
z3, c3 := bits.Add64(l3, 0, c2)
|
||||||
|
z0, _ := bits.Add64(l0, (-c3)&38, 0)
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
|
||||||
|
binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
|
||||||
|
binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
|
||||||
|
binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
|
||||||
|
}
|
|
@ -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) }
|
|
@ -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) }
|
|
@ -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)
|
|
@ -0,0 +1,590 @@
|
||||||
|
// 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) \
|
||||||
|
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;
|
|
@ -0,0 +1,74 @@
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
#include "fp_amd64.h"
|
||||||
|
|
||||||
|
// func cmovAmd64(x, y *Elt, n uint)
|
||||||
|
TEXT ·cmovAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
MOVQ n+16(FP), BX
|
||||||
|
cselect(0(DI),0(SI),BX)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func cswapAmd64(x, y *Elt, n uint)
|
||||||
|
TEXT ·cswapAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
MOVQ n+16(FP), BX
|
||||||
|
cswap(0(DI),0(SI),BX)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func subAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·subAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
subtraction(0(DI),0(SI),0(BX))
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func addsubAmd64(x, y *Elt)
|
||||||
|
TEXT ·addsubAmd64(SB),NOSPLIT,$0-16
|
||||||
|
MOVQ x+0(FP), DI
|
||||||
|
MOVQ y+8(FP), SI
|
||||||
|
addSub(0(DI),0(SI))
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define addLegacy \
|
||||||
|
additionLeg(0(DI),0(SI),0(BX))
|
||||||
|
#define addBmi2Adx \
|
||||||
|
additionAdx(0(DI),0(SI),0(BX))
|
||||||
|
|
||||||
|
#define mulLegacy \
|
||||||
|
integerMulLeg(0(SP),0(SI),0(BX)) \
|
||||||
|
reduceFromDoubleLeg(0(DI),0(SP))
|
||||||
|
#define mulBmi2Adx \
|
||||||
|
integerMulAdx(0(SP),0(SI),0(BX)) \
|
||||||
|
reduceFromDoubleAdx(0(DI),0(SP))
|
||||||
|
|
||||||
|
#define sqrLegacy \
|
||||||
|
integerSqrLeg(0(SP),0(SI)) \
|
||||||
|
reduceFromDoubleLeg(0(DI),0(SP))
|
||||||
|
#define sqrBmi2Adx \
|
||||||
|
integerSqrAdx(0(SP),0(SI)) \
|
||||||
|
reduceFromDoubleAdx(0(DI),0(SP))
|
||||||
|
|
||||||
|
// func addAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·addAmd64(SB),NOSPLIT,$0-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
CHECK_BMI2ADX(LADD, addLegacy, addBmi2Adx)
|
||||||
|
|
||||||
|
// func mulAmd64(z, x, y *Elt)
|
||||||
|
TEXT ·mulAmd64(SB),NOSPLIT,$112-24
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
MOVQ y+16(FP), BX
|
||||||
|
CHECK_BMI2ADX(LMUL, mulLegacy, mulBmi2Adx)
|
||||||
|
|
||||||
|
// func sqrAmd64(z, x *Elt)
|
||||||
|
TEXT ·sqrAmd64(SB),NOSPLIT,$112-16
|
||||||
|
MOVQ z+0(FP), DI
|
||||||
|
MOVQ x+8(FP), SI
|
||||||
|
CHECK_BMI2ADX(LSQR, sqrLegacy, sqrBmi2Adx)
|
|
@ -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)
|
||||||
|
}
|
|
@ -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) }
|
|
@ -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
|
||||||
|
}
|
302
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go
generated
vendored
Normal file
302
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZetasAVX2 contains all ζ used in NTT (like the Zetas array), but also
|
||||||
|
// the values int16(zeta * 62209) for each zeta, which is used in
|
||||||
|
// Montgomery reduction. There is some duplication and reordering as
|
||||||
|
// compared to Zetas to make it more covenient for use with AVX2.
|
||||||
|
var ZetasAVX2 = [...]int16{
|
||||||
|
// level 1: int16(Zetas[1]*62209) and Zetas[1]
|
||||||
|
31499, 2571,
|
||||||
|
|
||||||
|
// level 2
|
||||||
|
//
|
||||||
|
// int16(Zetas[2]*62209), Zetas[2], int16(Zetas[3]*62209), Zetas[3]
|
||||||
|
14746, 2970, 788, 1812,
|
||||||
|
|
||||||
|
// level 3, like level 2.
|
||||||
|
13525, 1493, -12402, 1422, 28191, 287, -16694, 202,
|
||||||
|
|
||||||
|
0, 0, // padding
|
||||||
|
|
||||||
|
// layer 4. offset: 1*16
|
||||||
|
//
|
||||||
|
// The precomputed multiplication and zetas are grouped by 16 at a
|
||||||
|
// time as used in the set of butterflies, etc.
|
||||||
|
-20906, -20906, -20906, -20906, -20906, -20906, -20906, -20906,
|
||||||
|
27758, 27758, 27758, 27758, 27758, 27758, 27758, 27758,
|
||||||
|
3158, 3158, 3158, 3158, 3158, 3158, 3158, 3158,
|
||||||
|
622, 622, 622, 622, 622, 622, 622, 622,
|
||||||
|
-3799, -3799, -3799, -3799, -3799, -3799, -3799, -3799,
|
||||||
|
-15690, -15690, -15690, -15690, -15690, -15690, -15690, -15690,
|
||||||
|
1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577,
|
||||||
|
182, 182, 182, 182, 182, 182, 182, 182,
|
||||||
|
10690, 10690, 10690, 10690, 10690, 10690, 10690, 10690,
|
||||||
|
1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
|
||||||
|
962, 962, 962, 962, 962, 962, 962, 962,
|
||||||
|
2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127,
|
||||||
|
-11201, -11201, -11201, -11201, -11201, -11201, -11201, -11201,
|
||||||
|
31164, 31164, 31164, 31164, 31164, 31164, 31164, 31164,
|
||||||
|
1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
|
||||||
|
1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468,
|
||||||
|
|
||||||
|
// layer 5. offset: 9*16
|
||||||
|
-5827, -5827, -5827, -5827, 17364, 17364, 17364, 17364,
|
||||||
|
-26360, -26360, -26360, -26360, -29057, -29057, -29057, -29057,
|
||||||
|
573, 573, 573, 573, 2004, 2004, 2004, 2004,
|
||||||
|
264, 264, 264, 264, 383, 383, 383, 383,
|
||||||
|
5572, 5572, 5572, 5572, -1102, -1102, -1102, -1102,
|
||||||
|
21439, 21439, 21439, 21439, -26241, -26241, -26241, -26241,
|
||||||
|
2500, 2500, 2500, 2500, 1458, 1458, 1458, 1458,
|
||||||
|
1727, 1727, 1727, 1727, 3199, 3199, 3199, 3199,
|
||||||
|
-28072, -28072, -28072, -28072, 24313, 24313, 24313, 24313,
|
||||||
|
-10532, -10532, -10532, -10532, 8800, 8800, 8800, 8800,
|
||||||
|
2648, 2648, 2648, 2648, 1017, 1017, 1017, 1017,
|
||||||
|
732, 732, 732, 732, 608, 608, 608, 608,
|
||||||
|
18427, 18427, 18427, 18427, 8859, 8859, 8859, 8859,
|
||||||
|
26676, 26676, 26676, 26676, -16162, -16162, -16162, -16162,
|
||||||
|
1787, 1787, 1787, 1787, 411, 411, 411, 411,
|
||||||
|
3124, 3124, 3124, 3124, 1758, 1758, 1758, 1758,
|
||||||
|
|
||||||
|
// layer 6. offset: 17*16
|
||||||
|
-5689, -5689, -6516, -6516, 1497, 1497, 30967, 30967,
|
||||||
|
-23564, -23564, 20179, 20179, 20711, 20711, 25081, 25081,
|
||||||
|
1223, 1223, 652, 652, 2777, 2777, 1015, 1015,
|
||||||
|
2036, 2036, 1491, 1491, 3047, 3047, 1785, 1785,
|
||||||
|
-12796, -12796, 26617, 26617, 16065, 16065, -12441, -12441,
|
||||||
|
9135, 9135, -649, -649, -25986, -25986, 27837, 27837,
|
||||||
|
516, 516, 3321, 3321, 3009, 3009, 2663, 2663,
|
||||||
|
1711, 1711, 2167, 2167, 126, 126, 1469, 1469,
|
||||||
|
19884, 19884, -28249, -28249, -15886, -15886, -8898, -8898,
|
||||||
|
-28309, -28309, 9076, 9076, -30198, -30198, 18250, 18250,
|
||||||
|
2476, 2476, 3239, 3239, 3058, 3058, 830, 830,
|
||||||
|
107, 107, 1908, 1908, 3082, 3082, 2378, 2378,
|
||||||
|
13427, 13427, 14017, 14017, -29155, -29155, -12756, -12756,
|
||||||
|
16832, 16832, 4312, 4312, -24155, -24155, -17914, -17914,
|
||||||
|
2931, 2931, 961, 961, 1821, 1821, 2604, 2604,
|
||||||
|
448, 448, 2264, 2264, 677, 677, 2054, 2054,
|
||||||
|
|
||||||
|
// layer 7. offset: 25*16
|
||||||
|
-334, 11182, -11477, 13387, -32226, -14233, 20494, -21655,
|
||||||
|
-27738, 13131, 945, -4586, -14882, 23093, 6182, 5493,
|
||||||
|
2226, 430, 555, 843, 2078, 871, 1550, 105,
|
||||||
|
422, 587, 177, 3094, 3038, 2869, 1574, 1653,
|
||||||
|
32011, -32502, 10631, 30318, 29176, -18741, -28761, 12639,
|
||||||
|
-18485, 20100, 17561, 18525, -14430, 19529, -5275, -12618,
|
||||||
|
3083, 778, 1159, 3182, 2552, 1483, 2727, 1119,
|
||||||
|
1739, 644, 2457, 349, 418, 329, 3173, 3254,
|
||||||
|
-31183, 20297, 25435, 2146, -7382, 15356, 24392, -32384,
|
||||||
|
-20926, -6279, 10946, -14902, 24215, -11044, 16990, 14470,
|
||||||
|
817, 1097, 603, 610, 1322, 2044, 1864, 384,
|
||||||
|
2114, 3193, 1218, 1994, 2455, 220, 2142, 1670,
|
||||||
|
10336, -21497, -7933, -20198, -22501, 23211, 10907, -17442,
|
||||||
|
31637, -23859, 28644, -20257, 23998, 7757, -17422, 23132,
|
||||||
|
2144, 1799, 2051, 794, 1819, 2475, 2459, 478,
|
||||||
|
3221, 3021, 996, 991, 958, 1869, 1522, 1628,
|
||||||
|
|
||||||
|
// layer 1 inverse
|
||||||
|
23132, -17422, 7757, 23998, -20257, 28644, -23859, 31637,
|
||||||
|
-17442, 10907, 23211, -22501, -20198, -7933, -21497, 10336,
|
||||||
|
1628, 1522, 1869, 958, 991, 996, 3021, 3221,
|
||||||
|
478, 2459, 2475, 1819, 794, 2051, 1799, 2144,
|
||||||
|
14470, 16990, -11044, 24215, -14902, 10946, -6279, -20926,
|
||||||
|
-32384, 24392, 15356, -7382, 2146, 25435, 20297, -31183,
|
||||||
|
1670, 2142, 220, 2455, 1994, 1218, 3193, 2114,
|
||||||
|
384, 1864, 2044, 1322, 610, 603, 1097, 817,
|
||||||
|
-12618, -5275, 19529, -14430, 18525, 17561, 20100, -18485,
|
||||||
|
12639, -28761, -18741, 29176, 30318, 10631, -32502, 32011,
|
||||||
|
3254, 3173, 329, 418, 349, 2457, 644, 1739,
|
||||||
|
1119, 2727, 1483, 2552, 3182, 1159, 778, 3083,
|
||||||
|
5493, 6182, 23093, -14882, -4586, 945, 13131, -27738,
|
||||||
|
-21655, 20494, -14233, -32226, 13387, -11477, 11182, -334,
|
||||||
|
1653, 1574, 2869, 3038, 3094, 177, 587, 422,
|
||||||
|
105, 1550, 871, 2078, 843, 555, 430, 2226,
|
||||||
|
|
||||||
|
// layer 2 inverse
|
||||||
|
-17914, -17914, -24155, -24155, 4312, 4312, 16832, 16832,
|
||||||
|
-12756, -12756, -29155, -29155, 14017, 14017, 13427, 13427,
|
||||||
|
2054, 2054, 677, 677, 2264, 2264, 448, 448,
|
||||||
|
2604, 2604, 1821, 1821, 961, 961, 2931, 2931,
|
||||||
|
18250, 18250, -30198, -30198, 9076, 9076, -28309, -28309,
|
||||||
|
-8898, -8898, -15886, -15886, -28249, -28249, 19884, 19884,
|
||||||
|
2378, 2378, 3082, 3082, 1908, 1908, 107, 107,
|
||||||
|
830, 830, 3058, 3058, 3239, 3239, 2476, 2476,
|
||||||
|
27837, 27837, -25986, -25986, -649, -649, 9135, 9135,
|
||||||
|
-12441, -12441, 16065, 16065, 26617, 26617, -12796, -12796,
|
||||||
|
1469, 1469, 126, 126, 2167, 2167, 1711, 1711,
|
||||||
|
2663, 2663, 3009, 3009, 3321, 3321, 516, 516,
|
||||||
|
25081, 25081, 20711, 20711, 20179, 20179, -23564, -23564,
|
||||||
|
30967, 30967, 1497, 1497, -6516, -6516, -5689, -5689,
|
||||||
|
1785, 1785, 3047, 3047, 1491, 1491, 2036, 2036,
|
||||||
|
1015, 1015, 2777, 2777, 652, 652, 1223, 1223,
|
||||||
|
|
||||||
|
// layer 3 inverse
|
||||||
|
-16162, -16162, -16162, -16162, 26676, 26676, 26676, 26676,
|
||||||
|
8859, 8859, 8859, 8859, 18427, 18427, 18427, 18427,
|
||||||
|
1758, 1758, 1758, 1758, 3124, 3124, 3124, 3124,
|
||||||
|
411, 411, 411, 411, 1787, 1787, 1787, 1787,
|
||||||
|
8800, 8800, 8800, 8800, -10532, -10532, -10532, -10532,
|
||||||
|
24313, 24313, 24313, 24313, -28072, -28072, -28072, -28072,
|
||||||
|
608, 608, 608, 608, 732, 732, 732, 732,
|
||||||
|
1017, 1017, 1017, 1017, 2648, 2648, 2648, 2648,
|
||||||
|
-26241, -26241, -26241, -26241, 21439, 21439, 21439, 21439,
|
||||||
|
-1102, -1102, -1102, -1102, 5572, 5572, 5572, 5572,
|
||||||
|
3199, 3199, 3199, 3199, 1727, 1727, 1727, 1727,
|
||||||
|
1458, 1458, 1458, 1458, 2500, 2500, 2500, 2500,
|
||||||
|
-29057, -29057, -29057, -29057, -26360, -26360, -26360, -26360,
|
||||||
|
17364, 17364, 17364, 17364, -5827, -5827, -5827, -5827,
|
||||||
|
383, 383, 383, 383, 264, 264, 264, 264,
|
||||||
|
2004, 2004, 2004, 2004, 573, 573, 573, 573,
|
||||||
|
|
||||||
|
// layer 4 inverse
|
||||||
|
31164, 31164, 31164, 31164, 31164, 31164, 31164, 31164,
|
||||||
|
-11201, -11201, -11201, -11201, -11201, -11201, -11201, -11201,
|
||||||
|
1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468,
|
||||||
|
1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
|
||||||
|
1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
|
||||||
|
10690, 10690, 10690, 10690, 10690, 10690, 10690, 10690,
|
||||||
|
2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127,
|
||||||
|
962, 962, 962, 962, 962, 962, 962, 962,
|
||||||
|
-15690, -15690, -15690, -15690, -15690, -15690, -15690, -15690,
|
||||||
|
-3799, -3799, -3799, -3799, -3799, -3799, -3799, -3799,
|
||||||
|
182, 182, 182, 182, 182, 182, 182, 182,
|
||||||
|
1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577,
|
||||||
|
27758, 27758, 27758, 27758, 27758, 27758, 27758, 27758,
|
||||||
|
-20906, -20906, -20906, -20906, -20906, -20906, -20906, -20906,
|
||||||
|
622, 622, 622, 622, 622, 622, 622, 622,
|
||||||
|
3158, 3158, 3158, 3158, 3158, 3158, 3158, 3158,
|
||||||
|
|
||||||
|
// layer 5 inverse
|
||||||
|
-16694, 202, 28191, 287, -12402, 1422, 13525, 1493,
|
||||||
|
|
||||||
|
// layer 6 inverse
|
||||||
|
788, 1812, 14746, 2970,
|
||||||
|
|
||||||
|
// layer 7 inverse
|
||||||
|
31499, 2571,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to a + b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) Add(a, b *Poly) {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
addAVX2(
|
||||||
|
(*[N]int16)(p),
|
||||||
|
(*[N]int16)(a),
|
||||||
|
(*[N]int16)(b),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
p.addGeneric(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to a - b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) Sub(a, b *Poly) {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
subAVX2(
|
||||||
|
(*[N]int16)(p),
|
||||||
|
(*[N]int16)(a),
|
||||||
|
(*[N]int16)(b),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
p.subGeneric(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place forward "NTT" on p.
|
||||||
|
//
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤7q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity of the NTT)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
// The order of coefficients will be "tangled". These can be put back into
|
||||||
|
// their proper order by calling Detangle().
|
||||||
|
func (p *Poly) NTT() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
nttAVX2((*[N]int16)(p))
|
||||||
|
} else {
|
||||||
|
p.nttGeneric()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
|
||||||
|
// factor R.
|
||||||
|
//
|
||||||
|
// Requires coefficients to be in "tangled" order, see Tangle().
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
func (p *Poly) InvNTT() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
invNttAVX2((*[N]int16)(p))
|
||||||
|
} else {
|
||||||
|
p.invNTTGeneric()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the "pointwise" multiplication of a and b.
|
||||||
|
//
|
||||||
|
// That is: InvNTT(p) = InvNTT(a) * InvNTT(b). Assumes a and b are in
|
||||||
|
// Montgomery form. Products between coefficients of a and b must be strictly
|
||||||
|
// bounded in absolute value by 2¹⁵q. p will be in Montgomery form and
|
||||||
|
// bounded in absolute value by 2q.
|
||||||
|
//
|
||||||
|
// Requires a and b to be in "tangled" order, see Tangle(). p will be in
|
||||||
|
// tangled order as well.
|
||||||
|
func (p *Poly) MulHat(a, b *Poly) {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
mulHatAVX2(
|
||||||
|
(*[N]int16)(p),
|
||||||
|
(*[N]int16)(a),
|
||||||
|
(*[N]int16)(b),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
p.mulHatGeneric(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts p into the right form to be used with (among others) InvNTT().
|
||||||
|
func (p *Poly) Tangle() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
tangleAVX2((*[N]int16)(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// When AVX2 is not available, we use the standard order.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts p back into standard form.
|
||||||
|
func (p *Poly) Detangle() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
detangleAVX2((*[N]int16)(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// When AVX2 is not available, we use the standard order.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (p *Poly) BarrettReduce() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
barrettReduceAVX2((*[N]int16)(p))
|
||||||
|
} else {
|
||||||
|
p.barrettReduceGeneric()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (p *Poly) Normalize() {
|
||||||
|
if cpu.X86.HasAVX2 {
|
||||||
|
normalizeAVX2((*[N]int16)(p))
|
||||||
|
} else {
|
||||||
|
p.normalizeGeneric()
|
||||||
|
}
|
||||||
|
}
|
2354
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s
generated
vendored
Normal file
2354
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
74
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go
generated
vendored
Normal file
74
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Given -2¹⁵ q ≤ x < 2¹⁵ q, returns -q < y < q with x 2⁻¹⁶ = y (mod q).
|
||||||
|
func montReduce(x int32) int16 {
|
||||||
|
// This is Montgomery reduction with R=2¹⁶.
|
||||||
|
//
|
||||||
|
// Note gcd(2¹⁶, q) = 1 as q is prime. Write q' := 62209 = q⁻¹ mod R.
|
||||||
|
// First we compute
|
||||||
|
//
|
||||||
|
// m := ((x mod R) q') mod R
|
||||||
|
// = x q' mod R
|
||||||
|
// = int16(x q')
|
||||||
|
// = int16(int32(x) * int32(q'))
|
||||||
|
//
|
||||||
|
// Note that x q' might be as big as 2³² and could overflow the int32
|
||||||
|
// multiplication in the last line. However for any int32s a and b,
|
||||||
|
// we have int32(int64(a)*int64(b)) = int32(a*b) and so the result is ok.
|
||||||
|
m := int16(x * 62209)
|
||||||
|
|
||||||
|
// Note that x - m q is divisable by R; indeed modulo R we have
|
||||||
|
//
|
||||||
|
// x - m q ≡ x - x q' q ≡ x - x q⁻¹ q ≡ x - x = 0.
|
||||||
|
//
|
||||||
|
// We return y := (x - m q) / R. Note that y is indeed correct as
|
||||||
|
// modulo q we have
|
||||||
|
//
|
||||||
|
// y ≡ x R⁻¹ - m q R⁻¹ = x R⁻¹
|
||||||
|
//
|
||||||
|
// and as both 2¹⁵ q ≤ m q, x < 2¹⁵ q, we have
|
||||||
|
// 2¹⁶ q ≤ x - m q < 2¹⁶ and so q ≤ (x - m q) / R < q as desired.
|
||||||
|
return int16(uint32(x-int32(m)*int32(Q)) >> 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given any x, returns x R mod q where R=2¹⁶.
|
||||||
|
func toMont(x int16) int16 {
|
||||||
|
// Note |1353 x| ≤ 1353 2¹⁵ ≤ 13318 q ≤ 2¹⁵ q and so we're within
|
||||||
|
// the bounds of montReduce.
|
||||||
|
return montReduce(int32(x) * 1353) // 1353 = R² mod q.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given any x, compute 0 ≤ y ≤ q with x = y (mod q).
|
||||||
|
//
|
||||||
|
// Beware: we might have barrettReduce(x) = q ≠ 0 for some x. In fact,
|
||||||
|
// this happens if and only if x = -nq for some positive integer n.
|
||||||
|
func barrettReduce(x int16) int16 {
|
||||||
|
// This is standard Barrett reduction.
|
||||||
|
//
|
||||||
|
// For any x we have x mod q = x - ⌊x/q⌋ q. We will use 20159/2²⁶ as
|
||||||
|
// an approximation of 1/q. Note that 0 ≤ 20159/2²⁶ - 1/q ≤ 0.135/2²⁶
|
||||||
|
// and so | x 20156/2²⁶ - x/q | ≤ 2⁻¹⁰ for |x| ≤ 2¹⁶. For all x
|
||||||
|
// not a multiple of q, the number x/q is further than 1/q from any integer
|
||||||
|
// and so ⌊x 20156/2²⁶⌋ = ⌊x/q⌋. If x is a multiple of q and x is positive,
|
||||||
|
// then x 20156/2²⁶ is larger than x/q so ⌊x 20156/2²⁶⌋ = ⌊x/q⌋ as well.
|
||||||
|
// Finally, if x is negative multiple of q, then ⌊x 20156/2²⁶⌋ = ⌊x/q⌋-1.
|
||||||
|
// Thus
|
||||||
|
// [ q if x=-nq for pos. integer n
|
||||||
|
// x - ⌊x 20156/2²⁶⌋ q = [
|
||||||
|
// [ x mod q otherwise
|
||||||
|
//
|
||||||
|
// To compute actually compute this, note that
|
||||||
|
//
|
||||||
|
// ⌊x 20156/2²⁶⌋ = (20159 x) >> 26.
|
||||||
|
return x - int16((int32(x)*20159)>>26)*Q
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns x if x < q and x - q otherwise. Assumes x ≥ -29439.
|
||||||
|
func csubq(x int16) int16 {
|
||||||
|
x -= Q // no overflow due to assumption x ≥ -29439.
|
||||||
|
// If x is positive, then x >> 15 = 0. If x is negative,
|
||||||
|
// then uint16(x >> 15) = 2¹⁶-1. So this will add back in q
|
||||||
|
// if x was smaller than q.
|
||||||
|
x += (x >> 15) & Q
|
||||||
|
return x
|
||||||
|
}
|
77
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go
generated
vendored
Normal file
77
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
//go:build !amd64
|
||||||
|
// +build !amd64
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Sets p to a + b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) Add(a, b *Poly) {
|
||||||
|
p.addGeneric(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to a - b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) Sub(a, b *Poly) {
|
||||||
|
p.subGeneric(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place forward "NTT" on p.
|
||||||
|
//
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤7q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity of the NTT)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
// The order of coefficients will be "tangled". These can be put back into
|
||||||
|
// their proper order by calling Detangle().
|
||||||
|
func (p *Poly) NTT() {
|
||||||
|
p.nttGeneric()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
|
||||||
|
// factor R.
|
||||||
|
//
|
||||||
|
// Requires coefficients to be in "tangled" order, see Tangle().
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
func (p *Poly) InvNTT() {
|
||||||
|
p.invNTTGeneric()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the "pointwise" multiplication of a and b.
|
||||||
|
//
|
||||||
|
// That is: InvNTT(p) = InvNTT(a) * InvNTT(b). Assumes a and b are in
|
||||||
|
// Montgomery form. Products between coefficients of a and b must be strictly
|
||||||
|
// bounded in absolute value by 2¹⁵q. p will be in Montgomery form and
|
||||||
|
// bounded in absolute value by 2q.
|
||||||
|
//
|
||||||
|
// Requires a and b to be in "tangled" order, see Tangle(). p will be in
|
||||||
|
// tangled order as well.
|
||||||
|
func (p *Poly) MulHat(a, b *Poly) {
|
||||||
|
p.mulHatGeneric(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts p into the right form to be used with (among others) InvNTT().
|
||||||
|
func (p *Poly) Tangle() {
|
||||||
|
// In the generic implementation there is no advantage to using a
|
||||||
|
// different order, so we use the standard order everywhere.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts p back into standard form.
|
||||||
|
func (p *Poly) Detangle() {
|
||||||
|
// In the generic implementation there is no advantage to using a
|
||||||
|
// different order, so we use the standard order everywhere.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (p *Poly) BarrettReduce() {
|
||||||
|
p.barrettReduceGeneric()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (p *Poly) Normalize() {
|
||||||
|
p.normalizeGeneric()
|
||||||
|
}
|
193
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go
generated
vendored
Normal file
193
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go
generated
vendored
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Zetas lists precomputed powers of the primitive root of unity in
|
||||||
|
// Montgomery representation used for the NTT:
|
||||||
|
//
|
||||||
|
// Zetas[i] = ζᵇʳᵛ⁽ⁱ⁾ R mod q
|
||||||
|
//
|
||||||
|
// where ζ = 17, brv(i) is the bitreversal of a 7-bit number and R=2¹⁶ mod q.
|
||||||
|
//
|
||||||
|
// The following Python code generates the Zetas arrays:
|
||||||
|
//
|
||||||
|
// q = 13*2**8 + 1; zeta = 17
|
||||||
|
// R = 2**16 % q # Montgomery const.
|
||||||
|
// def brv(x): return int(''.join(reversed(bin(x)[2:].zfill(7))),2)
|
||||||
|
// print([(pow(zeta, brv(i), q)*R)%q for i in range(128)])
|
||||||
|
var Zetas = [128]int16{
|
||||||
|
2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182,
|
||||||
|
962, 2127, 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199,
|
||||||
|
2648, 1017, 732, 608, 1787, 411, 3124, 1758, 1223, 652, 2777, 1015,
|
||||||
|
2036, 1491, 3047, 1785, 516, 3321, 3009, 2663, 1711, 2167, 126,
|
||||||
|
1469, 2476, 3239, 3058, 830, 107, 1908, 3082, 2378, 2931, 961, 1821,
|
||||||
|
2604, 448, 2264, 677, 2054, 2226, 430, 555, 843, 2078, 871, 1550,
|
||||||
|
105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, 3083, 778, 1159,
|
||||||
|
3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173,
|
||||||
|
3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218,
|
||||||
|
1994, 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475,
|
||||||
|
2459, 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628,
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvNTTReductions keeps track of which coefficients to apply Barrett
|
||||||
|
// reduction to in Poly.InvNTT().
|
||||||
|
//
|
||||||
|
// Generated in a lazily: once a butterfly is computed which is about to
|
||||||
|
// overflow the int16, the largest coefficient is reduced. If that is
|
||||||
|
// not enough, the other coefficient is reduced as well.
|
||||||
|
//
|
||||||
|
// This is actually optimal, as proven in https://eprint.iacr.org/2020/1377.pdf
|
||||||
|
var InvNTTReductions = [...]int{
|
||||||
|
-1, // after layer 1
|
||||||
|
-1, // after layer 2
|
||||||
|
16, 17, 48, 49, 80, 81, 112, 113, 144, 145, 176, 177, 208, 209, 240,
|
||||||
|
241, -1, // after layer 3
|
||||||
|
0, 1, 32, 33, 34, 35, 64, 65, 96, 97, 98, 99, 128, 129, 160, 161, 162, 163,
|
||||||
|
192, 193, 224, 225, 226, 227, -1, // after layer 4
|
||||||
|
2, 3, 66, 67, 68, 69, 70, 71, 130, 131, 194, 195, 196, 197, 198,
|
||||||
|
199, -1, // after layer 5
|
||||||
|
4, 5, 6, 7, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
||||||
|
143, -1, // after layer 6
|
||||||
|
-1, // after layer 7
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place forward "NTT" on p.
|
||||||
|
//
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤7q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity of the NTT)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
// The order of coefficients will be "tangled". These can be put back into
|
||||||
|
// their proper order by calling Detangle().
|
||||||
|
func (p *Poly) nttGeneric() {
|
||||||
|
// Note that ℤ_q does not have a primitive 512ᵗʰ root of unity (as 512
|
||||||
|
// does not divide into q-1) and so we cannot do a regular NTT. ℤ_q
|
||||||
|
// does have a primitive 256ᵗʰ root of unity, the smallest of which
|
||||||
|
// is ζ := 17.
|
||||||
|
//
|
||||||
|
// Recall that our base ring R := ℤ_q[x] / (x²⁵⁶ + 1). The polynomial
|
||||||
|
// x²⁵⁶+1 will not split completely (as its roots would be 512ᵗʰ roots
|
||||||
|
// of unity.) However, it does split almost (using ζ¹²⁸ = -1):
|
||||||
|
//
|
||||||
|
// x²⁵⁶ + 1 = (x²)¹²⁸ - ζ¹²⁸
|
||||||
|
// = ((x²)⁶⁴ - ζ⁶⁴)((x²)⁶⁴ + ζ⁶⁴)
|
||||||
|
// = ((x²)³² - ζ³²)((x²)³² + ζ³²)((x²)³² - ζ⁹⁶)((x²)³² + ζ⁹⁶)
|
||||||
|
// ⋮
|
||||||
|
// = (x² - ζ)(x² + ζ)(x² - ζ⁶⁵)(x² + ζ⁶⁵) … (x² + ζ¹²⁷)
|
||||||
|
//
|
||||||
|
// Note that the powers of ζ that appear (from the second line down) are
|
||||||
|
// in binary
|
||||||
|
//
|
||||||
|
// 0100000 1100000
|
||||||
|
// 0010000 1010000 0110000 1110000
|
||||||
|
// 0001000 1001000 0101000 1101000 0011000 1011000 0111000 1111000
|
||||||
|
// …
|
||||||
|
//
|
||||||
|
// That is: brv(2), brv(3), brv(4), …, where brv(x) denotes the 7-bit
|
||||||
|
// bitreversal of x. These powers of ζ are given by the Zetas array.
|
||||||
|
//
|
||||||
|
// The polynomials x² ± ζⁱ are irreducible and coprime, hence by
|
||||||
|
// the Chinese Remainder Theorem we know
|
||||||
|
//
|
||||||
|
// ℤ_q[x]/(x²⁵⁶+1) → ℤ_q[x]/(x²-ζ) x … x ℤ_q[x]/(x²+ζ¹²⁷)
|
||||||
|
//
|
||||||
|
// given by a ↦ ( a mod x²-ζ, …, a mod x²+ζ¹²⁷ )
|
||||||
|
// is an isomorphism, which is the "NTT". It can be efficiently computed by
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// a ↦ ( a mod (x²)⁶⁴ - ζ⁶⁴, a mod (x²)⁶⁴ + ζ⁶⁴ )
|
||||||
|
// ↦ ( a mod (x²)³² - ζ³², a mod (x²)³² + ζ³²,
|
||||||
|
// a mod (x²)⁹⁶ - ζ⁹⁶, a mod (x²)⁹⁶ + ζ⁹⁶ )
|
||||||
|
//
|
||||||
|
// et cetera
|
||||||
|
//
|
||||||
|
// If N was 8 then this can be pictured in the following diagram:
|
||||||
|
//
|
||||||
|
// https://cnx.org/resources/17ee4dfe517a6adda05377b25a00bf6e6c93c334/File0026.png
|
||||||
|
//
|
||||||
|
// Each cross is a Cooley-Tukey butterfly: it's the map
|
||||||
|
//
|
||||||
|
// (a, b) ↦ (a + ζb, a - ζb)
|
||||||
|
//
|
||||||
|
// for the appropriate power ζ for that column and row group.
|
||||||
|
|
||||||
|
k := 0 // Index into Zetas
|
||||||
|
|
||||||
|
// l runs effectively over the columns in the diagram above; it is half the
|
||||||
|
// height of a row group, i.e. the number of butterflies in each row group.
|
||||||
|
// In the diagram above it would be 4, 2, 1.
|
||||||
|
for l := N / 2; l > 1; l >>= 1 {
|
||||||
|
// On the nᵗʰ iteration of the l-loop, the absolute value of the
|
||||||
|
// coefficients are bounded by nq.
|
||||||
|
|
||||||
|
// offset effectively loops over the row groups in this column; it is
|
||||||
|
// the first row in the row group.
|
||||||
|
for offset := 0; offset < N-l; offset += 2 * l {
|
||||||
|
k++
|
||||||
|
zeta := int32(Zetas[k])
|
||||||
|
|
||||||
|
// j loops over each butterfly in the row group.
|
||||||
|
for j := offset; j < offset+l; j++ {
|
||||||
|
t := montReduce(zeta * int32(p[j+l]))
|
||||||
|
p[j+l] = p[j] - t
|
||||||
|
p[j] += t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
|
||||||
|
// factor R.
|
||||||
|
//
|
||||||
|
// Requires coefficients to be in "tangled" order, see Tangle().
|
||||||
|
// Assumes the coefficients are in absolute value ≤q. The resulting
|
||||||
|
// coefficients are in absolute value ≤q. If the input is in Montgomery
|
||||||
|
// form, then the result is in Montgomery form and so (by linearity)
|
||||||
|
// if the input is in regular form, then the result is also in regular form.
|
||||||
|
func (p *Poly) invNTTGeneric() {
|
||||||
|
k := 127 // Index into Zetas
|
||||||
|
r := -1 // Index into InvNTTReductions.
|
||||||
|
|
||||||
|
// We basically do the oppposite of NTT, but postpone dividing by 2 in the
|
||||||
|
// inverse of the Cooley-Tukey butterfly and accumulate that into a big
|
||||||
|
// division by 2⁷ at the end. See the comments in the NTT() function.
|
||||||
|
|
||||||
|
for l := 2; l < N; l <<= 1 {
|
||||||
|
for offset := 0; offset < N-l; offset += 2 * l {
|
||||||
|
// As we're inverting, we need powers of ζ⁻¹ (instead of ζ).
|
||||||
|
// To be precise, we need ζᵇʳᵛ⁽ᵏ⁾⁻¹²⁸. However, as ζ⁻¹²⁸ = -1,
|
||||||
|
// we can use the existing Zetas table instead of
|
||||||
|
// keeping a separate InvZetas table as in Dilithium.
|
||||||
|
|
||||||
|
minZeta := int32(Zetas[k])
|
||||||
|
k--
|
||||||
|
|
||||||
|
for j := offset; j < offset+l; j++ {
|
||||||
|
// Gentleman-Sande butterfly: (a, b) ↦ (a + b, ζ(a-b))
|
||||||
|
t := p[j+l] - p[j]
|
||||||
|
p[j] += p[j+l]
|
||||||
|
p[j+l] = montReduce(minZeta * int32(t))
|
||||||
|
|
||||||
|
// Note that if we had |a| < αq and |b| < βq before the
|
||||||
|
// butterfly, then now we have |a| < (α+β)q and |b| < q.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We let the InvNTTReductions instruct us which coefficients to
|
||||||
|
// Barrett reduce. See TestInvNTTReductions, which tests whether
|
||||||
|
// there is an overflow.
|
||||||
|
for {
|
||||||
|
r++
|
||||||
|
i := InvNTTReductions[r]
|
||||||
|
if i < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p[i] = barrettReduce(p[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < N; j++ {
|
||||||
|
// Note 1441 = (128)⁻¹ R². The coefficients are bounded by 9q, so
|
||||||
|
// as 1441 * 9 ≈ 2¹⁴ < 2¹⁵, we're within the required bounds
|
||||||
|
// for montReduce().
|
||||||
|
p[j] = montReduce(1441 * int32(p[j]))
|
||||||
|
}
|
||||||
|
}
|
22
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go
generated
vendored
Normal file
22
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common/params"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Q is the parameter q ≡ 3329 = 2¹¹ + 2¹⁰ + 2⁸ + 1.
|
||||||
|
Q = params.Q
|
||||||
|
|
||||||
|
// N is the parameter N: the length of the polynomials
|
||||||
|
N = params.N
|
||||||
|
|
||||||
|
// PolySize is the size of a packed polynomial.
|
||||||
|
PolySize = params.PolySize
|
||||||
|
|
||||||
|
// PlaintextSize is the size of the plaintext
|
||||||
|
PlaintextSize = params.PlaintextSize
|
||||||
|
|
||||||
|
// Eta2 is the parameter η₂
|
||||||
|
Eta2 = params.Eta2
|
||||||
|
)
|
21
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go
generated
vendored
Normal file
21
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package params
|
||||||
|
|
||||||
|
// We put these parameters in a separate package so that the Go code,
|
||||||
|
// such as asm/src.go, that generates assembler can import it.
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Q is the parameter q ≡ 3329 = 2¹¹ + 2¹⁰ + 2⁸ + 1.
|
||||||
|
Q int16 = 3329
|
||||||
|
|
||||||
|
// N is the parameter N: the length of the polynomials
|
||||||
|
N int = 256
|
||||||
|
|
||||||
|
// PolySize is the size of a packed polynomial.
|
||||||
|
PolySize int = 384
|
||||||
|
|
||||||
|
// PlaintextSize is the size of the plaintext
|
||||||
|
PlaintextSize = 32
|
||||||
|
|
||||||
|
// Eta2 is the parameter η₂
|
||||||
|
Eta2 = 2
|
||||||
|
)
|
324
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go
generated
vendored
Normal file
324
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go
generated
vendored
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// An element of our base ring R which are polynomials over ℤ_q
|
||||||
|
// modulo the equation Xᴺ = -1, where q=3329 and N=256.
|
||||||
|
//
|
||||||
|
// This type is also used to store NTT-transformed polynomials,
|
||||||
|
// see Poly.NTT().
|
||||||
|
//
|
||||||
|
// Coefficients aren't always reduced. See Normalize().
|
||||||
|
type Poly [N]int16
|
||||||
|
|
||||||
|
// Sets p to a + b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) addGeneric(a, b *Poly) {
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
p[i] = a[i] + b[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to a - b. Does not normalize coefficients.
|
||||||
|
func (p *Poly) subGeneric(a, b *Poly) {
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
p[i] = a[i] - b[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (p *Poly) barrettReduceGeneric() {
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
p[i] = barrettReduce(p[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (p *Poly) normalizeGeneric() {
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
p[i] = csubq(barrettReduce(p[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplies p in-place by the Montgomery factor 2¹⁶.
|
||||||
|
//
|
||||||
|
// Coefficients of p can be artbitray. Resulting coefficients are bounded
|
||||||
|
// in absolute value by q.
|
||||||
|
func (p *Poly) ToMont() {
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
p[i] = toMont(p[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the "pointwise" multiplication of a and b.
|
||||||
|
//
|
||||||
|
// That is: InvNTT(p) = InvNTT(a) * InvNTT(b). Assumes a and b are in
|
||||||
|
// Montgomery form. Products between coefficients of a and b must be strictly
|
||||||
|
// bounded in absolute value by 2¹⁵q. p will be in Montgomery form and
|
||||||
|
// bounded in absolute value by 2q.
|
||||||
|
//
|
||||||
|
// Requires a and b to be in "tangled" order, see Tangle(). p will be in
|
||||||
|
// tangled order as well.
|
||||||
|
func (p *Poly) mulHatGeneric(a, b *Poly) {
|
||||||
|
// Recall from the discussion in NTT(), that a transformed polynomial is
|
||||||
|
// an element of ℤ_q[x]/(x²-ζ) x … x ℤ_q[x]/(x²+ζ¹²⁷);
|
||||||
|
// that is: 128 degree-one polynomials instead of simply 256 elements
|
||||||
|
// from ℤ_q as in the regular NTT. So instead of pointwise multiplication,
|
||||||
|
// we multiply the 128 pairs of degree-one polynomials modulo the
|
||||||
|
// right equation:
|
||||||
|
//
|
||||||
|
// (a₁ + a₂x)(b₁ + b₂x) = a₁b₁ + a₂b₂ζ' + (a₁b₂ + a₂b₁)x,
|
||||||
|
//
|
||||||
|
// where ζ' is the appropriate power of ζ.
|
||||||
|
|
||||||
|
k := 64
|
||||||
|
for i := 0; i < N; i += 4 {
|
||||||
|
zeta := int32(Zetas[k])
|
||||||
|
k++
|
||||||
|
|
||||||
|
p0 := montReduce(int32(a[i+1]) * int32(b[i+1]))
|
||||||
|
p0 = montReduce(int32(p0) * zeta)
|
||||||
|
p0 += montReduce(int32(a[i]) * int32(b[i]))
|
||||||
|
|
||||||
|
p1 := montReduce(int32(a[i]) * int32(b[i+1]))
|
||||||
|
p1 += montReduce(int32(a[i+1]) * int32(b[i]))
|
||||||
|
|
||||||
|
p[i] = p0
|
||||||
|
p[i+1] = p1
|
||||||
|
|
||||||
|
p2 := montReduce(int32(a[i+3]) * int32(b[i+3]))
|
||||||
|
p2 = -montReduce(int32(p2) * zeta)
|
||||||
|
p2 += montReduce(int32(a[i+2]) * int32(b[i+2]))
|
||||||
|
|
||||||
|
p3 := montReduce(int32(a[i+2]) * int32(b[i+3]))
|
||||||
|
p3 += montReduce(int32(a[i+3]) * int32(b[i+2]))
|
||||||
|
|
||||||
|
p[i+2] = p2
|
||||||
|
p[i+3] = p3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs p into buf. buf should be of length PolySize.
|
||||||
|
//
|
||||||
|
// Assumes p is normalized (and not just Barrett reduced) and "tangled",
|
||||||
|
// see Tangle().
|
||||||
|
func (p *Poly) Pack(buf []byte) {
|
||||||
|
q := *p
|
||||||
|
q.Detangle()
|
||||||
|
for i := 0; i < 128; i++ {
|
||||||
|
t0 := q[2*i]
|
||||||
|
t1 := q[2*i+1]
|
||||||
|
buf[3*i] = byte(t0)
|
||||||
|
buf[3*i+1] = byte(t0>>8) | byte(t1<<4)
|
||||||
|
buf[3*i+2] = byte(t1 >> 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks p from buf.
|
||||||
|
//
|
||||||
|
// buf should be of length PolySize. p will be "tangled", see Detangle().
|
||||||
|
//
|
||||||
|
// p will not be normalized; instead 0 ≤ p[i] < 4096.
|
||||||
|
func (p *Poly) Unpack(buf []byte) {
|
||||||
|
for i := 0; i < 128; i++ {
|
||||||
|
p[2*i] = int16(buf[3*i]) | ((int16(buf[3*i+1]) << 8) & 0xfff)
|
||||||
|
p[2*i+1] = int16(buf[3*i+1]>>4) | (int16(buf[3*i+2]) << 4)
|
||||||
|
}
|
||||||
|
p.Tangle()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set p to Decompress_q(m, 1).
|
||||||
|
//
|
||||||
|
// p will be normalized. m has to be of PlaintextSize.
|
||||||
|
func (p *Poly) DecompressMessage(m []byte) {
|
||||||
|
// Decompress_q(x, 1) = ⌈xq/2⌋ = ⌊xq/2+½⌋ = (xq+1) >> 1 and so
|
||||||
|
// Decompress_q(0, 1) = 0 and Decompress_q(1, 1) = (q+1)/2.
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
bit := (m[i] >> uint(j)) & 1
|
||||||
|
|
||||||
|
// Set coefficient to either 0 or (q+1)/2 depending on the bit.
|
||||||
|
p[8*i+j] = -int16(bit) & ((Q + 1) / 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes Compress_q(p, 1) to m.
|
||||||
|
//
|
||||||
|
// Assumes p is normalized. m has to be of length at least PlaintextSize.
|
||||||
|
func (p *Poly) CompressMessageTo(m []byte) {
|
||||||
|
// Compress_q(x, 1) is 1 on {833, …, 2496} and zero elsewhere.
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
m[i] = 0
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
x := 1664 - p[8*i+j]
|
||||||
|
// With the previous substitution, we want to return 1 if
|
||||||
|
// and only if x is in {831, …, -832}.
|
||||||
|
x = (x >> 15) ^ x
|
||||||
|
// Note (x >> 15)ˣ if x≥0 and -x-1 otherwise. Thus now we want
|
||||||
|
// to return 1 iff x ≤ 831, ie. x - 832 < 0.
|
||||||
|
x -= 832
|
||||||
|
m[i] |= ((byte(x >> 15)) & 1) << uint(j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set p to Decompress_q(m, 1).
|
||||||
|
//
|
||||||
|
// Assumes d is in {3, 4, 5, 10, 11}. p will be normalized.
|
||||||
|
func (p *Poly) Decompress(m []byte, d int) {
|
||||||
|
// Decompress_q(x, d) = ⌈(q/2ᵈ)x⌋
|
||||||
|
// = ⌊(q/2ᵈ)x+½⌋
|
||||||
|
// = ⌊(qx + 2ᵈ⁻¹)/2ᵈ⌋
|
||||||
|
// = (qx + (1<<(d-1))) >> d
|
||||||
|
switch d {
|
||||||
|
case 4:
|
||||||
|
for i := 0; i < N/2; i++ {
|
||||||
|
p[2*i] = int16(((1 << 3) +
|
||||||
|
uint32(m[i]&15)*uint32(Q)) >> 4)
|
||||||
|
p[2*i+1] = int16(((1 << 3) +
|
||||||
|
uint32(m[i]>>4)*uint32(Q)) >> 4)
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
var t [8]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/8; i++ {
|
||||||
|
t[0] = uint16(m[idx])
|
||||||
|
t[1] = (uint16(m[idx]) >> 5) | (uint16(m[idx+1] << 3))
|
||||||
|
t[2] = uint16(m[idx+1]) >> 2
|
||||||
|
t[3] = (uint16(m[idx+1]) >> 7) | (uint16(m[idx+2] << 1))
|
||||||
|
t[4] = (uint16(m[idx+2]) >> 4) | (uint16(m[idx+3] << 4))
|
||||||
|
t[5] = uint16(m[idx+3]) >> 1
|
||||||
|
t[6] = (uint16(m[idx+3]) >> 6) | (uint16(m[idx+4] << 2))
|
||||||
|
t[7] = uint16(m[idx+4]) >> 3
|
||||||
|
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
p[8*i+j] = int16(((1 << 4) +
|
||||||
|
uint32(t[j]&((1<<5)-1))*uint32(Q)) >> 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
idx += 5
|
||||||
|
}
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
var t [4]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/4; i++ {
|
||||||
|
t[0] = uint16(m[idx]) | (uint16(m[idx+1]) << 8)
|
||||||
|
t[1] = (uint16(m[idx+1]) >> 2) | (uint16(m[idx+2]) << 6)
|
||||||
|
t[2] = (uint16(m[idx+2]) >> 4) | (uint16(m[idx+3]) << 4)
|
||||||
|
t[3] = (uint16(m[idx+3]) >> 6) | (uint16(m[idx+4]) << 2)
|
||||||
|
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
p[4*i+j] = int16(((1 << 9) +
|
||||||
|
uint32(t[j]&((1<<10)-1))*uint32(Q)) >> 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
idx += 5
|
||||||
|
}
|
||||||
|
case 11:
|
||||||
|
var t [8]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/8; i++ {
|
||||||
|
t[0] = uint16(m[idx]) | (uint16(m[idx+1]) << 8)
|
||||||
|
t[1] = (uint16(m[idx+1]) >> 3) | (uint16(m[idx+2]) << 5)
|
||||||
|
t[2] = (uint16(m[idx+2]) >> 6) | (uint16(m[idx+3]) << 2) | (uint16(m[idx+4]) << 10)
|
||||||
|
t[3] = (uint16(m[idx+4]) >> 1) | (uint16(m[idx+5]) << 7)
|
||||||
|
t[4] = (uint16(m[idx+5]) >> 4) | (uint16(m[idx+6]) << 4)
|
||||||
|
t[5] = (uint16(m[idx+6]) >> 7) | (uint16(m[idx+7]) << 1) | (uint16(m[idx+8]) << 9)
|
||||||
|
t[6] = (uint16(m[idx+8]) >> 2) | (uint16(m[idx+9]) << 6)
|
||||||
|
t[7] = (uint16(m[idx+9]) >> 5) | (uint16(m[idx+10]) << 3)
|
||||||
|
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
p[8*i+j] = int16(((1 << 10) +
|
||||||
|
uint32(t[j]&((1<<11)-1))*uint32(Q)) >> 11)
|
||||||
|
}
|
||||||
|
|
||||||
|
idx += 11
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unsupported d")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes Compress_q(p, d) to m.
|
||||||
|
//
|
||||||
|
// Assumes p is normalized and d is in {3, 4, 5, 10, 11}.
|
||||||
|
func (p *Poly) CompressTo(m []byte, d int) {
|
||||||
|
// Compress_q(x, d) = ⌈(2ᵈ/q)x⌋ mod⁺ 2ᵈ
|
||||||
|
// = ⌊(2ᵈ/q)x+½⌋ mod⁺ 2ᵈ
|
||||||
|
// = ⌊((x << d) + q/2) / q⌋ mod⁺ 2ᵈ
|
||||||
|
// = DIV((x << d) + q/2, q) & ((1<<d) - 1)
|
||||||
|
switch d {
|
||||||
|
case 4:
|
||||||
|
var t [8]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/8; i++ {
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
t[j] = uint16(((uint32(p[8*i+j])<<4)+uint32(Q)/2)/
|
||||||
|
uint32(Q)) & ((1 << 4) - 1)
|
||||||
|
}
|
||||||
|
m[idx] = byte(t[0]) | byte(t[1]<<4)
|
||||||
|
m[idx+1] = byte(t[2]) | byte(t[3]<<4)
|
||||||
|
m[idx+2] = byte(t[4]) | byte(t[5]<<4)
|
||||||
|
m[idx+3] = byte(t[6]) | byte(t[7]<<4)
|
||||||
|
idx += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
var t [8]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/8; i++ {
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
t[j] = uint16(((uint32(p[8*i+j])<<5)+uint32(Q)/2)/
|
||||||
|
uint32(Q)) & ((1 << 5) - 1)
|
||||||
|
}
|
||||||
|
m[idx] = byte(t[0]) | byte(t[1]<<5)
|
||||||
|
m[idx+1] = byte(t[1]>>3) | byte(t[2]<<2) | byte(t[3]<<7)
|
||||||
|
m[idx+2] = byte(t[3]>>1) | byte(t[4]<<4)
|
||||||
|
m[idx+3] = byte(t[4]>>4) | byte(t[5]<<1) | byte(t[6]<<6)
|
||||||
|
m[idx+4] = byte(t[6]>>2) | byte(t[7]<<3)
|
||||||
|
idx += 5
|
||||||
|
}
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
var t [4]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/4; i++ {
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
t[j] = uint16(((uint32(p[4*i+j])<<10)+uint32(Q)/2)/
|
||||||
|
uint32(Q)) & ((1 << 10) - 1)
|
||||||
|
}
|
||||||
|
m[idx] = byte(t[0])
|
||||||
|
m[idx+1] = byte(t[0]>>8) | byte(t[1]<<2)
|
||||||
|
m[idx+2] = byte(t[1]>>6) | byte(t[2]<<4)
|
||||||
|
m[idx+3] = byte(t[2]>>4) | byte(t[3]<<6)
|
||||||
|
m[idx+4] = byte(t[3] >> 2)
|
||||||
|
idx += 5
|
||||||
|
}
|
||||||
|
case 11:
|
||||||
|
var t [8]uint16
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < N/8; i++ {
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
t[j] = uint16(((uint32(p[8*i+j])<<11)+uint32(Q)/2)/
|
||||||
|
uint32(Q)) & ((1 << 11) - 1)
|
||||||
|
}
|
||||||
|
m[idx] = byte(t[0])
|
||||||
|
m[idx+1] = byte(t[0]>>8) | byte(t[1]<<3)
|
||||||
|
m[idx+2] = byte(t[1]>>5) | byte(t[2]<<6)
|
||||||
|
m[idx+3] = byte(t[2] >> 2)
|
||||||
|
m[idx+4] = byte(t[2]>>10) | byte(t[3]<<1)
|
||||||
|
m[idx+5] = byte(t[3]>>7) | byte(t[4]<<4)
|
||||||
|
m[idx+6] = byte(t[4]>>4) | byte(t[5]<<7)
|
||||||
|
m[idx+7] = byte(t[5] >> 1)
|
||||||
|
m[idx+8] = byte(t[5]>>9) | byte(t[6]<<2)
|
||||||
|
m[idx+9] = byte(t[6]>>6) | byte(t[7]<<5)
|
||||||
|
m[idx+10] = byte(t[7] >> 3)
|
||||||
|
idx += 11
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unsupported d")
|
||||||
|
}
|
||||||
|
}
|
236
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go
generated
vendored
Normal file
236
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go
generated
vendored
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/simd/keccakf1600"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeriveX4Available indicates whether the system supports the quick fourway
|
||||||
|
// sampling variants like PolyDeriveUniformX4.
|
||||||
|
var DeriveX4Available = keccakf1600.IsEnabledX4()
|
||||||
|
|
||||||
|
// Samples p from a centered binomial distribution with given η.
|
||||||
|
//
|
||||||
|
// Essentially CBD_η(PRF(seed, nonce)) from the specification.
|
||||||
|
func (p *Poly) DeriveNoise(seed []byte, nonce uint8, eta int) {
|
||||||
|
switch eta {
|
||||||
|
case 2:
|
||||||
|
p.DeriveNoise2(seed, nonce)
|
||||||
|
case 3:
|
||||||
|
p.DeriveNoise3(seed, nonce)
|
||||||
|
default:
|
||||||
|
panic("unsupported eta")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample p from a centered binomial distribution with n=6 and p=½ - that is:
|
||||||
|
// coefficients are in {-3, -2, -1, 0, 1, 2, 3} with probabilities {1/64, 3/32,
|
||||||
|
// 15/64, 5/16, 16/64, 3/32, 1/64}.
|
||||||
|
func (p *Poly) DeriveNoise3(seed []byte, nonce uint8) {
|
||||||
|
keySuffix := [1]byte{nonce}
|
||||||
|
h := sha3.NewShake256()
|
||||||
|
_, _ = h.Write(seed[:])
|
||||||
|
_, _ = h.Write(keySuffix[:])
|
||||||
|
|
||||||
|
// The distribution at hand is exactly the same as that
|
||||||
|
// of (a₁ + a₂ + a₃) - (b₁ + b₂+b₃) where a_i,b_i~U(1). Thus we need
|
||||||
|
// 6 bits per coefficients, thus 192 bytes of input entropy.
|
||||||
|
|
||||||
|
// We add two extra zero bytes in the buffer to be able to read 8 bytes
|
||||||
|
// at the same time (while using only 6.)
|
||||||
|
var buf [192 + 2]byte
|
||||||
|
_, _ = h.Read(buf[:192])
|
||||||
|
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
// t is interpreted as a₁ + 2a₂ + 4a₃ + 8b₁ + 16b₂ + ….
|
||||||
|
t := binary.LittleEndian.Uint64(buf[6*i:])
|
||||||
|
|
||||||
|
d := t & 0x249249249249 // a₁ + 8b₁ + …
|
||||||
|
d += (t >> 1) & 0x249249249249 // a₁ + a₂ + 8(b₁ + b₂) + …
|
||||||
|
d += (t >> 2) & 0x249249249249 // a₁ + a₂ + a₃ + 4(b₁ + b₂ + b₃) + …
|
||||||
|
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
a := int16(d) & 0x7 // a₁ + a₂ + a₃
|
||||||
|
d >>= 3
|
||||||
|
b := int16(d) & 0x7 // b₁ + b₂ + b₃
|
||||||
|
d >>= 3
|
||||||
|
p[8*i+j] = a - b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample p from a centered binomial distribution with n=4 and p=½ - that is:
|
||||||
|
// coefficients are in {-2, -1, 0, 1, 2} with probabilities {1/16, 1/4,
|
||||||
|
// 3/8, 1/4, 1/16}.
|
||||||
|
func (p *Poly) DeriveNoise2(seed []byte, nonce uint8) {
|
||||||
|
keySuffix := [1]byte{nonce}
|
||||||
|
h := sha3.NewShake256()
|
||||||
|
_, _ = h.Write(seed[:])
|
||||||
|
_, _ = h.Write(keySuffix[:])
|
||||||
|
|
||||||
|
// The distribution at hand is exactly the same as that
|
||||||
|
// of (a + a') - (b + b') where a,a',b,b'~U(1). Thus we need 4 bits per
|
||||||
|
// coefficients, thus 128 bytes of input entropy.
|
||||||
|
|
||||||
|
var buf [128]byte
|
||||||
|
_, _ = h.Read(buf[:])
|
||||||
|
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
// t is interpreted as a + 2a' + 4b + 8b' + ….
|
||||||
|
t := binary.LittleEndian.Uint64(buf[8*i:])
|
||||||
|
|
||||||
|
d := t & 0x5555555555555555 // a + 4b + …
|
||||||
|
d += (t >> 1) & 0x5555555555555555 // a+a' + 4(b + b') + …
|
||||||
|
|
||||||
|
for j := 0; j < 16; j++ {
|
||||||
|
a := int16(d) & 0x3
|
||||||
|
d >>= 2
|
||||||
|
b := int16(d) & 0x3
|
||||||
|
d >>= 2
|
||||||
|
p[16*i+j] = a - b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each i, sample ps[i] uniformly from the given seed for coordinates
|
||||||
|
// xs[i] and ys[i]. ps[i] may be nil and is ignored in that case.
|
||||||
|
//
|
||||||
|
// Can only be called when DeriveX4Available is true.
|
||||||
|
func PolyDeriveUniformX4(ps [4]*Poly, seed *[32]byte, xs, ys [4]uint8) {
|
||||||
|
var perm keccakf1600.StateX4
|
||||||
|
state := perm.Initialize()
|
||||||
|
|
||||||
|
// Absorb the seed in the four states
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
state[i*4+j] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absorb the coordinates, the SHAKE128 domain separator (0b1111), the
|
||||||
|
// start of the padding (0b…001) and the end of the padding 0b100….
|
||||||
|
// Recall that the rate of SHAKE128 is 168; ie. 21 uint64s.
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
state[4*4+j] = uint64(xs[j]) | (uint64(ys[j]) << 8) | (0x1f << 16)
|
||||||
|
state[20*4+j] = 0x80 << 56
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx [4]int // indices into ps
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
if ps[j] == nil {
|
||||||
|
idx[j] = N // mark nil polynomials as completed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done := false
|
||||||
|
for !done {
|
||||||
|
// Applies KeccaK-f[1600] to state to get the next 21 uint64s of each of
|
||||||
|
// the four SHAKE128 streams.
|
||||||
|
perm.Permute()
|
||||||
|
|
||||||
|
done = true
|
||||||
|
|
||||||
|
PolyLoop:
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
if idx[j] == N {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i := 0; i < 7; i++ {
|
||||||
|
var t [16]uint16
|
||||||
|
|
||||||
|
v1 := state[i*3*4+j]
|
||||||
|
v2 := state[(i*3+1)*4+j]
|
||||||
|
v3 := state[(i*3+2)*4+j]
|
||||||
|
|
||||||
|
t[0] = uint16(v1) & 0xfff
|
||||||
|
t[1] = uint16(v1>>12) & 0xfff
|
||||||
|
t[2] = uint16(v1>>24) & 0xfff
|
||||||
|
t[3] = uint16(v1>>36) & 0xfff
|
||||||
|
t[4] = uint16(v1>>48) & 0xfff
|
||||||
|
t[5] = uint16((v1>>60)|(v2<<4)) & 0xfff
|
||||||
|
|
||||||
|
t[6] = uint16(v2>>8) & 0xfff
|
||||||
|
t[7] = uint16(v2>>20) & 0xfff
|
||||||
|
t[8] = uint16(v2>>32) & 0xfff
|
||||||
|
t[9] = uint16(v2>>44) & 0xfff
|
||||||
|
t[10] = uint16((v2>>56)|(v3<<8)) & 0xfff
|
||||||
|
|
||||||
|
t[11] = uint16(v3>>4) & 0xfff
|
||||||
|
t[12] = uint16(v3>>16) & 0xfff
|
||||||
|
t[13] = uint16(v3>>28) & 0xfff
|
||||||
|
t[14] = uint16(v3>>40) & 0xfff
|
||||||
|
t[15] = uint16(v3>>52) & 0xfff
|
||||||
|
|
||||||
|
for k := 0; k < 16; k++ {
|
||||||
|
if t[k] < uint16(Q) {
|
||||||
|
ps[j][idx[j]] = int16(t[k])
|
||||||
|
idx[j]++
|
||||||
|
if idx[j] == N {
|
||||||
|
continue PolyLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
if ps[i] != nil {
|
||||||
|
ps[i].Tangle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample p uniformly from the given seed and x and y coordinates.
|
||||||
|
//
|
||||||
|
// Coefficients are reduced and will be in "tangled" order. See Tangle().
|
||||||
|
func (p *Poly) DeriveUniform(seed *[32]byte, x, y uint8) {
|
||||||
|
var seedSuffix [2]byte
|
||||||
|
var buf [168]byte // rate of SHAKE-128
|
||||||
|
|
||||||
|
seedSuffix[0] = x
|
||||||
|
seedSuffix[1] = y
|
||||||
|
|
||||||
|
h := sha3.NewShake128()
|
||||||
|
_, _ = h.Write(seed[:])
|
||||||
|
_, _ = h.Write(seedSuffix[:])
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for {
|
||||||
|
_, _ = h.Read(buf[:])
|
||||||
|
|
||||||
|
for j := 0; j < 168; j += 3 {
|
||||||
|
t1 := (uint16(buf[j]) | (uint16(buf[j+1]) << 8)) & 0xfff
|
||||||
|
t2 := (uint16(buf[j+1]>>4) | (uint16(buf[j+2]) << 4)) & 0xfff
|
||||||
|
|
||||||
|
if t1 < uint16(Q) {
|
||||||
|
p[i] = int16(t1)
|
||||||
|
i++
|
||||||
|
|
||||||
|
if i == N {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if t2 < uint16(Q) {
|
||||||
|
p[i] = int16(t2)
|
||||||
|
i++
|
||||||
|
|
||||||
|
if i == N {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == N {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Tangle()
|
||||||
|
}
|
33
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go
generated
vendored
Normal file
33
vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func addAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func subAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func nttAVX2(p *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func invNttAVX2(p *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func mulHatAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func detangleAVX2(p *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func tangleAVX2(p *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func barrettReduceAVX2(p *[256]int16)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func normalizeAVX2(p *[256]int16)
|
176
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go
generated
vendored
Normal file
176
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
// Code generated from kyber512/internal/cpapke.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE private key.
|
||||||
|
type PrivateKey struct {
|
||||||
|
sh Vec // NTT(s), normalized
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE public key.
|
||||||
|
type PublicKey struct {
|
||||||
|
rho [32]byte // ρ, the seed for the matrix A
|
||||||
|
th Vec // NTT(t), normalized
|
||||||
|
|
||||||
|
// cached values
|
||||||
|
aT Mat // the matrix Aᵀ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the private key to buf.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
sk.sh.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the private key from buf.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
sk.sh.Unpack(buf)
|
||||||
|
sk.sh.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the public key to buf.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
pk.th.Pack(buf)
|
||||||
|
copy(buf[K*common.PolySize:], pk.rho[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the public key from buf.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
pk.th.Unpack(buf)
|
||||||
|
pk.th.Normalize()
|
||||||
|
copy(pk.rho[:], buf[K*common.PolySize:])
|
||||||
|
pk.aT.Derive(&pk.rho, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derives a new Kyber.CPAPKE keypair from the given seed.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var pk PublicKey
|
||||||
|
var sk PrivateKey
|
||||||
|
|
||||||
|
var expandedSeed [64]byte
|
||||||
|
|
||||||
|
h := sha3.New512()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
|
||||||
|
// This writes hash into expandedSeed. Yes, this is idiomatic Go.
|
||||||
|
_, _ = h.Read(expandedSeed[:])
|
||||||
|
|
||||||
|
copy(pk.rho[:], expandedSeed[:32])
|
||||||
|
sigma := expandedSeed[32:] // σ, the noise seed
|
||||||
|
|
||||||
|
pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
|
||||||
|
|
||||||
|
var eh Vec
|
||||||
|
sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
|
||||||
|
sk.sh.NTT()
|
||||||
|
sk.sh.Normalize()
|
||||||
|
|
||||||
|
eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
|
||||||
|
eh.NTT()
|
||||||
|
|
||||||
|
// Next, we compute t = A s + e.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of s are bounded by q and those of A
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
|
||||||
|
|
||||||
|
// A and s were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// we'll cancel out now. This will also ensure the coefficients of
|
||||||
|
// t are bounded in absolute value by q.
|
||||||
|
pk.th[i].ToMont()
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.th.Add(&pk.th, &eh) // bounded by 8q.
|
||||||
|
pk.th.Normalize()
|
||||||
|
pk.aT.Transpose()
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypts ciphertext ct meant for private key sk to plaintext pt.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
|
||||||
|
var u Vec
|
||||||
|
var v, m common.Poly
|
||||||
|
|
||||||
|
u.Decompress(ct, DU)
|
||||||
|
v.Decompress(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
|
||||||
|
// Compute m = v - <s, u>
|
||||||
|
u.NTT()
|
||||||
|
PolyDotHat(&m, &sk.sh, &u)
|
||||||
|
m.BarrettReduce()
|
||||||
|
m.InvNTT()
|
||||||
|
m.Sub(&v, &m)
|
||||||
|
m.Normalize()
|
||||||
|
|
||||||
|
// Compress polynomial m to original message
|
||||||
|
m.CompressMessageTo(pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypts message pt for the public key to ciphertext ct using randomness
|
||||||
|
// from seed.
|
||||||
|
//
|
||||||
|
// seed has to be of length SeedSize, pt of PlaintextSize and ct of
|
||||||
|
// CiphertextSize.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
|
||||||
|
var rh, e1, u Vec
|
||||||
|
var e2, v, m common.Poly
|
||||||
|
|
||||||
|
// Sample r, e₁ and e₂ from B_η
|
||||||
|
rh.DeriveNoise(seed, 0, Eta1)
|
||||||
|
rh.NTT()
|
||||||
|
rh.BarrettReduce()
|
||||||
|
|
||||||
|
e1.DeriveNoise(seed, K, common.Eta2)
|
||||||
|
e2.DeriveNoise(seed, 2*K, common.Eta2)
|
||||||
|
|
||||||
|
// Next we compute u = Aᵀ r + e₁. First Aᵀ.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of r are bounded by q and those of Aᵀ
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&u[i], &pk.aT[i], &rh)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.BarrettReduce()
|
||||||
|
|
||||||
|
// Aᵀ and r were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// the InvNTT cancels out.
|
||||||
|
u.InvNTT()
|
||||||
|
|
||||||
|
u.Add(&u, &e1) // u = Aᵀ r + e₁
|
||||||
|
|
||||||
|
// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
|
||||||
|
PolyDotHat(&v, &pk.th, &rh)
|
||||||
|
v.BarrettReduce()
|
||||||
|
v.InvNTT()
|
||||||
|
|
||||||
|
m.DecompressMessage(pt)
|
||||||
|
v.Add(&v, &m)
|
||||||
|
v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
|
||||||
|
|
||||||
|
// Pack ciphertext
|
||||||
|
u.Normalize()
|
||||||
|
v.Normalize()
|
||||||
|
|
||||||
|
u.CompressTo(ct, DU)
|
||||||
|
v.CompressTo(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether sk equals other.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
ret := int16(0)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < common.N; j++ {
|
||||||
|
ret |= sk.sh[i][j] ^ other.sh[i][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret == 0
|
||||||
|
}
|
85
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go
generated
vendored
Normal file
85
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Code generated from kyber512/internal/mat.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A k by k matrix of polynomials.
|
||||||
|
type Mat [K]Vec
|
||||||
|
|
||||||
|
// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
|
||||||
|
func (m *Mat) Derive(seed *[32]byte, transpose bool) {
|
||||||
|
if !common.DeriveX4Available {
|
||||||
|
if transpose {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var ps [4]*common.Poly
|
||||||
|
var xs [4]uint8
|
||||||
|
var ys [4]uint8
|
||||||
|
x := uint8(0)
|
||||||
|
y := uint8(0)
|
||||||
|
|
||||||
|
for x != K {
|
||||||
|
idx := 0
|
||||||
|
for ; idx < 4; idx++ {
|
||||||
|
ps[idx] = &m[x][y]
|
||||||
|
|
||||||
|
if transpose {
|
||||||
|
xs[idx] = x
|
||||||
|
ys[idx] = y
|
||||||
|
} else {
|
||||||
|
xs[idx] = y
|
||||||
|
ys[idx] = x
|
||||||
|
}
|
||||||
|
|
||||||
|
y++
|
||||||
|
if y == K {
|
||||||
|
x++
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
if x == K {
|
||||||
|
if idx == 0 {
|
||||||
|
// If there is just one left, then a plain DeriveUniform
|
||||||
|
// is quicker than the X4 variant.
|
||||||
|
ps[0].DeriveUniform(seed, xs[0], ys[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx++; idx < 4; idx++ {
|
||||||
|
ps[idx] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
common.PolyDeriveUniformX4(ps, seed, xs, ys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tranposes A in place.
|
||||||
|
func (m *Mat) Transpose() {
|
||||||
|
for i := 0; i < K-1; i++ {
|
||||||
|
for j := i + 1; j < K; j++ {
|
||||||
|
t := m[i][j]
|
||||||
|
m[i][j] = m[j][i]
|
||||||
|
m[j][i] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go
generated
vendored
Normal file
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Code generated from params.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
K = 4
|
||||||
|
Eta1 = 2
|
||||||
|
DU = 11
|
||||||
|
DV = 5
|
||||||
|
PublicKeySize = 32 + K*common.PolySize
|
||||||
|
|
||||||
|
PrivateKeySize = K * common.PolySize
|
||||||
|
|
||||||
|
PlaintextSize = common.PlaintextSize
|
||||||
|
SeedSize = 32
|
||||||
|
CiphertextSize = 1568
|
||||||
|
)
|
125
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go
generated
vendored
Normal file
125
vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
// Code generated from kyber512/internal/vec.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A vector of K polynomials
|
||||||
|
type Vec [K]common.Poly
|
||||||
|
|
||||||
|
// Samples v[i] from a centered binomial distribution with given η,
|
||||||
|
// seed and nonce+i.
|
||||||
|
//
|
||||||
|
// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
|
||||||
|
func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].DeriveNoise(seed, nonce+uint8(i), eta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the inner product of a and b using "pointwise" multiplication.
|
||||||
|
//
|
||||||
|
// See MulHat() and NTT() for a description of the multiplication.
|
||||||
|
// Assumes a and b are in Montgomery form. p will be in Montgomery form,
|
||||||
|
// and its coefficients will be bounded in absolute value by 2kq.
|
||||||
|
// If a and b are not in Montgomery form, then the action is the same
|
||||||
|
// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
|
||||||
|
// of the Montgomery factor.
|
||||||
|
func PolyDotHat(p *common.Poly, a, b *Vec) {
|
||||||
|
var t common.Poly
|
||||||
|
*p = common.Poly{} // set p to zero
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
t.MulHat(&a[i], &b[i])
|
||||||
|
p.Add(&t, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (v *Vec) BarrettReduce() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].BarrettReduce()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (v *Vec) Normalize() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place inverse NTT(). See Poly.InvNTT() for assumptions.
|
||||||
|
func (v *Vec) InvNTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].InvNTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place forward NTT(). See Poly.NTT() for assumptions.
|
||||||
|
func (v *Vec) NTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].NTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets v to a + b.
|
||||||
|
func (v *Vec) Add(a, b *Vec) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Add(&a[i], &b[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs v into buf, which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Pack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Pack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks v from buf which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Unpack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Unpack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes Compress_q(v, d) to m.
|
||||||
|
//
|
||||||
|
// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
|
||||||
|
func (v *Vec) CompressTo(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].CompressTo(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set v to Decompress_q(m, 1).
|
||||||
|
//
|
||||||
|
// Assumes d is in {3, 4, 5, 10, 11}. v will be normalized.
|
||||||
|
func (v *Vec) Decompress(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Decompress(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⌈(256 d)/8⌉
|
||||||
|
func compressedPolySize(d int) int {
|
||||||
|
switch d {
|
||||||
|
case 4:
|
||||||
|
return 128
|
||||||
|
case 5:
|
||||||
|
return 160
|
||||||
|
case 10:
|
||||||
|
return 320
|
||||||
|
case 11:
|
||||||
|
return 352
|
||||||
|
}
|
||||||
|
panic("unsupported d")
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Code generated from modePkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// kyber1024 implements the IND-CPA-secure Public Key Encryption
|
||||||
|
// scheme Kyber1024.CPAPKE as submitted to round 3 of the NIST PQC competition
|
||||||
|
// and described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber1024
|
||||||
|
|
||||||
|
import (
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/kyber1024/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of seed for EncryptTo
|
||||||
|
EncryptionSeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of a packed PublicKey
|
||||||
|
PublicKeySize = internal.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed PrivateKey
|
||||||
|
PrivateKeySize = internal.PrivateKeySize
|
||||||
|
|
||||||
|
// Size of a ciphertext
|
||||||
|
CiphertextSize = internal.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a plaintext
|
||||||
|
PlaintextSize = internal.PlaintextSize
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Kyber1024.CPAPKE public key
|
||||||
|
type PublicKey internal.PublicKey
|
||||||
|
|
||||||
|
// PrivateKey is the type of Kyber1024.CPAPKE private key
|
||||||
|
type PrivateKey internal.PrivateKey
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed[:])
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private key pair using the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed)
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptTo encrypts message pt for the public key and writes the ciphertext
|
||||||
|
// to ct using randomness from seed.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of pt, seed, and ct are not
|
||||||
|
// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
if len(seed) != EncryptionSeedSize {
|
||||||
|
panic("seed must be of length EncryptionSeedSize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptTo decrypts message ct for the private key and writes the
|
||||||
|
// plaintext to pt.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of ct and pt are not
|
||||||
|
// CiphertextSize and PlaintextSize respectively.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether the two private keys are equal.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
|
||||||
|
}
|
174
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go
generated
vendored
Normal file
174
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go
generated
vendored
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE private key.
|
||||||
|
type PrivateKey struct {
|
||||||
|
sh Vec // NTT(s), normalized
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE public key.
|
||||||
|
type PublicKey struct {
|
||||||
|
rho [32]byte // ρ, the seed for the matrix A
|
||||||
|
th Vec // NTT(t), normalized
|
||||||
|
|
||||||
|
// cached values
|
||||||
|
aT Mat // the matrix Aᵀ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the private key to buf.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
sk.sh.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the private key from buf.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
sk.sh.Unpack(buf)
|
||||||
|
sk.sh.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the public key to buf.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
pk.th.Pack(buf)
|
||||||
|
copy(buf[K*common.PolySize:], pk.rho[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the public key from buf.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
pk.th.Unpack(buf)
|
||||||
|
pk.th.Normalize()
|
||||||
|
copy(pk.rho[:], buf[K*common.PolySize:])
|
||||||
|
pk.aT.Derive(&pk.rho, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derives a new Kyber.CPAPKE keypair from the given seed.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var pk PublicKey
|
||||||
|
var sk PrivateKey
|
||||||
|
|
||||||
|
var expandedSeed [64]byte
|
||||||
|
|
||||||
|
h := sha3.New512()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
|
||||||
|
// This writes hash into expandedSeed. Yes, this is idiomatic Go.
|
||||||
|
_, _ = h.Read(expandedSeed[:])
|
||||||
|
|
||||||
|
copy(pk.rho[:], expandedSeed[:32])
|
||||||
|
sigma := expandedSeed[32:] // σ, the noise seed
|
||||||
|
|
||||||
|
pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
|
||||||
|
|
||||||
|
var eh Vec
|
||||||
|
sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
|
||||||
|
sk.sh.NTT()
|
||||||
|
sk.sh.Normalize()
|
||||||
|
|
||||||
|
eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
|
||||||
|
eh.NTT()
|
||||||
|
|
||||||
|
// Next, we compute t = A s + e.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of s are bounded by q and those of A
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
|
||||||
|
|
||||||
|
// A and s were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// we'll cancel out now. This will also ensure the coefficients of
|
||||||
|
// t are bounded in absolute value by q.
|
||||||
|
pk.th[i].ToMont()
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.th.Add(&pk.th, &eh) // bounded by 8q.
|
||||||
|
pk.th.Normalize()
|
||||||
|
pk.aT.Transpose()
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypts ciphertext ct meant for private key sk to plaintext pt.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
|
||||||
|
var u Vec
|
||||||
|
var v, m common.Poly
|
||||||
|
|
||||||
|
u.Decompress(ct, DU)
|
||||||
|
v.Decompress(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
|
||||||
|
// Compute m = v - <s, u>
|
||||||
|
u.NTT()
|
||||||
|
PolyDotHat(&m, &sk.sh, &u)
|
||||||
|
m.BarrettReduce()
|
||||||
|
m.InvNTT()
|
||||||
|
m.Sub(&v, &m)
|
||||||
|
m.Normalize()
|
||||||
|
|
||||||
|
// Compress polynomial m to original message
|
||||||
|
m.CompressMessageTo(pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypts message pt for the public key to ciphertext ct using randomness
|
||||||
|
// from seed.
|
||||||
|
//
|
||||||
|
// seed has to be of length SeedSize, pt of PlaintextSize and ct of
|
||||||
|
// CiphertextSize.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
|
||||||
|
var rh, e1, u Vec
|
||||||
|
var e2, v, m common.Poly
|
||||||
|
|
||||||
|
// Sample r, e₁ and e₂ from B_η
|
||||||
|
rh.DeriveNoise(seed, 0, Eta1)
|
||||||
|
rh.NTT()
|
||||||
|
rh.BarrettReduce()
|
||||||
|
|
||||||
|
e1.DeriveNoise(seed, K, common.Eta2)
|
||||||
|
e2.DeriveNoise(seed, 2*K, common.Eta2)
|
||||||
|
|
||||||
|
// Next we compute u = Aᵀ r + e₁. First Aᵀ.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of r are bounded by q and those of Aᵀ
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&u[i], &pk.aT[i], &rh)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.BarrettReduce()
|
||||||
|
|
||||||
|
// Aᵀ and r were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// the InvNTT cancels out.
|
||||||
|
u.InvNTT()
|
||||||
|
|
||||||
|
u.Add(&u, &e1) // u = Aᵀ r + e₁
|
||||||
|
|
||||||
|
// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
|
||||||
|
PolyDotHat(&v, &pk.th, &rh)
|
||||||
|
v.BarrettReduce()
|
||||||
|
v.InvNTT()
|
||||||
|
|
||||||
|
m.DecompressMessage(pt)
|
||||||
|
v.Add(&v, &m)
|
||||||
|
v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
|
||||||
|
|
||||||
|
// Pack ciphertext
|
||||||
|
u.Normalize()
|
||||||
|
v.Normalize()
|
||||||
|
|
||||||
|
u.CompressTo(ct, DU)
|
||||||
|
v.CompressTo(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether sk equals other.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
ret := int16(0)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < common.N; j++ {
|
||||||
|
ret |= sk.sh[i][j] ^ other.sh[i][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret == 0
|
||||||
|
}
|
83
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go
generated
vendored
Normal file
83
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A k by k matrix of polynomials.
|
||||||
|
type Mat [K]Vec
|
||||||
|
|
||||||
|
// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
|
||||||
|
func (m *Mat) Derive(seed *[32]byte, transpose bool) {
|
||||||
|
if !common.DeriveX4Available {
|
||||||
|
if transpose {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var ps [4]*common.Poly
|
||||||
|
var xs [4]uint8
|
||||||
|
var ys [4]uint8
|
||||||
|
x := uint8(0)
|
||||||
|
y := uint8(0)
|
||||||
|
|
||||||
|
for x != K {
|
||||||
|
idx := 0
|
||||||
|
for ; idx < 4; idx++ {
|
||||||
|
ps[idx] = &m[x][y]
|
||||||
|
|
||||||
|
if transpose {
|
||||||
|
xs[idx] = x
|
||||||
|
ys[idx] = y
|
||||||
|
} else {
|
||||||
|
xs[idx] = y
|
||||||
|
ys[idx] = x
|
||||||
|
}
|
||||||
|
|
||||||
|
y++
|
||||||
|
if y == K {
|
||||||
|
x++
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
if x == K {
|
||||||
|
if idx == 0 {
|
||||||
|
// If there is just one left, then a plain DeriveUniform
|
||||||
|
// is quicker than the X4 variant.
|
||||||
|
ps[0].DeriveUniform(seed, xs[0], ys[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx++; idx < 4; idx++ {
|
||||||
|
ps[idx] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
common.PolyDeriveUniformX4(ps, seed, xs, ys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tranposes A in place.
|
||||||
|
func (m *Mat) Transpose() {
|
||||||
|
for i := 0; i < K-1; i++ {
|
||||||
|
for j := i + 1; j < K; j++ {
|
||||||
|
t := m[i][j]
|
||||||
|
m[i][j] = m[j][i]
|
||||||
|
m[j][i] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go
generated
vendored
Normal file
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Code generated from params.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
K = 2
|
||||||
|
Eta1 = 3
|
||||||
|
DU = 10
|
||||||
|
DV = 4
|
||||||
|
PublicKeySize = 32 + K*common.PolySize
|
||||||
|
|
||||||
|
PrivateKeySize = K * common.PolySize
|
||||||
|
|
||||||
|
PlaintextSize = common.PlaintextSize
|
||||||
|
SeedSize = 32
|
||||||
|
CiphertextSize = 768
|
||||||
|
)
|
123
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go
generated
vendored
Normal file
123
vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A vector of K polynomials
|
||||||
|
type Vec [K]common.Poly
|
||||||
|
|
||||||
|
// Samples v[i] from a centered binomial distribution with given η,
|
||||||
|
// seed and nonce+i.
|
||||||
|
//
|
||||||
|
// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
|
||||||
|
func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].DeriveNoise(seed, nonce+uint8(i), eta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the inner product of a and b using "pointwise" multiplication.
|
||||||
|
//
|
||||||
|
// See MulHat() and NTT() for a description of the multiplication.
|
||||||
|
// Assumes a and b are in Montgomery form. p will be in Montgomery form,
|
||||||
|
// and its coefficients will be bounded in absolute value by 2kq.
|
||||||
|
// If a and b are not in Montgomery form, then the action is the same
|
||||||
|
// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
|
||||||
|
// of the Montgomery factor.
|
||||||
|
func PolyDotHat(p *common.Poly, a, b *Vec) {
|
||||||
|
var t common.Poly
|
||||||
|
*p = common.Poly{} // set p to zero
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
t.MulHat(&a[i], &b[i])
|
||||||
|
p.Add(&t, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (v *Vec) BarrettReduce() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].BarrettReduce()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (v *Vec) Normalize() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place inverse NTT(). See Poly.InvNTT() for assumptions.
|
||||||
|
func (v *Vec) InvNTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].InvNTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place forward NTT(). See Poly.NTT() for assumptions.
|
||||||
|
func (v *Vec) NTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].NTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets v to a + b.
|
||||||
|
func (v *Vec) Add(a, b *Vec) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Add(&a[i], &b[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs v into buf, which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Pack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Pack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks v from buf which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Unpack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Unpack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes Compress_q(v, d) to m.
|
||||||
|
//
|
||||||
|
// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
|
||||||
|
func (v *Vec) CompressTo(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].CompressTo(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set v to Decompress_q(m, 1).
|
||||||
|
//
|
||||||
|
// Assumes d is in {3, 4, 5, 10, 11}. v will be normalized.
|
||||||
|
func (v *Vec) Decompress(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Decompress(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⌈(256 d)/8⌉
|
||||||
|
func compressedPolySize(d int) int {
|
||||||
|
switch d {
|
||||||
|
case 4:
|
||||||
|
return 128
|
||||||
|
case 5:
|
||||||
|
return 160
|
||||||
|
case 10:
|
||||||
|
return 320
|
||||||
|
case 11:
|
||||||
|
return 352
|
||||||
|
}
|
||||||
|
panic("unsupported d")
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Code generated from modePkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// kyber512 implements the IND-CPA-secure Public Key Encryption
|
||||||
|
// scheme Kyber512.CPAPKE as submitted to round 3 of the NIST PQC competition
|
||||||
|
// and described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber512
|
||||||
|
|
||||||
|
import (
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/kyber512/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of seed for EncryptTo
|
||||||
|
EncryptionSeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of a packed PublicKey
|
||||||
|
PublicKeySize = internal.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed PrivateKey
|
||||||
|
PrivateKeySize = internal.PrivateKeySize
|
||||||
|
|
||||||
|
// Size of a ciphertext
|
||||||
|
CiphertextSize = internal.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a plaintext
|
||||||
|
PlaintextSize = internal.PlaintextSize
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Kyber512.CPAPKE public key
|
||||||
|
type PublicKey internal.PublicKey
|
||||||
|
|
||||||
|
// PrivateKey is the type of Kyber512.CPAPKE private key
|
||||||
|
type PrivateKey internal.PrivateKey
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed[:])
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private key pair using the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed)
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptTo encrypts message pt for the public key and writes the ciphertext
|
||||||
|
// to ct using randomness from seed.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of pt, seed, and ct are not
|
||||||
|
// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
if len(seed) != EncryptionSeedSize {
|
||||||
|
panic("seed must be of length EncryptionSeedSize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptTo decrypts message ct for the private key and writes the
|
||||||
|
// plaintext to pt.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of ct and pt are not
|
||||||
|
// CiphertextSize and PlaintextSize respectively.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether the two private keys are equal.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
|
||||||
|
}
|
176
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go
generated
vendored
Normal file
176
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
// Code generated from kyber512/internal/cpapke.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE private key.
|
||||||
|
type PrivateKey struct {
|
||||||
|
sh Vec // NTT(s), normalized
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Kyber.CPAPKE public key.
|
||||||
|
type PublicKey struct {
|
||||||
|
rho [32]byte // ρ, the seed for the matrix A
|
||||||
|
th Vec // NTT(t), normalized
|
||||||
|
|
||||||
|
// cached values
|
||||||
|
aT Mat // the matrix Aᵀ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the private key to buf.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
sk.sh.Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the private key from buf.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
sk.sh.Unpack(buf)
|
||||||
|
sk.sh.Normalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs the public key to buf.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
pk.th.Pack(buf)
|
||||||
|
copy(buf[K*common.PolySize:], pk.rho[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks the public key from buf.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
pk.th.Unpack(buf)
|
||||||
|
pk.th.Normalize()
|
||||||
|
copy(pk.rho[:], buf[K*common.PolySize:])
|
||||||
|
pk.aT.Derive(&pk.rho, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derives a new Kyber.CPAPKE keypair from the given seed.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
var pk PublicKey
|
||||||
|
var sk PrivateKey
|
||||||
|
|
||||||
|
var expandedSeed [64]byte
|
||||||
|
|
||||||
|
h := sha3.New512()
|
||||||
|
_, _ = h.Write(seed)
|
||||||
|
|
||||||
|
// This writes hash into expandedSeed. Yes, this is idiomatic Go.
|
||||||
|
_, _ = h.Read(expandedSeed[:])
|
||||||
|
|
||||||
|
copy(pk.rho[:], expandedSeed[:32])
|
||||||
|
sigma := expandedSeed[32:] // σ, the noise seed
|
||||||
|
|
||||||
|
pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
|
||||||
|
|
||||||
|
var eh Vec
|
||||||
|
sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
|
||||||
|
sk.sh.NTT()
|
||||||
|
sk.sh.Normalize()
|
||||||
|
|
||||||
|
eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
|
||||||
|
eh.NTT()
|
||||||
|
|
||||||
|
// Next, we compute t = A s + e.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of s are bounded by q and those of A
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
|
||||||
|
|
||||||
|
// A and s were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// we'll cancel out now. This will also ensure the coefficients of
|
||||||
|
// t are bounded in absolute value by q.
|
||||||
|
pk.th[i].ToMont()
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.th.Add(&pk.th, &eh) // bounded by 8q.
|
||||||
|
pk.th.Normalize()
|
||||||
|
pk.aT.Transpose()
|
||||||
|
|
||||||
|
return &pk, &sk
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypts ciphertext ct meant for private key sk to plaintext pt.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
|
||||||
|
var u Vec
|
||||||
|
var v, m common.Poly
|
||||||
|
|
||||||
|
u.Decompress(ct, DU)
|
||||||
|
v.Decompress(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
|
||||||
|
// Compute m = v - <s, u>
|
||||||
|
u.NTT()
|
||||||
|
PolyDotHat(&m, &sk.sh, &u)
|
||||||
|
m.BarrettReduce()
|
||||||
|
m.InvNTT()
|
||||||
|
m.Sub(&v, &m)
|
||||||
|
m.Normalize()
|
||||||
|
|
||||||
|
// Compress polynomial m to original message
|
||||||
|
m.CompressMessageTo(pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypts message pt for the public key to ciphertext ct using randomness
|
||||||
|
// from seed.
|
||||||
|
//
|
||||||
|
// seed has to be of length SeedSize, pt of PlaintextSize and ct of
|
||||||
|
// CiphertextSize.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
|
||||||
|
var rh, e1, u Vec
|
||||||
|
var e2, v, m common.Poly
|
||||||
|
|
||||||
|
// Sample r, e₁ and e₂ from B_η
|
||||||
|
rh.DeriveNoise(seed, 0, Eta1)
|
||||||
|
rh.NTT()
|
||||||
|
rh.BarrettReduce()
|
||||||
|
|
||||||
|
e1.DeriveNoise(seed, K, common.Eta2)
|
||||||
|
e2.DeriveNoise(seed, 2*K, common.Eta2)
|
||||||
|
|
||||||
|
// Next we compute u = Aᵀ r + e₁. First Aᵀ.
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
// Note that coefficients of r are bounded by q and those of Aᵀ
|
||||||
|
// are bounded by 4.5q and so their product is bounded by 2¹⁵q
|
||||||
|
// as required for multiplication.
|
||||||
|
PolyDotHat(&u[i], &pk.aT[i], &rh)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.BarrettReduce()
|
||||||
|
|
||||||
|
// Aᵀ and r were not in Montgomery form, so the Montgomery
|
||||||
|
// multiplications in the inner product added a factor R⁻¹ which
|
||||||
|
// the InvNTT cancels out.
|
||||||
|
u.InvNTT()
|
||||||
|
|
||||||
|
u.Add(&u, &e1) // u = Aᵀ r + e₁
|
||||||
|
|
||||||
|
// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
|
||||||
|
PolyDotHat(&v, &pk.th, &rh)
|
||||||
|
v.BarrettReduce()
|
||||||
|
v.InvNTT()
|
||||||
|
|
||||||
|
m.DecompressMessage(pt)
|
||||||
|
v.Add(&v, &m)
|
||||||
|
v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
|
||||||
|
|
||||||
|
// Pack ciphertext
|
||||||
|
u.Normalize()
|
||||||
|
v.Normalize()
|
||||||
|
|
||||||
|
u.CompressTo(ct, DU)
|
||||||
|
v.CompressTo(ct[K*compressedPolySize(DU):], DV)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether sk equals other.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
ret := int16(0)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < common.N; j++ {
|
||||||
|
ret |= sk.sh[i][j] ^ other.sh[i][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret == 0
|
||||||
|
}
|
85
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go
generated
vendored
Normal file
85
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Code generated from kyber512/internal/mat.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A k by k matrix of polynomials.
|
||||||
|
type Mat [K]Vec
|
||||||
|
|
||||||
|
// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
|
||||||
|
func (m *Mat) Derive(seed *[32]byte, transpose bool) {
|
||||||
|
if !common.DeriveX4Available {
|
||||||
|
if transpose {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
for j := 0; j < K; j++ {
|
||||||
|
m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var ps [4]*common.Poly
|
||||||
|
var xs [4]uint8
|
||||||
|
var ys [4]uint8
|
||||||
|
x := uint8(0)
|
||||||
|
y := uint8(0)
|
||||||
|
|
||||||
|
for x != K {
|
||||||
|
idx := 0
|
||||||
|
for ; idx < 4; idx++ {
|
||||||
|
ps[idx] = &m[x][y]
|
||||||
|
|
||||||
|
if transpose {
|
||||||
|
xs[idx] = x
|
||||||
|
ys[idx] = y
|
||||||
|
} else {
|
||||||
|
xs[idx] = y
|
||||||
|
ys[idx] = x
|
||||||
|
}
|
||||||
|
|
||||||
|
y++
|
||||||
|
if y == K {
|
||||||
|
x++
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
if x == K {
|
||||||
|
if idx == 0 {
|
||||||
|
// If there is just one left, then a plain DeriveUniform
|
||||||
|
// is quicker than the X4 variant.
|
||||||
|
ps[0].DeriveUniform(seed, xs[0], ys[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx++; idx < 4; idx++ {
|
||||||
|
ps[idx] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
common.PolyDeriveUniformX4(ps, seed, xs, ys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tranposes A in place.
|
||||||
|
func (m *Mat) Transpose() {
|
||||||
|
for i := 0; i < K-1; i++ {
|
||||||
|
for j := i + 1; j < K; j++ {
|
||||||
|
t := m[i][j]
|
||||||
|
m[i][j] = m[j][i]
|
||||||
|
m[j][i] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go
generated
vendored
Normal file
21
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Code generated from params.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
K = 3
|
||||||
|
Eta1 = 2
|
||||||
|
DU = 10
|
||||||
|
DV = 4
|
||||||
|
PublicKeySize = 32 + K*common.PolySize
|
||||||
|
|
||||||
|
PrivateKeySize = K * common.PolySize
|
||||||
|
|
||||||
|
PlaintextSize = common.PlaintextSize
|
||||||
|
SeedSize = 32
|
||||||
|
CiphertextSize = 1088
|
||||||
|
)
|
125
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go
generated
vendored
Normal file
125
vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
// Code generated from kyber512/internal/vec.go by gen.go
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A vector of K polynomials
|
||||||
|
type Vec [K]common.Poly
|
||||||
|
|
||||||
|
// Samples v[i] from a centered binomial distribution with given η,
|
||||||
|
// seed and nonce+i.
|
||||||
|
//
|
||||||
|
// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
|
||||||
|
func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].DeriveNoise(seed, nonce+uint8(i), eta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets p to the inner product of a and b using "pointwise" multiplication.
|
||||||
|
//
|
||||||
|
// See MulHat() and NTT() for a description of the multiplication.
|
||||||
|
// Assumes a and b are in Montgomery form. p will be in Montgomery form,
|
||||||
|
// and its coefficients will be bounded in absolute value by 2kq.
|
||||||
|
// If a and b are not in Montgomery form, then the action is the same
|
||||||
|
// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
|
||||||
|
// of the Montgomery factor.
|
||||||
|
func PolyDotHat(p *common.Poly, a, b *Vec) {
|
||||||
|
var t common.Poly
|
||||||
|
*p = common.Poly{} // set p to zero
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
t.MulHat(&a[i], &b[i])
|
||||||
|
p.Add(&t, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q}.
|
||||||
|
func (v *Vec) BarrettReduce() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].BarrettReduce()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizes coefficients in-place.
|
||||||
|
//
|
||||||
|
// Ensures each coefficient is in {0, …, q-1}.
|
||||||
|
func (v *Vec) Normalize() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place inverse NTT(). See Poly.InvNTT() for assumptions.
|
||||||
|
func (v *Vec) InvNTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].InvNTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies in-place forward NTT(). See Poly.NTT() for assumptions.
|
||||||
|
func (v *Vec) NTT() {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].NTT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets v to a + b.
|
||||||
|
func (v *Vec) Add(a, b *Vec) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Add(&a[i], &b[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs v into buf, which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Pack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Pack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks v from buf which must be of length K*PolySize.
|
||||||
|
func (v *Vec) Unpack(buf []byte) {
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Unpack(buf[common.PolySize*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes Compress_q(v, d) to m.
|
||||||
|
//
|
||||||
|
// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
|
||||||
|
func (v *Vec) CompressTo(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].CompressTo(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set v to Decompress_q(m, 1).
|
||||||
|
//
|
||||||
|
// Assumes d is in {3, 4, 5, 10, 11}. v will be normalized.
|
||||||
|
func (v *Vec) Decompress(m []byte, d int) {
|
||||||
|
size := compressedPolySize(d)
|
||||||
|
for i := 0; i < K; i++ {
|
||||||
|
v[i].Decompress(m[size*i:], d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⌈(256 d)/8⌉
|
||||||
|
func compressedPolySize(d int) int {
|
||||||
|
switch d {
|
||||||
|
case 4:
|
||||||
|
return 128
|
||||||
|
case 5:
|
||||||
|
return 160
|
||||||
|
case 10:
|
||||||
|
return 320
|
||||||
|
case 11:
|
||||||
|
return 352
|
||||||
|
}
|
||||||
|
panic("unsupported d")
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
// Code generated from modePkg.templ.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// kyber768 implements the IND-CPA-secure Public Key Encryption
|
||||||
|
// scheme Kyber768.CPAPKE as submitted to round 3 of the NIST PQC competition
|
||||||
|
// and described in
|
||||||
|
//
|
||||||
|
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
|
||||||
|
package kyber768
|
||||||
|
|
||||||
|
import (
|
||||||
|
cryptoRand "crypto/rand"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/pke/kyber/kyber768/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Size of seed for NewKeyFromSeed
|
||||||
|
KeySeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of seed for EncryptTo
|
||||||
|
EncryptionSeedSize = internal.SeedSize
|
||||||
|
|
||||||
|
// Size of a packed PublicKey
|
||||||
|
PublicKeySize = internal.PublicKeySize
|
||||||
|
|
||||||
|
// Size of a packed PrivateKey
|
||||||
|
PrivateKeySize = internal.PrivateKeySize
|
||||||
|
|
||||||
|
// Size of a ciphertext
|
||||||
|
CiphertextSize = internal.CiphertextSize
|
||||||
|
|
||||||
|
// Size of a plaintext
|
||||||
|
PlaintextSize = internal.PlaintextSize
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Kyber768.CPAPKE public key
|
||||||
|
type PublicKey internal.PublicKey
|
||||||
|
|
||||||
|
// PrivateKey is the type of Kyber768.CPAPKE private key
|
||||||
|
type PrivateKey internal.PrivateKey
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
|
||||||
|
var seed [KeySeedSize]byte
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptoRand.Reader
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(rand, seed[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed[:])
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed derives a public/private key pair using the given seed.
|
||||||
|
//
|
||||||
|
// Panics if seed is not of length KeySeedSize.
|
||||||
|
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
|
||||||
|
if len(seed) != KeySeedSize {
|
||||||
|
panic("seed must be of length KeySeedSize")
|
||||||
|
}
|
||||||
|
pk, sk := internal.NewKeyFromSeed(seed)
|
||||||
|
return (*PublicKey)(pk), (*PrivateKey)(sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptTo encrypts message pt for the public key and writes the ciphertext
|
||||||
|
// to ct using randomness from seed.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of pt, seed, and ct are not
|
||||||
|
// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
|
||||||
|
func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
if len(seed) != EncryptionSeedSize {
|
||||||
|
panic("seed must be of length EncryptionSeedSize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptTo decrypts message ct for the private key and writes the
|
||||||
|
// plaintext to pt.
|
||||||
|
//
|
||||||
|
// This function panics if the lengths of ct and pt are not
|
||||||
|
// CiphertextSize and PlaintextSize respectively.
|
||||||
|
func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
|
||||||
|
if len(pt) != PlaintextSize {
|
||||||
|
panic("pt must be of length PlaintextSize")
|
||||||
|
}
|
||||||
|
if len(ct) != CiphertextSize {
|
||||||
|
panic("ct must be of length CiphertextSize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs pk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs sk into the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Pack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Pack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks pk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PublicKeySize.
|
||||||
|
func (pk *PublicKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PublicKeySize {
|
||||||
|
panic("buf must be of size PublicKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PublicKey)(pk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpacks sk from the given buffer.
|
||||||
|
//
|
||||||
|
// Panics if buf is not of length PrivateKeySize.
|
||||||
|
func (sk *PrivateKey) Unpack(buf []byte) {
|
||||||
|
if len(buf) != PrivateKeySize {
|
||||||
|
panic("buf must be of size PrivateKeySize")
|
||||||
|
}
|
||||||
|
(*internal.PrivateKey)(sk).Unpack(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns whether the two private keys are equal.
|
||||||
|
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
|
||||||
|
return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
// Package keccakf1600 provides a two and four-way Keccak-f[1600] permutation in parallel.
|
||||||
|
//
|
||||||
|
// Keccak-f[1600] is the permutation underlying several algorithms such as
|
||||||
|
// Keccak, SHA3 and SHAKE. Running two or four permutations in parallel is
|
||||||
|
// useful in some scenarios like in hash-based signatures.
|
||||||
|
//
|
||||||
|
// # Limitations
|
||||||
|
//
|
||||||
|
// Note that not all the architectures support SIMD instructions. This package
|
||||||
|
// uses AVX2 instructions that are available in some AMD64 architectures
|
||||||
|
// and NEON instructions that are available in some ARM64 architectures.
|
||||||
|
//
|
||||||
|
// For those systems not supporting these, the package still provides the
|
||||||
|
// expected functionality by means of a generic and slow implementation.
|
||||||
|
// The recommendation is to beforehand verify IsEnabledX4() and IsEnabledX2()
|
||||||
|
// to determine if the current system supports the SIMD implementation.
|
||||||
|
package keccakf1600
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/internal/sha3"
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StateX4 contains state for the four-way permutation including the four
|
||||||
|
// interleaved [25]uint64 buffers. Call Initialize() before use to initialize
|
||||||
|
// and get a pointer to the interleaved buffer.
|
||||||
|
type StateX4 struct {
|
||||||
|
// Go guarantees a to be aligned on 8 bytes, whereas we need it to be
|
||||||
|
// aligned on 32 bytes for bet performance. Thus we leave some headroom
|
||||||
|
// to be able to move the start of the state.
|
||||||
|
|
||||||
|
// 4 x 25 uint64s for the interleaved states and three uint64s headroom
|
||||||
|
// to fix alignment.
|
||||||
|
a [103]uint64
|
||||||
|
|
||||||
|
// Offset into a that is 32 byte aligned.
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateX2 contains state for the two-way permutation including the two
|
||||||
|
// interleaved [25]uint64 buffers. Call Initialize() before use to initialize
|
||||||
|
// and get a pointer to the interleaved buffer.
|
||||||
|
type StateX2 struct {
|
||||||
|
// Go guarantees a to be aligned on 8 bytes, whereas we need it to be
|
||||||
|
// aligned on 32 bytes for bet performance. Thus we leave some headroom
|
||||||
|
// to be able to move the start of the state.
|
||||||
|
|
||||||
|
// 2 x 25 uint64s for the interleaved states and three uint64s headroom
|
||||||
|
// to fix alignment.
|
||||||
|
a [53]uint64
|
||||||
|
|
||||||
|
// Offset into a that is 32 byte aligned.
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEnabledX4 returns true if the architecture supports a four-way SIMD
|
||||||
|
// implementation provided in this package.
|
||||||
|
func IsEnabledX4() bool { return cpu.X86.HasAVX2 }
|
||||||
|
|
||||||
|
// IsEnabledX2 returns true if the architecture supports a two-way SIMD
|
||||||
|
// implementation provided in this package.
|
||||||
|
func IsEnabledX2() bool {
|
||||||
|
// After Go 1.16 the flag cpu.ARM64.HasSHA3 is no longer exposed.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the state and returns the buffer on which the four permutations
|
||||||
|
// will act: a uint64 slice of length 100. The first permutation will act
|
||||||
|
// on {a[0], a[4], ..., a[96]}, the second on {a[1], a[5], ..., a[97]}, etc.
|
||||||
|
func (s *StateX4) Initialize() []uint64 {
|
||||||
|
rp := unsafe.Pointer(&s.a[0])
|
||||||
|
|
||||||
|
// uint64s are always aligned by a multiple of 8. Compute the remainder
|
||||||
|
// of the address modulo 32 divided by 8.
|
||||||
|
rem := (int(uintptr(rp)&31) >> 3)
|
||||||
|
|
||||||
|
if rem != 0 {
|
||||||
|
s.offset = 4 - rem
|
||||||
|
}
|
||||||
|
|
||||||
|
// The slice we return will be aligned on 32 byte boundary.
|
||||||
|
return s.a[s.offset : s.offset+100]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the state and returns the buffer on which the two permutations
|
||||||
|
// will act: a uint64 slice of length 50. The first permutation will act
|
||||||
|
// on {a[0], a[2], ..., a[48]} and the second on {a[1], a[3], ..., a[49]}.
|
||||||
|
func (s *StateX2) Initialize() []uint64 {
|
||||||
|
rp := unsafe.Pointer(&s.a[0])
|
||||||
|
|
||||||
|
// uint64s are always aligned by a multiple of 8. Compute the remainder
|
||||||
|
// of the address modulo 32 divided by 8.
|
||||||
|
rem := (int(uintptr(rp)&31) >> 3)
|
||||||
|
|
||||||
|
if rem != 0 {
|
||||||
|
s.offset = 4 - rem
|
||||||
|
}
|
||||||
|
|
||||||
|
// The slice we return will be aligned on 32 byte boundary.
|
||||||
|
return s.a[s.offset : s.offset+50]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permute performs the four parallel Keccak-f[1600]s interleaved on the slice
|
||||||
|
// returned from Initialize().
|
||||||
|
func (s *StateX4) Permute() {
|
||||||
|
if IsEnabledX4() {
|
||||||
|
permuteSIMDx4(s.a[s.offset:])
|
||||||
|
} else {
|
||||||
|
permuteScalarX4(s.a[s.offset:]) // A slower generic implementation.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permute performs the two parallel Keccak-f[1600]s interleaved on the slice
|
||||||
|
// returned from Initialize().
|
||||||
|
func (s *StateX2) Permute() {
|
||||||
|
if IsEnabledX2() {
|
||||||
|
permuteSIMDx2(s.a[s.offset:])
|
||||||
|
} else {
|
||||||
|
permuteScalarX2(s.a[s.offset:]) // A slower generic implementation.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func permuteScalarX4(a []uint64) {
|
||||||
|
var buf [25]uint64
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
for j := 0; j < 25; j++ {
|
||||||
|
buf[j] = a[4*j+i]
|
||||||
|
}
|
||||||
|
sha3.KeccakF1600(&buf)
|
||||||
|
for j := 0; j < 25; j++ {
|
||||||
|
a[4*j+i] = buf[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func permuteScalarX2(a []uint64) {
|
||||||
|
var buf [25]uint64
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
for j := 0; j < 25; j++ {
|
||||||
|
buf[j] = a[2*j+i]
|
||||||
|
}
|
||||||
|
sha3.KeccakF1600(&buf)
|
||||||
|
for j := 0; j < 25; j++ {
|
||||||
|
a[2*j+i] = buf[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go
generated
vendored
Normal file
13
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//go:build arm64 && go1.16
|
||||||
|
// +build arm64,go1.16
|
||||||
|
|
||||||
|
package keccakf1600
|
||||||
|
|
||||||
|
import "github.com/cloudflare/circl/internal/sha3"
|
||||||
|
|
||||||
|
func permuteSIMDx2(state []uint64) { f1600x2ARM(&state[0], &sha3.RC) }
|
||||||
|
|
||||||
|
func permuteSIMDx4(state []uint64) { permuteScalarX4(state) }
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func f1600x2ARM(state *uint64, rc *[24]uint64)
|
130
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s
generated
vendored
Normal file
130
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s
generated
vendored
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
// +build arm64,go1.16
|
||||||
|
|
||||||
|
// Taken from https://github.com/bwesterb/armed-keccak
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func f1600x2ARM(state *uint64, rc *[24]uint64)
|
||||||
|
TEXT ·f1600x2ARM(SB), NOSPLIT, $0-16
|
||||||
|
MOVD state+0(FP), R0
|
||||||
|
MOVD rc+8(FP), R1
|
||||||
|
MOVD R0, R2
|
||||||
|
MOVD $24, R3
|
||||||
|
|
||||||
|
VLD1.P 64(R0), [ V0.B16, V1.B16, V2.B16, V3.B16]
|
||||||
|
VLD1.P 64(R0), [ V4.B16, V5.B16, V6.B16, V7.B16]
|
||||||
|
VLD1.P 64(R0), [ V8.B16, V9.B16, V10.B16, V11.B16]
|
||||||
|
VLD1.P 64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
|
||||||
|
VLD1.P 64(R0), [V16.B16, V17.B16, V18.B16, V19.B16]
|
||||||
|
VLD1.P 64(R0), [V20.B16, V21.B16, V22.B16, V23.B16]
|
||||||
|
VLD1.P (R0), [V24.B16]
|
||||||
|
|
||||||
|
loop:
|
||||||
|
// Execute theta but without xorring into the state yet.
|
||||||
|
VEOR3 V10.B16, V5.B16, V0.B16, V25.B16
|
||||||
|
VEOR3 V11.B16, V6.B16, V1.B16, V26.B16
|
||||||
|
VEOR3 V12.B16, V7.B16, V2.B16, V27.B16
|
||||||
|
VEOR3 V13.B16, V8.B16, V3.B16, V28.B16
|
||||||
|
VEOR3 V14.B16, V9.B16, V4.B16, V29.B16
|
||||||
|
|
||||||
|
VEOR3 V20.B16, V15.B16, V25.B16, V25.B16
|
||||||
|
VEOR3 V21.B16, V16.B16, V26.B16, V26.B16
|
||||||
|
VEOR3 V22.B16, V17.B16, V27.B16, V27.B16
|
||||||
|
VEOR3 V23.B16, V18.B16, V28.B16, V28.B16
|
||||||
|
VEOR3 V24.B16, V19.B16, V29.B16, V29.B16
|
||||||
|
|
||||||
|
// Xor parities from step theta into the state at the same time as
|
||||||
|
// exeuting rho and pi.
|
||||||
|
VRAX1 V26.D2, V29.D2, V30.D2
|
||||||
|
VRAX1 V29.D2, V27.D2, V29.D2
|
||||||
|
VRAX1 V27.D2, V25.D2, V27.D2
|
||||||
|
VRAX1 V25.D2, V28.D2, V25.D2
|
||||||
|
VRAX1 V28.D2, V26.D2, V28.D2
|
||||||
|
|
||||||
|
VEOR V30.B16, V0.B16, V0.B16
|
||||||
|
VMOV V1.B16, V31.B16
|
||||||
|
|
||||||
|
VXAR $20, V27.D2, V6.D2, V1.D2
|
||||||
|
VXAR $44, V25.D2, V9.D2, V6.D2
|
||||||
|
VXAR $3 , V28.D2, V22.D2, V9.D2
|
||||||
|
VXAR $25, V25.D2, V14.D2, V22.D2
|
||||||
|
VXAR $46, V30.D2, V20.D2, V14.D2
|
||||||
|
VXAR $2 , V28.D2, V2.D2, V20.D2
|
||||||
|
VXAR $21, V28.D2, V12.D2, V2.D2
|
||||||
|
VXAR $39, V29.D2, V13.D2, V12.D2
|
||||||
|
VXAR $56, V25.D2, V19.D2, V13.D2
|
||||||
|
VXAR $8 , V29.D2, V23.D2, V19.D2
|
||||||
|
VXAR $23, V30.D2, V15.D2, V23.D2
|
||||||
|
VXAR $37, V25.D2, V4.D2, V15.D2
|
||||||
|
VXAR $50, V25.D2, V24.D2, V4.D2
|
||||||
|
VXAR $62, V27.D2, V21.D2, V24.D2
|
||||||
|
VXAR $9 , V29.D2, V8.D2, V21.D2
|
||||||
|
VXAR $19, V27.D2, V16.D2, V8.D2
|
||||||
|
VXAR $28, V30.D2, V5.D2, V16.D2
|
||||||
|
VXAR $36, V29.D2, V3.D2, V5.D2
|
||||||
|
VXAR $43, V29.D2, V18.D2, V3.D2
|
||||||
|
VXAR $49, V28.D2, V17.D2, V18.D2
|
||||||
|
VXAR $54, V27.D2, V11.D2, V17.D2
|
||||||
|
VXAR $58, V28.D2, V7.D2, V11.D2
|
||||||
|
VXAR $61, V30.D2, V10.D2, V7.D2
|
||||||
|
VXAR $63, V27.D2, V31.D2, V10.D2
|
||||||
|
|
||||||
|
// Chi
|
||||||
|
VBCAX V1.B16, V2.B16, V0.B16, V25.B16
|
||||||
|
VBCAX V2.B16, V3.B16, V1.B16, V26.B16
|
||||||
|
VBCAX V3.B16, V4.B16, V2.B16, V2.B16
|
||||||
|
VBCAX V4.B16, V0.B16, V3.B16, V3.B16
|
||||||
|
VBCAX V0.B16, V1.B16, V4.B16, V4.B16
|
||||||
|
VMOV V25.B16, V0.B16
|
||||||
|
VMOV V26.B16, V1.B16
|
||||||
|
|
||||||
|
VBCAX V6.B16, V7.B16, V5.B16, V25.B16
|
||||||
|
VBCAX V7.B16, V8.B16, V6.B16, V26.B16
|
||||||
|
VBCAX V8.B16, V9.B16, V7.B16, V7.B16
|
||||||
|
VBCAX V9.B16, V5.B16, V8.B16, V8.B16
|
||||||
|
VBCAX V5.B16, V6.B16, V9.B16, V9.B16
|
||||||
|
VMOV V25.B16, V5.B16
|
||||||
|
VMOV V26.B16, V6.B16
|
||||||
|
|
||||||
|
VBCAX V11.B16, V12.B16, V10.B16, V25.B16
|
||||||
|
VBCAX V12.B16, V13.B16, V11.B16, V26.B16
|
||||||
|
VBCAX V13.B16, V14.B16, V12.B16, V12.B16
|
||||||
|
VBCAX V14.B16, V10.B16, V13.B16, V13.B16
|
||||||
|
VBCAX V10.B16, V11.B16, V14.B16, V14.B16
|
||||||
|
VMOV V25.B16, V10.B16
|
||||||
|
VMOV V26.B16, V11.B16
|
||||||
|
|
||||||
|
VBCAX V16.B16, V17.B16, V15.B16, V25.B16
|
||||||
|
VBCAX V17.B16, V18.B16, V16.B16, V26.B16
|
||||||
|
VBCAX V18.B16, V19.B16, V17.B16, V17.B16
|
||||||
|
VBCAX V19.B16, V15.B16, V18.B16, V18.B16
|
||||||
|
VBCAX V15.B16, V16.B16, V19.B16, V19.B16
|
||||||
|
VMOV V25.B16, V15.B16
|
||||||
|
VMOV V26.B16, V16.B16
|
||||||
|
|
||||||
|
VBCAX V21.B16, V22.B16, V20.B16, V25.B16
|
||||||
|
VBCAX V22.B16, V23.B16, V21.B16, V26.B16
|
||||||
|
VBCAX V23.B16, V24.B16, V22.B16, V22.B16
|
||||||
|
VBCAX V24.B16, V20.B16, V23.B16, V23.B16
|
||||||
|
VBCAX V20.B16, V21.B16, V24.B16, V24.B16
|
||||||
|
VMOV V25.B16, V20.B16
|
||||||
|
VMOV V26.B16, V21.B16
|
||||||
|
|
||||||
|
// Iota
|
||||||
|
VLD1R.P 8(R1), [V25.D2]
|
||||||
|
VEOR V25.B16, V0.B16, V0.B16
|
||||||
|
|
||||||
|
SUBS $1, R3, R3
|
||||||
|
CBNZ R3, loop
|
||||||
|
|
||||||
|
MOVD R2, R0
|
||||||
|
|
||||||
|
VST1.P [ V0.B16, V1.B16, V2.B16, V3.B16], 64(R0)
|
||||||
|
VST1.P [ V4.B16, V5.B16, V6.B16, V7.B16], 64(R0)
|
||||||
|
VST1.P [ V8.B16, V9.B16, V10.B16, V11.B16], 64(R0)
|
||||||
|
VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R0)
|
||||||
|
VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R0)
|
||||||
|
VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R0)
|
||||||
|
VST1.P [V24.B16], (R0)
|
||||||
|
|
||||||
|
RET
|
7
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go
generated
vendored
Normal file
7
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package keccakf1600
|
||||||
|
|
||||||
|
import "github.com/cloudflare/circl/internal/sha3"
|
||||||
|
|
||||||
|
func permuteSIMDx4(state []uint64) { f1600x4AVX2(&state[0], &sha3.RC) }
|
||||||
|
|
||||||
|
func permuteSIMDx2(state []uint64) { permuteScalarX2(state) }
|
894
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s
generated
vendored
Normal file
894
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,894 @@
|
||||||
|
// Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT.
|
||||||
|
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func f1600x4AVX2(state *uint64, rc *[24]uint64)
|
||||||
|
// Requires: AVX, AVX2
|
||||||
|
TEXT ·f1600x4AVX2(SB), NOSPLIT, $0-16
|
||||||
|
MOVQ state+0(FP), AX
|
||||||
|
MOVQ rc+8(FP), CX
|
||||||
|
MOVQ $0x0000000000000006, DX
|
||||||
|
|
||||||
|
loop:
|
||||||
|
VMOVDQA (AX), Y0
|
||||||
|
VMOVDQA 32(AX), Y1
|
||||||
|
VMOVDQA 64(AX), Y2
|
||||||
|
VMOVDQA 96(AX), Y3
|
||||||
|
VMOVDQA 128(AX), Y4
|
||||||
|
VPXOR 160(AX), Y0, Y0
|
||||||
|
VPXOR 192(AX), Y1, Y1
|
||||||
|
VPXOR 224(AX), Y2, Y2
|
||||||
|
VPXOR 256(AX), Y3, Y3
|
||||||
|
VPXOR 288(AX), Y4, Y4
|
||||||
|
VPXOR 320(AX), Y0, Y0
|
||||||
|
VPXOR 352(AX), Y1, Y1
|
||||||
|
VPXOR 384(AX), Y2, Y2
|
||||||
|
VPXOR 416(AX), Y3, Y3
|
||||||
|
VPXOR 448(AX), Y4, Y4
|
||||||
|
VPXOR 480(AX), Y0, Y0
|
||||||
|
VPXOR 512(AX), Y1, Y1
|
||||||
|
VPXOR 544(AX), Y2, Y2
|
||||||
|
VPXOR 576(AX), Y3, Y3
|
||||||
|
VPXOR 608(AX), Y4, Y4
|
||||||
|
VPXOR 640(AX), Y0, Y0
|
||||||
|
VPXOR 672(AX), Y1, Y1
|
||||||
|
VPXOR 704(AX), Y2, Y2
|
||||||
|
VPXOR 736(AX), Y3, Y3
|
||||||
|
VPXOR 768(AX), Y4, Y4
|
||||||
|
VPSLLQ $0x01, Y1, Y5
|
||||||
|
VPSLLQ $0x01, Y2, Y6
|
||||||
|
VPSLLQ $0x01, Y3, Y7
|
||||||
|
VPSLLQ $0x01, Y4, Y8
|
||||||
|
VPSLLQ $0x01, Y0, Y9
|
||||||
|
VPSRLQ $0x3f, Y1, Y10
|
||||||
|
VPSRLQ $0x3f, Y2, Y11
|
||||||
|
VPSRLQ $0x3f, Y3, Y12
|
||||||
|
VPSRLQ $0x3f, Y4, Y13
|
||||||
|
VPSRLQ $0x3f, Y0, Y14
|
||||||
|
VPOR Y5, Y10, Y10
|
||||||
|
VPOR Y6, Y11, Y11
|
||||||
|
VPOR Y7, Y12, Y12
|
||||||
|
VPOR Y8, Y13, Y13
|
||||||
|
VPOR Y9, Y14, Y14
|
||||||
|
VPXOR Y10, Y4, Y10
|
||||||
|
VPXOR Y11, Y0, Y11
|
||||||
|
VPXOR Y12, Y1, Y12
|
||||||
|
VPXOR Y13, Y2, Y13
|
||||||
|
VPXOR Y14, Y3, Y14
|
||||||
|
VPXOR (AX), Y10, Y0
|
||||||
|
VPXOR 192(AX), Y11, Y1
|
||||||
|
VPXOR 384(AX), Y12, Y2
|
||||||
|
VPXOR 576(AX), Y13, Y3
|
||||||
|
VPXOR 768(AX), Y14, Y4
|
||||||
|
VPSLLQ $0x2c, Y1, Y6
|
||||||
|
VPSLLQ $0x2b, Y2, Y7
|
||||||
|
VPSLLQ $0x15, Y3, Y8
|
||||||
|
VPSLLQ $0x0e, Y4, Y9
|
||||||
|
VPSRLQ $0x14, Y1, Y1
|
||||||
|
VPSRLQ $0x15, Y2, Y2
|
||||||
|
VPSRLQ $0x2b, Y3, Y3
|
||||||
|
VPSRLQ $0x32, Y4, Y4
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VPBROADCASTQ (CX), Y0
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VMOVDQA Y5, (AX)
|
||||||
|
VMOVDQA Y6, 192(AX)
|
||||||
|
VMOVDQA Y7, 384(AX)
|
||||||
|
VMOVDQA Y8, 576(AX)
|
||||||
|
VMOVDQA Y9, 768(AX)
|
||||||
|
VPXOR 96(AX), Y13, Y0
|
||||||
|
VPXOR 288(AX), Y14, Y1
|
||||||
|
VPXOR 320(AX), Y10, Y2
|
||||||
|
VPXOR 512(AX), Y11, Y3
|
||||||
|
VPXOR 704(AX), Y12, Y4
|
||||||
|
VPSLLQ $0x1c, Y0, Y5
|
||||||
|
VPSLLQ $0x14, Y1, Y6
|
||||||
|
VPSLLQ $0x03, Y2, Y7
|
||||||
|
VPSLLQ $0x2d, Y3, Y8
|
||||||
|
VPSLLQ $0x3d, Y4, Y9
|
||||||
|
VPSRLQ $0x24, Y0, Y0
|
||||||
|
VPSRLQ $0x2c, Y1, Y1
|
||||||
|
VPSRLQ $0x3d, Y2, Y2
|
||||||
|
VPSRLQ $0x13, Y3, Y3
|
||||||
|
VPSRLQ $0x03, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 320(AX)
|
||||||
|
VMOVDQA Y6, 512(AX)
|
||||||
|
VMOVDQA Y7, 704(AX)
|
||||||
|
VMOVDQA Y8, 96(AX)
|
||||||
|
VMOVDQA Y9, 288(AX)
|
||||||
|
VPXOR 32(AX), Y11, Y0
|
||||||
|
VPXOR 224(AX), Y12, Y1
|
||||||
|
VPXOR 416(AX), Y13, Y2
|
||||||
|
VPXOR 608(AX), Y14, Y3
|
||||||
|
VPXOR 640(AX), Y10, Y4
|
||||||
|
VPSLLQ $0x01, Y0, Y5
|
||||||
|
VPSLLQ $0x06, Y1, Y6
|
||||||
|
VPSLLQ $0x19, Y2, Y7
|
||||||
|
VPSLLQ $0x08, Y3, Y8
|
||||||
|
VPSLLQ $0x12, Y4, Y9
|
||||||
|
VPSRLQ $0x3f, Y0, Y0
|
||||||
|
VPSRLQ $0x3a, Y1, Y1
|
||||||
|
VPSRLQ $0x27, Y2, Y2
|
||||||
|
VPSRLQ $0x38, Y3, Y3
|
||||||
|
VPSRLQ $0x2e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 640(AX)
|
||||||
|
VMOVDQA Y6, 32(AX)
|
||||||
|
VMOVDQA Y7, 224(AX)
|
||||||
|
VMOVDQA Y8, 416(AX)
|
||||||
|
VMOVDQA Y9, 608(AX)
|
||||||
|
VPXOR 128(AX), Y14, Y0
|
||||||
|
VPXOR 160(AX), Y10, Y1
|
||||||
|
VPXOR 352(AX), Y11, Y2
|
||||||
|
VPXOR 544(AX), Y12, Y3
|
||||||
|
VPXOR 736(AX), Y13, Y4
|
||||||
|
VPSLLQ $0x1b, Y0, Y5
|
||||||
|
VPSLLQ $0x24, Y1, Y6
|
||||||
|
VPSLLQ $0x0a, Y2, Y7
|
||||||
|
VPSLLQ $0x0f, Y3, Y8
|
||||||
|
VPSLLQ $0x38, Y4, Y9
|
||||||
|
VPSRLQ $0x25, Y0, Y0
|
||||||
|
VPSRLQ $0x1c, Y1, Y1
|
||||||
|
VPSRLQ $0x36, Y2, Y2
|
||||||
|
VPSRLQ $0x31, Y3, Y3
|
||||||
|
VPSRLQ $0x08, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 160(AX)
|
||||||
|
VMOVDQA Y6, 352(AX)
|
||||||
|
VMOVDQA Y7, 544(AX)
|
||||||
|
VMOVDQA Y8, 736(AX)
|
||||||
|
VMOVDQA Y9, 128(AX)
|
||||||
|
VPXOR 64(AX), Y12, Y0
|
||||||
|
VPXOR 256(AX), Y13, Y1
|
||||||
|
VPXOR 448(AX), Y14, Y2
|
||||||
|
VPXOR 480(AX), Y10, Y3
|
||||||
|
VPXOR 672(AX), Y11, Y4
|
||||||
|
VPSLLQ $0x3e, Y0, Y5
|
||||||
|
VPSLLQ $0x37, Y1, Y6
|
||||||
|
VPSLLQ $0x27, Y2, Y7
|
||||||
|
VPSLLQ $0x29, Y3, Y8
|
||||||
|
VPSLLQ $0x02, Y4, Y9
|
||||||
|
VPSRLQ $0x02, Y0, Y0
|
||||||
|
VPSRLQ $0x09, Y1, Y1
|
||||||
|
VPSRLQ $0x19, Y2, Y2
|
||||||
|
VPSRLQ $0x17, Y3, Y3
|
||||||
|
VPSRLQ $0x3e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 480(AX)
|
||||||
|
VMOVDQA Y6, 672(AX)
|
||||||
|
VMOVDQA Y7, 64(AX)
|
||||||
|
VMOVDQA Y8, 256(AX)
|
||||||
|
VMOVDQA Y9, 448(AX)
|
||||||
|
VMOVDQA (AX), Y0
|
||||||
|
VMOVDQA 32(AX), Y1
|
||||||
|
VMOVDQA 64(AX), Y2
|
||||||
|
VMOVDQA 96(AX), Y3
|
||||||
|
VMOVDQA 128(AX), Y4
|
||||||
|
VPXOR 160(AX), Y0, Y0
|
||||||
|
VPXOR 192(AX), Y1, Y1
|
||||||
|
VPXOR 224(AX), Y2, Y2
|
||||||
|
VPXOR 256(AX), Y3, Y3
|
||||||
|
VPXOR 288(AX), Y4, Y4
|
||||||
|
VPXOR 320(AX), Y0, Y0
|
||||||
|
VPXOR 352(AX), Y1, Y1
|
||||||
|
VPXOR 384(AX), Y2, Y2
|
||||||
|
VPXOR 416(AX), Y3, Y3
|
||||||
|
VPXOR 448(AX), Y4, Y4
|
||||||
|
VPXOR 480(AX), Y0, Y0
|
||||||
|
VPXOR 512(AX), Y1, Y1
|
||||||
|
VPXOR 544(AX), Y2, Y2
|
||||||
|
VPXOR 576(AX), Y3, Y3
|
||||||
|
VPXOR 608(AX), Y4, Y4
|
||||||
|
VPXOR 640(AX), Y0, Y0
|
||||||
|
VPXOR 672(AX), Y1, Y1
|
||||||
|
VPXOR 704(AX), Y2, Y2
|
||||||
|
VPXOR 736(AX), Y3, Y3
|
||||||
|
VPXOR 768(AX), Y4, Y4
|
||||||
|
VPSLLQ $0x01, Y1, Y5
|
||||||
|
VPSLLQ $0x01, Y2, Y6
|
||||||
|
VPSLLQ $0x01, Y3, Y7
|
||||||
|
VPSLLQ $0x01, Y4, Y8
|
||||||
|
VPSLLQ $0x01, Y0, Y9
|
||||||
|
VPSRLQ $0x3f, Y1, Y10
|
||||||
|
VPSRLQ $0x3f, Y2, Y11
|
||||||
|
VPSRLQ $0x3f, Y3, Y12
|
||||||
|
VPSRLQ $0x3f, Y4, Y13
|
||||||
|
VPSRLQ $0x3f, Y0, Y14
|
||||||
|
VPOR Y5, Y10, Y10
|
||||||
|
VPOR Y6, Y11, Y11
|
||||||
|
VPOR Y7, Y12, Y12
|
||||||
|
VPOR Y8, Y13, Y13
|
||||||
|
VPOR Y9, Y14, Y14
|
||||||
|
VPXOR Y10, Y4, Y10
|
||||||
|
VPXOR Y11, Y0, Y11
|
||||||
|
VPXOR Y12, Y1, Y12
|
||||||
|
VPXOR Y13, Y2, Y13
|
||||||
|
VPXOR Y14, Y3, Y14
|
||||||
|
VPXOR (AX), Y10, Y0
|
||||||
|
VPXOR 512(AX), Y11, Y1
|
||||||
|
VPXOR 224(AX), Y12, Y2
|
||||||
|
VPXOR 736(AX), Y13, Y3
|
||||||
|
VPXOR 448(AX), Y14, Y4
|
||||||
|
VPSLLQ $0x2c, Y1, Y6
|
||||||
|
VPSLLQ $0x2b, Y2, Y7
|
||||||
|
VPSLLQ $0x15, Y3, Y8
|
||||||
|
VPSLLQ $0x0e, Y4, Y9
|
||||||
|
VPSRLQ $0x14, Y1, Y1
|
||||||
|
VPSRLQ $0x15, Y2, Y2
|
||||||
|
VPSRLQ $0x2b, Y3, Y3
|
||||||
|
VPSRLQ $0x32, Y4, Y4
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VPBROADCASTQ 8(CX), Y0
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VMOVDQA Y5, (AX)
|
||||||
|
VMOVDQA Y6, 512(AX)
|
||||||
|
VMOVDQA Y7, 224(AX)
|
||||||
|
VMOVDQA Y8, 736(AX)
|
||||||
|
VMOVDQA Y9, 448(AX)
|
||||||
|
VPXOR 576(AX), Y13, Y0
|
||||||
|
VPXOR 288(AX), Y14, Y1
|
||||||
|
VPXOR 640(AX), Y10, Y2
|
||||||
|
VPXOR 352(AX), Y11, Y3
|
||||||
|
VPXOR 64(AX), Y12, Y4
|
||||||
|
VPSLLQ $0x1c, Y0, Y5
|
||||||
|
VPSLLQ $0x14, Y1, Y6
|
||||||
|
VPSLLQ $0x03, Y2, Y7
|
||||||
|
VPSLLQ $0x2d, Y3, Y8
|
||||||
|
VPSLLQ $0x3d, Y4, Y9
|
||||||
|
VPSRLQ $0x24, Y0, Y0
|
||||||
|
VPSRLQ $0x2c, Y1, Y1
|
||||||
|
VPSRLQ $0x3d, Y2, Y2
|
||||||
|
VPSRLQ $0x13, Y3, Y3
|
||||||
|
VPSRLQ $0x03, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 640(AX)
|
||||||
|
VMOVDQA Y6, 352(AX)
|
||||||
|
VMOVDQA Y7, 64(AX)
|
||||||
|
VMOVDQA Y8, 576(AX)
|
||||||
|
VMOVDQA Y9, 288(AX)
|
||||||
|
VPXOR 192(AX), Y11, Y0
|
||||||
|
VPXOR 704(AX), Y12, Y1
|
||||||
|
VPXOR 416(AX), Y13, Y2
|
||||||
|
VPXOR 128(AX), Y14, Y3
|
||||||
|
VPXOR 480(AX), Y10, Y4
|
||||||
|
VPSLLQ $0x01, Y0, Y5
|
||||||
|
VPSLLQ $0x06, Y1, Y6
|
||||||
|
VPSLLQ $0x19, Y2, Y7
|
||||||
|
VPSLLQ $0x08, Y3, Y8
|
||||||
|
VPSLLQ $0x12, Y4, Y9
|
||||||
|
VPSRLQ $0x3f, Y0, Y0
|
||||||
|
VPSRLQ $0x3a, Y1, Y1
|
||||||
|
VPSRLQ $0x27, Y2, Y2
|
||||||
|
VPSRLQ $0x38, Y3, Y3
|
||||||
|
VPSRLQ $0x2e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 480(AX)
|
||||||
|
VMOVDQA Y6, 192(AX)
|
||||||
|
VMOVDQA Y7, 704(AX)
|
||||||
|
VMOVDQA Y8, 416(AX)
|
||||||
|
VMOVDQA Y9, 128(AX)
|
||||||
|
VPXOR 768(AX), Y14, Y0
|
||||||
|
VPXOR 320(AX), Y10, Y1
|
||||||
|
VPXOR 32(AX), Y11, Y2
|
||||||
|
VPXOR 544(AX), Y12, Y3
|
||||||
|
VPXOR 256(AX), Y13, Y4
|
||||||
|
VPSLLQ $0x1b, Y0, Y5
|
||||||
|
VPSLLQ $0x24, Y1, Y6
|
||||||
|
VPSLLQ $0x0a, Y2, Y7
|
||||||
|
VPSLLQ $0x0f, Y3, Y8
|
||||||
|
VPSLLQ $0x38, Y4, Y9
|
||||||
|
VPSRLQ $0x25, Y0, Y0
|
||||||
|
VPSRLQ $0x1c, Y1, Y1
|
||||||
|
VPSRLQ $0x36, Y2, Y2
|
||||||
|
VPSRLQ $0x31, Y3, Y3
|
||||||
|
VPSRLQ $0x08, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 320(AX)
|
||||||
|
VMOVDQA Y6, 32(AX)
|
||||||
|
VMOVDQA Y7, 544(AX)
|
||||||
|
VMOVDQA Y8, 256(AX)
|
||||||
|
VMOVDQA Y9, 768(AX)
|
||||||
|
VPXOR 384(AX), Y12, Y0
|
||||||
|
VPXOR 96(AX), Y13, Y1
|
||||||
|
VPXOR 608(AX), Y14, Y2
|
||||||
|
VPXOR 160(AX), Y10, Y3
|
||||||
|
VPXOR 672(AX), Y11, Y4
|
||||||
|
VPSLLQ $0x3e, Y0, Y5
|
||||||
|
VPSLLQ $0x37, Y1, Y6
|
||||||
|
VPSLLQ $0x27, Y2, Y7
|
||||||
|
VPSLLQ $0x29, Y3, Y8
|
||||||
|
VPSLLQ $0x02, Y4, Y9
|
||||||
|
VPSRLQ $0x02, Y0, Y0
|
||||||
|
VPSRLQ $0x09, Y1, Y1
|
||||||
|
VPSRLQ $0x19, Y2, Y2
|
||||||
|
VPSRLQ $0x17, Y3, Y3
|
||||||
|
VPSRLQ $0x3e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 160(AX)
|
||||||
|
VMOVDQA Y6, 672(AX)
|
||||||
|
VMOVDQA Y7, 384(AX)
|
||||||
|
VMOVDQA Y8, 96(AX)
|
||||||
|
VMOVDQA Y9, 608(AX)
|
||||||
|
VMOVDQA (AX), Y0
|
||||||
|
VMOVDQA 32(AX), Y1
|
||||||
|
VMOVDQA 64(AX), Y2
|
||||||
|
VMOVDQA 96(AX), Y3
|
||||||
|
VMOVDQA 128(AX), Y4
|
||||||
|
VPXOR 160(AX), Y0, Y0
|
||||||
|
VPXOR 192(AX), Y1, Y1
|
||||||
|
VPXOR 224(AX), Y2, Y2
|
||||||
|
VPXOR 256(AX), Y3, Y3
|
||||||
|
VPXOR 288(AX), Y4, Y4
|
||||||
|
VPXOR 320(AX), Y0, Y0
|
||||||
|
VPXOR 352(AX), Y1, Y1
|
||||||
|
VPXOR 384(AX), Y2, Y2
|
||||||
|
VPXOR 416(AX), Y3, Y3
|
||||||
|
VPXOR 448(AX), Y4, Y4
|
||||||
|
VPXOR 480(AX), Y0, Y0
|
||||||
|
VPXOR 512(AX), Y1, Y1
|
||||||
|
VPXOR 544(AX), Y2, Y2
|
||||||
|
VPXOR 576(AX), Y3, Y3
|
||||||
|
VPXOR 608(AX), Y4, Y4
|
||||||
|
VPXOR 640(AX), Y0, Y0
|
||||||
|
VPXOR 672(AX), Y1, Y1
|
||||||
|
VPXOR 704(AX), Y2, Y2
|
||||||
|
VPXOR 736(AX), Y3, Y3
|
||||||
|
VPXOR 768(AX), Y4, Y4
|
||||||
|
VPSLLQ $0x01, Y1, Y5
|
||||||
|
VPSLLQ $0x01, Y2, Y6
|
||||||
|
VPSLLQ $0x01, Y3, Y7
|
||||||
|
VPSLLQ $0x01, Y4, Y8
|
||||||
|
VPSLLQ $0x01, Y0, Y9
|
||||||
|
VPSRLQ $0x3f, Y1, Y10
|
||||||
|
VPSRLQ $0x3f, Y2, Y11
|
||||||
|
VPSRLQ $0x3f, Y3, Y12
|
||||||
|
VPSRLQ $0x3f, Y4, Y13
|
||||||
|
VPSRLQ $0x3f, Y0, Y14
|
||||||
|
VPOR Y5, Y10, Y10
|
||||||
|
VPOR Y6, Y11, Y11
|
||||||
|
VPOR Y7, Y12, Y12
|
||||||
|
VPOR Y8, Y13, Y13
|
||||||
|
VPOR Y9, Y14, Y14
|
||||||
|
VPXOR Y10, Y4, Y10
|
||||||
|
VPXOR Y11, Y0, Y11
|
||||||
|
VPXOR Y12, Y1, Y12
|
||||||
|
VPXOR Y13, Y2, Y13
|
||||||
|
VPXOR Y14, Y3, Y14
|
||||||
|
VPXOR (AX), Y10, Y0
|
||||||
|
VPXOR 352(AX), Y11, Y1
|
||||||
|
VPXOR 704(AX), Y12, Y2
|
||||||
|
VPXOR 256(AX), Y13, Y3
|
||||||
|
VPXOR 608(AX), Y14, Y4
|
||||||
|
VPSLLQ $0x2c, Y1, Y6
|
||||||
|
VPSLLQ $0x2b, Y2, Y7
|
||||||
|
VPSLLQ $0x15, Y3, Y8
|
||||||
|
VPSLLQ $0x0e, Y4, Y9
|
||||||
|
VPSRLQ $0x14, Y1, Y1
|
||||||
|
VPSRLQ $0x15, Y2, Y2
|
||||||
|
VPSRLQ $0x2b, Y3, Y3
|
||||||
|
VPSRLQ $0x32, Y4, Y4
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VPBROADCASTQ 16(CX), Y0
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VMOVDQA Y5, (AX)
|
||||||
|
VMOVDQA Y6, 352(AX)
|
||||||
|
VMOVDQA Y7, 704(AX)
|
||||||
|
VMOVDQA Y8, 256(AX)
|
||||||
|
VMOVDQA Y9, 608(AX)
|
||||||
|
VPXOR 736(AX), Y13, Y0
|
||||||
|
VPXOR 288(AX), Y14, Y1
|
||||||
|
VPXOR 480(AX), Y10, Y2
|
||||||
|
VPXOR 32(AX), Y11, Y3
|
||||||
|
VPXOR 384(AX), Y12, Y4
|
||||||
|
VPSLLQ $0x1c, Y0, Y5
|
||||||
|
VPSLLQ $0x14, Y1, Y6
|
||||||
|
VPSLLQ $0x03, Y2, Y7
|
||||||
|
VPSLLQ $0x2d, Y3, Y8
|
||||||
|
VPSLLQ $0x3d, Y4, Y9
|
||||||
|
VPSRLQ $0x24, Y0, Y0
|
||||||
|
VPSRLQ $0x2c, Y1, Y1
|
||||||
|
VPSRLQ $0x3d, Y2, Y2
|
||||||
|
VPSRLQ $0x13, Y3, Y3
|
||||||
|
VPSRLQ $0x03, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 480(AX)
|
||||||
|
VMOVDQA Y6, 32(AX)
|
||||||
|
VMOVDQA Y7, 384(AX)
|
||||||
|
VMOVDQA Y8, 736(AX)
|
||||||
|
VMOVDQA Y9, 288(AX)
|
||||||
|
VPXOR 512(AX), Y11, Y0
|
||||||
|
VPXOR 64(AX), Y12, Y1
|
||||||
|
VPXOR 416(AX), Y13, Y2
|
||||||
|
VPXOR 768(AX), Y14, Y3
|
||||||
|
VPXOR 160(AX), Y10, Y4
|
||||||
|
VPSLLQ $0x01, Y0, Y5
|
||||||
|
VPSLLQ $0x06, Y1, Y6
|
||||||
|
VPSLLQ $0x19, Y2, Y7
|
||||||
|
VPSLLQ $0x08, Y3, Y8
|
||||||
|
VPSLLQ $0x12, Y4, Y9
|
||||||
|
VPSRLQ $0x3f, Y0, Y0
|
||||||
|
VPSRLQ $0x3a, Y1, Y1
|
||||||
|
VPSRLQ $0x27, Y2, Y2
|
||||||
|
VPSRLQ $0x38, Y3, Y3
|
||||||
|
VPSRLQ $0x2e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 160(AX)
|
||||||
|
VMOVDQA Y6, 512(AX)
|
||||||
|
VMOVDQA Y7, 64(AX)
|
||||||
|
VMOVDQA Y8, 416(AX)
|
||||||
|
VMOVDQA Y9, 768(AX)
|
||||||
|
VPXOR 448(AX), Y14, Y0
|
||||||
|
VPXOR 640(AX), Y10, Y1
|
||||||
|
VPXOR 192(AX), Y11, Y2
|
||||||
|
VPXOR 544(AX), Y12, Y3
|
||||||
|
VPXOR 96(AX), Y13, Y4
|
||||||
|
VPSLLQ $0x1b, Y0, Y5
|
||||||
|
VPSLLQ $0x24, Y1, Y6
|
||||||
|
VPSLLQ $0x0a, Y2, Y7
|
||||||
|
VPSLLQ $0x0f, Y3, Y8
|
||||||
|
VPSLLQ $0x38, Y4, Y9
|
||||||
|
VPSRLQ $0x25, Y0, Y0
|
||||||
|
VPSRLQ $0x1c, Y1, Y1
|
||||||
|
VPSRLQ $0x36, Y2, Y2
|
||||||
|
VPSRLQ $0x31, Y3, Y3
|
||||||
|
VPSRLQ $0x08, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 640(AX)
|
||||||
|
VMOVDQA Y6, 192(AX)
|
||||||
|
VMOVDQA Y7, 544(AX)
|
||||||
|
VMOVDQA Y8, 96(AX)
|
||||||
|
VMOVDQA Y9, 448(AX)
|
||||||
|
VPXOR 224(AX), Y12, Y0
|
||||||
|
VPXOR 576(AX), Y13, Y1
|
||||||
|
VPXOR 128(AX), Y14, Y2
|
||||||
|
VPXOR 320(AX), Y10, Y3
|
||||||
|
VPXOR 672(AX), Y11, Y4
|
||||||
|
VPSLLQ $0x3e, Y0, Y5
|
||||||
|
VPSLLQ $0x37, Y1, Y6
|
||||||
|
VPSLLQ $0x27, Y2, Y7
|
||||||
|
VPSLLQ $0x29, Y3, Y8
|
||||||
|
VPSLLQ $0x02, Y4, Y9
|
||||||
|
VPSRLQ $0x02, Y0, Y0
|
||||||
|
VPSRLQ $0x09, Y1, Y1
|
||||||
|
VPSRLQ $0x19, Y2, Y2
|
||||||
|
VPSRLQ $0x17, Y3, Y3
|
||||||
|
VPSRLQ $0x3e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 320(AX)
|
||||||
|
VMOVDQA Y6, 672(AX)
|
||||||
|
VMOVDQA Y7, 224(AX)
|
||||||
|
VMOVDQA Y8, 576(AX)
|
||||||
|
VMOVDQA Y9, 128(AX)
|
||||||
|
VMOVDQA (AX), Y0
|
||||||
|
VMOVDQA 32(AX), Y1
|
||||||
|
VMOVDQA 64(AX), Y2
|
||||||
|
VMOVDQA 96(AX), Y3
|
||||||
|
VMOVDQA 128(AX), Y4
|
||||||
|
VPXOR 160(AX), Y0, Y0
|
||||||
|
VPXOR 192(AX), Y1, Y1
|
||||||
|
VPXOR 224(AX), Y2, Y2
|
||||||
|
VPXOR 256(AX), Y3, Y3
|
||||||
|
VPXOR 288(AX), Y4, Y4
|
||||||
|
VPXOR 320(AX), Y0, Y0
|
||||||
|
VPXOR 352(AX), Y1, Y1
|
||||||
|
VPXOR 384(AX), Y2, Y2
|
||||||
|
VPXOR 416(AX), Y3, Y3
|
||||||
|
VPXOR 448(AX), Y4, Y4
|
||||||
|
VPXOR 480(AX), Y0, Y0
|
||||||
|
VPXOR 512(AX), Y1, Y1
|
||||||
|
VPXOR 544(AX), Y2, Y2
|
||||||
|
VPXOR 576(AX), Y3, Y3
|
||||||
|
VPXOR 608(AX), Y4, Y4
|
||||||
|
VPXOR 640(AX), Y0, Y0
|
||||||
|
VPXOR 672(AX), Y1, Y1
|
||||||
|
VPXOR 704(AX), Y2, Y2
|
||||||
|
VPXOR 736(AX), Y3, Y3
|
||||||
|
VPXOR 768(AX), Y4, Y4
|
||||||
|
VPSLLQ $0x01, Y1, Y5
|
||||||
|
VPSLLQ $0x01, Y2, Y6
|
||||||
|
VPSLLQ $0x01, Y3, Y7
|
||||||
|
VPSLLQ $0x01, Y4, Y8
|
||||||
|
VPSLLQ $0x01, Y0, Y9
|
||||||
|
VPSRLQ $0x3f, Y1, Y10
|
||||||
|
VPSRLQ $0x3f, Y2, Y11
|
||||||
|
VPSRLQ $0x3f, Y3, Y12
|
||||||
|
VPSRLQ $0x3f, Y4, Y13
|
||||||
|
VPSRLQ $0x3f, Y0, Y14
|
||||||
|
VPOR Y5, Y10, Y10
|
||||||
|
VPOR Y6, Y11, Y11
|
||||||
|
VPOR Y7, Y12, Y12
|
||||||
|
VPOR Y8, Y13, Y13
|
||||||
|
VPOR Y9, Y14, Y14
|
||||||
|
VPXOR Y10, Y4, Y10
|
||||||
|
VPXOR Y11, Y0, Y11
|
||||||
|
VPXOR Y12, Y1, Y12
|
||||||
|
VPXOR Y13, Y2, Y13
|
||||||
|
VPXOR Y14, Y3, Y14
|
||||||
|
VPXOR (AX), Y10, Y0
|
||||||
|
VPXOR 32(AX), Y11, Y1
|
||||||
|
VPXOR 64(AX), Y12, Y2
|
||||||
|
VPXOR 96(AX), Y13, Y3
|
||||||
|
VPXOR 128(AX), Y14, Y4
|
||||||
|
VPSLLQ $0x2c, Y1, Y6
|
||||||
|
VPSLLQ $0x2b, Y2, Y7
|
||||||
|
VPSLLQ $0x15, Y3, Y8
|
||||||
|
VPSLLQ $0x0e, Y4, Y9
|
||||||
|
VPSRLQ $0x14, Y1, Y1
|
||||||
|
VPSRLQ $0x15, Y2, Y2
|
||||||
|
VPSRLQ $0x2b, Y3, Y3
|
||||||
|
VPSRLQ $0x32, Y4, Y4
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VPBROADCASTQ 24(CX), Y0
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VMOVDQA Y5, (AX)
|
||||||
|
VMOVDQA Y6, 32(AX)
|
||||||
|
VMOVDQA Y7, 64(AX)
|
||||||
|
VMOVDQA Y8, 96(AX)
|
||||||
|
VMOVDQA Y9, 128(AX)
|
||||||
|
VPXOR 256(AX), Y13, Y0
|
||||||
|
VPXOR 288(AX), Y14, Y1
|
||||||
|
VPXOR 160(AX), Y10, Y2
|
||||||
|
VPXOR 192(AX), Y11, Y3
|
||||||
|
VPXOR 224(AX), Y12, Y4
|
||||||
|
VPSLLQ $0x1c, Y0, Y5
|
||||||
|
VPSLLQ $0x14, Y1, Y6
|
||||||
|
VPSLLQ $0x03, Y2, Y7
|
||||||
|
VPSLLQ $0x2d, Y3, Y8
|
||||||
|
VPSLLQ $0x3d, Y4, Y9
|
||||||
|
VPSRLQ $0x24, Y0, Y0
|
||||||
|
VPSRLQ $0x2c, Y1, Y1
|
||||||
|
VPSRLQ $0x3d, Y2, Y2
|
||||||
|
VPSRLQ $0x13, Y3, Y3
|
||||||
|
VPSRLQ $0x03, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 160(AX)
|
||||||
|
VMOVDQA Y6, 192(AX)
|
||||||
|
VMOVDQA Y7, 224(AX)
|
||||||
|
VMOVDQA Y8, 256(AX)
|
||||||
|
VMOVDQA Y9, 288(AX)
|
||||||
|
VPXOR 352(AX), Y11, Y0
|
||||||
|
VPXOR 384(AX), Y12, Y1
|
||||||
|
VPXOR 416(AX), Y13, Y2
|
||||||
|
VPXOR 448(AX), Y14, Y3
|
||||||
|
VPXOR 320(AX), Y10, Y4
|
||||||
|
VPSLLQ $0x01, Y0, Y5
|
||||||
|
VPSLLQ $0x06, Y1, Y6
|
||||||
|
VPSLLQ $0x19, Y2, Y7
|
||||||
|
VPSLLQ $0x08, Y3, Y8
|
||||||
|
VPSLLQ $0x12, Y4, Y9
|
||||||
|
VPSRLQ $0x3f, Y0, Y0
|
||||||
|
VPSRLQ $0x3a, Y1, Y1
|
||||||
|
VPSRLQ $0x27, Y2, Y2
|
||||||
|
VPSRLQ $0x38, Y3, Y3
|
||||||
|
VPSRLQ $0x2e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 320(AX)
|
||||||
|
VMOVDQA Y6, 352(AX)
|
||||||
|
VMOVDQA Y7, 384(AX)
|
||||||
|
VMOVDQA Y8, 416(AX)
|
||||||
|
VMOVDQA Y9, 448(AX)
|
||||||
|
VPXOR 608(AX), Y14, Y0
|
||||||
|
VPXOR 480(AX), Y10, Y1
|
||||||
|
VPXOR 512(AX), Y11, Y2
|
||||||
|
VPXOR 544(AX), Y12, Y3
|
||||||
|
VPXOR 576(AX), Y13, Y4
|
||||||
|
VPSLLQ $0x1b, Y0, Y5
|
||||||
|
VPSLLQ $0x24, Y1, Y6
|
||||||
|
VPSLLQ $0x0a, Y2, Y7
|
||||||
|
VPSLLQ $0x0f, Y3, Y8
|
||||||
|
VPSLLQ $0x38, Y4, Y9
|
||||||
|
VPSRLQ $0x25, Y0, Y0
|
||||||
|
VPSRLQ $0x1c, Y1, Y1
|
||||||
|
VPSRLQ $0x36, Y2, Y2
|
||||||
|
VPSRLQ $0x31, Y3, Y3
|
||||||
|
VPSRLQ $0x08, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 480(AX)
|
||||||
|
VMOVDQA Y6, 512(AX)
|
||||||
|
VMOVDQA Y7, 544(AX)
|
||||||
|
VMOVDQA Y8, 576(AX)
|
||||||
|
VMOVDQA Y9, 608(AX)
|
||||||
|
VPXOR 704(AX), Y12, Y0
|
||||||
|
VPXOR 736(AX), Y13, Y1
|
||||||
|
VPXOR 768(AX), Y14, Y2
|
||||||
|
VPXOR 640(AX), Y10, Y3
|
||||||
|
VPXOR 672(AX), Y11, Y4
|
||||||
|
VPSLLQ $0x3e, Y0, Y5
|
||||||
|
VPSLLQ $0x37, Y1, Y6
|
||||||
|
VPSLLQ $0x27, Y2, Y7
|
||||||
|
VPSLLQ $0x29, Y3, Y8
|
||||||
|
VPSLLQ $0x02, Y4, Y9
|
||||||
|
VPSRLQ $0x02, Y0, Y0
|
||||||
|
VPSRLQ $0x09, Y1, Y1
|
||||||
|
VPSRLQ $0x19, Y2, Y2
|
||||||
|
VPSRLQ $0x17, Y3, Y3
|
||||||
|
VPSRLQ $0x3e, Y4, Y4
|
||||||
|
VPOR Y5, Y0, Y0
|
||||||
|
VPOR Y6, Y1, Y1
|
||||||
|
VPOR Y7, Y2, Y2
|
||||||
|
VPOR Y8, Y3, Y3
|
||||||
|
VPOR Y9, Y4, Y4
|
||||||
|
VPANDN Y2, Y1, Y5
|
||||||
|
VPANDN Y3, Y2, Y6
|
||||||
|
VPANDN Y4, Y3, Y7
|
||||||
|
VPANDN Y0, Y4, Y8
|
||||||
|
VPANDN Y1, Y0, Y9
|
||||||
|
VPXOR Y0, Y5, Y5
|
||||||
|
VPXOR Y1, Y6, Y6
|
||||||
|
VPXOR Y2, Y7, Y7
|
||||||
|
VPXOR Y3, Y8, Y8
|
||||||
|
VPXOR Y4, Y9, Y9
|
||||||
|
VMOVDQA Y5, 640(AX)
|
||||||
|
VMOVDQA Y6, 672(AX)
|
||||||
|
VMOVDQA Y7, 704(AX)
|
||||||
|
VMOVDQA Y8, 736(AX)
|
||||||
|
VMOVDQA Y9, 768(AX)
|
||||||
|
ADDQ $0x20, CX
|
||||||
|
SUBQ $0x00000001, DX
|
||||||
|
JNZ loop
|
||||||
|
RET
|
9
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go
generated
vendored
Normal file
9
vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package keccakf1600
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func f1600x4AVX2(state *uint64, rc *[24]uint64)
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build (!amd64 && !arm64) || (arm64 && !go1.16)
|
||||||
|
// +build !amd64,!arm64 arm64,!go1.16
|
||||||
|
|
||||||
|
package keccakf1600
|
||||||
|
|
||||||
|
func permuteSIMDx2(state []uint64) { permuteScalarX2(state) }
|
||||||
|
|
||||||
|
func permuteSIMDx4(state []uint64) { permuteScalarX4(state) }
|
|
@ -0,0 +1,170 @@
|
||||||
|
// Copyright 2022 Cloudflare, Inc. All rights reserved. Use of this source code
|
||||||
|
// is governed by a BSD-style license that can be found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// Glue to add Circl's (post-quantum) hybrid KEMs.
|
||||||
|
//
|
||||||
|
// To enable set CurvePreferences with the desired scheme as the first element:
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "github.com/cloudflare/circl/kem/tls"
|
||||||
|
// "github.com/cloudflare/circl/kem/hybrid"
|
||||||
|
//
|
||||||
|
// [...]
|
||||||
|
//
|
||||||
|
// config.CurvePreferences = []tls.CurveID{
|
||||||
|
// qtls.X25519Kyber512Draft00,
|
||||||
|
// qtls.X25519,
|
||||||
|
// qtls.P256,
|
||||||
|
// }
|
||||||
|
|
||||||
|
package qtls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
"github.com/cloudflare/circl/kem/hybrid"
|
||||||
|
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Either ecdheParameters or kem.PrivateKey
|
||||||
|
type clientKeySharePrivate interface{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
X25519Kyber512Draft00 = CurveID(0xfe30)
|
||||||
|
X25519Kyber768Draft00 = CurveID(0xfe31)
|
||||||
|
invalidCurveID = CurveID(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
func kemSchemeKeyToCurveID(s kem.Scheme) CurveID {
|
||||||
|
switch s.Name() {
|
||||||
|
case "Kyber512-X25519":
|
||||||
|
return X25519Kyber512Draft00
|
||||||
|
case "Kyber768-X25519":
|
||||||
|
return X25519Kyber768Draft00
|
||||||
|
default:
|
||||||
|
return invalidCurveID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract CurveID from clientKeySharePrivate
|
||||||
|
func clientKeySharePrivateCurveID(ks clientKeySharePrivate) CurveID {
|
||||||
|
switch v := ks.(type) {
|
||||||
|
case kem.PrivateKey:
|
||||||
|
ret := kemSchemeKeyToCurveID(v.Scheme())
|
||||||
|
if ret == invalidCurveID {
|
||||||
|
panic("cfkem: internal error: don't know CurveID for this KEM")
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
case ecdheParameters:
|
||||||
|
return v.CurveID()
|
||||||
|
default:
|
||||||
|
panic("cfkem: internal error: unknown clientKeySharePrivate")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns scheme by CurveID if supported by Circl
|
||||||
|
func curveIdToCirclScheme(id CurveID) kem.Scheme {
|
||||||
|
switch id {
|
||||||
|
case X25519Kyber512Draft00:
|
||||||
|
return hybrid.Kyber512X25519()
|
||||||
|
case X25519Kyber768Draft00:
|
||||||
|
return hybrid.Kyber768X25519()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a new shared secret and encapsulates it for the packed
|
||||||
|
// public key in ppk using randomness from rnd.
|
||||||
|
func encapsulateForKem(scheme kem.Scheme, rnd io.Reader, ppk []byte) (
|
||||||
|
ct, ss []byte, alert alert, err error) {
|
||||||
|
pk, err := scheme.UnmarshalBinaryPublicKey(ppk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, alertIllegalParameter, fmt.Errorf("unpack pk: %w", err)
|
||||||
|
}
|
||||||
|
seed := make([]byte, scheme.EncapsulationSeedSize())
|
||||||
|
if _, err := io.ReadFull(rnd, seed); err != nil {
|
||||||
|
return nil, nil, alertInternalError, fmt.Errorf("random: %w", err)
|
||||||
|
}
|
||||||
|
ct, ss, err = scheme.EncapsulateDeterministically(pk, seed)
|
||||||
|
return ct, ss, alertIllegalParameter, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a new keypair using randomness from rnd.
|
||||||
|
func generateKemKeyPair(scheme kem.Scheme, rnd io.Reader) (
|
||||||
|
kem.PublicKey, kem.PrivateKey, error) {
|
||||||
|
seed := make([]byte, scheme.SeedSize())
|
||||||
|
if _, err := io.ReadFull(rnd, seed); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pk, sk := scheme.DeriveKeyPair(seed)
|
||||||
|
return pk, sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events. We cannot use the same approach as used in our plain Go fork
|
||||||
|
// as we cannot change tls.Config, tls.ConnectionState, etc. Also we do
|
||||||
|
// not want to maintain a fork of quic-go itself as well. This seems
|
||||||
|
// the simplest option.
|
||||||
|
|
||||||
|
// CFEvent. There are two events: one emitted on HRR and one emitted
|
||||||
|
type CFEvent interface {
|
||||||
|
// Common to all events
|
||||||
|
ServerSide() bool // true if server-side; false if on client-side
|
||||||
|
|
||||||
|
// HRR event. Emitted when an HRR happened.
|
||||||
|
IsHRR() bool // true if this is an HRR event
|
||||||
|
|
||||||
|
// Handshake event.
|
||||||
|
IsHandshake() bool // true if this is a handshake event.
|
||||||
|
Duration() time.Duration // how long did the handshake take?
|
||||||
|
KEX() tls.CurveID // which kex was established?
|
||||||
|
}
|
||||||
|
|
||||||
|
type CFEventHandler func(CFEvent)
|
||||||
|
|
||||||
|
// Registers a handler to be called when a CFEvent is emitted; returns
|
||||||
|
// the previous handler.
|
||||||
|
func SetCFEventHandler(handler CFEventHandler) CFEventHandler {
|
||||||
|
cfEventMux.Lock()
|
||||||
|
ret := cfEventHandler
|
||||||
|
cfEventHandler = handler
|
||||||
|
cfEventMux.Unlock()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func raiseCFEvent(ev CFEvent) {
|
||||||
|
cfEventMux.Lock()
|
||||||
|
handler := cfEventHandler
|
||||||
|
cfEventMux.Unlock()
|
||||||
|
if handler != nil {
|
||||||
|
handler(ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfEventMux sync.Mutex
|
||||||
|
cfEventHandler CFEventHandler
|
||||||
|
)
|
||||||
|
|
||||||
|
type cfEventHRR struct{ serverSide bool }
|
||||||
|
|
||||||
|
func (*cfEventHRR) IsHRR() bool { return true }
|
||||||
|
func (ev *cfEventHRR) ServerSide() bool { return ev.serverSide }
|
||||||
|
func (*cfEventHRR) IsHandshake() bool { return false }
|
||||||
|
func (ev *cfEventHRR) Duration() time.Duration { panic("wrong event") }
|
||||||
|
func (ev *cfEventHRR) KEX() tls.CurveID { panic("wrong event") }
|
||||||
|
|
||||||
|
type cfEventHandshake struct {
|
||||||
|
serverSide bool
|
||||||
|
duration time.Duration
|
||||||
|
kex tls.CurveID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*cfEventHandshake) IsHRR() bool { return false }
|
||||||
|
func (ev *cfEventHandshake) ServerSide() bool { return ev.serverSide }
|
||||||
|
func (*cfEventHandshake) IsHandshake() bool { return true }
|
||||||
|
func (ev *cfEventHandshake) Duration() time.Duration { return ev.duration }
|
||||||
|
func (ev *cfEventHandshake) KEX() tls.CurveID { return ev.kex }
|
|
@ -345,6 +345,7 @@ type clientSessionState struct {
|
||||||
// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
|
// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
|
||||||
// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
|
// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
|
||||||
// are supported via this interface.
|
// are supported via this interface.
|
||||||
|
//
|
||||||
//go:generate sh -c "mockgen -package qtls -destination mock_client_session_cache_test.go github.com/marten-seemann/qtls-go1-17 ClientSessionCache"
|
//go:generate sh -c "mockgen -package qtls -destination mock_client_session_cache_test.go github.com/marten-seemann/qtls-go1-17 ClientSessionCache"
|
||||||
type ClientSessionCache = tls.ClientSessionCache
|
type ClientSessionCache = tls.ClientSessionCache
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ type clientHandshakeState struct {
|
||||||
session *clientSessionState
|
session *clientSessionState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
|
func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error) {
|
||||||
config := c.config
|
config := c.config
|
||||||
if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
|
if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
|
||||||
return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
|
return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
|
||||||
|
@ -137,7 +137,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
|
||||||
hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
|
hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
|
||||||
}
|
}
|
||||||
|
|
||||||
var params ecdheParameters
|
var secret clientKeySharePrivate
|
||||||
if hello.supportedVersions[0] == VersionTLS13 {
|
if hello.supportedVersions[0] == VersionTLS13 {
|
||||||
var suites []uint16
|
var suites []uint16
|
||||||
for _, suiteID := range configCipherSuites {
|
for _, suiteID := range configCipherSuites {
|
||||||
|
@ -158,21 +158,37 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
curveID := config.curvePreferences()[0]
|
curveID := config.curvePreferences()[0]
|
||||||
|
if scheme := curveIdToCirclScheme(curveID); scheme != nil {
|
||||||
|
pk, sk, err := generateKemKeyPair(scheme, config.rand())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("generateKemKeyPair %s: %w",
|
||||||
|
scheme.Name(), err)
|
||||||
|
}
|
||||||
|
packedPk, err := pk.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("pack circl public key %s: %w",
|
||||||
|
scheme.Name(), err)
|
||||||
|
}
|
||||||
|
hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
|
||||||
|
secret = sk
|
||||||
|
} else {
|
||||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||||
return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
|
return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
|
||||||
}
|
}
|
||||||
params, err = generateECDHEParameters(config.rand(), curveID)
|
params, err := generateECDHEParameters(config.rand(), curveID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
||||||
|
secret = params
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil {
|
if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil {
|
||||||
hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello)
|
hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hello, params, nil
|
return hello, secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||||
|
@ -262,7 +278,7 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
serverHello: serverHello,
|
serverHello: serverHello,
|
||||||
hello: hello,
|
hello: hello,
|
||||||
ecdheParams: ecdheParams,
|
keySharePrivate: ecdheParams,
|
||||||
session: session,
|
session: session,
|
||||||
earlySecret: earlySecret,
|
earlySecret: earlySecret,
|
||||||
binderKey: binderKey,
|
binderKey: binderKey,
|
||||||
|
|
|
@ -12,10 +12,12 @@ import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
circlKem "github.com/cloudflare/circl/kem"
|
||||||
"golang.org/x/crypto/cryptobyte"
|
"golang.org/x/crypto/cryptobyte"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +26,8 @@ type clientHandshakeStateTLS13 struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
serverHello *serverHelloMsg
|
serverHello *serverHelloMsg
|
||||||
hello *clientHelloMsg
|
hello *clientHelloMsg
|
||||||
ecdheParams ecdheParameters
|
|
||||||
|
keySharePrivate clientKeySharePrivate
|
||||||
|
|
||||||
session *clientSessionState
|
session *clientSessionState
|
||||||
earlySecret []byte
|
earlySecret []byte
|
||||||
|
@ -44,6 +47,8 @@ type clientHandshakeStateTLS13 struct {
|
||||||
func (hs *clientHandshakeStateTLS13) handshake() error {
|
func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
|
// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
|
||||||
// sections 4.1.2 and 4.1.3.
|
// sections 4.1.2 and 4.1.3.
|
||||||
if c.handshakes > 0 {
|
if c.handshakes > 0 {
|
||||||
|
@ -52,7 +57,7 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consistency check on the presence of a keyShare and its parameters.
|
// Consistency check on the presence of a keyShare and its parameters.
|
||||||
if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 {
|
if hs.keySharePrivate == nil || len(hs.hello.keyShares) != 1 {
|
||||||
return c.sendAlert(alertInternalError)
|
return c.sendAlert(alertInternalError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +108,12 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raiseCFEvent(&cfEventHandshake{
|
||||||
|
serverSide: false,
|
||||||
|
duration: time.Since(startTime),
|
||||||
|
kex: hs.serverHello.serverShare.group,
|
||||||
|
})
|
||||||
|
|
||||||
atomic.StoreUint32(&c.handshakeStatus, 1)
|
atomic.StoreUint32(&c.handshakeStatus, 1)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -180,6 +191,8 @@ func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||||
func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
|
raiseCFEvent(&cfEventHRR{serverSide: false})
|
||||||
|
|
||||||
// The first ClientHello gets double-hashed into the transcript upon a
|
// The first ClientHello gets double-hashed into the transcript upon a
|
||||||
// HelloRetryRequest. (The idea is that the server might offload transcript
|
// HelloRetryRequest. (The idea is that the server might offload transcript
|
||||||
// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
|
// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
|
||||||
|
@ -221,10 +234,26 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: server selected unsupported group")
|
return errors.New("tls: server selected unsupported group")
|
||||||
}
|
}
|
||||||
if hs.ecdheParams.CurveID() == curveID {
|
if clientKeySharePrivateCurveID(hs.keySharePrivate) == curveID {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
|
return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
|
||||||
}
|
}
|
||||||
|
if scheme := curveIdToCirclScheme(curveID); scheme != nil {
|
||||||
|
pk, sk, err := generateKemKeyPair(scheme, c.config.rand())
|
||||||
|
if err != nil {
|
||||||
|
c.sendAlert(alertInternalError)
|
||||||
|
return fmt.Errorf("HRR generateKeyPair %s: %w",
|
||||||
|
scheme.Name(), err)
|
||||||
|
}
|
||||||
|
packedPk, err := pk.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
c.sendAlert(alertInternalError)
|
||||||
|
return fmt.Errorf("HRR pack circl public key %s: %w",
|
||||||
|
scheme.Name(), err)
|
||||||
|
}
|
||||||
|
hs.keySharePrivate = sk
|
||||||
|
hs.hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
|
||||||
|
} else {
|
||||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||||
c.sendAlert(alertInternalError)
|
c.sendAlert(alertInternalError)
|
||||||
return errors.New("tls: CurvePreferences includes unsupported curve")
|
return errors.New("tls: CurvePreferences includes unsupported curve")
|
||||||
|
@ -234,9 +263,10 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||||
c.sendAlert(alertInternalError)
|
c.sendAlert(alertInternalError)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
hs.ecdheParams = params
|
hs.keySharePrivate = params
|
||||||
hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hs.hello.raw = nil
|
hs.hello.raw = nil
|
||||||
if len(hs.hello.pskIdentities) > 0 {
|
if len(hs.hello.pskIdentities) > 0 {
|
||||||
|
@ -314,7 +344,7 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: server did not send a key share")
|
return errors.New("tls: server did not send a key share")
|
||||||
}
|
}
|
||||||
if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
|
if hs.serverHello.serverShare.group != clientKeySharePrivateCurveID(hs.keySharePrivate) {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: server selected unsupported group")
|
return errors.New("tls: server selected unsupported group")
|
||||||
}
|
}
|
||||||
|
@ -352,7 +382,18 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
|
||||||
func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
|
var sharedKey []byte
|
||||||
|
if params, ok := hs.keySharePrivate.(ecdheParameters); ok {
|
||||||
|
sharedKey = params.SharedKey(hs.serverHello.serverShare.data)
|
||||||
|
} else if sk, ok := hs.keySharePrivate.(circlKem.PrivateKey); ok {
|
||||||
|
var err error
|
||||||
|
sharedKey, err = sk.Scheme().Decapsulate(sk, hs.serverHello.serverShare.data)
|
||||||
|
if err != nil {
|
||||||
|
c.sendAlert(alertIllegalParameter)
|
||||||
|
return fmt.Errorf("%s decaps: %w", sk.Scheme().Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sharedKey == nil {
|
if sharedKey == nil {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: invalid server key share")
|
return errors.New("tls: invalid server key share")
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -46,6 +47,8 @@ type serverHandshakeStateTLS13 struct {
|
||||||
func (hs *serverHandshakeStateTLS13) handshake() error {
|
func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
|
// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
|
||||||
if err := hs.processClientHello(); err != nil {
|
if err := hs.processClientHello(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -79,6 +82,12 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raiseCFEvent(&cfEventHandshake{
|
||||||
|
serverSide: true,
|
||||||
|
duration: time.Since(startTime),
|
||||||
|
kex: hs.hello.serverShare.group,
|
||||||
|
})
|
||||||
|
|
||||||
atomic.StoreUint32(&c.handshakeStatus, 1)
|
atomic.StoreUint32(&c.handshakeStatus, 1)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -206,10 +215,19 @@ GroupSelection:
|
||||||
clientKeyShare = &hs.clientHello.keyShares[0]
|
clientKeyShare = &hs.clientHello.keyShares[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok {
|
if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && curveIdToCirclScheme(selectedGroup) == nil && !ok {
|
||||||
c.sendAlert(alertInternalError)
|
c.sendAlert(alertInternalError)
|
||||||
return errors.New("tls: CurvePreferences includes unsupported curve")
|
return errors.New("tls: CurvePreferences includes unsupported curve")
|
||||||
}
|
}
|
||||||
|
if kem := curveIdToCirclScheme(selectedGroup); kem != nil {
|
||||||
|
ct, ss, alert, err := encapsulateForKem(kem, c.config.rand(), clientKeyShare.data)
|
||||||
|
if err != nil {
|
||||||
|
c.sendAlert(alert)
|
||||||
|
return fmt.Errorf("%s encap: %w", kem.Name(), err)
|
||||||
|
}
|
||||||
|
hs.hello.serverShare = keyShare{group: selectedGroup, data: ct}
|
||||||
|
hs.sharedKey = ss
|
||||||
|
} else {
|
||||||
params, err := generateECDHEParameters(c.config.rand(), selectedGroup)
|
params, err := generateECDHEParameters(c.config.rand(), selectedGroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.sendAlert(alertInternalError)
|
c.sendAlert(alertInternalError)
|
||||||
|
@ -217,6 +235,7 @@ GroupSelection:
|
||||||
}
|
}
|
||||||
hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
|
hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
|
||||||
hs.sharedKey = params.SharedKey(clientKeyShare.data)
|
hs.sharedKey = params.SharedKey(clientKeyShare.data)
|
||||||
|
}
|
||||||
if hs.sharedKey == nil {
|
if hs.sharedKey == nil {
|
||||||
c.sendAlert(alertIllegalParameter)
|
c.sendAlert(alertIllegalParameter)
|
||||||
return errors.New("tls: invalid client key share")
|
return errors.New("tls: invalid client key share")
|
||||||
|
@ -437,6 +456,8 @@ func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||||
func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
|
func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
|
raiseCFEvent(&cfEventHRR{serverSide: true})
|
||||||
|
|
||||||
// The first ClientHello gets double-hashed into the transcript upon a
|
// The first ClientHello gets double-hashed into the transcript upon a
|
||||||
// HelloRetryRequest. See RFC 8446, Section 4.4.1.
|
// HelloRetryRequest. See RFC 8446, Section 4.4.1.
|
||||||
hs.transcript.Write(hs.clientHello.marshal())
|
hs.transcript.Write(hs.clientHello.marshal())
|
||||||
|
|
|
@ -168,7 +168,7 @@ type ecdheKeyAgreement struct {
|
||||||
func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||||
var curveID CurveID
|
var curveID CurveID
|
||||||
for _, c := range clientHello.supportedCurves {
|
for _, c := range clientHello.supportedCurves {
|
||||||
if config.supportsCurve(c) {
|
if config.supportsCurve(c) && curveIdToCirclScheme(c) == nil {
|
||||||
curveID = c
|
curveID = c
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue