Bump github.com/hashicorp/terraform-plugin-sdk/v2 from 2.26.1 to 2.27.0

Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.26.1 to 2.27.0.
- [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.26.1...v2.27.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-07-03 20:21:30 +00:00
committed by GitHub
parent b2403e2569
commit 910ccdb092
722 changed files with 31260 additions and 8125 deletions

View File

@ -0,0 +1,453 @@
// Package ed25519 implements Ed25519 signature scheme as described in RFC-8032.
//
// This package provides optimized implementations of the three signature
// variants and maintaining closer compatiblilty with crypto/ed25519.
//
// | Scheme Name | Sign Function | Verification | Context |
// |-------------|-------------------|---------------|-------------------|
// | Ed25519 | Sign | Verify | None |
// | Ed25519Ph | SignPh | VerifyPh | Yes, can be empty |
// | Ed25519Ctx | SignWithCtx | VerifyWithCtx | Yes, non-empty |
// | All above | (PrivateKey).Sign | VerifyAny | As above |
//
// Specific functions for sign and verify are defined. A generic signing
// function for all schemes is available through the crypto.Signer interface,
// which is implemented by the PrivateKey type. A correspond all-in-one
// verification method is provided by the VerifyAny function.
//
// Signing with Ed25519Ph or Ed25519Ctx requires a context string for domain
// separation. This parameter is passed using a SignerOptions struct defined
// in this package. While Ed25519Ph accepts an empty context, Ed25519Ctx
// enforces non-empty context strings.
//
// # Compatibility with crypto.ed25519
//
// These functions are compatible with the “Ed25519” function defined in
// RFC-8032. However, unlike RFC 8032's formulation, this package's private
// key representation includes a public key suffix to make multiple signing
// operations with the same key more efficient. This package refers to the
// RFC-8032 private key as the “seed”.
//
// References
//
// - RFC-8032: https://rfc-editor.org/rfc/rfc8032.txt
// - Ed25519: https://ed25519.cr.yp.to/
// - EdDSA: High-speed high-security signatures. https://doi.org/10.1007/s13389-012-0027-1
package ed25519
import (
"bytes"
"crypto"
cryptoRand "crypto/rand"
"crypto/sha512"
"crypto/subtle"
"errors"
"fmt"
"io"
"strconv"
"github.com/cloudflare/circl/sign"
)
const (
// ContextMaxSize is the maximum length (in bytes) allowed for context.
ContextMaxSize = 255
// PublicKeySize is the size, in bytes, of public keys as used in this package.
PublicKeySize = 32
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
PrivateKeySize = 64
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
SignatureSize = 64
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
SeedSize = 32
)
const (
paramB = 256 / 8 // Size of keys in bytes.
)
// SignerOptions implements crypto.SignerOpts and augments with parameters
// that are specific to the Ed25519 signature schemes.
type SignerOptions struct {
// Hash must be crypto.Hash(0) for Ed25519/Ed25519ctx, or crypto.SHA512
// for Ed25519ph.
crypto.Hash
// Context is an optional domain separation string for Ed25519ph and a
// must for Ed25519ctx. Its length must be less or equal than 255 bytes.
Context string
// Scheme is an identifier for choosing a signature scheme. The zero value
// is ED25519.
Scheme SchemeID
}
// SchemeID is an identifier for each signature scheme.
type SchemeID uint
const (
ED25519 SchemeID = iota
ED25519Ph
ED25519Ctx
)
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
type PrivateKey []byte
// Equal reports whether priv and x have the same value.
func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
xx, ok := x.(PrivateKey)
return ok && subtle.ConstantTimeCompare(priv, xx) == 1
}
// Public returns the PublicKey corresponding to priv.
func (priv PrivateKey) Public() crypto.PublicKey {
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, priv[SeedSize:])
return publicKey
}
// Seed returns the private key seed corresponding to priv. It is provided for
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
// in this package.
func (priv PrivateKey) Seed() []byte {
seed := make([]byte, SeedSize)
copy(seed, priv[:SeedSize])
return seed
}
func (priv PrivateKey) Scheme() sign.Scheme { return sch }
func (pub PublicKey) Scheme() sign.Scheme { return sch }
func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
privateKey := make(PrivateKey, PrivateKeySize)
copy(privateKey, priv)
return privateKey, nil
}
func (pub PublicKey) MarshalBinary() (data []byte, err error) {
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, pub)
return publicKey, nil
}
// Equal reports whether pub and x have the same value.
func (pub PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
return ok && bytes.Equal(pub, xx)
}
// Sign creates a signature of a message with priv key.
// This function is compatible with crypto.ed25519 and also supports the
// three signature variants defined in RFC-8032, namely Ed25519 (or pure
// EdDSA), Ed25519Ph, and Ed25519Ctx.
// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
// variant. This can be achieved by passing crypto.Hash(0) as the value for
// opts.
// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
// This can be achieved by passing crypto.SHA512 as the value for opts.
// Use a SignerOptions struct (defined in this package) to pass a context
// string for signing.
func (priv PrivateKey) Sign(
rand io.Reader,
message []byte,
opts crypto.SignerOpts,
) (signature []byte, err error) {
var ctx string
var scheme SchemeID
if o, ok := opts.(SignerOptions); ok {
ctx = o.Context
scheme = o.Scheme
}
switch true {
case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
return Sign(priv, message), nil
case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
return SignPh(priv, message, ctx), nil
case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
return SignWithCtx(priv, message, ctx), nil
default:
return nil, errors.New("ed25519: bad hash algorithm")
}
}
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
if rand == nil {
rand = cryptoRand.Reader
}
seed := make([]byte, SeedSize)
if _, err := io.ReadFull(rand, seed); err != nil {
return nil, nil, err
}
privateKey := NewKeyFromSeed(seed)
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, privateKey[SeedSize:])
return publicKey, privateKey, nil
}
// NewKeyFromSeed calculates a private key from a seed. It will panic if
// len(seed) is not SeedSize. This function is provided for interoperability
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
privateKey := make(PrivateKey, PrivateKeySize)
newKeyFromSeed(privateKey, seed)
return privateKey
}
func newKeyFromSeed(privateKey, seed []byte) {
if l := len(seed); l != SeedSize {
panic("ed25519: bad seed length: " + strconv.Itoa(l))
}
var P pointR1
k := sha512.Sum512(seed)
clamp(k[:])
reduceModOrder(k[:paramB], false)
P.fixedMult(k[:paramB])
copy(privateKey[:SeedSize], seed)
_ = P.ToBytes(privateKey[SeedSize:])
}
func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
if l := len(privateKey); l != PrivateKeySize {
panic("ed25519: bad private key length: " + strconv.Itoa(l))
}
H := sha512.New()
var PHM []byte
if preHash {
_, _ = H.Write(message)
PHM = H.Sum(nil)
H.Reset()
} else {
PHM = message
}
// 1. Hash the 32-byte private key using SHA-512.
_, _ = H.Write(privateKey[:SeedSize])
h := H.Sum(nil)
clamp(h[:])
prefix, s := h[paramB:], h[:paramB]
// 2. Compute SHA-512(dom2(F, C) || prefix || PH(M))
H.Reset()
writeDom(H, ctx, preHash)
_, _ = H.Write(prefix)
_, _ = H.Write(PHM)
r := H.Sum(nil)
reduceModOrder(r[:], true)
// 3. Compute the point [r]B.
var P pointR1
P.fixedMult(r[:paramB])
R := (&[paramB]byte{})[:]
if err := P.ToBytes(R); err != nil {
panic(err)
}
// 4. Compute SHA512(dom2(F, C) || R || A || PH(M)).
H.Reset()
writeDom(H, ctx, preHash)
_, _ = H.Write(R)
_, _ = H.Write(privateKey[SeedSize:])
_, _ = H.Write(PHM)
hRAM := H.Sum(nil)
reduceModOrder(hRAM[:], true)
// 5. Compute S = (r + k * s) mod order.
S := (&[paramB]byte{})[:]
calculateS(S, r[:paramB], hRAM[:paramB], s)
// 6. The signature is the concatenation of R and S.
copy(signature[:paramB], R[:])
copy(signature[paramB:], S[:])
}
// Sign signs the message with privateKey and returns a signature.
// This function supports the signature variant defined in RFC-8032: Ed25519,
// also known as the pure version of EdDSA.
// It will panic if len(privateKey) is not PrivateKeySize.
func Sign(privateKey PrivateKey, message []byte) []byte {
signature := make([]byte, SignatureSize)
signAll(signature, privateKey, message, []byte(""), false)
return signature
}
// SignPh creates a signature of a message with private key and context.
// This function supports the signature variant defined in RFC-8032: Ed25519ph,
// meaning it internally hashes the message using SHA-512, and optionally
// accepts a context string.
// It will panic if len(privateKey) is not PrivateKeySize.
// Context could be passed to this function, which length should be no more than
// ContextMaxSize=255. It can be empty.
func SignPh(privateKey PrivateKey, message []byte, ctx string) []byte {
if len(ctx) > ContextMaxSize {
panic(fmt.Errorf("ed25519: bad context length: %v", len(ctx)))
}
signature := make([]byte, SignatureSize)
signAll(signature, privateKey, message, []byte(ctx), true)
return signature
}
// SignWithCtx creates a signature of a message with private key and context.
// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
// meaning it accepts a non-empty context string.
// It will panic if len(privateKey) is not PrivateKeySize.
// Context must be passed to this function, which length should be no more than
// ContextMaxSize=255 and cannot be empty.
func SignWithCtx(privateKey PrivateKey, message []byte, ctx string) []byte {
if len(ctx) == 0 || len(ctx) > ContextMaxSize {
panic(fmt.Errorf("ed25519: bad context length: %v > %v", len(ctx), ContextMaxSize))
}
signature := make([]byte, SignatureSize)
signAll(signature, privateKey, message, []byte(ctx), false)
return signature
}
func verify(public PublicKey, message, signature, ctx []byte, preHash bool) bool {
if len(public) != PublicKeySize ||
len(signature) != SignatureSize ||
!isLessThanOrder(signature[paramB:]) {
return false
}
var P pointR1
if ok := P.FromBytes(public); !ok {
return false
}
H := sha512.New()
var PHM []byte
if preHash {
_, _ = H.Write(message)
PHM = H.Sum(nil)
H.Reset()
} else {
PHM = message
}
R := signature[:paramB]
writeDom(H, ctx, preHash)
_, _ = H.Write(R)
_, _ = H.Write(public)
_, _ = H.Write(PHM)
hRAM := H.Sum(nil)
reduceModOrder(hRAM[:], true)
var Q pointR1
encR := (&[paramB]byte{})[:]
P.neg()
Q.doubleMult(&P, signature[paramB:], hRAM[:paramB])
_ = Q.ToBytes(encR)
return bytes.Equal(R, encR)
}
// VerifyAny returns true if the signature is valid. Failure cases are invalid
// signature, or when the public key cannot be decoded.
// This function supports all the three signature variants defined in RFC-8032,
// namely Ed25519 (or pure EdDSA), Ed25519Ph, and Ed25519Ctx.
// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
// variant. This can be achieved by passing crypto.Hash(0) as the value for opts.
// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
// This can be achieved by passing crypto.SHA512 as the value for opts.
// Use a SignerOptions struct to pass a context string for signing.
func VerifyAny(public PublicKey, message, signature []byte, opts crypto.SignerOpts) bool {
var ctx string
var scheme SchemeID
if o, ok := opts.(SignerOptions); ok {
ctx = o.Context
scheme = o.Scheme
}
switch true {
case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
return Verify(public, message, signature)
case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
return VerifyPh(public, message, signature, ctx)
case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
return VerifyWithCtx(public, message, signature, ctx)
default:
return false
}
}
// Verify returns true if the signature is valid. Failure cases are invalid
// signature, or when the public key cannot be decoded.
// This function supports the signature variant defined in RFC-8032: Ed25519,
// also known as the pure version of EdDSA.
func Verify(public PublicKey, message, signature []byte) bool {
return verify(public, message, signature, []byte(""), false)
}
// VerifyPh returns true if the signature is valid. Failure cases are invalid
// signature, or when the public key cannot be decoded.
// This function supports the signature variant defined in RFC-8032: Ed25519ph,
// meaning it internally hashes the message using SHA-512.
// Context could be passed to this function, which length should be no more than
// 255. It can be empty.
func VerifyPh(public PublicKey, message, signature []byte, ctx string) bool {
return verify(public, message, signature, []byte(ctx), true)
}
// VerifyWithCtx returns true if the signature is valid. Failure cases are invalid
// signature, or when the public key cannot be decoded, or when context is
// not provided.
// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
// meaning it does not handle prehashed messages. Non-empty context string must be
// provided, and must not be more than 255 of length.
func VerifyWithCtx(public PublicKey, message, signature []byte, ctx string) bool {
if len(ctx) == 0 || len(ctx) > ContextMaxSize {
return false
}
return verify(public, message, signature, []byte(ctx), false)
}
func clamp(k []byte) {
k[0] &= 248
k[paramB-1] = (k[paramB-1] & 127) | 64
}
// isLessThanOrder returns true if 0 <= x < order.
func isLessThanOrder(x []byte) bool {
i := len(order) - 1
for i > 0 && x[i] == order[i] {
i--
}
return x[i] < order[i]
}
func writeDom(h io.Writer, ctx []byte, preHash bool) {
dom2 := "SigEd25519 no Ed25519 collisions"
if len(ctx) > 0 {
_, _ = h.Write([]byte(dom2))
if preHash {
_, _ = h.Write([]byte{byte(0x01), byte(len(ctx))})
} else {
_, _ = h.Write([]byte{byte(0x00), byte(len(ctx))})
}
_, _ = h.Write(ctx)
} else if preHash {
_, _ = h.Write([]byte(dom2))
_, _ = h.Write([]byte{0x01, 0x00})
}
}

