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