"log"
"go.stargrave.org/opus/v2"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
func newOpusEnc() *opus.Encoder {
}
func pcmConv(buf []byte, pcm []int16) {
- for i := 0; i < len(pcm); i++ {
+ for i := range len(pcm) {
buf[i*2+0] = byte((uint16(pcm[i]) & 0x00FF) >> 0)
buf[i*2+1] = byte((uint16(pcm[i]) & 0xFF00) >> 8)
}
"sort"
"github.com/jroimartin/gocui"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
var (
import (
"bytes"
+ "crypto/cipher"
+ "crypto/sha3"
"crypto/subtle"
- "encoding/base64"
"encoding/binary"
"flag"
"fmt"
"github.com/aead/chacha20"
"github.com/dchest/siphash"
"github.com/jroimartin/gocui"
- "github.com/katzenpost/noise"
- "go.cypherpunks.su/netstring/v3"
"go.stargrave.org/opus/v2"
- vors "go.stargrave.org/vors/v4/internal"
- "golang.org/x/crypto/blake2b"
+ vors "go.stargrave.org/vors/v5/internal"
+ "go.stargrave.org/vors/v5/pqhs"
+ "golang.org/x/crypto/chacha20poly1305"
)
type Stream struct {
Ctrl = make(chan []byte)
)
-func incr(data []byte) {
- for i := len(data) - 1; i >= 0; i-- {
- data[i]++
- if data[i] != 0 {
- return
- }
- }
- panic("overflow")
-}
-
func muteToggle() (muted bool) {
Muted = !Muted
if Ctrl != nil {
func main() {
srvAddr := flag.String("srv", "vors.home.arpa:"+strconv.Itoa(vors.DefaultPort),
"host:TCP/UDP port to connect to")
- srvPubB64 := flag.String("pub", "", "server's public key, Base64")
+ srvPubPth := flag.String("pub", "", "Path to server's public key")
recCmd := flag.String("rec", "rec "+vors.SoxParams, "rec command")
playCmd := flag.String("play", "play "+vors.SoxParams, "play command")
vadRaw := flag.Uint("vad", 0, "VAD threshold")
var passwdHsh []byte
if *passwd != "" {
- hsh := blake2b.Sum256([]byte(*passwd))
+ hsh := sha3.SumSHAKE128([]byte(*passwd), 32)
passwdHsh = hsh[:]
}
- srvPub, err := base64.RawURLEncoding.DecodeString(*srvPubB64)
+ srvPub, err := os.ReadFile(*srvPubPth)
if err != nil {
log.Fatal(err)
}
}
vors.PreferIPv4 = *prefer4
+ hs, buf, err := pqhs.NewClient(pqhs.KeyDecombine(srvPub))
+ if err != nil {
+ log.Fatalln("pqhs.NewClient:", err)
+ }
+
ctrlConn, err := net.DialTCP("tcp", nil, vors.MustResolveTCP(*srvAddr))
if err != nil {
log.Fatalln("dial server:", err)
if err = ctrlConn.SetNoDelay(true); err != nil {
log.Fatalln("nodelay:", err)
}
- ctrl := vors.NewNSConn(ctrlConn)
-
- hs, err := noise.NewHandshakeState(noise.Config{
- CipherSuite: vors.NoiseCipherSuite,
- Pattern: noise.HandshakeNK,
- Initiator: true,
- PeerStatic: srvPub,
- Prologue: []byte(vors.NoisePrologue),
- })
- if err != nil {
- log.Fatalln("noise.NewHandshakeState:", err)
+
+ ctrl := vors.NewNSConn(ctrlConn, 1<<16)
+ if err = ctrl.Tx([]byte(vors.Magic)); err != nil {
+ log.Fatalln("write handshake magic:", err)
}
- buf, _, _, err := hs.WriteMessage(nil, vors.ArgsEncode(
+ if err = ctrl.Tx(buf); err != nil {
+ log.Fatalln("write handshake hello:", err)
+ }
+ buf = <-ctrl.Rx
+ if buf == nil {
+ log.Fatalln("read handshake hello:", ctrl.Err)
+ }
+ buf, err = hs.Read(buf, vors.ArgsEncode(
[]byte(*Name), []byte(*Room), passwdHsh,
))
if err != nil {
- log.Fatalln("handshake encrypt:", err)
+ log.Fatalln("process handshake:", err)
}
- {
- var w bytes.Buffer
- w.WriteString(vors.NoisePrologue)
- netstring.NewWriter(&w).WriteChunk(buf)
- buf = w.Bytes()
+ if err = ctrl.Tx(buf); err != nil {
+ log.Fatalln("write handshake finish:", err)
}
- _, err = io.Copy(ctrlConn, bytes.NewReader(buf))
+
+ var txKey, rxKey, keyCiphOur, keyMACOur []byte
+ var txAEAD, rxAEAD cipher.AEAD
+ keys := hs.Binding(3*chacha20poly1305.KeySize + vors.SipHash24KeySize)
+ txKey, keys = keys[:chacha20poly1305.KeySize], keys[chacha20poly1305.KeySize:]
+ rxKey, keys = keys[:chacha20poly1305.KeySize], keys[chacha20poly1305.KeySize:]
+ keyCiphOur, keyMACOur = keys[:vors.ChaCha20KeySize], keys[vors.ChaCha20KeySize:]
+ txAEAD, err = chacha20poly1305.New(txKey)
if err != nil {
- log.Fatalln("write handshake:", err)
- return
+ log.Fatal(err)
+ }
+ rxAEAD, err = chacha20poly1305.New(rxKey)
+ if err != nil {
+ log.Fatal(err)
}
+ txNonce := make([]byte, chacha20poly1305.NonceSize)
+ rxNonce := make([]byte, chacha20poly1305.NonceSize)
+
buf = <-ctrl.Rx
if buf == nil {
- log.Fatalln("read handshake:", ctrl.Err)
+ log.Fatalln("read handshake finish:", ctrl.Err)
}
- buf, txCS, rxCS, err := hs.ReadMessage(nil, buf)
+ buf, err = rxAEAD.Open(buf[:0], rxNonce, buf, nil)
if err != nil {
log.Fatalln("handshake decrypt:", err)
}
rx := make(chan []byte)
go func() {
for buf := range ctrl.Rx {
- buf, err = rxCS.Decrypt(buf[:0], nil, buf)
+ buf, err = rxAEAD.Open(buf[:0], rxNonce, buf, nil)
if err != nil {
log.Println("rx decrypt", err)
break
}
rx <- buf
+ vors.Incr(rxNonce)
}
Finish <- struct{}{}
}()
}
}
- var keyCiphOur []byte
- var keyMACOur []byte
- {
- var xof blake2b.XOF
- xof, err = blake2b.NewXOF(vors.ChaCha20KeySize+vors.SipHash24KeySize, nil)
- if err != nil {
- log.Fatalln(err)
- }
- xof.Write([]byte(vors.NoisePrologue))
- xof.Write(hs.ChannelBinding())
- buf := make([]byte, vors.ChaCha20KeySize+vors.SipHash24KeySize)
- if _, err = io.ReadFull(xof, buf); err != nil {
- log.Fatalln(err)
- }
- keyCiphOur, keyMACOur = buf[:vors.ChaCha20KeySize], buf[vors.ChaCha20KeySize:]
- }
-
seen := time.Now()
LoggerReady := make(chan struct{})
go func() {
for buf := range Ctrl {
- buf, err = txCS.Encrypt(nil, nil, buf)
- if err != nil {
- log.Fatalln("tx encrypt:", err)
- }
+ buf = txAEAD.Seal(nil, txNonce, buf, nil)
if err = ctrl.Tx(buf); err != nil {
log.Fatalln("tx:", err)
}
+ vors.Incr(txNonce)
}
}()
log.Println("mic:", err)
break
}
- incr(actr[:])
+ vors.Incr(actr[:])
if Muted {
continue
}
- for i = 0; i < vors.FrameLen; i++ {
+ for i = range vors.FrameLen {
pcm[i] = int16(uint16(buf[i*2+0]) | (uint16(buf[i*2+1]) << 8))
}
if vad != 0 && vors.RMS(pcm) < vad {
continue
}
- incr(nonce[len(nonce)-3:])
+ vors.Incr(nonce[len(nonce)-3:])
copy(buf, nonce[len(nonce)-4:])
copy(buf[4:], actr)
chacha20.XORKeyStream(
"github.com/dustin/go-humanize"
"github.com/jroimartin/gocui"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
type Stats struct {
package main
import (
- "crypto/rand"
- "encoding/base64"
+ "bytes"
"flag"
"fmt"
"io"
"log"
"os"
- "github.com/katzenpost/noise"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
+ "go.stargrave.org/vors/v5/pqhs"
)
+func usage() {
+ fmt.Fprintf(os.Stderr, "Usage: vors-keygen 5>pub 9>prv\n")
+ flag.PrintDefaults()
+}
+
func main() {
- pub := flag.Bool("pub", false, "print Base64 public key")
version := flag.Bool("version", false, "print version")
warranty := flag.Bool("warranty", false, "print warranty information")
+ flag.Usage = usage
flag.Parse()
if *warranty {
fmt.Println(vors.Warranty)
fmt.Println(vors.GetVersion())
return
}
- if *pub {
- data, err := io.ReadAll(os.Stdin)
- if err != nil {
- log.Fatal(err)
- }
- if len(data) != 2*32 {
- log.Fatal("wrong length")
- }
- fmt.Printf("%s\n", base64.RawURLEncoding.EncodeToString(data[32:]))
- return
- }
- kp, err := noise.DH25519.GenerateKeypair(rand.Reader)
+ prvMcEliece, pubMcEliece, prvX25519, pubX25519, err := pqhs.KeyGen()
if err != nil {
log.Fatal(err)
}
- os.Stdout.Write(kp.Private[:])
- os.Stdout.Write(kp.Public[:])
+ fdPubW := os.NewFile(5, "pub-out")
+ if _, err = io.Copy(fdPubW, bytes.NewReader(pqhs.KeyCombine(pubMcEliece, pubX25519))); err != nil {
+ log.Fatal(err)
+ }
+ fdPrvW := os.NewFile(9, "prv-out")
+ if _, err = io.Copy(fdPrvW, bytes.NewReader(pqhs.KeyCombine(prvMcEliece, prvX25519))); err != nil {
+ log.Fatal(err)
+ }
}
import (
"crypto/rand"
+ "crypto/sha3"
"crypto/subtle"
- "encoding/base64"
"flag"
"fmt"
"io"
"github.com/dchest/siphash"
"github.com/jroimartin/gocui"
- "github.com/katzenpost/noise"
- vors "go.stargrave.org/vors/v4/internal"
- "golang.org/x/crypto/blake2b"
+ vors "go.stargrave.org/vors/v5/internal"
+ "go.stargrave.org/vors/v5/pqhs"
+ "golang.org/x/crypto/chacha20poly1305"
)
var (
- Prv, Pub []byte
- Cookies = map[vors.Cookie]chan *net.UDPAddr{}
+ PrvMcEliece []byte
+ PrvX25519 []byte
+ PubHash []byte
+ Cookies = map[vors.Cookie]chan *net.UDPAddr{}
)
func newPeer(conn *net.TCPConn) {
if err != nil {
log.Fatalln("nodelay:", err)
}
- buf := make([]byte, len(vors.NoisePrologue))
-
- if _, err = io.ReadFull(conn, buf); err != nil {
- logger.Error("handshake: read prologue", "err", err)
+ nsConn := vors.NewNSConn(conn, 1<<16)
+ buf := <-nsConn.Rx
+ if buf == nil {
+ logger.Error("read magic", "err", nsConn.Err)
return
}
- if string(buf) != vors.NoisePrologue {
- logger.Error("handshake: wrong prologue", "err", err)
+ if string(buf) != vors.Magic {
+ logger.Error("handshake: wrong magic")
return
}
-
- hs, err := noise.NewHandshakeState(noise.Config{
- CipherSuite: vors.NoiseCipherSuite,
- Pattern: noise.HandshakeNK,
- Initiator: false,
- StaticKeypair: noise.DHKey{Private: Prv, Public: Pub},
- Prologue: []byte(vors.NoisePrologue),
- })
+ buf = <-nsConn.Rx
+ if buf == nil {
+ logger.Error("handshake: read hello", "err", nsConn.Err)
+ return
+ }
+ hs, buf, err := pqhs.NewServer(PrvMcEliece, PrvX25519, PubHash, buf)
if err != nil {
- log.Fatalln("noise.NewHandshakeState:", err)
+ logger.Error("handshake: process hello", "err", err)
+ return
}
- nsConn := vors.NewNSConn(conn)
+ nsConn.Tx(buf)
buf = <-nsConn.Rx
if buf == nil {
- logger.Error("read handshake", "err", nsConn.Err)
+ logger.Error("handshake: read finish", "err", nsConn.Err)
+ return
+ }
+ buf, err = hs.Read(buf)
+ if err != nil {
+ logger.Error("handshake: process finish", "err", err)
return
}
peer := &Peer{
tx: make(chan []byte, 10),
alive: make(chan struct{}),
}
- var room *Room
{
- var argsRaw []byte
- argsRaw, _, _, err = hs.ReadMessage(nil, buf)
+ var rxKey, txKey []byte
+ keys := hs.Binding(3*chacha20poly1305.KeySize + vors.SipHash24KeySize)
+ rxKey, keys = keys[:chacha20poly1305.KeySize], keys[chacha20poly1305.KeySize:]
+ txKey, peer.key = keys[:chacha20poly1305.KeySize], keys[chacha20poly1305.KeySize:]
+ peer.mac = siphash.New(peer.key[vors.ChaCha20KeySize:])
+ peer.rxAEAD, err = chacha20poly1305.New(rxKey)
if err != nil {
- logger.Error("handshake: decrypt", "err", err)
- return
+ log.Fatal(err)
+ }
+ peer.txAEAD, err = chacha20poly1305.New(txKey)
+ if err != nil {
+ log.Fatal(err)
}
+ }
+ peer.rxNonce = make([]byte, chacha20poly1305.NonceSize)
+ peer.txNonce = make([]byte, chacha20poly1305.NonceSize)
+ var room *Room
+ {
var args [][]byte
- args, err = vors.ArgsDecode(argsRaw)
+ args, err = vors.ArgsDecode(buf)
if err != nil {
logger.Error("handshake: decode args", "err", err)
return
}
if room.key != key {
logger.Error("wrong password")
- buf, _, _, err = hs.WriteMessage(nil, vors.ArgsEncode(
+ nsConn.Tx(peer.txAEAD.Seal(nil, peer.txNonce, vors.ArgsEncode(
[]byte(vors.CmdErr), []byte("wrong password"),
- ))
- if err != nil {
- log.Fatal(err)
- }
- nsConn.Tx(buf)
+ ), nil))
return
}
}
continue
}
logger.Error("name already taken")
- buf, _, _, err = hs.WriteMessage(nil, vors.ArgsEncode(
+ nsConn.Tx(peer.txAEAD.Seal(nil, peer.txNonce, vors.ArgsEncode(
[]byte(vors.CmdErr), []byte("name already taken"),
- ))
- if err != nil {
- log.Fatal(err)
- }
+ ), nil))
room.peersM.RUnlock()
- nsConn.Tx(buf)
return
}
room.peersM.RUnlock()
}
PeersM.Unlock()
if !found {
- buf, _, _, err = hs.WriteMessage(nil, vors.ArgsEncode(
+ nsConn.Tx(peer.txAEAD.Seal(nil, peer.txNonce, vors.ArgsEncode(
[]byte(vors.CmdErr), []byte("too many users"),
- ))
- if err != nil {
- log.Fatal(err)
- }
- nsConn.Tx(buf)
+ ), nil))
return
}
}
gotCookie := make(chan *net.UDPAddr)
Cookies[cookie] = gotCookie
- var txCS, rxCS *noise.CipherState
- buf, txCS, rxCS, err := hs.WriteMessage(nil,
- vors.ArgsEncode([]byte(vors.CmdCookie), cookie[:]))
+ err = nsConn.Tx(peer.txAEAD.Seal(nil, peer.txNonce, vors.ArgsEncode(
+ []byte(vors.CmdCookie), cookie[:],
+ ), nil))
if err != nil {
- log.Fatalln("hs.WriteMessage:", err)
- }
- if err = nsConn.Tx(buf); err != nil {
logger.Error("handshake write", "err", err)
delete(Cookies, cookie)
return
}
- peer.rxCS, peer.txCS = txCS, rxCS
timeout := time.NewTimer(vors.PingTime)
select {
}
room.peersM.RUnlock()
- {
- xof, err := blake2b.NewXOF(vors.ChaCha20KeySize+vors.SipHash24KeySize, nil)
- if err != nil {
- log.Fatalln(err)
- }
- xof.Write([]byte(vors.NoisePrologue))
- xof.Write(hs.ChannelBinding())
- peer.key = make([]byte, vors.ChaCha20KeySize+vors.SipHash24KeySize)
- if _, err = io.ReadFull(xof, peer.key); err != nil {
- log.Fatalln(err)
- }
- peer.mac = siphash.New(peer.key[vors.ChaCha20KeySize:])
- }
-
{
s := vors.ArgsEncode(
[]byte(vors.CmdAdd), []byte{peer.sid}, []byte(peer.name), peer.key)
func main() {
bind := flag.String("bind", "[::1]:"+strconv.Itoa(vors.DefaultPort),
"host:TCP/UDP port to listen on")
- kpFile := flag.String("key", "key", "path to keypair file")
+ pubFile := flag.String("pub", "pub", "path to file with public key")
+ prvFile := flag.String("prv", "prv", "path to file with private key")
prefer4 := flag.Bool("4", false,
"Prefer obsolete legacy IPv4 address during name resolution")
version := flag.Bool("version", false, "print version")
warranty := flag.Bool("warranty", false, "print warranty information")
flag.Usage = func() {
- fmt.Fprintln(os.Stderr, "Usage: vors-server [opts] -bind HOST:PORT -key PATH -srv HOST:PORT")
+ fmt.Fprintln(os.Stderr, "Usage: vors-server [opts] -bind HOST:PORT -prv PRV -pub PUB -srv HOST:PORT")
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, `
List of known rooms is shown by default. If room requires password
}
{
- data, err := os.ReadFile(*kpFile)
+ prv, err := os.ReadFile(*prvFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ PrvMcEliece, PrvX25519 = pqhs.KeyDecombine(prv)
+ pub, err := os.ReadFile(*pubFile)
if err != nil {
log.Fatal(err)
}
- Prv, Pub = data[:len(data)/2], data[len(data)/2:]
+ PubHash = sha3.SumSHAKE256(pub, 64)
}
vors.PreferIPv4 = *prefer4
go func() {
<-LoggerReady
- slog.Info("listening",
- "bind", *bind,
- "pub", base64.RawURLEncoding.EncodeToString(Pub))
+ slog.Info("listening", "bind", *bind)
for {
conn, errConn := lnTCP.AcceptTCP()
if err != nil {
package main
import (
+ "crypto/cipher"
"hash"
"log/slog"
"net"
"sync"
"time"
- "github.com/katzenpost/noise"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
var (
muted bool
sid byte
- logger *slog.Logger
- conn *vors.NSConn
- rxCS, txCS *noise.CipherState
- rx, tx chan []byte
- alive chan struct{}
- aliveOnce sync.Once
+ logger *slog.Logger
+ conn *vors.NSConn
+ rxAEAD cipher.AEAD
+ txAEAD cipher.AEAD
+ rxNonce []byte
+ txNonce []byte
+ rx, tx chan []byte
+ alive chan struct{}
+ aliveOnce sync.Once
}
func (peer *Peer) Close() {
func (peer *Peer) Rx() {
var err error
for buf := range peer.conn.Rx {
- buf, err = peer.rxCS.Decrypt(buf[:0], nil, buf)
+ buf, err = peer.rxAEAD.Open(buf[:0], peer.rxNonce, buf, nil)
if err != nil {
peer.logger.Error("rx decrypt", "err", err)
break
}
peer.rx <- buf
+ vors.Incr(peer.rxNonce)
}
peer.Close()
}
func (peer *Peer) Tx() {
var err error
for buf := range peer.tx {
- if peer.txCS == nil {
- continue
- }
- buf, err = peer.txCS.Encrypt(buf[:0], nil, buf)
- if err != nil {
- peer.logger.Error("tx encrypt", "err", err)
- break
- }
+ buf = peer.txAEAD.Seal(buf[:0], peer.txNonce, buf, nil)
if err = peer.conn.Tx(buf); err != nil {
peer.logger.Error("tx write", "err", err)
break
}
+ vors.Incr(peer.txNonce)
}
peer.Close()
}
"time"
"github.com/dustin/go-humanize"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
var (
"os"
"strconv"
- vors "go.stargrave.org/vors/v4/internal"
+ vors "go.stargrave.org/vors/v5/internal"
)
func usage() {
if err != nil {
log.Fatal(err)
}
- for i = 0; i < vors.FrameLen; i++ {
+ for i = range vors.FrameLen {
pcm[i] = int16(uint16(buf[i*2+0]) | (uint16(buf[i*2+1]) << 8))
}
rms = vors.RMS(pcm)
and DTX (discontinuous transmission) features enabled. Optional [VAD]
(voice activity detection).
=> https://opus-codec.org/ Opus codec\r
-* Noise-NKhfs protocol-based 0-RTT single round-trip handshake over TCP
- between client and server for creating authenticated encrypted channel
- and authentication based on server's public key knowledge.
+* PQConnect and Noise inspired post-quantum secure handshake protocol
+ over TCP between client and server. Authentication is based on
+ server's public key knowledge.
+ => https://www.pqconnect.net/ PQConnect\r
=> http://noiseprotocol.org/ Noise protocol framework\r
- => https://github.com/noiseprotocol/noise_hfs_spec KEM-based hybrid forward secrecy\r
* Fast ChaCha20 encryption with SipHash24 message authentication.
* Rooms, optionally password protected. Peers are able to broadcast
text message to everyone in the room.
-VoRS is written on Go (at least 1.21 version is required), but also uses
+VoRS is written on Go (at least 1.24 version is required), but also uses
wrapper on libopus library. Provided tarballs include its source code
and a fork of the gopkg.in/hraban/opus.v2 with the added ability to use
Decoder.SetComplexity call, that is required for ML-related optimisations.
=> https://sourceforge.net/projects/sox/ SoX\r
- $ version=4.0.0
+ $ version=5.0.0
$ [fetch|wget] http://www.vors.stargrave.org/download/vors-$version.tar.zst
$ [fetch|wget] http://www.vors.stargrave.org/download/vors-$version.tar.zst.sig
[verify signature]
--- /dev/null
+Server has a long-term static Classic McEliece 6960-119 and X25519
+keypairs. They are transferred to client outside the connection.
+
+Client:
+ * has: serverStaticPubMcEliece, serverStaticPubX25519
+ * clientEphPrvX25519, clientEphPubX25519 = Generate()
+ * ctMcElice, ssMcEliece = Encapsulate(serverStaticPubMcEliece)
+ * H = SHAKE256("VoRS v5")
+ * H = SHAKE256(H || serverStaticPubMcEliece || serverStaticPubX25519)
+ * H = SHAKE256(H || ctMcElice)
+ * CK = HKDF-Extract(SHAKE256, ikm=ssMcEliece, salt="")
+ * k = HKDF-Expand(SHAKE256, prk=CK, info="VoRS v5 client x25519")
+ * ctX25519 = ChaCha20-Poly1305(k, nonce=0, ad=H, pt=clientEphPubX25519)
+ * H = SHAKE256(H || ctX25519)
+ * ssX25519 = X25519(clientEphPrvX25519, serverStaticPubX25519)
+ * CK = HKDF-Extract(SHAKE256, ikm=ssX25519, salt=CK)
+ * sends: ctMcElice || ctX25519
+
+Server:
+ * ...
+ * serverEphPrvX25519, serverEphPubX25519 = Generate()
+ * k = HKDF-Expand(SHAKE256, prk=CK, info="VoRS v5 server x25519")
+ * ctX25519 = ChaCha20-Poly1305(k, nonce=0, ad=H, pt=serverEphPubX25519)
+ * H = SHAKE256(H || ctX25519)
+ * ssX25519 = X25519(serverEphPrvX25519, clientEphPubX25519)
+ * CK = HKDF-Extract(SHAKE256, ikm=ssX25519, salt=CK)
+ * serverEphPrvSNTRUP761, serverEphPubSNTRUP761 = Generate()
+ * k = HKDF-Expand(SHAKE256, prk=CK, info="VoRS v5 server sntrup761")
+ * ctSNTRUP = ChaCha20-Poly1305(k, nonce=0, ad=H, pt=serverEphPubSNTRUP761)
+ * H = SHAKE256(H || ctSNTRUP)
+ * sends: ctX25519 || ctSNTRUP
+
+Client:
+ * has: prefinish message payload
+ * ...
+ * ctSNTRUP, ssSNTRUP = Encapsulate(serverEphPubSNTRUP761)
+ * k = HKDF-Expand(SHAKE256, prk=CK, info="VoRS v5 client sntrup761")
+ * ctSNTRUP = ChaCha20-Poly1305(k, nonce=0, ad=H, pt=ctSNTRUP)
+ * H = SHAKE256(H || ctSNTRUP)
+ * CK = HKDF-Extract(SHAKE256, ikm=ssSNTRUP, salt=CK)
+ * k = HKDF-Expand(SHAKE256, prk=CK, info="VoRS v5 client prefinish")
+ * ctPrefinish = ChaCha20-Poly1305(k, nonce=0, ad=H, pt=prefinish)
+ * H = SHAKE256(H || ctPrefinish)
+ * sends: ctPrefinish
+
+Server:
+ * ...
+
+Both:
+ clientChaPolyKey, serverChaPolyKey, VoIPKey =
+ HKDF-Expand(SHAKE256, ikm=CK, salt=H)
transmission.
Each packet is encrypted with ChaCha20 and authenticated with SipHash24.
-Their keys are generated from BLAKE2b-XOF, which is fed with completed
-handshake's binding value. Then they are shared among the other
-participants. The stream identifier together with the packet counter is
-used as a nonce.
+Their keys are generated with HKDF taken on handshake's state. Then they
+are shared among the other participants. The stream identifier together
+with the packet counter is used as a nonce.
It is tuned for 24Kbps bandwidth. But remember that it has additional 8B
of MAC tag, 7B VoRS, 8B UDP and 40B IPv6 headers.
Each client handshakes with the server over TCP connection using the
-Noise-NKhfs protocol pattern with curve25519, Kyber-1024, ChaCha20-Poly1305
-and BLAKE2b algorithms.
-=> http://noiseprotocol.org/ Noise protocol framework\r
-=> https://github.com/noiseprotocol/noise_hfs_spec KEM-based hybrid forward secrecy\r
-
-* Client sends "VoRS v4" to the socket. Just a magic number.
+PQConnect, Noise, Chempat inspired protocol. It consists of hybrid key
+exchange, using static Classic McEliece 6960-119 server's public key,
+static X25519, ephemeral X25519 and ephemeral Streamlined NTRU Prime 761
+ones. With HKDF as a KDF and SHAKE as a hash function.
-* All next messages are Netstring encoded strings. Most of them contain
+=> https://www.pqconnect.net/ PQConnect\r
+=> http://noiseprotocol.org/ Noise protocol framework\r
+=> https://datatracker.ietf.org/doc/draft-josefsson-chempat/ Chempat\r
+=> https://classic.mceliece.org/ Classic McEliece\r
+=> https://ntruprime.cr.yp.to/ Streamlined NTRU Prime\r
+=> https://datatracker.ietf.org/doc/html/rfc7748 X25519\r
+=> https://datatracker.ietf.org/doc/html/rfc5869.html HKDF\r
+=> https://keccak.team/ SHAKE\r
+
+* All messages are Netstring encoded strings. Most of them contain
netstring encoded sequence of netstrings if multiple values are expected:
NS(NS(arg0) || NS(arg1) || ...)
=> http://cr.yp.to/proto/netstrings.txt Netstring\r
-* Client sends initial Noise handshake message with his username, room
- name and optional BLAKE2b-256 hash of the room's password (or an empty
- string) as a payload: [USERNAME, ROOM, hash(PASSWD)].
+* Client sends NS("VoRS v5") to the socket. Just a magic number.
+
+* Then it performs [PQHS].
+
+* Client sends initial handshake message. Its prefinish payload message
+ contains his username, room name and optional SHAKE256 hash of the
+ room's password (or an empty string) as a payload:
+ [USERNAME, ROOM, hash(PASSWD)].
* Server answers with final noise handshake message with the
["COOKIE", COOKIE], or ["ERR", MSG] failure message. It may reject a
* Server replies with ["SID", SID], where SID is single byte stream
number client must use.
+TODO
+
* ["PING"] and ["PONG"] messages are then sent every ten seconds as a heartbeat.
- S <- C : e, es, e1, NS(NS(USERNAME) || NS(ROOM) || NS(hash(PASSWD)))
- S -> C : e, ee, ekem1, NS(NS("COOKIE") || NS(COOKIE))
+ S <- C : hello
+ S -> C : hello
+ S <- C : finish, NS(NS(USERNAME) || NS(ROOM) || NS(hash(PASSWD)))
+ S -> C : NS(NS("COOKIE") || NS(COOKIE))
S <- C : UDP(COOKIE)
S -> C : NS(NS("SID") || NS(SID))
* Generate server's keypair. And share its public key among users.
Fact of server's public key knowledge means ability to connect to it.
- $ vors-keygen | tee key | vors-keygen -pub | read pub
- $ vors-server -key key -bind [2001:db8::1]:12978
+ $ vors-keygen 5>pub 9>prv
+ $ vors-server -prv prv -pub pub -bind [2001:db8::1]:12978
* Client uses external commands for reading from microphone and playing
it back. By default it uses SoX'es "rec" and "play" commands.
* Start the client, providing server's public key and our username:
- $ vors-client -srv "[2001:db8::1]:12978" -pub $pub -name NAME
+ $ vors-client -srv "[2001:db8::1]:12978" -pub pub -name NAME
Pressing F10 in server/client TUIs means quitting.
Pressing F1 in client means "mute" toggling.
application? But a fancy real-time refreshing TUI would be desirable.
Mumble tends to output no information, sometimes hiding the fact of a
problem and that everything stopped working.
-* Mono-cypher, mono-codec protocol.
+* Mono-codec, mono-cypher, post-quantum ready protocol.
* Maximal easiness of usage: here is your address, key, do me good.
VoRS is copylefted free software licenced under GNU Affero GPLv3.
-module go.stargrave.org/vors/v4
+module go.stargrave.org/vors/v5
-go 1.23.0
+go 1.24.0
-toolchain go1.24.3
+toolchain go1.24.5
require (
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da
github.com/dchest/siphash v1.2.3
github.com/dustin/go-humanize v1.0.1
github.com/jroimartin/gocui v0.5.0
- github.com/katzenpost/noise v0.0.3
go.cypherpunks.su/netstring/v3 v3.0.0
go.stargrave.org/opus/v2 v2.1.0
golang.org/x/term v0.32.0
)
require (
- github.com/cloudflare/circl v1.6.1 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
)
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
-github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
-github.com/cloudflare/circl v1.0.1-0.20210824050549-9b4298fa53ce/go.mod h1:wqo+yhCGS0T5Ldpb0f4hdJqVGwsEBYDE3MrO6W/RACc=
-github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
-github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/jroimartin/gocui v0.5.0 h1:DCZc97zY9dMnHXJSJLLmx9VqiEnAj0yh0eTNpuEtG/4=
github.com/jroimartin/gocui v0.5.0/go.mod h1:l7Hz8DoYoL6NoYnlnaX6XCNR62G7J5FfSW5jEogzaxE=
-github.com/katzenpost/noise v0.0.3 h1:bpYnozkk8j0XE1FAX9iRYgKtfIywuAINF+vMdBOidrM=
-github.com/katzenpost/noise v0.0.3/go.mod h1:+3UhOI7g4gXPlAdRKdgMKmxZmK/PP1/3sCnX20SA/vQ=
-github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
go.cypherpunks.su/netstring/v3 v3.0.0/go.mod h1:S9pYNVqT6kL2uXbdHz+yxc+A4sAFxBkjSzu+g6KD0QE=
go.stargrave.org/opus/v2 v2.1.0 h1:WwyMf76wcIWEPIQlU2UI5V9YkqXRHQhq6wfZGslcMFc=
go.stargrave.org/opus/v2 v2.1.0/go.mod h1:Y57qgcaXH7jBvKW89fscWOT/Wd3MYfhXUbYUcOMV0A8=
-golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/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.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
--- /dev/null
+package internal
+
+func Incr(data []byte) {
+ for i := len(data) - 1; i >= 0; i-- {
+ data[i]++
+ if data[i] != 0 {
+ return
+ }
+ }
+ panic("overflow")
+}
+++ /dev/null
-package internal
-
-import (
- "github.com/katzenpost/noise"
-)
-
-const NoisePrologue = "VoRS v4"
-
-var NoiseCipherSuite = noise.NewCipherSuiteHFS(
- noise.DH25519,
- noise.CipherChaChaPoly,
- noise.HashBLAKE2b,
- noise.HFSKyber,
-)
}
type NSConn struct {
- Conn net.Conn
- Rx chan []byte
- Err error
+ Conn net.Conn
+ Rx chan []byte
+ Err error
+ MaxLen uint64
sync.Mutex
}
-func NewNSConn(conn net.Conn) *NSConn {
- c := NSConn{Conn: conn, Rx: make(chan []byte)}
+func NewNSConn(conn net.Conn, maxLen int) *NSConn {
+ c := NSConn{Conn: conn, Rx: make(chan []byte), MaxLen: uint64(maxLen)}
go func() {
r := netstring.NewReader(conn)
var n uint64
if c.Err != nil {
break
}
+ if n >= c.MaxLen {
+ c.Err = errors.New("exceeds MaxLen")
+ break
+ }
buf := make([]byte, int(n))
if _, c.Err = io.ReadFull(r, buf); c.Err != nil {
break
)
const (
+ Magic = "VoRS v5"
CmdErr = "ERR"
CmdCookie = "COOKIE"
CmdSID = "SID"
size=$(( $(stat -f %z $tarball) / 1024 ))
release_date=$(date "+%Y-%m-%d")
-release_underscored=`echo $release | tr . _`
cat <<EOF
An entry for documentation:
$release | $release_date | $size KiB
--- /dev/null
+package pqhs
+
+import (
+ "crypto/ecdh"
+ "crypto/rand"
+ "crypto/sha3"
+
+ vors "go.stargrave.org/vors/v5/internal"
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119"
+ sntrup761kem "go.stargrave.org/vors/v5/pqhs/sntrup761/kem"
+ sntrup761 "go.stargrave.org/vors/v5/pqhs/sntrup761/kem/ntruprime/sntrup761"
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+type Client struct {
+ ephPrvX25519 *ecdh.PrivateKey
+ SymmetricState
+}
+
+func NewClient(
+ serverStaticPubMcElieceRaw, serverStaticPubX25519Raw []byte,
+) (c *Client, payload []byte, err error) {
+ c = &Client{}
+ var serverStaticPubMcEliece *mceliece6960119.PublicKey
+ serverStaticPubMcEliece, err = mceliece6960119.UnmarshalBinaryPublicKey(
+ serverStaticPubMcElieceRaw)
+ if err != nil {
+ return
+ }
+ var serverStaticPubX25519 *ecdh.PublicKey
+ {
+ x25519 := ecdh.X25519()
+ serverStaticPubX25519, err = x25519.NewPublicKey(serverStaticPubX25519Raw)
+ if err != nil {
+ return
+ }
+ c.ephPrvX25519, err = x25519.GenerateKey(rand.Reader)
+ if err != nil {
+ return
+ }
+ }
+ var ctMcEliece []byte
+ var k []byte
+ ctMcEliece, k, err = mceliece6960119.Encapsulate(serverStaticPubMcEliece)
+ if err != nil {
+ return
+ }
+ c.H([]byte(vors.Magic))
+ c.H(sha3.SumSHAKE256(
+ append(serverStaticPubMcElieceRaw, serverStaticPubX25519Raw...), 64))
+ c.H(ctMcEliece)
+ c.CK(k)
+ payload = append(ctMcEliece,
+ c.Seal(CtxClientX25519, c.ephPrvX25519.PublicKey().Bytes())...)
+ k, err = c.ephPrvX25519.ECDH(serverStaticPubX25519)
+ if err == nil {
+ c.CK(k)
+ }
+ return
+}
+
+func (c *Client) Read(reply, prefinish []byte) (payload []byte, err error) {
+ ctX25519 := reply[:32+chacha20poly1305.Overhead]
+ ctSNTRUP := reply[len(ctX25519):]
+ var k []byte
+ {
+ var serverEphPubX25519Raw []byte
+ serverEphPubX25519Raw, err = c.Open(CtxServerX25519, ctX25519)
+ if err != nil {
+ return
+ }
+ _, k, err = DH(c.ephPrvX25519, serverEphPubX25519Raw)
+ if err != nil {
+ return
+ }
+ }
+ c.CK(k)
+ {
+ var serverEphPubSNTRUPRaw []byte
+ serverEphPubSNTRUPRaw, err = c.Open(CtxServerSNTRUP761, ctSNTRUP)
+ if err != nil {
+ return
+ }
+ sntrup761s := sntrup761.Scheme()
+ var serverEphPubSNTRUP sntrup761kem.PublicKey
+ serverEphPubSNTRUP, err = sntrup761s.UnmarshalBinaryPublicKey(
+ serverEphPubSNTRUPRaw)
+ if err != nil {
+ return
+ }
+ ctSNTRUP, k, err = sntrup761s.Encapsulate(serverEphPubSNTRUP)
+ if err != nil {
+ return
+ }
+ }
+ ctSNTRUP = c.Seal(CtxClientSNTRUP761, ctSNTRUP)
+ c.CK(k)
+ payload = append(ctSNTRUP, c.Seal(CtxClientPrefinish, prefinish)...)
+ return
+}
--- /dev/null
+package pqhs
+
+const (
+ CtxClientX25519 = "VoRS v5 client x25519"
+ CtxServerX25519 = "VoRS v5 server x25519"
+ CtxServerSNTRUP761 = "VoRS v5 server sntrup761"
+ CtxClientSNTRUP761 = "VoRS v5 client sntrup761"
+ CtxClientPrefinish = "VoRS v5 client prefinish"
+)
--- /dev/null
+package pqhs
+
+import "crypto/ecdh"
+
+func DH(prv *ecdh.PrivateKey, pubRaw []byte) (pub *ecdh.PublicKey, k []byte, err error) {
+ x25519 := ecdh.X25519()
+ pub, err = x25519.NewPublicKey(pubRaw)
+ if err != nil {
+ return
+ }
+ k, err = prv.ECDH(pub)
+ return
+}
--- /dev/null
+package pqhs
+
+import (
+ "bytes"
+ "crypto/sha3"
+ "testing"
+)
+
+func TestHandshake(t *testing.T) {
+ prvMcEliece, pubMcEliece, prvX25519, pubX25519, err := KeyGen()
+ if err != nil {
+ t.Fatal(err)
+ }
+ var c *Client
+ var payload []byte
+ c, payload, err = NewClient(KeyDecombine(KeyCombine(pubMcEliece, pubX25519)))
+ if err != nil {
+ t.Fatal(err)
+ }
+ var s *Server
+ prvMcEliece, prvX25519 = KeyDecombine(KeyCombine(prvMcEliece, prvX25519))
+ s, payload, err = NewServer(
+ prvMcEliece, prvX25519,
+ sha3.SumSHAKE256(append(pubMcEliece, pubX25519...), 64),
+ payload)
+ if err != nil {
+ t.Fatal(err)
+ }
+ payload, err = c.Read(payload, []byte("whatever"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ var prefinish []byte
+ prefinish, err = s.Read(payload)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(prefinish) != "whatever" {
+ t.Fatal("prefinish differs")
+ }
+ if !bytes.Equal(c.Binding(1234), s.Binding(1234)) {
+ t.Fatal("bindings differs")
+ }
+}
--- /dev/null
+package pqhs
+
+import (
+ "crypto/ecdh"
+ "crypto/rand"
+
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119"
+)
+
+func KeyGen() (
+ prvMcEliece, pubMcEliece, prvX25519, pubX25519 []byte, err error,
+) {
+ {
+ x25519 := ecdh.X25519()
+ var prv *ecdh.PrivateKey
+ prv, err = x25519.GenerateKey(rand.Reader)
+ if err != nil {
+ return
+ }
+ prvX25519 = prv.Bytes()
+ pubX25519 = prv.PublicKey().Bytes()
+ }
+ {
+ var pub *mceliece6960119.PublicKey
+ var prv *mceliece6960119.PrivateKey
+ pub, prv, err = mceliece6960119.GenerateKeyPair()
+ if err != nil {
+ return
+ }
+ prvMcEliece, err = prv.MarshalBinary()
+ if err != nil {
+ return
+ }
+ pubMcEliece, err = pub.MarshalBinary()
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+func KeyCombine(mcEliece, x25519 []byte) []byte {
+ return append(mcEliece, x25519...)
+}
+
+func KeyDecombine(combined []byte) (mcEliece, x25519 []byte) {
+ if len(combined) <= 32 {
+ panic("too short combined key")
+ }
+ mcEliece = combined[:len(combined)-32]
+ x25519 = combined[len(combined)-32:]
+ return
+}
--- /dev/null
+Go/Git is unable to fetch (https://github.com/cloudflare/circl)
+pull-request's commit (7dfc396c96830ed3601ace705e1612b9bcc447f9) to
+github.com/cloudflare/circl containing mceliece6960119 implementation
+(https://github.com/cloudflare/circl/pull/378). So copy it here.
--- /dev/null
+// Code generated from benes_other.templ.go. DO NOT EDIT.
+
+package mceliece6960119
+
+// Layers of the Beneš network. The required size of `data` and `bits` depends on the value `lgs`.
+func layerIn(data *[2][64]uint64, bits *[64]uint64, lgs int) {
+ s := 1 << lgs
+ index := 0
+ for i := 0; i < 64; i += s * 2 {
+ for j := i; j < i+s; j++ {
+ d := data[0][j+0] ^ data[0][j+s]
+ d &= bits[index]
+ data[0][j+0] ^= d
+ data[0][j+s] ^= d
+ index += 1
+
+ d = data[1][j+0] ^ data[1][j+s]
+ d &= bits[index]
+ data[1][j+0] ^= d
+ data[1][j+s] ^= d
+ index += 1
+ }
+ }
+}
+
+// Exterior layers of the Beneš network. The length of `bits` depends on the value of `lgs`.
+// Note that this implementation is quite different from the C implementation.
+// However, it does make sense. Whereas the C implementation uses pointer arithmetic to access
+// the entire array `data`, this implementation always considers `data` as two-dimensional array.
+// The C implementation uses 128 as upper bound (because the array contains 128 elements),
+// but this implementation has 64 elements per subarray and needs case distinctions at different places.
+func layerEx(data *[2][64]uint64, bits *[64]uint64, lgs int) {
+ data0Idx := 0
+ data1Idx := 32
+ s := 1 << lgs
+ if s == 64 {
+ for j := 0; j < 64; j++ {
+ d := data[0][j+0] ^ data[1][j]
+ d &= bits[data0Idx]
+ data0Idx += 1
+ data[0][j+0] ^= d
+ data[1][j] ^= d
+ }
+ } else {
+ for i := 0; i < 64; i += s * 2 {
+ for j := i; j < i+s; j++ {
+ d := data[0][j+0] ^ data[0][j+s]
+ d &= bits[data0Idx]
+ data0Idx += 1
+
+ data[0][j+0] ^= d
+ data[0][j+s] ^= d
+
+ // data[1] computations
+ d = data[1][j+0] ^ data[1][j+s]
+ d &= bits[data1Idx]
+ data1Idx += 1
+
+ data[1][j+0] ^= d
+ data[1][j+s] ^= d
+ }
+ }
+ }
+}
+
+// Apply Beneš network in-place to array `r` based on configuration `bits`.
+// Here, `r` is a sequence of bits to be permuted.
+// `bits` defines the condition bits configuring the Beneš network and
+// Note that this differs from the C implementation, missing the `rev` parameter.
+// This is because `rev` is not used throughout the entire codebase.
+func applyBenes(r *[1024]byte, bits *[condBytes]byte) {
+ rIntV := [2][64]uint64{}
+ rIntH := [2][64]uint64{}
+ bIntV := [64]uint64{}
+ bIntH := [64]uint64{}
+ bitsPtr := bits[:]
+
+ for i := 0; i < 64; i++ {
+ rIntV[0][i] = load8(r[i*16:])
+ rIntV[1][i] = load8(r[i*16+8:])
+ }
+
+ transpose64x64(&rIntH[0], &rIntV[0])
+ transpose64x64(&rIntH[1], &rIntV[1])
+
+ for iter := 0; iter <= 6; iter++ {
+ for i := 0; i < 64; i++ {
+ bIntV[i] = load8(bitsPtr)
+ bitsPtr = bitsPtr[8:]
+ }
+ transpose64x64(&bIntH, &bIntV)
+ layerEx(&rIntH, &bIntH, iter)
+ }
+
+ transpose64x64(&rIntV[0], &rIntH[0])
+ transpose64x64(&rIntV[1], &rIntH[1])
+
+ for iter := 0; iter <= 5; iter++ {
+ for i := 0; i < 64; i++ {
+ bIntV[i] = load8(bitsPtr)
+ bitsPtr = bitsPtr[8:]
+ }
+ layerIn(&rIntV, &bIntV, iter)
+ }
+
+ for iter := 4; iter >= 0; iter-- {
+ for i := 0; i < 64; i++ {
+ bIntV[i] = load8(bitsPtr)
+ bitsPtr = bitsPtr[8:]
+ }
+ layerIn(&rIntV, &bIntV, iter)
+ }
+
+ transpose64x64(&rIntH[0], &rIntV[0])
+ transpose64x64(&rIntH[1], &rIntV[1])
+
+ for iter := 6; iter >= 0; iter-- {
+ for i := 0; i < 64; i++ {
+ bIntV[i] = load8(bitsPtr)
+ bitsPtr = bitsPtr[8:]
+ }
+ transpose64x64(&bIntH, &bIntV)
+ layerEx(&rIntH, &bIntH, iter)
+ }
+
+ transpose64x64(&rIntV[0], &rIntH[0])
+ transpose64x64(&rIntV[1], &rIntH[1])
+
+ for i := 0; i < 64; i++ {
+ store8(r[i*16+0:], rIntV[0][i])
+ store8(r[i*16+8:], rIntV[1][i])
+ }
+}
--- /dev/null
+// Code generated from fft_other.templ.go. DO NOT EDIT.
+
+// The following code is translated from the C `vec` Additional Implementation
+// from the NIST round 4 submission package.
+
+package mceliece6960119
+
+import "go.stargrave.org/vors/v5/pqhs/mceliece6960119/internal"
+
+func fft(out *[exponent][gfBits]uint64, in *[2][gfBits]uint64) {
+ radixConversions(in)
+ butterflies(out, in)
+}
+
+func radixConversions(in *[2][gfBits]uint64) {
+ for j := 0; j <= 5; j++ {
+ for i := 0; i < gfBits; i++ {
+ in[1][i] ^= in[1][i] >> 32
+ in[0][i] ^= in[1][i] << 32
+ }
+
+ for i := 0; i < gfBits; i++ {
+ for k := 4; k >= j; k-- {
+ in[0][i] ^= (in[0][i] & internal.RadixConversionsMask[k][0]) >> (1 << k)
+ in[0][i] ^= (in[0][i] & internal.RadixConversionsMask[k][1]) >> (1 << k)
+ in[1][i] ^= (in[1][i] & internal.RadixConversionsMask[k][0]) >> (1 << k)
+ in[1][i] ^= (in[1][i] & internal.RadixConversionsMask[k][1]) >> (1 << k)
+ }
+ }
+
+ if j < 5 {
+ vecMul(&in[0], &in[0], &internal.RadixConversionsS[j][0])
+ vecMul(&in[1], &in[1], &internal.RadixConversionsS[j][1])
+ }
+ }
+}
+
+func butterflies(out *[exponent][gfBits]uint64, in *[2][gfBits]uint64) {
+ tmp := [gfBits]uint64{}
+ pre := [8][gfBits]uint64{}
+ buf := [128]uint64{}
+ constsPtr := 2
+ for i := 0; i < 7; i++ {
+ for j := 0; j < gfBits; j++ {
+ pre[i][j] = uint64(internal.ButterfliesBeta[i]>>j) & 1
+ pre[i][j] = -pre[i][j]
+ }
+
+ vecMul(&pre[i], &in[1], &pre[i])
+ }
+ for i := 0; i < gfBits; i++ {
+ buf[0] = in[0][i]
+
+ buf[1] = buf[0] ^ pre[0][i]
+ buf[32] = in[0][i] ^ pre[5][i]
+ buf[3] = buf[1] ^ pre[1][i]
+ buf[96] = buf[32] ^ pre[6][i]
+ buf[97] = buf[96] ^ pre[0][i]
+ buf[2] = in[0][i] ^ pre[1][i]
+ buf[99] = buf[97] ^ pre[1][i]
+ buf[6] = buf[2] ^ pre[2][i]
+ buf[98] = buf[99] ^ pre[0][i]
+ buf[7] = buf[6] ^ pre[0][i]
+ buf[102] = buf[98] ^ pre[2][i]
+ buf[5] = buf[7] ^ pre[1][i]
+ buf[103] = buf[102] ^ pre[0][i]
+ buf[101] = buf[103] ^ pre[1][i]
+ buf[4] = in[0][i] ^ pre[2][i]
+ buf[100] = buf[101] ^ pre[0][i]
+ buf[12] = buf[4] ^ pre[3][i]
+ buf[108] = buf[100] ^ pre[3][i]
+ buf[13] = buf[12] ^ pre[0][i]
+ buf[109] = buf[108] ^ pre[0][i]
+ buf[15] = buf[13] ^ pre[1][i]
+ buf[111] = buf[109] ^ pre[1][i]
+ buf[14] = buf[15] ^ pre[0][i]
+ buf[110] = buf[111] ^ pre[0][i]
+ buf[10] = buf[14] ^ pre[2][i]
+ buf[106] = buf[110] ^ pre[2][i]
+ buf[11] = buf[10] ^ pre[0][i]
+ buf[107] = buf[106] ^ pre[0][i]
+ buf[9] = buf[11] ^ pre[1][i]
+ buf[105] = buf[107] ^ pre[1][i]
+ buf[104] = buf[105] ^ pre[0][i]
+ buf[8] = in[0][i] ^ pre[3][i]
+ buf[120] = buf[104] ^ pre[4][i]
+ buf[24] = buf[8] ^ pre[4][i]
+ buf[121] = buf[120] ^ pre[0][i]
+ buf[25] = buf[24] ^ pre[0][i]
+ buf[123] = buf[121] ^ pre[1][i]
+ buf[27] = buf[25] ^ pre[1][i]
+ buf[122] = buf[123] ^ pre[0][i]
+ buf[26] = buf[27] ^ pre[0][i]
+ buf[126] = buf[122] ^ pre[2][i]
+ buf[30] = buf[26] ^ pre[2][i]
+ buf[127] = buf[126] ^ pre[0][i]
+ buf[31] = buf[30] ^ pre[0][i]
+ buf[125] = buf[127] ^ pre[1][i]
+ buf[29] = buf[31] ^ pre[1][i]
+ buf[124] = buf[125] ^ pre[0][i]
+ buf[28] = buf[29] ^ pre[0][i]
+ buf[116] = buf[124] ^ pre[3][i]
+ buf[20] = buf[28] ^ pre[3][i]
+ buf[117] = buf[116] ^ pre[0][i]
+ buf[21] = buf[20] ^ pre[0][i]
+ buf[119] = buf[117] ^ pre[1][i]
+ buf[23] = buf[21] ^ pre[1][i]
+ buf[118] = buf[119] ^ pre[0][i]
+ buf[22] = buf[23] ^ pre[0][i]
+ buf[114] = buf[118] ^ pre[2][i]
+ buf[18] = buf[22] ^ pre[2][i]
+ buf[115] = buf[114] ^ pre[0][i]
+ buf[19] = buf[18] ^ pre[0][i]
+ buf[113] = buf[115] ^ pre[1][i]
+ buf[17] = buf[19] ^ pre[1][i]
+ buf[112] = buf[113] ^ pre[0][i]
+ buf[80] = buf[112] ^ pre[5][i]
+ buf[16] = in[0][i] ^ pre[4][i]
+ buf[81] = buf[80] ^ pre[0][i]
+ buf[48] = buf[16] ^ pre[5][i]
+ buf[83] = buf[81] ^ pre[1][i]
+ buf[49] = buf[48] ^ pre[0][i]
+ buf[82] = buf[83] ^ pre[0][i]
+ buf[51] = buf[49] ^ pre[1][i]
+ buf[86] = buf[82] ^ pre[2][i]
+ buf[50] = buf[51] ^ pre[0][i]
+ buf[87] = buf[86] ^ pre[0][i]
+ buf[54] = buf[50] ^ pre[2][i]
+ buf[85] = buf[87] ^ pre[1][i]
+ buf[55] = buf[54] ^ pre[0][i]
+ buf[84] = buf[85] ^ pre[0][i]
+ buf[53] = buf[55] ^ pre[1][i]
+ buf[92] = buf[84] ^ pre[3][i]
+ buf[52] = buf[53] ^ pre[0][i]
+ buf[93] = buf[92] ^ pre[0][i]
+ buf[60] = buf[52] ^ pre[3][i]
+ buf[95] = buf[93] ^ pre[1][i]
+ buf[61] = buf[60] ^ pre[0][i]
+ buf[94] = buf[95] ^ pre[0][i]
+ buf[63] = buf[61] ^ pre[1][i]
+ buf[90] = buf[94] ^ pre[2][i]
+ buf[62] = buf[63] ^ pre[0][i]
+ buf[91] = buf[90] ^ pre[0][i]
+ buf[58] = buf[62] ^ pre[2][i]
+ buf[89] = buf[91] ^ pre[1][i]
+ buf[59] = buf[58] ^ pre[0][i]
+ buf[88] = buf[89] ^ pre[0][i]
+ buf[57] = buf[59] ^ pre[1][i]
+ buf[72] = buf[88] ^ pre[4][i]
+ buf[56] = buf[57] ^ pre[0][i]
+ buf[73] = buf[72] ^ pre[0][i]
+ buf[40] = buf[56] ^ pre[4][i]
+ buf[75] = buf[73] ^ pre[1][i]
+ buf[41] = buf[40] ^ pre[0][i]
+ buf[74] = buf[75] ^ pre[0][i]
+ buf[43] = buf[41] ^ pre[1][i]
+ buf[78] = buf[74] ^ pre[2][i]
+ buf[42] = buf[43] ^ pre[0][i]
+ buf[79] = buf[78] ^ pre[0][i]
+ buf[46] = buf[42] ^ pre[2][i]
+ buf[77] = buf[79] ^ pre[1][i]
+ buf[47] = buf[46] ^ pre[0][i]
+ buf[76] = buf[77] ^ pre[0][i]
+ buf[45] = buf[47] ^ pre[1][i]
+ buf[68] = buf[76] ^ pre[3][i]
+ buf[44] = buf[45] ^ pre[0][i]
+ buf[69] = buf[68] ^ pre[0][i]
+ buf[36] = buf[44] ^ pre[3][i]
+ buf[71] = buf[69] ^ pre[1][i]
+ buf[37] = buf[36] ^ pre[0][i]
+ buf[70] = buf[71] ^ pre[0][i]
+ buf[39] = buf[37] ^ pre[1][i]
+ buf[66] = buf[70] ^ pre[2][i]
+ buf[38] = buf[39] ^ pre[0][i]
+ buf[67] = buf[66] ^ pre[0][i]
+ buf[34] = buf[38] ^ pre[2][i]
+ buf[65] = buf[67] ^ pre[1][i]
+ buf[35] = buf[34] ^ pre[0][i]
+ buf[33] = buf[35] ^ pre[1][i]
+ buf[64] = in[0][i] ^ pre[6][i]
+
+ transpose64x64((*[64]uint64)(buf[:64]), (*[64]uint64)(buf[:64]))
+ transpose64x64((*[64]uint64)(buf[64:]), (*[64]uint64)(buf[64:]))
+
+ for j := 0; j < 128; j++ {
+ out[internal.ButterfliesReversal[j]][i] = buf[j]
+ }
+ }
+
+ for i := 1; i <= 6; i++ {
+ s := 1 << i
+
+ for j := 0; j < 128; j += 2 * s {
+ for k := j; k < j+s; k++ {
+ vecMul(&tmp, &out[k+s], &internal.ButterfliesConst[constsPtr+(k-j)])
+
+ for b := 0; b < gfBits; b++ {
+ out[k][b] ^= tmp[b]
+ }
+ for b := 0; b < gfBits; b++ {
+ out[k+s][b] ^= out[k][b]
+ }
+ }
+ }
+
+ constsPtr += 1 << i
+ }
+}
--- /dev/null
+// This file is for implementing the Nassimi-Sahni algorithm
+// See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork"
+// See also https://cr.yp.to/papers/controlbits-20200923.pdf
+
+package internal
+
+import (
+ "unsafe"
+)
+
+// layer implements one layer of the Beneš network.
+// It permutes elements `p` according to control bits `cb` in-place.
+// Thus, one layer of the Beneš network is created and if some control bits are set
+// the corresponding transposition is applied. Parameter `s` equals `n.len()` and
+// `s` configures `stride-2^s` conditional swaps.
+func layer(p []int16, cb []byte, s, n int) {
+ stride := 1 << s
+ index := 0
+ for i := int(0); i < n; i += stride * 2 {
+ for j := int(0); j < stride; j++ {
+ d := p[i+j] ^ p[i+j+stride]
+ m := int16(cb[index>>3]>>(index&7)) & 1
+ m = -m
+ d &= m
+ p[i+j] ^= d
+ p[i+j+stride] ^= d
+ index++
+ }
+ }
+}
+
+// cbRecursion implements a recursion step of controlbitsfrompermutation.
+// Pick `w ∈ {1, 2, …, 14}. Let `n = 2^w`.
+// `out` must be a reference to a slice with `((2*w-1)*(1<<(w-1))+7)/8` or more bytes.
+// It must zero-initialized before the first recursive call.
+// `step` is initialized with 0 and doubles in each recursion step.
+// `pi_offset` is an offset within temp slice ref (or aux in the first recursive call).
+// `temp` is an intermediate reference to a slice used for recursive computation and
+// temporarily stores values. It must be able to carry at least 2・n elements.
+// `aux` is an auxiliary reference to a slice. It points to the elements to be permuted.
+// After the first recursive iterations, the elements are stored in `temp` and thus `aux`
+// won't be read anymore. The first `n/2` elements are read.
+// nolint:funlen
+func cbRecursion(out []byte, pos, step int, pi []int16, w, n int32, temp []int32) {
+ A := temp
+ B := temp[n:]
+ if w == 1 {
+ out[pos>>3] ^= byte(pi[0] << (pos & 7))
+ return
+ }
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (int32(pi[x]^1) << 16) | int32(pi[x^1])
+ }
+ int32Sort(A, n) // A = (id<<16)+pibar
+
+ for x := int32(0); x < n; x++ {
+ Ax := A[x]
+ px := Ax & 0xffff
+ cx := px
+ if x < cx {
+ cx = x
+ }
+ B[x] = (px << 16) | cx
+ }
+ // B = (p<<16)+c
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (A[x] << 16) | x
+ }
+ int32Sort(A, n) // A = (id<<16)+pibar^-1
+
+ for x := int32(0); x < n; x++ {
+ // A = (pibar^(-1)<<16)+pibar
+ A[x] = (A[x] << 16) + (B[x] >> 16)
+ }
+ int32Sort(A, n) // A = (id<<16)+pibar^2
+
+ if w <= 10 {
+ for x := int32(0); x < n; x++ {
+ B[x] = ((A[x] & 0xffff) << 10) | (B[x] & 0x3ff)
+ }
+
+ for i := int32(1); i < w-1; i++ {
+ /* B = (p<<10)+c */
+
+ for x := int32(0); x < n; x++ {
+ A[x] = ((B[x] & ^0x3ff) << 6) | x /* A = (p<<16)+id */
+ }
+ int32Sort(A, n) /* A = (id<<16)+p^{-1} */
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (A[x] << 20) | B[x] /* A = (p^{-1}<<20)+(p<<10)+c */
+ }
+ int32Sort(A, n) /* A = (id<<20)+(pp<<10)+cp */
+
+ for x := int32(0); x < n; x++ {
+ ppcpx := A[x] & 0xfffff
+ ppcx := (A[x] & 0xffc00) | (B[x] & 0x3ff)
+ if ppcpx < ppcx {
+ ppcx = ppcpx
+ }
+ B[x] = ppcx
+ }
+ }
+
+ for x := int32(0); x < n; x++ {
+ B[x] &= 0x3ff
+ }
+ } else {
+ for x := int32(0); x < n; x++ {
+ B[x] = (A[x] << 16) | (B[x] & 0xffff)
+ }
+
+ for i := int32(1); i < w-1; i++ {
+ /* B = (p<<16)+c */
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (B[x] &^ 0xffff) | x
+ }
+ int32Sort(A, n) /* A = (id<<16)+p^(-1) */
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (A[x] << 16) | (B[x] & 0xffff)
+ }
+ /* A = p^(-1)<<16+c */
+
+ if i < w-2 {
+ for x := int32(0); x < n; x++ {
+ B[x] = (A[x] & ^0xffff) | (B[x] >> 16)
+ }
+ /* B = (p^(-1)<<16)+p */
+ int32Sort(B, n) /* B = (id<<16)+p^(-2) */
+ for x := int32(0); x < n; x++ {
+ B[x] = (B[x] << 16) | (A[x] & 0xffff)
+ }
+ /* B = (p^(-2)<<16)+c */
+ }
+
+ int32Sort(A, n)
+ /* A = id<<16+cp */
+ for x := int32(0); x < n; x++ {
+ cpx := (B[x] & ^0xffff) | (A[x] & 0xffff)
+ if cpx < B[x] {
+ B[x] = cpx
+ }
+ }
+ }
+
+ for x := int32(0); x < n; x++ {
+ B[x] &= 0xffff
+ }
+ }
+
+ for x := int32(0); x < n; x++ {
+ A[x] = (int32(pi[x]) << 16) + x
+ }
+ int32Sort(A, n) /* A = (id<<16)+pi^(-1) */
+
+ for j := int32(0); j < n/2; j++ {
+ x := 2 * j
+ fj := B[x] & 1 /* f[j] */
+ Fx := x + fj /* F[x] */
+ Fx1 := Fx ^ 1 /* F[x+1] */
+
+ out[pos>>3] ^= byte(fj << (pos & 7))
+ pos += step
+
+ B[x] = (A[x] << 16) | Fx
+ B[x+1] = (A[x+1] << 16) | Fx1
+ }
+ /* B = (pi^(-1)<<16)+F */
+
+ int32Sort(B, n) /* B = (id<<16)+F(pi) */
+
+ pos += int(2*w-3) * step * int(n/2)
+
+ for k := int32(0); k < n/2; k++ {
+ y := 2 * k
+ lk := B[y] & 1 /* l[k] */
+ Ly := y + lk /* L[y] */
+ Ly1 := Ly ^ 1 /* L[y+1] */
+
+ out[pos>>3] ^= byte(lk << (pos & 7))
+ pos += step
+
+ A[y] = (Ly << 16) | (B[y] & 0xffff)
+ A[y+1] = (Ly1 << 16) | (B[y+1] & 0xffff)
+ }
+ /* A = (L<<16)+F(pi) */
+
+ int32Sort(A, n) /* A = (id<<16)+F(pi(L)) = (id<<16)+M */
+
+ pos -= int(2*w-2) * step * int(n/2)
+
+ p := (*int16)(unsafe.Pointer(&temp[n+n/4]))
+ q := unsafe.Slice(p, n) // q can start anywhere between temp+n and temp+n/2
+ for j := int32(0); j < n/2; j++ {
+ q[j] = int16(A[2*j]&0xffff) >> 1
+ q[j+n/2] = int16(A[2*j+1]&0xffff) >> 1
+ }
+
+ cbRecursion(out, pos, step*2, q, w-1, n/2, temp)
+ cbRecursion(out, pos+step, step*2, q[n/2:], w-1, n/2, temp)
+}
+
+// ControlBitsFromPermutation computes control bits
+// parameters: 1 <= w <= 14; n = 2^w
+// input: permutation pi of {0,1,...,n-1}
+// output: (2m-1)n/2 control bits at positions 0,1,...
+// output position pos is by definition 1&(out[pos/8]>>(pos&7))
+func ControlBitsFromPermutation(out []byte, pi []int16, w, n int32) {
+ temp := make([]int32, 2*n)
+ piTest := make([]int16, n)
+ var ptr []byte
+ for {
+ for i := 0; i < int(((2*w-1)*n/2)+7)/8; i++ {
+ out[i] = 0
+ }
+
+ cbRecursion(out, 0, 1, pi[:], w, n, temp)
+ // check for correctness
+
+ for i := int32(0); i < n; i++ {
+ piTest[i] = int16(i)
+ }
+
+ ptr = out
+ for i := 0; i < int(w); i++ {
+ layer(piTest, ptr, i, int(n))
+ ptr = ptr[n>>4:]
+ }
+
+ for i := int(w - 2); i >= 0; i-- {
+ layer(piTest, ptr, i, int(n))
+ ptr = ptr[n>>4:]
+ }
+
+ diff := int16(0)
+ for i := int32(0); i < n; i++ {
+ diff |= pi[i] ^ piTest[i]
+ }
+
+ if diff == 0 {
+ break
+ }
+ }
+}
--- /dev/null
+package internal
+
+// Returns (min(a, b), max(a, b)), executes in constant time
+func minMaxI32(a, b *int32) {
+ ab := *b ^ *a
+ c := *b - *a
+ c ^= ab & (c ^ *b)
+ c >>= 31
+ c &= ab
+ *a ^= c
+ *b ^= c
+}
+
+// Returns (min(a, b), max(a, b)), executes in constant time
+//
+// This differs from the C implementation, because the C implementation
+// only works for 63-bit integers.
+//
+// Instead this implementation is based on
+// “side-channel effective overflow check of variable c”
+// from the book “Hacker's Delight” 2–13 Overflow Detection,
+// Section Unsigned Add/Subtract p. 40
+func minMaxU64(a, b *uint64) {
+ c := (^*b & *a) | ((^*b | *a) & (*b - *a))
+ c = -(c >> 63)
+ c &= *a ^ *b
+ *a ^= c
+ *b ^= c
+}
+
+// Reference: [djbsort](https://sorting.cr.yp.to/).
+func int32Sort(x []int32, n int32) {
+ if n < 2 {
+ return
+ }
+ top := int32(1)
+ for top < n-top {
+ top += top
+ }
+ for p := top; p > 0; p >>= 1 {
+ for i := int32(0); i < n-p; i++ {
+ if (i & p) == 0 {
+ minMaxI32(&x[i], &x[i+p])
+ }
+ }
+
+ i := int32(0)
+ for q := top; q > p; q >>= 1 {
+ for ; i < n-q; i++ {
+ if (i & p) == 0 {
+ a := x[i+p]
+ for r := q; r > p; r >>= 1 {
+ minMaxI32(&a, &x[i+r])
+ }
+ x[i+p] = a
+ }
+ }
+ }
+ }
+}
+
+// UInt64Sort sorts a slice of uint64
+// Reference: [djbsort](https://sorting.cr.yp.to/).
+func UInt64Sort(x []uint64, n int) {
+ if n < 2 {
+ return
+ }
+ top := 1
+ for top < n-top {
+ top += top
+ }
+ for p := top; p > 0; p >>= 1 {
+ for i := 0; i < n-p; i++ {
+ if (i & p) == 0 {
+ minMaxU64(&x[i], &x[i+p])
+ }
+ }
+
+ i := 0
+ for q := top; q > p; q >>= 1 {
+ for ; i < n-q; i++ {
+ if (i & p) == 0 {
+ a := x[i+p]
+ for r := q; r > p; r >>= 1 {
+ minMaxU64(&a, &x[i+r])
+ }
+ x[i+p] = a
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package internal
+
+import (
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/math/gf2e12"
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/math/gf2e13"
+)
+
+var ButterfliesReversal4096 = [64]byte{
+ 0, 32, 16, 48, 8, 40, 24, 56,
+ 4, 36, 20, 52, 12, 44, 28, 60,
+ 2, 34, 18, 50, 10, 42, 26, 58,
+ 6, 38, 22, 54, 14, 46, 30, 62,
+ 1, 33, 17, 49, 9, 41, 25, 57,
+ 5, 37, 21, 53, 13, 45, 29, 61,
+ 3, 35, 19, 51, 11, 43, 27, 59,
+ 7, 39, 23, 55, 15, 47, 31, 63,
+}
+
+var ButterfliesReversal = [128]byte{
+ 0, 64, 32, 96, 16, 80, 48, 112,
+ 8, 72, 40, 104, 24, 88, 56, 120,
+ 4, 68, 36, 100, 20, 84, 52, 116,
+ 12, 76, 44, 108, 28, 92, 60, 124,
+ 2, 66, 34, 98, 18, 82, 50, 114,
+ 10, 74, 42, 106, 26, 90, 58, 122,
+ 6, 70, 38, 102, 22, 86, 54, 118,
+ 14, 78, 46, 110, 30, 94, 62, 126,
+ 1, 65, 33, 97, 17, 81, 49, 113,
+ 9, 73, 41, 105, 25, 89, 57, 121,
+ 5, 69, 37, 101, 21, 85, 53, 117,
+ 13, 77, 45, 109, 29, 93, 61, 125,
+ 3, 67, 35, 99, 19, 83, 51, 115,
+ 11, 75, 43, 107, 27, 91, 59, 123,
+ 7, 71, 39, 103, 23, 87, 55, 119,
+ 15, 79, 47, 111, 31, 95, 63, 127,
+}
+
+var ButterfliesBeta = [7]uint16{2522, 7827, 7801, 8035, 6897, 8167, 3476}
+
+var RadixConversionsMask = [5][2]uint64{
+ {0x8888888888888888, 0x4444444444444444},
+ {0xC0C0C0C0C0C0C0C0, 0x3030303030303030},
+ {0xF000F000F000F000, 0x0F000F000F000F00},
+ {0xFF000000FF000000, 0x00FF000000FF0000},
+ {0xFFFF000000000000, 0x0000FFFF00000000},
+}
+
+var ButterfliesConst = [128][gf2e13.Bits]uint64{
+ {
+ 0x6969969669699696,
+ 0x9966669966999966,
+ 0x9966669966999966,
+ 0xFF0000FF00FFFF00,
+ 0xCC3333CCCC3333CC,
+ 0x9966669966999966,
+ 0x6666666666666666,
+ 0xA55AA55AA55AA55A,
+ 0xCCCC33333333CCCC,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00FF00F0FF0,
+ 0x5AA55AA5A55AA55A,
+ },
+ {
+ 0x6969969669699696,
+ 0x9966669966999966,
+ 0x9966669966999966,
+ 0xFF0000FF00FFFF00,
+ 0xCC3333CCCC3333CC,
+ 0x9966669966999966,
+ 0x6666666666666666,
+ 0xA55AA55AA55AA55A,
+ 0xCCCC33333333CCCC,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00FF00F0FF0,
+ 0x5AA55AA5A55AA55A,
+ },
+ {
+ 0xA55A5AA55AA5A55A,
+ 0x6969696996969696,
+ 0x5AA55AA5A55AA55A,
+ 0x9999999966666666,
+ 0x3C3CC3C3C3C33C3C,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xCC33CC3333CC33CC,
+ 0x0000000000000000,
+ 0x3C3C3C3C3C3C3C3C,
+ 0xAA5555AAAA5555AA,
+ 0xC33C3CC33CC3C33C,
+ 0x00FFFF0000FFFF00,
+ },
+ {
+ 0xA55A5AA55AA5A55A,
+ 0x6969696996969696,
+ 0x5AA55AA5A55AA55A,
+ 0x6666666699999999,
+ 0xC3C33C3C3C3CC3C3,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x33CC33CCCC33CC33,
+ 0x0000000000000000,
+ 0x3C3C3C3C3C3C3C3C,
+ 0xAA5555AAAA5555AA,
+ 0xC33C3CC33CC3C33C,
+ 0xFF0000FFFF0000FF,
+ },
+ {
+ 0xFFFFFFFF00000000,
+ 0xA5A5A5A55A5A5A5A,
+ 0x0FF0F00FF00F0FF0,
+ 0x9669966969966996,
+ 0x0000FFFFFFFF0000,
+ 0x33333333CCCCCCCC,
+ 0xA55A5AA55AA5A55A,
+ 0x00FFFF0000FFFF00,
+ 0x0000000000000000,
+ 0xC33CC33CC33CC33C,
+ 0x0F0FF0F00F0FF0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAA55555555AAAA,
+ },
+ {
+ 0xFFFFFFFF00000000,
+ 0xA5A5A5A55A5A5A5A,
+ 0x0FF0F00FF00F0FF0,
+ 0x6996699696699669,
+ 0xFFFF00000000FFFF,
+ 0x33333333CCCCCCCC,
+ 0x5AA5A55AA55A5AA5,
+ 0xFF0000FFFF0000FF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xC33CC33CC33CC33C,
+ 0x0F0FF0F00F0FF0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0x5555AAAAAAAA5555,
+ },
+ {
+ 0xFFFFFFFF00000000,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xF00F0FF00FF0F00F,
+ 0x6996699696699669,
+ 0x0000FFFFFFFF0000,
+ 0x33333333CCCCCCCC,
+ 0x5AA5A55AA55A5AA5,
+ 0xFF0000FFFF0000FF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xC33CC33CC33CC33C,
+ 0x0F0FF0F00F0FF0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAA55555555AAAA,
+ },
+ {
+ 0xFFFFFFFF00000000,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xF00F0FF00FF0F00F,
+ 0x9669966969966996,
+ 0xFFFF00000000FFFF,
+ 0x33333333CCCCCCCC,
+ 0xA55A5AA55AA5A55A,
+ 0x00FFFF0000FFFF00,
+ 0x0000000000000000,
+ 0xC33CC33CC33CC33C,
+ 0x0F0FF0F00F0FF0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0x5555AAAAAAAA5555,
+ },
+ {
+ 0xC33C3CC33CC3C33C,
+ 0x9966669966999966,
+ 0x9966996699669966,
+ 0x6969969669699696,
+ 0xAA55AA5555AA55AA,
+ 0x9966996699669966,
+ 0x5AA5A55A5AA5A55A,
+ 0xC3C3C3C33C3C3C3C,
+ 0x3CC33CC3C33CC33C,
+ 0x3333CCCC3333CCCC,
+ 0x9999999966666666,
+ 0xC33CC33CC33CC33C,
+ 0x6666999999996666,
+ },
+ {
+ 0x3CC3C33CC33C3CC3,
+ 0x6699996699666699,
+ 0x6699669966996699,
+ 0x6969969669699696,
+ 0xAA55AA5555AA55AA,
+ 0x9966996699669966,
+ 0xA55A5AA5A55A5AA5,
+ 0xC3C3C3C33C3C3C3C,
+ 0x3CC33CC3C33CC33C,
+ 0x3333CCCC3333CCCC,
+ 0x6666666699999999,
+ 0x3CC33CC33CC33CC3,
+ 0x9999666666669999,
+ },
+ {
+ 0xC33C3CC33CC3C33C,
+ 0x9966669966999966,
+ 0x6699669966996699,
+ 0x6969969669699696,
+ 0xAA55AA5555AA55AA,
+ 0x6699669966996699,
+ 0x5AA5A55A5AA5A55A,
+ 0x3C3C3C3CC3C3C3C3,
+ 0xC33CC33C3CC33CC3,
+ 0xCCCC3333CCCC3333,
+ 0x6666666699999999,
+ 0xC33CC33CC33CC33C,
+ 0x9999666666669999,
+ },
+ {
+ 0x3CC3C33CC33C3CC3,
+ 0x6699996699666699,
+ 0x9966996699669966,
+ 0x6969969669699696,
+ 0xAA55AA5555AA55AA,
+ 0x6699669966996699,
+ 0xA55A5AA5A55A5AA5,
+ 0x3C3C3C3CC3C3C3C3,
+ 0xC33CC33C3CC33CC3,
+ 0xCCCC3333CCCC3333,
+ 0x9999999966666666,
+ 0x3CC33CC33CC33CC3,
+ 0x6666999999996666,
+ },
+ {
+ 0xC33C3CC33CC3C33C,
+ 0x6699996699666699,
+ 0x6699669966996699,
+ 0x6969969669699696,
+ 0x55AA55AAAA55AA55,
+ 0x9966996699669966,
+ 0x5AA5A55A5AA5A55A,
+ 0xC3C3C3C33C3C3C3C,
+ 0xC33CC33C3CC33CC3,
+ 0x3333CCCC3333CCCC,
+ 0x9999999966666666,
+ 0xC33CC33CC33CC33C,
+ 0x6666999999996666,
+ },
+ {
+ 0x3CC3C33CC33C3CC3,
+ 0x9966669966999966,
+ 0x9966996699669966,
+ 0x6969969669699696,
+ 0x55AA55AAAA55AA55,
+ 0x9966996699669966,
+ 0xA55A5AA5A55A5AA5,
+ 0xC3C3C3C33C3C3C3C,
+ 0xC33CC33C3CC33CC3,
+ 0x3333CCCC3333CCCC,
+ 0x6666666699999999,
+ 0x3CC33CC33CC33CC3,
+ 0x9999666666669999,
+ },
+ {
+ 0xC33C3CC33CC3C33C,
+ 0x6699996699666699,
+ 0x9966996699669966,
+ 0x6969969669699696,
+ 0x55AA55AAAA55AA55,
+ 0x6699669966996699,
+ 0x5AA5A55A5AA5A55A,
+ 0x3C3C3C3CC3C3C3C3,
+ 0x3CC33CC3C33CC33C,
+ 0xCCCC3333CCCC3333,
+ 0x6666666699999999,
+ 0xC33CC33CC33CC33C,
+ 0x9999666666669999,
+ },
+ {
+ 0x3CC3C33CC33C3CC3,
+ 0x9966669966999966,
+ 0x6699669966996699,
+ 0x6969969669699696,
+ 0x55AA55AAAA55AA55,
+ 0x6699669966996699,
+ 0xA55A5AA5A55A5AA5,
+ 0x3C3C3C3CC3C3C3C3,
+ 0x3CC33CC3C33CC33C,
+ 0xCCCC3333CCCC3333,
+ 0x9999999966666666,
+ 0x3CC33CC33CC33CC3,
+ 0x6666999999996666,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0x55555555AAAAAAAA,
+ 0xF00FF00F0FF00FF0,
+ 0x5AA55AA5A55AA55A,
+ 0x55AAAA55AA5555AA,
+ 0xF00F0FF0F00F0FF0,
+ 0x9669699696696996,
+ 0xA55AA55AA55AA55A,
+ 0x55555555AAAAAAAA,
+ 0xCCCC33333333CCCC,
+ 0x0000FFFFFFFF0000,
+ 0xFF0000FF00FFFF00,
+ 0x6996699669966996,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0x55555555AAAAAAAA,
+ 0x0FF00FF0F00FF00F,
+ 0x5AA55AA5A55AA55A,
+ 0x55AAAA55AA5555AA,
+ 0xF00F0FF0F00F0FF0,
+ 0x9669699696696996,
+ 0x5AA55AA55AA55AA5,
+ 0x55555555AAAAAAAA,
+ 0x3333CCCCCCCC3333,
+ 0x0000FFFFFFFF0000,
+ 0x00FFFF00FF0000FF,
+ 0x9669966996699669,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0x55555555AAAAAAAA,
+ 0xF00FF00F0FF00FF0,
+ 0xA55AA55A5AA55AA5,
+ 0xAA5555AA55AAAA55,
+ 0x0FF0F00F0FF0F00F,
+ 0x9669699696696996,
+ 0x5AA55AA55AA55AA5,
+ 0xAAAAAAAA55555555,
+ 0x3333CCCCCCCC3333,
+ 0xFFFF00000000FFFF,
+ 0xFF0000FF00FFFF00,
+ 0x9669966996699669,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0x55555555AAAAAAAA,
+ 0x0FF00FF0F00FF00F,
+ 0xA55AA55A5AA55AA5,
+ 0xAA5555AA55AAAA55,
+ 0x0FF0F00F0FF0F00F,
+ 0x9669699696696996,
+ 0xA55AA55AA55AA55A,
+ 0xAAAAAAAA55555555,
+ 0xCCCC33333333CCCC,
+ 0xFFFF00000000FFFF,
+ 0x00FFFF00FF0000FF,
+ 0x6996699669966996,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0x55555555AAAAAAAA,
+ 0x0FF00FF0F00FF00F,
+ 0xA55AA55A5AA55AA5,
+ 0xAA5555AA55AAAA55,
+ 0x0FF0F00F0FF0F00F,
+ 0x6996966969969669,
+ 0xA55AA55AA55AA55A,
+ 0xAAAAAAAA55555555,
+ 0xCCCC33333333CCCC,
+ 0x0000FFFFFFFF0000,
+ 0xFF0000FF00FFFF00,
+ 0x6996699669966996,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0x55555555AAAAAAAA,
+ 0xF00FF00F0FF00FF0,
+ 0xA55AA55A5AA55AA5,
+ 0xAA5555AA55AAAA55,
+ 0x0FF0F00F0FF0F00F,
+ 0x6996966969969669,
+ 0x5AA55AA55AA55AA5,
+ 0xAAAAAAAA55555555,
+ 0x3333CCCCCCCC3333,
+ 0x0000FFFFFFFF0000,
+ 0x00FFFF00FF0000FF,
+ 0x9669966996699669,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0x55555555AAAAAAAA,
+ 0x0FF00FF0F00FF00F,
+ 0x5AA55AA5A55AA55A,
+ 0x55AAAA55AA5555AA,
+ 0xF00F0FF0F00F0FF0,
+ 0x6996966969969669,
+ 0x5AA55AA55AA55AA5,
+ 0x55555555AAAAAAAA,
+ 0x3333CCCCCCCC3333,
+ 0xFFFF00000000FFFF,
+ 0xFF0000FF00FFFF00,
+ 0x9669966996699669,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0x55555555AAAAAAAA,
+ 0xF00FF00F0FF00FF0,
+ 0x5AA55AA5A55AA55A,
+ 0x55AAAA55AA5555AA,
+ 0xF00F0FF0F00F0FF0,
+ 0x6996966969969669,
+ 0xA55AA55AA55AA55A,
+ 0x55555555AAAAAAAA,
+ 0xCCCC33333333CCCC,
+ 0xFFFF00000000FFFF,
+ 0x00FFFF00FF0000FF,
+ 0x6996699669966996,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0xAAAAAAAA55555555,
+ 0x0FF00FF0F00FF00F,
+ 0x5AA55AA5A55AA55A,
+ 0xAA5555AA55AAAA55,
+ 0xF00F0FF0F00F0FF0,
+ 0x9669699696696996,
+ 0xA55AA55AA55AA55A,
+ 0x55555555AAAAAAAA,
+ 0xCCCC33333333CCCC,
+ 0x0000FFFFFFFF0000,
+ 0xFF0000FF00FFFF00,
+ 0x6996699669966996,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0xAAAAAAAA55555555,
+ 0xF00FF00F0FF00FF0,
+ 0x5AA55AA5A55AA55A,
+ 0xAA5555AA55AAAA55,
+ 0xF00F0FF0F00F0FF0,
+ 0x9669699696696996,
+ 0x5AA55AA55AA55AA5,
+ 0x55555555AAAAAAAA,
+ 0x3333CCCCCCCC3333,
+ 0x0000FFFFFFFF0000,
+ 0x00FFFF00FF0000FF,
+ 0x9669966996699669,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0xAAAAAAAA55555555,
+ 0x0FF00FF0F00FF00F,
+ 0xA55AA55A5AA55AA5,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00F0FF0F00F,
+ 0x9669699696696996,
+ 0x5AA55AA55AA55AA5,
+ 0xAAAAAAAA55555555,
+ 0x3333CCCCCCCC3333,
+ 0xFFFF00000000FFFF,
+ 0xFF0000FF00FFFF00,
+ 0x9669966996699669,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0xAAAAAAAA55555555,
+ 0xF00FF00F0FF00FF0,
+ 0xA55AA55A5AA55AA5,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00F0FF0F00F,
+ 0x9669699696696996,
+ 0xA55AA55AA55AA55A,
+ 0xAAAAAAAA55555555,
+ 0xCCCC33333333CCCC,
+ 0xFFFF00000000FFFF,
+ 0x00FFFF00FF0000FF,
+ 0x6996699669966996,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0xAAAAAAAA55555555,
+ 0xF00FF00F0FF00FF0,
+ 0xA55AA55A5AA55AA5,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00F0FF0F00F,
+ 0x6996966969969669,
+ 0xA55AA55AA55AA55A,
+ 0xAAAAAAAA55555555,
+ 0xCCCC33333333CCCC,
+ 0x0000FFFFFFFF0000,
+ 0xFF0000FF00FFFF00,
+ 0x6996699669966996,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0xAAAAAAAA55555555,
+ 0x0FF00FF0F00FF00F,
+ 0xA55AA55A5AA55AA5,
+ 0x55AAAA55AA5555AA,
+ 0x0FF0F00F0FF0F00F,
+ 0x6996966969969669,
+ 0x5AA55AA55AA55AA5,
+ 0xAAAAAAAA55555555,
+ 0x3333CCCCCCCC3333,
+ 0x0000FFFFFFFF0000,
+ 0x00FFFF00FF0000FF,
+ 0x9669966996699669,
+ },
+ {
+ 0x3C3CC3C3C3C33C3C,
+ 0xAAAAAAAA55555555,
+ 0xF00FF00F0FF00FF0,
+ 0x5AA55AA5A55AA55A,
+ 0xAA5555AA55AAAA55,
+ 0xF00F0FF0F00F0FF0,
+ 0x6996966969969669,
+ 0x5AA55AA55AA55AA5,
+ 0x55555555AAAAAAAA,
+ 0x3333CCCCCCCC3333,
+ 0xFFFF00000000FFFF,
+ 0xFF0000FF00FFFF00,
+ 0x9669966996699669,
+ },
+ {
+ 0xC3C33C3C3C3CC3C3,
+ 0xAAAAAAAA55555555,
+ 0x0FF00FF0F00FF00F,
+ 0x5AA55AA5A55AA55A,
+ 0xAA5555AA55AAAA55,
+ 0xF00F0FF0F00F0FF0,
+ 0x6996966969969669,
+ 0xA55AA55AA55AA55A,
+ 0x55555555AAAAAAAA,
+ 0xCCCC33333333CCCC,
+ 0xFFFF00000000FFFF,
+ 0x00FFFF00FF0000FF,
+ 0x6996699669966996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0xAAAAAAAAAAAAAAAA,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0x0000FFFF0000FFFF,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0xC33C3CC3C33C3CC3,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0x55AA55AA55AA55AA,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0xFFFF0000FFFF0000,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x00FFFF00FF0000FF,
+ 0xCC3333CC33CCCC33,
+ 0xFF0000FF00FFFF00,
+ 0x6996966996696996,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x3CC3C33C3CC3C33C,
+ 0x5555555555555555,
+ 0xFFFF0000FFFF0000,
+ 0x3CC3C33C3CC3C33C,
+ 0xAA55AA55AA55AA55,
+ 0x0000FFFF0000FFFF,
+ 0xF0F0F0F00F0F0F0F,
+ 0xFF0000FF00FFFF00,
+ 0x33CCCC33CC3333CC,
+ 0x00FFFF00FF0000FF,
+ 0x9669699669969669,
+ 0xA55A5AA55AA5A55A,
+ 0x6996966996696996,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+}
+
+var RadixConversionsS = [5][2][gf2e13.Bits]uint64{
+ {
+ {
+ 0x3C3CF30C0000C003,
+ 0x0CCCC3F333C0000C,
+ 0x03C33F33FCC0C03C,
+ 0x0003000F3C03C0C0,
+ 0xF33FF33030CF03F0,
+ 0x0CF0303300F0CCC0,
+ 0xFF3F0C0CC0FF3CC0,
+ 0xCF3CF0FF003FC000,
+ 0xC00FF3CF0303F300,
+ 0x3CCC0CC00CF0CC00,
+ 0xF30FFC3C3FCCFC00,
+ 0x3F0FC3F0CCF0C000,
+ 0x3000FF33CCF0F000,
+ },
+ {
+ 0x0C0F0FCF0F0CF330,
+ 0xF0000FC33C3CCF3C,
+ 0x3C0F3F00C3C300FC,
+ 0x3C33CCC0F0F3CC30,
+ 0xC0CFFFFFCCCC30CC,
+ 0x3FC3F3CCFFFC033F,
+ 0xFC3030CCCCC0CFCF,
+ 0x0FCF0C00CCF333C3,
+ 0xCFFCF33000CFF030,
+ 0x00CFFCC330F30FCC,
+ 0x3CCC3FCCC0F3FFF3,
+ 0xF00F0C3FC003C0FF,
+ 0x330CCFCC03C0FC33,
+ },
+ },
+ {
+ {
+ 0x0F0F0FF0F000000F,
+ 0x00FFFFFFFF0000F0,
+ 0xFFFF00FF00000F00,
+ 0xFFF000F00F0FF000,
+ 0xFFF0000F0FF000F0,
+ 0x00FF000FFF000000,
+ 0xFF0F0FFF0F0FF000,
+ 0x0FFF0000000F0000,
+ 0x00F000F0FFF00F00,
+ 0x00F00FF00F00F000,
+ 0xFFF000F000F00000,
+ 0x00F00F000FF00000,
+ 0x0000FF0F0000F000,
+ },
+ {
+ 0xF0FFFFFFF0F00F00,
+ 0x00FFF0FFFF0000FF,
+ 0x00FF00000F0F0FFF,
+ 0xF000F0000F00FF0F,
+ 0xFF000000FFF00000,
+ 0xF0FF000FF00F0FF0,
+ 0x0F0F0F00FF000F0F,
+ 0x0F0F00F0F0F0F000,
+ 0x00F00F00F00F000F,
+ 0x00F0F0F00000FFF0,
+ 0xFFFFFF0FF00F0FFF,
+ 0x0F0FFFF00FFFFFFF,
+ 0xFFFF0F0FFF0FFF00,
+ },
+ },
+ {
+ {
+ 0x00FF0000000000FF,
+ 0xFFFFFFFFFF00FF00,
+ 0xFF0000FF00FF0000,
+ 0xFFFF000000FF0000,
+ 0xFF00000000FF0000,
+ 0x00FFFFFFFF000000,
+ 0xFF0000FFFFFF0000,
+ 0xFF00FF00FFFF0000,
+ 0x00FFFFFFFF00FF00,
+ 0xFFFF000000000000,
+ 0x00FF0000FF000000,
+ 0xFF00FF00FF000000,
+ 0x00FF00FFFF000000,
+ },
+ {
+ 0x00FF00FF00FF0000,
+ 0xFF00FFFF000000FF,
+ 0x0000FFFF000000FF,
+ 0x00FFFF00FF000000,
+ 0xFFFFFF0000FF00FF,
+ 0x0000FFFF00FFFF00,
+ 0xFF00FF0000FFFF00,
+ 0x00000000FFFFFFFF,
+ 0x0000FF0000000000,
+ 0xFF00FFFF00FFFF00,
+ 0x00FFFF00000000FF,
+ 0x0000FF00FF00FFFF,
+ 0xFF0000FFFFFF0000,
+ },
+ },
+ {
+ {
+ 0x000000000000FFFF,
+ 0xFFFFFFFFFFFF0000,
+ 0x0000000000000000,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFF0000,
+ 0x0000FFFF00000000,
+ 0x0000FFFFFFFF0000,
+ 0xFFFF0000FFFF0000,
+ 0x0000FFFF00000000,
+ 0xFFFF000000000000,
+ 0xFFFF000000000000,
+ 0xFFFF000000000000,
+ 0xFFFFFFFF00000000,
+ },
+ {
+ 0x0000FFFF00000000,
+ 0xFFFFFFFF0000FFFF,
+ 0x00000000FFFFFFFF,
+ 0x0000000000000000,
+ 0x0000FFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0x0000FFFFFFFF0000,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFF0000FFFF,
+ 0x00000000FFFF0000,
+ 0xFFFF0000FFFFFFFF,
+ 0xFFFF0000FFFFFFFF,
+ 0x0000000000000000,
+ },
+ },
+ {
+ {
+ 0x00000000FFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x00000000FFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00000000FFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ },
+ },
+}
+
+var RadixConversionsS4096 = [5][gf2e12.Bits]uint64{
+ {
+ 0xF3CFC030FC30F003,
+ 0x3FCF0F003C00C00C,
+ 0x30033CC300C0C03C,
+ 0xCCFF0F3C0F30F0C0,
+ 0x0300C03FF303C3F0,
+ 0x3FFF3C0FF0CCCCC0,
+ 0xF3FFF0C00F3C3CC0,
+ 0x3003333FFFC3C000,
+ 0x0FF30FFFC3FFF300,
+ 0xFFC0F300F0F0CC00,
+ 0xC0CFF3FCCC3CFC00,
+ 0xFC3C03F0F330C000,
+ },
+ {
+ 0x000F00000000F00F,
+ 0x00000F00F00000F0,
+ 0x0F00000F00000F00,
+ 0xF00F00F00F000000,
+ 0x00F00000000000F0,
+ 0x0000000F00000000,
+ 0xF00000000F00F000,
+ 0x00F00F00000F0000,
+ 0x0000F00000F00F00,
+ 0x000F00F00F00F000,
+ 0x00F00F0000000000,
+ 0x0000000000F00000,
+ },
+ {
+ 0x0000FF00FF0000FF,
+ 0x0000FF000000FF00,
+ 0xFF0000FF00FF0000,
+ 0xFFFF0000FF000000,
+ 0x00FF00FF00FF0000,
+ 0x0000FFFFFF000000,
+ 0x00FFFF00FF000000,
+ 0xFFFFFF0000FF0000,
+ 0xFFFF00FFFF00FF00,
+ 0x0000FF0000000000,
+ 0xFFFFFF00FF000000,
+ 0x00FF000000000000,
+ },
+ {
+ 0x000000000000FFFF,
+ 0x00000000FFFF0000,
+ 0x0000000000000000,
+ 0xFFFF000000000000,
+ 0x00000000FFFF0000,
+ 0x0000FFFF00000000,
+ 0x0000000000000000,
+ 0x00000000FFFF0000,
+ 0x0000FFFF00000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ },
+ {
+ 0x00000000FFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ },
+}
+
+var ButterfliesConsts4096 = [63][gf2e12.Bits]uint64{
+ // 64
+ {
+ 0xF00F0FF0F00F0FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0x0FF00FF00FF00FF0,
+ 0xAA5555AAAA5555AA,
+ 0xF00F0FF0F00F0FF0,
+ 0x33CCCC33CC3333CC,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC3333CC33CC,
+ 0x33CC33CC33CC33CC,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xFF00FF00FF00FF00,
+ 0xF00F0FF0F00F0FF0,
+ },
+ // 128
+ {
+ 0x3C3C3C3C3C3C3C3C,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x5555AAAA5555AAAA,
+ 0xCC3333CCCC3333CC,
+ 0xC33CC33CC33CC33C,
+ 0x55555555AAAAAAAA,
+ 0x33333333CCCCCCCC,
+ 0x00FF00FFFF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x0000FFFFFFFF0000,
+ 0xF0F00F0F0F0FF0F0,
+ },
+ {
+ 0x3C3C3C3C3C3C3C3C,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xAAAA5555AAAA5555,
+ 0xCC3333CCCC3333CC,
+ 0xC33CC33CC33CC33C,
+ 0x55555555AAAAAAAA,
+ 0x33333333CCCCCCCC,
+ 0xFF00FF0000FF00FF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x0000FFFFFFFF0000,
+ 0xF0F00F0F0F0FF0F0,
+ },
+ // 256
+ {
+ 0xAA55AA5555AA55AA,
+ 0xCC33CC3333CC33CC,
+ 0x33CCCC33CC3333CC,
+ 0x55555555AAAAAAAA,
+ 0xFF0000FF00FFFF00,
+ 0x3CC33CC3C33CC33C,
+ 0x5555AAAA5555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xCCCC33333333CCCC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x00FFFF0000FFFF00,
+ 0xC33CC33CC33CC33C,
+ },
+ {
+ 0x55AA55AAAA55AA55,
+ 0xCC33CC3333CC33CC,
+ 0xCC3333CC33CCCC33,
+ 0x55555555AAAAAAAA,
+ 0xFF0000FF00FFFF00,
+ 0xC33CC33C3CC33CC3,
+ 0xAAAA5555AAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x3333CCCCCCCC3333,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFF0000FFFF0000FF,
+ 0xC33CC33CC33CC33C,
+ },
+ {
+ 0xAA55AA5555AA55AA,
+ 0x33CC33CCCC33CC33,
+ 0xCC3333CC33CCCC33,
+ 0x55555555AAAAAAAA,
+ 0x00FFFF00FF0000FF,
+ 0x3CC33CC3C33CC33C,
+ 0x5555AAAA5555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x3333CCCCCCCC3333,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x00FFFF0000FFFF00,
+ 0xC33CC33CC33CC33C,
+ },
+ {
+ 0x55AA55AAAA55AA55,
+ 0x33CC33CCCC33CC33,
+ 0x33CCCC33CC3333CC,
+ 0x55555555AAAAAAAA,
+ 0x00FFFF00FF0000FF,
+ 0xC33CC33C3CC33CC3,
+ 0xAAAA5555AAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xCCCC33333333CCCC,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFF0000FFFF0000FF,
+ 0xC33CC33CC33CC33C,
+ },
+ // 512
+ {
+ 0x6699669999669966,
+ 0x33CCCC33CC3333CC,
+ 0xA5A5A5A55A5A5A5A,
+ 0x3C3CC3C3C3C33C3C,
+ 0xF00FF00F0FF00FF0,
+ 0x55AA55AA55AA55AA,
+ 0x3C3CC3C3C3C33C3C,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x55AA55AA55AA55AA,
+ 0x33CCCC33CC3333CC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x9966996666996699,
+ 0x33CCCC33CC3333CC,
+ 0xA5A5A5A55A5A5A5A,
+ 0x3C3CC3C3C3C33C3C,
+ 0x0FF00FF0F00FF00F,
+ 0xAA55AA55AA55AA55,
+ 0x3C3CC3C3C3C33C3C,
+ 0xF0F0F0F00F0F0F0F,
+ 0xAA55AA55AA55AA55,
+ 0xCC3333CC33CCCC33,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x6699669999669966,
+ 0x33CCCC33CC3333CC,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xC3C33C3C3C3CC3C3,
+ 0x0FF00FF0F00FF00F,
+ 0xAA55AA55AA55AA55,
+ 0xC3C33C3C3C3CC3C3,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xAA55AA55AA55AA55,
+ 0x33CCCC33CC3333CC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x9966996666996699,
+ 0x33CCCC33CC3333CC,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xC3C33C3C3C3CC3C3,
+ 0xF00FF00F0FF00FF0,
+ 0x55AA55AA55AA55AA,
+ 0xC3C33C3C3C3CC3C3,
+ 0xF0F0F0F00F0F0F0F,
+ 0x55AA55AA55AA55AA,
+ 0xCC3333CC33CCCC33,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x6699669999669966,
+ 0xCC3333CC33CCCC33,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x3C3CC3C3C3C33C3C,
+ 0x0FF00FF0F00FF00F,
+ 0x55AA55AA55AA55AA,
+ 0x3C3CC3C3C3C33C3C,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x55AA55AA55AA55AA,
+ 0x33CCCC33CC3333CC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x9966996666996699,
+ 0xCC3333CC33CCCC33,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x3C3CC3C3C3C33C3C,
+ 0xF00FF00F0FF00FF0,
+ 0xAA55AA55AA55AA55,
+ 0x3C3CC3C3C3C33C3C,
+ 0xF0F0F0F00F0F0F0F,
+ 0xAA55AA55AA55AA55,
+ 0xCC3333CC33CCCC33,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x6699669999669966,
+ 0xCC3333CC33CCCC33,
+ 0xA5A5A5A55A5A5A5A,
+ 0xC3C33C3C3C3CC3C3,
+ 0xF00FF00F0FF00FF0,
+ 0xAA55AA55AA55AA55,
+ 0xC3C33C3C3C3CC3C3,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xAA55AA55AA55AA55,
+ 0x33CCCC33CC3333CC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xA55A5AA55AA5A55A,
+ },
+ {
+ 0x9966996666996699,
+ 0xCC3333CC33CCCC33,
+ 0xA5A5A5A55A5A5A5A,
+ 0xC3C33C3C3C3CC3C3,
+ 0x0FF00FF0F00FF00F,
+ 0x55AA55AA55AA55AA,
+ 0xC3C33C3C3C3CC3C3,
+ 0xF0F0F0F00F0F0F0F,
+ 0x55AA55AA55AA55AA,
+ 0xCC3333CC33CCCC33,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xA55A5AA55AA5A55A,
+ },
+ // 1024
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x6996699669966996,
+ 0x00FFFF0000FFFF00,
+ 0xFF00FF00FF00FF00,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x6996699669966996,
+ 0x00FFFF0000FFFF00,
+ 0x00FF00FF00FF00FF,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x6996699669966996,
+ 0xFF0000FFFF0000FF,
+ 0x00FF00FF00FF00FF,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x6996699669966996,
+ 0xFF0000FFFF0000FF,
+ 0xFF00FF00FF00FF00,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x9669966996699669,
+ 0xFF0000FFFF0000FF,
+ 0x00FF00FF00FF00FF,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x9669966996699669,
+ 0xFF0000FFFF0000FF,
+ 0xFF00FF00FF00FF00,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x9669966996699669,
+ 0x00FFFF0000FFFF00,
+ 0xFF00FF00FF00FF00,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x6996699669966996,
+ 0x9669966996699669,
+ 0x00FFFF0000FFFF00,
+ 0x00FF00FF00FF00FF,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x9669966996699669,
+ 0x00FFFF0000FFFF00,
+ 0xFF00FF00FF00FF00,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x9669966996699669,
+ 0x00FFFF0000FFFF00,
+ 0x00FF00FF00FF00FF,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x9669966996699669,
+ 0xFF0000FFFF0000FF,
+ 0x00FF00FF00FF00FF,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x9669966996699669,
+ 0xFF0000FFFF0000FF,
+ 0xFF00FF00FF00FF00,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x6996699669966996,
+ 0xFF0000FFFF0000FF,
+ 0x00FF00FF00FF00FF,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x6996699669966996,
+ 0xFF0000FFFF0000FF,
+ 0xFF00FF00FF00FF00,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x6996699669966996,
+ 0x00FFFF0000FFFF00,
+ 0xFF00FF00FF00FF00,
+ 0x0FF00FF0F00FF00F,
+ 0x0F0FF0F0F0F00F0F,
+ 0xC33C3CC33CC3C33C,
+ 0xC33C3CC33CC3C33C,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ {
+ 0x9669699696696996,
+ 0x9669966996699669,
+ 0x6996699669966996,
+ 0x00FFFF0000FFFF00,
+ 0x00FF00FF00FF00FF,
+ 0xF00FF00F0FF00FF0,
+ 0xF0F00F0F0F0FF0F0,
+ 0x3CC3C33CC33C3CC3,
+ 0x3CC3C33CC33C3CC3,
+ 0xA55A5AA55AA5A55A,
+ 0xC33C3CC33CC3C33C,
+ 0x3CC3C33C3CC3C33C,
+ },
+ // 2048
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0000000000000000,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0000000000000000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFF00000000,
+ 0xFFFF0000FFFF0000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+}
--- /dev/null
+package internal
+
+import (
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/math/gf2e12"
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/math/gf2e13"
+)
+
+var Powers4096 = [64][gf2e12.Bits]uint64{
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x3333CCCC3333CCCC,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0x0000000000000000,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0xFF00FF00FF00FF00,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0xAAAAAAAAAAAAAAAA,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0xF0F0F0F00F0F0F0F,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0x0000000000000000,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0xAA55AA55AA55AA55,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+ {
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000FFFF0000FFFF,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x0F0F0F0F0F0F0F0F,
+ 0xFFFFFFFFFFFFFFFF,
+ 0x55AA55AA55AA55AA,
+ 0x0F0F0F0FF0F0F0F0,
+ 0x0000000000000000,
+ 0x00FF00FF00FF00FF,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xCCCC3333CCCC3333,
+ 0x5555555555555555,
+ },
+}
+
+var Powers8192 = [128][gf2e13.Bits]uint64{
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0x00000000FFFFFFFF,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0x5A5A5A5A5A5A5A5A,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0xCC33CC33CC33CC33,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0xCC33CC33CC33CC33,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x9696969669696969,
+ 0xA5A5A5A5A5A5A5A5,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0x0F0FF0F00F0FF0F0,
+ },
+ {
+ 0xA55AA55A5AA55AA5,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0x5A5A5A5A5A5A5A5A,
+ 0xA5A5A5A55A5A5A5A,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0x3CC33CC3C33CC33C,
+ 0xA5A55A5AA5A55A5A,
+ 0x0000FFFF0000FFFF,
+ 0x33CC33CC33CC33CC,
+ 0xF00FF00F0FF00FF0,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0x5555AAAAAAAA5555,
+ 0xF00FF00FF00FF00F,
+ 0xF0F00F0FF0F00F0F,
+ },
+ {
+ 0x5AA55AA5A55AA55A,
+ 0xC33CC33C3CC33CC3,
+ 0xA5A55A5AA5A55A5A,
+ 0xFFFF0000FFFF0000,
+ 0x33CC33CC33CC33CC,
+ 0x0FF00FF0F00FF00F,
+ 0xFFFFFFFF00000000,
+ 0x6969696996969696,
+ 0xA5A5A5A5A5A5A5A5,
+ 0x5A5A5A5AA5A5A5A5,
+ 0xAAAA55555555AAAA,
+ 0x0FF00FF00FF00FF0,
+ 0x0F0FF0F00F0FF0F0,
+ },
+}
--- /dev/null
+// Package gf2e12 provides finite field arithmetic over GF(2^12).
+package gf2e12
+
+// Elt is a field element of characteristic 2 modulo z^12 + z^3 + 1
+type Elt = uint16
+
+const (
+ Bits = 12
+ Mask = (1 << Bits) - 1
+)
+
+// Add two Elt elements together. Since an addition in Elt(2) is the same as XOR,
+// this implementation uses a simple XOR for addition.
+func Add(a, b Elt) Elt {
+ return a ^ b
+}
+
+// Mul calculate the product of two Elt elements.
+func Mul(a, b Elt) Elt {
+ a64 := uint64(a)
+ b64 := uint64(b)
+
+ // if the LSB of b is 1, set tmp to a64, and 0 otherwise
+ tmp := a64 & -(b64 & 1)
+
+ // check if i-th bit of b64 is set, add a64 shifted by i bits if so
+ for i := 1; i < Bits; i++ {
+ tmp ^= a64 * (b64 & (1 << i))
+ }
+
+ // polynomial reduction
+ t := tmp & 0x7FC000
+ tmp ^= t >> 9
+ tmp ^= t >> 12
+
+ t = tmp & 0x3000
+ tmp ^= t >> 9
+ tmp ^= t >> 12
+
+ return Elt(tmp & Mask)
+}
+
+// sqr calculates the square of Elt element a
+func sqr(a Elt) Elt {
+ a32 := uint32(a)
+ a32 = (a32 | (a32 << 8)) & 0x00FF00FF
+ a32 = (a32 | (a32 << 4)) & 0x0F0F0F0F
+ a32 = (a32 | (a32 << 2)) & 0x33333333
+ a32 = (a32 | (a32 << 1)) & 0x55555555
+
+ t := a32 & 0x7FC000
+ a32 ^= t >> 9
+ a32 ^= t >> 12
+
+ t = a32 & 0x3000
+ a32 ^= t >> 9
+ a32 ^= t >> 12
+
+ return uint16(a32 & Mask)
+}
+
+// Inv calculates the multiplicative inverse of Elt element a
+func Inv(a Elt) Elt {
+ out := sqr(a)
+ tmp3 := Mul(out, a) // a^3
+
+ out = sqr(sqr(tmp3))
+ tmp15 := Mul(out, tmp3) // a^15 = a^(3*2*2 + 3)
+
+ out = sqr(sqr(sqr(sqr(tmp15))))
+ out = Mul(out, tmp15) // a^255 = a^(15*2*2*2*2 + 15)
+
+ out = sqr(sqr(out))
+ out = Mul(out, tmp3) // a^1023 = a^(255*2*2 + 3)
+
+ out = Mul(sqr(out), a) // a^2047 = a^(1023*2 + 1)
+ return sqr(out) // a^4094 = a^(2047 * 2)
+}
+
+// Div calculates a / b
+func Div(a, b Elt) Elt {
+ return Mul(Inv(b), a)
+}
--- /dev/null
+// Package gf2e13 provides finite field arithmetic over GF(2^13).
+package gf2e13
+
+// Elt is a field element of characteristic 2 modulo z^13 + z^4 + z^3 + z + 1
+type Elt = uint16
+
+const (
+ Bits = 13
+ Mask = (1 << Bits) - 1
+)
+
+// Add two Elt elements together. Since an addition in Elt(2) is the same as XOR,
+// this implementation uses a simple XOR for addition.
+func Add(a, b Elt) Elt {
+ return a ^ b
+}
+
+// Mul calculate the product of two Elt elements.
+func Mul(a, b Elt) Elt {
+ a64 := uint64(a)
+ b64 := uint64(b)
+
+ // if the LSB of b is 1, set tmp to a64, and 0 otherwise
+ tmp := a64 & -(b64 & 1)
+
+ // check if i-th bit of b64 is set, add a64 shifted by i bits if so
+ for i := 1; i < Bits; i++ {
+ tmp ^= a64 * (b64 & (1 << i))
+ }
+
+ // polynomial reduction
+ t := tmp & 0x1FF0000
+ tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+
+ t = tmp & 0x000E000
+ tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+
+ return uint16(tmp & Mask)
+}
+
+// sqr2 calculates a^4
+func sqr2(a Elt) Elt {
+ a64 := uint64(a)
+ a64 = (a64 | (a64 << 24)) & 0x000000FF000000FF
+ a64 = (a64 | (a64 << 12)) & 0x000F000F000F000F
+ a64 = (a64 | (a64 << 6)) & 0x0303030303030303
+ a64 = (a64 | (a64 << 3)) & 0x1111111111111111
+
+ t := a64 & 0x0001FF0000000000
+ a64 ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = a64 & 0x000000FF80000000
+ a64 ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = a64 & 0x000000007FC00000
+ a64 ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = a64 & 0x00000000003FE000
+ a64 ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+
+ return uint16(a64 & Mask)
+}
+
+// sqrMul calculates the product of a^2 and b
+func sqrMul(a, b Elt) Elt {
+ a64 := uint64(a)
+ b64 := uint64(b)
+
+ x := (b64 << 6) * (a64 & (1 << 6))
+ a64 ^= a64 << 7
+ x ^= b64 * (a64 & (0x04001))
+ x ^= (b64 * (a64 & (0x08002))) << 1
+ x ^= (b64 * (a64 & (0x10004))) << 2
+ x ^= (b64 * (a64 & (0x20008))) << 3
+ x ^= (b64 * (a64 & (0x40010))) << 4
+ x ^= (b64 * (a64 & (0x80020))) << 5
+
+ t := x & 0x0000001FF0000000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x000000000FF80000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x000000000007E000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+
+ return uint16(x & Mask)
+}
+
+// sqr2Mul calculates the product of a^4 and b
+func sqr2Mul(a, b Elt) Elt {
+ a64 := uint64(a)
+ b64 := uint64(b)
+
+ x := (b64 << 18) * (a64 & (1 << 6))
+ a64 ^= a64 << 21
+ x ^= b64 * (a64 & (0x010000001))
+ x ^= (b64 * (a64 & (0x020000002))) << 3
+ x ^= (b64 * (a64 & (0x040000004))) << 6
+ x ^= (b64 * (a64 & (0x080000008))) << 9
+ x ^= (b64 * (a64 & (0x100000010))) << 12
+ x ^= (b64 * (a64 & (0x200000020))) << 15
+
+ t := x & 0x1FF0000000000000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x000FF80000000000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x000007FC00000000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x00000003FE000000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x0000000001FE0000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+ t = x & 0x000000000001E000
+ x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13)
+
+ return uint16(x & Mask)
+}
+
+// Inv calculates the multiplicative inverse of Elt element a
+func Inv(a Elt) Elt {
+ return Div(1, a)
+}
+
+// Div calculates a / b
+func Div(a, b Elt) Elt {
+ tmp3 := sqrMul(b, b) // b^3
+ tmp15 := sqr2Mul(tmp3, tmp3) // b^15 = b^(3*2*2+3)
+ out := sqr2(tmp15)
+ out = sqr2Mul(out, tmp15) // b^255 = b^(15*4*4+15)
+ out = sqr2(out)
+ out = sqr2Mul(out, tmp15) // b^4095 = b^(255*2*2*2*2+15)
+
+ return sqrMul(out, a) // b^8190 = b^(4095*2) = b^-1
+}
--- /dev/null
+// Code generated from mceliece.templ.go. DO NOT EDIT.
+
+// Package mceliece6960119 implements the IND-CCA2 secure key encapsulation mechanism
+// mceliece6960119 as submitted to round 4 of the NIST PQC competition and
+// described in
+//
+// https://classic.mceliece.org/nist/mceliece-20201010.pdf
+//
+// The following code is translated from the C reference implementation, and
+// from a Rust implementation by Bernhard Berg, Lukas Prokop, Daniel Kales
+// where direct translation from C is not applicable.
+//
+// https://github.com/Colfenor/classic-mceliece-rust
+package mceliece6960119
+
+import (
+ cryptoRand "crypto/rand"
+ "crypto/sha3"
+ "errors"
+ "fmt"
+ "io"
+
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/internal"
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119/math/gf2e13"
+)
+
+const (
+ sysT = 119 // F(y) is 64 degree
+ gfBits = gf2e13.Bits
+ gfMask = gf2e13.Mask
+ unusedBits = 16 - gfBits
+ sysN = 6960
+ condBytes = (1 << (gfBits - 4)) * (2*gfBits - 1)
+ irrBytes = sysT * 2
+ pkNRows = sysT * gfBits
+ pkNCols = sysN - pkNRows
+ pkRowBytes = (pkNCols + 7) / 8
+ syndBytes = (pkNRows + 7) / 8
+ PublicKeySize = 1047319
+ PrivateKeySize = 13948
+ CiphertextSize = 194
+ SharedKeySize = 32
+ seedSize = 32
+ encapsulationSeedSize = 48
+)
+
+var (
+ ErrCiphertextSize = errors.New("wrong size for ciphertext")
+ ErrPubKeySize = errors.New("wrong size for public key")
+ ErrPrivKeySize = errors.New("wrong size for private key")
+)
+
+type PublicKey struct {
+ pk [PublicKeySize]byte
+}
+
+type PrivateKey struct {
+ sk [PrivateKeySize]byte
+}
+
+type (
+ gf = gf2e13.Elt
+ randFunc = func(pool []byte) error
+)
+
+// KEM Keypair generation.
+//
+// The structure of the secret key is given by the following segments:
+// (32 bytes seed, 8 bytes pivots, IRR_BYTES bytes, COND_BYTES bytes, SYS_N/8 bytes).
+// The structure of the public key is simple: a matrix of PK_NROWS times PK_ROW_BYTES bytes.
+//
+// `entropy` corresponds to the l-bit input seed in SeededKeyGen from the specification.
+// The keypair is deterministically generated from `entropy`.
+// If the generated keypair is invalid, a new seed will be generated by hashing `entropy` to try again.
+func deriveKeyPair(entropy []byte) (*PublicKey, *PrivateKey) {
+ const (
+ irrPolys = sysN/8 + (1<<gfBits)*4
+ seedIndex = sysN/8 + (1<<gfBits)*4 + sysT*2
+ permIndex = sysN / 8
+ sBase = 32 + 8 + irrBytes + condBytes
+ )
+
+ var (
+ pk [PublicKeySize]byte
+ sk [PrivateKeySize]byte
+ )
+
+ seed := [33]byte{64}
+ r := [sysN/8 + (1<<gfBits)*4 + sysT*2 + 32]byte{}
+
+ f := [sysT]gf{}
+ irr := [sysT]gf{}
+ perm := [1 << gfBits]uint32{}
+ pi := [1 << gfBits]int16{}
+ pivots := uint64(0xFFFFFFFF)
+
+ copy(seed[1:], entropy[:])
+
+ for {
+ // expanding and updating the seed
+ err := shake256(r[:], seed[0:33])
+ if err != nil {
+ panic(err)
+ }
+
+ copy(sk[:32], seed[1:])
+ copy(seed[1:], r[len(r)-32:])
+
+ temp := r[irrPolys:seedIndex]
+ for i := 0; i < sysT; i++ {
+ f[i] = loadGf(temp)
+ temp = temp[2:]
+ }
+
+ if !minimalPolynomial(&irr, &f) {
+ continue
+ }
+
+ temp = sk[40 : 40+irrBytes]
+ for i := 0; i < sysT; i++ {
+ storeGf(temp, irr[i])
+ temp = temp[2:]
+ }
+
+ // generating permutation
+ temp = r[permIndex:irrPolys]
+ for i := 0; i < 1<<gfBits; i++ {
+ perm[i] = load4(temp)
+ temp = temp[4:]
+ }
+
+ if !pkGen(&pk, sk[40:40+irrBytes], &perm, &pi, &pivots) {
+ continue
+ }
+
+ internal.ControlBitsFromPermutation(sk[32+8+irrBytes:], pi[:], gfBits, 1<<gfBits)
+ copy(sk[sBase:sBase+sysN/8], r[0:sysN/8])
+ store8(sk[32:40], pivots)
+ return &PublicKey{pk: pk}, &PrivateKey{sk: sk}
+ }
+}
+
+// Encryption routine.
+// Takes a public key `pk` to compute error vector `e` and syndrome `s`.
+func encrypt(s *[CiphertextSize]byte, pk *[PublicKeySize]byte, e *[sysN / 8]byte, rand randFunc) error {
+ err := genE(e, rand)
+ if err != nil {
+ return err
+ }
+ syndrome(s, pk, e)
+ return nil
+}
+
+// KEM Encapsulation.
+//
+// Given a public key `pk`, sample a shared key.
+// This shared key is returned through parameter `key` whereas
+// the ciphertext (meant to be used for decapsulation) is returned as `c`.
+func kemEncapsulate(c *[CiphertextSize]byte, key *[SharedKeySize]byte, pk *[PublicKeySize]byte, rand randFunc) error {
+ e := [sysN / 8]byte{}
+ oneEC := [1 + sysN/8 + syndBytes]byte{1}
+
+ paddingOk := checkPkPadding(pk)
+
+ err := encrypt(c, pk, &e, rand)
+ if err != nil {
+ return err
+ }
+ copy(oneEC[1:1+sysN/8], e[:sysN/8])
+ copy(oneEC[1+sysN/8:1+sysN/8+syndBytes], c[:syndBytes])
+ err = shake256(key[0:32], oneEC[:])
+ if err != nil {
+ return err
+ }
+
+ mask := paddingOk ^ 0xFF
+ for i := 0; i < syndBytes; i++ {
+ c[i] &= mask
+ }
+ for i := 0; i < 32; i++ {
+ key[i] &= mask
+ }
+
+ if paddingOk == 0 {
+ return nil
+ }
+ return fmt.Errorf("public key padding error %d", paddingOk)
+}
+
+// KEM Decapsulation.
+//
+// Given a secret key `sk` and a ciphertext `c`,
+// determine the shared text `key` negotiated by both parties.
+func kemDecapsulate(key *[SharedKeySize]byte, c *[CiphertextSize]byte, sk *[PrivateKeySize]byte) error {
+ e := [sysN / 8]byte{}
+ preimage := [1 + sysN/8 + syndBytes]byte{}
+ s := sk[40+irrBytes+condBytes:]
+
+ paddingOk := checkCPadding(c)
+
+ retDecrypt := decrypt((*[sysN / 8]byte)(e[:sysN/8]), sk[40:], (*[syndBytes]byte)(c[:syndBytes]))
+ m := retDecrypt
+ m -= 1
+ m >>= 8
+
+ preimage[0] = byte(m & 1)
+ for i := 0; i < sysN/8; i++ {
+ preimage[1+i] = (byte(^m) & s[i]) | (byte(m) & e[i])
+ }
+
+ copy(preimage[1+sysN/8:][:syndBytes], c[0:syndBytes])
+ err := shake256(key[0:32], preimage[:])
+ if err != nil {
+ return err
+ }
+
+ // clear outputs (set to all 1's) if padding bits are not all zero
+ mask := paddingOk
+ for i := 0; i < 32; i++ {
+ key[i] |= mask
+ }
+
+ if paddingOk == 0 {
+ return nil
+ }
+ return fmt.Errorf("public key padding error %d", paddingOk)
+}
+
+// Generates `e`, a random error vector of weight `t`.
+// If generation of pseudo-random numbers fails, an error is returned
+func genE(e *[sysN / 8]byte, rand randFunc) error {
+ ind := [sysT]uint16{}
+ val := [sysT]byte{}
+ for {
+ buf := make([]byte, sysT*4)
+ err := rand(buf)
+ if err != nil {
+ return err
+ }
+
+ nums := [sysT * 2]uint16{}
+ for i := 0; i < sysT*2; i++ {
+ nums[i] = loadGf(buf[:])
+ buf = buf[2:]
+ }
+
+ count := 0
+ for i := 0; i < sysT*2 && count < sysT; i++ {
+ if nums[i] < sysN {
+ ind[count] = nums[i]
+ count++
+ }
+ }
+ if count < sysT {
+ continue
+ }
+
+ eq := false
+ for i := 1; i < sysT; i++ {
+ for j := 0; j < i; j++ {
+ if ind[i] == ind[j] {
+ eq = true
+ }
+ }
+ }
+
+ if !eq {
+ break
+ }
+ }
+
+ for j := 0; j < sysT; j++ {
+ val[j] = 1 << (ind[j] & 7)
+ }
+
+ for i := uint16(0); i < sysN/8; i++ {
+ e[i] = 0
+
+ for j := 0; j < sysT; j++ {
+ mask := sameMask(i, ind[j]>>3)
+ e[i] |= val[j] & mask
+ }
+ }
+ return nil
+}
+
+// Takes two 16-bit integers and determines whether they are equal
+// Return byte with all bit set if equal, 0 otherwise
+func sameMask(x uint16, y uint16) byte {
+ mask := uint32(x ^ y)
+ mask -= 1
+ mask >>= 31
+ mask = -mask
+
+ return byte(mask & 0xFF)
+}
+
+// Given condition bits `c`, returns the support `s`.
+func supportGen(s *[sysN]gf, c *[condBytes]byte) {
+ L := [gfBits][(1 << gfBits) / 8]byte{}
+ for i := 0; i < (1 << gfBits); i++ {
+ a := bitRev(gf(i))
+ for j := 0; j < gfBits; j++ {
+ L[j][i/8] |= byte(((a >> j) & 1) << (i % 8))
+ }
+ }
+ for j := 0; j < gfBits; j++ {
+ applyBenes(&L[j], c)
+ }
+ for i := 0; i < sysN; i++ {
+ s[i] = 0
+ for j := gfBits - 1; j >= 0; j-- {
+ s[i] <<= 1
+ s[i] |= uint16(L[j][i/8]>>(i%8)) & 1
+ }
+ }
+}
+
+// Given Goppa polynomial `f`, support `l`, and received word `r`
+// compute `out`, the syndrome of length 2t
+func synd(out *[sysT * 2]gf, f *[sysT + 1]gf, L *[sysN]gf, r *[sysN / 8]byte) {
+ for j := 0; j < 2*sysT; j++ {
+ out[j] = 0
+ }
+
+ for i := 0; i < sysN; i++ {
+ c := uint16(r[i/8]>>(i%8)) & 1
+ e := eval(f, L[i])
+ eInv := gf2e13.Inv(gf2e13.Mul(e, e))
+ for j := 0; j < 2*sysT; j++ {
+ out[j] = gf2e13.Add(out[j], gf2e13.Mul(eInv, c))
+ eInv = gf2e13.Mul(eInv, L[i])
+ }
+ }
+}
+
+func min(a, b int) int {
+ if a > b {
+ return b
+ }
+ return a
+}
+
+// The Berlekamp-Massey algorithm. <http://crypto.stanford.edu/~mironov/cs359/massey.pdf>
+// Uses `s` as input (sequence of field elements)
+// and `out` as output (minimal polynomial of `s`)
+func bm(out *[sysT + 1]gf, s *[2 * sysT]gf) {
+ var L, mle, mne uint16
+ T := [sysT + 1]gf{}
+ C := [sysT + 1]gf{}
+ B := [sysT + 1]gf{}
+ var b, d, f gf
+ b = 1
+ B[1] = 1
+ C[0] = 1
+ for N := 0; N < 2*sysT; N++ {
+ d = 0
+ for i := 0; i <= min(N, sysT); i++ {
+ d ^= gf2e13.Mul(C[i], s[N-i])
+ }
+ mne = d
+ mne -= 1
+ mne >>= 15
+ mne -= 1
+ mle = uint16(N)
+ mle -= 2 * L
+ mle >>= 15
+ mle -= 1
+ mle &= mne
+ for i := 0; i <= sysT; i++ {
+ T[i] = C[i]
+ }
+ f = gf2e13.Div(d, b)
+ for i := 0; i <= sysT; i++ {
+ C[i] ^= gf2e13.Mul(f, B[i]) & mne
+ }
+ L = (L & ^mle) | ((uint16(N) + 1 - L) & mle)
+
+ for i := 0; i <= sysT; i++ {
+ B[i] = (B[i] & ^mle) | (T[i] & mle)
+ }
+
+ b = (b & ^mle) | (d & mle)
+
+ for i := sysT; i >= 1; i-- {
+ B[i] = B[i-1]
+ }
+ B[0] = 0
+ }
+
+ for i := 0; i <= sysT; i++ {
+ out[i] = C[sysT-i]
+ }
+}
+
+// Niederreiter decryption with the Berlekamp decoder.
+//
+// It takes as input the secret key `sk` and a ciphertext `c`.
+// It returns an error vector in `e` and the return value indicates success (0) or failure (1)
+func decrypt(e *[sysN / 8]byte, sk []byte, c *[syndBytes]byte) uint16 {
+ var check uint16
+ w := 0
+ r := [sysN / 8]byte{}
+
+ g := [sysT + 1]gf{}
+ L := [sysN]gf{}
+
+ s := [sysT * 2]gf{}
+ sCmp := [sysT * 2]gf{}
+ locator := [sysT + 1]gf{}
+ images := [sysN]gf{}
+
+ copy(r[:syndBytes], c[:syndBytes])
+ for i := 0; i < sysT; i++ {
+ g[i] = loadGf(sk)
+ sk = sk[2:]
+ }
+ g[sysT] = 1
+
+ supportGen(&L, (*[condBytes]byte)(sk[:condBytes]))
+
+ synd(&s, &g, &L, &r)
+ bm(&locator, &s)
+ root(&images, &locator, &L)
+
+ for i := 0; i < sysN/8; i++ {
+ e[i] = 0
+ }
+ for i := 0; i < sysN; i++ {
+ t := isZeroMask(images[i]) & 1
+
+ e[i/8] |= byte(t << (i % 8))
+ w += int(t)
+ }
+
+ synd(&sCmp, &g, &L, e)
+ check = uint16(w) ^ sysT
+ for i := 0; i < sysT*2; i++ {
+ check |= s[i] ^ sCmp[i]
+ }
+
+ check -= 1
+ check >>= 15
+
+ return check ^ 1
+}
+
+// check if element is 0, returns a mask with all bits set if so, and 0 otherwise
+func isZeroMask(element gf) uint16 {
+ t := uint32(element) - 1
+ t >>= 19
+ return uint16(t)
+}
+
+// calculate the minimal polynomial of f and store it in out
+func minimalPolynomial(out *[sysT]gf, f *[sysT]gf) bool {
+ mat := [sysT + 1][sysT]gf{}
+ mat[0][0] = 1
+ for i := 1; i < sysT; i++ {
+ mat[0][i] = 0
+ }
+
+ for i := 0; i < sysT; i++ {
+ mat[1][i] = f[i]
+ }
+
+ for i := 2; i <= sysT; i++ {
+ polyMul(&mat[i], &mat[i-1], f)
+ }
+
+ for j := 0; j < sysT; j++ {
+ for k := j + 1; k < sysT; k++ {
+ mask := isZeroMask(mat[j][j])
+ // if mat[j][j] is not zero, add mat[c..sysT+1][k] to mat[c][j]
+ // do nothing otherwise
+ for c := j; c <= sysT; c++ {
+ mat[c][j] ^= mat[c][k] & mask
+ }
+ }
+
+ if mat[j][j] == 0 {
+ return false
+ }
+
+ inv := gf2e13.Inv(mat[j][j])
+ for c := 0; c <= sysT; c++ {
+ mat[c][j] = gf2e13.Mul(mat[c][j], inv)
+ }
+
+ for k := 0; k < sysT; k++ {
+ if k != j {
+ t := mat[j][k]
+ for c := 0; c <= sysT; c++ {
+ mat[c][k] ^= gf2e13.Mul(mat[c][j], t)
+ }
+ }
+ }
+ }
+
+ for i := 0; i < sysT; i++ {
+ out[i] = mat[sysT][i]
+ }
+
+ return true
+}
+
+// calculate the product of a and b in Fq^t
+func polyMul(out *[sysT]gf, a *[sysT]gf, b *[sysT]gf) {
+ product := [sysT*2 - 1]gf{}
+ for i := 0; i < sysT; i++ {
+ for j := 0; j < sysT; j++ {
+ product[i+j] ^= gf2e13.Mul(a[i], b[j])
+ }
+ }
+
+ for i := (sysT - 1) * 2; i >= sysT; i-- {
+ // polynomial reduction
+
+ product[i-sysT+8] ^= product[i]
+ product[i-sysT+0] ^= product[i]
+
+ }
+
+ for i := 0; i < sysT; i++ {
+ out[i] = product[i]
+ }
+}
+
+// Compute transposition of `in` and store it in `out`
+func transpose64x64(out, in *[64]uint64) {
+ masks := [6][2]uint64{
+ {0x5555555555555555, 0xAAAAAAAAAAAAAAAA},
+ {0x3333333333333333, 0xCCCCCCCCCCCCCCCC},
+ {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0},
+ {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00},
+ {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000},
+ {0x00000000FFFFFFFF, 0xFFFFFFFF00000000},
+ }
+ copy(out[:], in[:])
+
+ for d := 5; d >= 0; d-- {
+ s := 1 << d
+ for i := 0; i < 64; i += s * 2 {
+ for j := i; j < i+s; j++ {
+ x := (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s)
+ y := ((out[j] & masks[d][1]) >> s) | (out[j+s] & masks[d][1])
+
+ out[j+0] = x
+ out[j+s] = y
+ }
+ }
+ }
+}
+
+// given polynomial `f`, evaluate `f` at `a`
+func eval(f *[sysT + 1]gf, a gf) gf {
+ r := f[sysT]
+ for i := sysT - 1; i >= 0; i-- {
+ r = gf2e13.Mul(r, a)
+ r = gf2e13.Add(r, f[i])
+ }
+ return r
+}
+
+// Given polynomial `f` and a list of field elements `l`,
+// return the roots `out` satisfying `[ f(a) for a in L ]`
+func root(out *[sysN]gf, f *[sysT + 1]gf, l *[sysN]gf) {
+ for i := 0; i < sysN; i++ {
+ out[i] = eval(f, l[i])
+ }
+}
+
+// performs SHAKE-256 on `input` and store the hash in `output`
+func shake256(output []byte, input []byte) error {
+ shake := sha3.NewSHAKE256()
+ _, err := shake.Write(input)
+ if err != nil {
+ return err
+ }
+ _, err = shake.Read(output)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// store field element `a` in the first 2 bytes of `dest`
+func storeGf(dest []byte, a gf) {
+ dest[0] = byte(a & 0xFF)
+ dest[1] = byte(a >> 8)
+}
+
+// load a field element from the first 2 bytes of `src`
+func loadGf(src []byte) gf {
+ a := uint16(src[1])
+ a <<= 8
+ a |= uint16(src[0])
+ return a & gfMask
+}
+
+// load a 32-bit little endian integer from `in`
+func load4(in []byte) uint32 {
+ ret := uint32(in[3])
+ for i := 2; i >= 0; i-- {
+ ret <<= 8
+ ret |= uint32(in[i])
+ }
+ return ret
+}
+
+// store a 64-bit integer to `out` in little endian
+func store8(out []byte, in uint64) {
+ out[0] = byte((in >> 0x00) & 0xFF)
+ out[1] = byte((in >> 0x08) & 0xFF)
+ out[2] = byte((in >> 0x10) & 0xFF)
+ out[3] = byte((in >> 0x18) & 0xFF)
+ out[4] = byte((in >> 0x20) & 0xFF)
+ out[5] = byte((in >> 0x28) & 0xFF)
+ out[6] = byte((in >> 0x30) & 0xFF)
+ out[7] = byte((in >> 0x38) & 0xFF)
+}
+
+// load a 64-bit little endian integer from `in`
+func load8(in []byte) uint64 {
+ ret := uint64(in[7])
+ for i := 6; i >= 0; i-- {
+ ret <<= 8
+ ret |= uint64(in[i])
+ }
+ return ret
+}
+
+// reverse the bits in the field element `a`
+func bitRev(a gf) gf {
+ a = ((a & 0x00FF) << 8) | ((a & 0xFF00) >> 8)
+ a = ((a & 0x0F0F) << 4) | ((a & 0xF0F0) >> 4)
+ a = ((a & 0x3333) << 2) | ((a & 0xCCCC) >> 2)
+ a = ((a & 0x5555) << 1) | ((a & 0xAAAA) >> 1)
+
+ return a >> unusedBits
+}
+
+func SeedSize() int { return seedSize }
+func EncapsulationSeedSize() int { return encapsulationSeedSize }
+
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+ var ret [PrivateKeySize]byte
+ copy(ret[:], sk.sk[:])
+ return ret[:], nil
+}
+
+// MarshalCompressedBinary returns a 32-byte seed that can be used to regenerate
+// the key pair when passed to DeriveKeyPair
+func (sk *PrivateKey) MarshalCompressedBinary() []byte {
+ seed := [32]byte{}
+ copy(seed[:], sk.sk[:32])
+ return seed[:]
+}
+
+func (sk *PrivateKey) Public() *PublicKey {
+ pk, _ := DeriveKeyPair(sk.MarshalCompressedBinary())
+ return pk
+}
+
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+ var ret [PublicKeySize]byte
+ copy(ret[:], pk.pk[:])
+ return ret[:], nil
+}
+
+func GenerateKeyPair() (*PublicKey, *PrivateKey, error) {
+ seed := [32]byte{}
+ _, err := io.ReadFull(cryptoRand.Reader, seed[:])
+ if err != nil {
+ return nil, nil, err
+ }
+ pk, sk := deriveKeyPair(seed[:])
+ return pk, sk, nil
+}
+
+func DeriveKeyPair(seed []byte) (*PublicKey, *PrivateKey) {
+ if len(seed) != seedSize {
+ panic("seed must be of length EncapsulationSeedSize")
+ }
+ return deriveKeyPair(seed)
+}
+
+func encapsulate(pk *PublicKey, rand randFunc) (ct, ss []byte, err error) {
+ ciphertext := [CiphertextSize]byte{}
+ sharedSecret := [SharedKeySize]byte{}
+ err = kemEncapsulate(&ciphertext, &sharedSecret, &pk.pk, rand)
+ if err != nil {
+ return nil, nil, err
+ }
+ return ciphertext[:], sharedSecret[:], nil
+}
+
+func Encapsulate(pk *PublicKey) (ct, ss []byte, err error) {
+ return encapsulate(pk, func(pool []byte) error {
+ _, err2 := io.ReadFull(cryptoRand.Reader, pool)
+ return err2
+ })
+}
+
+func Decapsulate(sk *PrivateKey, ct []byte) ([]byte, error) {
+ if len(ct) != CiphertextSize {
+ return nil, ErrCiphertextSize
+ }
+ ss := [SharedKeySize]byte{}
+ err := kemDecapsulate(&ss, (*[CiphertextSize]byte)(ct), &sk.sk)
+ if err != nil {
+ return nil, err
+ }
+ return ss[:], nil
+}
+
+func UnmarshalBinaryPublicKey(buf []byte) (*PublicKey, error) {
+ if len(buf) != PublicKeySize {
+ return nil, ErrPubKeySize
+ }
+ pk := [PublicKeySize]byte{}
+ copy(pk[:], buf)
+ return &PublicKey{pk: pk}, nil
+}
+
+func UnmarshalBinaryPrivateKey(buf []byte) (*PrivateKey, error) {
+ if len(buf) != PrivateKeySize {
+ return nil, ErrPrivKeySize
+ }
+ sk := [PrivateKeySize]byte{}
+ copy(sk[:], buf)
+ return &PrivateKey{sk: sk}, nil
+}
--- /dev/null
+// Code generated from operations_6960119.templ.go. DO NOT EDIT.
+
+package mceliece6960119
+
+// This function determines (in a constant-time manner) whether the padding bits of `pk` are all zero.
+func checkPkPadding(pk *[PublicKeySize]byte) byte {
+ b := byte(0)
+ for i := 0; i < pkNRows; i++ {
+ b |= pk[i*pkRowBytes+pkRowBytes-1]
+ }
+ b >>= pkNCols % 8
+ b -= 1
+ b >>= 7
+ return b - 1
+}
+
+// This function determines (in a constant-time manner) whether the padding bits of `c` are all zero.
+func checkCPadding(c *[CiphertextSize]byte) byte {
+ b := c[syndBytes-1] >> (pkNRows % 8)
+ b -= 1
+ b >>= 7
+ return b - 1
+}
+
+// input: public key pk, error vector e
+// output: syndrome s
+func syndrome(s *[CiphertextSize]byte, pk *[PublicKeySize]byte, e *[sysN / 8]byte) {
+ row := [sysN / 8]byte{}
+ tail := pkNRows % 8
+ for i := 0; i < syndBytes; i++ {
+ s[i] = 0
+ }
+ for i := 0; i < pkNRows; i++ {
+ for j := 0; j < sysN/8; j++ {
+ row[j] = 0
+ }
+ for j := 0; j < pkRowBytes; j++ {
+ row[sysN/8-pkRowBytes+j] = pk[i*pkRowBytes+j]
+ }
+ for j := sysN/8 - 1; j >= sysN/8-pkRowBytes; j-- {
+ row[j] = (row[j] << tail) | (row[j-1] >> (8 - tail))
+ }
+ row[i/8] |= 1 << (i % 8)
+
+ b := byte(0)
+ for j := 0; j < sysN/8; j++ {
+ b ^= row[j] & e[j]
+ }
+
+ b ^= b >> 4
+ b ^= b >> 2
+ b ^= b >> 1
+ b &= 1
+
+ s[i/8] |= b << (i % 8)
+ }
+}
--- /dev/null
+// Code generated from pk_gen_vec.templ.go. DO NOT EDIT.
+
+// The following code is translated from the C `vec` Additional Implementation
+// from the NIST round 4 submission package.
+
+package mceliece6960119
+
+import "go.stargrave.org/vors/v5/pqhs/mceliece6960119/internal"
+
+const exponent = 128
+
+func storeI(out []byte, in uint64, i int) {
+ for j := 0; j < i; j++ {
+ out[j] = byte((in >> (j * 8)) & 0xFF)
+ }
+}
+
+func deBitSlicing(out *[1 << gfBits]uint64, in *[exponent][gfBits]uint64) {
+ for i := 0; i < (1 << gfBits); i++ {
+ out[i] = 0
+ }
+
+ for i := 0; i < exponent; i++ {
+ for j := gfBits - 1; j >= 0; j-- {
+ for r := 0; r < 64; r++ {
+ out[i*64+r] <<= 1
+ out[i*64+r] |= (in[i][j] >> r) & 1
+ }
+ }
+ }
+}
+
+func toBitslicing2x(out0 *[exponent][gfBits]uint64, out1 *[exponent][gfBits]uint64, in *[1 << gfBits]uint64) {
+ for i := 0; i < exponent; i++ {
+ for j := gfBits - 1; j >= 0; j-- {
+ for r := 63; r >= 0; r-- {
+ out1[i][j] <<= 1
+ out1[i][j] |= (in[i*64+r] >> (j + gfBits)) & 1
+ }
+ }
+
+ for j := gfBits - 1; j >= 0; j-- {
+ for r := 63; r >= 0; r-- {
+ out0[i][gfBits-1-j] <<= 1
+ out0[i][gfBits-1-j] |= (in[i*64+r] >> j) & 1
+ }
+ }
+ }
+}
+
+func irrLoad(out *[2][gfBits]uint64, in []byte) {
+ irr := [sysT + 1]uint16{}
+
+ for i := 0; i < sysT; i++ {
+ irr[i] = loadGf(in[i*2:])
+ }
+
+ irr[sysT] = 1
+
+ v := [2]uint64{}
+ for i := 0; i < gfBits; i++ {
+ v[0] = 0
+ v[1] = 0
+
+ for j := 63; j >= 0; j-- {
+ v[0] <<= 1
+ v[0] |= uint64(irr[j]>>i) & 1
+ }
+ for j := sysT; j >= 64; j-- {
+ v[1] <<= 1
+ v[1] |= uint64(irr[j]>>i) & 1
+ }
+
+ out[0][i] = v[0]
+ out[1][i] = v[1]
+ }
+}
+
+// nolint:unparam
+// Public key generation. Generate the public key `pk`,
+// permutation `pi` and pivot element `pivots` based on the
+// secret key `sk` and permutation `perm` provided.
+// `pk` has `max(1 << GFBITS, SYS_N)` elements which is
+// 4096 for mceliece348864 and 8192 for mceliece8192128.
+// `sk` has `2 * SYS_T` elements and perm `1 << GFBITS`.
+func pkGen(pk *[pkNRows * pkRowBytes]byte, irr []byte, perm *[1 << gfBits]uint32, pi *[1 << gfBits]int16, pivots *uint64) bool {
+ const (
+ nblocksH = (sysN + 63) / 64
+ nblocksI = (pkNRows + 63) / 64
+
+ blockIdx = nblocksI - 1
+ tail = pkNRows % 64
+ )
+ mat := [pkNRows][nblocksH]uint64{}
+ var mask uint64
+
+ irrInt := [2][gfBits]uint64{}
+
+ consts := [exponent][gfBits]uint64{}
+ eval := [exponent][gfBits]uint64{}
+ prod := [exponent][gfBits]uint64{}
+ tmp := [gfBits]uint64{}
+ list := [1 << gfBits]uint64{}
+
+ ops := [pkNRows][nblocksI]uint64{}
+
+ oneRow := [exponent]uint64{}
+
+ // compute the inverses
+ irrLoad(&irrInt, irr)
+ fft(&eval, &irrInt)
+ vecCopy(&prod[0], &eval[0])
+ for i := 1; i < exponent; i++ {
+ vecMul(&prod[i], &prod[i-1], &eval[i])
+ }
+ vecInv(&tmp, &prod[exponent-1])
+ for i := exponent - 2; i >= 0; i-- {
+ vecMul(&prod[i+1], &prod[i], &tmp)
+ vecMul(&tmp, &tmp, &eval[i+1])
+ }
+ vecCopy(&prod[0], &tmp)
+
+ // fill matrix
+ deBitSlicing(&list, &prod)
+ for i := uint64(0); i < (1 << gfBits); i++ {
+ list[i] <<= gfBits
+ list[i] |= i
+ list[i] |= (uint64(perm[i])) << 31
+ }
+ internal.UInt64Sort(list[:], 1<<gfBits)
+
+ for i := 1; i < (1 << gfBits); i++ {
+ if (list[i-1] >> 31) == (list[i] >> 31) {
+ return false
+ }
+ }
+ toBitslicing2x(&consts, &prod, &list)
+
+ for i := 0; i < (1 << gfBits); i++ {
+ pi[i] = int16(list[i] & gfMask)
+ }
+
+ for j := 0; j < nblocksI; j++ {
+ for k := 0; k < gfBits; k++ {
+ mat[k][j] = prod[j][k]
+ }
+ }
+
+ for i := 1; i < sysT; i++ {
+ for j := 0; j < nblocksI; j++ {
+ vecMul(&prod[j], &prod[j], &consts[j])
+ for k := 0; k < gfBits; k++ {
+ mat[i*gfBits+k][j] = prod[j][k]
+ }
+ }
+ }
+
+ // gaussian elimination to obtain an upper triangular matrix
+ // and keep track of the operations in ops
+
+ for i := 0; i < pkNRows; i++ {
+ for j := 0; j < nblocksI; j++ {
+ ops[i][j] = 0
+ }
+ }
+ for i := 0; i < pkNRows; i++ {
+ ops[i][i/64] = 1
+ ops[i][i/64] <<= (i % 64)
+ }
+
+ column := [pkNRows]uint64{}
+ for i := 0; i < pkNRows; i++ {
+ column[i] = mat[i][blockIdx]
+ }
+
+ for row := 0; row < pkNRows; row++ {
+ i := row >> 6
+ j := row & 63
+
+ for k := row + 1; k < pkNRows; k++ {
+ mask = mat[row][i] >> j
+ mask &= 1
+ mask -= 1
+
+ for c := 0; c < nblocksI; c++ {
+ mat[row][c] ^= mat[k][c] & mask
+ ops[row][c] ^= ops[k][c] & mask
+ }
+
+ }
+ // return if not systematic
+ if ((mat[row][i] >> j) & 1) == 0 {
+ return false
+ }
+
+ for k := row + 1; k < pkNRows; k++ {
+ mask = mat[k][i] >> j
+ mask &= 1
+ mask = -mask
+
+ for c := 0; c < nblocksI; c++ {
+ mat[k][c] ^= mat[row][c] & mask
+
+ ops[k][c] ^= ops[row][c] & mask
+
+ }
+ }
+ }
+
+ pkp := pk[:]
+
+ // computing the lineaer map required to obatin the systematic form
+
+ for row := pkNRows - 1; row >= 0; row-- {
+ for k := 0; k < row; k++ {
+ mask = mat[k][row/64] >> (row & 63)
+ mask &= 1
+ mask = -mask
+
+ for c := 0; c < nblocksI; c++ {
+ ops[k][c] ^= ops[row][c] & mask
+ }
+ }
+ }
+
+ // apply the linear map to the non-systematic part
+ for j := nblocksI; j < nblocksH; j++ {
+ for k := 0; k < gfBits; k++ {
+ mat[k][j] = prod[j][k]
+ }
+ }
+
+ for i := 1; i < sysT; i++ {
+ for j := nblocksI; j < nblocksH; j++ {
+ vecMul(&prod[j], &prod[j], &consts[j])
+ for k := 0; k < gfBits; k++ {
+ mat[i*gfBits+k][j] = prod[j][k]
+ }
+ }
+ }
+
+ for i := 0; i < pkNRows; i++ {
+ mat[i][blockIdx] = column[i]
+ }
+
+ for row := 0; row < pkNRows; row++ {
+ for k := 0; k < nblocksH; k++ {
+ oneRow[k] = 0
+ }
+
+ for c := 0; c < pkNRows; c++ {
+ mask = ops[row][c>>6] >> (c & 63)
+ mask &= 1
+ mask = -mask
+
+ for k := blockIdx; k < nblocksH; k++ {
+ oneRow[k] ^= mat[c][k] & mask
+ }
+ }
+
+ var k int
+ for k = blockIdx; k < nblocksH-1; k++ {
+
+ oneRow[k] = (oneRow[k] >> tail) | (oneRow[k+1] << (64 - tail))
+
+ store8(pkp, oneRow[k])
+ pkp = pkp[8:]
+ }
+
+ oneRow[k] >>= tail
+
+ storeI(pkp, oneRow[k], pkRowBytes%8)
+
+ pkp[(pkRowBytes%8)-1] &= (1 << (pkNCols % 8)) - 1 // removing redundant bits
+
+ pkp = pkp[pkRowBytes%8:]
+ }
+
+ return true
+}
--- /dev/null
+// Code generated from vec.templ.go. DO NOT EDIT.
+
+// The following code is translated from the C `vec` Additional Implementation
+// from the NIST round 4 submission package.
+
+package mceliece6960119
+
+func vecMul(h, f, g *[gfBits]uint64) {
+ buf := [2*gfBits - 1]uint64{}
+
+ for i := 0; i < 2*gfBits-1; i++ {
+ buf[i] = 0
+ }
+
+ for i := 0; i < gfBits; i++ {
+ for j := 0; j < gfBits; j++ {
+ buf[i+j] ^= f[i] & g[j]
+ }
+ }
+
+ for i := 2*gfBits - 2; i >= gfBits; i-- {
+
+ buf[i-gfBits+4] ^= buf[i]
+ buf[i-gfBits+3] ^= buf[i]
+ buf[i-gfBits+1] ^= buf[i]
+ buf[i-gfBits+0] ^= buf[i]
+
+ }
+
+ for i := 0; i < gfBits; i++ {
+ h[i] = buf[i]
+ }
+}
+
+// bitsliced field squarings
+func vecSq(out, in *[gfBits]uint64) {
+ result := [gfBits]uint64{}
+
+ t := in[11] ^ in[12]
+
+ result[0] = in[0] ^ in[11]
+ result[1] = in[7] ^ t
+ result[2] = in[1] ^ in[7]
+ result[3] = in[8] ^ t
+ result[4] = in[2] ^ in[7]
+ result[4] = result[4] ^ in[8]
+ result[4] = result[4] ^ t
+ result[5] = in[7] ^ in[9]
+ result[6] = in[3] ^ in[8]
+ result[6] = result[6] ^ in[9]
+ result[6] = result[6] ^ in[12]
+ result[7] = in[8] ^ in[10]
+ result[8] = in[4] ^ in[9]
+ result[8] = result[8] ^ in[10]
+ result[9] = in[9] ^ in[11]
+ result[10] = in[5] ^ in[10]
+ result[10] = result[10] ^ in[11]
+ result[11] = in[10] ^ in[12]
+ result[12] = in[6] ^ t
+
+ for i := 0; i < gfBits; i++ {
+ out[i] = result[i]
+ }
+}
+
+// bitsliced field inverses
+func vecInv(out, in *[gfBits]uint64) {
+ tmp11 := [gfBits]uint64{}
+ tmp1111 := [gfBits]uint64{}
+
+ vecCopy(out, in)
+
+ vecSq(out, out)
+ vecMul(&tmp11, out, in) // ^11
+
+ vecSq(out, &tmp11)
+ vecSq(out, out)
+ vecMul(&tmp1111, out, &tmp11) // ^1111
+
+ vecSq(out, &tmp1111)
+ vecSq(out, out)
+ vecSq(out, out)
+ vecSq(out, out)
+ vecMul(out, out, &tmp1111) // ^11111111
+
+ vecSq(out, out)
+ vecSq(out, out)
+ vecSq(out, out)
+ vecSq(out, out)
+ vecMul(out, out, &tmp1111) // ^111111111111
+
+ vecSq(out, out) // ^1111111111110
+}
+
+func vecSetBits(b uint64) uint64 {
+ ret := -b
+ return ret
+}
+
+func vecSet116b(v uint16) uint64 {
+ ret := uint64(v)
+ ret |= ret << 16
+ ret |= ret << 32
+
+ return ret
+}
+
+func vecCopy(out, in *[gfBits]uint64) {
+ for i := 0; i < gfBits; i++ {
+ out[i] = in[i]
+ }
+}
+
+func vecOrReduce(a *[gfBits]uint64) uint64 {
+ ret := a[0]
+ for i := 1; i < gfBits; i++ {
+ ret |= a[i]
+ }
+
+ return ret
+}
+
+func vecTestZ(a uint64) int {
+ a |= a >> 32
+ a |= a >> 16
+ a |= a >> 8
+ a |= a >> 4
+ a |= a >> 2
+ a |= a >> 1
+
+ return int((a & 1) ^ 1)
+}
--- /dev/null
+package pqhs
+
+import (
+ "crypto/ecdh"
+ "crypto/rand"
+
+ vors "go.stargrave.org/vors/v5/internal"
+ "go.stargrave.org/vors/v5/pqhs/mceliece6960119"
+ sntrup761kem "go.stargrave.org/vors/v5/pqhs/sntrup761/kem"
+ sntrup761 "go.stargrave.org/vors/v5/pqhs/sntrup761/kem/ntruprime/sntrup761"
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+type Server struct {
+ ephPrvSNTRUP sntrup761kem.PrivateKey
+ SymmetricState
+}
+
+func NewServer(
+ serverStaticPrvMcElieceRaw, serverStaticPrvX25519Raw,
+ serverStaticPubHash, clientPayload []byte,
+) (s *Server, payload []byte, err error) {
+ var serverStaticPrvMcEliece *mceliece6960119.PrivateKey
+ serverStaticPrvMcEliece, err = mceliece6960119.UnmarshalBinaryPrivateKey(
+ serverStaticPrvMcElieceRaw)
+ if err != nil {
+ return
+ }
+ x25519 := ecdh.X25519()
+ var serverStaticPrvX25519 *ecdh.PrivateKey
+ serverStaticPrvX25519, err = x25519.NewPrivateKey(serverStaticPrvX25519Raw)
+ if err != nil {
+ return
+ }
+ ctMcEliece := clientPayload[:mceliece6960119.CiphertextSize]
+ ctX25519 := clientPayload[mceliece6960119.CiphertextSize:]
+ var k []byte
+ k, err = mceliece6960119.Decapsulate(serverStaticPrvMcEliece, ctMcEliece)
+ if err != nil {
+ return
+ }
+ s = &Server{}
+ s.CK(k)
+ s.H([]byte(vors.Magic))
+ s.H(serverStaticPubHash)
+ s.H(ctMcEliece)
+ var clientEphPubX25519Raw []byte
+ clientEphPubX25519Raw, err = s.Open(CtxClientX25519, ctX25519)
+ if err != nil {
+ return
+ }
+ var clientEphPubX25519 *ecdh.PublicKey
+ clientEphPubX25519, k, err = DH(serverStaticPrvX25519, clientEphPubX25519Raw)
+ if err != nil {
+ return
+ }
+ s.CK(k)
+ var serverEphPrvX25519 *ecdh.PrivateKey
+ serverEphPrvX25519, err = x25519.GenerateKey(rand.Reader)
+ if err != nil {
+ return
+ }
+ ctX25519 = s.Seal(CtxServerX25519, serverEphPrvX25519.PublicKey().Bytes())
+ k, err = serverEphPrvX25519.ECDH(clientEphPubX25519)
+ if err != nil {
+ return
+ }
+ s.CK(k)
+ var serverEphPubSNTRUP sntrup761kem.PublicKey
+ serverEphPubSNTRUP, s.ephPrvSNTRUP, err = sntrup761.Scheme().GenerateKeyPair()
+ if err != nil {
+ return
+ }
+ var serverEphPubSNTRUPRaw []byte
+ serverEphPubSNTRUPRaw, err = serverEphPubSNTRUP.MarshalBinary()
+ if err != nil {
+ return
+ }
+ payload = append(ctX25519, s.Seal(CtxServerSNTRUP761, serverEphPubSNTRUPRaw)...)
+ return
+}
+
+func (s *Server) Read(reply []byte) (prefinish []byte, err error) {
+ sntrup761s := sntrup761.Scheme()
+ clientEphCTSNTRUPRaw := reply[:sntrup761s.CiphertextSize()+chacha20poly1305.Overhead]
+ prefinish = reply[len(clientEphCTSNTRUPRaw):]
+ {
+ clientEphCTSNTRUPRaw, err = s.Open(CtxClientSNTRUP761, clientEphCTSNTRUPRaw)
+ if err != nil {
+ return
+ }
+ var k []byte
+ k, err = sntrup761s.Decapsulate(s.ephPrvSNTRUP, clientEphCTSNTRUPRaw)
+ if err != nil {
+ return
+ }
+ s.CK(k)
+ }
+ prefinish, err = s.Open(CtxClientPrefinish, prefinish)
+ return
+}
--- /dev/null
+package pqhs
+
+import (
+ "crypto/sha3"
+ "hash"
+ "io"
+)
+
+type SHAKE struct {
+ xof *sha3.SHAKE
+}
+
+func (h SHAKE) Size() int {
+ return 64
+}
+
+func (h SHAKE) BlockSize() int {
+ return h.xof.BlockSize()
+}
+
+func (h SHAKE) Reset() {
+ h.xof.Reset()
+}
+
+func (h SHAKE) Write(p []byte) (int, error) {
+ return h.xof.Write(p)
+}
+
+func (h SHAKE) Sum(b []byte) []byte {
+ buf := make([]byte, 64)
+ if _, err := io.ReadFull(h.xof, buf); err != nil {
+ panic(err)
+ }
+ return append(b, buf...)
+}
+
+func NewSHAKE256() hash.Hash {
+ return SHAKE{xof: sha3.NewSHAKE256()}
+}
--- /dev/null
+Go/Git is unable to fetch (https://github.com/cloudflare/circl)
+pull-request's commit (e8d7edb133624b7fa80e66fd9f6eb97f3f1cd361) to
+github.com/cloudflare/circl containing NTRU prime implementation
+(https://github.com/cloudflare/circl/pull/384). So copy it here.
--- /dev/null
+// 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")
+)
--- /dev/null
+//go:generate go run gen.go
+
+// Package ntruprime implements the NTRU Prime IND-CCA2 secure
+// key encapsulation mechanism (KEM) as submitted to round 3 of the NIST PQC
+// competition and described in
+//
+// https://ntruprime.cr.yp.to/nist/ntruprime-20201007.pdf
+//
+// The code is translated from the C reference implementation.
+package ntruprime
--- /dev/null
+package internal
+
+// TO DO: Optimize the Decode function
+/* Decode(R,s,M,len) */
+/* assumes 0 < M[i] < 16384 */
+/* produces 0 <= R[i] < M[i] */
+func Decode(out []uint16, S []uint8, M []uint16, len int) {
+ index := 0
+ if len == 1 {
+ if M[0] == 1 {
+ out[index] = 0
+ } else if M[0] <= 256 {
+ out[index] = Uint32ModUint14(uint32(S[0]), M[0])
+ } else {
+ out[index] = Uint32ModUint14(uint32(uint16(S[0])+((uint16(S[1]))<<8)), M[0])
+ }
+ }
+ if len > 1 {
+ R2 := make([]uint16, (len+1)/2)
+ M2 := make([]uint16, (len+1)/2)
+ bottomr := make([]uint16, len/2)
+ bottomt := make([]uint32, len/2)
+ i := 0
+ for i = 0; i < len-1; i += 2 {
+ m := uint32(M[i]) * uint32(M[i+1])
+
+ if m > 256*16383 {
+ bottomt[i/2] = 256 * 256
+ bottomr[i/2] = uint16(S[0]) + 256*uint16(S[1])
+ S = S[2:]
+ M2[i/2] = uint16((((m + 255) >> 8) + 255) >> 8)
+ } else if m >= 16384 {
+ bottomt[i/2] = 256
+ bottomr[i/2] = uint16(S[0])
+ S = S[1:]
+ M2[i/2] = uint16((m + 255) >> 8)
+ } else {
+ bottomt[i/2] = 1
+ bottomr[i/2] = 0
+ M2[i/2] = uint16(m)
+ }
+ }
+ if i < len {
+ M2[i/2] = M[i]
+ }
+
+ Decode(R2, S, M2, (len+1)/2)
+
+ for i = 0; i < len-1; i += 2 {
+ r := uint32(bottomr[i/2])
+ var r1 uint32
+ var r0 uint16
+
+ r += bottomt[i/2] * uint32(R2[i/2])
+ Uint32DivmodUint14(&r1, &r0, r, M[i])
+ r1 = uint32(Uint32ModUint14(r1, M[i+1])) /* only needed for invalid inputs */
+
+ out[index] = r0
+ index++
+ out[index] = uint16(r1)
+ index++
+ }
+ if i < len {
+ out[index] = R2[i/2]
+ }
+ }
+}
--- /dev/null
+package internal
+
+/*
+CPU division instruction typically takes time depending on x.
+This software is designed to take time independent of x.
+Time still varies depending on m; user must ensure that m is constant.
+Time also varies on CPUs where multiplication is variable-time.
+There could be more CPU issues.
+There could also be compiler issues.
+*/
+// q, r = x/m
+// Returns quotient and remainder
+func Uint32DivmodUint14(q *uint32, r *uint16, x uint32, m uint16) {
+ var v uint32 = 0x80000000
+
+ v /= uint32(m)
+
+ *q = 0
+
+ qpart := uint32(uint64(x) * uint64(v) >> 31)
+
+ x -= qpart * uint32(m)
+ *q += qpart
+
+ qpart = uint32(uint64(x) * uint64(v) >> 31)
+ x -= qpart * uint32(m)
+ *q += qpart
+
+ x -= uint32(m)
+ *q += 1
+ mask := -(x >> 31)
+ x += mask & uint32(m)
+ *q += mask
+
+ *r = uint16(x)
+}
+
+// Returns the quotient of x/m
+func Uint32DivUint14(x uint32, m uint16) uint32 {
+ var q uint32
+ var r uint16
+ Uint32DivmodUint14(&q, &r, x, m)
+ return q
+}
+
+// Returns the remainder of x/m
+func Uint32ModUint14(x uint32, m uint16) uint16 {
+ var q uint32
+ var r uint16
+ Uint32DivmodUint14(&q, &r, x, m)
+ return r
+}
+
+// Calculates quotient and remainder
+func Int32DivmodUint14(q *int32, r *uint16, x int32, m uint16) {
+ var uq, uq2 uint32
+ var ur, ur2 uint16
+ var mask uint32
+
+ Uint32DivmodUint14(&uq, &ur, 0x80000000+uint32(x), m)
+ Uint32DivmodUint14(&uq2, &ur2, 0x80000000, m)
+
+ ur -= ur2
+ uq -= uq2
+ mask = -(uint32)(ur >> 15)
+ ur += uint16(mask & uint32(m))
+ uq += mask
+ *r = ur
+ *q = int32(uq)
+}
+
+// Returns quotient of x/m
+func Int32DivUint14(x int32, m uint16) int32 {
+ var q int32
+ var r uint16
+ Int32DivmodUint14(&q, &r, x, m)
+ return q
+}
+
+// Returns remainder of x/m
+func Int32ModUint14(x int32, m uint16) uint16 {
+ var q int32
+ var r uint16
+ Int32DivmodUint14(&q, &r, x, m)
+ return r
+}
+
+// Returns -1 if x!=0; else return 0
+func Int16NonzeroMask(x int16) int {
+ u := uint16(x) /* 0, else 1...65535 */
+ v := uint32(u) /* 0, else 1...65535 */
+ v = -v /* 0, else 2^32-65535...2^32-1 */
+ v >>= 31 /* 0, else 1 */
+ return -int(v) /* 0, else -1 */
+}
+
+// Returns -1 if x<0; otherwise return 0
+func Int16NegativeMask(x int16) int {
+ u := uint16(x)
+ u >>= 15
+ return -(int)(u)
+}
--- /dev/null
+package internal
+
+/* 0 <= R[i] < M[i] < 16384 */
+func Encode(out []uint8, R, M []uint16, len int) {
+ if len > 1 {
+ R2 := make([]uint16, (len+1)/2)
+ M2 := make([]uint16, (len+1)/2)
+ var i int
+ for ; len > 1; len = (len + 1) / 2 {
+ for i = 0; i < len-1; i += 2 {
+ m0 := uint32(M[i])
+ r := uint32(R[i]) + uint32(R[i+1])*m0
+ m := uint32(M[i+1]) * m0
+ for m >= 16384 {
+ out[0] = uint8(r)
+ out = out[1:]
+
+ r >>= 8
+ m = (m + 255) >> 8
+ }
+ R2[i/2] = uint16(r)
+ M2[i/2] = uint16(m)
+ }
+ if i < len {
+ R2[i/2] = R[i]
+ M2[i/2] = M[i]
+ }
+ copy(R, R2)
+ copy(M, M2)
+ }
+ }
+ if len == 1 {
+ r := R[0]
+ m := M[0]
+ for m > 1 {
+ out[0] = uint8(r)
+ out = out[1:]
+ r >>= 8
+ m = (m + 255) >> 8
+ }
+ }
+}
--- /dev/null
+// Code generated from sntrup.templ.go. DO NOT EDIT.
+
+// Package sntrup761 implements the IND-CCA2 secure key encapsulation mechanism
+// sntrup761 as submitted to round 3 of the NIST PQC competition and
+// described in
+//
+// https://ntruprime.cr.yp.to/nist/ntruprime-20201007.pdf
+package sntrup761
+
+import (
+ "bytes"
+ cryptoRand "crypto/rand"
+ "crypto/sha512"
+ "io"
+
+ "go.stargrave.org/vors/v5/pqhs/sntrup761/kem"
+ "go.stargrave.org/vors/v5/pqhs/sntrup761/kem/ntruprime/internal"
+ sntrupKem "go.stargrave.org/vors/v5/pqhs/sntrup761/pke/ntruprime/kem"
+ ntrup "go.stargrave.org/vors/v5/pqhs/sntrup761/pke/ntruprime/sntrup761"
+)
+
+type (
+ small int8
+ Fq int16
+ Inputs [p]small
+)
+
+const (
+ p = ntrup.P
+ q = ntrup.Q
+ q12 = ((q - 1) / 2)
+ roundedBytes = ntrup.RoundedBytes
+ rqBytes = ntrup.RqBytes
+ w = ntrup.W
+
+ hashBytes = 32
+
+ smallBytes = ((p + 3) / 4)
+
+ inputsBytes = smallBytes
+ ciphertextsBytes = roundedBytes
+ secretKeysBytes = (2 * smallBytes)
+ publicKeysBytes = rqBytes
+
+ confirmBytes = 32
+)
+
+const (
+ // Size of seed for NewKeyFromSeed
+ // Note that during keyGen, a random small is generated until a valid one (whose reciprocal succeeds) is found
+ // The size of keySeed depends on the number of times the reciprocal fails
+ // This is why DeriveKeyPairFromGen is used to deterministically derive key pair instead of using seed
+ KeySeedSize = 4*p + p*4 + inputsBytes
+
+ // Size of seed for EncapsulateTo.
+ EncapsulationSeedSize = 4 * p
+
+ // Size of the established shared key.
+ SharedKeySize = ntrup.SharedKeySize
+
+ // Size of the encapsulated shared key.
+ CiphertextSize = ntrup.CiphertextSize
+
+ // Size of a packed public key.
+ PublicKeySize = ntrup.PublicKeySize
+
+ // Size of a packed private key.
+ PrivateKeySize = ntrup.PrivateKeySize
+)
+
+// Arithmetic operations over GF(3)
+
+// A polynomial of R has all of its coefficients in (-1,0,1)
+// F3 is always represented as -1,0,1
+// so ZZ_fromF3 is a no-op
+
+// x must not be close to top int16
+func f3Freeze(x int16) small {
+ return small(internal.Int32ModUint14(int32(x)+1, 3)) - 1
+}
+
+// Arithmetic operations over GF(q)
+
+/* always represented as -q12...q12 */
+/* so ZZ_fromFq is a no-op */
+
+/* x must not be close to top int32 */
+func fqFreeze(x int32) Fq {
+ return Fq(internal.Int32ModUint14(x+q12, q) - q12)
+}
+
+// Calculates reciprocal of Fq
+func fqRecip(a1 Fq) Fq {
+ var i int = 1
+ ai := a1
+
+ for i < (q - 2) {
+ ai = fqFreeze(int32(a1) * int32(ai))
+ i += 1
+ }
+ return ai
+}
+
+// Returns 0 if the weight w is equal to r
+// otherwise returns -1
+func weightwMask(r []small) int {
+ var weight int = 0
+
+ for i := 0; i < p; i++ {
+ weight += int(r[i]) & 1
+ }
+
+ // returns -1 if non zero
+ // otherwise returns 0 if weight==w
+ return internal.Int16NonzeroMask(int16(weight - w))
+
+}
+
+/* R3_fromR(R_fromRq(r)) */
+func r3FromRq(out []small, r []Fq) {
+ for i := 0; i < p; i++ {
+ out[i] = small(f3Freeze(int16(r[i])))
+ }
+}
+
+// h = f*g in the ring R3
+func r3Mult(h []small, f []small, g []small) {
+ fg := make([]small, p+p-1)
+ var result small
+ var i, j int
+
+ for i = 0; i < p; i++ {
+ result = 0
+ for j = 0; j <= i; j++ {
+ result = f3Freeze(int16(result + f[j]*g[i-j]))
+ }
+ fg[i] = result
+ }
+
+ for i = p; i < p+p-1; i++ {
+ result = 0
+ for j = i - p + 1; j < p; j++ {
+ result = f3Freeze(int16(result + f[j]*g[i-j]))
+ }
+ fg[i] = result
+ }
+
+ for i = p + p - 2; i >= p; i-- {
+ fg[i-p] = f3Freeze(int16(fg[i-p] + fg[i]))
+ fg[i-p+1] = f3Freeze(int16(fg[i-p+1] + fg[i]))
+ }
+
+ for i = 0; i < p; i++ {
+ h[i] = fg[i]
+ }
+}
+
+// Calculates the reciprocal of R3 polynomials
+// Returns 0 if recip succeeded; else -1
+func r3Recip(out []small, in []small) int {
+ // out := make([]small, p)
+ f := make([]small, p+1)
+ g := make([]small, p+1)
+ v := make([]small, p+1)
+ r := make([]small, p+1)
+
+ var sign int
+
+ r[0] = 1
+ f[0] = 1
+
+ f[p-1] = -1
+ f[p] = -1
+
+ for i := 0; i < p; i++ {
+ g[p-1-i] = in[i]
+ }
+
+ g[p] = 0
+
+ delta := 1
+
+ for loop := 0; loop < 2*p-1; loop++ {
+ for i := p; i > 0; i-- {
+ v[i] = v[i-1]
+ }
+ v[0] = 0
+
+ sign = int(-g[0] * f[0])
+ var swap int = int(internal.Int16NegativeMask(int16(-delta)) & internal.Int16NonzeroMask(int16(g[0])))
+ delta ^= swap & int(delta^-delta)
+ delta += 1
+
+ for i := 0; i < p+1; i++ {
+ t := swap & int(f[i]^g[i])
+ f[i] ^= small(t)
+ g[i] ^= small(t)
+ t = swap & int(v[i]^r[i])
+ v[i] ^= small(t)
+ r[i] ^= small(t)
+ }
+ for i := 0; i < p+1; i++ {
+ g[i] = f3Freeze(int16(int(g[i]) + sign*int(f[i])))
+ }
+
+ for i := 0; i < p+1; i++ {
+ r[i] = f3Freeze(int16(int(r[i]) + sign*int(v[i])))
+ }
+
+ for i := 0; i < p; i++ {
+ g[i] = g[i+1]
+ }
+
+ g[p] = 0
+
+ }
+ sign = int(f[0])
+
+ for i := 0; i < p; i++ {
+
+ out[i] = small(sign * int(v[p-1-i]))
+ }
+
+ return internal.Int16NonzeroMask(int16(delta))
+
+}
+
+// Polynomials mod q
+
+// h = f*g in the ring Rq */
+func rqMultSmall(h []Fq, f []Fq, g []small) {
+ fg := make([]Fq, p+p-1)
+ var result Fq
+
+ for i := 0; i < p; i++ {
+ result = 0
+ for j := 0; j <= i; j++ {
+ result = fqFreeze(int32(result) + int32(f[j])*(int32)(g[i-j]))
+ }
+ fg[i] = result
+ }
+
+ for i := p; i < p+p-1; i++ {
+ result = 0
+ for j := i - p + 1; j < p; j++ {
+ result = fqFreeze(int32(result) + int32(f[j])*(int32)(g[i-j]))
+ }
+ fg[i] = result
+ }
+
+ for i := p + p - 2; i >= p; i-- {
+ fg[i-p] = fqFreeze(int32(fg[i-p] + fg[i]))
+ fg[i-p+1] = fqFreeze(int32(fg[i-p+1] + fg[i]))
+
+ }
+
+ for i := 0; i < p; i++ {
+ h[i] = fg[i]
+ }
+}
+
+// h = 3f in Rq
+func rqMult3(h []Fq, f []Fq) {
+ for i := 0; i < p; i++ {
+ h[i] = fqFreeze(int32(3 * f[i]))
+ }
+}
+
+// Returns 0 if recip succeeded; else -1
+// out = 1/(3*in) in Rq
+func rqRecip3(out []Fq, in []small) int {
+ f := make([]Fq, p+1)
+ g := make([]Fq, p+1)
+ v := make([]Fq, p+1)
+ r := make([]Fq, p+1)
+
+ var swap, t int
+ var f0, g0 int32
+
+ r[0] = fqRecip(3)
+ f[0] = 1
+ f[p-1] = -1
+ f[p] = -1
+
+ for i := 0; i < p; i++ {
+ g[p-1-i] = Fq(in[i])
+ }
+ g[p] = 0
+
+ delta := 1
+
+ for loop := 0; loop < 2*p-1; loop++ {
+ for i := p; i > 0; i-- {
+ v[i] = v[i-1]
+ }
+ v[0] = 0
+
+ swap = internal.Int16NegativeMask(int16(-delta)) & internal.Int16NonzeroMask(int16(g[0]))
+ delta ^= swap & (delta ^ -delta)
+ delta += 1
+
+ for i := 0; i < p+1; i++ {
+ t = swap & int(f[i]^g[i])
+ f[i] ^= Fq(t)
+ g[i] ^= Fq(t)
+ t = swap & int(v[i]^r[i])
+ v[i] ^= Fq(t)
+ r[i] ^= Fq(t)
+ }
+
+ f0 = int32(f[0])
+ g0 = int32(g[0])
+
+ for i := 0; i < p+1; i++ {
+ g[i] = fqFreeze(f0*int32(g[i]) - g0*int32(f[i]))
+ }
+ for i := 0; i < p+1; i++ {
+ r[i] = fqFreeze(f0*int32(r[i]) - g0*int32(v[i]))
+ }
+
+ for i := 0; i < p; i++ {
+ g[i] = g[i+1]
+ }
+ g[p] = 0
+ }
+
+ scale := Fq(fqRecip(f[0]))
+ for i := 0; i < p; i++ {
+ out[i] = fqFreeze(int32(scale) * (int32)(v[p-1-i]))
+ }
+
+ return internal.Int16NonzeroMask(int16(delta))
+
+}
+
+// Rounding all coefficients of a polynomial to the nearest multiple of 3
+// Rounded polynomials mod q
+func round(out []Fq, a []Fq) {
+ for i := 0; i < p; i++ {
+ out[i] = a[i] - Fq(f3Freeze(int16(a[i])))
+ }
+}
+
+// Returns (min(x, y), max(x, y)), executes in constant time
+func minmax(x, y *uint32) {
+ var xi uint32 = *x
+ var yi uint32 = *y
+ var xy uint32 = xi ^ yi
+ var c uint32 = yi - xi
+ c ^= xy & (c ^ yi ^ 0x80000000)
+ c >>= 31
+ c = -c
+ c &= xy
+ *x = xi ^ c
+ *y = yi ^ c
+}
+
+// Sorts the array of unsigned integers
+func cryptoSortUint32(x []uint32, n int) {
+ if n < 2 {
+ return
+ }
+ top := 1
+
+ for top < n-top {
+ top += top
+ }
+
+ for p := top; p > 0; p >>= 1 {
+ for i := 0; i < n-p; i++ {
+ if i&p == 0 {
+ minmax(&x[i], &x[i+p])
+ }
+ }
+ for q := top; q > p; q >>= 1 {
+ for i := 0; i < n-q; i++ {
+ if i&p == 0 {
+ minmax(&x[i+p], &x[i+q])
+ }
+ }
+ }
+ }
+}
+
+// Sorting to generate short polynomial
+func shortFromList(out []small, in []int32) {
+ L := make([]uint32, p)
+
+ var neg2, neg3 int = -2, -3
+
+ for i := 0; i < w; i++ {
+ L[i] = uint32(in[i]) & uint32((neg2))
+ }
+
+ for i := w; i < p; i++ {
+ L[i] = (uint32(in[i]) & uint32((neg3))) | 1
+ }
+
+ cryptoSortUint32(L, p)
+
+ for i := 0; i < p; i++ {
+ out[i] = small((L[i] & 3) - 1)
+ }
+}
+
+// Underlying hash function
+
+// The input byte array, in, is prepended by the byte b
+// and its SHA-512 hash is calculated
+// Only the first 32 bytes of the hash are returned
+// e.g., b = 0 means out = Hash0(in)
+func hashPrefix(out []byte, b int, in []byte, inlen int) {
+ x := make([]byte, inlen+1)
+ h := make([]byte, 64)
+
+ x[0] = byte(b)
+ copy(x[1:], in)
+
+ hash := sha512.New()
+ hash.Write([]byte(x))
+ h = hash.Sum(nil)
+
+ copy(out, h[:32])
+
+}
+
+// Higher level randomness
+// Returns a random unsigned integer
+func urandom32(seed []byte) uint32 {
+ var out [4]uint32
+
+ out[0] = uint32(seed[0])
+ out[1] = uint32(seed[1]) << 8
+ out[2] = uint32(seed[2]) << 16
+ out[3] = uint32(seed[3]) << 24
+ return out[0] + out[1] + out[2] + out[3]
+}
+
+// Generates a random short polynomial
+func shortRandom(out []small, seed []byte) {
+
+ L := make([]uint32, p)
+
+ for i := 0; i < p; i++ {
+ L[i] = urandom32(seed[4*i : 4*i+4])
+ }
+
+ // Converts uint32 array to int32 array
+ L_int32 := make([]int32, p)
+ for i := 0; i < len(L); i++ {
+ L_int32[i] = int32(L[i])
+ }
+ shortFromList(out, L_int32)
+}
+
+// Generates a random list of small
+func smallRandom(out []small, seed []byte) {
+ for i := 0; i < p; i++ {
+ out[i] = small(((urandom32(seed[4*i:4*i+4])&0x3fffffff)*3)>>30) - 1
+ }
+}
+
+// Streamlined NTRU Prime Core
+
+// h,(f,ginv) = keyGen()
+func keyGen(h []Fq, f []small, ginv []small, gen *io.Reader) {
+ g := make([]small, p)
+ seed := make([]byte, 4*p+4*p)
+
+ if gen == nil {
+ for {
+ cryptoRand.Read(seed[:4*p])
+ smallRandom(g, seed[:4*p])
+ if r3Recip(ginv, g) == 0 {
+ break
+ }
+ }
+ cryptoRand.Read(seed[4*p:])
+ } else {
+ for {
+ for i := 0; i < p; i++ {
+ (*gen).Read(seed[4*i : 4*i+4])
+ }
+ smallRandom(g, seed[:4*p])
+ if r3Recip(ginv, g) == 0 {
+ break
+ }
+ }
+ for i := 0; i < p; i++ {
+ (*gen).Read(seed[4*p+4*i : 4*p+4*i+4])
+ }
+ }
+ shortRandom(f, seed[4*p:])
+
+ finv := make([]Fq, p)
+
+ rqRecip3(finv, f) /* always works */
+ rqMultSmall(h, finv, g)
+}
+
+// c = encrypt(r,h)
+func encrypt(c []Fq, r []small, h []Fq) {
+ hr := make([]Fq, p)
+
+ rqMultSmall(hr, h, r)
+ round(c, hr)
+}
+
+// r = decrypt(c,(f,ginv))
+func decrypt(r []small, c []Fq, f []small, ginv []small) {
+ cf := make([]Fq, p)
+ cf3 := make([]Fq, p)
+ e := make([]small, p)
+ ev := make([]small, p)
+
+ rqMultSmall(cf, c, f)
+ rqMult3(cf3, cf)
+ r3FromRq(e, cf3)
+ r3Mult(ev, e, ginv)
+
+ mask := weightwMask(ev) /* 0 if weight w, else -1 */
+ for i := 0; i < w; i++ {
+ r[i] = ((ev[i] ^ 1) & small(^mask)) ^ 1
+ }
+
+ for i := w; i < p; i++ {
+ r[i] = ev[i] & small(^mask)
+ }
+}
+
+// Encoding small polynomials (including short polynomials)
+
+// Transform polynomial in R to bytes
+// these are the only functions that rely on p mod 4 = 1 */
+func smallEncode(s []byte, f []small) {
+ var x small
+ var index int = 0
+ for i := 0; i < p/4; i++ {
+ x = f[index] + 1
+ index++
+
+ x += (f[index] + 1) << 2
+ index++
+ x += (f[index] + 1) << 4
+ index++
+ x += (f[index] + 1) << 6
+ index++
+
+ s[0] = byte(x)
+ s = s[1:]
+ }
+ x = f[index] + 1
+
+ s[0] = byte(x)
+}
+
+// Transform bytes into polynomial in R
+func smallDecode(f []small, s []byte) {
+ var index int = 0
+ var x byte
+
+ for i := 0; i < p/4; i++ {
+ x = s[0]
+ s = s[1:]
+
+ f[index] = ((small)(x & 3)) - 1
+ x >>= 2
+ index++
+ f[index] = ((small)(x & 3)) - 1
+ x >>= 2
+ index++
+ f[index] = ((small)(x & 3)) - 1
+ x >>= 2
+ index++
+ f[index] = ((small)(x & 3)) - 1
+ index++
+ }
+ x = s[0]
+ f[index] = ((small)(x & 3)) - 1
+}
+
+// Encoding general polynomials
+
+// Transform polynomials in R/q to bytes
+func rqEncode(s []byte, r []Fq) {
+ R := make([]uint16, p)
+ M := make([]uint16, p)
+
+ for i := 0; i < p; i++ {
+ R[i] = uint16(r[i] + q12)
+ M[i] = q
+ }
+ internal.Encode(s, R, M, p)
+}
+
+// Transform polynomials in R/q from bytes
+func rqDecode(r []Fq, s []byte) {
+ R := make([]uint16, p)
+ M := make([]uint16, p)
+
+ for i := 0; i < p; i++ {
+ M[i] = q
+ }
+ internal.Decode(R, s, M, p)
+ for i := 0; i < p; i++ {
+ r[i] = ((Fq)(R[i])) - q12
+ }
+
+}
+
+// Encoding rounded polynomials
+
+// Transform rounded polynomials to bytes
+func roundedEncode(s []byte, r []Fq) {
+
+ R := make([]uint16, p)
+ M := make([]uint16, p)
+
+ for i := 0; i < p; i++ {
+ R[i] = uint16((int32((r[i])+q12) * 10923) >> 15)
+ M[i] = (q + 2) / 3
+ }
+ internal.Encode(s, R, M, p)
+}
+
+// Transform bytes to rounded polynomials
+func roundedDecode(r []Fq, s []byte) {
+ R := make([]uint16, p)
+ M := make([]uint16, p)
+
+ for i := 0; i < p; i++ {
+ M[i] = (q + 2) / 3
+ }
+ internal.Decode(R, s, M, p)
+ for i := 0; i < p; i++ {
+ r[i] = Fq(R[i]*3 - q12)
+ }
+
+}
+
+// Streamlined NTRU Prime Core plus encoding
+
+// Generates public key and private key
+// pk,sk = zKeyGen()
+func zKeyGen(pk []byte, sk []byte, gen *io.Reader) {
+
+ h := make([]Fq, p)
+ f := make([]small, p)
+ v := make([]small, p)
+ keyGen(h, f, v, gen)
+
+ rqEncode(pk, h)
+ smallEncode(sk, f)
+ sk = sk[smallBytes:]
+ smallEncode(sk, v)
+
+}
+
+// C = zEncrypt(r,pk)
+func zEncrypt(C []byte, r Inputs, pk []byte) {
+ h := make([]Fq, p)
+ c := make([]Fq, p)
+ rqDecode(h, pk)
+ encrypt(c, r[:], h)
+ roundedEncode(C, c)
+}
+
+// r = zDecrypt(C,sk)
+func zDecrypt(r *Inputs, C []byte, sk []byte) {
+ f := make([]small, p)
+ v := make([]small, p)
+ c := make([]Fq, p)
+
+ smallDecode(f, sk)
+ sk = sk[smallBytes:]
+ smallDecode(v, sk)
+ roundedDecode(c, C)
+
+ decrypt(r[:], c, f, v)
+}
+
+// Confirmation hash
+
+// h = hashConfirm(r,pk,cache); cache is Hash4(pk)
+func hashConfirm(h []byte, r []byte, pk []byte, cache []byte) {
+ x := make([]byte, hashBytes*2)
+
+ hashPrefix(x, 3, r, inputsBytes)
+
+ copy(x[hashBytes:], cache[:hashBytes])
+
+ hashPrefix(h, 2, x, len(x))
+
+}
+
+// Session-key hash
+
+// k = hashSession(b,y,z)
+func hashSession(k []byte, b int, y []byte, z []byte) {
+ x := make([]byte, hashBytes+ciphertextsBytes+confirmBytes)
+
+ hashPrefix(x, 3, y, inputsBytes)
+
+ copy(x[hashBytes:], z[:ciphertextsBytes+confirmBytes])
+
+ hashPrefix(k, b, x, len(x))
+
+}
+
+// Streamlined NTRU Prime
+
+// pk,sk = kemKeyGen()
+func kemKeyGen(pk []byte, sk []byte, gen *io.Reader) {
+ zKeyGen(pk, sk, gen)
+ sk = sk[secretKeysBytes:]
+
+ copy(sk, pk)
+ sk = sk[publicKeysBytes:]
+
+ if gen != nil {
+ (*gen).Read(sk[:inputsBytes])
+
+ } else {
+ cryptoRand.Read(sk[:inputsBytes])
+ }
+ sk = sk[inputsBytes:]
+ hashPrefix(sk, 4, pk, publicKeysBytes)
+
+}
+
+// c,r_enc = hide(r,pk,cache); cache is Hash4(pk)
+func hide(c []byte, r_enc []byte, r Inputs, pk []byte, cache []byte) {
+ smallEncode(r_enc, r[:])
+ zEncrypt(c, r, pk)
+ c = c[ciphertextsBytes:]
+ hashConfirm(c, r_enc, pk, cache)
+
+}
+
+// Takes as input a public key
+// Returns ciphertext and shared key
+// c,k = encap(pk)
+func (pub PublicKey) EncapsulateTo(c []byte, k []byte, seed []byte) {
+ if seed == nil {
+ seed = make([]byte, 4*p)
+ cryptoRand.Read(seed)
+ }
+ if len(seed) != 4*p {
+ panic("seed must be of length EncapsulationSeedSize")
+ }
+ if len(c) != CiphertextSize {
+ panic("ct must be of length CiphertextSize")
+ }
+ if len(k) != SharedKeySize {
+ panic("ss must be of length SharedKeySize")
+ }
+
+ pk := pub.pk[:]
+
+ var r Inputs
+ r_enc := make([]byte, inputsBytes)
+ cache := make([]byte, hashBytes)
+
+ hashPrefix(cache, 4, pk, publicKeysBytes)
+ shortRandom(r[:], seed)
+ hide(c, r_enc, r, pk, cache)
+ hashSession(k, 1, r_enc, c)
+
+}
+
+// Returns 0 if matching ciphertext+confirm, else -1
+func ciphertexts_diff_mask(c []byte, c2 []byte) int {
+ var differentbits uint16 = 0
+ var len int = ciphertextsBytes + confirmBytes
+
+ for i := 0; i < len; i++ {
+ differentbits |= uint16((c[i]) ^ (c2[i]))
+ }
+ return int((1 & ((differentbits - 1) >> 8)) - 1)
+
+}
+
+// Returns shared key from ciphertext and private key
+// k = decap(c,sk)
+func (priv *PrivateKey) DecapsulateTo(k []byte, c []byte) {
+ if len(c) != CiphertextSize {
+ panic("ct must be of length CiphertextSize")
+ }
+
+ if len(k) != SharedKeySize {
+ panic("ss must be of length SharedKeySize")
+ }
+
+ sk := priv.sk[:]
+
+ pk := sk[secretKeysBytes:]
+ rho := pk[publicKeysBytes:]
+ cache := rho[inputsBytes:]
+ var r Inputs
+
+ r_enc := make([]byte, inputsBytes)
+ cnew := make([]byte, ciphertextsBytes+confirmBytes)
+
+ zDecrypt(&r, c, sk)
+ hide(cnew, r_enc, r, pk, cache)
+ var mask int = ciphertexts_diff_mask(c, cnew)
+
+ for i := 0; i < inputsBytes; i++ {
+ r_enc[i] ^= byte(mask & int(r_enc[i]^rho[i]))
+ }
+ hashSession(k, 1+mask, r_enc, c)
+}
+
+// The structure of the private key is given by the following segments:
+// The secret key, the public key, entropy and the hash of the public key
+type PrivateKey struct {
+ sk [PrivateKeySize]byte
+}
+
+type PublicKey struct {
+ pk [PublicKeySize]byte
+}
+
+type scheme struct{}
+
+var sch sntrupKem.Scheme = &scheme{}
+
+// Scheme returns a KEM interface.
+func Scheme() kem.Scheme { return sch }
+
+// SntrupScheme returns a sntrup.KEM interface
+func SntrupScheme() sntrupKem.Scheme { return sch }
+
+func (*scheme) Name() string { return "sntrup761" }
+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
+ copy(ret[:], sk.sk[:])
+ return ret[:], nil
+}
+
+func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
+ oth, ok := other.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ return bytes.Equal(sk.sk[:], oth.sk[:])
+}
+
+func (pk *PublicKey) Equal(other kem.PublicKey) bool {
+ oth, ok := other.(*PublicKey)
+ if !ok {
+ return false
+ }
+ return bytes.Equal(pk.pk[:], oth.pk[:])
+}
+
+func (sk *PrivateKey) Public() kem.PublicKey {
+ var pk [PublicKeySize]byte
+ skey, _ := sk.MarshalBinary()
+ ppk := skey[secretKeysBytes : secretKeysBytes+publicKeysBytes]
+ copy(pk[:], ppk[:])
+ return &PublicKey{pk: pk}
+}
+
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+ var ret [PublicKeySize]byte
+ copy(ret[:], pk.pk[:])
+ return ret[:], nil
+}
+
+func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+ var pk [PublicKeySize]byte
+ var sk [PrivateKeySize]byte
+ kemKeyGen(pk[:], sk[:], nil)
+
+ return &PublicKey{pk: pk}, &PrivateKey{sk: sk}, nil
+
+}
+
+// Not used
+func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+ return nil, nil
+}
+
+func (*scheme) DeriveKeyPairFromGen(gen *io.Reader) (kem.PublicKey, kem.PrivateKey) {
+
+ if gen == nil {
+ panic("A nist DRBG must be provided")
+ }
+
+ var pk [PublicKeySize]byte
+ var sk [PrivateKeySize]byte
+
+ kemKeyGen(pk[:], sk[:], gen)
+
+ return &PublicKey{pk: pk}, &PrivateKey{sk: sk}
+}
+
+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 ct, ss, nil
+
+}
+
+func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (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, seed)
+
+ return ct, ss, nil
+}
+
+func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+ ssk, ok := sk.(*PrivateKey)
+ if !ok {
+ return nil, kem.ErrTypeMismatch
+ }
+
+ if len(ct) != CiphertextSize {
+ return nil, kem.ErrCiphertextSize
+ }
+ ss := [SharedKeySize]byte{}
+
+ ssk.DecapsulateTo(ss[:], ct)
+
+ return ss[:], nil
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+ if len(buf) != PublicKeySize {
+ return nil, kem.ErrPubKeySize
+ }
+ pk := [PublicKeySize]byte{}
+ copy(pk[:], buf)
+ return &PublicKey{pk: pk}, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+ if len(buf) != PrivateKeySize {
+ return nil, kem.ErrPrivKeySize
+ }
+ sk := [PrivateKeySize]byte{}
+ copy(sk[:], buf)
+ return &PrivateKey{sk: sk}, nil
+}
--- /dev/null
+// Package kem provides a unified interface for Streamlined NTRU Prime KEM schemes.
+package kem
+
+import (
+ "io"
+
+ "go.stargrave.org/vors/v5/pqhs/sntrup761/kem"
+)
+
+// A Scheme represents a specific instance of a NTRU PRIME KEM.
+type Scheme interface {
+ kem.Scheme
+
+ // DeriveKeyPairFromGen deterministicallly derives a pair of keys from a nist DRBG.
+ // Only used for deterministic testing
+ DeriveKeyPairFromGen(gen *io.Reader) (kem.PublicKey, kem.PrivateKey)
+}
--- /dev/null
+// Package schemes contains a register of Streamlined NTRU Prime KEM schemes.
+//
+// # Schemes Implemented
+//
+// Post-quantum kems:
+//
+// SNTRUP653, SNTRUP761, SNTRUP857, SNTRUP953, SNTRUP1013, SNTRUP1277
+package sntrupSchemes
+
+import (
+ "strings"
+
+ "go.stargrave.org/vors/v5/pqhs/sntrup761/kem/ntruprime/sntrup761"
+ "go.stargrave.org/vors/v5/pqhs/sntrup761/pke/ntruprime/kem"
+)
+
+var allSchemes = [...]kem.Scheme{
+ sntrup761.SntrupScheme(),
+}
+
+var allSchemeNames map[string]kem.Scheme
+
+func init() {
+ allSchemeNames = make(map[string]kem.Scheme)
+ for _, scheme := range allSchemes {
+ allSchemeNames[strings.ToLower(scheme.Name())] = scheme
+ }
+}
+
+// ByName returns the scheme with the given name and nil if it is not
+// supported.
+//
+// Names are case insensitive.
+func ByName(name string) kem.Scheme {
+ return allSchemeNames[strings.ToLower(name)]
+}
+
+// All returns all KEM schemes supported.
+func All() []kem.Scheme { a := allSchemes; return a[:] }
--- /dev/null
+// Code generated from sntrup.params.templ.go. DO NOT EDIT.
+package ntruprime
+
+const (
+ P = 761
+ Q = 4591
+ RoundedBytes = 1007
+ RqBytes = 1158
+ W = 286
+)
+
+const (
+
+ // Size of the established shared key.
+ SharedKeySize = 32
+
+ // Size of the encapsulated shared key.
+ CiphertextSize = 1039
+
+ // Size of a packed public key.
+ PublicKeySize = 1158
+
+ // Size of a packed private key.
+ PrivateKeySize = 1763
+)
--- /dev/null
+package pqhs
+
+import (
+ "crypto/cipher"
+ "crypto/hkdf"
+ "crypto/sha3"
+
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+type SymmetricState struct {
+ h, ck []byte
+}
+
+func (state *SymmetricState) K(ctx string) []byte {
+ k, err := hkdf.Expand(NewSHAKE256, state.ck, ctx, chacha20poly1305.KeySize)
+ if err != nil {
+ panic(err)
+ }
+ return k
+}
+
+func (state *SymmetricState) H(data []byte) {
+ state.h = sha3.SumSHAKE256(append(state.h, data...), 64)
+}
+
+func (state *SymmetricState) CK(key []byte) {
+ var err error
+ state.ck, err = hkdf.Extract(NewSHAKE256, key, state.ck)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (state *SymmetricState) Seal(ctx string, data []byte) []byte {
+ aead, err := chacha20poly1305.New(state.K(ctx))
+ if err != nil {
+ panic(err)
+ }
+ ct := aead.Seal(nil, make([]byte, aead.NonceSize()), data, state.h)
+ state.H(ct)
+ return ct
+}
+
+func (state *SymmetricState) Open(ctx string, ct []byte) (pt []byte, err error) {
+ var aead cipher.AEAD
+ aead, err = chacha20poly1305.New(state.K(ctx))
+ if err != nil {
+ panic(err)
+ }
+ pt, err = aead.Open(nil, make([]byte, aead.NonceSize()), ct, state.h)
+ if err == nil {
+ state.H(ct)
+ }
+ return
+}
+
+func (state *SymmetricState) Binding(l int) []byte {
+ binding, err := hkdf.Expand(NewSHAKE256, state.ck, string(state.h), l)
+ if err != nil {
+ panic(err)
+ }
+ return binding
+}