View File

@ -0,0 +1,175 @@
package ed25519
import (
"encoding/binary"
"math/bits"
)
var order = [paramB]byte{
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
}
// isLessThan returns true if 0 <= x < y, and assumes that slices have the same length.
func isLessThan(x, y []byte) bool {
i := len(x) - 1
for i > 0 && x[i] == y[i] {
i--
}
return x[i] < y[i]
}
// reduceModOrder calculates k = k mod order of the curve.
func reduceModOrder(k []byte, is512Bit bool) {
var X [((2 * paramB) * 8) / 64]uint64
numWords := len(k) >> 3
for i := 0; i < numWords; i++ {
X[i] = binary.LittleEndian.Uint64(k[i*8 : (i+1)*8])
}
red512(&X, is512Bit)
for i := 0; i < numWords; i++ {
binary.LittleEndian.PutUint64(k[i*8:(i+1)*8], X[i])
}
}
// red512 calculates x = x mod Order of the curve.
func red512(x *[8]uint64, full bool) {
// Implementation of Algs.(14.47)+(14.52) of Handbook of Applied
// Cryptography, by A. Menezes, P. van Oorschot, and S. Vanstone.
const (
ell0 = uint64(0x5812631a5cf5d3ed)
ell1 = uint64(0x14def9dea2f79cd6)
ell160 = uint64(0x812631a5cf5d3ed0)
ell161 = uint64(0x4def9dea2f79cd65)
ell162 = uint64(0x0000000000000001)
)
var c0, c1, c2, c3 uint64
r0, r1, r2, r3, r4 := x[0], x[1], x[2], x[3], uint64(0)
if full {
q0, q1, q2, q3 := x[4], x[5], x[6], x[7]
for i := 0; i < 3; i++ {
h0, s0 := bits.Mul64(q0, ell160)
h1, s1 := bits.Mul64(q1, ell160)
h2, s2 := bits.Mul64(q2, ell160)
h3, s3 := bits.Mul64(q3, ell160)
s1, c0 = bits.Add64(h0, s1, 0)
s2, c1 = bits.Add64(h1, s2, c0)
s3, c2 = bits.Add64(h2, s3, c1)
s4, _ := bits.Add64(h3, 0, c2)
h0, l0 := bits.Mul64(q0, ell161)
h1, l1 := bits.Mul64(q1, ell161)
h2, l2 := bits.Mul64(q2, ell161)
h3, l3 := bits.Mul64(q3, ell161)
l1, c0 = bits.Add64(h0, l1, 0)
l2, c1 = bits.Add64(h1, l2, c0)
l3, c2 = bits.Add64(h2, l3, c1)
l4, _ := bits.Add64(h3, 0, c2)
s1, c0 = bits.Add64(s1, l0, 0)
s2, c1 = bits.Add64(s2, l1, c0)
s3, c2 = bits.Add64(s3, l2, c1)
s4, c3 = bits.Add64(s4, l3, c2)
s5, s6 := bits.Add64(l4, 0, c3)
s2, c0 = bits.Add64(s2, q0, 0)
s3, c1 = bits.Add64(s3, q1, c0)
s4, c2 = bits.Add64(s4, q2, c1)
s5, c3 = bits.Add64(s5, q3, c2)
s6, s7 := bits.Add64(s6, 0, c3)
q := q0 | q1 | q2 | q3
m := -((q | -q) >> 63) // if q=0 then m=0...0 else m=1..1
s0 &= m
s1 &= m
s2 &= m
s3 &= m
q0, q1, q2, q3 = s4, s5, s6, s7
if (i+1)%2 == 0 {
r0, c0 = bits.Add64(r0, s0, 0)
r1, c1 = bits.Add64(r1, s1, c0)
r2, c2 = bits.Add64(r2, s2, c1)
r3, c3 = bits.Add64(r3, s3, c2)
r4, _ = bits.Add64(r4, 0, c3)
} else {
r0, c0 = bits.Sub64(r0, s0, 0)
r1, c1 = bits.Sub64(r1, s1, c0)
r2, c2 = bits.Sub64(r2, s2, c1)
r3, c3 = bits.Sub64(r3, s3, c2)
r4, _ = bits.Sub64(r4, 0, c3)
}
}
m := -(r4 >> 63)
r0, c0 = bits.Add64(r0, m&ell160, 0)
r1, c1 = bits.Add64(r1, m&ell161, c0)
r2, c2 = bits.Add64(r2, m&ell162, c1)
r3, c3 = bits.Add64(r3, 0, c2)
r4, _ = bits.Add64(r4, m&1, c3)
x[4], x[5], x[6], x[7] = 0, 0, 0, 0
}
q0 := (r4 << 4) | (r3 >> 60)
r3 &= (uint64(1) << 60) - 1
h0, s0 := bits.Mul64(ell0, q0)
h1, s1 := bits.Mul64(ell1, q0)
s1, c0 = bits.Add64(h0, s1, 0)
s2, _ := bits.Add64(h1, 0, c0)
r0, c0 = bits.Sub64(r0, s0, 0)
r1, c1 = bits.Sub64(r1, s1, c0)
r2, c2 = bits.Sub64(r2, s2, c1)
r3, _ = bits.Sub64(r3, 0, c2)
x[0], x[1], x[2], x[3] = r0, r1, r2, r3
}
// calculateS performs s = r+k*a mod Order of the curve.
func calculateS(s, r, k, a []byte) {
K := [4]uint64{
binary.LittleEndian.Uint64(k[0*8 : 1*8]),
binary.LittleEndian.Uint64(k[1*8 : 2*8]),
binary.LittleEndian.Uint64(k[2*8 : 3*8]),
binary.LittleEndian.Uint64(k[3*8 : 4*8]),
}
S := [8]uint64{
binary.LittleEndian.Uint64(r[0*8 : 1*8]),
binary.LittleEndian.Uint64(r[1*8 : 2*8]),
binary.LittleEndian.Uint64(r[2*8 : 3*8]),
binary.LittleEndian.Uint64(r[3*8 : 4*8]),
}
var c3 uint64
for i := range K {
ai := binary.LittleEndian.Uint64(a[i*8 : (i+1)*8])
h0, l0 := bits.Mul64(K[0], ai)
h1, l1 := bits.Mul64(K[1], ai)
h2, l2 := bits.Mul64(K[2], ai)
h3, l3 := bits.Mul64(K[3], ai)
l1, c0 := bits.Add64(h0, l1, 0)
l2, c1 := bits.Add64(h1, l2, c0)
l3, c2 := bits.Add64(h2, l3, c1)
l4, _ := bits.Add64(h3, 0, c2)
S[i+0], c0 = bits.Add64(S[i+0], l0, 0)
S[i+1], c1 = bits.Add64(S[i+1], l1, c0)
S[i+2], c2 = bits.Add64(S[i+2], l2, c1)
S[i+3], c3 = bits.Add64(S[i+3], l3, c2)
S[i+4], _ = bits.Add64(S[i+4], l4, c3)
}
red512(&S, true)
binary.LittleEndian.PutUint64(s[0*8:1*8], S[0])
binary.LittleEndian.PutUint64(s[1*8:2*8], S[1])
binary.LittleEndian.PutUint64(s[2*8:3*8], S[2])
binary.LittleEndian.PutUint64(s[3*8:4*8], S[3])
}

180
vendor/github.com/cloudflare/circl/sign/ed25519/mult.go generated vendored Normal file
View File

@ -0,0 +1,180 @@
package ed25519
import (
"crypto/subtle"
"encoding/binary"
"math/bits"
"github.com/cloudflare/circl/internal/conv"
"github.com/cloudflare/circl/math"
fp "github.com/cloudflare/circl/math/fp25519"
)
var paramD = fp.Elt{
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52,
}
// mLSBRecoding parameters.
const (
fxT = 257
fxV = 2
fxW = 3
fx2w1 = 1 << (uint(fxW) - 1)
numWords64 = (paramB * 8 / 64)
)
// mLSBRecoding is the odd-only modified LSB-set.
//
// Reference:
//
// "Efficient and secure algorithms for GLV-based scalar multiplication and
// their implementation on GLVGLS curves" by (Faz-Hernandez et al.)
// http://doi.org/10.1007/s13389-014-0085-7.
func mLSBRecoding(L []int8, k []byte) {
const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
const dd = ee * fxV
const ll = dd * fxW
if len(L) == (ll + 1) {
var m [numWords64 + 1]uint64
for i := 0; i < numWords64; i++ {
m[i] = binary.LittleEndian.Uint64(k[8*i : 8*i+8])
}
condAddOrderN(&m)
L[dd-1] = 1
for i := 0; i < dd-1; i++ {
kip1 := (m[(i+1)/64] >> (uint(i+1) % 64)) & 0x1
L[i] = int8(kip1<<1) - 1
}
{ // right-shift by d
right := uint(dd % 64)
left := uint(64) - right
lim := ((numWords64+1)*64 - dd) / 64
j := dd / 64
for i := 0; i < lim; i++ {
m[i] = (m[i+j] >> right) | (m[i+j+1] << left)
}
m[lim] = m[lim+j] >> right
}
for i := dd; i < ll; i++ {
L[i] = L[i%dd] * int8(m[0]&0x1)
div2subY(m[:], int64(L[i]>>1), numWords64)
}
L[ll] = int8(m[0])
}
}
// absolute returns always a positive value.
func absolute(x int32) int32 {
mask := x >> 31
return (x + mask) ^ mask
}
// condAddOrderN updates x = x+order if x is even, otherwise x remains unchanged.
func condAddOrderN(x *[numWords64 + 1]uint64) {
isOdd := (x[0] & 0x1) - 1
c := uint64(0)
for i := 0; i < numWords64; i++ {
orderWord := binary.LittleEndian.Uint64(order[8*i : 8*i+8])
o := isOdd & orderWord
x0, c0 := bits.Add64(x[i], o, c)
x[i] = x0
c = c0
}
x[numWords64], _ = bits.Add64(x[numWords64], 0, c)
}
// div2subY update x = (x/2) - y.
func div2subY(x []uint64, y int64, l int) {
s := uint64(y >> 63)
for i := 0; i < l-1; i++ {
x[i] = (x[i] >> 1) | (x[i+1] << 63)
}
x[l-1] = (x[l-1] >> 1)
b := uint64(0)
x0, b0 := bits.Sub64(x[0], uint64(y), b)
x[0] = x0
b = b0
for i := 1; i < l-1; i++ {
x0, b0 := bits.Sub64(x[i], s, b)
x[i] = x0
b = b0
}
x[l-1], _ = bits.Sub64(x[l-1], s, b)
}
func (P *pointR1) fixedMult(scalar []byte) {
if len(scalar) != paramB {
panic("wrong scalar size")
}
const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
const dd = ee * fxV
const ll = dd * fxW
L := make([]int8, ll+1)
mLSBRecoding(L[:], scalar)
S := &pointR3{}
P.SetIdentity()
for ii := ee - 1; ii >= 0; ii-- {
P.double()
for j := 0; j < fxV; j++ {
dig := L[fxW*dd-j*ee+ii-ee]
for i := (fxW-1)*dd - j*ee + ii - ee; i >= (2*dd - j*ee + ii - ee); i = i - dd {
dig = 2*dig + L[i]
}
idx := absolute(int32(dig))
sig := L[dd-j*ee+ii-ee]
Tabj := &tabSign[fxV-j-1]
for k := 0; k < fx2w1; k++ {
S.cmov(&Tabj[k], subtle.ConstantTimeEq(int32(k), idx))
}
S.cneg(subtle.ConstantTimeEq(int32(sig), -1))
P.mixAdd(S)
}
}
}
const (
omegaFix = 7
omegaVar = 5
)
// doubleMult returns P=mG+nQ.
func (P *pointR1) doubleMult(Q *pointR1, m, n []byte) {
nafFix := math.OmegaNAF(conv.BytesLe2BigInt(m), omegaFix)
nafVar := math.OmegaNAF(conv.BytesLe2BigInt(n), omegaVar)
if len(nafFix) > len(nafVar) {
nafVar = append(nafVar, make([]int32, len(nafFix)-len(nafVar))...)
} else if len(nafFix) < len(nafVar) {
nafFix = append(nafFix, make([]int32, len(nafVar)-len(nafFix))...)
}
var TabQ [1 << (omegaVar - 2)]pointR2
Q.oddMultiples(TabQ[:])
P.SetIdentity()
for i := len(nafFix) - 1; i >= 0; i-- {
P.double()
// Generator point
if nafFix[i] != 0 {
idxM := absolute(nafFix[i]) >> 1
R := tabVerif[idxM]
if nafFix[i] < 0 {
R.neg()
}
P.mixAdd(&R)
}
// Variable input point
if nafVar[i] != 0 {
idxN := absolute(nafVar[i]) >> 1
S := TabQ[idxN]
if nafVar[i] < 0 {
S.neg()
}
P.add(&S)
}
}
}

View File

@ -0,0 +1,195 @@
package ed25519
import fp "github.com/cloudflare/circl/math/fp25519"
type (
pointR1 struct{ x, y, z, ta, tb fp.Elt }
pointR2 struct {
pointR3
z2 fp.Elt
}
)
type pointR3 struct{ addYX, subYX, dt2 fp.Elt }
func (P *pointR1) neg() {
fp.Neg(&P.x, &P.x)
fp.Neg(&P.ta, &P.ta)
}
func (P *pointR1) SetIdentity() {
P.x = fp.Elt{}
fp.SetOne(&P.y)
fp.SetOne(&P.z)
P.ta = fp.Elt{}
P.tb = fp.Elt{}
}
func (P *pointR1) toAffine() {
fp.Inv(&P.z, &P.z)
fp.Mul(&P.x, &P.x, &P.z)
fp.Mul(&P.y, &P.y, &P.z)
fp.Modp(&P.x)
fp.Modp(&P.y)
fp.SetOne(&P.z)
P.ta = P.x
P.tb = P.y
}
func (P *pointR1) ToBytes(k []byte) error {
P.toAffine()
var x [fp.Size]byte
err := fp.ToBytes(k[:fp.Size], &P.y)
if err != nil {
return err
}
err = fp.ToBytes(x[:], &P.x)
if err != nil {
return err
}
b := x[0] & 1
k[paramB-1] = k[paramB-1] | (b << 7)
return nil
}
func (P *pointR1) FromBytes(k []byte) bool {
if len(k) != paramB {
panic("wrong size")
}
signX := k[paramB-1] >> 7
copy(P.y[:], k[:fp.Size])
P.y[fp.Size-1] &= 0x7F
p := fp.P()
if !isLessThan(P.y[:], p[:]) {
return false
}
one, u, v := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
fp.SetOne(one)
fp.Sqr(u, &P.y) // u = y^2
fp.Mul(v, u, &paramD) // v = dy^2
fp.Sub(u, u, one) // u = y^2-1
fp.Add(v, v, one) // v = dy^2+1
isQR := fp.InvSqrt(&P.x, u, v) // x = sqrt(u/v)
if !isQR {
return false
}
fp.Modp(&P.x) // x = x mod p
if fp.IsZero(&P.x) && signX == 1 {
return false
}
if signX != (P.x[0] & 1) {
fp.Neg(&P.x, &P.x)
}
P.ta = P.x
P.tb = P.y
fp.SetOne(&P.z)
return true
}
// double calculates 2P for curves with A=-1.
func (P *pointR1) double() {
Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
fp.Add(e, Px, Py) // x+y
fp.Sqr(a, Px) // A = x^2
fp.Sqr(b, Py) // B = y^2
fp.Sqr(c, Pz) // z^2
fp.Add(c, c, c) // C = 2*z^2
fp.Add(h, a, b) // H = A+B
fp.Sqr(e, e) // (x+y)^2
fp.Sub(e, e, h) // E = (x+y)^2-A-B
fp.Sub(g, b, a) // G = B-A
fp.Sub(f, c, g) // F = C-G
fp.Mul(Pz, f, g) // Z = F * G
fp.Mul(Px, e, f) // X = E * F
fp.Mul(Py, g, h) // Y = G * H, T = E * H
}
func (P *pointR1) mixAdd(Q *pointR3) {
fp.Add(&P.z, &P.z, &P.z) // D = 2*z1
P.coreAddition(Q)
}
func (P *pointR1) add(Q *pointR2) {
fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2
P.coreAddition(&Q.pointR3)
}
// coreAddition calculates P=P+Q for curves with A=-1.
func (P *pointR1) coreAddition(Q *pointR3) {
Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
fp.Mul(c, Pta, Ptb) // t1 = ta*tb
fp.Sub(h, Py, Px) // y1-x1
fp.Add(b, Py, Px) // y1+x1
fp.Mul(a, h, subYX2) // A = (y1-x1)*(y2-x2)
fp.Mul(b, b, addYX2) // B = (y1+x1)*(y2+x2)
fp.Mul(c, c, dt2) // C = 2*D*t1*t2
fp.Sub(e, b, a) // E = B-A
fp.Add(h, b, a) // H = B+A
fp.Sub(f, d, c) // F = D-C
fp.Add(g, d, c) // G = D+C
fp.Mul(Pz, f, g) // Z = F * G
fp.Mul(Px, e, f) // X = E * F
fp.Mul(Py, g, h) // Y = G * H, T = E * H
}
func (P *pointR1) oddMultiples(T []pointR2) {
var R pointR2
n := len(T)
T[0].fromR1(P)
_2P := *P
_2P.double()
R.fromR1(&_2P)
for i := 1; i < n; i++ {
P.add(&R)
T[i].fromR1(P)
}
}
func (P *pointR1) isEqual(Q *pointR1) bool {
l, r := &fp.Elt{}, &fp.Elt{}
fp.Mul(l, &P.x, &Q.z)
fp.Mul(r, &Q.x, &P.z)
fp.Sub(l, l, r)
b := fp.IsZero(l)
fp.Mul(l, &P.y, &Q.z)
fp.Mul(r, &Q.y, &P.z)
fp.Sub(l, l, r)
b = b && fp.IsZero(l)
fp.Mul(l, &P.ta, &P.tb)
fp.Mul(l, l, &Q.z)
fp.Mul(r, &Q.ta, &Q.tb)
fp.Mul(r, r, &P.z)
fp.Sub(l, l, r)
b = b && fp.IsZero(l)
return b
}
func (P *pointR3) neg() {
P.addYX, P.subYX = P.subYX, P.addYX
fp.Neg(&P.dt2, &P.dt2)
}
func (P *pointR2) fromR1(Q *pointR1) {
fp.Add(&P.addYX, &Q.y, &Q.x)
fp.Sub(&P.subYX, &Q.y, &Q.x)
fp.Mul(&P.dt2, &Q.ta, &Q.tb)
fp.Mul(&P.dt2, &P.dt2, &paramD)
fp.Add(&P.dt2, &P.dt2, &P.dt2)
fp.Add(&P.z2, &Q.z, &Q.z)
}
func (P *pointR3) cneg(b int) {
t := &fp.Elt{}
fp.Cswap(&P.addYX, &P.subYX, uint(b))
fp.Neg(t, &P.dt2)
fp.Cmov(&P.dt2, t, uint(b))
}
func (P *pointR3) cmov(Q *pointR3, b int) {
fp.Cmov(&P.addYX, &Q.addYX, uint(b))
fp.Cmov(&P.subYX, &Q.subYX, uint(b))
fp.Cmov(&P.dt2, &Q.dt2, uint(b))
}

View File

@ -0,0 +1,9 @@
//go:build go1.13
// +build go1.13
package ed25519
import cryptoEd25519 "crypto/ed25519"
// PublicKey is the type of Ed25519 public keys.
type PublicKey cryptoEd25519.PublicKey

View File

@ -0,0 +1,7 @@
//go:build !go1.13
// +build !go1.13
package ed25519
// PublicKey is the type of Ed25519 public keys.
type PublicKey []byte

View File

@ -0,0 +1,87 @@
package ed25519
import (
"crypto/rand"
"encoding/asn1"
"github.com/cloudflare/circl/sign"
)
var sch sign.Scheme = &scheme{}
// Scheme returns a signature interface.
func Scheme() sign.Scheme { return sch }
type scheme struct{}
func (*scheme) Name() string { return "Ed25519" }
func (*scheme) PublicKeySize() int { return PublicKeySize }
func (*scheme) PrivateKeySize() int { return PrivateKeySize }
func (*scheme) SignatureSize() int { return SignatureSize }
func (*scheme) SeedSize() int { return SeedSize }
func (*scheme) TLSIdentifier() uint { return 0x0807 }
func (*scheme) SupportsContext() bool { return false }
func (*scheme) Oid() asn1.ObjectIdentifier {
return asn1.ObjectIdentifier{1, 3, 101, 112}
}
func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
return GenerateKey(rand.Reader)
}
func (*scheme) Sign(
sk sign.PrivateKey,
message []byte,
opts *sign.SignatureOpts,
) []byte {
priv, ok := sk.(PrivateKey)
if !ok {
panic(sign.ErrTypeMismatch)
}
if opts != nil && opts.Context != "" {
panic(sign.ErrContextNotSupported)
}
return Sign(priv, message)
}
func (*scheme) Verify(
pk sign.PublicKey,
message, signature []byte,
opts *sign.SignatureOpts,
) bool {
pub, ok := pk.(PublicKey)
if !ok {
panic(sign.ErrTypeMismatch)
}
if opts != nil {
if opts.Context != "" {
panic(sign.ErrContextNotSupported)
}
}
return Verify(pub, message, signature)
}
func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
privateKey := NewKeyFromSeed(seed)
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, privateKey[SeedSize:])
return publicKey, privateKey
}
func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
if len(buf) < PublicKeySize {
return nil, sign.ErrPubKeySize
}
pub := make(PublicKey, PublicKeySize)
copy(pub, buf[:PublicKeySize])
return pub, nil
}
func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
if len(buf) < PrivateKeySize {
return nil, sign.ErrPrivKeySize
}
priv := make(PrivateKey, PrivateKeySize)
copy(priv, buf[:PrivateKeySize])
return priv, nil
}

View File

@ -0,0 +1,213 @@
package ed25519
import fp "github.com/cloudflare/circl/math/fp25519"
var tabSign = [fxV][fx2w1]pointR3{
{
pointR3{
addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
dt2: fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
},
{
addYX: fp.Elt{0x7c, 0xb0, 0x9e, 0xe6, 0xc5, 0xbf, 0xfa, 0x13, 0x8e, 0x0d, 0x22, 0xde, 0xc8, 0xd1, 0xce, 0x52, 0x02, 0xd5, 0x62, 0x31, 0x71, 0x0e, 0x8e, 0x9d, 0xb0, 0xd6, 0x00, 0xa5, 0x5a, 0x0e, 0xce, 0x72},
subYX: fp.Elt{0x1a, 0x8e, 0x5c, 0xdc, 0xa4, 0xb3, 0x6c, 0x51, 0x18, 0xa0, 0x09, 0x80, 0x9a, 0x46, 0x33, 0xd5, 0xe0, 0x3c, 0x4d, 0x3b, 0xfc, 0x49, 0xa2, 0x43, 0x29, 0xe1, 0x29, 0xa9, 0x93, 0xea, 0x7c, 0x35},
dt2: fp.Elt{0x08, 0x46, 0x6f, 0x68, 0x7f, 0x0b, 0x7c, 0x9e, 0xad, 0xba, 0x07, 0x61, 0x74, 0x83, 0x2f, 0xfc, 0x26, 0xd6, 0x09, 0xb9, 0x00, 0x34, 0x36, 0x4f, 0x01, 0xf3, 0x48, 0xdb, 0x43, 0xba, 0x04, 0x44},
},
{
addYX: fp.Elt{0x4c, 0xda, 0x0d, 0x13, 0x66, 0xfd, 0x82, 0x84, 0x9f, 0x75, 0x5b, 0xa2, 0x17, 0xfe, 0x34, 0xbf, 0x1f, 0xcb, 0xba, 0x90, 0x55, 0x80, 0x83, 0xfd, 0x63, 0xb9, 0x18, 0xf8, 0x5b, 0x5d, 0x94, 0x1e},
subYX: fp.Elt{0xb9, 0xdb, 0x6c, 0x04, 0x88, 0x22, 0xd8, 0x79, 0x83, 0x2f, 0x8d, 0x65, 0x6b, 0xd2, 0xab, 0x1b, 0xdd, 0x65, 0xe5, 0x93, 0x63, 0xf8, 0xa2, 0xd8, 0x3c, 0xf1, 0x4b, 0xc5, 0x99, 0xd1, 0xf2, 0x12},
dt2: fp.Elt{0x05, 0x4c, 0xb8, 0x3b, 0xfe, 0xf5, 0x9f, 0x2e, 0xd1, 0xb2, 0xb8, 0xff, 0xfe, 0x6d, 0xd9, 0x37, 0xe0, 0xae, 0xb4, 0x5a, 0x51, 0x80, 0x7e, 0x9b, 0x1d, 0xd1, 0x8d, 0x8c, 0x56, 0xb1, 0x84, 0x35},
},
{
addYX: fp.Elt{0x39, 0x71, 0x43, 0x34, 0xe3, 0x42, 0x45, 0xa1, 0xf2, 0x68, 0x71, 0xa7, 0xe8, 0x23, 0xfd, 0x9f, 0x86, 0x48, 0xff, 0xe5, 0x96, 0x74, 0xcf, 0x05, 0x49, 0xe2, 0xb3, 0x6c, 0x17, 0x77, 0x2f, 0x6d},
subYX: fp.Elt{0x73, 0x3f, 0xc1, 0xc7, 0x6a, 0x66, 0xa1, 0x20, 0xdd, 0x11, 0xfb, 0x7a, 0x6e, 0xa8, 0x51, 0xb8, 0x3f, 0x9d, 0xa2, 0x97, 0x84, 0xb5, 0xc7, 0x90, 0x7c, 0xab, 0x48, 0xd6, 0x84, 0xa3, 0xd5, 0x1a},
dt2: fp.Elt{0x63, 0x27, 0x3c, 0x49, 0x4b, 0xfc, 0x22, 0xf2, 0x0b, 0x50, 0xc2, 0x0f, 0xb4, 0x1f, 0x31, 0x0c, 0x2f, 0x53, 0xab, 0xaa, 0x75, 0x6f, 0xe0, 0x69, 0x39, 0x56, 0xe0, 0x3b, 0xb7, 0xa8, 0xbf, 0x45},
},
},
{
{
addYX: fp.Elt{0x00, 0x45, 0xd9, 0x0d, 0x58, 0x03, 0xfc, 0x29, 0x93, 0xec, 0xbb, 0x6f, 0xa4, 0x7a, 0xd2, 0xec, 0xf8, 0xa7, 0xe2, 0xc2, 0x5f, 0x15, 0x0a, 0x13, 0xd5, 0xa1, 0x06, 0xb7, 0x1a, 0x15, 0x6b, 0x41},
subYX: fp.Elt{0x85, 0x8c, 0xb2, 0x17, 0xd6, 0x3b, 0x0a, 0xd3, 0xea, 0x3b, 0x77, 0x39, 0xb7, 0x77, 0xd3, 0xc5, 0xbf, 0x5c, 0x6a, 0x1e, 0x8c, 0xe7, 0xc6, 0xc6, 0xc4, 0xb7, 0x2a, 0x8b, 0xf7, 0xb8, 0x61, 0x0d},
dt2: fp.Elt{0xb0, 0x36, 0xc1, 0xe9, 0xef, 0xd7, 0xa8, 0x56, 0x20, 0x4b, 0xe4, 0x58, 0xcd, 0xe5, 0x07, 0xbd, 0xab, 0xe0, 0x57, 0x1b, 0xda, 0x2f, 0xe6, 0xaf, 0xd2, 0xe8, 0x77, 0x42, 0xf7, 0x2a, 0x1a, 0x19},
},
{
addYX: fp.Elt{0x6a, 0x6d, 0x6d, 0xd1, 0xfa, 0xf5, 0x03, 0x30, 0xbd, 0x6d, 0xc2, 0xc8, 0xf5, 0x38, 0x80, 0x4f, 0xb2, 0xbe, 0xa1, 0x76, 0x50, 0x1a, 0x73, 0xf2, 0x78, 0x2b, 0x8e, 0x3a, 0x1e, 0x34, 0x47, 0x7b},
subYX: fp.Elt{0xc3, 0x2c, 0x36, 0xdc, 0xc5, 0x45, 0xbc, 0xef, 0x1b, 0x64, 0xd6, 0x65, 0x28, 0xe9, 0xda, 0x84, 0x13, 0xbe, 0x27, 0x8e, 0x3f, 0x98, 0x2a, 0x37, 0xee, 0x78, 0x97, 0xd6, 0xc0, 0x6f, 0xb4, 0x53},
dt2: fp.Elt{0x58, 0x5d, 0xa7, 0xa3, 0x68, 0xbb, 0x20, 0x30, 0x2e, 0x03, 0xe9, 0xb1, 0xd4, 0x90, 0x72, 0xe3, 0x71, 0xb2, 0x36, 0x3e, 0x73, 0xa0, 0x2e, 0x3d, 0xd1, 0x85, 0x33, 0x62, 0x4e, 0xa7, 0x7b, 0x31},
},
{
addYX: fp.Elt{0xbf, 0xc4, 0x38, 0x53, 0xfb, 0x68, 0xa9, 0x77, 0xce, 0x55, 0xf9, 0x05, 0xcb, 0xeb, 0xfb, 0x8c, 0x46, 0xc2, 0x32, 0x7c, 0xf0, 0xdb, 0xd7, 0x2c, 0x62, 0x8e, 0xdd, 0x54, 0x75, 0xcf, 0x3f, 0x33},
subYX: fp.Elt{0x49, 0x50, 0x1f, 0x4e, 0x6e, 0x55, 0x55, 0xde, 0x8c, 0x4e, 0x77, 0x96, 0x38, 0x3b, 0xfe, 0xb6, 0x43, 0x3c, 0x86, 0x69, 0xc2, 0x72, 0x66, 0x1f, 0x6b, 0xf9, 0x87, 0xbc, 0x4f, 0x37, 0x3e, 0x3c},
dt2: fp.Elt{0xd2, 0x2f, 0x06, 0x6b, 0x08, 0x07, 0x69, 0x77, 0xc0, 0x94, 0xcc, 0xae, 0x43, 0x00, 0x59, 0x6e, 0xa3, 0x63, 0xa8, 0xdd, 0xfa, 0x24, 0x18, 0xd0, 0x35, 0xc7, 0x78, 0xf7, 0x0d, 0xd4, 0x5a, 0x1e},
},
{
addYX: fp.Elt{0x45, 0xc1, 0x17, 0x51, 0xf8, 0xed, 0x7e, 0xc7, 0xa9, 0x1a, 0x11, 0x6e, 0x2d, 0xef, 0x0b, 0xd5, 0x3f, 0x98, 0xb0, 0xa3, 0x9d, 0x65, 0xf1, 0xcd, 0x53, 0x4a, 0x8a, 0x18, 0x70, 0x0a, 0x7f, 0x23},
subYX: fp.Elt{0xdd, 0xef, 0xbe, 0x3a, 0x31, 0xe0, 0xbc, 0xbe, 0x6d, 0x5d, 0x79, 0x87, 0xd6, 0xbe, 0x68, 0xe3, 0x59, 0x76, 0x8c, 0x86, 0x0e, 0x7a, 0x92, 0x13, 0x14, 0x8f, 0x67, 0xb3, 0xcb, 0x1a, 0x76, 0x76},
dt2: fp.Elt{0x56, 0x7a, 0x1c, 0x9d, 0xca, 0x96, 0xf9, 0xf9, 0x03, 0x21, 0xd4, 0xe8, 0xb3, 0xd5, 0xe9, 0x52, 0xc8, 0x54, 0x1e, 0x1b, 0x13, 0xb6, 0xfd, 0x47, 0x7d, 0x02, 0x32, 0x33, 0x27, 0xe2, 0x1f, 0x19},
},
},
}
var tabVerif = [1 << (omegaFix - 2)]pointR3{
{ /* 1P */
addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
dt2: fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
},
{ /* 3P */
addYX: fp.Elt{0x30, 0x97, 0xee, 0x4c, 0xa8, 0xb0, 0x25, 0xaf, 0x8a, 0x4b, 0x86, 0xe8, 0x30, 0x84, 0x5a, 0x02, 0x32, 0x67, 0x01, 0x9f, 0x02, 0x50, 0x1b, 0xc1, 0xf4, 0xf8, 0x80, 0x9a, 0x1b, 0x4e, 0x16, 0x7a},
subYX: fp.Elt{0x65, 0xd2, 0xfc, 0xa4, 0xe8, 0x1f, 0x61, 0x56, 0x7d, 0xba, 0xc1, 0xe5, 0xfd, 0x53, 0xd3, 0x3b, 0xbd, 0xd6, 0x4b, 0x21, 0x1a, 0xf3, 0x31, 0x81, 0x62, 0xda, 0x5b, 0x55, 0x87, 0x15, 0xb9, 0x2a},
dt2: fp.Elt{0x89, 0xd8, 0xd0, 0x0d, 0x3f, 0x93, 0xae, 0x14, 0x62, 0xda, 0x35, 0x1c, 0x22, 0x23, 0x94, 0x58, 0x4c, 0xdb, 0xf2, 0x8c, 0x45, 0xe5, 0x70, 0xd1, 0xc6, 0xb4, 0xb9, 0x12, 0xaf, 0x26, 0x28, 0x5a},
},
{ /* 5P */
addYX: fp.Elt{0x33, 0xbb, 0xa5, 0x08, 0x44, 0xbc, 0x12, 0xa2, 0x02, 0xed, 0x5e, 0xc7, 0xc3, 0x48, 0x50, 0x8d, 0x44, 0xec, 0xbf, 0x5a, 0x0c, 0xeb, 0x1b, 0xdd, 0xeb, 0x06, 0xe2, 0x46, 0xf1, 0xcc, 0x45, 0x29},
subYX: fp.Elt{0xba, 0xd6, 0x47, 0xa4, 0xc3, 0x82, 0x91, 0x7f, 0xb7, 0x29, 0x27, 0x4b, 0xd1, 0x14, 0x00, 0xd5, 0x87, 0xa0, 0x64, 0xb8, 0x1c, 0xf1, 0x3c, 0xe3, 0xf3, 0x55, 0x1b, 0xeb, 0x73, 0x7e, 0x4a, 0x15},
dt2: fp.Elt{0x85, 0x82, 0x2a, 0x81, 0xf1, 0xdb, 0xbb, 0xbc, 0xfc, 0xd1, 0xbd, 0xd0, 0x07, 0x08, 0x0e, 0x27, 0x2d, 0xa7, 0xbd, 0x1b, 0x0b, 0x67, 0x1b, 0xb4, 0x9a, 0xb6, 0x3b, 0x6b, 0x69, 0xbe, 0xaa, 0x43},
},
{ /* 7P */
addYX: fp.Elt{0xbf, 0xa3, 0x4e, 0x94, 0xd0, 0x5c, 0x1a, 0x6b, 0xd2, 0xc0, 0x9d, 0xb3, 0x3a, 0x35, 0x70, 0x74, 0x49, 0x2e, 0x54, 0x28, 0x82, 0x52, 0xb2, 0x71, 0x7e, 0x92, 0x3c, 0x28, 0x69, 0xea, 0x1b, 0x46},
subYX: fp.Elt{0xb1, 0x21, 0x32, 0xaa, 0x9a, 0x2c, 0x6f, 0xba, 0xa7, 0x23, 0xba, 0x3b, 0x53, 0x21, 0xa0, 0x6c, 0x3a, 0x2c, 0x19, 0x92, 0x4f, 0x76, 0xea, 0x9d, 0xe0, 0x17, 0x53, 0x2e, 0x5d, 0xdd, 0x6e, 0x1d},
dt2: fp.Elt{0xa2, 0xb3, 0xb8, 0x01, 0xc8, 0x6d, 0x83, 0xf1, 0x9a, 0xa4, 0x3e, 0x05, 0x47, 0x5f, 0x03, 0xb3, 0xf3, 0xad, 0x77, 0x58, 0xba, 0x41, 0x9c, 0x52, 0xa7, 0x90, 0x0f, 0x6a, 0x1c, 0xbb, 0x9f, 0x7a},
},
{ /* 9P */
addYX: fp.Elt{0x2f, 0x63, 0xa8, 0xa6, 0x8a, 0x67, 0x2e, 0x9b, 0xc5, 0x46, 0xbc, 0x51, 0x6f, 0x9e, 0x50, 0xa6, 0xb5, 0xf5, 0x86, 0xc6, 0xc9, 0x33, 0xb2, 0xce, 0x59, 0x7f, 0xdd, 0x8a, 0x33, 0xed, 0xb9, 0x34},
subYX: fp.Elt{0x64, 0x80, 0x9d, 0x03, 0x7e, 0x21, 0x6e, 0xf3, 0x9b, 0x41, 0x20, 0xf5, 0xb6, 0x81, 0xa0, 0x98, 0x44, 0xb0, 0x5e, 0xe7, 0x08, 0xc6, 0xcb, 0x96, 0x8f, 0x9c, 0xdc, 0xfa, 0x51, 0x5a, 0xc0, 0x49},
dt2: fp.Elt{0x1b, 0xaf, 0x45, 0x90, 0xbf, 0xe8, 0xb4, 0x06, 0x2f, 0xd2, 0x19, 0xa7, 0xe8, 0x83, 0xff, 0xe2, 0x16, 0xcf, 0xd4, 0x93, 0x29, 0xfc, 0xf6, 0xaa, 0x06, 0x8b, 0x00, 0x1b, 0x02, 0x72, 0xc1, 0x73},
},
{ /* 11P */
addYX: fp.Elt{0xde, 0x2a, 0x80, 0x8a, 0x84, 0x00, 0xbf, 0x2f, 0x27, 0x2e, 0x30, 0x02, 0xcf, 0xfe, 0xd9, 0xe5, 0x06, 0x34, 0x70, 0x17, 0x71, 0x84, 0x3e, 0x11, 0xaf, 0x8f, 0x6d, 0x54, 0xe2, 0xaa, 0x75, 0x42},
subYX: fp.Elt{0x48, 0x43, 0x86, 0x49, 0x02, 0x5b, 0x5f, 0x31, 0x81, 0x83, 0x08, 0x77, 0x69, 0xb3, 0xd6, 0x3e, 0x95, 0xeb, 0x8d, 0x6a, 0x55, 0x75, 0xa0, 0xa3, 0x7f, 0xc7, 0xd5, 0x29, 0x80, 0x59, 0xab, 0x18},
dt2: fp.Elt{0xe9, 0x89, 0x60, 0xfd, 0xc5, 0x2c, 0x2b, 0xd8, 0xa4, 0xe4, 0x82, 0x32, 0xa1, 0xb4, 0x1e, 0x03, 0x22, 0x86, 0x1a, 0xb5, 0x99, 0x11, 0x31, 0x44, 0x48, 0xf9, 0x3d, 0xb5, 0x22, 0x55, 0xc6, 0x3d},
},
{ /* 13P */
addYX: fp.Elt{0x6d, 0x7f, 0x00, 0xa2, 0x22, 0xc2, 0x70, 0xbf, 0xdb, 0xde, 0xbc, 0xb5, 0x9a, 0xb3, 0x84, 0xbf, 0x07, 0xba, 0x07, 0xfb, 0x12, 0x0e, 0x7a, 0x53, 0x41, 0xf2, 0x46, 0xc3, 0xee, 0xd7, 0x4f, 0x23},
subYX: fp.Elt{0x93, 0xbf, 0x7f, 0x32, 0x3b, 0x01, 0x6f, 0x50, 0x6b, 0x6f, 0x77, 0x9b, 0xc9, 0xeb, 0xfc, 0xae, 0x68, 0x59, 0xad, 0xaa, 0x32, 0xb2, 0x12, 0x9d, 0xa7, 0x24, 0x60, 0x17, 0x2d, 0x88, 0x67, 0x02},
dt2: fp.Elt{0x78, 0xa3, 0x2e, 0x73, 0x19, 0xa1, 0x60, 0x53, 0x71, 0xd4, 0x8d, 0xdf, 0xb1, 0xe6, 0x37, 0x24, 0x33, 0xe5, 0xa7, 0x91, 0xf8, 0x37, 0xef, 0xa2, 0x63, 0x78, 0x09, 0xaa, 0xfd, 0xa6, 0x7b, 0x49},
},
{ /* 15P */
addYX: fp.Elt{0xa0, 0xea, 0xcf, 0x13, 0x03, 0xcc, 0xce, 0x24, 0x6d, 0x24, 0x9c, 0x18, 0x8d, 0xc2, 0x48, 0x86, 0xd0, 0xd4, 0xf2, 0xc1, 0xfa, 0xbd, 0xbd, 0x2d, 0x2b, 0xe7, 0x2d, 0xf1, 0x17, 0x29, 0xe2, 0x61},
subYX: fp.Elt{0x0b, 0xcf, 0x8c, 0x46, 0x86, 0xcd, 0x0b, 0x04, 0xd6, 0x10, 0x99, 0x2a, 0xa4, 0x9b, 0x82, 0xd3, 0x92, 0x51, 0xb2, 0x07, 0x08, 0x30, 0x08, 0x75, 0xbf, 0x5e, 0xd0, 0x18, 0x42, 0xcd, 0xb5, 0x43},
dt2: fp.Elt{0x16, 0xb5, 0xd0, 0x9b, 0x2f, 0x76, 0x9a, 0x5d, 0xee, 0xde, 0x3f, 0x37, 0x4e, 0xaf, 0x38, 0xeb, 0x70, 0x42, 0xd6, 0x93, 0x7d, 0x5a, 0x2e, 0x03, 0x42, 0xd8, 0xe4, 0x0a, 0x21, 0x61, 0x1d, 0x51},
},
{ /* 17P */
addYX: fp.Elt{0x81, 0x9d, 0x0e, 0x95, 0xef, 0x76, 0xc6, 0x92, 0x4f, 0x04, 0xd7, 0xc0, 0xcd, 0x20, 0x46, 0xa5, 0x48, 0x12, 0x8f, 0x6f, 0x64, 0x36, 0x9b, 0xaa, 0xe3, 0x55, 0xb8, 0xdd, 0x24, 0x59, 0x32, 0x6d},
subYX: fp.Elt{0x87, 0xde, 0x20, 0x44, 0x48, 0x86, 0x13, 0x08, 0xb4, 0xed, 0x92, 0xb5, 0x16, 0xf0, 0x1c, 0x8a, 0x25, 0x2d, 0x94, 0x29, 0x27, 0x4e, 0xfa, 0x39, 0x10, 0x28, 0x48, 0xe2, 0x6f, 0xfe, 0xa7, 0x71},
dt2: fp.Elt{0x54, 0xc8, 0xc8, 0xa5, 0xb8, 0x82, 0x71, 0x6c, 0x03, 0x2a, 0x5f, 0xfe, 0x79, 0x14, 0xfd, 0x33, 0x0c, 0x8d, 0x77, 0x83, 0x18, 0x59, 0xcf, 0x72, 0xa9, 0xea, 0x9e, 0x55, 0xb6, 0xc4, 0x46, 0x47},
},
{ /* 19P */
addYX: fp.Elt{0x2b, 0x9a, 0xc6, 0x6d, 0x3c, 0x7b, 0x77, 0xd3, 0x17, 0xf6, 0x89, 0x6f, 0x27, 0xb2, 0xfa, 0xde, 0xb5, 0x16, 0x3a, 0xb5, 0xf7, 0x1c, 0x65, 0x45, 0xb7, 0x9f, 0xfe, 0x34, 0xde, 0x51, 0x9a, 0x5c},
subYX: fp.Elt{0x47, 0x11, 0x74, 0x64, 0xc8, 0x46, 0x85, 0x34, 0x49, 0xc8, 0xfc, 0x0e, 0xdd, 0xae, 0x35, 0x7d, 0x32, 0xa3, 0x72, 0x06, 0x76, 0x9a, 0x93, 0xff, 0xd6, 0xe6, 0xb5, 0x7d, 0x49, 0x63, 0x96, 0x21},
dt2: fp.Elt{0x67, 0x0e, 0xf1, 0x79, 0xcf, 0xf1, 0x10, 0xf5, 0x5b, 0x51, 0x58, 0xe6, 0xa1, 0xda, 0xdd, 0xff, 0x77, 0x22, 0x14, 0x10, 0x17, 0xa7, 0xc3, 0x09, 0xbb, 0x23, 0x82, 0x60, 0x3c, 0x50, 0x04, 0x48},
},
{ /* 21P */
addYX: fp.Elt{0xc7, 0x7f, 0xa3, 0x2c, 0xd0, 0x9e, 0x24, 0xc4, 0xab, 0xac, 0x15, 0xa6, 0xe3, 0xa0, 0x59, 0xa0, 0x23, 0x0e, 0x6e, 0xc9, 0xd7, 0x6e, 0xa9, 0x88, 0x6d, 0x69, 0x50, 0x16, 0xa5, 0x98, 0x33, 0x55},
subYX: fp.Elt{0x75, 0xd1, 0x36, 0x3a, 0xd2, 0x21, 0x68, 0x3b, 0x32, 0x9e, 0x9b, 0xe9, 0xa7, 0x0a, 0xb4, 0xbb, 0x47, 0x8a, 0x83, 0x20, 0xe4, 0x5c, 0x9e, 0x5d, 0x5e, 0x4c, 0xde, 0x58, 0x88, 0x09, 0x1e, 0x77},
dt2: fp.Elt{0xdf, 0x1e, 0x45, 0x78, 0xd2, 0xf5, 0x12, 0x9a, 0xcb, 0x9c, 0x89, 0x85, 0x79, 0x5d, 0xda, 0x3a, 0x08, 0x95, 0xa5, 0x9f, 0x2d, 0x4a, 0x7f, 0x47, 0x11, 0xa6, 0xf5, 0x8f, 0xd6, 0xd1, 0x5e, 0x5a},
},
{ /* 23P */
addYX: fp.Elt{0x83, 0x0e, 0x15, 0xfe, 0x2a, 0x12, 0x95, 0x11, 0xd8, 0x35, 0x4b, 0x7e, 0x25, 0x9a, 0x20, 0xcf, 0x20, 0x1e, 0x71, 0x1e, 0x29, 0xf8, 0x87, 0x73, 0xf0, 0x92, 0xbf, 0xd8, 0x97, 0xb8, 0xac, 0x44},
subYX: fp.Elt{0x59, 0x73, 0x52, 0x58, 0xc5, 0xe0, 0xe5, 0xba, 0x7e, 0x9d, 0xdb, 0xca, 0x19, 0x5c, 0x2e, 0x39, 0xe9, 0xab, 0x1c, 0xda, 0x1e, 0x3c, 0x65, 0x28, 0x44, 0xdc, 0xef, 0x5f, 0x13, 0x60, 0x9b, 0x01},
dt2: fp.Elt{0x83, 0x4b, 0x13, 0x5e, 0x14, 0x68, 0x60, 0x1e, 0x16, 0x4c, 0x30, 0x24, 0x4f, 0xe6, 0xf5, 0xc4, 0xd7, 0x3e, 0x1a, 0xfc, 0xa8, 0x88, 0x6e, 0x50, 0x92, 0x2f, 0xad, 0xe6, 0xfd, 0x49, 0x0c, 0x15},
},
{ /* 25P */
addYX: fp.Elt{0x38, 0x11, 0x47, 0x09, 0x95, 0xf2, 0x7b, 0x8e, 0x51, 0xa6, 0x75, 0x4f, 0x39, 0xef, 0x6f, 0x5d, 0xad, 0x08, 0xa7, 0x25, 0xc4, 0x79, 0xaf, 0x10, 0x22, 0x99, 0xb9, 0x5b, 0x07, 0x5a, 0x2b, 0x6b},
subYX: fp.Elt{0x68, 0xa8, 0xdc, 0x9c, 0x3c, 0x86, 0x49, 0xb8, 0xd0, 0x4a, 0x71, 0xb8, 0xdb, 0x44, 0x3f, 0xc8, 0x8d, 0x16, 0x36, 0x0c, 0x56, 0xe3, 0x3e, 0xfe, 0xc1, 0xfb, 0x05, 0x1e, 0x79, 0xd7, 0xa6, 0x78},
dt2: fp.Elt{0x76, 0xb9, 0xa0, 0x47, 0x4b, 0x70, 0xbf, 0x58, 0xd5, 0x48, 0x17, 0x74, 0x55, 0xb3, 0x01, 0xa6, 0x90, 0xf5, 0x42, 0xd5, 0xb1, 0x1f, 0x2b, 0xaa, 0x00, 0x5d, 0xd5, 0x4a, 0xfc, 0x7f, 0x5c, 0x72},
},
{ /* 27P */
addYX: fp.Elt{0xb2, 0x99, 0xcf, 0xd1, 0x15, 0x67, 0x42, 0xe4, 0x34, 0x0d, 0xa2, 0x02, 0x11, 0xd5, 0x52, 0x73, 0x9f, 0x10, 0x12, 0x8b, 0x7b, 0x15, 0xd1, 0x23, 0xa3, 0xf3, 0xb1, 0x7c, 0x27, 0xc9, 0x4c, 0x79},
subYX: fp.Elt{0xc0, 0x98, 0xd0, 0x1c, 0xf7, 0x2b, 0x80, 0x91, 0x66, 0x63, 0x5e, 0xed, 0xa4, 0x6c, 0x41, 0xfe, 0x4c, 0x99, 0x02, 0x49, 0x71, 0x5d, 0x58, 0xdf, 0xe7, 0xfa, 0x55, 0xf8, 0x25, 0x46, 0xd5, 0x4c},
dt2: fp.Elt{0x53, 0x50, 0xac, 0xc2, 0x26, 0xc4, 0xf6, 0x4a, 0x58, 0x72, 0xf6, 0x32, 0xad, 0xed, 0x9a, 0xbc, 0x21, 0x10, 0x31, 0x0a, 0xf1, 0x32, 0xd0, 0x2a, 0x85, 0x8e, 0xcc, 0x6f, 0x7b, 0x35, 0x08, 0x70},
},
{ /* 29P */
addYX: fp.Elt{0x01, 0x3f, 0x77, 0x38, 0x27, 0x67, 0x88, 0x0b, 0xfb, 0xcc, 0xfb, 0x95, 0xfa, 0xc8, 0xcc, 0xb8, 0xb6, 0x29, 0xad, 0xb9, 0xa3, 0xd5, 0x2d, 0x8d, 0x6a, 0x0f, 0xad, 0x51, 0x98, 0x7e, 0xef, 0x06},
subYX: fp.Elt{0x34, 0x4a, 0x58, 0x82, 0xbb, 0x9f, 0x1b, 0xd0, 0x2b, 0x79, 0xb4, 0xd2, 0x63, 0x64, 0xab, 0x47, 0x02, 0x62, 0x53, 0x48, 0x9c, 0x63, 0x31, 0xb6, 0x28, 0xd4, 0xd6, 0x69, 0x36, 0x2a, 0xa9, 0x13},
dt2: fp.Elt{0xe5, 0x7d, 0x57, 0xc0, 0x1c, 0x77, 0x93, 0xca, 0x5c, 0xdc, 0x35, 0x50, 0x1e, 0xe4, 0x40, 0x75, 0x71, 0xe0, 0x02, 0xd8, 0x01, 0x0f, 0x68, 0x24, 0x6a, 0xf8, 0x2a, 0x8a, 0xdf, 0x6d, 0x29, 0x3c},
},
{ /* 31P */
addYX: fp.Elt{0x13, 0xa7, 0x14, 0xd9, 0xf9, 0x15, 0xad, 0xae, 0x12, 0xf9, 0x8f, 0x8c, 0xf9, 0x7b, 0x2f, 0xa9, 0x30, 0xd7, 0x53, 0x9f, 0x17, 0x23, 0xf8, 0xaf, 0xba, 0x77, 0x0c, 0x49, 0x93, 0xd3, 0x99, 0x7a},
subYX: fp.Elt{0x41, 0x25, 0x1f, 0xbb, 0x2e, 0x4d, 0xeb, 0xfc, 0x1f, 0xb9, 0xad, 0x40, 0xc7, 0x10, 0x95, 0xb8, 0x05, 0xad, 0xa1, 0xd0, 0x7d, 0xa3, 0x71, 0xfc, 0x7b, 0x71, 0x47, 0x07, 0x70, 0x2c, 0x89, 0x0a},
dt2: fp.Elt{0xe8, 0xa3, 0xbd, 0x36, 0x24, 0xed, 0x52, 0x8f, 0x94, 0x07, 0xe8, 0x57, 0x41, 0xc8, 0xa8, 0x77, 0xe0, 0x9c, 0x2f, 0x26, 0x63, 0x65, 0xa9, 0xa5, 0xd2, 0xf7, 0x02, 0x83, 0xd2, 0x62, 0x67, 0x28},
},
{ /* 33P */
addYX: fp.Elt{0x25, 0x5b, 0xe3, 0x3c, 0x09, 0x36, 0x78, 0x4e, 0x97, 0xaa, 0x6b, 0xb2, 0x1d, 0x18, 0xe1, 0x82, 0x3f, 0xb8, 0xc7, 0xcb, 0xd3, 0x92, 0xc1, 0x0c, 0x3a, 0x9d, 0x9d, 0x6a, 0x04, 0xda, 0xf1, 0x32},
subYX: fp.Elt{0xbd, 0xf5, 0x2e, 0xce, 0x2b, 0x8e, 0x55, 0x7c, 0x63, 0xbc, 0x47, 0x67, 0xb4, 0x6c, 0x98, 0xe4, 0xb8, 0x89, 0xbb, 0x3b, 0x9f, 0x17, 0x4a, 0x15, 0x7a, 0x76, 0xf1, 0xd6, 0xa3, 0xf2, 0x86, 0x76},
dt2: fp.Elt{0x6a, 0x7c, 0x59, 0x6d, 0xa6, 0x12, 0x8d, 0xaa, 0x2b, 0x85, 0xd3, 0x04, 0x03, 0x93, 0x11, 0x8f, 0x22, 0xb0, 0x09, 0xc2, 0x73, 0xdc, 0x91, 0x3f, 0xa6, 0x28, 0xad, 0xa9, 0xf8, 0x05, 0x13, 0x56},
},
{ /* 35P */
addYX: fp.Elt{0xd1, 0xae, 0x92, 0xec, 0x8d, 0x97, 0x0c, 0x10, 0xe5, 0x73, 0x6d, 0x4d, 0x43, 0xd5, 0x43, 0xca, 0x48, 0xba, 0x47, 0xd8, 0x22, 0x1b, 0x13, 0x83, 0x2c, 0x4d, 0x5d, 0xe3, 0x53, 0xec, 0xaa},
subYX: fp.Elt{0xd5, 0xc0, 0xb0, 0xe7, 0x28, 0xcc, 0x22, 0x67, 0x53, 0x5c, 0x07, 0xdb, 0xbb, 0xe9, 0x9d, 0x70, 0x61, 0x0a, 0x01, 0xd7, 0xa7, 0x8d, 0xf6, 0xca, 0x6c, 0xcc, 0x57, 0x2c, 0xef, 0x1a, 0x0a, 0x03},
dt2: fp.Elt{0xaa, 0xd2, 0x3a, 0x00, 0x73, 0xf7, 0xb1, 0x7b, 0x08, 0x66, 0x21, 0x2b, 0x80, 0x29, 0x3f, 0x0b, 0x3e, 0xd2, 0x0e, 0x52, 0x86, 0xdc, 0x21, 0x78, 0x80, 0x54, 0x06, 0x24, 0x1c, 0x9c, 0xbe, 0x20},
},
{ /* 37P */
addYX: fp.Elt{0xa6, 0x73, 0x96, 0x24, 0xd8, 0x87, 0x53, 0xe1, 0x93, 0xe4, 0x46, 0xf5, 0x2d, 0xbc, 0x43, 0x59, 0xb5, 0x63, 0x6f, 0xc3, 0x81, 0x9a, 0x7f, 0x1c, 0xde, 0xc1, 0x0a, 0x1f, 0x36, 0xb3, 0x0a, 0x75},
subYX: fp.Elt{0x60, 0x5e, 0x02, 0xe2, 0x4a, 0xe4, 0xe0, 0x20, 0x38, 0xb9, 0xdc, 0xcb, 0x2f, 0x3b, 0x3b, 0xb0, 0x1c, 0x0d, 0x5a, 0xf9, 0x9c, 0x63, 0x5d, 0x10, 0x11, 0xe3, 0x67, 0x50, 0x54, 0x4c, 0x76, 0x69},
dt2: fp.Elt{0x37, 0x10, 0xf8, 0xa2, 0x83, 0x32, 0x8a, 0x1e, 0xf1, 0xcb, 0x7f, 0xbd, 0x23, 0xda, 0x2e, 0x6f, 0x63, 0x25, 0x2e, 0xac, 0x5b, 0xd1, 0x2f, 0xb7, 0x40, 0x50, 0x07, 0xb7, 0x3f, 0x6b, 0xf9, 0x54},
},
{ /* 39P */
addYX: fp.Elt{0x79, 0x92, 0x66, 0x29, 0x04, 0xf2, 0xad, 0x0f, 0x4a, 0x72, 0x7d, 0x7d, 0x04, 0xa2, 0xdd, 0x3a, 0xf1, 0x60, 0x57, 0x8c, 0x82, 0x94, 0x3d, 0x6f, 0x9e, 0x53, 0xb7, 0x2b, 0xc5, 0xe9, 0x7f, 0x3d},
subYX: fp.Elt{0xcd, 0x1e, 0xb1, 0x16, 0xc6, 0xaf, 0x7d, 0x17, 0x79, 0x64, 0x57, 0xfa, 0x9c, 0x4b, 0x76, 0x89, 0x85, 0xe7, 0xec, 0xe6, 0x10, 0xa1, 0xa8, 0xb7, 0xf0, 0xdb, 0x85, 0xbe, 0x9f, 0x83, 0xe6, 0x78},
dt2: fp.Elt{0x6b, 0x85, 0xb8, 0x37, 0xf7, 0x2d, 0x33, 0x70, 0x8a, 0x17, 0x1a, 0x04, 0x43, 0x5d, 0xd0, 0x75, 0x22, 0x9e, 0xe5, 0xa0, 0x4a, 0xf7, 0x0f, 0x32, 0x42, 0x82, 0x08, 0x50, 0xf3, 0x68, 0xf2, 0x70},
},
{ /* 41P */
addYX: fp.Elt{0x47, 0x5f, 0x80, 0xb1, 0x83, 0x45, 0x86, 0x66, 0x19, 0x7c, 0xdd, 0x60, 0xd1, 0xc5, 0x35, 0xf5, 0x06, 0xb0, 0x4c, 0x1e, 0xb7, 0x4e, 0x87, 0xe9, 0xd9, 0x89, 0xd8, 0xfa, 0x5c, 0x34, 0x0d, 0x7c},
subYX: fp.Elt{0x55, 0xf3, 0xdc, 0x70, 0x20, 0x11, 0x24, 0x23, 0x17, 0xe1, 0xfc, 0xe7, 0x7e, 0xc9, 0x0c, 0x38, 0x98, 0xb6, 0x52, 0x35, 0xed, 0xde, 0x1d, 0xb3, 0xb9, 0xc4, 0xb8, 0x39, 0xc0, 0x56, 0x4e, 0x40},
dt2: fp.Elt{0x8a, 0x33, 0x78, 0x8c, 0x4b, 0x1f, 0x1f, 0x59, 0xe1, 0xb5, 0xe0, 0x67, 0xb1, 0x6a, 0x36, 0xa0, 0x44, 0x3d, 0x5f, 0xb4, 0x52, 0x41, 0xbc, 0x5c, 0x77, 0xc7, 0xae, 0x2a, 0x76, 0x54, 0xd7, 0x20},
},
{ /* 43P */
addYX: fp.Elt{0x58, 0xb7, 0x3b, 0xc7, 0x6f, 0xc3, 0x8f, 0x5e, 0x9a, 0xbb, 0x3c, 0x36, 0xa5, 0x43, 0xe5, 0xac, 0x22, 0xc9, 0x3b, 0x90, 0x7d, 0x4a, 0x93, 0xa9, 0x62, 0xec, 0xce, 0xf3, 0x46, 0x1e, 0x8f, 0x2b},
subYX: fp.Elt{0x43, 0xf5, 0xb9, 0x35, 0xb1, 0xfe, 0x74, 0x9d, 0x6c, 0x95, 0x8c, 0xde, 0xf1, 0x7d, 0xb3, 0x84, 0xa9, 0x8b, 0x13, 0x57, 0x07, 0x2b, 0x32, 0xe9, 0xe1, 0x4c, 0x0b, 0x79, 0xa8, 0xad, 0xb8, 0x38},
dt2: fp.Elt{0x5d, 0xf9, 0x51, 0xdf, 0x9c, 0x4a, 0xc0, 0xb5, 0xac, 0xde, 0x1f, 0xcb, 0xae, 0x52, 0x39, 0x2b, 0xda, 0x66, 0x8b, 0x32, 0x8b, 0x6d, 0x10, 0x1d, 0x53, 0x19, 0xba, 0xce, 0x32, 0xeb, 0x9a, 0x04},
},
{ /* 45P */
addYX: fp.Elt{0x31, 0x79, 0xfc, 0x75, 0x0b, 0x7d, 0x50, 0xaa, 0xd3, 0x25, 0x67, 0x7a, 0x4b, 0x92, 0xef, 0x0f, 0x30, 0x39, 0x6b, 0x39, 0x2b, 0x54, 0x82, 0x1d, 0xfc, 0x74, 0xf6, 0x30, 0x75, 0xe1, 0x5e, 0x79},
subYX: fp.Elt{0x7e, 0xfe, 0xdc, 0x63, 0x3c, 0x7d, 0x76, 0xd7, 0x40, 0x6e, 0x85, 0x97, 0x48, 0x59, 0x9c, 0x20, 0x13, 0x7c, 0x4f, 0xe1, 0x61, 0x68, 0x67, 0xb6, 0xfc, 0x25, 0xd6, 0xc8, 0xe0, 0x65, 0xc6, 0x51},
dt2: fp.Elt{0x81, 0xbd, 0xec, 0x52, 0x0a, 0x5b, 0x4a, 0x25, 0xe7, 0xaf, 0x34, 0xe0, 0x6e, 0x1f, 0x41, 0x5d, 0x31, 0x4a, 0xee, 0xca, 0x0d, 0x4d, 0xa2, 0xe6, 0x77, 0x44, 0xc5, 0x9d, 0xf4, 0x9b, 0xd1, 0x6c},
},
{ /* 47P */
addYX: fp.Elt{0x86, 0xc3, 0xaf, 0x65, 0x21, 0x61, 0xfe, 0x1f, 0x10, 0x1b, 0xd5, 0xb8, 0x88, 0x2a, 0x2a, 0x08, 0xaa, 0x0b, 0x99, 0x20, 0x7e, 0x62, 0xf6, 0x76, 0xe7, 0x43, 0x9e, 0x42, 0xa7, 0xb3, 0x01, 0x5e},
subYX: fp.Elt{0xa3, 0x9c, 0x17, 0x52, 0x90, 0x61, 0x87, 0x7e, 0x85, 0x9f, 0x2c, 0x0b, 0x06, 0x0a, 0x1d, 0x57, 0x1e, 0x71, 0x99, 0x84, 0xa8, 0xba, 0xa2, 0x80, 0x38, 0xe6, 0xb2, 0x40, 0xdb, 0xf3, 0x20, 0x75},
dt2: fp.Elt{0xa1, 0x57, 0x93, 0xd3, 0xe3, 0x0b, 0xb5, 0x3d, 0xa5, 0x94, 0x9e, 0x59, 0xdd, 0x6c, 0x7b, 0x96, 0x6e, 0x1e, 0x31, 0xdf, 0x64, 0x9a, 0x30, 0x1a, 0x86, 0xc9, 0xf3, 0xce, 0x9c, 0x2c, 0x09, 0x71},
},
{ /* 49P */
addYX: fp.Elt{0xcf, 0x1d, 0x05, 0x74, 0xac, 0xd8, 0x6b, 0x85, 0x1e, 0xaa, 0xb7, 0x55, 0x08, 0xa4, 0xf6, 0x03, 0xeb, 0x3c, 0x74, 0xc9, 0xcb, 0xe7, 0x4a, 0x3a, 0xde, 0xab, 0x37, 0x71, 0xbb, 0xa5, 0x73, 0x41},
subYX: fp.Elt{0x8c, 0x91, 0x64, 0x03, 0x3f, 0x52, 0xd8, 0x53, 0x1c, 0x6b, 0xab, 0x3f, 0xf4, 0x04, 0xb4, 0xa2, 0xa4, 0xe5, 0x81, 0x66, 0x9e, 0x4a, 0x0b, 0x08, 0xa7, 0x7b, 0x25, 0xd0, 0x03, 0x5b, 0xa1, 0x0e},
dt2: fp.Elt{0x8a, 0x21, 0xf9, 0xf0, 0x31, 0x6e, 0xc5, 0x17, 0x08, 0x47, 0xfc, 0x1a, 0x2b, 0x6e, 0x69, 0x5a, 0x76, 0xf1, 0xb2, 0xf4, 0x68, 0x16, 0x93, 0xf7, 0x67, 0x3a, 0x4e, 0x4a, 0x61, 0x65, 0xc5, 0x5f},
},
{ /* 51P */
addYX: fp.Elt{0x8e, 0x98, 0x90, 0x77, 0xe6, 0xe1, 0x92, 0x48, 0x22, 0xd7, 0x5c, 0x1c, 0x0f, 0x95, 0xd5, 0x01, 0xed, 0x3e, 0x92, 0xe5, 0x9a, 0x81, 0xb0, 0xe3, 0x1b, 0x65, 0x46, 0x9d, 0x40, 0xc7, 0x14, 0x32},
subYX: fp.Elt{0xe5, 0x7a, 0x6d, 0xc4, 0x0d, 0x57, 0x6e, 0x13, 0x8f, 0xdc, 0xf8, 0x54, 0xcc, 0xaa, 0xd0, 0x0f, 0x86, 0xad, 0x0d, 0x31, 0x03, 0x9f, 0x54, 0x59, 0xa1, 0x4a, 0x45, 0x4c, 0x41, 0x1c, 0x71, 0x62},
dt2: fp.Elt{0x70, 0x17, 0x65, 0x06, 0x74, 0x82, 0x29, 0x13, 0x36, 0x94, 0x27, 0x8a, 0x66, 0xa0, 0xa4, 0x3b, 0x3c, 0x22, 0x5d, 0x18, 0xec, 0xb8, 0xb6, 0xd9, 0x3c, 0x83, 0xcb, 0x3e, 0x07, 0x94, 0xea, 0x5b},
},
{ /* 53P */
addYX: fp.Elt{0xf8, 0xd2, 0x43, 0xf3, 0x63, 0xce, 0x70, 0xb4, 0xf1, 0xe8, 0x43, 0x05, 0x8f, 0xba, 0x67, 0x00, 0x6f, 0x7b, 0x11, 0xa2, 0xa1, 0x51, 0xda, 0x35, 0x2f, 0xbd, 0xf1, 0x44, 0x59, 0x78, 0xd0, 0x4a},
subYX: fp.Elt{0xe4, 0x9b, 0xc8, 0x12, 0x09, 0xbf, 0x1d, 0x64, 0x9c, 0x57, 0x6e, 0x7d, 0x31, 0x8b, 0xf3, 0xac, 0x65, 0xb0, 0x97, 0xf6, 0x02, 0x9e, 0xfe, 0xab, 0xec, 0x1e, 0xf6, 0x48, 0xc1, 0xd5, 0xac, 0x3a},
dt2: fp.Elt{0x01, 0x83, 0x31, 0xc3, 0x34, 0x3b, 0x8e, 0x85, 0x26, 0x68, 0x31, 0x07, 0x47, 0xc0, 0x99, 0xdc, 0x8c, 0xa8, 0x9d, 0xd3, 0x2e, 0x5b, 0x08, 0x34, 0x3d, 0x85, 0x02, 0xd9, 0xb1, 0x0c, 0xff, 0x3a},
},
{ /* 55P */
addYX: fp.Elt{0x05, 0x35, 0xc5, 0xf4, 0x0b, 0x43, 0x26, 0x92, 0x83, 0x22, 0x1f, 0x26, 0x13, 0x9c, 0xe4, 0x68, 0xc6, 0x27, 0xd3, 0x8f, 0x78, 0x33, 0xef, 0x09, 0x7f, 0x9e, 0xd9, 0x2b, 0x73, 0x9f, 0xcf, 0x2c},
subYX: fp.Elt{0x5e, 0x40, 0x20, 0x3a, 0xeb, 0xc7, 0xc5, 0x87, 0xc9, 0x56, 0xad, 0xed, 0xef, 0x11, 0xe3, 0x8e, 0xf9, 0xd5, 0x29, 0xad, 0x48, 0x2e, 0x25, 0x29, 0x1d, 0x25, 0xcd, 0xf4, 0x86, 0x7e, 0x0e, 0x11},
dt2: fp.Elt{0xe4, 0xf5, 0x03, 0xd6, 0x9e, 0xd8, 0xc0, 0x57, 0x0c, 0x20, 0xb0, 0xf0, 0x28, 0x86, 0x88, 0x12, 0xb7, 0x3b, 0x2e, 0xa0, 0x09, 0x27, 0x17, 0x53, 0x37, 0x3a, 0x69, 0xb9, 0xe0, 0x57, 0xc5, 0x05},
},
{ /* 57P */
addYX: fp.Elt{0xb0, 0x0e, 0xc2, 0x89, 0xb0, 0xbb, 0x76, 0xf7, 0x5c, 0xd8, 0x0f, 0xfa, 0xf6, 0x5b, 0xf8, 0x61, 0xfb, 0x21, 0x44, 0x63, 0x4e, 0x3f, 0xb9, 0xb6, 0x05, 0x12, 0x86, 0x41, 0x08, 0xef, 0x9f, 0x28},
subYX: fp.Elt{0x6f, 0x7e, 0xc9, 0x1f, 0x31, 0xce, 0xf9, 0xd8, 0xae, 0xfd, 0xf9, 0x11, 0x30, 0x26, 0x3f, 0x7a, 0xdd, 0x25, 0xed, 0x8b, 0xa0, 0x7e, 0x5b, 0xe1, 0x5a, 0x87, 0xe9, 0x8f, 0x17, 0x4c, 0x15, 0x6e},
dt2: fp.Elt{0xbf, 0x9a, 0xd6, 0xfe, 0x36, 0x63, 0x61, 0xcf, 0x4f, 0xc9, 0x35, 0x83, 0xe7, 0xe4, 0x16, 0x9b, 0xe7, 0x7f, 0x3a, 0x75, 0x65, 0x97, 0x78, 0x13, 0x19, 0xa3, 0x5c, 0xa9, 0x42, 0xf6, 0xfb, 0x6a},
},
{ /* 59P */
addYX: fp.Elt{0xcc, 0xa8, 0x13, 0xf9, 0x70, 0x50, 0xe5, 0x5d, 0x61, 0xf5, 0x0c, 0x2b, 0x7b, 0x16, 0x1d, 0x7d, 0x89, 0xd4, 0xea, 0x90, 0xb6, 0x56, 0x29, 0xda, 0xd9, 0x1e, 0x80, 0xdb, 0xce, 0x93, 0xc0, 0x12},
subYX: fp.Elt{0xc1, 0xd2, 0xf5, 0x62, 0x0c, 0xde, 0xa8, 0x7d, 0x9a, 0x7b, 0x0e, 0xb0, 0xa4, 0x3d, 0xfc, 0x98, 0xe0, 0x70, 0xad, 0x0d, 0xda, 0x6a, 0xeb, 0x7d, 0xc4, 0x38, 0x50, 0xb9, 0x51, 0xb8, 0xb4, 0x0d},
dt2: fp.Elt{0x0f, 0x19, 0xb8, 0x08, 0x93, 0x7f, 0x14, 0xfc, 0x10, 0xe3, 0x1a, 0xa1, 0xa0, 0x9d, 0x96, 0x06, 0xfd, 0xd7, 0xc7, 0xda, 0x72, 0x55, 0xe7, 0xce, 0xe6, 0x5c, 0x63, 0xc6, 0x99, 0x87, 0xaa, 0x33},
},
{ /* 61P */
addYX: fp.Elt{0xb1, 0x6c, 0x15, 0xfc, 0x88, 0xf5, 0x48, 0x83, 0x27, 0x6d, 0x0a, 0x1a, 0x9b, 0xba, 0xa2, 0x6d, 0xb6, 0x5a, 0xca, 0x87, 0x5c, 0x2d, 0x26, 0xe2, 0xa6, 0x89, 0xd5, 0xc8, 0xc1, 0xd0, 0x2c, 0x21},
subYX: fp.Elt{0xf2, 0x5c, 0x08, 0xbd, 0x1e, 0xf5, 0x0f, 0xaf, 0x1f, 0x3f, 0xd3, 0x67, 0x89, 0x1a, 0xf5, 0x78, 0x3c, 0x03, 0x60, 0x50, 0xe1, 0xbf, 0xc2, 0x6e, 0x86, 0x1a, 0xe2, 0xe8, 0x29, 0x6f, 0x3c, 0x23},
dt2: fp.Elt{0x81, 0xc7, 0x18, 0x7f, 0x10, 0xd5, 0xf4, 0xd2, 0x28, 0x9d, 0x7e, 0x52, 0xf2, 0xcd, 0x2e, 0x12, 0x41, 0x33, 0x3d, 0x3d, 0x2a, 0x86, 0x0a, 0xa7, 0xe3, 0x4c, 0x91, 0x11, 0x89, 0x77, 0xb7, 0x1d},
},
{ /* 63P */
addYX: fp.Elt{0xb6, 0x1a, 0x70, 0xdd, 0x69, 0x47, 0x39, 0xb3, 0xa5, 0x8d, 0xcf, 0x19, 0xd4, 0xde, 0xb8, 0xe2, 0x52, 0xc8, 0x2a, 0xfd, 0x61, 0x41, 0xdf, 0x15, 0xbe, 0x24, 0x7d, 0x01, 0x8a, 0xca, 0xe2, 0x7a},
subYX: fp.Elt{0x6f, 0xc2, 0x6b, 0x7c, 0x39, 0x52, 0xf3, 0xdd, 0x13, 0x01, 0xd5, 0x53, 0xcc, 0xe2, 0x97, 0x7a, 0x30, 0xa3, 0x79, 0xbf, 0x3a, 0xf4, 0x74, 0x7c, 0xfc, 0xad, 0xe2, 0x26, 0xad, 0x97, 0xad, 0x31},
dt2: fp.Elt{0x62, 0xb9, 0x20, 0x09, 0xed, 0x17, 0xe8, 0xb7, 0x9d, 0xda, 0x19, 0x3f, 0xcc, 0x18, 0x85, 0x1e, 0x64, 0x0a, 0x56, 0x25, 0x4f, 0xc1, 0x91, 0xe4, 0x83, 0x2c, 0x62, 0xa6, 0x53, 0xfc, 0xd1, 0x1e},
},
}