Browse Source

Breaking changes!

Switch everything over to the Ristretto variant of the Decaf encoding,
for compatibility with https://github.com/isislovecruft/curve25519-dalek
and others.  Documentation coming sometime at https://ristretto.group/.

For now, suffice it to say that Ristretto has the same API and security
properties, but slightly different input and output bytes.

Also close Ticket 9, renaming "mul_by_cofactor_and_encode" functions to
"mul_by_ratio_and_encode" with an appropriate #defined ENCODE_RATIO.
This is because the base points in RFC 7748 and RFC 8032 have different
relationships with the libdecaf base points.  With this change,
mul_by_ratio_and_encode'ing the base point will result in
[EDDSA|X25519|X448]_ENCODE_RATIO times the RFC 8032 EdDSA and RFC 7748
X25519|X448 base point.

Merge branch 'ristretto-work'
master
Michael Hamburg 7 years ago
parent
commit
7527e91a56
44 changed files with 3250 additions and 1679 deletions
  1. +26
    -0
      HISTORY.txt
  2. +8
    -1
      Makefile
  3. +6
    -3
      README.md
  4. +0
    -224
      aux/ristretto.sage
  5. +764
    -0
      aux/ristretto/ristretto.sage
  6. +140
    -0
      aux/ristretto/ristretto.tex
  7. +15
    -0
      aux/ristretto/ristretto_work.txt
  8. +185
    -229
      src/GENERATED/c/curve25519/decaf.c
  9. +13
    -4
      src/GENERATED/c/curve25519/decaf_gen_tables.c
  10. +148
    -148
      src/GENERATED/c/curve25519/decaf_tables.c
  11. +14
    -12
      src/GENERATED/c/curve25519/eddsa.c
  12. +62
    -61
      src/GENERATED/c/curve25519/elligator.c
  13. +185
    -229
      src/GENERATED/c/ed448goldilocks/decaf.c
  14. +13
    -4
      src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c
  15. +276
    -276
      src/GENERATED/c/ed448goldilocks/decaf_tables.c
  16. +14
    -12
      src/GENERATED/c/ed448goldilocks/eddsa.c
  17. +62
    -61
      src/GENERATED/c/ed448goldilocks/elligator.c
  18. +3
    -1
      src/GENERATED/c/p25519/f_field.h
  19. +14
    -3
      src/GENERATED/c/p25519/f_generic.c
  20. +3
    -1
      src/GENERATED/c/p448/f_field.h
  21. +14
    -3
      src/GENERATED/c/p448/f_generic.c
  22. +1
    -1
      src/GENERATED/include/decaf.hxx
  23. +30
    -6
      src/GENERATED/include/decaf/ed255.h
  24. +5
    -5
      src/GENERATED/include/decaf/ed255.hxx
  25. +30
    -6
      src/GENERATED/include/decaf/ed448.h
  26. +41
    -0
      src/GENERATED/include/decaf/point_255.h
  27. +65
    -18
      src/GENERATED/include/decaf/point_255.hxx
  28. +41
    -0
      src/GENERATED/include/decaf/point_448.h
  29. +55
    -9
      src/GENERATED/include/decaf/point_448.hxx
  30. +20
    -4
      src/generator/curve_data.py
  31. +5
    -0
      src/include/field.h
  32. +185
    -229
      src/per_curve/decaf.tmpl.c
  33. +13
    -4
      src/per_curve/decaf_gen_tables.tmpl.c
  34. +13
    -17
      src/per_curve/eddsa.tmpl.c
  35. +30
    -6
      src/per_curve/eddsa.tmpl.h
  36. +62
    -61
      src/per_curve/elligator.tmpl.c
  37. +41
    -0
      src/per_curve/point.tmpl.h
  38. +55
    -9
      src/per_curve/point.tmpl.hxx
  39. +3
    -1
      src/per_field/f_field.tmpl.h
  40. +14
    -3
      src/per_field/f_generic.tmpl.c
  41. +214
    -0
      test/ristretto.cxx
  42. +290
    -0
      test/ristretto_vectors.inc.cxx
  43. +57
    -13
      test/test_decaf.cxx
  44. +15
    -15
      test/vectors.inc.cxx

+ 26
- 0
HISTORY.txt View File

@@ -1,3 +1,29 @@
October 13, 2017:
OK, back to preparations for 1.0, today with major changes.
Another group (Isis Lovecruft and Henry de Valence) implemented
Decaf for Ed25519, whereas this code was implemented for IsoEd25519.
These curves are isogenous, but not exactly the same, so the
encodings all came out differently.
To harmonize these two so that there is only one implementation
for Ed25519, we've hammered out a compromise implementation called
Ristretto. This is different from the old Decaf encoding in two
major ways:
* It checks the sign of x on Ed25519 instead of IsoEd25519.
* It considers a number "negative" if its low bit is set,
instead of its high bit.
To avoid extra branches in the code, Ed448Goldilocks is also
getting these changes to match Ristretto.
The C++ class is also renamed to Ristretto, but IsoEd25519 is a
synonym for that class.
We might need to check the high bit again instead of low bit if
E-521 is ever implemented, but I'll special case it then.

April 22, 2017:
Remove STROBE in preparation for 1.0 release. STROBE has its own
repo now at https://strobe.sourceforge.io. I might re-integrate


+ 8
- 1
Makefile View File

@@ -85,7 +85,7 @@ LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/sha512.o

BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o

all: lib $(BUILD_IBIN)/test $(BUILD_IBIN)/bench $(BUILD_BIN)/shakesum
all: lib $(BUILD_IBIN)/test $(BUILD_BIN)/ristretto $(BUILD_IBIN)/bench $(BUILD_BIN)/shakesum

scan: clean
scan-build --use-analyzer=`which clang` \
@@ -101,6 +101,13 @@ else
$(LDXX) $(LDFLAGS) -Wl,-rpath,`pwd`/$(BUILD_LIB) -o $@ $< -L$(BUILD_LIB) -ldecaf
endif

$(BUILD_BIN)/ristretto: $(BUILD_OBJ)/ristretto.o lib
ifeq ($(UNAME),Darwin)
$(LDXX) $(LDFLAGS) -o $@ $< -L$(BUILD_LIB) -ldecaf
else
$(LDXX) $(LDFLAGS) -Wl,-rpath,`pwd`/$(BUILD_LIB) -o $@ $< -L$(BUILD_LIB) -ldecaf
endif

# Internal test programs, which are not part of the final build/bin directory.
$(BUILD_IBIN)/test_ct: $(BUILD_OBJ)/test_ct.o lib
ifeq ($(UNAME),Darwin)


+ 6
- 3
README.md View File

@@ -9,9 +9,12 @@ Because this is new software, please expect it to have bugs, perhaps
even critical security bugs. If you are using it, please sign up for
updates:

* Security-critical announcements (very low volume, God willing): decaf-security@googlegroups.com
* New version announcements (low volume): decaf-announce@googlegroups.com
* Library discussion (potentially more volume): decaf-discuss@googlegroups.com
* Security-critical announcements (very low volume, God willing):
decaf-security@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-security
* New version announcements (low volume):
decaf-announce@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-annonuce
* Library discussion (potentially more volume):
decaf-discuss@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-discuss

## General elliptic curve operations.



+ 0
- 224
aux/ristretto.sage View File

@@ -1,224 +0,0 @@

class InvalidEncodingException(Exception): pass
class NotOnCurveException(Exception): pass

def lobit(x): return int(x) & 1
def hibit(x): return lobit(2*x)
def enc_le(x,n): return bytearray([int(x)>>(8*i) & 0xFF for i in xrange(n)])
def dec_le(x): return sum(b<<(8*i) for i,b in enumerate(x))

def isqrt(x,exn=InvalidEncodingException("Not on curve")):
"""Return 1/sqrt(x)"""
if x==0: return 0
if not is_square(x): raise exn
return 1/sqrt(x)

class EdwardsPoint(object):
"""Abstract class for point an an Edwards curve; needs F,a,d to work"""
def __init__(self,x=0,y=1):
x = self.x = self.F(x)
y = self.y = self.F(y)
if y^2 + self.a*x^2 != 1 + self.d*x^2*y^2:
raise NotOnCurveException()

def __repr__(self):
return "%s(0x%x,0x%x)" % (self.__class__.__name__, self.x, self.y)

def __iter__(self):
yield self.x
yield self.y

def __add__(self,other):
x,y = self
X,Y = other
a,d = self.a,self.d
return self.__class__(
(x*Y+y*X)/(1+d*x*y*X*Y),
(y*Y-a*x*X)/(1-d*x*y*X*Y)
)
def __neg__(self): return self.__class__(-self.x,self.y)
def __sub__(self,other): return self + (-other)
def __rmul__(self,other): return self*other
def __eq__(self,other): return tuple(self) == tuple(other)
def __ne__(self,other): return not (self==other)
def __mul__(self,exp):
exp = int(exp)
total = self.__class__()
work = self
while exp != 0:
if exp & 1: total += work
work += work
exp >>= 1
return total
def xyzt(self):
x,y = self
z = self.F.random_element()
return x*z,y*z,z,x*y*z

class RistrettoPoint(EdwardsPoint):
"""Like current decaf but tweaked for simplicity"""
def __eq__(self,other):
x,y = self
X,Y = other
return x*Y == X*y or x*X == y*Y
@staticmethod
def sqrt(x,negative=lobit,exn=InvalidEncodingException("Not on curve")):
if not is_square(x): raise exn
s = sqrt(x)
if negative(s): s=-s
return s
def encodeSpec(self):
"""Unoptimized specification for encoding"""
x,y = self
if self.cofactor==8 and (lobit(x*y) or x==0):
(x,y) = (self.i*y,self.i*x)
elif self.cofactor==4 and y==-1:
y = 1 # Doesn't affect impl
if lobit(x): y=-y
s = self.sqrt((1-y)/(1+y),exn=Exception("Unimplemented: point is even"))
return enc_le(s,self.encLen)
@classmethod
def decodeSpec(cls,s):
"""Unoptimized specification for decoding"""
if len(s) != cls.encLen:
raise InvalidEncodingException("wrong length %d" % len(s))
s = dec_le(s)
if s < 0 or s >= cls.F.modulus() or lobit(s):
raise InvalidEncodingException("%d out of range!" % s)
s = cls.F(s)
x = cls.sqrt(-4*s^2 / (cls.d*(s^2-1)^2 + (s^2+1)^2))
y = (1-s^2) / (1+s^2)
if cls.cofactor==8 and (lobit(x*y) or x==0):
raise InvalidEncodingException("x*y has high bit")
return cls(x,y)
def encode(self):
x,y,z,t = self.xyzt()

u1 = (z+y)*(z-y)
u2 = x*y # = t*z
isr = isqrt(u1 * u2^2)
i1 = isr*u1
i2 = isr*u2
z_inv = i1*i2*t

rotate = self.cofactor==8 and lobit(t*z_inv)
if rotate:
magic = isqrt(-self.d-1)
x,y = y*self.i,x*self.i
den_inv = magic * i1
else:
den_inv = i2

if lobit(x*z_inv): y = -y
s = (z-y) * den_inv
if self.cofactor==8 and s==0: s += 1
if lobit(s): s=-s
ret = enc_le(s,self.encLen)
assert ret == self.encodeSpec()
return ret
@classmethod
def decode(cls,s):
right_answer = cls.decodeSpec(s)
# Sanity check s
if len(s) != cls.encLen:
raise InvalidEncodingException("wrong length %d" % len(s))
s = dec_le(s)
if s < 0 or s >= cls.F.modulus() or lobit(s):
raise InvalidEncodingException("%d out of range!" % s)
s = cls.F(s)
yden = 1+s^2
ynum = 1-s^2
yden_sqr = yden^2
xden_sqr = -cls.d*ynum^2 - yden_sqr
isr = isqrt(xden_sqr * yden_sqr)
xden_inv = isr * yden
yden_inv = xden_inv * isr * xden_sqr
x = 2*s*xden_inv
if lobit(x): x = -x
y = ynum * yden_inv
if cls.cofactor==8 and (lobit(x*y) or x==0):
raise InvalidEncodingException("x*y has high bit")
ret = cls(x,y)
assert ret == right_answer
return ret
def torque(self):
if self.cofactor == 8:
return self.__class__(self.y*self.i, self.x*self.i)
else:
return self.__class__(-self.x, -self.y)

class Ed25519Point(RistrettoPoint):
F = GF(2^255-19)
d = F(-121665/121666)
a = F(-1)
i = sqrt(F(-1))
cofactor = 8
encLen = 32
@classmethod
def base(cls):
y = cls.F(4/5)
x = sqrt((y^2-1)/(cls.d*y^2+1))
if lobit(x): x = -x
return cls(x,y)

class Ed448Point(RistrettoPoint):
F = GF(2^448-2^224-1)
d = F(-39082)
a = F(-1)
cofactor = 4
encLen = 56
@classmethod
def base(cls):
y = cls.F(6) # FIXME: no it isn't
x = sqrt((y^2-1)/(cls.d*y^2+1))
if lobit(x): x = -x
return cls(x,y)

class TestFailedException(Exception): pass
def test(cls,n):
# TODO: test corner cases like 0,1,i
P = cls.base()
Q = cls()
for i in xrange(n):
QQ = cls.decode(Q.encode())
if QQ != Q: raise TestFailedException("Round trip %s != %s" % (str(QQ),str(Q)))
if Q.encode() != Q.torque().encode():
raise TestFailedException("Can't torque %s" % str(Q))
Q0 = Q + P
if Q0 == Q: raise TestFailedException("Addition doesn't work")
if Q0-P != Q: raise TestFailedException("Subtraction doesn't work")
r = randint(1,1000)
Q1 = Q0*r
Q2 = Q0*(r+1)
if Q1 + Q0 != Q2: raise TestFailedException("Scalarmul doesn't work")
Q = Q1

+ 764
- 0
aux/ristretto/ristretto.sage View File

@@ -0,0 +1,764 @@
import binascii
class InvalidEncodingException(Exception): pass
class NotOnCurveException(Exception): pass
class SpecException(Exception): pass

def lobit(x): return int(x) & 1
def hibit(x): return lobit(2*x)
def negative(x): return lobit(x)
def enc_le(x,n): return bytearray([int(x)>>(8*i) & 0xFF for i in xrange(n)])
def dec_le(x): return sum(b<<(8*i) for i,b in enumerate(x))
def randombytes(n): return bytearray([randint(0,255) for _ in range(n)])

def optimized_version_of(spec):
"""Decorator: This function is an optimized version of some specification"""
def decorator(f):
def wrapper(self,*args,**kwargs):
def pr(x):
if isinstance(x,bytearray): return binascii.hexlify(x)
else: return str(x)
try: spec_ans = getattr(self,spec,spec)(*args,**kwargs),None
except Exception as e: spec_ans = None,e
try: opt_ans = f(self,*args,**kwargs),None
except Exception as e: opt_ans = None,e
if spec_ans[1] is None and opt_ans[1] is not None:
raise
#raise SpecException("Mismatch in %s: spec returned %s but opt threw %s"
# % (f.__name__,str(spec_ans[0]),str(opt_ans[1])))
if spec_ans[1] is not None and opt_ans[1] is None:
raise
#raise SpecException("Mismatch in %s: spec threw %s but opt returned %s"
# % (f.__name__,str(spec_ans[1]),str(opt_ans[0])))
if spec_ans[0] != opt_ans[0]:
raise SpecException("Mismatch in %s: %s != %s"
% (f.__name__,pr(spec_ans[0]),pr(opt_ans[0])))
if opt_ans[1] is not None: raise
else: return opt_ans[0]
wrapper.__name__ = f.__name__
return wrapper
return decorator
def xsqrt(x,exn=InvalidEncodingException("Not on curve")):
"""Return sqrt(x)"""
if not is_square(x): raise exn
s = sqrt(x)
if negative(s): s=-s
return s

def isqrt(x,exn=InvalidEncodingException("Not on curve")):
"""Return 1/sqrt(x)"""
if x==0: return 0
if not is_square(x): raise exn
s = sqrt(x)
#if negative(s): s=-s
return 1/s

def inv0(x): return 1/x if x != 0 else 0

def isqrt_i(x):
"""Return 1/sqrt(x) or 1/sqrt(zeta * x)"""
if x==0: return True,0
gen = x.parent(-1)
while is_square(gen): gen = sqrt(gen)
if is_square(x): return True,1/sqrt(x)
else: return False,1/sqrt(x*gen)

class QuotientEdwardsPoint(object):
"""Abstract class for point an a quotiented Edwards curve; needs F,a,d,cofactor to work"""
def __init__(self,x=0,y=1):
x = self.x = self.F(x)
y = self.y = self.F(y)
if y^2 + self.a*x^2 != 1 + self.d*x^2*y^2:
raise NotOnCurveException(str(self))

def __repr__(self):
return "%s(0x%x,0x%x)" % (self.__class__.__name__, self.x, self.y)

def __iter__(self):
yield self.x
yield self.y

def __add__(self,other):
x,y = self
X,Y = other
a,d = self.a,self.d
return self.__class__(
(x*Y+y*X)/(1+d*x*y*X*Y),
(y*Y-a*x*X)/(1-d*x*y*X*Y)
)
def __neg__(self): return self.__class__(-self.x,self.y)
def __sub__(self,other): return self + (-other)
def __rmul__(self,other): return self*other
def __eq__(self,other):
"""NB: this is the only method that is different from the usual one"""
x,y = self
X,Y = other
return x*Y == X*y or (self.cofactor==8 and -self.a*x*X == y*Y)
def __ne__(self,other): return not (self==other)
def __mul__(self,exp):
exp = int(exp)
if exp < 0: exp,self = -exp,-self
total = self.__class__()
work = self
while exp != 0:
if exp & 1: total += work
work += work
exp >>= 1
return total
def xyzt(self):
x,y = self
z = self.F.random_element()
return x*z,y*z,z,x*y*z
def torque(self):
"""Apply cofactor group, except keeping the point even"""
if self.cofactor == 8:
if self.a == -1: return self.__class__(self.y*self.i, self.x*self.i)
if self.a == 1: return self.__class__(-self.y, self.x)
else:
return self.__class__(-self.x, -self.y)

# Utility functions
@classmethod
def bytesToGf(cls,bytes,mustBeProper=True,mustBePositive=False,maskHiBits=False):
"""Convert little-endian bytes to field element, sanity check length"""
if len(bytes) != cls.encLen:
raise InvalidEncodingException("wrong length %d" % len(bytes))
s = dec_le(bytes)
if mustBeProper and s >= cls.F.order():
raise InvalidEncodingException("%d out of range!" % s)
bitlen = int(ceil(log(cls.F.order())/log(2)))
if maskHiBits: s &= 2^bitlen-1
s = cls.F(s)
if mustBePositive and negative(s):
raise InvalidEncodingException("%d is negative!" % s)
return s
@classmethod
def gfToBytes(cls,x,mustBePositive=False):
"""Convert little-endian bytes to field element, sanity check length"""
if negative(x) and mustBePositive: x = -x
return enc_le(x,cls.encLen)

class RistrettoPoint(QuotientEdwardsPoint):
"""The new Ristretto group"""
def encodeSpec(self):
"""Unoptimized specification for encoding"""
x,y = self
if self.cofactor==8 and (negative(x*y) or y==0): (x,y) = self.torque()
if y == -1: y = 1 # Avoid divide by 0; doesn't affect impl
if negative(x): x,y = -x,-y
s = xsqrt(self.mneg*(1-y)/(1+y),exn=Exception("Unimplemented: point is odd: " + str(self)))
return self.gfToBytes(s)
@classmethod
def decodeSpec(cls,s):
"""Unoptimized specification for decoding"""
s = cls.bytesToGf(s,mustBePositive=True)
a,d = cls.a,cls.d
x = xsqrt(4*s^2 / (a*d*(1+a*s^2)^2 - (1-a*s^2)^2))
y = (1+a*s^2) / (1-a*s^2)
if cls.cofactor==8 and (negative(x*y) or y==0):
raise InvalidEncodingException("x*y has high bit")
return cls(x,y)

@optimized_version_of("encodeSpec")
def encode(self):
"""Encode, optimized version"""
a,d,mneg = self.a,self.d,self.mneg
x,y,z,t = self.xyzt()
if self.cofactor==8:
u1 = mneg*(z+y)*(z-y)
u2 = x*y # = t*z
isr = isqrt(u1*u2^2)
i1 = isr*u1 # sqrt(mneg*(z+y)*(z-y))/(x*y)
i2 = isr*u2 # 1/sqrt(a*(y+z)*(y-z))
z_inv = i1*i2*t # 1/z
if negative(t*z_inv):
if a==-1:
x,y = y*self.i,x*self.i
den_inv = self.magic * i1
else:
x,y = -y,x
den_inv = self.i * self.magic * i1
else:
den_inv = i2

if negative(x*z_inv): y = -y
s = (z-y) * den_inv
else:
num = mneg*(z+y)*(z-y)
isr = isqrt(num*y^2)
if negative(isr^2*num*y*t): y = -y
s = isr*y*(z-y)
return self.gfToBytes(s,mustBePositive=True)
@classmethod
@optimized_version_of("decodeSpec")
def decode(cls,s):
"""Decode, optimized version"""
s = cls.bytesToGf(s,mustBePositive=True)
a,d = cls.a,cls.d
yden = 1-a*s^2
ynum = 1+a*s^2
yden_sqr = yden^2
xden_sqr = a*d*ynum^2 - yden_sqr
isr = isqrt(xden_sqr * yden_sqr)
xden_inv = isr * yden
yden_inv = xden_inv * isr * xden_sqr
x = 2*s*xden_inv
if negative(x): x = -x
y = ynum * yden_inv
if cls.cofactor==8 and (negative(x*y) or y==0):
raise InvalidEncodingException("x*y is invalid: %d, %d" % (x,y))
return cls(x,y)
@classmethod
def fromJacobiQuartic(cls,s,t,sgn=1):
"""Convert point from its Jacobi Quartic representation"""
a,d = cls.a,cls.d
assert s^4 - 2*cls.a*(1-2*d/(d-a))*s^2 + 1 == t^2
x = 2*s*cls.magic / t
y = (1+a*s^2) / (1-a*s^2)
return cls(sgn*x,y)
@classmethod
def elligatorSpec(cls,r0):
a,d = cls.a,cls.d
r = cls.qnr * cls.bytesToGf(r0,mustBeProper=False,maskHiBits=True)^2
den = (d*r-a)*(a*r-d)
if den == 0: return cls()
n1 = cls.a*(r+1)*(a+d)*(d-a)/den
n2 = r*n1
if is_square(n1):
sgn,s,t = 1, xsqrt(n1), -(r-1)*(a+d)^2 / den - 1
else:
sgn,s,t = -1,-xsqrt(n2), r*(r-1)*(a+d)^2 / den - 1
return cls.fromJacobiQuartic(s,t)
@classmethod
@optimized_version_of("elligatorSpec")
def elligator(cls,r0):
a,d = cls.a,cls.d
r0 = cls.bytesToGf(r0,mustBeProper=False,maskHiBits=True)
r = cls.qnr * r0^2
den = (d*r-a)*(a*r-d)
num = cls.a*(r+1)*(a+d)*(d-a)
iss,isri = isqrt_i(num*den)
if iss: sgn,twiddle = 1,1
else: sgn,twiddle = -1,r0*cls.qnr
isri *= twiddle
s = isri*num
t = -sgn*isri*s*(r-1)*(d+a)^2 - 1
if negative(s) == iss: s = -s
return cls.fromJacobiQuartic(s,t)


class Decaf_1_1_Point(QuotientEdwardsPoint):
"""Like current decaf but tweaked for simplicity"""
def encodeSpec(self):
"""Unoptimized specification for encoding"""
a,d = self.a,self.d
x,y = self
if x==0 or y==0: return(self.gfToBytes(0))
if self.cofactor==8 and negative(x*y*self.isoMagic):
x,y = self.torque()
sr = xsqrt(1-a*x^2)
altx = x*y*self.isoMagic / sr
if negative(altx): s = (1+sr)/x
else: s = (1-sr)/x
return self.gfToBytes(s,mustBePositive=True)
@classmethod
def decodeSpec(cls,s):
"""Unoptimized specification for decoding"""
a,d = cls.a,cls.d
s = cls.bytesToGf(s,mustBePositive=True)
if s==0: return cls()
t = xsqrt(s^4 + 2*(a-2*d)*s^2 + 1)
altx = 2*s*cls.isoMagic/t
if negative(altx): t = -t
x = 2*s / (1+a*s^2)
y = (1-a*s^2) / t
if cls.cofactor==8 and (negative(x*y*cls.isoMagic) or y==0):
raise InvalidEncodingException("x*y is invalid: %d, %d" % (x,y))
return cls(x,y)

def toJacobiQuartic(self,toggle_rotation=False,toggle_altx=False,toggle_s=False):
"Return s,t on jacobi curve"
a,d = self.a,self.d
x,y,z,t = self.xyzt()
if self.cofactor == 8:
# Cofactor 8 version
# Simulate IMAGINE_TWIST because that's how libdecaf does it
x = self.i*x
t = self.i*t
a = -a
d = -d
# OK, the actual libdecaf code should be here
num = (z+y)*(z-y)
den = x*y
isr = isqrt(num*(a-d)*den^2)
iden = isr * den * self.isoMagic # 1/sqrt((z+y)(z-y)) = 1/sqrt(1-Y^2) / z
inum = isr * num # sqrt(1-Y^2) * z / xysqrt(a-d) ~ 1/sqrt(1-ax^2)/z
if negative(iden*inum*self.i*t^2*(d-a)) != toggle_rotation:
iden,inum = inum,iden
fac = x*sqrt(a)
toggle=(a==-1)
else:
fac = y
toggle=False
imi = self.isoMagic * self.i
altx = inum*t*imi
neg_altx = negative(altx) != toggle_altx
if neg_altx != toggle: inum =- inum
tmp = fac*(inum*z + 1)
s = iden*tmp*imi
negm1 = (negative(s) != toggle_s) != neg_altx
if negm1: m1 = a*fac + z
else: m1 = a*fac - z
swap = toggle_s
else:
# Much simpler cofactor 4 version
num = (x+t)*(x-t)
isr = isqrt(num*(a-d)*x^2)
ratio = isr*num
altx = ratio*self.isoMagic
neg_altx = negative(altx) != toggle_altx
if neg_altx: ratio =- ratio
tmp = ratio*z - t
s = (a-d)*isr*x*tmp
negx = (negative(s) != toggle_s) != neg_altx
if negx: m1 = -a*t + x
else: m1 = -a*t - x
swap = toggle_s
if negative(s): s = -s
return s,m1,a*tmp,swap
def invertElligator(self,toggle_r=False,*args,**kwargs):
"Produce preimage of self under elligator, or None"
a,d = self.a,self.d
rets = []
tr = [False,True] if self.cofactor == 8 else [False]
for toggle_rotation in tr:
for toggle_altx in [False,True]:
for toggle_s in [False,True]:
for toggle_r in [False,True]:
s,m1,m12,swap = self.toJacobiQuartic(toggle_rotation,toggle_altx,toggle_s)

#print
#print toggle_rotation,toggle_altx,toggle_s
#print m1
#print m12
if self == self.__class__():
if self.cofactor == 4:
# Hacks for identity!
if toggle_altx: m12 = 1
elif toggle_s: m1 = 1
elif toggle_r: continue
## BOTH???
else:
m12 = 1
imi = self.isoMagic * self.i
if toggle_rotation:
if toggle_altx: m1 = -imi
else: m1 = +imi
else:
if toggle_altx: m1 = 0
else: m1 = a-d
rnum = (d*a*m12-m1)
rden = ((d*a-1)*m12+m1)
if swap: rnum,rden = rden,rnum
ok,sr = isqrt_i(rnum*rden*self.qnr)
if not ok: continue
sr *= rnum
#print "Works! %d %x" % (swap,sr)
if negative(sr) != toggle_r: sr = -sr
ret = self.gfToBytes(sr)
if self.elligator(ret) != self and self.elligator(ret) != -self:
print "WRONG!",[toggle_rotation,toggle_altx,toggle_s]
if self.elligator(ret) == -self and self != -self: print "Negated!",[toggle_rotation,toggle_altx,toggle_s]
rets.append(bytes(ret))
return rets

@optimized_version_of("encodeSpec")
def encode(self):
"""Encode, optimized version"""
return self.gfToBytes(self.toJacobiQuartic()[0])
@classmethod
@optimized_version_of("decodeSpec")
def decode(cls,s):
"""Decode, optimized version"""
a,d = cls.a,cls.d
s = cls.bytesToGf(s,mustBePositive=True)
#if s==0: return cls()
s2 = s^2
den = 1+a*s2
num = den^2 - 4*d*s2
isr = isqrt(num*den^2)
altx = 2*s*isr*den*cls.isoMagic
if negative(altx): isr = -isr
x = 2*s *isr^2*den*num
y = (1-a*s^2) * isr*den
if cls.cofactor==8 and (negative(x*y*cls.isoMagic) or y==0):
raise InvalidEncodingException("x*y is invalid: %d, %d" % (x,y))
return cls(x,y)

@classmethod
def fromJacobiQuartic(cls,s,t,sgn=1):
"""Convert point from its Jacobi Quartic representation"""
a,d = cls.a,cls.d
if s==0: return cls()
x = 2*s / (1+a*s^2)
y = (1-a*s^2) / t
return cls(x,sgn*y)
@classmethod
def elligatorSpec(cls,r0,fromR=False):
a,d = cls.a,cls.d
if fromR: r = r0
else: r = cls.qnr * cls.bytesToGf(r0,mustBeProper=False,maskHiBits=True)^2
den = (d*r-(d-a))*((d-a)*r-d)
if den == 0: return cls()
n1 = (r+1)*(a-2*d)/den
n2 = r*n1
if is_square(n1):
sgn,s,t = 1, xsqrt(n1), -(r-1)*(a-2*d)^2 / den - 1
else:
sgn,s,t = -1, -xsqrt(n2), r*(r-1)*(a-2*d)^2 / den - 1
return cls.fromJacobiQuartic(s,t)
@classmethod
@optimized_version_of("elligatorSpec")
def elligator(cls,r0):
a,d = cls.a,cls.d
r0 = cls.bytesToGf(r0,mustBeProper=False,maskHiBits=True)
r = cls.qnr * r0^2
den = (d*r-(d-a))*((d-a)*r-d)
num = (r+1)*(a-2*d)
iss,isri = isqrt_i(num*den)
if iss: sgn,twiddle = 1,1
else: sgn,twiddle = -1,r0*cls.qnr
isri *= twiddle
s = isri*num
t = -sgn*isri*s*(r-1)*(a-2*d)^2 - 1
if negative(s) == iss: s = -s
return cls.fromJacobiQuartic(s,t)
def elligatorInverseBruteForce(self):
"""Invert Elligator using SAGE's polynomial solver"""
a,d = self.a,self.d
R.<r0> = self.F[]
r = self.qnr * r0^2
den = (d*r-(d-a))*((d-a)*r-d)
n1 = (r+1)*(a-2*d)/den
n2 = r*n1
ret = set()
for s2,t in [(n1, -(r-1)*(a-2*d)^2 / den - 1),
(n2,r*(r-1)*(a-2*d)^2 / den - 1)]:
x2 = 4*s2/(1+a*s2)^2
y = (1-a*s2) / t

selfT = self
for i in xrange(self.cofactor/2):
xT,yT = selfT
polyX = xT^2-x2
polyY = yT-y
sx = set(r for r,_ in polyX.numerator().roots())
sy = set(r for r,_ in polyY.numerator().roots())
ret = ret.union(sx.intersection(sy))
selfT = selfT.torque()

ret = [self.gfToBytes(r) for r in ret]
for r in ret:
assert self.elligator(r) in [self,-self]
ret = [r for r in ret if self.elligator(r) == self]

return ret
class Ed25519Point(RistrettoPoint):
F = GF(2^255-19)
d = F(-121665/121666)
a = F(-1)
i = sqrt(F(-1))
mneg = F(1)
qnr = i
magic = isqrt(a*d-1)
cofactor = 8
encLen = 32
@classmethod
def base(cls):
return cls( 15112221349535400772501151409588531511454012693041857206046113283949847762202, 46316835694926478169428394003475163141307993866256225615783033603165251855960
)
class NegEd25519Point(RistrettoPoint):
F = GF(2^255-19)
d = F(121665/121666)
a = F(1)
i = sqrt(F(-1))
mneg = F(-1) # TODO checkme vs 1-ad or whatever
qnr = i
magic = isqrt(a*d-1)
cofactor = 8
encLen = 32
@classmethod
def base(cls):
y = cls.F(4/5)
x = sqrt((y^2-1)/(cls.d*y^2-cls.a))
if negative(x): x = -x
return cls(x,y)

class IsoEd448Point(RistrettoPoint):
F = GF(2^448-2^224-1)
d = F(39082/39081)
a = F(1)
mneg = F(-1)
qnr = -1
magic = isqrt(a*d-1)
cofactor = 4
encLen = 56
@classmethod
def base(cls):
return cls( # RFC has it wrong
345397493039729516374008604150537410266655260075183290216406970281645695073672344430481787759340633221708391583424041788924124567700732,
-363419362147803445274661903944002267176820680343659030140745099590306164083365386343198191849338272965044442230921818680526749009182718
)
class TwistedEd448GoldilocksPoint(Decaf_1_1_Point):
F = GF(2^448-2^224-1)
d = F(-39082)
a = F(-1)
qnr = -1
cofactor = 4
encLen = 56
isoMagic = IsoEd448Point.magic

@classmethod
def base(cls):
return cls.decodeSpec(Ed448GoldilocksPoint.base().encodeSpec())

class Ed448GoldilocksPoint(Decaf_1_1_Point):
F = GF(2^448-2^224-1)
d = F(-39081)
a = F(1)
qnr = -1
cofactor = 4
encLen = 56
isoMagic = IsoEd448Point.magic
@classmethod
def base(cls):
return 2*cls(
224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710, 298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660
)

class IsoEd25519Point(Decaf_1_1_Point):
# TODO: twisted iso too!
# TODO: twisted iso might have to IMAGINE_TWIST or whatever
F = GF(2^255-19)
d = F(-121665)
a = F(1)
i = sqrt(F(-1))
qnr = i
magic = isqrt(a*d-1)
cofactor = 8
encLen = 32
isoMagic = Ed25519Point.magic
isoA = Ed25519Point.a
@classmethod
def base(cls):
return cls.decodeSpec(Ed25519Point.base().encode())

class TestFailedException(Exception): pass

def test(cls,n):
print "Testing curve %s" % cls.__name__
specials = [1]
ii = cls.F(-1)
while is_square(ii):
specials.append(ii)
ii = sqrt(ii)
specials.append(ii)
for i in specials:
if negative(cls.F(i)): i = -i
i = enc_le(i,cls.encLen)
try:
Q = cls.decode(i)
QE = Q.encode()
if QE != i:
raise TestFailedException("Round trip special %s != %s" %
(binascii.hexlify(QE),binascii.hexlify(i)))
except NotOnCurveException: pass
except InvalidEncodingException: pass
P = cls.base()
Q = cls()
for i in xrange(n):
#print binascii.hexlify(Q.encode())
QE = Q.encode()
QQ = cls.decode(QE)
if QQ != Q: raise TestFailedException("Round trip %s != %s" % (str(QQ),str(Q)))
# Testing s -> 1/s: encodes -point on cofactor
s = cls.bytesToGf(QE)
if s != 0:
ss = cls.gfToBytes(1/s,mustBePositive=True)
try:
QN = cls.decode(ss)
if cls.cofactor == 8:
raise TestFailedException("1/s shouldnt work for cofactor 8")
if QN != -Q:
raise TestFailedException("s -> 1/s should negate point for cofactor 4")
except InvalidEncodingException as e:
# Should be raised iff cofactor==8
if cls.cofactor == 4:
raise TestFailedException("s -> 1/s should work for cofactor 4")
QT = Q
for h in xrange(cls.cofactor):
QT = QT.torque()
if QT.encode() != QE:
raise TestFailedException("Can't torque %s,%d" % (str(Q),h+1))
Q0 = Q + P
if Q0 == Q: raise TestFailedException("Addition doesn't work")
if Q0-P != Q: raise TestFailedException("Subtraction doesn't work")
r = randint(1,1000)
Q1 = Q0*r
Q2 = Q0*(r+1)
if Q1 + Q0 != Q2: raise TestFailedException("Scalarmul doesn't work")
Q = Q1
def testElligator(cls,n):
print "Testing elligator on %s" % cls.__name__
for i in xrange(n):
r = randombytes(cls.encLen)
P = cls.elligator(r)
if hasattr(P,"invertElligator"):
iv = P.invertElligator()
modr = bytes(cls.gfToBytes(cls.bytesToGf(r,mustBeProper=False,maskHiBits=True)))
iv2 = P.torque().invertElligator()
if modr not in iv: print "Failed to invert Elligator!"
if len(iv) != len(set(iv)):
print "Elligator inverses not unique!", len(set(iv)), len(iv)
if iv != iv2:
print "Elligator is untorqueable!"
#print [binascii.hexlify(j) for j in iv]
#print [binascii.hexlify(j) for j in iv2]
#break
else:
pass # TODO



def gangtest(classes,n):
print "Gang test",[cls.__name__ for cls in classes]
specials = [1]
ii = classes[0].F(-1)
while is_square(ii):
specials.append(ii)
ii = sqrt(ii)
specials.append(ii)
for i in xrange(n):
rets = [bytes((cls.base()*i).encode()) for cls in classes]
if len(set(rets)) != 1:
print "Divergence in encode at %d" % i
for c,ret in zip(classes,rets):
print c,binascii.hexlify(ret)
print
if i < len(specials): r0 = enc_le(specials[i],classes[0].encLen)
else: r0 = randombytes(classes[0].encLen)
rets = [bytes((cls.elligator(r0)*i).encode()) for cls in classes]
if len(set(rets)) != 1:
print "Divergence in elligator at %d" % i
for c,ret in zip(classes,rets):
print c,binascii.hexlify(ret)
print


test(Ed25519Point,100)
test(NegEd25519Point,100)
test(IsoEd25519Point,100)
test(IsoEd448Point,100)
test(TwistedEd448GoldilocksPoint,100)
test(Ed448GoldilocksPoint,100)
testElligator(Ed25519Point,100)
testElligator(NegEd25519Point,100)
testElligator(IsoEd25519Point,100)
testElligator(IsoEd448Point,100)
testElligator(Ed448GoldilocksPoint,100)
testElligator(TwistedEd448GoldilocksPoint,100)
gangtest([IsoEd448Point,TwistedEd448GoldilocksPoint,Ed448GoldilocksPoint],100)
gangtest([Ed25519Point,IsoEd25519Point],100)

+ 140
- 0
aux/ristretto/ristretto.tex View File

@@ -0,0 +1,140 @@
\documentclass[11pt]{article}

\usepackage{amsmath,amsthm,amsfonts,amssymb,xspace,graphicx,url,stmaryrd,parskip}

\newtheorem{lemma}{Lemma}

\newcommand\todo[1]{\textbf{[[TODO: #1]]}\xspace}
\def\F{\ensuremath{\mathbb{F}}}
\def\G{\ensuremath{\mathbb{G}}}
\def\Z{\ensuremath{\mathbb{Z}}}
\def\O{\ensuremath{O}}

\begin{document}
\title{The Ristretto and Cortado elliptic curve groups}
\author{Mike Hamburg\thanks{Rambus Security Division}}
\maketitle

\begin{abstract}
\end{abstract}

\section{Introduction}
\section{Definitions and notation}

Let the symbol $\bot$ denote failure.

\subsection{Field elements}
Let \F\ be a finite field of prime order $p$. For an element $x\in\F$, let $\text{res}(x)$ be the integer representative of $x\in[0,p-1]$. We call an element $x\in\F$ \textit{negative} if $\text{res}(x)$ is odd. Call an element in \F\ \textit{square} if it is a quadratic residue, i.e.\ if there exists $\sqrt{x}\in\F$ such that $\sqrt{x}^2=x$. There will in general be two such square roots; let the notation $\sqrt{x}$ mean the unique non-negative square root of $x$. If $p\equiv1\pmod 4$, then \F\ contains an element $i := \sqrt{-1}$.

Let $\ell := \lceil \log_{2^8} p\rceil$. Each $x\in\F$ has a unique \textit{little-endian byte representation}, namely the sequence
$$
\text{\F\_to\_bytes}(x) := \llbracket b_i\rrbracket_{i=0}^{\l-1} \ \text{where}\ b_i\in[0,255]\text{\ and\ }\sum_{i=0}^{\l-1} 2^{8i} \cdot b_i = \text{res}(x)
$$
\todo{bytes to \F}

\subsection{Groups}
For an abelian group \G\ with identity \O, let $n\G$ denote the subgroup of $\G$ which are of the form $n\cdot g$ for some $g\in\G$. Let $\G_n$ denote the $n$-torsion group of \G, namely the subgroup $\{g\in\G : n\cdot g = O\}$.

\subsection{Edwards curves}
We will work with twisted Edwards elliptic curves of the form
%
$$E_{a,d} : y^2 + a\cdot x^2 = 1 + d\cdot x^2\cdot y^2$$
%
where $x,y\in\F$. Twisted Edwards curves curves have a group law
$$(x_1,y_1) + (x_2,y_2) :=
\left(
\frac{x_1 y_2 + x_2 y_1}{1+d x_1 x_2 y_1 y_2},
\frac{y_1 y_2 - a x_1 x_2}{1-d x_1 x_2 y_1 y_2}
\right)
$$
with identity point $\O := (0,1)$ and group inverse operation $$-(x,y) = (-x,y)$$
The group law is called \textit{complete} if is produces the correct answer (rather than e.g.\ $0/0$) for all points on the curve. The above formulas are complete when $d$ and $ad$ are nonsquare in \F, which implies that $a$ is square. When these conditions hold, we also say that the curve itself is complete.

Let the number of points on the curve be $$\#E_{a,d} = h\cdot q$$ where $q$ is prime and $h\in\{4,8\}$. We call $h$ the \textit{cofactor}.

For $P = (x,y)\in E$, we can define the \textit{projective homogeneous form} of $P$ as $(X,Y,Z)$ with $Z\neq 0$ and $$(x,y) = (X/Z,Y/Z)$$ and the \textit{extended homogeneous form} as $(X,Y,Z,T)$ where additionally $XY=ZT$. Extended homogeneous form is popular because it supports simple and efficient complete addition formulas~\cite{hisil}.

\subsection{Montgomery curves}

When $a-d$ is square in \F, the twisted Edwards curve $E_{a,d}$ is isomorphic to the Montgomery curve
$$v^2 = u\cdot\left(u^2 + 2\cdot\frac{a+d}{a-d}\cdot u + 1\right)$$
by the map
$$(u,v) = \left(\frac{1+y}{1-y},\ \ \frac{1+y}{1-y}\cdot\frac1x\cdot\frac{2}{\sqrt{a-d}}\right)$$
with inverse
$$(x,y) = \left(\frac{u}{v}\cdot\frac{\sqrt{a-d}}{2},\ \ \frac{u-1}{u+1}\right)$$

If $M = (u,v)$ is a point on the Montgomery curve, then the $u$-coordinate of $2M$ is $(u^2-1)^2 / (4v^2)$ is necessarily square. It follows that if $(x,y)$ is a point on $E_{a,d}$, and $a-d$ is square, then $(1+y)/(1-y)$ is also square.

Likewhise, when $d-a$ is square in \F, $E_{a,d}$ is isomorphic to the Montgomery curve
$$v^2 = u\cdot\left(u^2 - 2\cdot\frac{a+d}{a-d}\cdot u + 1\right)$$
by the map
$$(u,v) = \left(\frac{y+1}{y-1},\ \ \frac{y+1}{y-1}\cdot\frac1x\cdot\frac{2}{\sqrt{d-a}}\right)$$
with inverse
$$(x,y) = \left(\frac{u}{v}\cdot\frac{\sqrt{d-a}}{2},\ \ \frac{1+u}{1-u}\right)$$

\section{Lemmas}
First, we characterize the 2-torsion and 4-torsion groups.\\
\begin{lemma}\label{lemma:tors}
Let $E_{a,d}$ be a complete Edwards curve. Its 2-torsion subgroup is generated by $(0,-1)$. The 4-torsion subgroup is generated by $(1/\sqrt{a},0)$.

Adding the 2-torsion generator to $(x,y)$ produces $(-x,-y)$. Adding the 4-torsion generator $(1/\sqrt{a},0)$ produces $(y/\sqrt{a},-x\cdot\sqrt{a})$
\end{lemma}
\begin{proof}
Inspection.
\end{proof}

\begin{lemma}\label{lemma:line}
Let $E_{a,d}$ be a complete twisted Edwards curve over \F, and $P_1 = (x_1,y_1)$ be any point on it. Then there are exactly two points $P_2 = (x_2,y_2)$ satisfying $x_1 y_2 = x_2 y_1$, namely $P_1$ itself and $(-x_1,-y_1)$. That is, there are either 0 or 2 points on any line through the origin.
\end{lemma}
\begin{proof}
Plugging into the group operation gives
$$x_1 y_2 = x_2 y_1 \Longleftrightarrow P_1-P_2 = (0,y_3)$$
for some $y_3$. Plugging $x=0$ into the curve equation gives $y=\pm1$, the 2-torsion points. Adding back, we have $P_2 = P_1 + (0,\pm1) = (\pm x_1, \pm y_1)$ as claimed.
\end{proof}

\begin{lemma}\label{lemma:dma}
If $E_{a,d}$ is a complete Edwards curve, then $a^2-ad$ is square in \F\ (and thus $a-d$ is square in \F) if and only if the cofactor of $E_{a,d}$ is divisible by 8.
\end{lemma}
\begin{proof}
Doubling an 8-torsion generator $(x,y)$ should produce a 4-torsion generator, i.e.\ a point with $y=0$. From the doubling formula, this happens precisely when $y^2=ax^2$, or $2ax^2=1+adx^4$. This has roots in \F\ if and only if its discriminant $4a^2-4ad$ is square, so that $a^2-ad$ is square.
\end{proof}

\begin{lemma}\label{lemma:sqrt}
If $(x_2,y_2) = 2\cdot(x_1,y_1)$ is an even point in $E_{a,d}$, then $(1-ax_2^2)$ is a quadratic residue in \F. \todo{$(y_2^2-1)$}.
\end{lemma}
\begin{proof}
The doubling formula has $$x_2 = \frac{2x_1 y_1}{y_1^2+ax_1^2}$$
so that $$1-ax_2^2 = \left(\frac{y_1^2-ax_1^2}{y_1^2+ax_1^2}\right)^2$$
is a quadratic residue. Now for any point $(x,y)\in E_{a,d}$, we have
$$(y^2-1)\cdot(1-ax^2)
= y^2+ax^2-1-ax^2y^2
= (d-a)x^2y^2
$$
which is a quadratic residue by Lemma~\ref{lemma:dma}.
\end{proof}

\section{The Espresso groups}
Let $E$ be a complete twisted Edwards curve with $a\in\{\pm1\}$ and cofactor $4$ or $8$. We describe the \textit{Espresso} group $\G(E)$ as
$$\text{Espresso}(E) := 2E / E_{h/2}$$
This group has prime order $q$.
\subsection{Group law}
The group law on $\text{Espresso}(E)$ is the same as that on $E$.
\subsection{Equality}
Two elements $P_1 := (x_1,y_1)$ and $P_2 := (x_2,y_2)$ in $\text{Espresso}(E)$ are equal if they differ by an element of $E_{h/2}$.

If $h=4$, the points are equal if $P_1-P_2\in E_2$. By Lemma~\ref{lemma:line}, this is equivalent to $$x_1 y_2 = x_2 y_1$$

If $h=8$, the points are equal if $P_1-P_2\in E_4$. By Lemmas~\ref{lemma:tors} and~\ref{lemma:line}, this is equivalent to $$x_1 y_2 = x_2 y_1\text{\ \ or\ \ }x_1 x_2 = -a y_1 y_2$$

These equations are homogeneous, so they may be evaluated in projective homogeneous form with $X_i$ and $Y_i$ in place of $x_i$ and $y_i$

\subsection{Encoding}
We now describe how to encode a point $P = (x,y)$ to bytes. The requirements of encoding are that
\begin{itemize}
\item Any point $P\in2E$ can be encoded.
\item Two points $P,Q$ have the same encoding if and only if $P-Q\in E_{h/2}$.
\end{itemize}

When $h=4$, we encode a point as $\sqrt{a(y-1)/(y+1)}$

\end{document}

+ 15
- 0
aux/ristretto/ristretto_work.txt View File

@@ -0,0 +1,15 @@
Have (1-ydbl)/(1+ydbl)
= (y^2-1)/(ax^2-1)

Have (y^2-1)*(ax^2-1) = (a-d) x^2 y^2

==> (1-ydbl)/(1+ydbl) has same parity as a-d

No points at infinity => d nonsqr, ad nonsqr -> a sqr.

Point of order 8: ax^2=y^2
2y^2 = 1+day^4
product of roots = 1/ad = nonsquare, so one will be square (if no point at infty)
b^2-4ac = 4(1-ad) -> 1-ad square iff point of order 8 exists

If a^2 = 1, then 1-ad = a(a-d)

+ 185
- 229
src/GENERATED/c/curve25519/decaf.c View File

@@ -48,10 +48,23 @@ static const scalar_t point_scalarmul_adjustment = {{{

const uint8_t decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] = { 0x09 };

#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL(
0x6db8831bbddec, 0x38d7b56c9c165, 0x016b221394bdc, 0x7540f7816214a, 0x0a0d85b4032b1
)};
#define RISTRETTO_FACTOR DECAF_255_RISTRETTO_FACTOR
const gf RISTRETTO_FACTOR = {{{
0x702557fa2bf03, 0x514b7d1a82cc6, 0x7f89efd8b43a7, 0x1aef49ec23700, 0x079376fa30500
}}};

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

/* End of template stuff */
@@ -109,128 +122,112 @@ gf_invert(gf y, const gf x, int assert_nonzero) {
gf_copy(y, t2);
}

/** Return high bit of x = low bit of 2x mod p */
static mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** identity = (0,1) */
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}};

/* Predeclare because not static: called by elligator */
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void) toggle_rotation;
gf b, d;
gf_s *c = s, *a = minus_t_over_s;
gf_mulw(a, p->y, 1-EDWARDS_D);
gf_mul(c, a, p->t); /* -dYT, with EDWARDS_D = d-1 */
gf_mul(a, p->x, p->z);
gf_sub(d, c, a); /* aXZ-dYT with a=-1 */
gf_add(a, p->z, p->y);
gf_sub(b, p->z, p->y);
gf_mul(c, b, a);
gf_mulw(b, c, -EDWARDS_D); /* (a-d)(Z+Y)(Z-Y) */
mask_t ok = gf_isr (a,b); /* r in the paper */
(void)ok; assert(ok | gf_eq(b,ZERO));
gf_mulw (b, a, -EDWARDS_D); /* u in the paper */

gf_mul(c,a,d); /* r(aZX-dYT) */
gf_mul(a,b,p->z); /* uZ */
gf_add(a,a,a); /* 2uZ */
mask_t tg = toggle_hibit_t_over_s ^ ~gf_hibit(minus_t_over_s);
gf_cond_neg(minus_t_over_s, tg); /* t/s <-? -t/s */
gf_cond_neg(c, tg); /* u <- -u if negative. */
gf_add(d,c,p->y);
gf_mul(s,b,d);
gf_cond_neg(s, toggle_hibit_s ^ gf_hibit(s));
#else
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1;
gf_add(t1,p->x,p->t);
gf_sub(t2,p->x,p->t);
gf_mul(t3,t1,t2); /* t3 = num */
gf_sqr(t2,p->x);
gf_mul(t1,t2,t3);
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */
gf_isr(t1,t2); /* t1 = isr */
gf_mul(t2,t1,t3); /* t2 = ratio */
gf_mul(t4,t2,RISTRETTO_FACTOR);
mask_t negx = gf_lobit(t4) ^ toggle_altx;
gf_cond_neg(t2, negx);
gf_mul(t3,t2,p->z);
gf_sub(t3,t3,p->t);
gf_mul(t2,t3,p->x);
gf_mulw(t4,t2,-1-TWISTED_D);
gf_mul(s,t4,t1);
mask_t lobs = gf_lobit(s);
gf_cond_neg(s,lobs);
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
#elif COFACTOR == 8 && IMAGINE_TWIST
/* More complicated because of rotation */
/* MAGIC This code is wrong for certain non-Curve25519 curves;
* check if it's because of Cofactor==8 or IMAGINE_TWIST */
gf c, d;
gf_s *b = s, *a = minus_t_over_s;

#if IMAGINE_TWIST
gf x, t;
gf_div_qnr(x,p->x);
gf_div_qnr(t,p->t);
gf_add ( a, p->z, x );
gf_sub ( b, p->z, x );
gf_mul ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 - X^2 */
#else
const gf_s *x = p->x, *t = p->t;
gf_sqr ( a, p->z );
gf_sqr ( b, p->x );
gf_add ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 + X^2 */
#endif
/* Here: c = "zx" in the SAGE code = Z^2 - aX^2 */
gf_mul ( a, p->z, t ); /* "tz" = T*Z */
gf_sqr ( b, a );
gf_mul ( d, b, c ); /* (TZ)^2 * (Z^2-aX^2) */
mask_t ok = gf_isr(b, d);
(void)ok; assert(ok | gf_eq(d,ZERO));
gf_mul ( d, b, a ); /* "osx" = 1 / sqrt(z^2-ax^2) */
gf_mul ( a, b, c );
gf_mul ( b, a, d ); /* 1/tz */

mask_t rotate;
#if (COFACTOR == 8)
gf e;
gf_sqr(e, p->z);
gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */
rotate = gf_hibit(a) ^ toggle_rotation;
/* Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x */
gf_mul ( a, b, c );
gf_cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate );
gf_cond_sel ( e, p->y, x, rotate );
#else
const gf_s *e = x;
(void)toggle_rotation;
rotate = 0;
#endif
gf_mul ( c, a, d ); // new "osx"
gf_mul ( a, c, p->z );
gf_add ( minus_t_over_s, a, a ); // 2 * "osx" * Z
gf_mul ( d, b, p->z );
mask_t tg = toggle_hibit_t_over_s ^~ gf_hibit(minus_t_over_s);
gf_cond_neg ( minus_t_over_s, tg );
gf_cond_neg ( c, rotate ^ tg );
gf_add ( d, d, c );
gf_mul ( s, d, e ); /* here "x" = y unless rotate */
gf_cond_neg ( s, toggle_hibit_s ^ gf_hibit(s) );
gf t1,t2,t3,t4,t5;
gf_add(t1,p->z,p->y);
gf_sub(t2,p->z,p->y);
gf_mul(t3,t1,t2); /* t3 = num */
gf_mul(t2,p->x,p->y); /* t2 = den */
gf_sqr(t1,t2);
gf_mul(t4,t1,t3);
gf_mulw(t1,t4,-1-TWISTED_D);
gf_isr(t4,t1); /* isqrt(num*(a-d)*den^2) */
gf_mul(t1,t2,t4);
gf_mul(t2,t1,RISTRETTO_FACTOR); /* t2 = "iden" in ristretto.sage */
gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */

/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_i(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */
mask_t rotate = toggle_rotation ^ gf_lobit(t3);
/* Rotate if altxy is negative */
gf_cond_swap(t1,t2,rotate);
gf_mul_i(t4,p->x);
gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */
gf_mul_i(t5,RISTRETTO_FACTOR); /* t5 = imi */
gf_mul(t3,t5,t2); /* iden * imi */
gf_mul(t2,t5,t1);
gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */
mask_t negx = gf_lobit(t5) ^ toggle_altx;
gf_cond_neg(t1,negx^rotate);
gf_mul(t2,t1,p->z);
gf_add(t2,t2,ONE);
gf_mul(inv_el_sum,t2,t4);
gf_mul(s,inv_el_sum,t3);
mask_t negs = gf_lobit(s);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
gf_cond_neg(inv_el_m1,negz);
gf_sub(inv_el_m1,inv_el_m1,t4);
#else
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
}

void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
gf s, mtos;
API_NS(deisogenize)(s,mtos,p,0,0,0);
gf_serialize(ser,s,0);
gf s,ie1,ie2;
API_NS(deisogenize)(s,ie1,ie2,p,0,0,0);
gf_serialize(ser,s,1);
}

decaf_error_t API_NS(point_decode) (
@@ -238,89 +235,54 @@ decaf_error_t API_NS(point_decode) (
const unsigned char ser[SER_BYTES],
decaf_bool_t allow_identity
) {
gf s, a, b, c, d, e, f;
mask_t succ = gf_deserialize(s, ser, 0);
mask_t zero = gf_eq(s, ZERO);
succ &= bool_to_mask(allow_identity) | ~zero;
gf_sqr ( a, s ); /* s^2 */
gf s, s2, num, tmp;
gf_s *tmp2=s2, *ynum=p->z, *isr=p->x, *den=p->t;
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
gf_sqr(s2,s); /* s^2 = -as^2 */
#if IMAGINE_TWIST
gf_sub ( f, ONE, a ); /* f = 1-as^2 = 1-s^2*/
#else
gf_add ( f, ONE, a ); /* f = 1-as^2 = 1+s^2 */
gf_sub(s2,ZERO,s2); /* -as^2 */
#endif
succ &= ~ gf_eq( f, ZERO );
gf_sqr ( b, f ); /* (1-as^2)^2 = 1 - 2as^2 + a^2 s^4 */
gf_mulw ( c, a, 4*IMAGINE_TWIST-4*EDWARDS_D );
gf_add ( c, c, b ); /* t^2 = 1 + (2a-4d) s^2 + s^4 */
gf_mul ( d, f, s ); /* s * (1-as^2) for denoms */
gf_sqr ( e, d ); /* s^2 * (1-as^2)^2 */
gf_mul ( b, c, e ); /* t^2 * s^2 * (1-as^2)^2 */
succ &= gf_isr(e,b) | gf_eq(b,ZERO); /* e = 1/(t s (1-as^2)) */
gf_mul ( b, e, d ); /* 1 / t */
gf_mul ( d, e, c ); /* t / (s(1-as^2)) */
gf_mul ( e, d, f ); /* t / s */
mask_t negtos = gf_hibit(e);
gf_cond_neg(b, negtos);
gf_cond_neg(d, negtos);

#if IMAGINE_TWIST
gf_add ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
#else
gf_sub ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
gf_sub(den,ONE,s2); /* 1+as^2 */
gf_add(ynum,ONE,s2); /* 1-as^2 */
gf_mulw(num,s2,-4*TWISTED_D);
gf_sqr(tmp,den); /* tmp = den^2 */
gf_add(num,tmp,num); /* num = den^2 - 4*d*s^2 */
gf_mul(tmp2,num,tmp); /* tmp2 = num*den^2 */
succ &= gf_isr(isr,tmp2); /* isr = 1/sqrt(num*den^2) */
gf_mul(tmp,isr,den); /* isr*den */
gf_mul(p->y,tmp,ynum); /* isr*den*(1-as^2) */
gf_mul(tmp2,tmp,s); /* s*isr*den */
gf_add(tmp2,tmp2,tmp2); /* 2*s*isr*den */
gf_mul(tmp,tmp2,isr); /* 2*s*isr^2*den */
gf_mul(p->x,tmp,num); /* 2*s*isr^2*den*num */
gf_mul(tmp,tmp2,RISTRETTO_FACTOR); /* 2*s*isr*den*magic */
gf_cond_neg(p->x,gf_lobit(tmp)); /* flip x */
#if COFACTOR==8
/* Additionally check y != 0 and x*y*isomagic nonegative */
succ &= ~gf_eq(p->y,ZERO);
gf_mul(tmp,p->x,p->y);
gf_mul(tmp2,tmp,RISTRETTO_FACTOR);
succ &= ~gf_lobit(tmp2);
#endif

#if COFACTOR == 8
gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */
succ &= ~gf_lobit(a); /* = ~gf_hibit(a/2), since gf_hibit(x) = gf_lobit(2x) */
#endif
gf_mul ( a, f, b ); /* y = (1-s^2) / t */
gf_mul ( p->y, p->z, a ); /* Y = yZ */
#if IMAGINE_TWIST
gf_add ( b, s, s );
gf_mul(p->x, b, SQRT_MINUS_ONE); /* Curve25519 */
#else
gf_add ( p->x, s, s );
#endif
gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */
#if UNSAFE_CURVE_HAS_POINTS_AT_INFINITY
/* This can't happen for any of the supported configurations.
*
* If it can happen (because s=1), it's because the curve has points
* at infinity, which means that there may be critical security bugs
* elsewhere in the library. In that case, it's better that you hit
* the assertion in point_valid, which will happen in the test suite
* since it tests s=1.
*
* This debugging option is to allow testing of IMAGINE_TWIST = 0 on
* Ed25519, without hitting that assertion. Don't use it in
* production.
*/
succ &= ~gf_eq(p->z,ZERO);
gf_copy(tmp,p->x);
gf_mul_i(p->x,tmp);
#endif

/* Fill in z and t */
gf_copy(p->z,ONE);
gf_mul(p->t,p->x,p->y);
p->y->limb[0] -= zero;
assert(API_NS(point_valid)(p) | ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

void API_NS(point_sub) (
point_t p,
const point_t q,
@@ -865,7 +827,7 @@ void API_NS(point_debugging_pscale) (
) {
gf gfac,tmp;
/* NB this means you'll never pscale by negative numbers for p521 */
ignore_result(gf_deserialize(gfac,factor,0));
ignore_result(gf_deserialize(gfac,factor,0,0));
gf_cond_sel(gfac,gfac,ONE,gf_eq(gfac,ZERO));
gf_mul(tmp,p->x,gfac);
gf_copy(q->x,tmp);
@@ -1078,7 +1040,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES],
const point_t p
) {
@@ -1116,15 +1078,20 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_mul ( y, u, t ); // (x^2+y^2)(2z^2-y^2+x^2)
gf_mul ( u, z, t );
gf_copy( z, u );
gf_mul ( u, x, SQRT_ONE_MINUS_D );
gf_mul ( u, x, RISTRETTO_FACTOR );
#if IMAGINE_TWIST
gf_mul_i( x, u );
#else
#error "... probably wrong"
gf_copy( x, u );
#endif
decaf_bzero(u,sizeof(u));
}
#elif IMAGINE_TWIST
{
API_NS(point_double)(q,q);
API_NS(point_double)(q,q);
gf_mul_qnr(x, q->x);
gf_mul_i(x, q->x);
gf_copy(y, q->y);
gf_copy(z, q->z);
}
@@ -1137,7 +1104,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_add( u, x, t );
gf_add( z, q->y, q->x );
gf_sqr ( y, z);
gf_sub ( y, u, y );
gf_sub ( y, y, u );
gf_sub ( z, t, x );
gf_sqr ( x, q->z );
gf_add ( t, x, x);
@@ -1166,7 +1133,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES]
) {
@@ -1176,7 +1143,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
mask_t low = ~word_is_zero(enc2[DECAF_EDDSA_25519_PRIVATE_BYTES-1] & 0x80);
enc2[DECAF_EDDSA_25519_PRIVATE_BYTES-1] &= ~0x80;
mask_t succ = gf_deserialize(p->y, enc2, 1);
mask_t succ = gf_deserialize(p->y, enc2, 1, 0);
#if 7 == 0
succ &= word_is_zero(enc2[DECAF_EDDSA_25519_PRIVATE_BYTES-1]);
#endif
@@ -1196,7 +1163,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
succ &= gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */
gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */
gf_cond_neg(p->x,~gf_lobit(p->x)^low);
gf_cond_neg(p->x,gf_lobit(p->x)^low);
gf_copy(p->z,ONE);
#if EDDSA_USE_SIGMA_ISOGENY
@@ -1221,8 +1188,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
gf_sub ( p->t, a, c ); // y^2 - x^2
gf_sqr ( p->x, p->z );
gf_add ( p->z, p->x, p->x );
gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_mul ( c, a, SQRT_ONE_MINUS_D );
gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_div_i ( a, c );
gf_mul ( c, a, RISTRETTO_FACTOR );
gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2)
gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2)
gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2)
@@ -1265,6 +1233,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_bzero(enc2,sizeof(enc2));
assert(API_NS(point_valid)(p) || ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

@@ -1274,7 +1243,7 @@ decaf_error_t decaf_x25519 (
const uint8_t scalar[X_PRIVATE_BYTES]
) {
gf x1, x2, z2, x3, z3, t1, t2;
ignore_result(gf_deserialize(x1,base,1));
ignore_result(gf_deserialize(x1,base,1,0));
gf_copy(x2,ONE);
gf_copy(z2,ZERO);
gf_copy(x3,x1);
@@ -1345,15 +1314,8 @@ void decaf_ed25519_convert_public_key_to_x25519 (
const uint8_t ed[DECAF_EDDSA_25519_PUBLIC_BYTES]
) {
gf y;
{
uint8_t enc2[DECAF_EDDSA_25519_PUBLIC_BYTES];
memcpy(enc2,ed,sizeof(enc2));

/* retrieve y from the ed compressed point */
enc2[DECAF_EDDSA_25519_PUBLIC_BYTES-1] &= ~0x80;
ignore_result(gf_deserialize(y, enc2, 0));
decaf_bzero(enc2,sizeof(enc2));
}
const uint8_t mask = (uint8_t)(0xFE<<(6));
ignore_result(gf_deserialize(y, ed, 1, mask));
{
gf n,d;
@@ -1390,6 +1352,26 @@ void decaf_x25519_generate_key (
decaf_x25519_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_ratio_and_encode_like_x25519) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(q->y,ZERO,q->y);
#endif
gf_serialize(out,q->y,1);
API_NS(point_destroy(q));
}

void decaf_x25519_derive_public_key (
uint8_t out[X_PUBLIC_BYTES],
const uint8_t scalar[X_PRIVATE_BYTES]
@@ -1405,39 +1387,13 @@ void decaf_x25519_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
API_NS(scalar_halve)(the_scalar,the_scalar);
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X25519_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
/* Isogenize to Montgomery curve.
*
* Why isn't this just a separate function, eg decaf_encode_like_x25519?
* Basically because in general it does the wrong thing if there is a cofactor
* component in the input. In this function though, there isn't a cofactor
* component in the input.
*/
gf_invert(p->t,p->x,0); /* 1/x */
gf_mul(p->z,p->t,p->y); /* y/x */
gf_sqr(p->y,p->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(p->y,ZERO,p->y);
#endif
gf_serialize(out,p->y,1);
decaf_bzero(scalar2,sizeof(scalar2));
API_NS(scalar_destroy)(the_scalar);
API_NS(point_mul_by_ratio_and_encode_like_x25519)(out,p);
API_NS(point_destroy)(p);
}



+ 13
- 4
src/GENERATED/c/curve25519/decaf_gen_tables.c View File

@@ -21,7 +21,7 @@

#define API_NS(_id) decaf_255_##_id
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = {
0x03
0xe2, 0xf2, 0xae, 0x0a, 0x6a, 0xbc, 0x4e, 0x71, 0xa8, 0x84, 0xa9, 0x61, 0xc5, 0x00, 0x51, 0x5f, 0x58, 0xe3, 0x0b, 0x6a, 0xa5, 0x82, 0xdd, 0x8d, 0xb6, 0xa6, 0x59, 0x45, 0xe0, 0x8d, 0x2d, 0x76
};

/* To satisfy linker. */
@@ -63,16 +63,25 @@ int main(int argc, char **argv) {
API_NS(point_t) real_point_base;
int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0);
if (ret != DECAF_SUCCESS) return 1;
if (ret != DECAF_SUCCESS) {
fprintf(stderr, "Can't decode base point!\n");
return 1;
}
API_NS(precomputed_s) *pre;
ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s));
if (ret || !pre) return 1;
if (ret || !pre) {
fprintf(stderr, "Can't allocate space for precomputed table\n");
return 1;
}
API_NS(precompute)(pre, real_point_base);
struct niels_s *pre_wnaf;
ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs));
if (ret || !pre_wnaf) return 1;
if (ret || !pre_wnaf) {
fprintf(stderr, "Can't allocate space for precomputed WNAF table\n");
return 1;
}
API_NS(precompute_wnafs)(pre_wnaf, real_point_base);

const gf_s *output;


+ 148
- 148
src/GENERATED/c/curve25519/decaf_tables.c View File

@@ -5,61 +5,61 @@

#define API_NS(_id) decaf_255_##_id
const API_NS(point_t) API_NS(point_base) = {{
{FIELD_LITERAL(0x0004a2ebbc57c446,0x000501e3eb5a93b2,0x00079c37ac6e4a40,0x00052181e701cbb9,0x0000512db01de8b3)},
{FIELD_LITERAL(0x0005ef58002a189b,0x0000f03409118cd4,0x00033a3f7e448905,0x0006a725fcccd553,0x0000863a7a72a10d)},
{FIELD_LITERAL(0x000000000000000a,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000)},
{FIELD_LITERAL(0x00064dd34108cd8b,0x00074d6a76c1aa17,0x0007ee5469f0a08a,0x0007eb4b28e92c93,0x00076326b6a09052)}
{FIELD_LITERAL(0x0000485cca7e8859,0x00041dc396dfb8fc,0x0005584743ad3a93,0x0006ae1e23d9233c,0x00056f798c3a929c)},
{FIELD_LITERAL(0x0004ccccccccccc2,0x0001999999999999,0x0003333333333333,0x0006666666666666,0x0004cccccccccccc)},
{FIELD_LITERAL(0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000)},
{FIELD_LITERAL(0x0004f837acb251cf,0x0000dea88db96efd,0x00019b5df567eff2,0x00059babaf1be1f1,0x000342e2875657f7)}
}};
const gf API_NS(precomputed_base_as_fe)[144]
VECTOR_ALIGNED __attribute__((visibility("hidden"))) = {
{FIELD_LITERAL(0x00074308734f7d55,0x000380ac08a23a96,0x00024b4b5cef028b,0x000632cbb8646ab5,0x00075516b5681530)},
{FIELD_LITERAL(0x0005729461e535df,0x0004a8e85565dffb,0x000246a85e49fde1,0x000285c20023113d,0x00028a44366a7a53)},
{FIELD_LITERAL(0x0007900f448afdf1,0x0003b19d978aa5b4,0x00001f24c6a6a64c,0x0002087f8eafcb75,0x0002908747e585e7)},
{FIELD_LITERAL(0x00076d889cad4165,0x00071362fbf32e38,0x000690aefb540c46,0x000621cc7bb1b618,0x000221025cc4baa9)},
{FIELD_LITERAL(0x0007bebe4b16496c,0x0002e7f9398fd049,0x0000e75000bce490,0x000524d09bad6a16,0x0006e0956a9e4b96)},
{FIELD_LITERAL(0x00011021995f4d69,0x000408ad873a4a85,0x0001eabfb56a654e,0x0000c9929a913e80,0x000089c71d2ad5fb)},
{FIELD_LITERAL(0x0001074205aa7651,0x00070175da77bb6c,0x0003aabc342a7247,0x00053b258c3bfab2,0x00026b1876e97291)},
{FIELD_LITERAL(0x00011e80f790420b,0x00005b106301a4b8,0x0003655366fb76bd,0x0000db29fd744fb9,0x000421bcf8c7f1c9)},
{FIELD_LITERAL(0x00046711fde8d258,0x000470e3497ac3e2,0x000194ae035752d1,0x0004ae895c0abf15,0x0005ddd80811ad26)},
{FIELD_LITERAL(0x0005b4e34964bdc6,0x0001e81fa96ce1f5,0x0007e2df72008566,0x000168443f698ebe,0x000152ac0b755c25)},
{FIELD_LITERAL(0x000290744e6e5635,0x0006c5bc38e03bc3,0x0006c96e2fbd1fda,0x00013f648afeb2d4,0x0007c62b7a2c6a06)},
{FIELD_LITERAL(0x000318c70c2f945b,0x0004239d8e807a94,0x0004188e8a39e6a0,0x00059e2ee0252e08,0x00040068a0c16600)},
{FIELD_LITERAL(0x0006e6b7abb10734,0x0006c794fd3e62f5,0x00020e578b02d4d6,0x00071c80374f0b04,0x00012c3bfb2d0371)},
{FIELD_LITERAL(0x00055466e28f151e,0x0006b7f47234ae9b,0x00000e13de9f7ae1,0x000397ae5535fd30,0x0003770095a7d1b6)},
{FIELD_LITERAL(0x0000bf2a1151e097,0x00034b6f37a26f1c,0x0006c920dc5af278,0x00036a5fdeecf456,0x0000274e3992daca)},
{FIELD_LITERAL(0x00059e4ca2f8886f,0x0006b4750e946c95,0x00059eec7f9ece40,0x00005a4cea7306d6,0x0002942643555c80)},
{FIELD_LITERAL(0x000032272e61054e,0x0002fd234cb15146,0x00023e3ee1ef8f01,0x0004cbc46f7dc7bd,0x00012823d598d1eb)},
{FIELD_LITERAL(0x00038ad274b8a817,0x0004fc82ef8b5d5c,0x00041bd3024f4574,0x00055d7231efff55,0x0000c5645a2c0dfe)},
{FIELD_LITERAL(0x00046d0660706b4f,0x00026639b32bc46a,0x00047778c8f868cf,0x00026f6f03de7b3f,0x000152449d80f37a)},
{FIELD_LITERAL(0x000775f7d7c489e4,0x000753ccdcef1f73,0x0000794b3d428f1b,0x00069f835109615b,0x0007c293b3c9fd03)},
{FIELD_LITERAL(0x00023ede6e1d8634,0x0000a56181b173a2,0x0004562f62daae1f,0x00052816d45aa833,0x0007ff582bb6653c)},
{FIELD_LITERAL(0x0002454ac31a713a,0x00046a1aff243be4,0x00061d4625463d74,0x0007381029e9febe,0x0000d36e87e5c9f8)},
{FIELD_LITERAL(0x0000366482a905cf,0x0006027364c80753,0x00047dbd74ea5f7d,0x0007370de9872204,0x0001d4b014ca1204)},
{FIELD_LITERAL(0x00053ea1c4c97833,0x0002df62d318036e,0x000288c25f0a8ee5,0x0007b269312b6991,0x000605703efca474)},
{FIELD_LITERAL(0x0005411db67012d5,0x0003839ba04d414e,0x000427bac114c00c,0x0006101f4dbbd8ba,0x0005d0d37579b501)},
{FIELD_LITERAL(0x0003f868cecaff25,0x00050633eeea03f4,0x0005b378fd40553d,0x00022b1fd96bba9c,0x00038e387b07f4b2)},
{FIELD_LITERAL(0x00068bb1688f018a,0x00059ca4f89e5af1,0x0006cdd39e07c0ff,0x0001c41c8682a8f3,0x0002501bad194816)},
{FIELD_LITERAL(0x00057a048831afd7,0x0001db1d8848cb7c,0x0001c19664abd34d,0x000263448bc1ac3d,0x0000a1eb87cc5550)},
{FIELD_LITERAL(0x00071d63dc03d8dd,0x00054edf28315a40,0x0005fe7a8b0c9d28,0x0006e8ba1d5c3992,0x000178b0808a422d)},
{FIELD_LITERAL(0x00042084b3f0d594,0x0004fd2f47147e58,0x00063d8e820cc500,0x00010c06f4c00216,0x0004bd7eea1193b9)},
{FIELD_LITERAL(0x0007b23a241e726b,0x000282c8eb1f96ae,0x000248d8ea07c098,0x0003da55bdb3a408,0x0005ecfe96ec945e)},
{FIELD_LITERAL(0x000149c42977f67f,0x00047674073754cb,0x000775f8ea834290,0x000433d0d9140645,0x0003e8d14fa401e1)},
{FIELD_LITERAL(0x000698be8aeb7d5b,0x000492c2fc1e06a3,0x0003613444b366db,0x0001fc87dfbe6c92,0x0002de2e337b3729)},
{FIELD_LITERAL(0x00056790106623d8,0x00055d885f4a0c01,0x00033933a8257fe2,0x0002f1c5bf947de4,0x0000ae7e40035af0)},
{FIELD_LITERAL(0x000508a1f1d4682b,0x0003b54ef307cd48,0x0000a5d58aa5768e,0x0004517d377be18f,0x000593760533c5ff)},
{FIELD_LITERAL(0x000763e76811d43a,0x0005d342e8bf6b90,0x0002e1707e229c60,0x0003bbdc425fceed,0x0005a2ab1a4a0de9)},
{FIELD_LITERAL(0x0006b384c7e1e2b9,0x000164f357c822fd,0x0000c4c2d68283dc,0x0007b356c6bbf73b,0x0004a57a4935fc97)},
{FIELD_LITERAL(0x0000e3b94bdc9773,0x0003c3d5d69b31dc,0x00069a7f6da96736,0x0002be940a2193d7,0x00032f05636602b8)},
{FIELD_LITERAL(0x00070b26342e2300,0x0007357ea5a05bad,0x0003f322f4d1d92d,0x000254cdfca21e23,0x0003c784682a918b)},
{FIELD_LITERAL(0x00036fe4c08fe3a9,0x0005d27b152b9afe,0x0006e4037781ebf5,0x000588f5fe18f990,0x0006c18726bb2385)},
{FIELD_LITERAL(0x0005d22a0a21bdd4,0x00069bb3d6587726,0x0001187048cafffe,0x00038b6bb210a404,0x0001f9644d68f257)},
{FIELD_LITERAL(0x0000ca52c758f28b,0x00003d3ffb8ca649,0x0002c133f22ac9b8,0x000705af85c4ecdf,0x00049d2f4f3a6e62)},
{FIELD_LITERAL(0x0007da0f4e1565e0,0x0006fa7a1e4779d2,0x00003c3ea7568e41,0x00011f89f112d22c,0x00036de81e03d02d)},
{FIELD_LITERAL(0x0004d13807f938ee,0x000701c7c55031ce,0x0001d7e07fd92939,0x0000a1f04baafe91,0x0006505e3a8412b4)},
{FIELD_LITERAL(0x0005383940f7159b,0x000331630c6fa442,0x0001100ad7ae8320,0x0002e381cf7e6260,0x000072201917150f)},
{FIELD_LITERAL(0x000683d5cfeca129,0x0004dbe0eef910b4,0x0005abce5d5576c5,0x000396e6a3a58311,0x000752c6080343f2)},
{FIELD_LITERAL(0x0002e1404ee6d107,0x0004064a3bd93e57,0x00078a011f16378f,0x00032f7253e4b397,0x0006a54ad677432e)},
{FIELD_LITERAL(0x000734b7d62b820c,0x0004ad861c234f0b,0x00078691d4e8036c,0x000708b8ec865a61,0x000334c73b5b80d2)},
{FIELD_LITERAL(0x000787c06838438e,0x000079b93ae8d43f,0x0006ce4230c8d2e4,0x0001e958b5ba51e1,0x000581f2251d4761)},
{FIELD_LITERAL(0x00028065bd02efcb,0x00072c06ae982429,0x0001a39392af7f7c,0x000398aaf36dab32,0x0004c8a8c4525fae)},
{FIELD_LITERAL(0x00006ff0bb7501fc,0x00044e6268755a4b,0x0007e0db395959b3,0x0005f7807150348a,0x00056f78b81a7a18)},
{FIELD_LITERAL(0x00013c159d969f7f,0x00038046e416d34a,0x00030a05d3333cd8,0x0003fc17afcf330a,0x0001456fcd6c2c06)},
{FIELD_LITERAL(0x0001b3b052f3a00d,0x00050d154cc33fb6,0x000570a09253802b,0x0006af26330b8f09,0x000503fdb7977d73)},
{FIELD_LITERAL(0x0006efde66a0b284,0x0003f75278c5b57a,0x000615404a959ab1,0x0007366d656ec17f,0x00077638e2d52a04)},
{FIELD_LITERAL(0x00002d288a8a8e1c,0x000029f655eeea29,0x00069ca769b47ee2,0x0002d41c299b6574,0x0002fcdb7d8bda37)},
{FIELD_LITERAL(0x0005883fa323a11e,0x000241047ad9c769,0x000233d3283fbb6d,0x000041bda7280e1d,0x00018a85382540f5)},
{FIELD_LITERAL(0x000398ee02172d95,0x00038f1cb6853c1d,0x00066b51fca8ad2e,0x00035176a3f540ea,0x00022227f7ee52d9)},
{FIELD_LITERAL(0x000790607ffeebfe,0x000725f8959cf0e0,0x00016b68dcd68a0f,0x00046f439e78680b,0x00026be3a14518fd)},
{FIELD_LITERAL(0x0002216f73946c7d,0x0000f4eb865cbfbf,0x0003c96750df440c,0x000655188ab63a68,0x0002a93e3b59098a)},
{FIELD_LITERAL(0x0004e738f3d06b92,0x0003dc62717f856b,0x0003e77175c6195f,0x000261d11fdad1f7,0x0003ff975f3e99ff)},
{FIELD_LITERAL(0x00031becbaeb1b98,0x0007912ee9ea6632,0x0004e42e201b640f,0x0007e5a0ef458ef1,0x000383f3cebfcbef)},
{FIELD_LITERAL(0x00004a9f30d26d26,0x0001838b85de7867,0x0006904531c39e2b,0x0000b5c478c98d49,0x0007d059931f87d8)},
{FIELD_LITERAL(0x000740d5eeae1f56,0x0004b490c85d90e3,0x000136df23a50d87,0x000495a021130ba9,0x0007d8b1c66d2535)},
{FIELD_LITERAL(0x000711d059bc6cef,0x0000ea1c699aeba1,0x0006371a8052c525,0x000699f87dd13a72,0x00021319ac452786)},
{FIELD_LITERAL(0x0004179c92b1b0bb,0x00046e9ddba894d8,0x0001e24442ec9a91,0x0004c132a51620b3,0x0006d110187f3653)},
{FIELD_LITERAL(0x0004752d8b4757d6,0x0003037d1074a2a3,0x0003e42cfdb0ba8b,0x0002a28dce1000aa,0x00073a9ba5d3f201)},
{FIELD_LITERAL(0x000605edf6ba1a36,0x000013aba4619a54,0x0007ad04bb3634df,0x0007d3751dadf975,0x0007857a65f3ad25)},
{FIELD_LITERAL(0x0003117ab7b95c2b,0x0000f4a313b2a63d,0x0006eb78029227ec,0x00043b924f138238,0x00073aad45f02122)},
{FIELD_LITERAL(0x0005c12191e279b9,0x00075a9e7e4e8c5d,0x0003a9d09d2551e0,0x0002d7e92ba557cc,0x000000a7d4499ac3)},
{FIELD_LITERAL(0x0005b75a63605042,0x0001fb3e9b1e1738,0x00054c87b6f7d7b6,0x0003b73e6812d3e8,0x000633794ff51d12)},
{FIELD_LITERAL(0x00058b7c046273ac,0x0000464dc4a43f06,0x0004eb0e5479c3c5,0x00036c45d45ee21a,0x00047b89a5b4d946)},
{FIELD_LITERAL(0x0002c15e3b3687ba,0x0005209d2ce7fc91,0x0005773da0f5711a,0x00004d96ced4966e,0x0001fa8fc1035b8b)},
{FIELD_LITERAL(0x00075c8cfdf08431,0x0003e5ee1a32e561,0x00017f242d52abcb,0x00070b795ca26857,0x0002cb36d5df0af3)},
{FIELD_LITERAL(0x0006a3037380c025,0x0005f0b9e09cee4c,0x000333017642af74,0x00023fd62c2cfe7a,0x00070eee8fed21d2)},
{FIELD_LITERAL(0x0001744e9770fe63,0x0002635b0761a50e,0x0001322c61f83f00,0x00063be3797d570c,0x0005afe452e6b7e9)},
{FIELD_LITERAL(0x00005fff6e9b6af7,0x0003e58a55a575a1,0x000616d026c6eff2,0x000186a3124f745b,0x0002eec52ffe33c4)},
{FIELD_LITERAL(0x0001ee0dff83b7ca,0x00022805e31c6873,0x0006fd7df7edeaef,0x0002f0f61779d562,0x0004deb8f2bacd10)},
{FIELD_LITERAL(0x0003df7b4c0f2a59,0x000302d0b8eb81a7,0x0001c2717df33aff,0x0006f3f90b3ffde9,0x0003428115ee6c46)},
{FIELD_LITERAL(0x0001ab77a68de949,0x0005da9c4d9a1ae9,0x0003ce86c23f9b7c,0x00007c893f16e3d9,0x000190c2b28c32a8)},
{FIELD_LITERAL(0x0000bae92c40e17e,0x0004a8ef7ffd05e8,0x0005e3a63cc24e24,0x0001ed40c1f74c12,0x000258c0a1c13ff6)},
{FIELD_LITERAL(0x0001674175148292,0x00036d3d03e1f95c,0x00049ecbbb4c9924,0x000603782041936d,0x000521d1cc84c8d6)},
{FIELD_LITERAL(0x0004c7d5df621bb3,0x00063a78ba5518cb,0x00050af726ccf0a4,0x0003745ad4fb4c6d,0x0004b598e9a94c84)},
{FIELD_LITERAL(0x000546d94d9e537c,0x0001f783b157c7bb,0x00034c7f212657b4,0x0006ea763a87171a,0x00074beeb5597da9)},
{FIELD_LITERAL(0x00009c1897ee2bb3,0x00022cbd1740946f,0x00051e8f81dd639f,0x00044423bda03112,0x00025d54e5b5f216)},
{FIELD_LITERAL(0x00037efe726b959f,0x000251179afe0af9,0x00027abb104aaf2d,0x0000409b36a0b0c0,0x0007f20165baf2eb)},
{FIELD_LITERAL(0x0001e7dc70d2e455,0x00079f1c0b114486,0x0002b9b9c0211476,0x000420d65df5b9c1,0x0007ad32d88f4e65)},
{FIELD_LITERAL(0x0000f4d9cbd1dced,0x0000ca815a5fa452,0x00040cdd0b2e26d2,0x0005ab32035de1dc,0x0004387b97d56e74)},
{FIELD_LITERAL(0x0004282b73d9d3e6,0x0006f6ae3911c629,0x0007e698e17d290f,0x000064657542456d,0x00022eaf07413105)},
{FIELD_LITERAL(0x0004d9e24bbb1c38,0x00001d0b9cb4f6e6,0x00008953dd712c89,0x00062f9f338dc8e9,0x0005b270d74b9a0b)},
{FIELD_LITERAL(0x000735ad38a70d62,0x0007c2c0047359b6,0x00053ecc0dd53647,0x0000fa507a3b1320,0x000362d0b0c5919d)},
{FIELD_LITERAL(0x0001e756ac51c2d7,0x0002fb982df272d3,0x0002bcba823c3ff6,0x00000e8c28e674f5,0x0001511ccec93f3e)},
{FIELD_LITERAL(0x0005d9d5f3a4d0f4,0x00014e0b6acbbb8a,0x0004c935dce28917,0x0004e84532fe74e9,0x0003532b26c5bdd3)},
{FIELD_LITERAL(0x0002c7c6bf08ea52,0x0004ce9cf3905bbd,0x0006eff528517cdf,0x00051c7e30819d9f,0x00078ddfe6e8eaf0)},
{FIELD_LITERAL(0x00040b28295a488c,0x00058f3942269291,0x0002eae04529af91,0x0005a950aa509a31,0x00051d13d423f3cc)},
{FIELD_LITERAL(0x00075bbfd400a649,0x0002c84af6f7554f,0x00010589298f1c45,0x0002df1c4551d7a3,0x00040ada606a7008)},
{FIELD_LITERAL(0x0000cb4829d47de1,0x00035279e3dcb0f4,0x0000796e2b17fc93,0x0000f7471379a59e,0x0004cb38c4a47f2d)},
{FIELD_LITERAL(0x00063d326152d536,0x0001f0f272df8e88,0x00020d57f1ef5f0b,0x000049ae733cd741,0x000789b0bd910484)},
{FIELD_LITERAL(0x00049e000de68a33,0x0002569532faf05e,0x0002c360e2577651,0x00023e58038a73d4,0x0005cfd1c66aa5db)},
{FIELD_LITERAL(0x0005219445517667,0x00052a931068f3ea,0x0006cc6f70494867,0x00050f70ab70bd44,0x0004939aea5e18ae)},
@@ -159,100 +159,100 @@ VECTOR_ALIGNED __attribute__((visibility("hidden"))) = {
};
const gf API_NS(precomputed_wnaf_as_fe)[96]
VECTOR_ALIGNED __attribute__((visibility("hidden"))) = {
{FIELD_LITERAL(0x000743d2369750f6,0x000698b734af8c74,0x0003c7e6ca7de989,0x0004137b677d5a14,0x000602a70a1dd604)},
{FIELD_LITERAL(0x000620e9c96ce4a2,0x000718e799056806,0x0003bdec5bbc2429,0x0003ca0864fd880d,0x00013df868873a16)},
{FIELD_LITERAL(0x0005ac6e48dfc457,0x0004b83cf2fa3b88,0x000036ccd665d9e2,0x0003eb7fcdb11759,0x0001b35e6ddb1020)},
{FIELD_LITERAL(0x0007ccb3f6a10981,0x0000da543ce37bbf,0x00050b9209636544,0x0000d2b0429e9ce7,0x00074186575eae41)},
{FIELD_LITERAL(0x0002504ab1b01a82,0x000740ed4b7cc499,0x0003069cb6ca6ba3,0x0003c80e50487d68,0x0003342b644eef24)},
{FIELD_LITERAL(0x00049584d605e6e0,0x00016cad8c3a0b14,0x0002bf8a350d0042,0x0006bd8f108a926f,0x0002cc1d5eef3036)},
{FIELD_LITERAL(0x000224075358ec99,0x000230ff1b8a53aa,0x000252117056a351,0x00060743c508fae8,0x0001c04f5d1353b7)},
{FIELD_LITERAL(0x00062b5e839935b4,0x0005b02eb7b4e0d0,0x0002afa8629ae76f,0x0003bce28577fcae,0x0006041f9433c6e5)},
{FIELD_LITERAL(0x0003aa8f4a1d8f00,0x0002a8c9cce67276,0x000035ddc332a503,0x00007963621fb93b,0x00016176cef7ee40)},
{FIELD_LITERAL(0x0007844f7ba1cba7,0x0004289c1bd2a22a,0x0001b82a79e54f30,0x0003f2eafdf66144,0x0007da88f52cff12)},
{FIELD_LITERAL(0x0001435ccbef7ad2,0x0002ea3968864b1a,0x00028ffbb295dfb3,0x00005cc6454e1a56,0x000118fec97e8196)},
{FIELD_LITERAL(0x000039800ab41821,0x0000256683f84cd6,0x0004a13569b54086,0x0000f91fd3009a54,0x000032dcb2da50c3)},
{FIELD_LITERAL(0x0007839c8a17923b,0x000289a30b913a2d,0x00053c030ee71ea6,0x00002e6800c51b3e,0x0002b490d56ed17c)},
{FIELD_LITERAL(0x0005994df663e026,0x000768669098c9f0,0x000162cd08abef32,0x0004e454dc2612eb,0x0000e67536846b6c)},
{FIELD_LITERAL(0x00038e9c32917745,0x00043ced54b6ba1e,0x0004fde18248c8a5,0x0002a04384c093f9,0x00058d130d26a4b1)},
{FIELD_LITERAL(0x0006b2bedf0160b4,0x0004c358673bc4df,0x00004b7cb73858dc,0x0003ce1efb2bb821,0x0004678c0b830186)},
{FIELD_LITERAL(0x0007ca530af5c4f0,0x00016b5286e93694,0x000659359b212d67,0x00049b8a75475c8d,0x00060315a6cbe365)},
{FIELD_LITERAL(0x0006e25ec0d1f161,0x00055570af71e028,0x0003ed583cc18071,0x0004af3d5eed4270,0x00046fc5b551e1ce)},
{FIELD_LITERAL(0x000109b61d35f784,0x00006f9c76807b2a,0x00016785e92d7d92,0x0001259af252e1fc,0x0001b26b4c137c2f)},
{FIELD_LITERAL(0x00044ca6598cc832,0x000665b54839a384,0x0001e6ac6ab983a7,0x0001fdd6b13cdb62,0x0007deb170a5cdd6)},
{FIELD_LITERAL(0x0007e80f449d9a39,0x0003484eb5cd07d7,0x00047caa9ec3f9f4,0x000500ef87bc5ada,0x000187a67cc2f430)},
{FIELD_LITERAL(0x0007c02cdacf8a52,0x00079d67ea5c92b3,0x0002f0a7f9d32d93,0x0006fab780441ed9,0x0003168c11a2dd70)},
{FIELD_LITERAL(0x0007b23805768cf7,0x0001b85ac1197abe,0x0000a84d11198b19,0x0001554cd3699a16,0x0000b2d83584a435)},
{FIELD_LITERAL(0x0000420968ce6088,0x0000cc5150df8ac3,0x000417109dda028d,0x00035a467ace9b33,0x00001f365e1c5d3f)},
{FIELD_LITERAL(0x0006a07632f786c1,0x00072b0af45dcdb7,0x00071e70402c687b,0x0005718eb4d6b056,0x00010d977fb49765)},
{FIELD_LITERAL(0x0005a3beb1d34a87,0x000179261d82fa41,0x00027ef49938fbd9,0x000393146b5d52b8,0x0003d532d9c7fd8b)},
{FIELD_LITERAL(0x00028db255727690,0x000723b04a325e5e,0x0002351555604a71,0x000533831cacd285,0x000073463e9558c6)},
{FIELD_LITERAL(0x00076ceb26b3c5d4,0x000118ee75e27eca,0x0006c8f5746eb4d9,0x000108f3ab526482,0x0007814bee3f31ea)},
{FIELD_LITERAL(0x0005469b27b0273f,0x000722c4740b42ed,0x00003774b73b1ec2,0x0006975e5845ba85,0x000279f0b9aef6d8)},
{FIELD_LITERAL(0x000086e7726efe30,0x00046f84a1d534a8,0x00070dfe952cd70e,0x0005a9c277bc3691,0x0004dab8837a8f79)},
{FIELD_LITERAL(0x00015857a17c5473,0x0006c6f1f9ecee05,0x000142ff5cfa92e9,0x0002fadbc290acba,0x0002afe96b249c8e)},
{FIELD_LITERAL(0x000534f64fe6546e,0x0007b9d6e279298a,0x00039d003aef00b2,0x00059f49b9a4852d,0x00014231773d812c)},
{FIELD_LITERAL(0x0002240be6516279,0x0003718ee020a890,0x0000af97358cd479,0x00011746695ab6ef,0x00008dd9f53c8e71)},
{FIELD_LITERAL(0x00056e798b523179,0x00061c15a11e6553,0x000127cdf4dba7fe,0x0004ec0a026fe93f,0x0006f81c908a88b8)},
{FIELD_LITERAL(0x000687514dfa3a3b,0x0003dede73973032,0x0006848771c31d8b,0x00035001bf224172,0x00045c2c0115e2a5)},
{FIELD_LITERAL(0x000273710ccec161,0x000301989216eaf3,0x00078ecdd4517c80,0x00038e65639bcbe8,0x00074c272578c47e)},
{FIELD_LITERAL(0x000697f25f2c6de4,0x0001c40484164b5a,0x0006e268824a8cdb,0x000189aeb1055818,0x00010d43bf6ed421)},
{FIELD_LITERAL(0x0001b2b89e1685bd,0x00037dc20eb9d1fc,0x0004dfeab3a62c72,0x000103f9cffa384a,0x00067a6fbbd0d79f)},
{FIELD_LITERAL(0x000277a74a9d1b19,0x0000558a9562cc3f,0x00072aea9d8917b7,0x0002cb9e55344e41,0x0007fc2fc3988035)},
{FIELD_LITERAL(0x000749bf55899998,0x00071fc079537515,0x000175bc8875f5ae,0x00028cd79c84d4ff,0x00060cff8d61fcb9)},
{FIELD_LITERAL(0x000619495eef1208,0x0003ae99098e8a9e,0x0003736d7378cdcd,0x0004c9c881e59d8d,0x00060f51372948ca)},
{FIELD_LITERAL(0x000653ad6e70b35f,0x0000f2e72673c00b,0x00041a8cd4eaac24,0x0000d20b9168b162,0x0006dd0479c03028)},
{FIELD_LITERAL(0x000224c166967a71,0x0003b68b7f69a426,0x0004e031ef85509f,0x0006eddf508d3143,0x00034644b2fded93)},
{FIELD_LITERAL(0x0007f8fa58983740,0x000591f53ca681ae,0x00018b202d61b69a,0x0004fc0280de98fe,0x0006785de5920076)},
{FIELD_LITERAL(0x00041699232389e1,0x0003822a5c348c53,0x0001e29ca07ec9da,0x000128910390a845,0x0002b213535bf600)},
{FIELD_LITERAL(0x000417bc4d41cf19,0x00031c294352e330,0x00020a94ff61c9d5,0x00031858c5974e19,0x00058517be5b44d0)},
{FIELD_LITERAL(0x00017d3e06b8a658,0x000143bb6ba1cf12,0x000719f71ff82335,0x0005940429c47d68,0x0003b60dd1548856)},
{FIELD_LITERAL(0x00004c2bddb8b3dc,0x0004a028442be56e,0x00047cec2a9828b9,0x0003b41d389be98c,0x0004304d1864f24b)},
{FIELD_LITERAL(0x000649f3323200e1,0x0007efe729c48cce,0x000786d72426898b,0x0001da85f6f36d7f,0x0007afaf872e143b)},
{FIELD_LITERAL(0x0000c5b03a9ad985,0x00001cb1fa90f4d4,0x0000dd387fb86459,0x00027a356d168448,0x00042ada3a8601d0)},
{FIELD_LITERAL(0x00032c3175e087f6,0x0004e9886f0f8a4e,0x00031943180b56fb,0x00032d332e84f78b,0x000022fe4c9f0a99)},
{FIELD_LITERAL(0x00004e12e08f3cf1,0x00059187b665bc45,0x0007256e995bdef2,0x0000262f4793b87f,0x000367324411af89)},
{FIELD_LITERAL(0x00010f9e0f6efa7b,0x00036f8f54758003,0x00013f525e654d31,0x0002192ebcf9f453,0x0002e0f80630b257)},
{FIELD_LITERAL(0x0001e68e538e7134,0x00053124b27c4383,0x0003afa7e55b7619,0x00077a5411f3b516,0x00048a1cfbcea526)},
{FIELD_LITERAL(0x0002d8e9a252d6bb,0x00027ad3c557244c,0x0005c8fd932f4ed4,0x0006fad7ca74e589,0x000423ad018bc13d)},
{FIELD_LITERAL(0x0000a1da6d58cf72,0x00025c445f860800,0x000698590629c3ab,0x0003c3a59208ffe8,0x000169000ba9197f)},
{FIELD_LITERAL(0x0005e5bcd4e61d7d,0x0001bb779e9dc08f,0x0003c7c5aff92ebf,0x0003d921c5764bbc,0x0006d695748c1b54)},
{FIELD_LITERAL(0x00020303a62cd160,0x000347eb92fc693a,0x0004850e9f667fcf,0x000208e2e66428a6,0x0006e21933165db3)},
{FIELD_LITERAL(0x000492a0691faaf3,0x000381f60373488c,0x0003d6f183197f09,0x00040163d988c397,0x0004e0d5bbeaa234)},
{FIELD_LITERAL(0x00015c50e219a243,0x000279df295b9db5,0x0001d3a06b1ce50c,0x0001a0d41ae8bef3,0x0001e12777751552)},
{FIELD_LITERAL(0x00073984cea05b9b,0x0000deff48eae16e,0x00040dd1d363093a,0x000125195e7f0589,0x00037a4d480f49a3)},
{FIELD_LITERAL(0x0004106c5e793fd3,0x000514a760ed60b3,0x00007a66701ef207,0x0002bea3ba33657f,0x0007af61727fd2d9)},
{FIELD_LITERAL(0x00043e7c7334b0e7,0x0003cc0e9c6c62d0,0x00043ba8761df2f1,0x000333e22830d325,0x00035c2e2471d04f)},
{FIELD_LITERAL(0x00013082646c1f9c,0x000362ef8568ffd2,0x00067b2ba55e12c3,0x0000a9825fde937b,0x0000c769bb66060c)},
{FIELD_LITERAL(0x0002367467a85096,0x0001133815110a70,0x0000ab74011fdc31,0x000100a78312f6df,0x00029c7cc3eb674b)},
{FIELD_LITERAL(0x00047e13df7b9ff7,0x0006fd78b662bee6,0x0000e0a5e1ed9a65,0x0000ee6133b13803,0x0001a49790841cb9)},
{FIELD_LITERAL(0x0003d887edc2ac17,0x00034ca9e5fb9a49,0x0006fa601857d317,0x00028c1c25f0a90f,0x000177f44e824cf9)},
{FIELD_LITERAL(0x0007c3e3a1f49841,0x0006ddd51697801e,0x0001b24bfd50f063,0x00013782899c047b,0x00056c54300ac2cf)},
{FIELD_LITERAL(0x0000756a8926c43e,0x00054d58198a5543,0x00008330139de7a0,0x0004f31feb6a6b14,0x00006525c89b0161)},
{FIELD_LITERAL(0x000650e695c5da40,0x0001033c791eabeb,0x00056f2360fb33b3,0x00047bdaa765f629,0x0006945f8a73a000)},
{FIELD_LITERAL(0x0002f9a99b7729ec,0x0003decb7e034d67,0x0005097cfcdc63d5,0x0001b9a8f6131bde,0x00056f1fdc6c596a)},
{FIELD_LITERAL(0x00070cee95c4544c,0x0007781e63838577,0x0001b1520dd885b0,0x0000265e72115db1,0x0005fb0324a91d4a)},
{FIELD_LITERAL(0x000650f5f8fbdd64,0x00031c2678c34c82,0x000065353f0cf936,0x0002491692e94e39,0x0006c3b66eb95cad)},
{FIELD_LITERAL(0x0007bb94b92d721a,0x000448c1a7a663f9,0x0005ec6c88be1b48,0x000683856f731a08,0x000411cf4c796636)},
{FIELD_LITERAL(0x000291a06b298f50,0x000745565bb5621a,0x000506925fdd5f18,0x0002dd0e5cefdf2b,0x00053a9ec799d04e)},
{FIELD_LITERAL(0x0005797b7369b0b2,0x000155565f699e37,0x0002b176d189610f,0x00058199f8d7fc6a,0x0007566e666e3a30)},
{FIELD_LITERAL(0x00073dda6e080b0a,0x00001193e044b254,0x00077e225d7670be,0x0000639a471cc676,0x0001261c25a7bd1c)},
{FIELD_LITERAL(0x0007024967ec86ea,0x000204ae4dc589af,0x000293680fe404f4,0x0005375c121f1939,0x000720010ab2b942)},
{FIELD_LITERAL(0x00007e6d310ec5dc,0x000047ac0cce852a,0x00043e23334c026a,0x0006ed366b38ee5a,0x0000d1458ba5a6df)},
{FIELD_LITERAL(0x00021b90f03cbf2d,0x0007977528da577d,0x000427536441d483,0x00029da71b8e79d3,0x00036ec244e19089)},
{FIELD_LITERAL(0x00019dbd0a87d8a2,0x000275ffe2770607,0x0004951784ea41c8,0x00069242bc5080c1,0x000631809b789f7a)},
{FIELD_LITERAL(0x000073405335f633,0x0006bc653424f657,0x0000f51782d233b8,0x00006bc1af07bb36,0x0002565b5c69b722)},
{FIELD_LITERAL(0x00017c7391d3e6b9,0x0005eddc736945f7,0x000368b0f32ec6dc,0x0005b00a58d2f62d,0x000262d4dc5fde05)},
{FIELD_LITERAL(0x0003effc881c81dc,0x000753b7016dba17,0x0007673af68eee2a,0x00073ce00df1f3ee,0x00032e60f04936ec)},
{FIELD_LITERAL(0x00016eb1e06b15da,0x00043a71fa2e28a9,0x00015971af1affe4,0x0003efc95563ffda,0x00000c34ebdda4e3)},
{FIELD_LITERAL(0x00019e3b9f82ba88,0x0002fa37a814d2a8,0x0006196e62b9f46b,0x0003e7590757040d,0x00001e1f5a5bed8e)},
{FIELD_LITERAL(0x00031322bd434d6b,0x000491460ddbbf29,0x0006a8c7420141a7,0x00002592832e7a12,0x0006eb32d11aebda)},
{FIELD_LITERAL(0x0000be17064868aa,0x0000e11f8e414f0c,0x0001d178e11b5113,0x0000d9c0407c52d7,0x00027cbd7ccc2804)},
{FIELD_LITERAL(0x0004f0667ec85b85,0x0002cd4060677445,0x0004234b38aba23a,0x00065332ae9516f1,0x00056dc729ea4b26)},
{FIELD_LITERAL(0x000119ab40400ee4,0x0001fe7cae43441d,0x0002869b20e7e0dd,0x0004c1f98c26304e,0x0001b1020675efbf)},
{FIELD_LITERAL(0x000369f957477df9,0x0004806fc3a6b4c4,0x0000682fc6009497,0x0000190600762d8c,0x0000105698d28452)},
{FIELD_LITERAL(0x0000db58e90b0258,0x0002faa725dd0cb8,0x0006bcd0fb7d7773,0x000025525eeafd1d,0x00032541b927bcd7)},
{FIELD_LITERAL(0x0004f1e166f0bd7e,0x00075f57198553f9,0x00022a3bd982e093,0x0002e4f143a9eb47,0x000735c8594a0a9c)},
{FIELD_LITERAL(0x00070ac72f9780aa,0x0003e873b4d59105,0x0007f6c02aa0281c,0x00024fa03888dad7,0x00009c751940b87e)},
{FIELD_LITERAL(0x000297476c6d9690,0x000689d5de7319f7,0x0002ba11aa2814f7,0x00003265301b3019,0x0003a1cc84857e0c)},
{FIELD_LITERAL(0x0003b824eb77c5ed,0x000533420322f935,0x0002d51e82c71d7b,0x000528ab31dfcc63,0x00069ca6b033d9fc)}
{FIELD_LITERAL(0x000642380127222b,0x0006bdeb015cf04e,0x0006ed75f7c2fc4f,0x0007dc242146a194,0x0003aea9a0491d17)},
{FIELD_LITERAL(0x00068a94cba5aa97,0x0002dbae983ca94a,0x000445bd3b7036e3,0x00068a42451fc4d1,0x00011e232c83afb4)},
{FIELD_LITERAL(0x00025391b7203b96,0x000347c30d05c477,0x0007c933299a261d,0x00041480324ee8a6,0x00064ca19224efdf)},
{FIELD_LITERAL(0x0005870a7d58f0a0,0x0001b114a243c47e,0x00041892d3f588cf,0x0000dd81de11287e,0x00017356a5582dd5)},
{FIELD_LITERAL(0x00010182955b295c,0x00066c5c9ffd69b2,0x00061b151a710972,0x000283e92443fc68,0x0006d37a5c5e317b)},
{FIELD_LITERAL(0x00036a7b29fa190d,0x0006935273c5f4eb,0x00054075caf2ffbd,0x00014270ef756d90,0x000533e2a110cfc9)},
{FIELD_LITERAL(0x0001629db13df925,0x0005b8e4096d6111,0x0003f69f6e1fa07d,0x0000ad2fb64a4e21,0x0003804eca6f1a1b)},
{FIELD_LITERAL(0x00004152d30c2a52,0x0002c24984123284,0x00042e97ac31b344,0x00019fefd67353e1,0x0004e8cd7188a7e4)},
{FIELD_LITERAL(0x00045570b5e270ed,0x0005573633198d89,0x0007ca223ccd5afc,0x0007869c9de046c4,0x00069e89310811bf)},
{FIELD_LITERAL(0x0006d9d11e7eae02,0x0000be17c117a8e5,0x0005bd1bacc035a8,0x00055263e886a24c,0x0004f490d4442b45)},
{FIELD_LITERAL(0x000011c8b01f8feb,0x0007bf1c4cb192c2,0x000326354b21cbf2,0x000488390b6dfc94,0x0005ba34838ba4de)},
{FIELD_LITERAL(0x0007c67ff54be7cc,0x0007da997c07b329,0x00035eca964abf79,0x000706e02cff65ab,0x0007cd234d25af3c)},
{FIELD_LITERAL(0x0001fb4c93b5f593,0x0007144dc0cada1e,0x0000d50f94b1cb97,0x0006df9cbaf29c61,0x0003edfa4c8c2b32)},
{FIELD_LITERAL(0x0007271443c9ba84,0x00016f294c6baac0,0x00044dfa59cab659,0x0002fe9702828a2a,0x0007db9144c036dd)},
{FIELD_LITERAL(0x00047163cd6e88a8,0x0003c312ab4945e1,0x0003021e7db7375a,0x00055fbc7b3f6c06,0x000272ecf2d95b4e)},
{FIELD_LITERAL(0x00038b922c70ed29,0x000253866fc7c488,0x000576f12a312db9,0x00045d4f321497af,0x00018e5445d11403)},
{FIELD_LITERAL(0x0003f8e7ccec15a0,0x00052340d38e8703,0x0001fe25f1ae8f20,0x0003ddd469f772d0,0x000462fbbea67ca2)},
{FIELD_LITERAL(0x00011da13f2e0e8c,0x0002aa8f508e1fd7,0x000412a7c33e7f8e,0x000350c2a112bd8f,0x0003903a4aae1e31)},
{FIELD_LITERAL(0x0007f9daed4a4867,0x0002b6b4ed700133,0x0002630bb5d53e2d,0x00052b6f0617a8d5,0x0003a71ea3b7dd75)},
{FIELD_LITERAL(0x000784badf35d97a,0x000130c033b608d3,0x0004d1ca333b988c,0x00046996c1106167,0x00006cd17cb32faf)},
{FIELD_LITERAL(0x000017f0bb6265b4,0x0004b7b14a32f828,0x00038355613c060b,0x0002ff107843a525,0x00067859833d0bcf)},
{FIELD_LITERAL(0x0007efb1526681aa,0x0005d3f09cc25381,0x0005070ed313624a,0x0007dc7c70fcf2e6,0x00035f22ab001ece)},
{FIELD_LITERAL(0x0001d03d7131822b,0x00041269a071318a,0x00066b533c7c2f0e,0x00079eb2962ac445,0x0007c84f8b7d6434)},
{FIELD_LITERAL(0x0007bdf697319f65,0x000733aeaf20753c,0x0003e8ef6225fd72,0x0004a5b9853164cc,0x0007e0c9a1e3a2c0)},
{FIELD_LITERAL(0x0000ea923f718b41,0x0003ed3cdc5c1206,0x0007fcd7e9778042,0x000087a1037b0d5d,0x00007a7a0abbab1c)},
{FIELD_LITERAL(0x0001f75504e732eb,0x00022ebe847278d8,0x0007ea9ffc7568b3,0x0005ce813453dcf8,0x000487735ef97869)},
{FIELD_LITERAL(0x0005724daa8d895d,0x0000dc4fb5cda1a1,0x0005caeaaa9fb58e,0x0002cc7ce3532d7a,0x00078cb9c16aa739)},
{FIELD_LITERAL(0x000132663b80f4fb,0x0003569bb0747910,0x0001254f43541bae,0x0005ef6302e41398,0x0000f0739e94acdc)},
{FIELD_LITERAL(0x00062c278d9a1d30,0x000160f59d5d7ddb,0x0003a13c02fd4a4c,0x0003ae8e19ec0313,0x0007ff33d0402d0a)},
{FIELD_LITERAL(0x000779188d9101bd,0x0003907b5e2acb57,0x0000f2016ad328f1,0x0002563d8843c96e,0x000325477c857086)},
{FIELD_LITERAL(0x0002b91f27fd54d4,0x0006396d4db9c2ed,0x0001910e4a18d580,0x00013a22c5bab363,0x0007a440ee553a25)},
{FIELD_LITERAL(0x000490c21e746b15,0x00024b7059991174,0x00008ee694b74d75,0x0005e237b7856642,0x0007642c6cdb680c)},
{FIELD_LITERAL(0x0005dbf419ae9d74,0x00048e711fdf576f,0x00075068ca732b86,0x0006e8b996a54910,0x000772260ac3718e)},
{FIELD_LITERAL(0x000482565fa8a25b,0x0003df033dcf6602,0x00064e0f3b4e7074,0x00021b4575c116f5,0x0002208124f689de)},
{FIELD_LITERAL(0x0007585a86ebfdf4,0x0007b22f0200bb5d,0x0004c01c0570390b,0x00012d4f936a9ace,0x0007061937f48098)},
{FIELD_LITERAL(0x00058c8ef3313e8c,0x0004fe676de9150c,0x000071322bae837f,0x0004719a9c643417,0x0000b3d8da873b81)},
{FIELD_LITERAL(0x0004a783941354c6,0x0004a8dbae0192b1,0x00066e6e2284eb96,0x000328e80b25e8c3,0x000042a8e76bf4d5)},
{FIELD_LITERAL(0x0001d8c052051ec3,0x000366a48a8dd65b,0x0002a78e24295abf,0x000129d49470f3e6,0x0006c57172fbfc6f)},
{FIELD_LITERAL(0x00058858b562e4d4,0x0007aa756a9d33c0,0x0000d5156276e848,0x00053461aacbb1be,0x000003d03c677fca)},
{FIELD_LITERAL(0x0004ec9d19b70d7e,0x0006b590207bdecd,0x0001637d3bcc3bb3,0x00000c22df7f92fb,0x00041ea544c47cfa)},
{FIELD_LITERAL(0x0005bb2c05450730,0x000699da0443d31e,0x00029833797938dd,0x00047094e611ef5a,0x0003a80296f5af96)},
{FIELD_LITERAL(0x0001ac52918f4c8e,0x00070d18d98c3ff4,0x0003e5732b1553db,0x00072df46e974e9d,0x000122fb863fcfd7)},
{FIELD_LITERAL(0x00000849cf428975,0x000727067cad891a,0x0004f88f61de7005,0x00044257203c4bbb,0x0004c637329a0014)},
{FIELD_LITERAL(0x000765ea2cf96125,0x00020be964ac2553,0x0006542c16078fcd,0x0007e1c9a694af26,0x000670be61b828ab)},
{FIELD_LITERAL(0x0003e966dcdc760c,0x00047dd5a3cb73ac,0x00061d635f813625,0x0006d76efc6f57ba,0x00054decaca409ff)},
{FIELD_LITERAL(0x00006abffd1f9a07,0x0006a24984b59c94,0x00001c88b2d5ccab,0x00078756f923d472,0x000523ae194c2908)},
{FIELD_LITERAL(0x000295f6aed6c95f,0x00063835a88edc2f,0x0000d413a8f5d2be,0x0006d19ac30fb51e,0x000209a4daa47af4)},
{FIELD_LITERAL(0x0007b3d422474c11,0x00035fd7bbd41a91,0x00038313d567d746,0x00044be2c7641673,0x0003cfb2e79b0db4)},
{FIELD_LITERAL(0x0007deb72bd44d2d,0x000739424ef1d75e,0x0004018d17e7a6b2,0x0007b6e2a9d39e87,0x000521ea05c6c6dd)},
{FIELD_LITERAL(0x0001a5e807310023,0x00064308e578ea3e,0x00051e6fd6a01240,0x000274e880dadbdd,0x0001f551c726c373)},
{FIELD_LITERAL(0x0004d3ce8a1f77f7,0x0003167790f075b1,0x0004e6bce7f4a904,0x0004d2ccd17b0874,0x0007dd01b360f566)},
{FIELD_LITERAL(0x00073aa273d83a1f,0x000509605eef38e1,0x0002478a49a7bd9c,0x00037b4fffcc9a8f,0x0003de7bfae4d9c0)},
{FIELD_LITERAL(0x00010ab29d20014a,0x0003dad754471f37,0x0005db76f33e4e9e,0x000233bcc4657dd9,0x00064a6db2e9a1a4)},
{FIELD_LITERAL(0x00061971ac718eb9,0x0002cedb4d83bc7c,0x000450581aa489e6,0x000085abee0c4ae9,0x000375e304315ad9)},
{FIELD_LITERAL(0x0004e69a3015eec3,0x00014f8520f65886,0x000603fe316ae01d,0x000266136364ded2,0x0001ca16145255d7)},
{FIELD_LITERAL(0x000195b299aaa7a2,0x00029dcb30ab6966,0x0007db5d6559e7e8,0x0003080db154f47f,0x00039c84ee5affcf)},
{FIELD_LITERAL(0x00021a432b19e270,0x0006448861623f70,0x0004383a5006d140,0x000426de3a89b443,0x0001296a8b73e4ab)},
{FIELD_LITERAL(0x00026b6e1920377f,0x0001fe04f05868d1,0x00035b308dd430aa,0x0004a38a5bd39fc2,0x0007a2a54f12cec0)},
{FIELD_LITERAL(0x00019031dbbe6961,0x000228c57c496dbd,0x00016d3b12e551b5,0x0006f71b0487b7f1,0x0000576d528efd97)},
{FIELD_LITERAL(0x0006a3af1de65daa,0x00058620d6a4624a,0x00062c5f94e31af3,0x00065f2be517410c,0x00061ed8888aeaad)},
{FIELD_LITERAL(0x000460e8ec01abc0,0x00029d22bb6910a9,0x0000bb5a4290fa5c,0x000761396d21fe81,0x00017529bc98149c)},
{FIELD_LITERAL(0x0001a2d5558fa158,0x00018db5df86dcda,0x000628100de92051,0x0002e1d2985a8b52,0x0000a021ed4469e4)},
{FIELD_LITERAL(0x0003c1838ccb4f06,0x000433f163939d2f,0x0003c45789e20d0e,0x0004cc1dd7cf2cda,0x0004a3d1db8e2fb0)},
{FIELD_LITERAL(0x00078bc9fe3174f7,0x0005463ef645ece5,0x0005977ab88ef0f8,0x000143fe3a6097c1,0x00014e54b582e50b)},
{FIELD_LITERAL(0x000297c2159dd2ea,0x0002225918017b5d,0x0000fd2c877e4d6d,0x0000a876d935de03,0x0003aa2b685088ec)},
{FIELD_LITERAL(0x000381ec20845ff6,0x00010287499d4119,0x00071f5a1e12659a,0x0007119ecc4ec7fc,0x00065b686f7be346)},
{FIELD_LITERAL(0x00079aa225363911,0x0004401073991c38,0x0002d622e1b2ab01,0x0006d88484b2ff0e,0x0001af6bad1d0067)},
{FIELD_LITERAL(0x0004a9bd5d80f94a,0x000200829b9a0578,0x00005d3adbbe3535,0x0004a01abc9f4d78,0x000318228e347c33)},
{FIELD_LITERAL(0x00078a9576d93baf,0x0002b2a7e675aabc,0x00077ccfec62185f,0x00030ce0149594eb,0x00079ada3764fe9e)},
{FIELD_LITERAL(0x00019f03aa64e86b,0x000524ed3ec7b93e,0x00051dea71a325e6,0x0006072282cc2dd1,0x0003f6161300548d)},
{FIELD_LITERAL(0x0003d4e4793a59c5,0x00039088df420d66,0x000059f2dc08ae93,0x0002a529016f70f4,0x00003d508c2008c6)},
{FIELD_LITERAL(0x0000f3116a3baba1,0x000087e19c7c7a88,0x00064eadf2277a4f,0x0007d9a18deea24e,0x000204fcdb56e2b5)},
{FIELD_LITERAL(0x000740a868c461a6,0x00008d33fd39e939,0x000546fc277d8361,0x00049a29cc27b47d,0x00066efe0241ab2d)},
{FIELD_LITERAL(0x0004c02370cdf9e0,0x0002753707967fe5,0x0003e9e845537aa4,0x00052e8412924bcd,0x00035a32466d04a6)},
{FIELD_LITERAL(0x00056e5f94d6709d,0x0000baa9a44a9de5,0x0002f96da022a0e7,0x000522f1a31020d4,0x0002c56138662fb1)},
{FIELD_LITERAL(0x0003a975fed6c7ef,0x0005be0807c70f4d,0x00056cb1100a4f60,0x000039e4317fae1e,0x0002d3e8e7c807c5)},
{FIELD_LITERAL(0x000049cd79d8153d,0x0005f7f1bfb82d68,0x0006329634d9cab0,0x0007bcb505082b4e,0x00053f1ca734f15f)},
{FIELD_LITERAL(0x0000fdb698137903,0x0005fb51b23a7650,0x00056c97f01bfb0b,0x0002c8a3ede0e6c6,0x0000dffef54d46bd)},
{FIELD_LITERAL(0x000023fde8f23ca3,0x0003e79e97bcb77c,0x0006682d0da044a2,0x0002b5cc9caad587,0x0007053a7396d844)},
{FIELD_LITERAL(0x0007325e1ff6a8d7,0x000144c86fd24546,0x000196593acaf904,0x000241f57ca53397,0x00023e58d23dff45)},
{FIELD_LITERAL(0x00066242f578274b,0x00058a001d88f9f8,0x00036ae87b15be37,0x00016dbd43af7f3e,0x0001ce7f64876085)},
{FIELD_LITERAL(0x00015f6b0f790623,0x0007d5b90970fb7b,0x00045b6bd21c9701,0x0003fbe8a13740fc,0x00059a684a214173)},
{FIELD_LITERAL(0x00014da626cba741,0x000101c3468580bb,0x0004c6fb5709eea8,0x000354aaf860f432,0x0003d9501bbcc86d)},
{FIELD_LITERAL(0x0004100377e37e11,0x0000ac48fe9245e8,0x000098c5097111d5,0x0000c31ff20e0c11,0x0004d19f0fb6c913)},
{FIELD_LITERAL(0x0007c87f12093bcc,0x000223769c082868,0x00074d424db97824,0x0006d7020a556573,0x0001e0afdef95d3d)},
{FIELD_LITERAL(0x000201774f4281a6,0x00040d577fbe10c0,0x0001d96faea48a3a,0x00019d06096a4cb9,0x0000c0410e02b892)},
{FIELD_LITERAL(0x0004ecdd42bcb282,0x00036eb9f22440d6,0x00015738bdfebe58,0x0007da6d7cd185ed,0x000114cd2ee51425)},
{FIELD_LITERAL(0x00061fb7d973a125,0x00060a3d5f860ddc,0x00058032f5a2bae4,0x0001ae3459e6da16,0x0004d8e17bd386cb)},
{FIELD_LITERAL(0x0003d4f4a0189763,0x0002ebc953fe02a4,0x00004d165b695009,0x00050cba13806a99,0x0000f5b62c0c84e5)},
{FIELD_LITERAL(0x0006e654bfbff109,0x0006018351bcbbe2,0x00057964df181f22,0x00033e0673d9cfb1,0x00064efdf98a1040)},
{FIELD_LITERAL(0x00073ad6128efea0,0x0007c86bdff5a7c5,0x0001a71115a02aff,0x00049b3a3e67b1f4,0x00033315bb103c63)},
{FIELD_LITERAL(0x0006aac38a327053,0x0005351c17ce82af,0x0000f07d6bbd51f7,0x00039497c5b160b1,0x0001ca565d3b0b4c)},
{FIELD_LITERAL(0x00030e1e990f426f,0x0000a0a8e67aac06,0x0005d5c4267d1f6c,0x00051b0ebc5614b8,0x0000ca37a6b5f563)},
{FIELD_LITERAL(0x00009dcbfce95c17,0x0001ea312e0ecf1f,0x0001bfaafa617fde,0x00017565626471ce,0x00057a7e865a0896)},
{FIELD_LITERAL(0x00036e4ca4b09fec,0x00070559d5d9b147,0x00035855772927b5,0x000651fbdadbcd73,0x0007aea9eb02eba1)},
{FIELD_LITERAL(0x000447db14883a00,0x0002ccbdfcdd06ca,0x00052ae17d38e284,0x0002d754ce20339c,0x000163594fcc2603)}
};

+ 14
- 12
src/GENERATED/c/curve25519/eddsa.c View File

@@ -31,6 +31,7 @@
#define NO_CONTEXT DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY 1
#define COFACTOR 8
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t NO_CONTEXT_POINTS_HERE = 0;
@@ -41,7 +42,7 @@ const uint8_t * const DECAF_ED25519_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES]
@@ -128,14 +129,14 @@ void decaf_ed25519_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<DECAF_255_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -191,13 +192,13 @@ void decaf_ed25519_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < DECAF_255_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -237,7 +238,7 @@ void decaf_ed25519_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed25519_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
@@ -259,10 +260,10 @@ decaf_error_t decaf_ed25519_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -287,9 +288,10 @@ decaf_error_t decaf_ed25519_verify (
&signature[DECAF_EDDSA_25519_PUBLIC_BYTES],
DECAF_EDDSA_25519_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<DECAF_255_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */
@@ -312,7 +314,7 @@ decaf_error_t decaf_ed25519_verify_prehash (
) {
decaf_error_t ret;
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed25519_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));


+ 62
- 61
src/GENERATED/c/curve25519/elligator.c View File

@@ -21,14 +21,18 @@
#define IMAGINE_TWIST 1
#define COFACTOR 8
static const int EDWARDS_D = -121665;
/* End of template stuff */

extern void API_NS(deisogenize) (
#define RISTRETTO_FACTOR DECAF_255_RISTRETTO_FACTOR
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */
extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

@@ -37,7 +41,8 @@ void API_NS(point_from_hash_nonuniform) (
const unsigned char ser[SER_BYTES]
) {
gf r0,r,a,b,c,N,e;
ignore_result(gf_deserialize(r0,ser,0));
const uint8_t mask = (uint8_t)(0xFE<<(6));
ignore_result(gf_deserialize(r0,ser,0,mask));
gf_strong_reduce(r0);
gf_sqr(a,r0);
gf_mul_qnr(r,a);
@@ -61,7 +66,7 @@ void API_NS(point_from_hash_nonuniform) (
/* s@a = +-|N.e| */
gf_mul(a,N,e);
gf_cond_neg(a,gf_hibit(a)^square); /* NB this is - what is listed in the paper */
gf_cond_neg(a,gf_lobit(a) ^ ~square);
/* t@b = -+ cN(r-1)((a-2d)e)^2 - 1 */
gf_mulw(c,e,1-2*EDWARDS_D); /* (a-2d)e */
@@ -107,23 +112,6 @@ void API_NS(point_from_hash_uniform) (
* log p == 1 mod 8 brainpool curves maybe?
*/
#define MAX(A,B) (((A)>(B)) ? (A) : (B))
#define PKP_MASK ((1<<(MAX(8*SER_BYTES + 0 - 255,0)))-1)
#if PKP_MASK != 0
static DECAF_INLINE mask_t plus_k_p (
uint8_t x[SER_BYTES],
uint32_t factor_
) {
uint32_t carry = 0;
uint64_t factor = factor_;
const uint8_t p[SER_BYTES] = { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f };
for (unsigned int i=0; i<SER_BYTES; i++) {
uint64_t tmp = carry + p[i] * factor + x[i];
/* tmp <= 2^32-1 + (2^32-1)*(2^8-1) + (2^8-1) = 2^40-1 */
x[i] = tmp; carry = tmp>>8;
}
return word_is_zero(carry);
}
#endif

decaf_error_t
API_NS(invert_elligator_nonuniform) (
@@ -133,60 +121,73 @@ API_NS(invert_elligator_nonuniform) (
) {
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_t_over_s = -(hint>>1 & 1),
sgn_altx = -(hint>>1 & 1),
sgn_r0 = -(hint>>2 & 1),
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0,
* change this mask extraction.
*/
sgn_ed_T = -(hint>>3 & 1);
gf a, b, c, d;
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T);
gf a,b,c;
API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T);
#if 255 == 8*SER_BYTES + 1 /* p521. */
sgn_r0 = 0;
mask_t is_identity = gf_eq(p->t,ZERO);
#if COFACTOR==4
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#elif IMAGINE_TWIST
/* Terrible, terrible special casing due to lots of 0/0 is deisogenize
* Basically we need to generate -D and +- i*RISTRETTO_FACTOR
*/
gf_mul_i(a,RISTRETTO_FACTOR);
gf_cond_sel(b,b,ONE,is_identity);
gf_cond_neg(a,sgn_altx);
gf_cond_sel(c,c,a,is_identity & sgn_ed_T);
gf_cond_sel(c,c,ZERO,is_identity & ~sgn_ed_T);
gf_mulw(a,ONE,-EDWARDS_D);
gf_cond_sel(c,c,a,is_identity & ~sgn_ed_T &~ sgn_altx);
#else
#error "Different special-casing goes here!"
#endif
/* ok, a = s; c = -t/s */
#if IMAGINE_TWIST
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
#endif
gf_add(b,a,b);
gf_sub(a,a,c);
gf_add(b,b,c);
gf_cond_swap(a,b,sgn_s);
gf_mul_qnr(c,b);
gf_mul(b,c,a);
mask_t succ = gf_isr(c,b);
succ |= gf_eq(b,ZERO);
gf_mul(b,c,a);
gf_sub(b,ONE,b); /* t+1 */
gf_sqr(c,a); /* s^2 */
mask_t is_identity = gf_eq(p->t,ZERO);

/* identity adjustments */
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */
/* if hint is 0, -> 0 */
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s);
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s);
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */
gf_add(a,b,d); /* num? */
gf_sub(d,d,b); /* den? */
gf_mul(b,a,d); /* n*d */
gf_cond_sel(a,d,a,sgn_s);
gf_mul_qnr(d,b);
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO);
gf_mul(b,a,c);
gf_cond_neg(b, sgn_r0^gf_hibit(b));
succ &= ~(gf_eq(b,ZERO) & sgn_r0);
#if COFACTOR == 8
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
#endif
#if 255 == 8*SER_BYTES + 1 /* p521. */
#error "this won't work because it needs to adjust high bit, not low bit"
sgn_r0 = 0;
#endif
gf_cond_neg(b, sgn_r0^gf_lobit(b));
/* Eliminate duplicate values for identity ... */
succ &= ~(gf_eq(b,ZERO) & (sgn_r0 | sgn_s));
// #if COFACTOR == 8
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
// #endif
#if 255 == 8*SER_BYTES + 1 /* p521 */
gf_serialize(recovered_hash,b,0);
#else
gf_serialize(recovered_hash,b,1);
#if PKP_MASK != 0
/* Add a multiple of p to make the result either almost-onto or completely onto. */
#if COFACTOR == 8
succ &= plus_k_p(recovered_hash, (hint >> 4) & PKP_MASK);
#else
succ &= plus_k_p(recovered_hash, (hint >> 3) & PKP_MASK);
#endif
#endif
#endif
#if 7
#if COFACTOR==8
recovered_hash[SER_BYTES-1] ^= (hint>>4)<<7;
#else
recovered_hash[SER_BYTES-1] ^= (hint>>3)<<7;
#endif
#endif
return decaf_succeed_if(mask_to_bool(succ));
}



+ 185
- 229
src/GENERATED/c/ed448goldilocks/decaf.c View File

@@ -48,10 +48,23 @@ static const scalar_t point_scalarmul_adjustment = {{{

const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] = { 0x05 };

#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL(
/* NONE */
)};
#define RISTRETTO_FACTOR DECAF_448_RISTRETTO_FACTOR
const gf RISTRETTO_FACTOR = {{{
0x42ef0f45572736, 0x7bf6aa20ce5296, 0xf4fd6eded26033, 0x968c14ba839a66, 0xb8d54b64a2d780, 0x6aa0a1f1a7b8a5, 0x683bf68d722fa2, 0x22d962fbeb24f7
}}};

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

/* End of template stuff */
@@ -109,128 +122,112 @@ gf_invert(gf y, const gf x, int assert_nonzero) {
gf_copy(y, t2);
}

/** Return high bit of x = low bit of 2x mod p */
static mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** identity = (0,1) */
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}};

/* Predeclare because not static: called by elligator */
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void) toggle_rotation;
gf b, d;
gf_s *c = s, *a = minus_t_over_s;
gf_mulw(a, p->y, 1-EDWARDS_D);
gf_mul(c, a, p->t); /* -dYT, with EDWARDS_D = d-1 */
gf_mul(a, p->x, p->z);
gf_sub(d, c, a); /* aXZ-dYT with a=-1 */
gf_add(a, p->z, p->y);
gf_sub(b, p->z, p->y);
gf_mul(c, b, a);
gf_mulw(b, c, -EDWARDS_D); /* (a-d)(Z+Y)(Z-Y) */
mask_t ok = gf_isr (a,b); /* r in the paper */
(void)ok; assert(ok | gf_eq(b,ZERO));
gf_mulw (b, a, -EDWARDS_D); /* u in the paper */

gf_mul(c,a,d); /* r(aZX-dYT) */
gf_mul(a,b,p->z); /* uZ */
gf_add(a,a,a); /* 2uZ */
mask_t tg = toggle_hibit_t_over_s ^ ~gf_hibit(minus_t_over_s);
gf_cond_neg(minus_t_over_s, tg); /* t/s <-? -t/s */
gf_cond_neg(c, tg); /* u <- -u if negative. */
gf_add(d,c,p->y);
gf_mul(s,b,d);
gf_cond_neg(s, toggle_hibit_s ^ gf_hibit(s));
#else
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1;
gf_add(t1,p->x,p->t);
gf_sub(t2,p->x,p->t);
gf_mul(t3,t1,t2); /* t3 = num */
gf_sqr(t2,p->x);
gf_mul(t1,t2,t3);
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */
gf_isr(t1,t2); /* t1 = isr */
gf_mul(t2,t1,t3); /* t2 = ratio */
gf_mul(t4,t2,RISTRETTO_FACTOR);
mask_t negx = gf_lobit(t4) ^ toggle_altx;
gf_cond_neg(t2, negx);
gf_mul(t3,t2,p->z);
gf_sub(t3,t3,p->t);
gf_mul(t2,t3,p->x);
gf_mulw(t4,t2,-1-TWISTED_D);
gf_mul(s,t4,t1);
mask_t lobs = gf_lobit(s);
gf_cond_neg(s,lobs);
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
#elif COFACTOR == 8 && IMAGINE_TWIST
/* More complicated because of rotation */
/* MAGIC This code is wrong for certain non-Curve25519 curves;
* check if it's because of Cofactor==8 or IMAGINE_TWIST */
gf c, d;
gf_s *b = s, *a = minus_t_over_s;

#if IMAGINE_TWIST
gf x, t;
gf_div_qnr(x,p->x);
gf_div_qnr(t,p->t);
gf_add ( a, p->z, x );
gf_sub ( b, p->z, x );
gf_mul ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 - X^2 */
#else
const gf_s *x = p->x, *t = p->t;
gf_sqr ( a, p->z );
gf_sqr ( b, p->x );
gf_add ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 + X^2 */
#endif
/* Here: c = "zx" in the SAGE code = Z^2 - aX^2 */
gf_mul ( a, p->z, t ); /* "tz" = T*Z */
gf_sqr ( b, a );
gf_mul ( d, b, c ); /* (TZ)^2 * (Z^2-aX^2) */
mask_t ok = gf_isr(b, d);
(void)ok; assert(ok | gf_eq(d,ZERO));
gf_mul ( d, b, a ); /* "osx" = 1 / sqrt(z^2-ax^2) */
gf_mul ( a, b, c );
gf_mul ( b, a, d ); /* 1/tz */

mask_t rotate;
#if (COFACTOR == 8)
gf e;
gf_sqr(e, p->z);
gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */
rotate = gf_hibit(a) ^ toggle_rotation;
/* Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x */
gf_mul ( a, b, c );
gf_cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate );
gf_cond_sel ( e, p->y, x, rotate );
#else
const gf_s *e = x;
(void)toggle_rotation;
rotate = 0;
#endif
gf_mul ( c, a, d ); // new "osx"
gf_mul ( a, c, p->z );
gf_add ( minus_t_over_s, a, a ); // 2 * "osx" * Z
gf_mul ( d, b, p->z );
mask_t tg = toggle_hibit_t_over_s ^~ gf_hibit(minus_t_over_s);
gf_cond_neg ( minus_t_over_s, tg );
gf_cond_neg ( c, rotate ^ tg );
gf_add ( d, d, c );
gf_mul ( s, d, e ); /* here "x" = y unless rotate */
gf_cond_neg ( s, toggle_hibit_s ^ gf_hibit(s) );
gf t1,t2,t3,t4,t5;
gf_add(t1,p->z,p->y);
gf_sub(t2,p->z,p->y);
gf_mul(t3,t1,t2); /* t3 = num */
gf_mul(t2,p->x,p->y); /* t2 = den */
gf_sqr(t1,t2);
gf_mul(t4,t1,t3);
gf_mulw(t1,t4,-1-TWISTED_D);
gf_isr(t4,t1); /* isqrt(num*(a-d)*den^2) */
gf_mul(t1,t2,t4);
gf_mul(t2,t1,RISTRETTO_FACTOR); /* t2 = "iden" in ristretto.sage */
gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */

/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_i(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */
mask_t rotate = toggle_rotation ^ gf_lobit(t3);
/* Rotate if altxy is negative */
gf_cond_swap(t1,t2,rotate);
gf_mul_i(t4,p->x);
gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */
gf_mul_i(t5,RISTRETTO_FACTOR); /* t5 = imi */
gf_mul(t3,t5,t2); /* iden * imi */
gf_mul(t2,t5,t1);
gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */
mask_t negx = gf_lobit(t5) ^ toggle_altx;
gf_cond_neg(t1,negx^rotate);
gf_mul(t2,t1,p->z);
gf_add(t2,t2,ONE);
gf_mul(inv_el_sum,t2,t4);
gf_mul(s,inv_el_sum,t3);
mask_t negs = gf_lobit(s);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
gf_cond_neg(inv_el_m1,negz);
gf_sub(inv_el_m1,inv_el_m1,t4);
#else
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
}

void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
gf s, mtos;
API_NS(deisogenize)(s,mtos,p,0,0,0);
gf_serialize(ser,s,0);
gf s,ie1,ie2;
API_NS(deisogenize)(s,ie1,ie2,p,0,0,0);
gf_serialize(ser,s,1);
}

decaf_error_t API_NS(point_decode) (
@@ -238,89 +235,54 @@ decaf_error_t API_NS(point_decode) (
const unsigned char ser[SER_BYTES],
decaf_bool_t allow_identity
) {
gf s, a, b, c, d, e, f;
mask_t succ = gf_deserialize(s, ser, 0);
mask_t zero = gf_eq(s, ZERO);
succ &= bool_to_mask(allow_identity) | ~zero;
gf_sqr ( a, s ); /* s^2 */
gf s, s2, num, tmp;
gf_s *tmp2=s2, *ynum=p->z, *isr=p->x, *den=p->t;
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
gf_sqr(s2,s); /* s^2 = -as^2 */
#if IMAGINE_TWIST
gf_sub ( f, ONE, a ); /* f = 1-as^2 = 1-s^2*/
#else
gf_add ( f, ONE, a ); /* f = 1-as^2 = 1+s^2 */
gf_sub(s2,ZERO,s2); /* -as^2 */
#endif
succ &= ~ gf_eq( f, ZERO );
gf_sqr ( b, f ); /* (1-as^2)^2 = 1 - 2as^2 + a^2 s^4 */
gf_mulw ( c, a, 4*IMAGINE_TWIST-4*EDWARDS_D );
gf_add ( c, c, b ); /* t^2 = 1 + (2a-4d) s^2 + s^4 */
gf_mul ( d, f, s ); /* s * (1-as^2) for denoms */
gf_sqr ( e, d ); /* s^2 * (1-as^2)^2 */
gf_mul ( b, c, e ); /* t^2 * s^2 * (1-as^2)^2 */
succ &= gf_isr(e,b) | gf_eq(b,ZERO); /* e = 1/(t s (1-as^2)) */
gf_mul ( b, e, d ); /* 1 / t */
gf_mul ( d, e, c ); /* t / (s(1-as^2)) */
gf_mul ( e, d, f ); /* t / s */
mask_t negtos = gf_hibit(e);
gf_cond_neg(b, negtos);
gf_cond_neg(d, negtos);

#if IMAGINE_TWIST
gf_add ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
#else
gf_sub ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
gf_sub(den,ONE,s2); /* 1+as^2 */
gf_add(ynum,ONE,s2); /* 1-as^2 */
gf_mulw(num,s2,-4*TWISTED_D);
gf_sqr(tmp,den); /* tmp = den^2 */
gf_add(num,tmp,num); /* num = den^2 - 4*d*s^2 */
gf_mul(tmp2,num,tmp); /* tmp2 = num*den^2 */
succ &= gf_isr(isr,tmp2); /* isr = 1/sqrt(num*den^2) */
gf_mul(tmp,isr,den); /* isr*den */
gf_mul(p->y,tmp,ynum); /* isr*den*(1-as^2) */
gf_mul(tmp2,tmp,s); /* s*isr*den */
gf_add(tmp2,tmp2,tmp2); /* 2*s*isr*den */
gf_mul(tmp,tmp2,isr); /* 2*s*isr^2*den */
gf_mul(p->x,tmp,num); /* 2*s*isr^2*den*num */
gf_mul(tmp,tmp2,RISTRETTO_FACTOR); /* 2*s*isr*den*magic */
gf_cond_neg(p->x,gf_lobit(tmp)); /* flip x */
#if COFACTOR==8
/* Additionally check y != 0 and x*y*isomagic nonegative */
succ &= ~gf_eq(p->y,ZERO);
gf_mul(tmp,p->x,p->y);
gf_mul(tmp2,tmp,RISTRETTO_FACTOR);
succ &= ~gf_lobit(tmp2);
#endif

#if COFACTOR == 8
gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */
succ &= ~gf_lobit(a); /* = ~gf_hibit(a/2), since gf_hibit(x) = gf_lobit(2x) */
#endif
gf_mul ( a, f, b ); /* y = (1-s^2) / t */
gf_mul ( p->y, p->z, a ); /* Y = yZ */
#if IMAGINE_TWIST
gf_add ( b, s, s );
gf_mul(p->x, b, SQRT_MINUS_ONE); /* Curve25519 */
#else
gf_add ( p->x, s, s );
#endif
gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */
#if UNSAFE_CURVE_HAS_POINTS_AT_INFINITY
/* This can't happen for any of the supported configurations.
*
* If it can happen (because s=1), it's because the curve has points
* at infinity, which means that there may be critical security bugs
* elsewhere in the library. In that case, it's better that you hit
* the assertion in point_valid, which will happen in the test suite
* since it tests s=1.
*
* This debugging option is to allow testing of IMAGINE_TWIST = 0 on
* Ed25519, without hitting that assertion. Don't use it in
* production.
*/
succ &= ~gf_eq(p->z,ZERO);
gf_copy(tmp,p->x);
gf_mul_i(p->x,tmp);
#endif

/* Fill in z and t */
gf_copy(p->z,ONE);
gf_mul(p->t,p->x,p->y);
p->y->limb[0] -= zero;
assert(API_NS(point_valid)(p) | ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

void API_NS(point_sub) (
point_t p,
const point_t q,
@@ -865,7 +827,7 @@ void API_NS(point_debugging_pscale) (
) {
gf gfac,tmp;
/* NB this means you'll never pscale by negative numbers for p521 */
ignore_result(gf_deserialize(gfac,factor,0));
ignore_result(gf_deserialize(gfac,factor,0,0));
gf_cond_sel(gfac,gfac,ONE,gf_eq(gfac,ZERO));
gf_mul(tmp,p->x,gfac);
gf_copy(q->x,tmp);
@@ -1078,7 +1040,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES],
const point_t p
) {
@@ -1116,15 +1078,20 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_mul ( y, u, t ); // (x^2+y^2)(2z^2-y^2+x^2)
gf_mul ( u, z, t );
gf_copy( z, u );
gf_mul ( u, x, SQRT_ONE_MINUS_D );
gf_mul ( u, x, RISTRETTO_FACTOR );
#if IMAGINE_TWIST
gf_mul_i( x, u );
#else
#error "... probably wrong"
gf_copy( x, u );
#endif
decaf_bzero(u,sizeof(u));
}
#elif IMAGINE_TWIST
{
API_NS(point_double)(q,q);
API_NS(point_double)(q,q);
gf_mul_qnr(x, q->x);
gf_mul_i(x, q->x);
gf_copy(y, q->y);
gf_copy(z, q->z);
}
@@ -1137,7 +1104,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_add( u, x, t );
gf_add( z, q->y, q->x );
gf_sqr ( y, z);
gf_sub ( y, u, y );
gf_sub ( y, y, u );
gf_sub ( z, t, x );
gf_sqr ( x, q->z );
gf_add ( t, x, x);
@@ -1166,7 +1133,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES]
) {
@@ -1176,7 +1143,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
mask_t low = ~word_is_zero(enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1] & 0x80);
enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1] &= ~0x80;
mask_t succ = gf_deserialize(p->y, enc2, 1);
mask_t succ = gf_deserialize(p->y, enc2, 1, 0);
#if 0 == 0
succ &= word_is_zero(enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1]);
#endif
@@ -1196,7 +1163,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
succ &= gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */
gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */
gf_cond_neg(p->x,~gf_lobit(p->x)^low);
gf_cond_neg(p->x,gf_lobit(p->x)^low);
gf_copy(p->z,ONE);
#if EDDSA_USE_SIGMA_ISOGENY
@@ -1221,8 +1188,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
gf_sub ( p->t, a, c ); // y^2 - x^2
gf_sqr ( p->x, p->z );
gf_add ( p->z, p->x, p->x );
gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_mul ( c, a, SQRT_ONE_MINUS_D );
gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_div_i ( a, c );
gf_mul ( c, a, RISTRETTO_FACTOR );
gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2)
gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2)
gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2)
@@ -1265,6 +1233,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_bzero(enc2,sizeof(enc2));
assert(API_NS(point_valid)(p) || ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

@@ -1274,7 +1243,7 @@ decaf_error_t decaf_x448 (
const uint8_t scalar[X_PRIVATE_BYTES]
) {
gf x1, x2, z2, x3, z3, t1, t2;
ignore_result(gf_deserialize(x1,base,1));
ignore_result(gf_deserialize(x1,base,1,0));
gf_copy(x2,ONE);
gf_copy(z2,ZERO);
gf_copy(x3,x1);
@@ -1345,15 +1314,8 @@ void decaf_ed448_convert_public_key_to_x448 (
const uint8_t ed[DECAF_EDDSA_448_PUBLIC_BYTES]
) {
gf y;
{
uint8_t enc2[DECAF_EDDSA_448_PUBLIC_BYTES];
memcpy(enc2,ed,sizeof(enc2));

/* retrieve y from the ed compressed point */
enc2[DECAF_EDDSA_448_PUBLIC_BYTES-1] &= ~0x80;
ignore_result(gf_deserialize(y, enc2, 0));
decaf_bzero(enc2,sizeof(enc2));
}
const uint8_t mask = (uint8_t)(0xFE<<(7));
ignore_result(gf_deserialize(y, ed, 1, mask));
{
gf n,d;
@@ -1390,6 +1352,26 @@ void decaf_x448_generate_key (
decaf_x448_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_ratio_and_encode_like_x448) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(q->y,ZERO,q->y);
#endif
gf_serialize(out,q->y,1);
API_NS(point_destroy(q));
}

void decaf_x448_derive_public_key (
uint8_t out[X_PUBLIC_BYTES],
const uint8_t scalar[X_PRIVATE_BYTES]
@@ -1405,39 +1387,13 @@ void decaf_x448_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
API_NS(scalar_halve)(the_scalar,the_scalar);
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X448_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
/* Isogenize to Montgomery curve.
*
* Why isn't this just a separate function, eg decaf_encode_like_x448?
* Basically because in general it does the wrong thing if there is a cofactor
* component in the input. In this function though, there isn't a cofactor
* component in the input.
*/
gf_invert(p->t,p->x,0); /* 1/x */
gf_mul(p->z,p->t,p->y); /* y/x */
gf_sqr(p->y,p->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(p->y,ZERO,p->y);
#endif
gf_serialize(out,p->y,1);
decaf_bzero(scalar2,sizeof(scalar2));
API_NS(scalar_destroy)(the_scalar);
API_NS(point_mul_by_ratio_and_encode_like_x448)(out,p);
API_NS(point_destroy)(p);
}



+ 13
- 4
src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c View File

@@ -21,7 +21,7 @@

#define API_NS(_id) decaf_448_##_id
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33
};

/* To satisfy linker. */
@@ -63,16 +63,25 @@ int main(int argc, char **argv) {
API_NS(point_t) real_point_base;
int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0);
if (ret != DECAF_SUCCESS) return 1;
if (ret != DECAF_SUCCESS) {
fprintf(stderr, "Can't decode base point!\n");
return 1;
}
API_NS(precomputed_s) *pre;
ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s));
if (ret || !pre) return 1;
if (ret || !pre) {
fprintf(stderr, "Can't allocate space for precomputed table\n");
return 1;
}
API_NS(precompute)(pre, real_point_base);
struct niels_s *pre_wnaf;
ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs));
if (ret || !pre_wnaf) return 1;
if (ret || !pre_wnaf) {
fprintf(stderr, "Can't allocate space for precomputed WNAF table\n");
return 1;
}
API_NS(precompute_wnafs)(pre_wnaf, real_point_base);

const gf_s *output;


+ 276
- 276
src/GENERATED/c/ed448goldilocks/decaf_tables.c View File

@@ -5,350 +5,350 @@

#define API_NS(_id) decaf_448_##_id
const API_NS(point_t) API_NS(point_base) = {{
{FIELD_LITERAL(0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff,0x0000000000000003,0x0000000000000000,0x0000000000000000,0x0000000000000000)},
{FIELD_LITERAL(0x0081e6d37f752992,0x003078ead1c28721,0x00135cfd2394666c,0x0041149c50506061,0x0031d30e4f5490b3,0x00902014990dc141,0x0052341b04c1e328,0x0014237853c10a1b)},
{FIELD_LITERAL(0x00fffffffffffffb,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff,0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff)},
{FIELD_LITERAL(0x008f205b70660415,0x00881c60cfd3824f,0x00377a638d08500d,0x008c66d5d4672615,0x00e52fa558e08e13,0x0087770ae1b6983d,0x004388f55a0aa7ff,0x00b4d9a785cf1a91)}
{FIELD_LITERAL(0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0080000000000000,0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x007fffffffffffff)},
{FIELD_LITERAL(0x006079b4dfdd4a64,0x000c1e3ab470a1c8,0x0044d73f48e5199b,0x0050452714141818,0x004c74c393d5242c,0x0024080526437050,0x00d48d06c13078ca,0x008508de14f04286)},
{FIELD_LITERAL(0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000)},
{FIELD_LITERAL(0x00e3c816dc198105,0x0062071833f4e093,0x004dde98e3421403,0x00a319b57519c985,0x00794be956382384,0x00e1ddc2b86da60f,0x0050e23d5682a9ff,0x006d3669e173c6a4)}
}};
const gf API_NS(precomputed_base_as_fe)[240]
VECTOR_ALIGNED __attribute__((visibility("hidden"))) = {
{FIELD_LITERAL(0x00e614a9f7278dc5,0x002e454ad04c5124,0x00d8f58cee1436f3,0x00c83ed46e4180ec,0x00a41e93274a38fa,0x00c1e7e53257771e,0x0043e0ff03c0392f,0x002c7c6405ce61df)},
{FIELD_LITERAL(0x0033c4f9dc990b33,0x00c291cb1ceb55c3,0x002ae3f58ade88b2,0x006b1f9f11395474,0x002ded6e4b27ff7c,0x0041012ed4aa10e1,0x003c22d20a36bae7,0x001f584eed472b19)},
{FIELD_LITERAL(0x00c3514779ee6f60,0x001574c873b20c2b,0x004cd6a46a5a5e65,0x0059a068aeb4204a,0x004c610458bc354d,0x00e94567479d02d2,0x00feaf77ed118e28,0x00f58a8bf115eeb5)},
{FIELD_LITERAL(0x0046110878fcb20f,0x00df43db21cc6f32,0x00ffdde9f4516644,0x00519917791686b9,0x00b72b441fd34473,0x008d45684cb1c72b,0x0015181370fc17a5,0x00a456d1307f74d3)},
{FIELD_LITERAL(0x001430f149b607dc,0x00e992ccd16715fc,0x00a62209b0a32a09,0x00b889cedc26b8e4,0x0059bf9a3ac109cf,0x006871bb3b7feac2,0x00f4a4d5fd9a0e6b,0x00b95db460cd69a5)},
{FIELD_LITERAL(0x0036304418bda702,0x007bc56861561558,0x00f344bc8e30416f,0x00a64537080f59d7,0x00b4c20077d00ace,0x00ee79620b26f8cc,0x00a6a558e0b5403d,0x008f1d2c766f3d19)},
{FIELD_LITERAL(0x00ef21c0297d3112,0x0073f89bd27c35b1,0x00ec44f9b1ff5e33,0x006bee51d878f1ee,0x001571a4b2aceddb,0x00cd0182d55131d1,0x0026761dbc1844be,0x00f01865af716474)},
{FIELD_LITERAL(0x0021dfef3f5fe8cc,0x0038c659ed1dbd68,0x0058ded9bcebe283,0x00077bbb094983ee,0x00b7b484e913d70c,0x0063e477a9506397,0x0000b996a6e01629,0x00ab68b41f75cd37)},
{FIELD_LITERAL(0x00a1fbd946403a4e,0x00be5a4e2d611b05,0x00ea4f210888bc6e,0x0043e9b0e0ae50fe,0x002abc4f6bd86845,0x00c3ed649c67f663,0x00d4eeb391a520e7,0x004b19cf1bfe7584)},
{FIELD_LITERAL(0x0099a75e6f22999e,0x001f16454c79f659,0x00d776a37fddc812,0x0095fdd63b6b0a78,0x00d232169366e947,0x002ea77dd21e9de7,0x00e8c46e85f97a90,0x00358758651f8cd9)},
{FIELD_LITERAL(0x002b6f5036a07bdf,0x004f6940af3e2646,0x00866028f8986799,0x00838b26ccb50415,0x0010557417f00b11,0x008a3b6bc447e96b,0x003de3d035e9e0c9,0x00188fca2b6d4011)},
{FIELD_LITERAL(0x001ca4038635312b,0x0078dc75c1e01c44,0x004340f00b3100a4,0x005e63e36bf6646e,0x008e1efd4b624688,0x00a61c2ffb1525e1,0x0072587505a75b81,0x00a8637140d96e78)},
{FIELD_LITERAL(0x004a7c41ffac8a41,0x005bf37075b1c20b,0x00c053b570a42408,0x002bb7e278d328e7,0x00b2378b63245100,0x003318bf2a1a368a,0x00f4e3e0bdbe02de,0x0058921e4b1e32f8)},
{FIELD_LITERAL(0x005e93d6fa1118a0,0x0062b43515d381e2,0x002c42864052e620,0x00af258bae6ccbd3,0x00954247094d654d,0x005db01f5b010810,0x009c8cf25efa8204,0x005f73ced3714ef7)},
{FIELD_LITERAL(0x0085f89aff2cf49d,0x00f591ee8480f6f0,0x00378ed518114265,0x00f04293e2a09008,0x00c58688db9140ed,0x00e9912696399ff1,0x0055bd1b96367413,0x0023a70cf830f999)},
{FIELD_LITERAL(0x001c83772944584e,0x00c1ba881e472bcc,0x00af2715a0aef13f,0x00bd0360d25610a6,0x00c42f8b3eebebde,0x00a9e474849788b1,0x00dcd1a1a2efec5c,0x009480d34c2818c0)},
{FIELD_LITERAL(0x00b4b6e09a565d74,0x0095efcf6175aa48,0x00498defe7ae7810,0x00309b684ed26470,0x007a8873a91d4e44,0x00ea4b3f857eb27a,0x00979b8619d25a9e,0x00721a2770eeb6e9)},
{FIELD_LITERAL(0x00b422f0f4be195f,0x00e88cfa83bfa2db,0x009fd60666ea4268,0x0095a458f5e801d0,0x00b9eee6882081f6,0x00b27edb37604948,0x00a7f67c4d44d8db,0x00df840ccf290c01)},
{FIELD_LITERAL(0x00c9fed0d47c9103,0x00ba73ed9294a043,0x005cbbc928e652e1,0x0068419e98ee8215,0x00f63de63786300b,0x009aa9bb6c19f8aa,0x0066c536b573213f,0x00d2b77a5b2f2450)},
{FIELD_LITERAL(0x00810236c68d5b74,0x00d0a1af1872a011,0x007f23ee29e3801a,0x009a55a678f8dba4,0x0065445dcff9be40,0x00f3978789a9abc5,0x00001f010d23f5e8,0x00ff80042934b0c5)},
{FIELD_LITERAL(0x00a6749f4b3f9745,0x003ab85f4180e502,0x006a7de9b530ed50,0x0050b5353b0441bf,0x00a093583ac6ede4,0x00c4918ad1406299,0x000f75cf2a353a2b,0x001c6644a0683a56)},
{FIELD_LITERAL(0x00e8694156c09bfe,0x00f6f3a5bd17ad96,0x0098dbed45edad12,0x00edfe2b84921821,0x0097884330199b67,0x004aab02685b3e9e,0x0068ac0bd2453c30,0x00167c1c1c87d8f5)},
{FIELD_LITERAL(0x008bba5fbf63f599,0x0059a3c960c7d63f,0x00ce2db75b08b7d9,0x0097e80cb2104171,0x009b68be26a140d0,0x002b9b9954e94c68,0x00023ca8fc411beb,0x00cbc4bcccbada07)},
{FIELD_LITERAL(0x0053c100e77b678d,0x000f115c400fa96f,0x005928d3de22afa2,0x00e47cd9bdbdbe96,0x00597ecfe84abf19,0x0058bb428e4c7a32,0x00dd582f76ecf584,0x00b1211365eccb79)},
{FIELD_LITERAL(0x00dbfb9a00a58e68,0x004468189350d82f,0x00b4b12407ee92c6,0x00e27a7908f73455,0x00f071170071b5ae,0x00221a5e6ba229dd,0x001903e3f6a81f83,0x00be36325402775f)},
{FIELD_LITERAL(0x004d298d6e691756,0x00775644dfce310b,0x00a861887823ea98,0x00cf0b6014fa6e6f,0x005f4e296380826f,0x00bf423392627f90,0x002893bfc8122f6a,0x00440dbc89bea228)},
{FIELD_LITERAL(0x00acbb4f40a4ab73,0x00d6a82f48fa3366,0x000a7958fc6faac2,0x008a4cdd60a7c33c,0x005e5587dd8b6f1a,0x00e40f63086a88e8,0x0030940cbbcda0ad,0x009a42e3dc35c130)},
{FIELD_LITERAL(0x00d37716cad825f1,0x00883870cba9552a,0x008ef785f5c762e3,0x006cb253e0469242,0x007b8f17fee9d967,0x00a43de6932b52b6,0x001aca9fe2af783c,0x008967778ff0b680)},
{FIELD_LITERAL(0x006400c4cdc6c9c3,0x001e8c978691083f,0x00ad74f01f68e0c5,0x00f7feb0372b5f6a,0x002f60d175ade13a,0x0098ec54a221a678,0x00fcfea8a71f244e,0x00dea6660e45ded2)},
{FIELD_LITERAL(0x002585b4aa8d6752,0x00e62da7615a2089,0x0010c1c741f39b68,0x00569bb1eced9f65,0x00ba6d09e4daa724,0x007d3e20aef281b9,0x00bd7f65aca3ffdc,0x00dea434a50288a8)},
{FIELD_LITERAL(0x007ba92a2489170f,0x00cd356354d31e9c,0x00a60d47406e5430,0x009c3d5fde8ed877,0x00079eaa50dd08d1,0x0024674d593ffa5f,0x005391be9596c53b,0x00856ca8d50acdd9)},
{FIELD_LITERAL(0x00d4620aa5e5bdec,0x002303c4b9b5d941,0x003b061f857ebb2a,0x00371f9e856d49fd,0x0071c36c5335051e,0x0040e4346a4d359f,0x00b31dbd959ec40c,0x00d99353a71bf6de)},
{FIELD_LITERAL(0x0078898adf0f21dd,0x006e09bfedd8604a,0x00efaf0e0f9bb666,0x00b0f685db8852c3,0x0094c86ec566b841,0x00e5c2879ba50dbe,0x00a87cd444cff758,0x00d3e26fd47f23df)},
{FIELD_LITERAL(0x00b82c07fb1854f8,0x0057f654a06fad9f,0x004c00383250cf92,0x008b91713d291af6,0x002f2521777859b9,0x00533111421f22c8,0x00643da86fab9794,0x00dc7fb0680e3d40)},
{FIELD_LITERAL(0x00e59ffd40e87788,0x006431e9755a50af,0x00a03ce700fb580a,0x00ad7e70aa3c9b9e,0x0078970a2b4db503,0x00c800451849637a,0x00e7e6a5b49e123f,0x00e1ed15f77bcb4d)},
{FIELD_LITERAL(0x00bc1d1d1af47f28,0x00ebc5501bbd81f0,0x00aa6b5513547aa4,0x0074ed33551343fe,0x00d2114f6ef7d43b,0x006335b41d518aeb,0x00ebd46919692fb8,0x0052d5d4e3fada95)},
{FIELD_LITERAL(0x00ebfc9f489799a4,0x00497535b6980688,0x00fef76499e6a51b,0x00018eedde7a18da,0x00f435d9e72b69c7,0x005ab0faa8281675,0x003232d06e290be8,0x005473ec8be0286c)},
{FIELD_LITERAL(0x00c6eb0d0ebb4874,0x00856a2274119097,0x00380bc7b29e3719,0x00b1ae149f0e424d,0x0009b41855b9de26,0x0098684013d0f53f,0x0082e8554c38a6ff,0x00e76c18c353743a)},
{FIELD_LITERAL(0x008da1194e1ab61f,0x008edb5f89688805,0x00f4970252f851bd,0x007a46f632b6ad20,0x006d2d1c37e9f90a,0x0060dd09353f665f,0x000a625a80d86657,0x000f93f6fedd0888)},
{FIELD_LITERAL(0x003b019b31992fb4,0x004f6a2ad1f64c28,0x008a744134e5c571,0x000ca33172f9af3f,0x00d478755a67bb8b,0x009d1f5c48abb223,0x004da4d6f12ee901,0x0084f09541f4140d)},
{FIELD_LITERAL(0x0031f412f5cacd43,0x00e5afb75dd20e94,0x001ce24b3452740e,0x00176d6dedf30ff1,0x0082e22e564fffca,0x001d56fbe007097f,0x0095b37c851a6918,0x008ec50ef97f8f4c)},
{FIELD_LITERAL(0x007e2b1c52251f57,0x00cbef37c9380033,0x0037ed652761bceb,0x00f1c2a5dc6dd232,0x0026e1b90d63ce0b,0x00938d732173a6b8,0x00d439aa45da993f,0x00d356b8deaccef7)},
{FIELD_LITERAL(0x00ed32377f56c67d,0x00c3b6a4de32e4a7,0x00481a36c0dd5d91,0x00bb557d20466ba7,0x00645f6d3200163e,0x005eb4c54df7c48c,0x00fd8e3d08f1e3b4,0x001156353f099147)},
{FIELD_LITERAL(0x00ae1b4c089b2756,0x00e686d2b916fb5f,0x007ac43ec2437dd8,0x00f7bfdf7e860ed2,0x0097dbcb8b786dc9,0x00ec7a90401c8b2f,0x00425ed017989bdb,0x00444bc9ca6d914d)},
{FIELD_LITERAL(0x00e5e7b83b53ab7f,0x004e4bed6ca44fc5,0x0008bd7a67c40d4d,0x009dbec74a4a2f0e,0x0077df3f4fc2c73f,0x0046b1af5e73ea8d,0x009f096cb7be8670,0x003ad0a29929141d)},
{FIELD_LITERAL(0x00991a1222e9b2e1,0x00be7583901d7dc7,0x00fd1d0c8169d3da,0x000fe0a94a68acf9,0x00b77bd05afc78a2,0x00a84f1697f87ebc,0x000097cfdb0c2ecb,0x007d51d70352ed1b)},
{FIELD_LITERAL(0x0025dc2a60643159,0x001f0d8ff85f95b4,0x00ed74a4bc598a73,0x00f30afe6f0574a9,0x0003788545d4d28c,0x009dc410ad120ac0,0x001950947e69961d,0x001ceb23cb0355b0)},
{FIELD_LITERAL(0x00ee2202ded9f1bd,0x002fa4fce658976d,0x00e7c15bc9716470,0x004f7ea99d500369,0x004b995a18318376,0x00246c4f8af91911,0x00cc77a07d09dbfe,0x007906f6f1364be6)},
{FIELD_LITERAL(0x003c97e6384da36e,0x00423d53eac81a09,0x00b70d68f3cdce35,0x00ee7959b354b92c,0x00f4e9718819c8ca,0x009349f12acbffe9,0x005aee7b62cb7da6,0x00d97764154ffc86)},
{FIELD_LITERAL(0x00cc3b062366f4cc,0x003d6e34e314aa3c,0x00d51c0a7521774d,0x0094e060eec6ab8b,0x00d21291b4d80082,0x00befed12b55ef1e,0x00c3dd2df5c94518,0x00e0a7b112b8d4e6)},
{FIELD_LITERAL(0x0019eb5608d8723a,0x00d1bab52fb3aedb,0x00270a7311ebc90c,0x0037c12b91be7f13,0x005be16cd8b5c704,0x003e181acda888e1,0x00bc1f00fc3fc6d0,0x00d3839bfa319e20)},
{FIELD_LITERAL(0x003caeb88611909f,0x00ea8b378c4df3d4,0x00b3295b95a5a19a,0x00a65f97514bdfb5,0x00b39efba743cab1,0x0016ba98b862fd2d,0x0001508812ee71d7,0x000a75740eea114a)},
{FIELD_LITERAL(0x00ebcf0eb649f823,0x00166d332e98ea03,0x0059ddf64f5cd5f6,0x0047763123d9471b,0x00a64065c53ef62f,0x00978e44c480153d,0x000b5b2a0265f194,0x0046a24b9f32965a)},
{FIELD_LITERAL(0x00b9eef787034df0,0x0020bc24de3390cd,0x000022160bae99bb,0x00ae66e886e97946,0x0048d4bbe02cbb8b,0x0072ba97b34e38d4,0x00eae7ec8f03e85a,0x005ba92ecf808b2c)},
{FIELD_LITERAL(0x00c9cfbbe74258fd,0x00843a979ea9eaa7,0x000cbb4371cfbe90,0x0059bac8f7f0a628,0x004b3dff882ff530,0x0011869df4d90733,0x00595aa71f4abfc2,0x0070e2d38990c2e6)},
{FIELD_LITERAL(0x00de2010c0a01733,0x00c739a612e24297,0x00a7212643141d7c,0x00f88444f6b67c11,0x00484b7b16ec28f2,0x009c1b8856af9c68,0x00ff4669591fe9d6,0x0054974be08a32c8)},
{FIELD_LITERAL(0x0010de3fd682ceed,0x008c07642d83ca4e,0x0013bb064e00a1cc,0x009411ae27870e11,0x00ea8e5b4d531223,0x0032fe7d2aaece2e,0x00d989e243e7bb41,0x000fe79a508e9b8b)},
{FIELD_LITERAL(0x005e0426b9bfc5b1,0x0041a5b1d29ee4fa,0x0015b0def7774391,0x00bc164f1f51af01,0x00d543b0942797b9,0x003c129b6398099c,0x002b114c6e5adf18,0x00b4e630e4018a7b)},
{FIELD_LITERAL(0x00d490afc95f8420,0x00b096bf50c1d9b9,0x00799fd707679866,0x007c74d9334afbea,0x00efaa8be80ff4ed,0x0075c4943bb81694,0x00c21c2fca161f36,0x00e77035d492bfee)},
{FIELD_LITERAL(0x006658a190dd6661,0x00e0e9bab38609a6,0x0028895c802237ed,0x006a0229c494f587,0x002dcde96c9916b7,0x00d158822de16218,0x00173b917a06856f,0x00ca78a79ae07326)},
{FIELD_LITERAL(0x00e35bfc79caced4,0x0087238a3e1fe3bb,0x00bcbf0ff4ceff5b,0x00a19c1c94099b91,0x0071e102b49db976,0x0059e3d004eada1e,0x008da78afa58a47e,0x00579c8ebf269187)},
{FIELD_LITERAL(0x00a16c2905eee75f,0x009d4bcaea2c7e1d,0x00d3bd79bfad19df,0x0050da745193342c,0x006abdb8f6b29ab1,0x00a24fe0a4fef7ef,0x0063730da1057dfb,0x00a08c312c8eb108)},
{FIELD_LITERAL(0x00b583be005375be,0x00a40c8f8a4e3df4,0x003fac4a8f5bdbf7,0x00d4481d872cd718,0x004dc8749cdbaefe,0x00cce740d5e5c975,0x000b1c1f4241fd21,0x00a76de1b4e1cd07)},
{FIELD_LITERAL(0x007a076500d30b62,0x000a6e117b7f090f,0x00c8712ae7eebd9a,0x000fbd6c1d5f6ff7,0x003a7977246ebf11,0x00166ed969c6600e,0x00aa42e469c98bec,0x00dc58f307cf0666)},
{FIELD_LITERAL(0x004b491f65a9a28b,0x006a10309e8a55b7,0x00b67210185187ef,0x00cf6497b12d9b8f,0x0085778c56e2b1ba,0x0015b4c07a814d85,0x00686479e62da561,0x008de5d88f114916)},
{FIELD_LITERAL(0x00e37c88d6bba7b1,0x003e4577e1b8d433,0x0050d8ea5f510ec0,0x0042fc9f2da9ef59,0x003bd074c1141420,0x00561b8b7b68774e,0x00232e5e5d1013a3,0x006b7f2cb3d7e73f)},
{FIELD_LITERAL(0x004bdd0f0b41e6a0,0x001773057c405d24,0x006029f99915bd97,0x006a5ba70a17fe2f,0x0046111977df7e08,0x004d8124c89fb6b7,0x00580983b2bb2724,0x00207bf330d6f3fe)},
{FIELD_LITERAL(0x007efdc93972a48b,0x002f5e50e78d5fee,0x0080dc11d61c7fe5,0x0065aa598707245b,0x009abba2300641be,0x000c68787656543a,0x00ffe0fef2dc0a17,0x00007ffbd6cb4f3a)},
{FIELD_LITERAL(0x0036012f2b836efc,0x00458c126d6b5fbc,0x00a34436d719ad1e,0x0097be6167117dea,0x0009c219c879cff3,0x0065564493e60755,0x00993ac94a8cdec0,0x002d4885a4d0dbaf)},
{FIELD_LITERAL(0x00598b60b4c068ba,0x00c547a0be7f1afd,0x009582164acf12af,0x00af4acac4fbbe40,0x005f6ca7c539121a,0x003b6e752ebf9d66,0x00f08a30d5cac5d4,0x00e399bb5f97c5a9)},
{FIELD_LITERAL(0x007445a0409c0a66,0x00a65c369f3829c0,0x0031d248a4f74826,0x006817f34defbe8e,0x00649741d95ebf2e,0x00d46466ab16b397,0x00fdc35703bee414,0x00343b43334525f8)},
{FIELD_LITERAL(0x001796bea93f6401,0x00090c5a42e85269,0x00672412ba1252ed,0x001201d47b6de7de,0x006877bccfe66497,0x00b554fd97a4c161,0x009753f42dbac3cf,0x00e983e3e378270a)},
{FIELD_LITERAL(0x00ac3eff18849872,0x00f0eea3bff05690,0x00a6d72c21dd505d,0x001b832642424169,0x00a6813017b540e5,0x00a744bd71b385cd,0x0022a7d089130a7b,0x004edeec9a133486)},
{FIELD_LITERAL(0x00b2d6729196e8a9,0x0088a9bb2031cef4,0x00579e7787dc1567,0x0030f49feb059190,0x00a0b1d69c7f7d8f,0x0040bdcc6d9d806f,0x00d76c4037edd095,0x00bbf24376415dd7)},
{FIELD_LITERAL(0x00240465ff5a7197,0x00bb97e76caf27d0,0x004b4edbf8116d39,0x001d8586f708cbaa,0x000f8ee8ff8e4a50,0x00dde5a1945dd622,0x00e6fc1c0957e07c,0x0041c9cdabfd88a0)},
{FIELD_LITERAL(0x005344b0bf5b548c,0x002957d0b705cc99,0x00f586a70390553d,0x0075b3229f583cc3,0x00a1aa78227490e4,0x001bf09cf7957717,0x00cf6bf344325f52,0x0065bd1c23ca3ecf)},
{FIELD_LITERAL(0x009bff3b3239363c,0x00e17368796ef7c0,0x00528b0fe0971f3a,0x0008014fc8d4a095,0x00d09f2e8a521ec4,0x006713ab5dde5987,0x0003015758e0dbb1,0x00215999f1ba212d)},
{FIELD_LITERAL(0x002c88e93527da0e,0x0077c78f3456aad5,0x0071087a0a389d1c,0x00934dac1fb96dbd,0x008470e801162697,0x005bc2196cd4ad49,0x00e535601d5087c3,0x00769888700f497f)},
{FIELD_LITERAL(0x00da7a4b557298ad,0x0019d2589ea5df76,0x00ef3e38be0c6497,0x00a9644e1312609a,0x004592f61b2558da,0x0082c1df510d7e46,0x0042809a535c0023,0x00215bcb5afd7757)},
{FIELD_LITERAL(0x002b9df55a1a4213,0x00dcfc3b464a26be,0x00c4f9e07a8144d5,0x00c8e0617a92b602,0x008e3c93accafae0,0x00bf1bcb95b2ca60,0x004ce2426a613bf3,0x00266cac58e40921)},
{FIELD_LITERAL(0x008456d5db76e8f0,0x0032ca9cab2ce163,0x0059f2b8bf91abcf,0x0063c2a021712788,0x00f86155af22f72d,0x00db98b2a6c005a0,0x00ac6e416a693ac4,0x007a93572af53226)},
{FIELD_LITERAL(0x0087767520f0de22,0x0091f64012279fb5,0x001050f1f0644999,0x004f097a2477ad3c,0x006b37913a9947bd,0x001a3d78645af241,0x0057832bbb3008a7,0x002c1d902b80dc20)},
{FIELD_LITERAL(0x001a6002bf178877,0x009bce168aa5af50,0x005fc318ff04a7f5,0x0052818f55c36461,0x008768f5d4b24afb,0x0037ffbae7b69c85,0x0018195a4b61edc0,0x001e12ea088434b2)},
{FIELD_LITERAL(0x0047d3f804e7ab07,0x00a809ab5f905260,0x00b3ffc7cdaf306d,0x00746e8ec2d6e509,0x00d0dade8887a645,0x00acceeebde0dd37,0x009bc2579054686b,0x0023804f97f1c2bf)},
{FIELD_LITERAL(0x0043e2e2e50b80d7,0x00143aafe4427e0f,0x005594aaecab855b,0x008b12ccaaecbc01,0x002deeb091082bc3,0x009cca4be2ae7514,0x00142b96e696d047,0x00ad2a2b1c05256a)},
{FIELD_LITERAL(0x003914f2f144b78b,0x007a95dd8bee6f68,0x00c7f4384d61c8e6,0x004e51eb60f1bdb2,0x00f64be7aa4621d8,0x006797bfec2f0ac0,0x007d17aab3c75900,0x001893e73cac8bc5)},
{FIELD_LITERAL(0x00140360b768665b,0x00b68aca4967f977,0x0001089b66195ae4,0x00fe71122185e725,0x000bca2618d49637,0x00a54f0557d7e98a,0x00cdcd2f91d6f417,0x00ab8c13741fd793)},
{FIELD_LITERAL(0x00725ee6b1e549e0,0x007124a0769777fa,0x000b68fdad07ae42,0x0085b909cd4952df,0x0092d2e3c81606f4,0x009f22f6cac099a0,0x00f59da57f2799a8,0x00f06c090122f777)},
{FIELD_LITERAL(0x00ce0bed0a3532bc,0x001a5048a22df16b,0x00e31db4cbad8bf1,0x00e89292120cf00e,0x007d1dd1a9b00034,0x00e2a9041ff8f680,0x006a4c837ae596e7,0x00713af1068070b3)},
{FIELD_LITERAL(0x00c4fe64ce66d04b,0x00b095d52e09b3d7,0x00758bbecb1a3a8e,0x00f35cce8d0650c0,0x002b878aa5984473,0x0062e0a3b7544ddc,0x00b25b290ed116fe,0x007b0f6abe0bebf2)},
{FIELD_LITERAL(0x0081d4e3addae0a8,0x003410c836c7ffcc,0x00c8129ad89e4314,0x000e3d5a23922dcd,0x00d91e46f29c31f3,0x006c728cde8c5947,0x002bc655ba2566c0,0x002ca94721533108)},
{FIELD_LITERAL(0x0051e4b3f764d8a9,0x0019792d46e904a0,0x00853bc13dbc8227,0x000840208179f12d,0x0068243474879235,0x0013856fbfe374d0,0x00bda12fe8676424,0x00bbb43635926eb2)},
{FIELD_LITERAL(0x0012cdc880a93982,0x003c495b21cd1b58,0x00b7e5c93f22a26e,0x0044aa82dfb99458,0x009ba092cdffe9c0,0x00a14b3ab2083b73,0x000271c2f70e1c4b,0x00eea9cac0f66eb8)},
{FIELD_LITERAL(0x001a1847c4ac5480,0x00b1b412935bb03a,0x00f74285983bf2b2,0x00624138b5b5d0f1,0x008820c0b03d38bf,0x00b94e50a18c1572,0x0060f6934841798f,0x00c52f5d66d6ebe2)},
{FIELD_LITERAL(0x00da23d59f9bcea6,0x00e0f27007a06a4b,0x00128b5b43a6758c,0x000cf50190fa8b56,0x00fc877aba2b2d72,0x00623bef52edf53f,0x00e6af6b819669e2,0x00e314dc34fcaa4f)},
{FIELD_LITERAL(0x0066e5eddd164d1e,0x00418a7c6fe28238,0x0002e2f37e962c25,0x00f01f56b5975306,0x0048842fa503875c,0x0057b0e968078143,0x00ff683024f3d134,0x0082ae28fcad12e4)},
{FIELD_LITERAL(0x0011ddfd21260e42,0x00d05b0319a76892,0x00183ea4368e9b8f,0x00b0815662affc96,0x00b466a5e7ce7c88,0x00db93b07506e6ee,0x0033885f82f62401,0x0086f9090ec9b419)},
{FIELD_LITERAL(0x00d95d1c5fcb435a,0x0016d1ed6b5086f9,0x00792aa0b7e54d71,0x0067b65715f1925d,0x00a219755ec6176b,0x00bc3f026b12c28f,0x00700c897ffeb93e,0x0089b83f6ec50b46)},
{FIELD_LITERAL(0x00ad9cdb4544b923,0x00d11664c7284061,0x00815ae86b8f910b,0x005414fb2591c3c6,0x0094ba83e2d7ef9e,0x0001dbc16599386c,0x00c8721f0493911b,0x00c1be6b463c346c)},
{FIELD_LITERAL(0x0079680ce111ed3b,0x001a1ed82806122c,0x000c2e7466d15df3,0x002c407f6f7150fd,0x00c5e7c96b1b0ce3,0x009aa44626863ff9,0x00887b8b5b80be42,0x00b6023cec964825)},
{FIELD_LITERAL(0x003c97e6384da36e,0x00423d53eac81a09,0x00b70d68f3cdce35,0x00ee7959b354b92c,0x00f4e9718819c8ca,0x009349f12acbffe9,0x005aee7b62cb7da6,0x00d97764154ffc86)},
{FIELD_LITERAL(0x00526324babb46dc,0x002ee99b38d7bf9e,0x007ea51794706ef4,0x00abeb04da6e3c39,0x006b457c1d281060,0x00fe243e9a66c793,0x00378de0fb6c6ee4,0x003e4194b9c3cb93)},
{FIELD_LITERAL(0x00fed3cd80ca2292,0x0015b043a73ca613,0x000a9fd7bf9be227,0x003b5e03de2db983,0x005af72d46904ef7,0x00c0f1b5c49faa99,0x00dc86fc3bd305e1,0x00c92f08c1cb1797)},
{FIELD_LITERAL(0x001b571efb768f37,0x009d778487cf5cfd,0x00430e37327ebfd4,0x00a92447e5970a41,0x00eb13127c0edbac,0x00ec61e5aefeaf20,0x00447eebf57d2e5c,0x00f01433e550e558)},
{FIELD_LITERAL(0x0039dd7ce7fc6860,0x00d64f6425653da1,0x003e037c7f57d0af,0x0063477a06e2bcf2,0x001727dbb7ac67e6,0x0049589f5efafe2e,0x00fc0fef2e813d54,0x008baa5d087fb50d)},
{FIELD_LITERAL(0x0079680ce111ed3b,0x001a1ed82806122c,0x000c2e7466d15df3,0x002c407f6f7150fd,0x00c5e7c96b1b0ce3,0x009aa44626863ff9,0x00887b8b5b80be42,0x00b6023cec964825)},
{FIELD_LITERAL(0x00e4a8e1048970c8,0x0062887b7830a302,0x00bcf1c8cd81402b,0x0056dbb81a68f5be,0x0014eced83f12452,0x00139e1a510150df,0x00bb81140a82d1a3,0x000febcc1aaf1aa7)},
{FIELD_LITERAL(0x00a7527958238159,0x0013ec9537a84cd6,0x001d7fee7d562525,0x00b9eefa6191d5e5,0x00dbc97db70bcb8a,0x00481affc7a4d395,0x006f73d3e70c31bb,0x00183f324ed96a61)},
{FIELD_LITERAL(0x00db04a6264ba838,0x00582b1f9fddc1b3,0x003ee72e4aaa027f,0x007d1de938cd0dd5,0x0032d5d66cf76afa,0x00c9c717c95c1ec2,0x00f27aa11764b8d6,0x00713a482b7ef36e)},
{FIELD_LITERAL(0x00ece96f95f2b66f,0x00ece7952813a27b,0x0026fc36592e489e,0x007157d1a2de0f66,0x00759dc111d86ddf,0x0012881e5780bb0f,0x00c8ccc83ad29496,0x0012b9bd1929eb71)},
{FIELD_LITERAL(0x0039dd7ce7fc6860,0x00d64f6425653da1,0x003e037c7f57d0af,0x0063477a06e2bcf2,0x001727dbb7ac67e6,0x0049589f5efafe2e,0x00fc0fef2e813d54,0x008baa5d087fb50d)},
{FIELD_LITERAL(0x0024fb59d9b457c7,0x00a7d4e060223e4c,0x00c118d1b555fd80,0x0082e216c732f22a,0x00cd2a2993089504,0x003638e836a3e13d,0x000d855ee89b4729,0x008ec5b7d4810c91)},
{FIELD_LITERAL(0x001bf51f7d65cdfd,0x00d14cdafa16a97d,0x002c38e60fcd10e7,0x00a27446e393efbd,0x000b5d8946a71fdd,0x0063df2cde128f2f,0x006c8679569b1888,0x0059ffc4925d732d)},
{FIELD_LITERAL(0x00f05ea5df25a20f,0x00cb6224e5b932ce,0x00d3aed52e2718d9,0x00fb89ee0996ce72,0x006197045a6e1e80,0x00bcdf20057fc6f9,0x0059bf78b6ae5c2c,0x0049cacb87455db0)},
{FIELD_LITERAL(0x006a15bb20f75c0c,0x0079a144027a5d0c,0x00d19116ce0b4d70,0x0059b83bcb0b268e,0x005f58f63f16c127,0x0079958318ee2c37,0x00defbb063d07f82,0x00f1f0b931d2d446)},
{FIELD_LITERAL(0x00ece96f95f2b66f,0x00ece7952813a27b,0x0026fc36592e489e,0x007157d1a2de0f66,0x00759dc111d86ddf,0x0012881e5780bb0f,0x00c8ccc83ad29496,0x0012b9bd1929eb71)},
{FIELD_LITERAL(0x000fa15a20da5df0,0x00349ddb1a46cd31,0x002c512ad1d8e726,0x00047611f669318d,0x009e68fba591e17e,0x004320dffa803906,0x00a640874951a3d3,0x00b6353478baa24f)},
{FIELD_LITERAL(0x009696510000d333,0x00ec2f788bc04826,0x000e4d02b1f67ba5,0x00659aa8dace08b6,0x00d7a38a3a3ae533,0x008856defa8c746b,0x004d7a4402d3da1a,0x00ea82e06229260f)},
{FIELD_LITERAL(0x0034a1b3c3ca2bdd,0x0072077a35bca880,0x0005af4e935c1b8e,0x00a5f1a71e8b7737,0x004d3133292cb2e5,0x000fe2a2dca1c916,0x0024d181b41935bb,0x00d9f54880ca0332)},
{FIELD_LITERAL(0x009ffd90abfeae96,0x00cba3c2b624a516,0x005ef08bcee46c91,0x00e6fde30afb6185,0x00f0b4db4f818ce4,0x006c54f45d2127f5,0x00040125035854c7,0x00372658a3287e13)},
{FIELD_LITERAL(0x006a15bb20f75c0c,0x0079a144027a5d0c,0x00d19116ce0b4d70,0x0059b83bcb0b268e,0x005f58f63f16c127,0x0079958318ee2c37,0x00defbb063d07f82,0x00f1f0b931d2d446)},
{FIELD_LITERAL(0x00cb5e4c3c35d422,0x008df885ca43577f,0x00fa50b16ca3e471,0x005a0e58e17488c8,0x00b2ceccd6d34d19,0x00f01d5d235e36e9,0x00db2e7e4be6ca44,0x00260ab77f35fccd)},
{FIELD_LITERAL(0x006f6fd9baac61d5,0x002a7710a020a895,0x009de0db7fc03d4d,0x00cdedcb1875f40b,0x00050caf9b6b1e22,0x005e3a6654456ab0,0x00775fdf8c4423d4,0x0028701ea5738b5d)},
{FIELD_LITERAL(0x0028f8f04e414d54,0x0087037ba56c7694,0x00976b5b4d0ddb59,0x00a4227e6d462421,0x004c77c678b4c560,0x0006c9e74fb485a8,0x00c1c138a02d3981,0x0040a19403d6b6b5)},
{FIELD_LITERAL(0x0045e8dda9400888,0x002ff12e5fc05db7,0x00a7098d54afe69c,0x00cdbe846a500585,0x00879c1593ca1882,0x003f7a7fea76c8b0,0x002cd73dd0c8e0a1,0x00645d6ce96f51fe)},
{FIELD_LITERAL(0x009ffd90abfeae96,0x00cba3c2b624a516,0x005ef08bcee46c91,0x00e6fde30afb6185,0x00f0b4db4f818ce4,0x006c54f45d2127f5,0x00040125035854c7,0x00372658a3287e13)},
{FIELD_LITERAL(0x00d7070fb1beb2ab,0x0078fc845a93896b,0x006894a4b2f224a6,0x005bdd8192b9dbde,0x00b38839874b3a9e,0x00f93618b04b7a57,0x003e3ec75fd2c67e,0x00bf5e6bfc29494a)},
{FIELD_LITERAL(0x00f19224ebba2aa5,0x0074f89d358e694d,0x00eea486597135ad,0x0081579a4555c7e1,0x0010b9b872930a9d,0x00f002e87a30ecc0,0x009b9d66b6de56e2,0x00a3c4f45e8004eb)},
{FIELD_LITERAL(0x00d4817c1edc2929,0x00c67cb908be637f,0x00bd6dd1aa6bfe9c,0x00a1803a9fe7795c,0x001770d311e2cefb,0x0018054eca0d1c88,0x004fa667b240f212,0x00f631f7f055a447)},
{FIELD_LITERAL(0x00f89335c2a59286,0x00a0f5c905d55141,0x00b41fb836ee9382,0x00e235d51730ca43,0x00a5cb37b5c0a69a,0x009b966ffe136c45,0x00cb2ea10bf80ed1,0x00fb2b370b40dc35)},
{FIELD_LITERAL(0x0045e8dda9400888,0x002ff12e5fc05db7,0x00a7098d54afe69c,0x00cdbe846a500585,0x00879c1593ca1882,0x003f7a7fea76c8b0,0x002cd73dd0c8e0a1,0x00645d6ce96f51fe)},
{FIELD_LITERAL(0x002b7e83e123d6d6,0x00398346f7419c80,0x0042922e55940163,0x005e7fc5601886a3,0x00e88f2cee1d3103,0x00e7fab135f2e377,0x00b059984dbf0ded,0x0009ce080faa5bb8)},
{FIELD_LITERAL(0x0085e78af7758979,0x00275a4ee1631a3a,0x00d26bc0ed78b683,0x004f8355ea21064f,0x00d618e1a32696e5,0x008d8d7b150e5680,0x00a74cd854b278d2,0x001dd62702203ea0)},
{FIELD_LITERAL(0x0029782e92b11745,0x008eadf422f96200,0x00217a39f2cdcaa2,0x00782d1ca9aefd0b,0x00321c6e47203654,0x001e72961020101a,0x00b562fa6e6ab16e,0x0005c92274af111a)},
{FIELD_LITERAL(0x006bc3d53011f470,0x00032d6e692b83e8,0x00059722f497cd0b,0x0009b4e6f0c497cc,0x0058a804b7cce6c0,0x002b71d3302bbd5d,0x00e2f82a36765fce,0x008dded99524c703)},
{FIELD_LITERAL(0x00f89335c2a59286,0x00a0f5c905d55141,0x00b41fb836ee9382,0x00e235d51730ca43,0x00a5cb37b5c0a69a,0x009b966ffe136c45,0x00cb2ea10bf80ed1,0x00fb2b370b40dc35)},
{FIELD_LITERAL(0x00d687d16d4ee8ba,0x0071520bdd069dff,0x00de85c60d32355d,0x0087d2e3565102f4,0x00cde391b8dfc9aa,0x00e18d69efdfefe5,0x004a9d0591954e91,0x00fa36dd8b50eee5)},
{FIELD_LITERAL(0x002e788749a865f7,0x006e4dc3116861ea,0x009f1428c37276e6,0x00e7d2e0fc1e1226,0x003aeebc6b6c45f6,0x0071a8073bf500c9,0x004b22ad986b530c,0x00f439e63c0d79d4)},
{FIELD_LITERAL(0x00b2fa76ac8b829b,0x008fe6bf01865590,0x0059df538e389f40,0x006acd49eeea748a,0x00ab81280b990cfe,0x00c34a54ac57bfe5,0x003889ce9731cedf,0x0081b71cc1b4654d)},
{FIELD_LITERAL(0x002f194eaafa46dc,0x008e38f57fe87613,0x00dc8e5ae25f4ab2,0x000a17809575e6bd,0x00d3ec7923ba366a,0x003a7e72e0ad75e3,0x0010024b88436e0a,0x00ed3c5444b64051)},
{FIELD_LITERAL(0x006bc3d53011f470,0x00032d6e692b83e8,0x00059722f497cd0b,0x0009b4e6f0c497cc,0x0058a804b7cce6c0,0x002b71d3302bbd5d,0x00e2f82a36765fce,0x008dded99524c703)},
{FIELD_LITERAL(0x004d058953747d64,0x00701940fe79aa6f,0x00a620ac71c760bf,0x009532b611158b75,0x00547ed7f466f300,0x003cb5ab53a8401a,0x00c7763168ce3120,0x007e48e33e4b9ab2)},
{FIELD_LITERAL(0x001b2fc57bf3c738,0x006a3f918993fb80,0x0026f7a14fdec288,0x0075a2cdccef08db,0x00d3ecbc9eecdbf1,0x0048c40f06e5bf7f,0x00d63e423009896b,0x000598bc99c056a8)},
{FIELD_LITERAL(0x007ce03ecbf50cbd,0x00369ba996b992ca,0x00896d4b33a5f7f0,0x00602b5b8536da60,0x00e1122082ba6d73,0x00c3fbb903ba0d74,0x00d3f8ec55c1daf8,0x006a8f96ca0f0be1)},
{FIELD_LITERAL(0x001fb73475c45509,0x00d2b2e5ea43345a,0x00cb3c3842077bd1,0x0029f90ad820946e,0x007c11b2380778aa,0x009e54ece62c1704,0x004bc60c41ca01c3,0x004525679a5a0b03)},
{FIELD_LITERAL(0x002f194eaafa46dc,0x008e38f57fe87613,0x00dc8e5ae25f4ab2,0x000a17809575e6bd,0x00d3ec7923ba366a,0x003a7e72e0ad75e3,0x0010024b88436e0a,0x00ed3c5444b64051)},
{FIELD_LITERAL(0x00831fc1340af342,0x00c9645669466d35,0x007692b4cc5a080f,0x009fd4a47ac9259f,0x001eeddf7d45928b,0x003c0446fc45f28b,0x002c0713aa3e2507,0x0095706935f0f41e)},
{FIELD_LITERAL(0x00766ae4190ec6d8,0x0065768cabc71380,0x00b902598416cdc2,0x00380021ad38df52,0x008f0b89d6551134,0x004254d4cc62c5a5,0x000d79f4484b9b94,0x00b516732ae3c50e)},
{FIELD_LITERAL(0x0039b0422412784c,0x00bf9fe2ee8ce055,0x0063ddb8a4906298,0x00db48625178a0ea,0x009e9012c0fd3c4e,0x00ff30c60950d2c4,0x003b9453f5565977,0x0054dc1d7ff25dfb)},
{FIELD_LITERAL(0x0017085f4a346148,0x00c7cf7a37f62272,0x001776e129bc5c30,0x009955134c9eef2a,0x001ba5bdf1df07be,0x00ec39497103a55c,0x006578354fda6cfb,0x005f02719d4f15ee)},
{FIELD_LITERAL(0x001fb73475c45509,0x00d2b2e5ea43345a,0x00cb3c3842077bd1,0x0029f90ad820946e,0x007c11b2380778aa,0x009e54ece62c1704,0x004bc60c41ca01c3,0x004525679a5a0b03)},
{FIELD_LITERAL(0x00c64fbddbed87b3,0x0040601d11731faa,0x009c22475b6f9d67,0x0024b79dae875f15,0x00616fed3f02c3b0,0x0000cf39f6af2d3b,0x00c46bac0aa9a688,0x00ab23e2800da204)},
{FIELD_LITERAL(0x000b3a37617632b0,0x00597199fe1cfb6c,0x0042a7ccdfeafdd6,0x004cc9f15ebcea17,0x00f436e596a6b4a4,0x00168861142df0d8,0x000753edfec26af5,0x000c495d7e388116)},
{FIELD_LITERAL(0x00ad46264a269aa2,0x002b13845e4b9e3c,0x0006a20b68b0d7f4,0x00c271a35ee514ae,0x002b67e14a58f4d8,0x00f5065b099a60d6,0x00ba6737b90514bc,0x00b6265e7c5b898f)},
{FIELD_LITERAL(0x00b60167d9e7d065,0x00e60ba0d07381e8,0x003a4f17b725c2d4,0x006c19fe176b64fa,0x003b57b31af86ccb,0x0021047c286180fd,0x00bdc8fb00c6dbb6,0x00fe4a9f4bab4f3f)},
{FIELD_LITERAL(0x0017085f4a346148,0x00c7cf7a37f62272,0x001776e129bc5c30,0x009955134c9eef2a,0x001ba5bdf1df07be,0x00ec39497103a55c,0x006578354fda6cfb,0x005f02719d4f15ee)},
{FIELD_LITERAL(0x0052b9d9b5d9655d,0x00d4ec7ba1b461c3,0x00f95df4974f280b,0x003d8e5ca11aeb51,0x00d4981eb5a70b26,0x000af9a4f6659f29,0x004598c846faeb43,0x0049d9a183a47670)},
{FIELD_LITERAL(0x000a72d23dcb3f1f,0x00a3737f84011727,0x00f870c0fbbf4a47,0x00a7aadd04b5c9ca,0x000c7715c67bd072,0x00015a136afcd74e,0x0080d5caea499634,0x0026b448ec7514b7)},
{FIELD_LITERAL(0x0077003c5e9eee08,0x006eaa1bdba2f437,0x007ae297ddfa8d2a,0x00aa8531e1aeb2d6,0x00ce283cc626efdc,0x00efe2f51d153115,0x00db954c07c84995,0x002ade92c7e00acf)},
{FIELD_LITERAL(0x00a6295218dc136a,0x00563b3af0e9c012,0x00d3753b0145db1b,0x004550389c043dc1,0x00ea94ae27401bdf,0x002b0b949f2b7956,0x00c63f780ad8e23c,0x00e591c47d6bab15)},
{FIELD_LITERAL(0x00b60167d9e7d065,0x00e60ba0d07381e8,0x003a4f17b725c2d4,0x006c19fe176b64fa,0x003b57b31af86ccb,0x0021047c286180fd,0x00bdc8fb00c6dbb6,0x00fe4a9f4bab4f3f)},
{FIELD_LITERAL(0x0088ffc3a16111f7,0x009155e4245d0bc8,0x00851d68220572d5,0x00557ace1e514d29,0x0031d7c339d91022,0x00101d0ae2eaceea,0x00246ab3f837b66a,0x00d5216d381ff530)},
{FIELD_LITERAL(0x0057e7ea35f36dae,0x00f47d7ad15de22e,0x00d757ea4b105115,0x008311457d579d7e,0x00b49b75b1edd4eb,0x0081c7ff742fd63a,0x00ddda3187433df6,0x00475727d55f9c66)},
{FIELD_LITERAL(0x00be93a7d4fa7149,0x00bef825a4d3396a,0x004c32daa951139b,0x003f4be7d981a85e,0x00e866d6ca8642d0,0x00b912bba6f1b2f8,0x00e28ba64c9cf5e1,0x0039504574996955)},
{FIELD_LITERAL(0x002419222c607674,0x00a7f23af89188b3,0x00ad127284e73d1c,0x008bba582fae1c51,0x00fc6aa7ca9ecab1,0x003df5319eb6c2ba,0x002a05af8a8b199a,0x004bf8354558407c)},
{FIELD_LITERAL(0x00a6295218dc136a,0x00563b3af0e9c012,0x00d3753b0145db1b,0x004550389c043dc1,0x00ea94ae27401bdf,0x002b0b949f2b7956,0x00c63f780ad8e23c,0x00e591c47d6bab15)},
{FIELD_LITERAL(0x00416c582b058eb6,0x004107da5b2cc695,0x00b3cd2556aeec64,0x00c0b418267e57a1,0x001799293579bd2e,0x0046ed44590e4d07,0x001d7459b3630a1e,0x00c6afba8b6696aa)},
{FIELD_LITERAL(0x008d6009b26da3f8,0x00898e88ca06b1ca,0x00edb22b2ed7fe62,0x00fbc93516aabe80,0x008b4b470c42ce0d,0x00e0032ba7d0dcbb,0x00d76da3a956ecc8,0x007f20fe74e3852a)},
{FIELD_LITERAL(0x003182b5cf0f0340,0x002fd3d8d9d60fc2,0x00b73ffe08bff43d,0x00d3dec97fee6a72,0x00675aafc6e16949,0x00d27f499c6f0c86,0x00e0578789f3387a,0x00e52031ab49ec2a)},
{FIELD_LITERAL(0x006b7a0674f9f8de,0x00a742414e5c7cff,0x0041cbf3c6e13221,0x00e3a64fd207af24,0x0087c05f15fbe8d1,0x004c50936d9e8a33,0x001306ec21042b6d,0x00a4f4137d1141c2)},
{FIELD_LITERAL(0x002419222c607674,0x00a7f23af89188b3,0x00ad127284e73d1c,0x008bba582fae1c51,0x00fc6aa7ca9ecab1,0x003df5319eb6c2ba,0x002a05af8a8b199a,0x004bf8354558407c)},
{FIELD_LITERAL(0x00ce7d4a30f0fcbf,0x00d02c272629f03d,0x0048c001f7400bc2,0x002c21368011958d,0x0098a550391e96b5,0x002d80b66390f379,0x001fa878760cc785,0x001adfce54b613d5)},
{FIELD_LITERAL(0x001ed4dc71fa2523,0x005d0bff19bf9b5c,0x00c3801cee065a64,0x001ed0b504323fbf,0x0003ab9fdcbbc593,0x00df82070178b8d2,0x00a2bcaa9c251f85,0x00c628a3674bd02e)},
{FIELD_LITERAL(0x00f619046dea974f,0x004c39fedfde6ee7,0x00d593cb9f22afc5,0x00624e10ee9ab4ab,0x009c1b40f41869fd,0x0098f2cb44da6d46,0x002311d093becf31,0x004d97d1771880ab)},
{FIELD_LITERAL(0x00ddbe0750dd1add,0x004b3c7b885844b8,0x00363e7ecf12f1ae,0x0062e953e6438f9d,0x0023cc73b076afe9,0x00b09fa083b4da32,0x00c7c3d2456c541d,0x005b591ec6b694d4)},
{FIELD_LITERAL(0x006b7a0674f9f8de,0x00a742414e5c7cff,0x0041cbf3c6e13221,0x00e3a64fd207af24,0x0087c05f15fbe8d1,0x004c50936d9e8a33,0x001306ec21042b6d,0x00a4f4137d1141c2)},
{FIELD_LITERAL(0x0009e6fb921568b0,0x00b3c60120219118,0x002a6c3460dd503a,0x009db1ef11654b54,0x0063e4bf0be79601,0x00670d34bb2592b9,0x00dcee2f6c4130ce,0x00b2682e88e77f54)},
{FIELD_LITERAL(0x000d5b4b3da135ab,0x00838f3e5064d81d,0x00d44eb50f6d94ed,0x0008931ab502ac6d,0x00debe01ca3d3586,0x0025c206775f0641,0x005ad4b6ae912763,0x007e2c318ad8f247)},
{FIELD_LITERAL(0x00d79a91e629d030,0x00ad5b50fc20eb72,0x00edd89a222eb1bd,0x000ddad6fb098ea8,0x00b8be69a49c90c4,0x009bbe2d69ecd346,0x00a1def906a95a48,0x00db8fd6a6d2cca3)},
{FIELD_LITERAL(0x00c41d1f9c1f1ac1,0x007b2df4e9f19146,0x00b469355fd5ba7a,0x00b5e1965afc852a,0x00388d5f1e2d8217,0x0022079e4c09ae93,0x0014268acd4ef518,0x00c1dd8d9640464c)},
{FIELD_LITERAL(0x00ddbe0750dd1add,0x004b3c7b885844b8,0x00363e7ecf12f1ae,0x0062e953e6438f9d,0x0023cc73b076afe9,0x00b09fa083b4da32,0x00c7c3d2456c541d,0x005b591ec6b694d4)},
{FIELD_LITERAL(0x0028656e19d62fcf,0x0052a4af03df148d,0x00122765ddd14e42,0x00f2252904f67157,0x004741965b636f3a,0x006441d296132cb9,0x005e2106f956a5b7,0x00247029592d335c)},
{FIELD_LITERAL(0x003fe038eb92f894,0x000e6da1b72e8e32,0x003a1411bfcbe0fa,0x00b55d473164a9e4,0x00b9a775ac2df48d,0x0002ddf350659e21,0x00a279a69eb19cb3,0x00f844eab25cba44)},
{FIELD_LITERAL(0x00c7ad952112f3aa,0x00229739f81c017a,0x0008b9222b75a2a8,0x00bd0d6ad469c483,0x00e344297892a13c,0x00a1cbeb8f435a3d,0x0078e2be1f7a0bec,0x001ac54f670ba8cd)},
{FIELD_LITERAL(0x00adb2c1566e8b8f,0x0096c68a35771a9a,0x00869933356f334a,0x00ba9c93459f5962,0x009ec73fb6e8ca4b,0x003c3802c27202e1,0x0031f5b733e0c008,0x00f9058c19611fa9)},
{FIELD_LITERAL(0x00c41d1f9c1f1ac1,0x007b2df4e9f19146,0x00b469355fd5ba7a,0x00b5e1965afc852a,0x00388d5f1e2d8217,0x0022079e4c09ae93,0x0014268acd4ef518,0x00c1dd8d9640464c)},
{FIELD_LITERAL(0x0038526adeed0c55,0x00dd68c607e3fe85,0x00f746ddd48a5d57,0x0042f2952b963b7c,0x001cbbd6876d5ec2,0x005e341470bca5c2,0x00871d41e085f413,0x00e53ab098f45732)},
{FIELD_LITERAL(0x004d51124797c831,0x008f5ae3750347ad,0x0070ced94c1a0c8e,0x00f6db2043898e64,0x000d00c9a5750cd0,0x000741ec59bad712,0x003c9d11aab37b7f,0x00a67ba169807714)},
{FIELD_LITERAL(0x00dc70fe7eb5cbde,0x003cda5bb49331d7,0x00dec9068514f18c,0x00f3537d975b501d,0x00dd02de725b8e4b,0x0062327200072106,0x0034607e7e266644,0x00ebc51a91215cb6)},
{FIELD_LITERAL(0x00a5187e6ee7341b,0x00e6d52e82d83b6e,0x00df3c41323094a7,0x00b3324f444e9de9,0x00689eb21a35bfe5,0x00f16363becd548d,0x00e187cc98e7f60f,0x00127d9062f0ccab)},
{FIELD_LITERAL(0x00adb2c1566e8b8f,0x0096c68a35771a9a,0x00869933356f334a,0x00ba9c93459f5962,0x009ec73fb6e8ca4b,0x003c3802c27202e1,0x0031f5b733e0c008,0x00f9058c19611fa9)},
{FIELD_LITERAL(0x00238f01814a3421,0x00c325a44b6cce28,0x002136f97aeb0e73,0x000cac8268a4afe2,0x0022fd218da471b3,0x009dcd8dfff8def9,0x00cb9f8181d999bb,0x00143ae56edea349)},
{FIELD_LITERAL(0x0000623bf87622c5,0x00a1966fdd069496,0x00c315b7b812f9fc,0x00bdf5efcd128b97,0x001d464f532e3e16,0x003cd94f081bfd7e,0x00ed9dae12ce4009,0x002756f5736eee70)},
{FIELD_LITERAL(0x00b528e4ce3d61bf,0x005a03531ed051d6,0x00bbda4aa68d7f12,0x001810a28e93ccb9,0x00ef4ac525bef536,0x006dcefdd9f9f364,0x006e3d9ed78d6381,0x00774bd6ff0713c4)},
{FIELD_LITERAL(0x00c13c5aae3ae341,0x009c6c9ed98373e7,0x00098f26864577a8,0x0015b886e9488b45,0x0037692c42aadba5,0x00b83170b8e7791c,0x001670952ece1b44,0x00fd932a39276da2)},
{FIELD_LITERAL(0x00a5187e6ee7341b,0x00e6d52e82d83b6e,0x00df3c41323094a7,0x00b3324f444e9de9,0x00689eb21a35bfe5,0x00f16363becd548d,0x00e187cc98e7f60f,0x00127d9062f0ccab)},
{FIELD_LITERAL(0x004ad71b31c29e40,0x00a5fcace12fae29,0x004425b5597280ed,0x00e7ef5d716c3346,0x0010b53ada410ac8,0x0092310226060c9b,0x0091c26128729c7e,0x0088b42900f8ec3b)},
{FIELD_LITERAL(0x00f1e26e9762d4a8,0x00d9d74082183414,0x00ffec9bd57a0282,0x000919e128fd497a,0x00ab7ae7d00fe5f8,0x0054dc442851ff68,0x00c9ebeb3b861687,0x00507f7cab8b698f)},
{FIELD_LITERAL(0x007e5cda6410cc67,0x00ab7f000be9ef84,0x0031b09f82de4167,0x00c003f7b4be2064,0x00bc2f44effafd2d,0x0013ca0a8a45cd9e,0x0035e70988cff10c,0x001744f57d827ab7)},
{FIELD_LITERAL(0x009ae3b93a56c404,0x004a410b7a456699,0x00023a619355e6b2,0x009cdc7297387257,0x0055b94d4ae70d04,0x002cbd607f65b005,0x003208b489697166,0x00ea2aa058867370)},
{FIELD_LITERAL(0x00c13c5aae3ae341,0x009c6c9ed98373e7,0x00098f26864577a8,0x0015b886e9488b45,0x0037692c42aadba5,0x00b83170b8e7791c,0x001670952ece1b44,0x00fd932a39276da2)},
{FIELD_LITERAL(0x0081a3259bef3398,0x005480fff416107b,0x00ce4f607d21be98,0x003ffc084b41df9b,0x0043d0bb100502d1,0x00ec35f575ba3261,0x00ca18f677300ef3,0x00e8bb0a827d8548)},
{FIELD_LITERAL(0x00df76b3328ada72,0x002e20621604a7c2,0x00f910638a105b09,0x00ef4724d96ef2cd,0x00377d83d6b8a2f7,0x00b4f48805ade324,0x001cd5da8b152018,0x0045af671a20ca7f)},
{FIELD_LITERAL(0x000d62da6711c0cd,0x004b53ac7a27d523,0x0089cc150fb20e64,0x0055d2c2883154fe,0x00b5dcfd03448874,0x006d80dda2a505cb,0x00b57162afb80dc8,0x007ddb5162431acf)},
{FIELD_LITERAL(0x00c845923c084294,0x00072419a201bc25,0x0045f408b5f8e669,0x00e9d6a186b74dfe,0x00e19108c68fa075,0x0017b91d874177b7,0x002f0ca2c7912c5a,0x009400aa385a90a2)},
{FIELD_LITERAL(0x009ae3b93a56c404,0x004a410b7a456699,0x00023a619355e6b2,0x009cdc7297387257,0x0055b94d4ae70d04,0x002cbd607f65b005,0x003208b489697166,0x00ea2aa058867370)},
{FIELD_LITERAL(0x00f29d2598ee3f32,0x00b4ac5385d82adc,0x007633eaf04df19b,0x00aa2d3d77ceab01,0x004a2302fcbb778a,0x00927f225d5afa34,0x004a8e9d5047f237,0x008224ae9dbce530)},
{FIELD_LITERAL(0x001cf640859b02f8,0x00758d1d5d5ce427,0x00763c784ef4604c,0x005fa81aee205270,0x00ac537bfdfc44cb,0x004b919bd342d670,0x00238508d9bf4b7a,0x00154888795644f3)},
{FIELD_LITERAL(0x008eeef4feb7de7b,0x003012ffbb0d4107,0x00cb0d6fe30b99d1,0x00c4b51d598067cb,0x003356469016b7ee,0x00addaf85188542f,0x004538bdd8de18c1,0x00999dd4f0c59d4f)},
{FIELD_LITERAL(0x0026ef1614e160af,0x00c023f9edfc9c76,0x00cff090da5f57ba,0x0076db7a66643ae9,0x0019462f8c646999,0x008fec00b3854b22,0x00d55041692a0a1c,0x0065db894215ca00)},
{FIELD_LITERAL(0x00c845923c084294,0x00072419a201bc25,0x0045f408b5f8e669,0x00e9d6a186b74dfe,0x00e19108c68fa075,0x0017b91d874177b7,0x002f0ca2c7912c5a,0x009400aa385a90a2)},
{FIELD_LITERAL(0x0071110b01482184,0x00cfed0044f2bef8,0x0034f2901cf4662e,0x003b4ae2a67f9834,0x00cca9b96fe94810,0x00522507ae77abd0,0x00bac7422721e73e,0x0066622b0f3a62b0)},
{FIELD_LITERAL(0x00f8ac5cf4705b6a,0x00867d82dcb457e3,0x007e13ab2ccc2ce9,0x009ee9a018d3930e,0x008370f8ecb42df8,0x002d9f019add263e,0x003302385b92d196,0x00a15654536e2c0c)},
{FIELD_LITERAL(0x0056dafc91f5bae3,0x00d5fc6f3c94933e,0x000d8fdf26f76b0b,0x00726f2ad342c280,0x001e2fec8c6d0c46,0x000fe83ea74ae570,0x00353cec2c128243,0x0046657e1c14bd2c)},
{FIELD_LITERAL(0x008cc9cd236315c0,0x0031d9c5b39fda54,0x00a5713ef37e1171,0x00293d5ae2886325,0x00c4aba3e05015e1,0x0003f35ef78e4fc6,0x0039d6bd3ac1527b,0x0019d7c3afb77106)},
{FIELD_LITERAL(0x0026ef1614e160af,0x00c023f9edfc9c76,0x00cff090da5f57ba,0x0076db7a66643ae9,0x0019462f8c646999,0x008fec00b3854b22,0x00d55041692a0a1c,0x0065db894215ca00)},
{FIELD_LITERAL(0x00a925036e0a451c,0x002a0390c36b6cc1,0x00f27020d90894f4,0x008d90d52cbd3d7f,0x00e1d0137392f3b8,0x00f017c158b51a8f,0x00cac313d3ed7dbc,0x00b99a81e3eb42d3)},
{FIELD_LITERAL(0x00b54850275fe626,0x0053a3fd1ec71140,0x00e3d2d7dbe096fa,0x00e4ac7b595cce4c,0x0077bad449c0a494,0x00b7c98814afd5b3,0x0057226f58486cf9,0x00b1557154f0cc57)},
{FIELD_LITERAL(0x0084e9d6ce567a50,0x0052bf5d1f2558ec,0x00920d83bff60ee7,0x00afc160b1d17413,0x008ae58837d3e7d1,0x00fd676c8896dba4,0x00004e170540611a,0x00f7ccb8f91f6541)},
{FIELD_LITERAL(0x004246bfcecc627a,0x004ba431246c03a4,0x00bd1d101872d497,0x003b73d3f185ee16,0x001feb2e2678c0e3,0x00ff13c5a89dec76,0x00ed06042e771d8f,0x00a4fd2a897a83dd)},
{FIELD_LITERAL(0x008cc9cd236315c0,0x0031d9c5b39fda54,0x00a5713ef37e1171,0x00293d5ae2886325,0x00c4aba3e05015e1,0x0003f35ef78e4fc6,0x0039d6bd3ac1527b,0x0019d7c3afb77106)},
{FIELD_LITERAL(0x007b162931a985af,0x00ad40a2e0daa713,0x006df27c4009f118,0x00503e9f4e2e8bec,0x00751a77c82c182d,0x000298937769245b,0x00ffb1e8fabf9ee5,0x0008334706e09abe)},
{FIELD_LITERAL(0x00dbca4e98a7dcd9,0x00ee29cfc78bde99,0x00e4a3b6995f52e9,0x0045d70189ae8096,0x00fd2a8a3b9b0d1b,0x00af1793b107d8e1,0x00dbf92cbe4afa20,0x00da60f798e3681d)},
{FIELD_LITERAL(0x0065b5c41af29a68,0x0021ce9a03a5ef69,0x00b0c0a91cba4f38,0x0008408de2a54743,0x00bcec1b84f673ae,0x001b382a3f1e5244,0x00d1c1c24c9afae1,0x005b7f3d32956904)},
{FIELD_LITERAL(0x004ede34af2813f3,0x00d4a8e11c9e8216,0x004796d5041de8a5,0x00c4c6b4d21cc987,0x00e8a433ee07fa1e,0x0055720b5abcc5a1,0x008873ea9c74b080,0x005b3fec1ab65d48)},
{FIELD_LITERAL(0x004246bfcecc627a,0x004ba431246c03a4,0x00bd1d101872d497,0x003b73d3f185ee16,0x001feb2e2678c0e3,0x00ff13c5a89dec76,0x00ed06042e771d8f,0x00a4fd2a897a83dd)},
{FIELD_LITERAL(0x009a4a3be50d6597,0x00de3165fc5a1096,0x004f3f56e345b0c7,0x00f7bf721d5ab8bc,0x004313e47b098c50,0x00e4c7d5c0e1adbb,0x002e3e3db365051e,0x00a480c2cd6a96fb)},
{FIELD_LITERAL(0x00417fa30a7119ed,0x00af257758419751,0x00d358a487b463d4,0x0089703cc720b00d,0x00ce56314ff7f271,0x0064db171ade62c1,0x00640b36d4a22fed,0x00424eb88696d23f)},
{FIELD_LITERAL(0x00b81ad88248f13a,0x00f5f69399248294,0x004be9b33e8cfea6,0x00b56087c018df01,0x0057e8846bbb6242,0x006a5db00b65a660,0x00963e3a87daf343,0x00badfe6dec2140b)},
{FIELD_LITERAL(0x001bd59c09e982ea,0x00f72daeb937b289,0x0018b76dca908e0e,0x00edb498512384ad,0x00ce0243b6cc9538,0x00f96ff690cb4e70,0x007c77bf9f673c8d,0x005bf704c088a528)},
{FIELD_LITERAL(0x004ede34af2813f3,0x00d4a8e11c9e8216,0x004796d5041de8a5,0x00c4c6b4d21cc987,0x00e8a433ee07fa1e,0x0055720b5abcc5a1,0x008873ea9c74b080,0x005b3fec1ab65d48)},
{FIELD_LITERAL(0x0047e5277db70ec5,0x000a096c66db7d6b,0x00b4164cc1730159,0x004a9f783fe720fe,0x00a8177b94449dbc,0x0095a24ff49a599f,0x0069c1c578250cbc,0x00452019213debf4)},
{FIELD_LITERAL(0x0021ce99e09ebda3,0x00fcbd9f91875ad0,0x009bbf6b7b7a0b5f,0x00388886a69b1940,0x00926a56d0f81f12,0x00e12903c3358d46,0x005dfce4e8e1ce9d,0x0044cfa94e2f7e23)},
{FIELD_LITERAL(0x006c2b9d7234cc41,0x006ad9c2ae2bda7d,0x00b64cdddba701f9,0x00180318c49ac580,0x00c35d14319f4c95,0x003a21dc65cd415b,0x009c474c28e04940,0x00c65114875e57c6)},
{FIELD_LITERAL(0x00fb22bb5fd3ce50,0x0017b48aada7ae54,0x00fd5c44ad19a536,0x000ccc4e4e55e45c,0x00fd637d45b4c3f5,0x0038914e023c37cf,0x00ac1881d6a8d898,0x00611ed8d3d943a8)},
{FIELD_LITERAL(0x001bd59c09e982ea,0x00f72daeb937b289,0x0018b76dca908e0e,0x00edb498512384ad,0x00ce0243b6cc9538,0x00f96ff690cb4e70,0x007c77bf9f673c8d,0x005bf704c088a528)},
{FIELD_LITERAL(0x0093d4628dcb33be,0x0095263d51d42582,0x0049b3222458fe06,0x00e7fce73b653a7f,0x003ca2ebce60b369,0x00c5de239a32bea4,0x0063b8b3d71fb6bf,0x0039aeeb78a1a839)},
{FIELD_LITERAL(0x007dc52da400336c,0x001fded1e15b9457,0x00902e00f5568e3a,0x00219bef40456d2d,0x005684161fb3dbc9,0x004a4e9be49a76ea,0x006e685ae88b78ff,0x0021c42f13042d3c)},
{FIELD_LITERAL(0x00a91dda62eec2d4,0x00a6b7e64d7b13e9,0x00384086b44c9969,0x008de118af683239,0x0008e416fb85d76c,0x0020945ebda9b120,0x0096a7f485e7b172,0x000fa91c7035f011)},
{FIELD_LITERAL(0x005e8694077a1535,0x008bef75f71c8f1d,0x000a7c1316423511,0x00906e1d70604320,0x003fc46c1a2ffbd6,0x00d1d5022e68f360,0x002515fba37bbf46,0x00ca16234e023b44)},
{FIELD_LITERAL(0x00fb22bb5fd3ce50,0x0017b48aada7ae54,0x00fd5c44ad19a536,0x000ccc4e4e55e45c,0x00fd637d45b4c3f5,0x0038914e023c37cf,0x00ac1881d6a8d898,0x00611ed8d3d943a8)},
{FIELD_LITERAL(0x0056e2259d113d2b,0x00594819b284ec16,0x00c7bf794bb36696,0x00721ee75097cdc6,0x00f71be9047a2892,0x00df6ba142564edf,0x0069580b7a184e8d,0x00f056e38fca0fee)},
{FIELD_LITERAL(0x009df98566a18c6d,0x00cf3a200968f219,0x0044ba60da6d9086,0x00dbc9c0e344da03,0x000f9401c4466855,0x00d46a57c5b0a8d1,0x00875a635d7ac7c6,0x00ef4a933b7e0ae6)},
{FIELD_LITERAL(0x00878366a9e0b96f,0x0057a8573ea9e0d8,0x005ef206ddc3f601,0x0046756a9d1c4eab,0x00bccf478bb3c12c,0x001f97ed7f813a3b,0x001b309582460e1c,0x0026a4f760ecd5cb)},
{FIELD_LITERAL(0x00139078397030bd,0x000e3c447e859a00,0x0064a5b334c82393,0x00b8aabeb7358093,0x00020778bb9ae73b,0x0032ee94c7892a18,0x008215253cb41bda,0x005e2797593517ae)},
{FIELD_LITERAL(0x005e8694077a1535,0x008bef75f71c8f1d,0x000a7c1316423511,0x00906e1d70604320,0x003fc46c1a2ffbd6,0x00d1d5022e68f360,0x002515fba37bbf46,0x00ca16234e023b44)},
{FIELD_LITERAL(0x00787c99561f4690,0x00a857a8c1561f27,0x00a10df9223c09fe,0x00b98a9562e3b154,0x004330b8744c3ed2,0x00e06812807ec5c4,0x00e4cf6a7db9f1e3,0x00d95b089f132a34)},
{FIELD_LITERAL(0x002922b39ca33eec,0x0090d12a5f3ab194,0x00ab60c02fb5f8ed,0x00188d292abba1cf,0x00e10edec9698f6e,0x0069a4d9934133c8,0x0024aac40e6d3d06,0x001702c2177661b0)},
{FIELD_LITERAL(0x007c89a5a07aa2b5,0x00ae492ecae4711d,0x00ee921ab74f0844,0x007842778fc5005f,0x006a4d33cb28022c,0x007b327e4ac0f437,0x007a9d0366acaf12,0x005c6544e6c9ae1c)},
{FIELD_LITERAL(0x0091868594265aa2,0x00797accae98ca6d,0x0008d8c5f0f8a184,0x00d1f4f1c2b2fe6e,0x0036783dfb48a006,0x008c165120503527,0x0025fd780058ce9b,0x0068beb007be7d27)},
{FIELD_LITERAL(0x00139078397030bd,0x000e3c447e859a00,0x0064a5b334c82393,0x00b8aabeb7358093,0x00020778bb9ae73b,0x0032ee94c7892a18,0x008215253cb41bda,0x005e2797593517ae)},
{FIELD_LITERAL(0x0083765a5f855d4a,0x0051b6d1351b8ee2,0x00116de548b0f7bb,0x0087bd88703affa0,0x0095b2cc34d7fdd2,0x0084cd81b53f0bc8,0x008562fc995350ed,0x00a39abb193651e3)},
{FIELD_LITERAL(0x0019e23f0474b114,0x00eb94c2ad3b437e,0x006ddb34683b75ac,0x00391f9209b564c6,0x00083b3bb3bff7aa,0x00eedcd0f6dceefc,0x00b50817f794fe01,0x0036474deaaa75c9)},
{FIELD_LITERAL(0x002f007755836f3d,0x004d39f2530acc6b,0x006b58d7b2699929,0x004126fdd3185e62,0x003aeaac0f32897c,0x003c0478f4edb66d,0x0072f43ac66a9364,0x0003730da744777a)},
{FIELD_LITERAL(0x0045fdc16487cda3,0x00b2d8e844cf2ed7,0x00612c50e88c1607,0x00a08aabc66c1672,0x006031fdcbb24d97,0x001b639525744b93,0x004409d62639ab17,0x00a1853d0347ab1d)},
{FIELD_LITERAL(0x0091868594265aa2,0x00797accae98ca6d,0x0008d8c5f0f8a184,0x00d1f4f1c2b2fe6e,0x0036783dfb48a006,0x008c165120503527,0x0025fd780058ce9b,0x0068beb007be7d27)},
{FIELD_LITERAL(0x00d0ff88aa7c90c2,0x00b2c60dacf53394,0x0094a7284d9666d6,0x00bed9022ce7a19d,0x00c51553f0cd7682,0x00c3fb870b124992,0x008d0bc539956c9b,0x00fc8cf258bb8885)},
{FIELD_LITERAL(0x003667bf998406f8,0x0000115c43a12975,0x001e662f3b20e8fd,0x0019ffa534cb24eb,0x00016be0dc8efb45,0x00ff76a8b26243f5,0x00ae20d241a541e3,0x0069bd6af13cd430)},
{FIELD_LITERAL(0x008a5e5a9140a3de,0x005c18d41653ac12,0x0010321e9d6e8f3d,0x00fbdda016e10aca,0x0077fb6038c20257,0x00b5438b7a81ed77,0x00db1dbcb9a8ce83,0x0026734c2c1aabc3)},
{FIELD_LITERAL(0x007e32c049b5c477,0x009d2bfdbd9bcfd8,0x00636e93045938c6,0x007fde4af7687298,0x0046a5184fafa5d3,0x0079b1e7f13a359b,0x00875adf1fb927d6,0x00333e21c61bcad2)},
{FIELD_LITERAL(0x0045fdc16487cda3,0x00b2d8e844cf2ed7,0x00612c50e88c1607,0x00a08aabc66c1672,0x006031fdcbb24d97,0x001b639525744b93,0x004409d62639ab17,0x00a1853d0347ab1d)},
{FIELD_LITERAL(0x0075a1a56ebf5c21,0x00a3e72be9ac53ed,0x00efcde1629170c2,0x0004225fe91ef535,0x0088049fc73dfda7,0x004abc74857e1288,0x0024e2434657317c,0x00d98cb3d3e5543c)},
{FIELD_LITERAL(0x00b4b53eab6bdb19,0x009b22d8b43711d0,0x00d948b9d961785d,0x00cb167b6f279ead,0x00191de3a678e1c9,0x00d9dd9511095c2e,0x00f284324cd43067,0x00ed74fa535151dd)},
{FIELD_LITERAL(0x00fb7feb08c27472,0x008a97b55f699c77,0x006d41820f923b83,0x006831432f0aa975,0x00a58ffb263b3955,0x004f13449a66db38,0x0026fccd22b6d583,0x00a803eb20eeb6c2)},
{FIELD_LITERAL(0x007df6cbb926830b,0x00d336058ae37865,0x007af47dac696423,0x0048d3011ec64ac8,0x006b87666e40049f,0x0036a2e0e51303d7,0x00ba319bd79dbc55,0x003e2737ecc94f53)},
{FIELD_LITERAL(0x007e32c049b5c477,0x009d2bfdbd9bcfd8,0x00636e93045938c6,0x007fde4af7687298,0x0046a5184fafa5d3,0x0079b1e7f13a359b,0x00875adf1fb927d6,0x00333e21c61bcad2)},
{FIELD_LITERAL(0x00048014f73d8b8d,0x0075684aa0966388,0x0092be7df06dc47c,0x0097cebcd0f5568a,0x005a7004d9c4c6a9,0x00b0ecbb659924c7,0x00d90332dd492a7c,0x0057fc14df11493d)},
{FIELD_LITERAL(0x0008ed8ea0ad95be,0x0041d324b9709645,0x00e25412257a19b4,0x0058df9f3423d8d2,0x00a9ab20def71304,0x009ae0dbf8ac4a81,0x00c9565977e4392a,0x003c9269444baf55)},
{FIELD_LITERAL(0x002d69008d9d8d26,0x00092f686d7030a8,0x001f19e95aa28fec,0x002150bab1261538,0x008c5a941210b26c,0x009330209036d1e6,0x0062e11ec8e58de7,0x0011c3d11bb9d27f)},
{FIELD_LITERAL(0x008132ae5c5d8cd1,0x00121d68324a1d9f,0x00d6be9dafcb8c76,0x00684d9070edf745,0x00519fbc96d7448e,0x00388182fdc1f27e,0x000235baed41f158,0x00bf6cf6f1a1796a)},
{FIELD_LITERAL(0x007df6cbb926830b,0x00d336058ae37865,0x007af47dac696423,0x0048d3011ec64ac8,0x006b87666e40049f,0x0036a2e0e51303d7,0x00ba319bd79dbc55,0x003e2737ecc94f53)},
{FIELD_LITERAL(0x00d296ff726272d9,0x00f6d097928fcf57,0x00e0e616a55d7013,0x00deaf454ed9eac7,0x0073a56bedef4d92,0x006ccfdf6fc92e19,0x009d1ee1371a7218,0x00ee3c2ee4462d80)},
{FIELD_LITERAL(0x00437bce9bccdf9d,0x00e0c8e2f85dc0a3,0x00c91a7073995a19,0x00856ec9fe294559,0x009e4b33394b156e,0x00e245b0dc497e5c,0x006a54e687eeaeff,0x00f1cd1cd00fdb7c)},
{FIELD_LITERAL(0x00d523b4b2eb7de6,0x00cf7b525f2c56f5,0x00b9217554f0d1b1,0x00bad2cbd5984a02,0x002b4af0fe2b21dd,0x002492603f310486,0x0073e7b3795b9d32,0x001e837c89b2bd25)},
{FIELD_LITERAL(0x00ce382dc7993d92,0x00021153e938b4c8,0x00096f7567f48f51,0x0058f81ddfe4b0d5,0x00cc379a56b355c7,0x002c760770d3e819,0x00ee22d1d26e5a40,0x00de6d93d5b082d7)},
{FIELD_LITERAL(0x008132ae5c5d8cd1,0x00121d68324a1d9f,0x00d6be9dafcb8c76,0x00684d9070edf745,0x00519fbc96d7448e,0x00388182fdc1f27e,0x000235baed41f158,0x00bf6cf6f1a1796a)},
{FIELD_LITERAL(0x002adc4b4d148219,0x003084ada0d3a90a,0x0046de8aab0f2e4e,0x00452d342a67b5fd,0x00d4b50f01d4de21,0x00db6d9fc0cefb79,0x008c184c86a462cd,0x00e17c83764d42da)},
{FIELD_LITERAL(0x007b2743b9a1e01a,0x007847ffd42688c4,0x006c7844d610a316,0x00f0cb8b250aa4b0,0x00a19060143b3ae6,0x0014eb10b77cfd80,0x000170905729dd06,0x00063b5b9cd72477)},
{FIELD_LITERAL(0x00f56e5bd3ad1fa9,0x00e7a09488031815,0x00f7fc3ae69d094a,0x00ddad7a7d45a9c2,0x00bc07fbf167a928,0x007a5d6137e0479f,0x00a0659eeab60a00,0x003e068b1342b4f9)},
{FIELD_LITERAL(0x00ffc5c89d2b0cba,0x00d363d42e3e6fc3,0x0019a1a0118e2e8a,0x00f7baeff48882e1,0x001bd5af28c6b514,0x0055476ca2253cb2,0x00d8eb1977e2ddf3,0x00b173b1adb228a1)},
{FIELD_LITERAL(0x00ce382dc7993d92,0x00021153e938b4c8,0x00096f7567f48f51,0x0058f81ddfe4b0d5,0x00cc379a56b355c7,0x002c760770d3e819,0x00ee22d1d26e5a40,0x00de6d93d5b082d7)},
{FIELD_LITERAL(0x000a91a42c52e056,0x00185f6b77fce7ea,0x000803c51962f6b5,0x0022528582ba563d,0x0043f8040e9856d6,0x0085a29ec81fb860,0x005f9a611549f5ff,0x00c1f974ecbd4b06)},
{FIELD_LITERAL(0x005b64c6fd65ec97,0x00c1fdd7f877bc7f,0x000d9cc6c89f841c,0x005c97b7f1aff9ad,0x0075e3c61475d47e,0x001ecb1ba8153011,0x00fe7f1c8d71d40d,0x003fa9757a229832)},
{FIELD_LITERAL(0x000d346622f528f8,0x001e1f7497a62227,0x00fff70d2f9af433,0x002812c6d079ea3c,0x006898af56b25d7f,0x00c17c44f1349645,0x00207172ea3eb539,0x000608e8bd6a263d)},
{FIELD_LITERAL(0x002389319450f9ba,0x003677f31aa1250a,0x0092c3db642f38cb,0x00f8b64c0dfc9773,0x00cd49fe3505b795,0x0068105a4090a510,0x00df0ba2072a8bb6,0x00eb396143afd8be)},
{FIELD_LITERAL(0x00ffc5c89d2b0cba,0x00d363d42e3e6fc3,0x0019a1a0118e2e8a,0x00f7baeff48882e1,0x001bd5af28c6b514,0x0055476ca2253cb2,0x00d8eb1977e2ddf3,0x00b173b1adb228a1)},
{FIELD_LITERAL(0x00f2cb99dd0ad707,0x00e1e08b6859ddd8,0x000008f2d0650bcc,0x00d7ed392f8615c3,0x00976750a94da27f,0x003e83bb0ecb69ba,0x00df8e8d15c14ac6,0x00f9f7174295d9c2)},
{FIELD_LITERAL(0x00f11cc8e0e70bcb,0x00e5dc689974e7dd,0x0014e409f9ee5870,0x00826e6689acbd63,0x008a6f4e3d895d88,0x00b26a8da41fd4ad,0x000fb7723f83efd7,0x009c749db0a5f6c3)},
{FIELD_LITERAL(0x005f2b1304db3200,0x0022507ff7459b86,0x000f4c1c92b4f0bb,0x00c8cb42c50e0eb9,0x004781d1038aad80,0x002dcf20aa2254af,0x00d9ecda851a93e2,0x0043f6b92eca6cb2)},
{FIELD_LITERAL(0x0067f8f0c4fe26c9,0x0079c4a3cc8f67b9,0x0082b1e62f23550d,0x00f2d409caefd7f5,0x0080e67dcdb26e81,0x0087ae993ea1f98a,0x00aa108becf61d03,0x001acf11efb608a3)},
{FIELD_LITERAL(0x002389319450f9ba,0x003677f31aa1250a,0x0092c3db642f38cb,0x00f8b64c0dfc9773,0x00cd49fe3505b795,0x0068105a4090a510,0x00df0ba2072a8bb6,0x00eb396143afd8be)},
{FIELD_LITERAL(0x00a0d4ecfb24cdff,0x00ddaf8008ba6479,0x00f0b3e36d4b0f44,0x003734bd3af1f146,0x00b87e2efc75527e,0x00d230df55ddab50,0x002613257ae56c1d,0x00bc0946d135934d)},
{FIELD_LITERAL(0x00468711bd994651,0x0033108fa67561bf,0x0089d760192a54b4,0x00adc433de9f1871,0x000467d05f36e050,0x007847e0f0579f7f,0x00a2314ad320052d,0x00b3a93649f0b243)},
{FIELD_LITERAL(0x007dda014454af26,0x000c49fa1b22df7c,0x005cd4d7e761dc2d,0x002af81a1a14b368,0x00a5e57b1cfd7ddf,0x00f90ab3e3a0f738,0x005cb83734d7bc0f,0x00f608c16abb405a)},
{FIELD_LITERAL(0x00e828333c297f8b,0x009ef3cf8c3f7e1f,0x00ab45f8fff31cb9,0x00c8b4178cb0b013,0x00d0c50dd3260a3f,0x0097126ac257f5bc,0x0042376cc90c705a,0x001d96fdb4a1071e)},
{FIELD_LITERAL(0x0067f8f0c4fe26c9,0x0079c4a3cc8f67b9,0x0082b1e62f23550d,0x00f2d409caefd7f5,0x0080e67dcdb26e81,0x0087ae993ea1f98a,0x00aa108becf61d03,0x001acf11efb608a3)},
{FIELD_LITERAL(0x008225febbab50d9,0x00f3b605e4dd2083,0x00a32b28189e23d2,0x00d507e5e5eb4c97,0x005a1a84e302821f,0x0006f54c1c5f08c7,0x00a347c8cb2843f0,0x0009f73e9544bfa5)},
{FIELD_LITERAL(0x006c59c9ae744185,0x009fc32f1b4282cd,0x004d6348ca59b1ac,0x00105376881be067,0x00af4096013147dc,0x004abfb5a5cb3124,0x000d2a7f8626c354,0x009c6ed568e07431)},
{FIELD_LITERAL(0x00abd2bb27611e57,0x00cf99bd1fbbd267,0x006f7ac78d478cc7,0x00dc9d340dd23fbb,0x00d3ddd520099c46,0x009836dbb6a03486,0x00f19de267c36883,0x0020885613349904)},
{FIELD_LITERAL(0x00832d02369b482c,0x00cba52ff0d93450,0x003fa9c908d554db,0x008d1e357b54122f,0x00abd91c2dc950c6,0x007eff1df4c0ec69,0x003f6aeb13fb2d31,0x00002d6179fc5b2c)},
{FIELD_LITERAL(0x00e828333c297f8b,0x009ef3cf8c3f7e1f,0x00ab45f8fff31cb9,0x00c8b4178cb0b013,0x00d0c50dd3260a3f,0x0097126ac257f5bc,0x0042376cc90c705a,0x001d96fdb4a1071e)},
{FIELD_LITERAL(0x00542d44d89ee1a8,0x00306642e0442d98,0x0090853872b87338,0x002362cbf22dc044,0x002c222adff663b8,0x0067c924495fcb79,0x000e621d983c977c,0x00df77a9eccb66fb)},
{FIELD_LITERAL(0x002809e4bbf1814a,0x00b9e854f9fafb32,0x00d35e67c10f7a67,0x008f1bcb76e748cf,0x004224d9515687d2,0x005ba0b774e620c4,0x00b5e57db5d54119,0x00e15babe5683282)},
{FIELD_LITERAL(0x00b9361257e36376,0x0049f348e3709d03,0x00dd0a597c455aa7,0x00078ce603320668,0x00635f64ae3195dc,0x00a4ed450b508288,0x0075b9adb5e1cc1d,0x00fca588167741f2)},
{FIELD_LITERAL(0x00a9e7730a819691,0x00d9cc73c4992b70,0x00e299bde067de5a,0x008c314eb705192a,0x00e7226f17e8a3cc,0x0029dfd956e65a47,0x0053a8e839073b12,0x006f942b2ab1597e)},
{FIELD_LITERAL(0x00832d02369b482c,0x00cba52ff0d93450,0x003fa9c908d554db,0x008d1e357b54122f,0x00abd91c2dc950c6,0x007eff1df4c0ec69,0x003f6aeb13fb2d31,0x00002d6179fc5b2c)},
{FIELD_LITERAL(0x0046c9eda81c9c89,0x00b60cb71c8f62fc,0x0022f5a683baa558,0x00f87319fccdf997,0x009ca09b51ce6a22,0x005b12baf4af7d77,0x008a46524a1e33e2,0x00035a77e988be0d)},
{FIELD_LITERAL(0x00a7efe46a7dbe2f,0x002f66fd55014fe7,0x006a428afa1ff026,0x0056caaa9604ab72,0x0033f3bcd7fac8ae,0x00ccb1aa01c86764,0x00158d1edf13bf40,0x009848ee76fcf3b4)},
{FIELD_LITERAL(0x00e3c287f132a1c6,0x006b0db804233a01,0x002a387902ad889b,0x00490b258b0f24d5,0x007f0e0745232a02,0x000c95c8c52d1dc4,0x0007fb060bcbc40d,0x002e50bf139dc67d)},
{FIELD_LITERAL(0x0039343746531ebe,0x00c8509d835d429d,0x00e79eceff6b0018,0x004abfd31e8efce5,0x007bbfaaa1e20210,0x00e3be89c193e179,0x001c420f4c31d585,0x00f414a315bef5ae)},
{FIELD_LITERAL(0x00a9e7730a819691,0x00d9cc73c4992b70,0x00e299bde067de5a,0x008c314eb705192a,0x00e7226f17e8a3cc,0x0029dfd956e65a47,0x0053a8e839073b12,0x006f942b2ab1597e)},
{FIELD_LITERAL(0x001c3d780ecd5e39,0x0094f247fbdcc5fe,0x00d5c786fd527764,0x00b6f4da74f0db2a,0x0080f1f8badcd5fc,0x00f36a373ad2e23b,0x00f804f9f4343bf2,0x00d1af40ec623982)},
{FIELD_LITERAL(0x0082aeace5f1b144,0x00f68b3108cf4dd3,0x00634af01dde3020,0x000beab5df5c2355,0x00e8b790d1b49b0b,0x00e48d15854e36f4,0x0040ab2d95f3db9f,0x002711c4ed9e899a)},
{FIELD_LITERAL(0x0083d695db66f207,0x002a2f8ada58aa77,0x002271eec16b4818,0x008443a70141f337,0x00d60ae50640352b,0x00816cee1385490c,0x006577b21e989cbc,0x00af2a0d2317b416)},
{FIELD_LITERAL(0x0098cddc8b39549a,0x006da37e3b05d22c,0x00ce633cfd4eb3cb,0x00fda288ef526acd,0x0025338878c5d30a,0x00f34438c4e5a1b4,0x00584efea7c310f1,0x0041a551f1b660ad)},
{FIELD_LITERAL(0x0039343746531ebe,0x00c8509d835d429d,0x00e79eceff6b0018,0x004abfd31e8efce5,0x007bbfaaa1e20210,0x00e3be89c193e179,0x001c420f4c31d585,0x00f414a315bef5ae)},
{FIELD_LITERAL(0x007c296a24990df8,0x00d5d07525a75588,0x00dd8e113e94b7e7,0x007bbc58febe0cc8,0x0029f51af9bfcad3,0x007e9311ec7ab6f3,0x009a884de1676343,0x0050d5f2dce84be9)},
{FIELD_LITERAL(0x005fa020cca2450a,0x00491c29db6416d8,0x0037cefe3f9f9a85,0x003d405230647066,0x0049e835f0fdbe89,0x00feb78ac1a0815c,0x00828e4b32dc9724,0x00db84f2dc8d6fd4)},
{FIELD_LITERAL(0x002808570429bc85,0x009d78dbec40c8ac,0x0052b4434bc3a7b4,0x00801b6419fe281c,0x008839a68764540a,0x0014ba034f958be4,0x00a31dbb6ec068f7,0x0077bd9bfe8c9cd9)},
{FIELD_LITERAL(0x00a0b68ec1eb72d2,0x002c03235c0d45a0,0x00553627323fe8c5,0x006186e94b17af94,0x00a9906196e29f14,0x0025b3aee6567733,0x007e0dd840080517,0x0018eb5801a4ba93)},
{FIELD_LITERAL(0x0098cddc8b39549a,0x006da37e3b05d22c,0x00ce633cfd4eb3cb,0x00fda288ef526acd,0x0025338878c5d30a,0x00f34438c4e5a1b4,0x00584efea7c310f1,0x0041a551f1b660ad)},
{FIELD_LITERAL(0x00d7f7a8fbd6437a,0x0062872413bf3753,0x00ad4bbcb43c584b,0x007fe49be601d7e3,0x0077c659789babf4,0x00eb45fcb06a741b,0x005ce244913f9708,0x0088426401736326)},
{FIELD_LITERAL(0x007bf562ca768d7c,0x006c1f3a174e387c,0x00f024b447fee939,0x007e7af75f01143f,0x003adb70b4eed89d,0x00e43544021ad79a,0x0091f7f7042011f6,0x0093c1a1ee3a0ddc)},
{FIELD_LITERAL(0x0028018fe84095bf,0x0091c0f9db41f3bd,0x0000445dfaca7dba,0x000603d307e6bdc6,0x00726c4c840ea4b0,0x009220d1c741716a,0x00d4918640a03006,0x0054caa25bda1d21)},
{FIELD_LITERAL(0x003973d8938971d6,0x002aca26fa80c1f5,0x00108af1faa6b513,0x00daae275d7924e6,0x0053634ced721308,0x00d2355fe0bbd443,0x00357612b2d22095,0x00f9bb9dd4136cf3)},
{FIELD_LITERAL(0x00a0b68ec1eb72d2,0x002c03235c0d45a0,0x00553627323fe8c5,0x006186e94b17af94,0x00a9906196e29f14,0x0025b3aee6567733,0x007e0dd840080517,0x0018eb5801a4ba93)},
{FIELD_LITERAL(0x00d7fe7017bf6a40,0x006e3f0624be0c42,0x00ffbba205358245,0x00f9fc2cf8194239,0x008d93b37bf15b4e,0x006ddf2e38be8e95,0x002b6e79bf5fcff9,0x00ab355da425e2de)},
{FIELD_LITERAL(0x00938f97e20be973,0x0099141a36aaf306,0x0057b0ca29e545a1,0x0085db571f9fbc13,0x008b333c554b4693,0x0043ab6ef3e241cb,0x0054fb20aa1e5c70,0x00be0ff852760adf)},
{FIELD_LITERAL(0x00d400ed30a1fc5a,0x00e424e0575e6307,0x0036e3986c07b2c6,0x0007960e4d145650,0x00a643ab823cdc93,0x0026e9ee292c7976,0x001f9d2555d3fdeb,0x0012c3fb833d437d)},
{FIELD_LITERAL(0x0062dd0fb31be374,0x00fcc96b84c8e727,0x003f64f1375e6ae3,0x0057d9b6dd1af004,0x00d6a167b1103c7b,0x00dd28f3180fb537,0x004ff27ad7167128,0x008934c33461f2ac)},
{FIELD_LITERAL(0x003973d8938971d6,0x002aca26fa80c1f5,0x00108af1faa6b513,0x00daae275d7924e6,0x0053634ced721308,0x00d2355fe0bbd443,0x00357612b2d22095,0x00f9bb9dd4136cf3)},
{FIELD_LITERAL(0x002bff12cf5e03a5,0x001bdb1fa8a19cf8,0x00c91c6793f84d39,0x00f869f1b2eba9af,0x0059bc547dc3236b,0x00d91611d6d38689,0x00e062daaa2c0214,0x00ed3c047cc2bc82)},
{FIELD_LITERAL(0x000050d70c32b31a,0x001939d576d437b3,0x00d709e598bf9fe6,0x00a885b34bd2ee9e,0x00dd4b5c08ab1a50,0x0091bebd50b55639,0x00cf79ff64acdbc6,0x006067a39d826336)},
{FIELD_LITERAL(0x009a4b8d486fffbc,0x00458102d00ef9b4,0x00f498293b3cfdf0,0x00ed2d7b960b1b92,0x00ce3cd6c68fc137,0x004b60f431eccf99,0x00081efbe9e7e2b8,0x00a36f0ae7981133)},
{FIELD_LITERAL(0x0006918f5dfce6dc,0x00d4bf1c793c57fb,0x0069a3f649435364,0x00e89a50e5b0cd6e,0x00b9f6a237e973af,0x006d4ed8b104e41d,0x00498946a3924cd2,0x00c136ec5ac9d4f7)},
{FIELD_LITERAL(0x0062dd0fb31be374,0x00fcc96b84c8e727,0x003f64f1375e6ae3,0x0057d9b6dd1af004,0x00d6a167b1103c7b,0x00dd28f3180fb537,0x004ff27ad7167128,0x008934c33461f2ac)},
{FIELD_LITERAL(0x0065b472b7900043,0x00ba7efd2ff1064b,0x000b67d6c4c3020f,0x0012d28469f4e46d,0x0031c32939703ec7,0x00b49f0bce133066,0x00f7e10416181d47,0x005c90f51867eecc)},
{FIELD_LITERAL(0x0051207abd179101,0x00fc2a5c20d9c5da,0x00fb9d5f2701b6df,0x002dd040fdea82b8,0x00f163b0738442ff,0x00d9736bd68855b8,0x00e0d8e93005e61c,0x00df5a40b3988570)},
{FIELD_LITERAL(0x00ee563d6f53acc9,0x00d465d2b5959acc,0x006575973bba26c8,0x00c9e4d84f81a1a3,0x00c3fbc4e8aa468a,0x0048149930eeaa11,0x008850a6f611000d,0x006709f6788337f9)},
{FIELD_LITERAL(0x00b373076597455f,0x00e83f1af53ac0f5,0x0041f63c01dc6840,0x0097dea19b0c6f4b,0x007f9d63b4c1572c,0x00e692d492d0f5f0,0x00cbcb392e83b4ad,0x0069c0f39ed9b1a8)},
{FIELD_LITERAL(0x0006918f5dfce6dc,0x00d4bf1c793c57fb,0x0069a3f649435364,0x00e89a50e5b0cd6e,0x00b9f6a237e973af,0x006d4ed8b104e41d,0x00498946a3924cd2,0x00c136ec5ac9d4f7)},
{FIELD_LITERAL(0x0011a9c290ac5336,0x002b9a2d4a6a6533,0x009a8a68c445d937,0x00361b27b07e5e5c,0x003c043b1755b974,0x00b7eb66cf1155ee,0x0077af5909eefff2,0x0098f609877cc806)},
{FIELD_LITERAL(0x00ab13af436bf8f4,0x000bcf0a0dac8574,0x00d50c864f705045,0x00c40e611debc842,0x0085010489bd5caa,0x007c5050acec026f,0x00f67d943c8da6d1,0x00de1da0278074c6)},
{FIELD_LITERAL(0x0079efcffed8f836,0x00604423802b5504,0x0070a6e294aab7dd,0x0020f75be15e7521,0x0062827c19bd5414,0x006738e425c48700,0x00dd37618fde0ffa,0x00bb2d65c01e1c3b)},
{FIELD_LITERAL(0x00c903ee6d825540,0x00add6c4cf98473e,0x007636efed4227f1,0x00905124ae55e772,0x00e6b38fab12ed53,0x0045e132b863fe55,0x003974662edb366a,0x00b1787052be8208)},
{FIELD_LITERAL(0x00b373076597455f,0x00e83f1af53ac0f5,0x0041f63c01dc6840,0x0097dea19b0c6f4b,0x007f9d63b4c1572c,0x00e692d492d0f5f0,0x00cbcb392e83b4ad,0x0069c0f39ed9b1a8)},
{FIELD_LITERAL(0x00861030012707c9,0x009fbbdc7fd4aafb,0x008f591d6b554822,0x00df08a41ea18ade,0x009d7d83e642abea,0x0098c71bda3b78ff,0x0022c89e7021f005,0x0044d29a3fe1e3c4)},
{FIELD_LITERAL(0x00e748cd7b5c52f2,0x00ea9df883f89cc3,0x0018970df156b6c7,0x00c5a46c2a33a847,0x00cbde395e32aa09,0x0072474ebb423140,0x00fb00053086a23d,0x001dafcfe22d4e1f)},
{FIELD_LITERAL(0x0059eb4ff288a383,0x00283876be3388ab,0x00bdd22974a2543b,0x0059eef0fe982d74,0x0097a5cf63dad778,0x004bc6002aebc99f,0x00c9a91d6118c690,0x0038364612a527ab)},
{FIELD_LITERAL(0x00006e34a35d9fbc,0x00eee4e48b2f019a,0x006b344743003a5f,0x00541d514f04a7e3,0x00e81f9ee7647455,0x005e2b916c438f81,0x00116f8137b7eff0,0x009bd3decc7039d1)},
{FIELD_LITERAL(0x00c903ee6d825540,0x00add6c4cf98473e,0x007636efed4227f1,0x00905124ae55e772,0x00e6b38fab12ed53,0x0045e132b863fe55,0x003974662edb366a,0x00b1787052be8208)},
{FIELD_LITERAL(0x00a614b00d775c7c,0x00d7c78941cc7754,0x00422dd68b5dabc4,0x00a6110f0167d28b,0x00685a309c252886,0x00b439ffd5143660,0x003656e29ee7396f,0x00c7c9b9ed5ad854)},
{FIELD_LITERAL(0x0040f7e7c5b37bf2,0x0064e4dc81181bba,0x00a8767ae2a366b6,0x001496b4f90546f2,0x002a28493f860441,0x0021f59513049a3a,0x00852d369a8b7ee3,0x00dd2e7d8b7d30a9)},
{FIELD_LITERAL(0x00fa2dd90bcbeef2,0x00507d774710de2a,0x00b585ad10e7e373,0x0041f487e4b4f921,0x00191c9d8212f81d,0x001bc55cbdd8d474,0x0017954bdba8827b,0x0004d6d3a991ca44)},
{FIELD_LITERAL(0x00e38abece3c82ab,0x005a51f18a2c7a86,0x009dafa2e86d592e,0x00495a62eb688678,0x00b79df74c0eb212,0x0023e8cc78b75982,0x005998cb91075e13,0x00735aa9ba61bc76)},
{FIELD_LITERAL(0x00006e34a35d9fbc,0x00eee4e48b2f019a,0x006b344743003a5f,0x00541d514f04a7e3,0x00e81f9ee7647455,0x005e2b916c438f81,0x00116f8137b7eff0,0x009bd3decc7039d1)},
{FIELD_LITERAL(0x0005d226f434110d,0x00af8288b8ef21d5,0x004a7a52ef181c8c,0x00be0b781b4b06de,0x00e6e3627ded07e1,0x00e43aa342272b8b,0x00e86ab424577d84,0x00fb292c566e35bb)},
{FIELD_LITERAL(0x00334f5303ea1222,0x00dfb3dbeb0a5d3e,0x002940d9592335c1,0x00706a7a63e8938a,0x005a533558bc4caf,0x00558e33192022a9,0x00970d9faf74c133,0x002979fcb63493ca)},
{FIELD_LITERAL(0x00260857d22419d7,0x005e0387d77651f0,0x008e0025ed2eb499,0x00c830b135804c2a,0x0037f43dbd3a77f6,0x008a4073d2f7379c,0x0072be0ce503ad58,0x00e6869d130c78be)},
{FIELD_LITERAL(0x00bfc5fa1e4ea21f,0x00c21d7b6bb892e6,0x00cf043f3acf0291,0x00c13f2f849b3c90,0x00d1a97ebef10891,0x0061e130a445e7fe,0x0019513fdedbf22b,0x001d60c813bff841)},
{FIELD_LITERAL(0x00e38abece3c82ab,0x005a51f18a2c7a86,0x009dafa2e86d592e,0x00495a62eb688678,0x00b79df74c0eb212,0x0023e8cc78b75982,0x005998cb91075e13,0x00735aa9ba61bc76)},
{FIELD_LITERAL(0x00d9f7a82ddbe628,0x00a1fc782889ae0f,0x0071ffda12d14b66,0x0037cf4eca7fb3d5,0x00c80bc242c58808,0x0075bf8c2d08c863,0x008d41f31afc52a7,0x00197962ecf38741)},
{FIELD_LITERAL(0x006e9f475cccf2ee,0x00454b9cd506430c,0x00224a4fb79ee479,0x0062e3347ef0b5e2,0x0034fd2a3512232a,0x00b8b3cb0f457046,0x00eb20165daa38ec,0x00128eebc2d9c0f7)},
{FIELD_LITERAL(0x00e6a9e38030fdec,0x001c23597bc14288,0x0097156a46356df1,0x00642048f0daca6a,0x003970a6e7955fd4,0x00a511e335e3cfc6,0x0054865756c85e31,0x00465f1ab66a6190)},
{FIELD_LITERAL(0x003e4964fa8a8fc8,0x00f6a1cdbcf41689,0x00943cb18fe7fda7,0x00606dafbf34440a,0x005d37a86399c789,0x00e79a2a69417403,0x00fe34f7e68b8866,0x0011f448ed2df10e)},
{FIELD_LITERAL(0x00bfc5fa1e4ea21f,0x00c21d7b6bb892e6,0x00cf043f3acf0291,0x00c13f2f849b3c90,0x00d1a97ebef10891,0x0061e130a445e7fe,0x0019513fdedbf22b,0x001d60c813bff841)},
{FIELD_LITERAL(0x0019561c7fcf0213,0x00e3dca6843ebd77,0x0068ea95b9ca920e,0x009bdfb70f253595,0x00c68f59186aa02a,0x005aee1cca1c3039,0x00ab79a8a937a1ce,0x00b9a0e549959e6f)},
{FIELD_LITERAL(0x00c79e0b6d97dfbd,0x00917c71fd2bc6e8,0x00db7529ccfb63d8,0x00be5be957f17866,0x00a9e11fdc2cdac1,0x007b91a8e1f44443,0x00a3065e4057d80f,0x004825f5b8d5f6d4)},
{FIELD_LITERAL(0x000e0a81033e033b,0x00aec986ee821eab,0x00d1a4a48379273c,0x00609b79a9e06304,0x00e9618b4fe8f307,0x006ffdfa50b50969,0x009530224887ac0c,0x0020e7b36f0cef97)},
{FIELD_LITERAL(0x00fd579ffb691713,0x00b76af4f81c412d,0x00f239de96110f82,0x00e965fb437f0306,0x00ca7e9436900921,0x00e487f1325fa24a,0x00633907de476380,0x00721c62ac5b8ea0)},
{FIELD_LITERAL(0x003e4964fa8a8fc8,0x00f6a1cdbcf41689,0x00943cb18fe7fda7,0x00606dafbf34440a,0x005d37a86399c789,0x00e79a2a69417403,0x00fe34f7e68b8866,0x0011f448ed2df10e)},
{FIELD_LITERAL(0x00f1f57efcc1fcc4,0x00513679117de154,0x002e5b5b7c86d8c3,0x009f6486561f9cfb,0x00169e74b0170cf7,0x00900205af4af696,0x006acfddb77853f3,0x00df184c90f31068)},
{FIELD_LITERAL(0x00b37396c3320791,0x00fc7b67175c5783,0x00c36d2cd73ecc38,0x0080ebcc0b328fc5,0x0043a5b22b35d35d,0x00466c9f1713c9da,0x0026ad346dcaa8da,0x007c684e701183a6)},
{FIELD_LITERAL(0x003f2ab1abd14b06,0x00b129a8e8e37230,0x0048bc5b083d5c64,0x0002606c12933a98,0x00cf8051ceec1a73,0x00a755a8836c3ce6,0x002dabaa90ca4cb9,0x00b6e5525ddfc0f2)},
{FIELD_LITERAL(0x00c4a1fb48635413,0x00b5dd54423ad59f,0x009ff5d53fd24a88,0x003c98d267fc06a7,0x002db7cb20013641,0x00bd1d6716e191f2,0x006dbc8b29094241,0x0044bbf233dafa2c)},
{FIELD_LITERAL(0x00fd579ffb691713,0x00b76af4f81c412d,0x00f239de96110f82,0x00e965fb437f0306,0x00ca7e9436900921,0x00e487f1325fa24a,0x00633907de476380,0x00721c62ac5b8ea0)},
{FIELD_LITERAL(0x00c0d54e542eb4f9,0x004ed657171c8dcf,0x00b743a4f7c2a39b,0x00fd9f93ed6cc567,0x00307fae3113e58b,0x0058aa577c93c319,0x00d254556f35b346,0x00491aada2203f0d)},
{FIELD_LITERAL(0x00dff3103786ff34,0x000144553b1f20c3,0x0095613baeb930e4,0x00098058275ea5d4,0x007cd1402b046756,0x0074d74e4d58aee3,0x005f93fc343ff69b,0x00873df17296b3b0)},
{FIELD_LITERAL(0x00aa7c72be0ace19,0x004095d22fc37e4d,0x00a7d85f9e3b7c61,0x00ff21d344c9553c,0x00d105d6268e8b86,0x000616d733758845,0x003ecb4ba7210610,0x006a75e7dddc03b7)},
{FIELD_LITERAL(0x007860d99db787cf,0x00fda8983018f4a8,0x008c8866bac4743c,0x00ef471f84c82a3f,0x00abea5976d3b8e7,0x00714882896cd015,0x00b49fae584ddac5,0x008e33a1a0b69c81)},
{FIELD_LITERAL(0x00c4a1fb48635413,0x00b5dd54423ad59f,0x009ff5d53fd24a88,0x003c98d267fc06a7,0x002db7cb20013641,0x00bd1d6716e191f2,0x006dbc8b29094241,0x0044bbf233dafa2c)},
{FIELD_LITERAL(0x0055838d41f531e6,0x00bf6a2dd03c81b2,0x005827a061c4839e,0x0000de2cbb36aac3,0x002efa29d9717478,0x00f9e928cc8a77ba,0x00c134b458def9ef,0x00958a182223fc48)},
{FIELD_LITERAL(0x000a9ee23c06881f,0x002c727d3d871945,0x00f47d971512d24a,0x00671e816f9ef31a,0x00883af2cfaad673,0x00601f98583d6c9a,0x00b435f5adc79655,0x00ad87b71c04bff2)},
{FIELD_LITERAL(0x0084911d36175613,0x00dbaa24427629dd,0x009b6f30b1554fc7,0x0026da093cf7ea9e,0x00eac4cfb8218c7c,0x00c4bde074231490,0x0089e5b5afb62587,0x0067fcb73adfdbcc)},
{FIELD_LITERAL(0x00eebfd4e2312cc3,0x00474b2564e4fc8c,0x003303ef14b1da9b,0x003c93e0e66beb1d,0x0013619b0566925a,0x008817c24d901bf3,0x00b62bd8898d218b,0x0075a7716f1e88a2)},
{FIELD_LITERAL(0x007860d99db787cf,0x00fda8983018f4a8,0x008c8866bac4743c,0x00ef471f84c82a3f,0x00abea5976d3b8e7,0x00714882896cd015,0x00b49fae584ddac5,0x008e33a1a0b69c81)},
{FIELD_LITERAL(0x007b6ee2c9e8a9ec,0x002455dbbd89d622,0x006490cf4eaab038,0x00d925f6c3081561,0x00153b3047de7382,0x003b421f8bdceb6f,0x00761a4a5049da78,0x00980348c5202433)},
{FIELD_LITERAL(0x007f8a43da97dd5c,0x00058539c800fc7b,0x0040f3cf5a28414a,0x00d68dd0d95283d6,0x004adce9da90146e,0x00befa41c7d4f908,0x007603bc2e3c3060,0x00bdf360ab3545db)},
{FIELD_LITERAL(0x00f6de725e1976f0,0x00d96f80a02fda8a,0x00b25412a0e629fa,0x00c540e7e78fdb62,0x004ad02fb7336d3a,0x004922ae1bea5a3a,0x0026147d42d4bfeb,0x00d379a5bc4b94bc)},
{FIELD_LITERAL(0x00c338b915d8fef0,0x00a893292045c39a,0x0028ab4f2eba6887,0x0060743cb519fd61,0x0006213964093ac0,0x007c0b7a43f6266d,0x008e3557c4fa5bda,0x002da976de7b8d9d)},
{FIELD_LITERAL(0x00eebfd4e2312cc3,0x00474b2564e4fc8c,0x003303ef14b1da9b,0x003c93e0e66beb1d,0x0013619b0566925a,0x008817c24d901bf3,0x00b62bd8898d218b,0x0075a7716f1e88a2)},
{FIELD_LITERAL(0x0009218da1e6890f,0x0026907f5fd02575,0x004dabed5f19d605,0x003abf181870249d,0x00b52fd048cc92c4,0x00b6dd51e415a5c5,0x00d9eb82bd2b4014,0x002c865a43b46b43)},
{FIELD_LITERAL(0x0070047189452f4c,0x00f7ad12e1ce78d5,0x00af1ba51ec44a8b,0x005f39f63e667cd6,0x00058eac4648425e,0x00d7fdab42bea03b,0x0028576a5688de15,0x00af973209e77c10)},
{FIELD_LITERAL(0x00b78d6075749232,0x0001dc47a33b2cdc,0x0018c7b2e91b24f1,0x00b5bdc68f9876bd,0x0013f489ccba2b44,0x003b8846066128de,0x003d6252c8884dcf,0x00e3ae84b9908209)},
{FIELD_LITERAL(0x00aa2261022d883f,0x00ebcca4548010ac,0x002528512e28a437,0x0070ca7676b66082,0x0084bda170f7c6d3,0x00581b4747c9b8bb,0x005c96a01061c7e2,0x00fb7c4a362b5273)},
{FIELD_LITERAL(0x00c338b915d8fef0,0x00a893292045c39a,0x0028ab4f2eba6887,0x0060743cb519fd61,0x0006213964093ac0,0x007c0b7a43f6266d,0x008e3557c4fa5bda,0x002da976de7b8d9d)},
{FIELD_LITERAL(0x0048729f8a8b6dcd,0x00fe23b85cc4d323,0x00e7384d16e4db0e,0x004a423970678942,0x00ec0b763345d4ba,0x00c477b9f99ed721,0x00c29dad3777b230,0x001c517b466f7df6)},
{FIELD_LITERAL(0x006366c380f7b574,0x001c7d1f09ff0438,0x003e20a7301f5b22,0x00d3efb1916d28f6,0x0049f4f81060ce83,0x00c69d91ea43ced1,0x002b6f3e5cd269ed,0x005b0fb22ce9ec65)},
{FIELD_LITERAL(0x003cffdf14aed2fd,0x009f0d77d7c5b2d9,0x004812ec41321d9f,0x008a1448bddf0916,0x008fef86030175df,0x00e3d703200a76c7,0x00d1babb470b2094,0x009f3a43b0e5828c)},
{FIELD_LITERAL(0x00a94700032a093f,0x0076e96c225216e7,0x00a63a4316e45f91,0x007d8bbb4645d3b2,0x00340a6ff22793eb,0x006f935d4572aeb7,0x00b1fb69f00afa28,0x009e8f3423161ed3)},
{FIELD_LITERAL(0x00aa2261022d883f,0x00ebcca4548010ac,0x002528512e28a437,0x0070ca7676b66082,0x0084bda170f7c6d3,0x00581b4747c9b8bb,0x005c96a01061c7e2,0x00fb7c4a362b5273)},
{FIELD_LITERAL(0x00c30020eb512d02,0x0060f288283a4d26,0x00b7ed13becde260,0x0075ebb74220f6e9,0x00701079fcfe8a1f,0x001c28fcdff58938,0x002e4544b8f4df6b,0x0060c5bc4f1a7d73)},
{FIELD_LITERAL(0x00ae307cf069f701,0x005859f222dd618b,0x00212d6c46ec0b0d,0x00a0fe4642afb62d,0x00420d8e4a0a8903,0x00a80ff639bdf7b0,0x0019bee1490b5d8e,0x007439e4b9c27a86)},
{FIELD_LITERAL(0x00610b6394a312e8,0x005aaa19d96160f5,0x008190e286138c4a,0x006538796a5cd53b,0x00fe28804432a97c,0x007315e011f55112,0x000bd4157d5acb9d,0x00d1b95469350336)},
{FIELD_LITERAL(0x0060db815bc4786c,0x006fab25beedc434,0x00c610d06084797c,0x000c48f08537bec0,0x0031aba51c5b93da,0x007968fa6e01f347,0x0030070da52840c6,0x00c043c225a4837f)},
{FIELD_LITERAL(0x00a94700032a093f,0x0076e96c225216e7,0x00a63a4316e45f91,0x007d8bbb4645d3b2,0x00340a6ff22793eb,0x006f935d4572aeb7,0x00b1fb69f00afa28,0x009e8f3423161ed3)},
{FIELD_LITERAL(0x009ef49c6b5ced17,0x00a555e6269e9f0a,0x007e6f1d79ec73b5,0x009ac78695a32ac4,0x0001d77fbbcd5682,0x008cea1fee0aaeed,0x00f42bea82a53462,0x002e46ab96cafcc9)},
{FIELD_LITERAL(0x0051cfcc5885377a,0x00dce566cb1803ca,0x00430c7643f2c7d4,0x00dce1a1337bdcc0,0x0010d5bd7283c128,0x003b1b547f9b46fe,0x000f245e37e770ab,0x007b72511f022b37)},
{FIELD_LITERAL(0x00e4302ff9b6116c,0x0092314b81d5f02a,0x000d31425f30702f,0x004946262e04213c,0x007ead9d19b6f9ed,0x001080a31ce8989f,0x001b632f36672a74,0x00a03933d9645a83)},
{FIELD_LITERAL(0x004a2902926f8d3f,0x00ad79b42637ab75,0x0088f60b90f2d4e8,0x0030f54ef0e398c4,0x00021dc9bf99681e,0x007ebf66fde74ee3,0x004ade654386e9a4,0x00e7485066be4c27)},
{FIELD_LITERAL(0x0060db815bc4786c,0x006fab25beedc434,0x00c610d06084797c,0x000c48f08537bec0,0x0031aba51c5b93da,0x007968fa6e01f347,0x0030070da52840c6,0x00c043c225a4837f)},
{FIELD_LITERAL(0x001bcfd00649ee93,0x006dceb47e2a0fd5,0x00f2cebda0cf8fd0,0x00b6b9d9d1fbdec3,0x00815262e6490611,0x00ef7f5ce3176760,0x00e49cd0c998d58b,0x005fc6cc269ba57c)},
{FIELD_LITERAL(0x008940211aa0d633,0x00addae28136571d,0x00d68fdbba20d673,0x003bc6129bc9e21a,0x000346cf184ebe9a,0x0068774d741ebc7f,0x0019d5e9e6966557,0x0003cbd7f981b651)},
{FIELD_LITERAL(0x00bba0ed9c67c41f,0x00b30c8e225ba195,0x008bb5762a5cef18,0x00e0df31b06fb7cc,0x0018b912141991d5,0x00f6ed54e093eac2,0x0009e288264dbbb3,0x00feb663299b89ef)}
{FIELD_LITERAL(0x004a2902926f8d3f,0x00ad79b42637ab75,0x0088f60b90f2d4e8,0x0030f54ef0e398c4,0x00021dc9bf99681e,0x007ebf66fde74ee3,0x004ade654386e9a4,0x00e7485066be4c27)},
{FIELD_LITERAL(0x00445f1263983be0,0x004cf371dda45e6a,0x00744a89d5a310e7,0x001f20ce4f904833,0x00e746edebe66e29,0x000912ab1f6c153d,0x00f61d77d9b2444c,0x0001499cd6647610)}
};
const gf API_NS(precomputed_wnaf_as_fe)[96]
VECTOR_ALIGNED __attribute__((visibility("hidden"))) = {
{FIELD_LITERAL(0x00cfc32590115acd,0x0079f0e2a5c7af1b,0x00dd94605b8d7332,0x0097dd6c75f5f3f3,0x00d9c59e36156de9,0x00edfbfd6cde47d7,0x0095b97c9f67c39a,0x007d7b90f587debc)},
{FIELD_LITERAL(0x00cfc32590115acd,0x0079f0e2a5c7af1b,0x00dd94605b8d7332,0x0017dd6c75f5f3f3,0x00d9c59e36156de8,0x00edfbfd6cde47d7,0x0095b97c9f67c39a,0x00fd7b90f587debc)},
{FIELD_LITERAL(0x001071dd4d8ae672,0x004f14ebe5f4f174,0x00e0987625c34c73,0x0092d00712c6f8c1,0x009ef424965e980b,0x00a8e0cf9369764b,0x000aa81907b4d207,0x00d5002c74d37924)},
{FIELD_LITERAL(0x00f3c4efe62b8b17,0x001e6acc1b6add7b,0x003367ef45836df5,0x000efc2d87a6ba53,0x00405a96933964ca,0x00572c2ae16357c6,0x00a9dc34ba6a7946,0x00151831e32ad161)},
{FIELD_LITERAL(0x00315f0372d1774a,0x007de9ed2960e79d,0x008b3d7c4c198add,0x00a5e6a45fa57892,0x00f32201aa80115a,0x007fb9386a433a1a,0x00abf6960b291ee6,0x002d8069294ebc2a)},
{FIELD_LITERAL(0x00fa5e878ae22827,0x00d33c7bb3963bd0,0x0053401a101efac6,0x0063df0bcbce59a5,0x007bca269c8b584b,0x00611a8a9978842c,0x00bb96e8da12b8a8,0x00e17844d01d394d)},
{FIELD_LITERAL(0x00c107c50e9b4d0d,0x00f6b65a5fada2f2,0x000bb67e79353fae,0x0018853f610ed92d,0x008c51f4d36d6915,0x00e3e9c096dd1c12,0x009d6b9ea6cde415,0x00304864dd66f4c6)},
{FIELD_LITERAL(0x00f3123b214085fb,0x00d005bafffb8f53,0x00d1606987dfe6ea,0x00e825edf73b018d,0x0082aa733829a933,0x00c857d8d7830d76,0x00ebdb8d2cbbe7e6,0x0063de0e9930722e)},
{FIELD_LITERAL(0x004ffebce35619ab,0x00d281a1543365c5,0x00ad17eeb3d098b8,0x008653b06bb7806d,0x0040026e64a28b62,0x00d9e06d52ea19df,0x008e7c684856876a,0x003ebbc191443f3b)},
{FIELD_LITERAL(0x00c0a062813b8884,0x0054d18cc36e636b,0x00e4493fcadba51a,0x005cda5b6577c9cf,0x00cc165615c315cf,0x001bbd5e155f17bb,0x004dee92a4f18e47,0x003e95412929bfb8)},
{FIELD_LITERAL(0x0015326f3e1f5fb6,0x0076886ca4eb6041,0x00fb34645ee36c23,0x006042a4cb8f7bb2,0x00b43e736403dd2f,0x00a8986566e7c60c,0x0010ea48904bf6d1,0x008b5ae8c5ddafbe)},
{FIELD_LITERAL(0x003a9f4a12faee9a,0x00e6ba523a29af6b,0x001dde79a8ef06ef,0x0033ed4361647314,0x00b0556ae76eb1c9,0x00e8b892762bd092,0x004709c83705e374,0x0077382d86f79b47)},
{FIELD_LITERAL(0x006638c5cee4113d,0x005c100c7276ed52,0x00d10562e281768d,0x0008e851e1eb2ed9,0x00d7cc086a7af373,0x00993ed528eb7942,0x0051677625b7df14,0x0029fbbcf6aaa3f7)},
{FIELD_LITERAL(0x001081503e396419,0x007a2c7aa8870415,0x00d372a4baf3490a,0x00b18821a1e18013,0x00b83fa876c54211,0x00e4bcf47a2ae1e9,0x0069a384ba9bf3c3,0x00b784d44ee9d468)},
{FIELD_LITERAL(0x00b4e3ad7c2ea1be,0x009962715cf7008a,0x00fbc6fdcc089d5e,0x001e29847c349313,0x00c1145569b3874d,0x0094f50069a1499b,0x004cec2bb8f423c8,0x0077eb0034c34627)},
{FIELD_LITERAL(0x008f00d279b21a44,0x00a5c81149c8116a,0x00cc8be3da721e9f,0x001935a34e6770b9,0x00e315426d5db99d,0x00cf6a842aff01bf,0x00e3cc9d5016ed3a,0x00ae78776098742d)},
{FIELD_LITERAL(0x0068db473197248f,0x0089874a12ff90c2,0x00420b4763f5428c,0x00d668b71fb38392,0x0022279b6d3c3687,0x003a5801405cf566,0x00127b8ea4b4fd44,0x00ce6a975208fb79)},
{FIELD_LITERAL(0x00797ca039d44238,0x0063cae935b6ef5e,0x006a938e072ff87c,0x006a3870309cdca0,0x0003800945fa3ddc,0x0032274c0728b5ad,0x0053a51e9217da91,0x00162b41712b79db)},
{FIELD_LITERAL(0x000911f06768bdc6,0x00bd27650f82c5b0,0x007b948017bcb94a,0x0095de039572c65e,0x0053743dabe00d25,0x0092b1d5888cd8cd,0x0065c6496b33c0d0,0x007a3f55d5bfb370)},
{FIELD_LITERAL(0x003f31eebfa20d27,0x00b1c0c84d6c2849,0x00dbefe8d1e53924,0x00472400b407ebc2,0x00c584bf62a91498,0x00c1f095f2010650,0x007e3b1b2c9ba41e,0x003189f894ed89dc)},
{FIELD_LITERAL(0x004d9eefe5de7ab7,0x003e35169bdbd884,0x0079625f58822d97,0x0043f4f607137c15,0x0029efd80717d455,0x0055b37a66623198,0x00153cecd460c01e,0x000464f30e396a2d)},
{FIELD_LITERAL(0x0057b28375dc4b6e,0x00771e6557974d80,0x00fa6792bc187316,0x000d7fed0f9f92d7,0x00e821281efdb64b,0x00a12bf7b4dc5064,0x00464f56bfa9bb8d,0x00526fa933114e0b)},
{FIELD_LITERAL(0x00bcf86d6aaed0f2,0x00b95ff679e8a71f,0x00c11d7bd57f8c87,0x00cb3362ed671b05,0x0068bb14b2ce4c10,0x00505313699af32f,0x005376e4cec89e51,0x00179b292d918f75)},
{FIELD_LITERAL(0x00246e4ca8018aa1,0x005e55abb4eaca63,0x0050b6ce5fe6aa8b,0x008979edb01ee510,0x002e152c38461080,0x00550a03a7f073ea,0x0018d841eb811e13,0x00c39e3e1ea88479)},
{FIELD_LITERAL(0x007f1264364f8cc7,0x000315388ba2d9ad,0x007562aa0a0d3396,0x0069318d20cfe53a,0x000acdcd1868b277,0x008e8d738518c6b8,0x006faf89fda8f887,0x00347e30277c4e4d)},
{FIELD_LITERAL(0x0062c03567cddf30,0x0032ee53437ac23b,0x00e8a6fbf62d80e2,0x002de89967f7d7fd,0x0005fedae4d7c736,0x0022d685f264ae39,0x0028936d3fba7df5,0x00acb4383b936fcc)},
{FIELD_LITERAL(0x00afee55215c8c25,0x00c57a8713769fcb,0x000df59aca05928e,0x00aead2ce1a57830,0x00d453e3719735cd,0x004f1cdc24b3ec7e,0x000e2a69482a51da,0x00151ba7f6834b1f)},
{FIELD_LITERAL(0x003eaec329954173,0x00fec61feee76bb2,0x009b544347f7f444,0x004c4f7dfdb8cebd,0x0039d610da25dbfb,0x000f513ccef26480,0x00af4ddd8b8d2732,0x00093756dd2be04b)},
{FIELD_LITERAL(0x006df537f064f2de,0x0007f0808cbfedb9,0x00792c87b64aa829,0x00fd42b4ce848ad1,0x004d9b9c66c5bd43,0x00df8fbdd58c4ed6,0x00cbe5355fc7f34c,0x00abe6eb22995e4d)},
{FIELD_LITERAL(0x00ef8a330d9484e0,0x0044944dece8fbcc,0x0016b6e52d9d2586,0x00610b0b72d2c7b3,0x00766d88f8990f61,0x00ea7bc69494eefe,0x0050c07989360110,0x00db9fc3bfd96ee7)},
{FIELD_LITERAL(0x0069991db096c6b8,0x0008ebceed962ba0,0x00ef0053e2f37ae3,0x009917f3c8c9cb68,0x000e0b52fef39f4e,0x00ea378bf7b8f008,0x009ae2a16388995b,0x007ec77e628ee921)},
{FIELD_LITERAL(0x0062284cece6ad83,0x00e18536b7278c56,0x0005ab4b910698c5,0x009910472a4fd019,0x008ab4e2c6d75150,0x00fbd9d538d59094,0x0086482b65914fd9,0x00ced958acabfefd)},
{FIELD_LITERAL(0x00c6cb4ee3a8dac4,0x0010cf7120de0b91,0x001ab166385e9e67,0x007f2a8eca89b19c,0x008ae3d846b943da,0x0022c7631b161ed6,0x005e5d402e327b23,0x00d0518c1aeb64cd)},
{FIELD_LITERAL(0x000d45c95be55ebb,0x005f3dd26b911e70,0x00755171065eb066,0x00110b2864e644c9,0x00718a31c2d84e02,0x0059a255fc4d65d8,0x0026337c97b14eba,0x0061e127f33d128b)},
{FIELD_LITERAL(0x006ee9a82004b322,0x003eff4833aac2f9,0x00bb62f8a13b9833,0x008f9deff439b18f,0x00bc30790842de17,0x000bfe23b4868215,0x00addb504d09d19a,0x002e121c04a5bd41)},
{FIELD_LITERAL(0x004126ac2e668677,0x0046c12e8a5dbed7,0x0078e3a69c049c9a,0x0035d20dffeb5878,0x000a263e2f4cbcdc,0x00090a6bd7e724f5,0x00b33f6e0b6366f9,0x00175e7759f40060)},
{FIELD_LITERAL(0x0083b4b835838c18,0x00ac69ddefc68cb4,0x00749b220f1ba281,0x004052a50d7a193d,0x007138ee3a4e5e56,0x003099ccfedc8067,0x006e811c0e9aaed9,0x00bead0cc8101227)},
{FIELD_LITERAL(0x00cd3889dfcd0517,0x001bf78dcd1f43de,0x000898cbb491727a,0x00440c964893d55d,0x0075e0b9391ea8f2,0x00ec9732687fc960,0x008ca65c62f86bcf,0x00fc9b9aed6debcb)},
{FIELD_LITERAL(0x00f8381236cfa255,0x00f5999b0d8c8fe3,0x000918786a1dff4e,0x00a2fa46132db8c1,0x00eb0a0e8379a878,0x003802d2e990566a,0x00b6c65d27147f1f,0x00ddbb45f6bd3e66)},
{FIELD_LITERAL(0x000f68a71ee1c67a,0x00e96102429b052c,0x0017776482925329,0x00ca322a71577df6,0x004325b8a79280b5,0x00c322234d786f77,0x00e9258fe7816ab4,0x006aa915d16d5532)},
{FIELD_LITERAL(0x00cde18980fd9d30,0x00d1a82889350971,0x0040d36b7eb0fbc8,0x003cc6e695329dd0,0x00e24b3318e1d88e,0x00e212a22459111d,0x00879f754eaab372,0x00f9801f5489c9a4)},
{FIELD_LITERAL(0x007354e942e00768,0x004c7668d3208ac0,0x0015712e1b92023f,0x00b018106b3a760b,0x00d4751647fa130b,0x00da3f7276d78b5a,0x00dc6c71672bb3b3,0x0008a6ecb3540963)},
{FIELD_LITERAL(0x00e13a624c26a6f1,0x00e161c0e3c0e7d2,0x00ba563c13d354eb,0x00f7e67a8d51498c,0x0088c48bf9742e97,0x00edaca155c6abcb,0x00bb24561c4448b5,0x00d045b2c38b42f1)},
{FIELD_LITERAL(0x0093d57b9871b4c4,0x0085e6b5532e7970,0x0012fdda50bdb89e,0x0025f590d6c39b47,0x00ef9d53a39585e6,0x00cf0a88a575110b,0x00fd53552894850f,0x00bef47029c5a860)},
{FIELD_LITERAL(0x00bd40f701996dd3,0x00cce747044b6173,0x0028a6b9ffb55eb3,0x0009fea794bd40e3,0x0038b30e26ed0198,0x005434c968b4cf52,0x00814878df362d47,0x0060ab54842b207a)},
{FIELD_LITERAL(0x00bd19d97479e8ae,0x00f722fb96aff3e9,0x004ae4a83cc75c02,0x0033bb6827a30094,0x00d0ec294a83cb5a,0x007c9ad150cfeefa,0x0033cbbd6b336c57,0x009f0b2fd7ef1d8f)},
{FIELD_LITERAL(0x00246036b708c7d9,0x000574c8b9127116,0x00ecd349a550414d,0x003c900c0186da47,0x007c82512cac2d00,0x001399e41f99830b,0x00a414712d16fdfb,0x0028822961a9b698)},
{FIELD_LITERAL(0x00576abc9c32ae74,0x0052e8eedb433484,0x009a0b95b52551ff,0x00e4e5a4d5691aff,0x00bc01db07dccd79,0x00996692751e0d3c,0x003acf0cd9be9606,0x003f06d2f83095a8)},
{FIELD_LITERAL(0x0028c4051a1ff7bb,0x0040ba689904a0ad,0x009e4b0a5acec321,0x00bc6d2b3c46aaeb,0x00f2caae4ef88adb,0x00ff6677bf11a28e,0x0092191cbfbb7484,0x00dae55afb78a291)},
{FIELD_LITERAL(0x00c95aa397ea26bc,0x007372e21066c24c,0x00d1f1e17008ce70,0x00277c5b46d24ff5,0x00d0a187e51cc6f8,0x00e58d524dca3f92,0x000d1a618c916355,0x00e5b4a71cfce6eb)},
{FIELD_LITERAL(0x00c40cbcbd853cbd,0x00523f5879bd473a,0x00fc476ce8a57ceb,0x009e5cb521a8fc43,0x0015c157448e29cc,0x0041f2065e0e673d,0x00b9227183e9ca04,0x000eadc022da2a1a)},
{FIELD_LITERAL(0x00d6313aad8c08f2,0x008fbb11d8a39cbf,0x00bf09c856cfea1d,0x00cc7448724a5516,0x00eb6e4d59ecdeb7,0x005eda293019421c,0x00a0853a9e457996,0x00e2a1515c045530)},
{FIELD_LITERAL(0x009cc09c03622bf9,0x0018ec007f1fb5bc,0x009f39168f0d29de,0x005a83280f20e76e,0x000dbf95aaf9af43,0x004f9bd6f102397b,0x00e154febb2e86e9,0x0032ea079c3d6c54)},
{FIELD_LITERAL(0x00fab169ca1c41ce,0x00f1bc0ce1d78d41,0x002fa4e361cc67be,0x009053af427e0267,0x0032387ad15144f5,0x00b00ae64f9e66e4,0x006f6617ef82b37a,0x00d8c1db3c95b59e)},
{FIELD_LITERAL(0x0035175500c7799c,0x00a167c5ca225e38,0x00854efcf271c80b,0x001b76bf0a2fcd01,0x0095c90610cf4ccd,0x0064190fc6a738a8,0x0079dce31456ebff,0x00742f0847dc1855)},
{FIELD_LITERAL(0x00f8f4bbbe10d3b9,0x00105a4fd7fe5ef6,0x0040f473c119b520,0x0075981f4cbad167,0x00e6e94e0d05858a,0x00287e587009323c,0x00797d31a81a36e6,0x0033eef622def25c)},
{FIELD_LITERAL(0x003077e1410a5ba5,0x00b14158718390d3,0x006f256df630d95f,0x0021d4d1b388a47b,0x008e29fce3c3ea50,0x002616d810e8828f,0x0076b1173dc76902,0x001c4c4bfe1be552)},
{FIELD_LITERAL(0x00a2657cac024d24,0x00aa33dfb739670f,0x00093b53769a8de7,0x00adafcb28c0514d,0x00bca8890425c381,0x008f15acedcdc343,0x0085efa2bb2f9604,0x0092437292387955)},
{FIELD_LITERAL(0x00dfb010d979be8f,0x007e6d963a211f07,0x00404b8ec1368699,0x00d9cc6590cb2087,0x00e0d919b389e23c,0x001001c50cec349f,0x001e848fec709fe4,0x000e91e3326121a1)},
{FIELD_LITERAL(0x00e8300e632c6b13,0x00010847ef6dda78,0x0019b7c68f200ab7,0x00220c952978bd9b,0x0019e887adc0331c,0x006c5993f36c4db5,0x0002c98eeb248079,0x0089ad282231d922)},
{FIELD_LITERAL(0x0059811830606614,0x00a8ec4d8a0d0097,0x000e2ac957beaec2,0x007dc4a64fdb8ed1,0x0063b9462f2c7312,0x00324ea6a55d282b,0x007c8a4cbdc26507,0x00f54f4ae9268708)},
{FIELD_LITERAL(0x0026d312845ed7bc,0x0051563888e17918,0x00b99c696ccab084,0x0059d7244957f3b8,0x00c5f4faf8c8d6ab,0x00bdeeec54ba3f26,0x001aba0f7c9d5485,0x00d731f784b29269)},
{FIELD_LITERAL(0x00bd7234c3aef4f0,0x00a7a9f815db44b1,0x00c8c940e9fc9785,0x003b81a973b01c38,0x00c32ffd7d7b79f9,0x00bc5b783c46e6c6,0x00b003fb1ef6a5f9,0x005b36765c2b46e7)},
{FIELD_LITERAL(0x0030b09f9659a719,0x00ac35ad7a6bc959,0x009b466b281c1ee8,0x0034b96465f80acb,0x00304970c66162b7,0x000f2347253e3918,0x000d54980ac74c5a,0x00aaabb0e875468a)},
{FIELD_LITERAL(0x00578872f1bd6085,0x00b3fd4fa6efa597,0x00e99ac49f625c00,0x002aef842e5ed2d8,0x004b8f706588e353,0x00449c499dfcc096,0x008d0cdddbf18dea,0x00e6bba4a6396ddd)},
{FIELD_LITERAL(0x0066485d97a2ac73,0x001d0e768483ffe7,0x00c5253731b7251c,0x00f76d892a3af3f3,0x00e8d035f85298e7,0x0034e58d0abf961a,0x00b11bd0eccaba4c,0x0087a079aec9d0e9)},
{FIELD_LITERAL(0x00d38488bd2e2026,0x00d35414e79dc3fe,0x00faa0a1c1fbbbb9,0x0093df0c4b10ab45,0x0039ffebe1394c9f,0x00cab0bc80e5cd5c,0x00453b9db5cadf06,0x003b7c08cb56f96e)},
{FIELD_LITERAL(0x00b63453c7af61ee,0x00eadcbafa2bd320,0x0086b04f4a7bf0e3,0x00b69bc8cbbfba5a,0x00ce4926bb1b064e,0x004df8ce753e0a27,0x00ff37bf2580a3a2,0x00ad90c8c5a377eb)},
{FIELD_LITERAL(0x00ac58c82bdd6e72,0x0008035e278a79da,0x003c9fcc92524fb3,0x000c71c26ea75e47,0x009631c4be717b38,0x00a2e968135e9152,0x00074295ca131ec2,0x00877a203d4a5015)},
{FIELD_LITERAL(0x00a49896f002be26,0x00ad6b0d720ae906,0x005786d8dbed0346,0x00f6749d6592e372,0x000542c37faf79a4,0x003281a4f5c7863a,0x00eacdc7def0cbdc,0x00ca8353efe160bd)},
{FIELD_LITERAL(0x003c9e851d9f8893,0x004df23c1696dd28,0x005e587fddb98f95,0x00359afa5adbfdbb,0x00ddb949d26e687c,0x00ebc6efd285564c,0x001750eec619bdd3,0x0037772e4ad0d4fa)},
{FIELD_LITERAL(0x0076e84babbbb048,0x000a6db83681bbe4,0x0059dff597eaead2,0x00f65bdd79fe2dab,0x00e3fc9faa642c8a,0x008a9cc9dfc634c9,0x00428a4b728b1cd4,0x00e80aea53cb6617)},
{FIELD_LITERAL(0x002ab17fdf7d2bd3,0x005aa55f23183393,0x009b88469f8c0eb9,0x007d101b314bca6b,0x0056dd4345fd97b9,0x00880e62e548ae7d,0x003d44d8c87b91a6,0x00fb2811386e22cc)},
{FIELD_LITERAL(0x00eacd58001be3a5,0x0014e1231ca72940,0x0022453384987584,0x0075848f0c37be5c,0x000e6dc40d82c0b2,0x00f4d8ec1270878c,0x00550981d6fb86fd,0x00bb66b58f4c6892)},
{FIELD_LITERAL(0x00bba772e57e297f,0x004f56f68df71b07,0x00ded9facaf23a81,0x00d78e832d78eedc,0x0004f7c3eff02685,0x00ba5fa931f9c020,0x005a29fb4b2295be,0x00e2543f745b1dc9)},
{FIELD_LITERAL(0x00712177652580f9,0x00e9ee16e21d1eca,0x0002465ba75b8e46,0x00a9cb7b1fc8ef2e,0x00ce337e6da1cf8e,0x009d3684c507fffa,0x00058cc115d71214,0x0017dba81e144377)},
{FIELD_LITERAL(0x003b778e67285805,0x00dbb06704ba87b5,0x00ba6ee1ea5ea2fe,0x00e2cdc2c8b3f699,0x006983c6eae69a9c,0x00c6c8c542d0c398,0x00f2d3a9ebcedbdc,0x00be30ddeabbd31c)},
{FIELD_LITERAL(0x0095f20a016490a6,0x005f2b00b9fbf26d,0x00b583124906cdaf,0x002e2077aa473ca8,0x0018c5b9f7902fa6,0x00b704f5229201a6,0x00e1fc5d70e4b1c2,0x00578e366ccf7289)},
{FIELD_LITERAL(0x00932127be1d579d,0x00e6729f50f54904,0x00e70f6247f618af,0x00b1953989fe9d9c,0x0015032e9df69633,0x00d3687b35cb6e82,0x00ab0fff86869218,0x0026054a3a68ddfb)},
{FIELD_LITERAL(0x00cf244d2e899137,0x00a793f52ec7aaa1,0x002e5cb0616e3883,0x009cbf752f176feb,0x0029edce4fa090a3,0x00f6540a960a0275,0x00513985eef0e3bc,0x00ce2e586f6c7228)},
{FIELD_LITERAL(0x00b42f011dbc757c,0x004a8e19d4f07c42,0x00a6d7828318b7ff,0x0004c9ce49ba3c0f,0x005fe71688087b6a,0x006e1d8f9a3d84ed,0x0089693e7e8e9a1f,0x0073bf4183ba45c5)},
{FIELD_LITERAL(0x0029e8ce35530d30,0x00d20f389f61fe3a,0x00cf9e8ddf74e1d4,0x004bec01b04d4979,0x007d92c9f6fd5ddd,0x00c072fa91981808,0x009afda4fe8a1676,0x00c96522ee879a14)},
{FIELD_LITERAL(0x005f0cd9cd83497b,0x00e382f098d97f00,0x0073e37e004eed2e,0x000707fe98b12237,0x0016d92a2b73d561,0x00a42926ab390165,0x00b394db4b1cc8fc,0x002fa14a3f6efa33)},
{FIELD_LITERAL(0x0055076a513d05ee,0x00f076d43cec14ad,0x00a4e386b252faf4,0x00c0713b79b313eb,0x00507efa72f46f19,0x00141bc1e7c66844,0x005629ef060c19ea,0x0085327113d1772c)},
{FIELD_LITERAL(0x00ed490108514e35,0x006bed897e6b4958,0x0000f2cae0dc546c,0x008175eb3e5008e4,0x0093e3fe8f3aed42,0x00e9dbc15fd54d1a,0x00844979a4cfc0c1,0x00ea3194d64ea60b)},
{FIELD_LITERAL(0x00b64d054ec7ed5c,0x007b924cd329fbce,0x00fe8805a8737293,0x00fb82f1d52b43ae,0x004ea745c72e1a76,0x0095ba2552861c0c,0x00f66846c3547784,0x003b815bd05dc23c)},
{FIELD_LITERAL(0x00669e32fd197ef7,0x001dfca2c5e2f7c9,0x00a2ae0964a1e5e2,0x00b4334b15c91232,0x0096419585110d96,0x009c0b2262172a58,0x009d7c87cf6d35ca,0x008a5ce50d3cabf6)},
{FIELD_LITERAL(0x00888b9c1cf73530,0x00375346c6afecd2,0x00142240b35b74d3,0x00d952835f86a5f5,0x000665c2658eaf9a,0x00f29f43062b2033,0x00a19a58c5bc85f9,0x00e62ac95724a937)},
{FIELD_LITERAL(0x003bedc9ae9d1730,0x00fedd7c04cbc775,0x00c19abc4540c61d,0x00115294c57fb687,0x00663fceb174cd8f,0x001671f572b885b0,0x002d14694ed85978,0x00127282078a8e44)},
{FIELD_LITERAL(0x00e6d2822aa72eca,0x00d832957cdc0058,0x00dc60e5bed23e18,0x00b94b4c418b03a3,0x00df3b85d410a430,0x0055e81b70bc79d4,0x00081d9369cbd1a0,0x00f7fee3acf0c656)},
{FIELD_LITERAL(0x003baba41b5abffb,0x00661ee09fca8193,0x00e0c6c92e6aea59,0x00886c207bcbe591,0x00aef9e7798e8004,0x00164f599f4d707a,0x00bb1597a76d21f2,0x00fda82d5e025626)},
{FIELD_LITERAL(0x00552b53a9640f0e,0x005985236f4d88bf,0x00b7aaec965a8ae5,0x00cedada7b5ccf95,0x007b1ea2088f1902,0x0028445e38b4a7fa,0x0057f10ddc50efed,0x007637a3147bc5cb)},
{FIELD_LITERAL(0x008174fe4db53757,0x00930c4f4a35ecc8,0x000e9f82c1c95a8f,0x00c6480547d66e5e,0x00dce888f9a7bf39,0x006671a5022cb906,0x004823c19b5337a0,0x00455338b7fec529)},
{FIELD_LITERAL(0x005ac123fdc45964,0x00395057c2221d17,0x003c09c74cf84eb1,0x00b5ca859bbebf9d,0x001b26b274a7d235,0x00e8c63508e96a48,0x00edbce4d51d721e,0x00c49436797d6f83)},
{FIELD_LITERAL(0x0071595be88a7f40,0x00a05e6ac1c0fc87,0x00a01bf6538b29eb,0x00badcd80b881fb8,0x005bfe7af8049f8b,0x0084918e6ae35537,0x00ed4bd54759316e,0x007f135988d6b548)},
{FIELD_LITERAL(0x0075656c41e06629,0x0086059d83396637,0x004f304ecb457b37,0x00e3b4887db6be65,0x0020b54c263bb0be,0x0060a69193e561c3,0x00e6863f20dc8ce9,0x00afe16ac56e6478)}
{FIELD_LITERAL(0x00303cda6feea532,0x00860f1d5a3850e4,0x00226b9fa4728ccd,0x00e822938a0a0c0c,0x00263a61c9ea9216,0x001204029321b828,0x006a468360983c65,0x0002846f0a782143)},
{FIELD_LITERAL(0x00303cda6feea532,0x00860f1d5a3850e4,0x00226b9fa4728ccd,0x006822938a0a0c0c,0x00263a61c9ea9215,0x001204029321b828,0x006a468360983c65,0x0082846f0a782143)},
{FIELD_LITERAL(0x00ef8e22b275198d,0x00b0eb141a0b0e8b,0x001f6789da3cb38c,0x006d2ff8ed39073e,0x00610bdb69a167f3,0x00571f306c9689b4,0x00f557e6f84b2df8,0x002affd38b2c86db)},
{FIELD_LITERAL(0x00cea0fc8d2e88b5,0x00821612d69f1862,0x0074c283b3e67522,0x005a195ba05a876d,0x000cddfe557feea4,0x008046c795bcc5e5,0x00540969f4d6e119,0x00d27f96d6b143d5)},
{FIELD_LITERAL(0x000c3b1019d474e8,0x00e19533e4952284,0x00cc9810ba7c920a,0x00f103d2785945ac,0x00bfa5696cc69b34,0x00a8d3d51e9ca839,0x005623cb459586b9,0x00eae7ce1cd52e9e)},
{FIELD_LITERAL(0x0005a178751dd7d8,0x002cc3844c69c42f,0x00acbfe5efe10539,0x009c20f43431a65a,0x008435d96374a7b3,0x009ee57566877bd3,0x0044691725ed4757,0x001e87bb2fe2c6b2)},
{FIELD_LITERAL(0x000cedc4debf7a04,0x002ffa45000470ac,0x002e9f9678201915,0x0017da1208c4fe72,0x007d558cc7d656cb,0x0037a827287cf289,0x00142472d3441819,0x009c21f166cf8dd1)},
{FIELD_LITERAL(0x003ef83af164b2f2,0x000949a5a0525d0d,0x00f4498186cac051,0x00e77ac09ef126d2,0x0073ae0b2c9296e9,0x001c163f6922e3ed,0x0062946159321bea,0x00cfb79b22990b39)},
{FIELD_LITERAL(0x00b001431ca9e654,0x002d7e5eabcc9a3a,0x0052e8114c2f6747,0x0079ac4f94487f92,0x00bffd919b5d749c,0x00261f92ad15e620,0x00718397b7a97895,0x00c1443e6ebbc0c4)},
{FIELD_LITERAL(0x00eacd90c1e0a049,0x008977935b149fbe,0x0004cb9ba11c93dc,0x009fbd5b3470844d,0x004bc18c9bfc22cf,0x0057679a991839f3,0x00ef15b76fb4092e,0x0074a5173a225041)},
{FIELD_LITERAL(0x003f5f9d7ec4777b,0x00ab2e733c919c94,0x001bb6c035245ae5,0x00a325a49a883630,0x0033e9a9ea3cea2f,0x00e442a1eaa0e844,0x00b2116d5b0e71b8,0x00c16abed6d64047)},
{FIELD_LITERAL(0x00c560b5ed051165,0x001945adc5d65094,0x00e221865710f910,0x00cc12bc9e9b8ceb,0x004faa9518914e35,0x0017476d89d42f6d,0x00b8f637c8fa1c8b,0x0088c7d2790864b8)},
{FIELD_LITERAL(0x00ef7eafc1c69be6,0x0085d3855778fbea,0x002c8d5b450cb6f5,0x004e77de5e1e7fec,0x0047c057893abded,0x001b430b85d51e16,0x00965c7b45640c3c,0x00487b2bb1162b97)},
{FIELD_LITERAL(0x0099c73a311beec2,0x00a3eff38d8912ad,0x002efa9d1d7e8972,0x00f717ae1e14d126,0x002833f795850c8b,0x0066c12ad71486bd,0x00ae9889da4820eb,0x00d6044309555c08)},
{FIELD_LITERAL(0x004b1c5283d15e41,0x00669d8ea308ff75,0x0004390233f762a1,0x00e1d67b83cb6cec,0x003eebaa964c78b1,0x006b0aff965eb664,0x00b313d4470bdc37,0x008814ffcb3cb9d8)},
{FIELD_LITERAL(0x009724b8ce68db70,0x007678b5ed006f3d,0x00bdf4b89c0abd73,0x00299748e04c7c6d,0x00ddd86492c3c977,0x00c5a7febfa30a99,0x00ed84715b4b02bb,0x00319568adf70486)},
{FIELD_LITERAL(0x0070ff2d864de5bb,0x005a37eeb637ee95,0x0033741c258de160,0x00e6ca5cb1988f46,0x001ceabd92a24661,0x0030957bd500fe40,0x001c3362afe912c5,0x005187889f678bd2)},
{FIELD_LITERAL(0x0086835fc62bbdc7,0x009c3516ca4910a1,0x00956c71f8d00783,0x0095c78fcf63235f,0x00fc7ff6ba05c222,0x00cdd8b3f8d74a52,0x00ac5ae16de8256e,0x00e9d4be8ed48624)},
{FIELD_LITERAL(0x00c0ce11405df2d8,0x004e3f37b293d7b6,0x002410172e1ac6db,0x00b8dbff4bf8143d,0x003a7b409d56eb66,0x003e0f6a0dfef9af,0x0081c4e4d3645be1,0x00ce76076b127623)},
{FIELD_LITERAL(0x00f6ee0f98974239,0x0042d89af07d3a4f,0x00846b7fe84346b5,0x006a21fc6a8d39a1,0x00ac8bc2541ff2d9,0x006d4e2a77732732,0x009a39b694cc3f2f,0x0085c0aa2a404c8f)},
{FIELD_LITERAL(0x00b261101a218548,0x00c1cae96424277b,0x00869da0a77dd268,0x00bc0b09f8ec83ea,0x00d61027f8e82ba9,0x00aa4c85999dce67,0x00eac3132b9f3fe1,0x00fb9b0cf1c695d2)},
{FIELD_LITERAL(0x0043079295512f0d,0x0046a009861758e0,0x003ee2842a807378,0x0034cc9d1298e4fa,0x009744eb4d31b3ee,0x00afacec96650cd0,0x00ac891b313761ae,0x00e864d6d26e708a)},
{FIELD_LITERAL(0x00a84d7c8a23b491,0x0088e19aa868b27f,0x0005986d43e78ce9,0x00f28012f0606d28,0x0017ded7e10249b3,0x005ed4084b23af9b,0x00b9b0a940564472,0x00ad9056cceeb1f4)},
{FIELD_LITERAL(0x00db91b357fe755e,0x00a1aa544b15359c,0x00af4931a0195574,0x007686124fe11aef,0x00d1ead3c7b9ef7e,0x00aaf5fc580f8c15,0x00e727be147ee1ec,0x003c61c1e1577b86)},
{FIELD_LITERAL(0x009d3fca983220cf,0x00cd11acbc853dc4,0x0017590409d27f1d,0x00d2176698082802,0x00fa01251b2838c8,0x00dd297a0d9b51c6,0x00d76c92c045820a,0x00534bc7c46c9033)},
{FIELD_LITERAL(0x0080ed9bc9b07338,0x00fceac7745d2652,0x008a9d55f5f2cc69,0x0096ce72df301ac5,0x00f53232e7974d87,0x0071728c7ae73947,0x0090507602570778,0x00cb81cfd883b1b2)},
{FIELD_LITERAL(0x005011aadea373da,0x003a8578ec896034,0x00f20a6535fa6d71,0x005152d31e5a87cf,0x002bac1c8e68ca31,0x00b0e323db4c1381,0x00f1d596b7d5ae25,0x00eae458097cb4e0)},
{FIELD_LITERAL(0x00920ac80f9b0d21,0x00f80f7f73401246,0x0086d37849b557d6,0x0002bd4b317b752e,0x00b26463993a42bb,0x002070422a73b129,0x00341acaa0380cb3,0x00541914dd66a1b2)},
{FIELD_LITERAL(0x00c1513cd66abe8c,0x000139e01118944d,0x0064abbcb8080bbb,0x00b3b08202473142,0x00c629ef25da2403,0x00f0aec3310d9b7f,0x0050b2227472d8cd,0x00f6c8a922d41fb4)},
{FIELD_LITERAL(0x001075ccf26b7b1f,0x00bb6bb213170433,0x00e9491ad262da79,0x009ef4f48d2d384c,0x008992770766f09d,0x001584396b6b1101,0x00af3f8676c9feef,0x0024603c40269118)},
{FIELD_LITERAL(0x009dd7b31319527c,0x001e7ac948d873a9,0x00fa54b46ef9673a,0x0066efb8d5b02fe6,0x00754b1d3928aeae,0x0004262ac72a6f6b,0x0079b7d49a6eb026,0x003126a753540102)},
{FIELD_LITERAL(0x009666e24f693947,0x00f714311269d45f,0x0010ffac1d0c851c,0x0066e80c37363497,0x00f1f4ad010c60b0,0x0015c87408470ff7,0x00651d5e9c7766a4,0x008138819d7116de)},
{FIELD_LITERAL(0x003934b11c57253b,0x00ef308edf21f46e,0x00e54e99c7a16198,0x0080d57135764e63,0x00751c27b946bc24,0x00dd389ce4e9e129,0x00a1a2bfd1cd84dc,0x002fae73e5149b32)},
{FIELD_LITERAL(0x00911657dffb4cdd,0x00c100b7cc553d06,0x00449d075ec467cc,0x007062100bc64e70,0x0043cf86f7bd21e7,0x00f401dc4b797dea,0x005224afb2f62e65,0x00d1ede3fb5a42be)},
{FIELD_LITERAL(0x00f2ba36a41aa144,0x00a0c22d946ee18f,0x008aae8ef9a14f99,0x00eef4d79b19bb36,0x008e75ce3d27b1fc,0x00a65daa03b29a27,0x00d9cc83684eb145,0x009e1ed80cc2ed74)},
{FIELD_LITERAL(0x00bed953d1997988,0x00b93ed175a24128,0x00871c5963fb6365,0x00ca2df20014a787,0x00f5d9c1d0b34322,0x00f6f5942818db0a,0x004cc091f49c9906,0x00e8a188a60bff9f)},
{FIELD_LITERAL(0x0032c7762032fae8,0x00e4087232e0bc21,0x00f767344b6e8d85,0x00bbf369b76c2aa2,0x008a1f46c6e1570c,0x001368cd9780369f,0x007359a39d079430,0x0003646512921434)},
{FIELD_LITERAL(0x007c4b47ca7c73e7,0x005396221039734b,0x008b64ddf0e45d7e,0x00bfad5af285e6c2,0x008ec711c5b1a1a8,0x00cf663301237f98,0x00917ee3f1655126,0x004152f337efedd8)},
{FIELD_LITERAL(0x0007c7edc9305daa,0x000a6664f273701c,0x00f6e78795e200b1,0x005d05b9ecd2473e,0x0014f5f17c865786,0x00c7fd2d166fa995,0x004939a2d8eb80e0,0x002244ba0942c199)},
{FIELD_LITERAL(0x00321e767f0262cf,0x002e57d776caf68e,0x00bf2c94814f0437,0x00c339196acd622f,0x001db4cce71e2770,0x001ded5ddba6eee2,0x0078608ab1554c8d,0x00067fe0ab76365b)},
{FIELD_LITERAL(0x00f09758e11e3985,0x00169efdbd64fad3,0x00e8889b7d6dacd6,0x0035cdd58ea88209,0x00bcda47586d7f49,0x003cdddcb2879088,0x0016da70187e954b,0x009556ea2e92aacd)},
{FIELD_LITERAL(0x008cab16bd1ff897,0x00b389972cdf753f,0x00ea8ed1e46dfdc0,0x004fe7ef94c589f4,0x002b8ae9b805ecf3,0x0025c08d892874a5,0x0023938e98d44c4c,0x00f759134cabf69c)},
{FIELD_LITERAL(0x006c2a84678e4b3b,0x007a194aacd1868f,0x00ed0225af424761,0x00da0a6f293c64b8,0x001062ac5c6a7a18,0x0030f5775a8aeef4,0x0002acaad76b7af0,0x00410b8fd63a579f)},
{FIELD_LITERAL(0x001ec59db3d9590e,0x001e9e3f1c3f182d,0x0045a9c3ec2cab14,0x0008198572aeb673,0x00773b74068bd167,0x0012535eaa395434,0x0044dba9e3bbb74a,0x002fba4d3c74bd0e)},
{FIELD_LITERAL(0x0042bf08fe66922c,0x003318b8fbb49e8c,0x00d75946004aa14c,0x00f601586b42bf1c,0x00c74cf1d912fe66,0x00abcb36974b30ad,0x007eb78720c9d2b8,0x009f54ab7bd4df85)},
{FIELD_LITERAL(0x00db9fc948f73826,0x00fa8b3746ed8ee9,0x00132cb65aafbeb2,0x00c36ff3fe7925b8,0x00837daed353d2fe,0x00ec661be0667cf4,0x005beb8ed2e90204,0x00d77dd69e564967)},
{FIELD_LITERAL(0x0042e6268b861751,0x0008dd0469500c16,0x00b51b57c338a3fd,0x00cc4497d85cff6b,0x002f13d6b57c34a4,0x0083652eaf301105,0x00cc344294cc93a8,0x0060f4d02810e270)},
{FIELD_LITERAL(0x00a8954363cd518b,0x00ad171124bccb7b,0x0065f46a4adaae00,0x001b1a5b2a96e500,0x0043fe24f8233285,0x0066996d8ae1f2c3,0x00c530f3264169f9,0x00c0f92d07cf6a57)},
{FIELD_LITERAL(0x0036a55c6815d943,0x008c8d1def993db3,0x002e0e1e8ff7318f,0x00d883a4b92db00a,0x002f5e781ae33906,0x001a72adb235c06d,0x00f2e59e736e9caa,0x001a4b58e3031914)},
{FIELD_LITERAL(0x00d73bfae5e00844,0x00bf459766fb5f52,0x0061b4f5a5313cde,0x004392d4c3b95514,0x000d3551b1077523,0x0000998840ee5d71,0x006de6e340448b7b,0x00251aa504875d6e)},
{FIELD_LITERAL(0x003bf343427ac342,0x00adc0a78642b8c5,0x0003b893175a8314,0x0061a34ade5703bc,0x00ea3ea8bb71d632,0x00be0df9a1f198c2,0x0046dd8e7c1635fb,0x00f1523fdd25d5e5)},
{FIELD_LITERAL(0x00633f63fc9dd406,0x00e713ff80e04a43,0x0060c6e970f2d621,0x00a57cd7f0df1891,0x00f2406a550650bb,0x00b064290efdc684,0x001eab0144d17916,0x00cd15f863c293ab)},
{FIELD_LITERAL(0x0029cec55273f70d,0x007044ee275c6340,0x0040f637a93015e2,0x00338bb78db5aae9,0x001491b2a6132147,0x00a125d6cfe6bde3,0x005f7ac561ba8669,0x001d5eaea3fbaacf)},
{FIELD_LITERAL(0x00054e9635e3be31,0x000e43f31e2872be,0x00d05b1c9e339841,0x006fac50bd81fd98,0x00cdc7852eaebb09,0x004ff519b061991b,0x009099e8107d4c85,0x00273e24c36a4a61)},
{FIELD_LITERAL(0x00070b4441ef2c46,0x00efa5b02801a109,0x00bf0b8c3ee64adf,0x008a67e0b3452e98,0x001916b1f2fa7a74,0x00d781a78ff6cdc3,0x008682ce57e5c919,0x00cc1109dd210da3)},
{FIELD_LITERAL(0x00cae8aaff388663,0x005e983a35dda1c7,0x007ab1030d8e37f4,0x00e48940f5d032fe,0x006a36f9ef30b331,0x009be6f03958c757,0x0086231ceba91400,0x008bd0f7b823e7aa)},
{FIELD_LITERAL(0x00cf881ebef5a45a,0x004ebea78e7c6f2c,0x0090da9209cf26a0,0x00de2b2e4c775b84,0x0071d6031c3c15ae,0x00d9e927ef177d70,0x00894ee8c23896fd,0x00e3b3b401e41aad)},
{FIELD_LITERAL(0x00204fef26864170,0x00819269c5dee0f8,0x00bfb4713ec97966,0x0026339a6f34df78,0x001f26e64c761dc2,0x00effe3af313cb60,0x00e17b70138f601b,0x00f16e1ccd9ede5e)},
{FIELD_LITERAL(0x005d9a8353fdb2db,0x0055cc2048c698f0,0x00f6c4ac89657218,0x00525034d73faeb2,0x00435776fbda3c7d,0x0070ea5312323cbc,0x007a105d44d069fb,0x006dbc8d6dc786aa)},
{FIELD_LITERAL(0x0017cff19cd394ec,0x00fef7b810922587,0x00e6483970dff548,0x00ddf36ad6874264,0x00e61778523fcce2,0x0093a66c0c93b24a,0x00fd367114db7f86,0x007652d7ddce26dd)},
{FIELD_LITERAL(0x00d92ced7ba12843,0x00aea9c7771e86e7,0x0046639693354f7b,0x00a628dbb6a80c47,0x003a0b0507372953,0x00421113ab45c0d9,0x00e545f08362ab7a,0x0028ce087b4d6d96)},
{FIELD_LITERAL(0x00a67ee7cf9f99eb,0x005713b275f2ff68,0x00f1d536a841513d,0x00823b59b024712e,0x009c46b9d0d38cec,0x00cdb1595aa2d7d4,0x008375b3423d9af8,0x000ab0b516d978f7)},
{FIELD_LITERAL(0x00428dcb3c510b0f,0x00585607ea24bb4e,0x003736bf1603687a,0x00c47e568c4fe3c7,0x003cd00282848605,0x0043a487c3b91939,0x004ffc04e1095a06,0x00a4c989a3d4b918)},
{FIELD_LITERAL(0x00a8778d0e429f7a,0x004c02b059105a68,0x0016653b609da3ff,0x00d5107bd1a12d27,0x00b4708f9a771cab,0x00bb63b662033f69,0x0072f322240e7215,0x0019445b59c69222)},
{FIELD_LITERAL(0x00cf4f6069a658e6,0x0053ca52859436a6,0x0064b994d7e3e117,0x00cb469b9a07f534,0x00cfb68f399e9d47,0x00f0dcb8dac1c6e7,0x00f2ab67f538b3a5,0x0055544f178ab975)},
{FIELD_LITERAL(0x0099b7a2685d538c,0x00e2f1897b7c0018,0x003adac8ce48dae3,0x00089276d5c50c0c,0x00172fca07ad6717,0x00cb1a72f54069e5,0x004ee42f133545b3,0x00785f8651362f16)},
{FIELD_LITERAL(0x0049cbac38509e11,0x0015234505d42cdf,0x00794fb0b5840f1c,0x00496437344045a5,0x0031b6d944e4f9b0,0x00b207318ac1f5d8,0x0000c840da7f5c5d,0x00526f373a5c8814)},
{FIELD_LITERAL(0x002c7b7742d1dfd9,0x002cabeb18623c01,0x00055f5e3e044446,0x006c20f3b4ef54ba,0x00c600141ec6b35f,0x00354f437f1a32a3,0x00bac4624a3520f9,0x00c483f734a90691)},
{FIELD_LITERAL(0x0053a737d422918d,0x00f7fca1d8758625,0x00c360336dadb04c,0x00f38e3d9158a1b8,0x0069ce3b418e84c6,0x005d1697eca16ead,0x00f8bd6a35ece13d,0x007885dfc2b5afea)},
{FIELD_LITERAL(0x00c3617ae260776c,0x00b20dc3e96922d7,0x00a1a7802246706a,0x00ca6505a5240244,0x002246b62d919782,0x001439102d7aa9b3,0x00e8af1139e6422c,0x00c888d1b52f2b05)},
{FIELD_LITERAL(0x005b67690ffd41d9,0x005294f28df516f9,0x00a879272412fcb9,0x00098b629a6d1c8d,0x00fabd3c8050865a,0x00cd7e5b0a3879c5,0x00153238210f3423,0x00357cac101e9f42)},
{FIELD_LITERAL(0x008917b454444fb7,0x00f59247c97e441b,0x00a6200a6815152d,0x0009a4228601d254,0x001c0360559bd374,0x007563362039cb36,0x00bd75b48d74e32b,0x0017f515ac3499e8)},
{FIELD_LITERAL(0x001532a7ffe41c5a,0x00eb1edce358d6bf,0x00ddbacc7b678a7b,0x008a7b70f3c841a3,0x00f1923bf27d3f4c,0x000b2713ed8f7873,0x00aaf67e29047902,0x0044994a70b3976d)},
{FIELD_LITERAL(0x00d54e802082d42c,0x00a55aa0dce7cc6c,0x006477b96073f146,0x0082efe4ceb43594,0x00a922bcba026845,0x0077f19d1ab75182,0x00c2bb2737846e59,0x0004d7eec791dd33)},
{FIELD_LITERAL(0x0044588d1a81d680,0x00b0a9097208e4f8,0x00212605350dc57e,0x0028717cd2871123,0x00fb083c100fd979,0x0045a056ce063fdf,0x00a5d604b4dd6a41,0x001dabc08ba4e236)},
{FIELD_LITERAL(0x00c4887198d7a7fa,0x00244f98fb45784a,0x0045911e15a15d01,0x001d323d374c0966,0x00967c3915196562,0x0039373abd2f3c67,0x000d2c5614312423,0x0041cf2215442ce3)},
{FIELD_LITERAL(0x008ede889ada7f06,0x001611e91de2e135,0x00fdb9a458a471b9,0x00563484e03710d1,0x0031cc81925e3070,0x0062c97b3af80005,0x00fa733eea28edeb,0x00e82457e1ebbc88)},
{FIELD_LITERAL(0x006a0df5fe9b6f59,0x00a0d4ff46040d92,0x004a7cedb6f93250,0x00d1df8855b8c357,0x00e73a46086fd058,0x0048fb0add6dfe59,0x001e03a28f1b4e3d,0x00a871c993308d76)},
{FIELD_LITERAL(0x0030dbb2d1766ec8,0x00586c0ad138555e,0x00d1a34f9e91c77c,0x0063408ad0e89014,0x00d61231b05f6f5b,0x0009abf569f5fd8a,0x00aec67a110f1c43,0x0031d1a790938dd7)},
{FIELD_LITERAL(0x006cded841e2a862,0x00198d60af0ab6fb,0x0018f09db809e750,0x004e6ac676016263,0x00eafcd1620969cb,0x002c9784ca34917d,0x0054f00079796de7,0x00d9fab5c5972204)},
{FIELD_LITERAL(0x004bd0fee2438a83,0x00b571e62b0f83bd,0x0059287d7ce74800,0x00fb3631b645c3f0,0x00a018e977f78494,0x0091e27065c27b12,0x007696c1817165e0,0x008c40be7c45ba3a)},
{FIELD_LITERAL(0x00a0f326327cb684,0x001c7d0f672680ff,0x008c1c81ffb112d1,0x00f8f801674eddc8,0x00e926d5d48c2a9d,0x005bd6d954c6fe9a,0x004c6b24b4e33703,0x00d05eb5c09105cc)},
{FIELD_LITERAL(0x00d61731caacf2cf,0x002df0c7609e01c5,0x00306172208b1e2b,0x00b413fe4fb2b686,0x00826d360902a221,0x003f8d056e67e7f7,0x0065025b0175e989,0x00369add117865eb)},
{FIELD_LITERAL(0x00aaf895aec2fa11,0x000f892bc313eb52,0x005b1c794dad050b,0x003f8ec4864cec14,0x00af81058d0b90e5,0x00ebe43e183997bb,0x00a9d610f9f3e615,0x007acd8eec2e88d3)},
{FIELD_LITERAL(0x0049b2fab13812a3,0x00846db32cd60431,0x000177fa578c8d6c,0x00047d0e2ad4bc51,0x00b158ba38d1e588,0x006a45daad79e3f3,0x000997b93cab887b,0x00c47ea42fa23dc3)},
{FIELD_LITERAL(0x0012b6fef7aeb1ca,0x009412768194b6a7,0x00ff0d351f23ab93,0x007e8a14c1aff71b,0x006c1c0170c512bc,0x0016243ea02ab2e5,0x007bb6865b303f3e,0x0015ce6b29b159f4)},
{FIELD_LITERAL(0x009961cd02e68108,0x00e2035d3a1d0836,0x005d51f69b5e1a1d,0x004bccb4ea36edcd,0x0069be6a7aeef268,0x0063f4dd9de8d5a7,0x006283783092ca35,0x0075a31af2c35409)},
{FIELD_LITERAL(0x00c412365162e8cf,0x00012283fb34388a,0x003e6543babf39e2,0x00eead6b3a804978,0x0099c0314e8b326f,0x00e98e0a8d477a4f,0x00d2eb96b127a687,0x00ed8d7df87571bb)},
{FIELD_LITERAL(0x00777463e308cacf,0x00c8acb93950132d,0x00ebddbf4ca48b2c,0x0026ad7ca0795a0a,0x00f99a3d9a715064,0x000d60bcf9d4dfcc,0x005e65a73a437a06,0x0019d536a8db56c8)},
{FIELD_LITERAL(0x00192d7dd558d135,0x0027cd6a8323ffa7,0x00239f1a412dc1e7,0x0046b4b3be74fc5c,0x0020c47a2bef5bce,0x00aa17e48f43862b,0x00f7e26c96342e5f,0x0008011c530f39a9)},
{FIELD_LITERAL(0x00aad4ac569bf0f1,0x00a67adc90b27740,0x0048551369a5751a,0x0031252584a3306a,0x0084e15df770e6fc,0x00d7bba1c74b5805,0x00a80ef223af1012,0x0089c85ceb843a34)},
{FIELD_LITERAL(0x00c4545be4a54004,0x0099e11f60357e6c,0x001f3936d19515a6,0x007793df84341a6e,0x0051061886717ffa,0x00e9b0a660b28f85,0x0044ea685892de0d,0x000257d2a1fda9d9)},
{FIELD_LITERAL(0x007e8b01b24ac8a8,0x006cf3b0b5ca1337,0x00f1607d3e36a570,0x0039b7fab82991a1,0x00231777065840c5,0x00998e5afdd346f9,0x00b7dc3e64acc85f,0x00baacc748013ad6)},
{FIELD_LITERAL(0x008ea6a4177580bf,0x005fa1953e3f0378,0x005fe409ac74d614,0x00452327f477e047,0x00a4018507fb6073,0x007b6e71951caac8,0x0012b42ab8a6ce91,0x0080eca677294ab7)},
{FIELD_LITERAL(0x00a53edc023ba69b,0x00c6afa83ddde2e8,0x00c3f638b307b14e,0x004a357a64414062,0x00e4d94d8b582dc9,0x001739caf71695b7,0x0012431b2ae28de1,0x003b6bc98682907c)},
{FIELD_LITERAL(0x008a9a93be1f99d6,0x0079fa627cc699c8,0x00b0cfb134ba84c8,0x001c4b778249419a,0x00df4ab3d9c44f40,0x009f596e6c1a9e3c,0x001979c0df237316,0x00501e953a919b87)}
};

+ 14
- 12
src/GENERATED/c/ed448goldilocks/eddsa.c View File

@@ -31,6 +31,7 @@
#define NO_CONTEXT DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY 0
#define COFACTOR 4
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t NO_CONTEXT_POINTS_HERE = 0;
@@ -41,7 +42,7 @@ const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]
@@ -128,14 +129,14 @@ void decaf_ed448_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -191,13 +192,13 @@ void decaf_ed448_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -237,7 +238,7 @@ void decaf_ed448_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
@@ -259,10 +260,10 @@ decaf_error_t decaf_ed448_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -287,9 +288,10 @@ decaf_error_t decaf_ed448_verify (
&signature[DECAF_EDDSA_448_PUBLIC_BYTES],
DECAF_EDDSA_448_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<DECAF_448_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */
@@ -312,7 +314,7 @@ decaf_error_t decaf_ed448_verify_prehash (
) {
decaf_error_t ret;
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));


+ 62
- 61
src/GENERATED/c/ed448goldilocks/elligator.c View File

@@ -21,14 +21,18 @@
#define IMAGINE_TWIST 0
#define COFACTOR 4
static const int EDWARDS_D = -39081;
/* End of template stuff */

extern void API_NS(deisogenize) (
#define RISTRETTO_FACTOR DECAF_448_RISTRETTO_FACTOR
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */
extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

@@ -37,7 +41,8 @@ void API_NS(point_from_hash_nonuniform) (
const unsigned char ser[SER_BYTES]
) {
gf r0,r,a,b,c,N,e;
ignore_result(gf_deserialize(r0,ser,0));
const uint8_t mask = (uint8_t)(0xFE<<(7));
ignore_result(gf_deserialize(r0,ser,0,mask));
gf_strong_reduce(r0);
gf_sqr(a,r0);
gf_mul_qnr(r,a);
@@ -61,7 +66,7 @@ void API_NS(point_from_hash_nonuniform) (
/* s@a = +-|N.e| */
gf_mul(a,N,e);
gf_cond_neg(a,gf_hibit(a)^square); /* NB this is - what is listed in the paper */
gf_cond_neg(a,gf_lobit(a) ^ ~square);
/* t@b = -+ cN(r-1)((a-2d)e)^2 - 1 */
gf_mulw(c,e,1-2*EDWARDS_D); /* (a-2d)e */
@@ -107,23 +112,6 @@ void API_NS(point_from_hash_uniform) (
* log p == 1 mod 8 brainpool curves maybe?
*/
#define MAX(A,B) (((A)>(B)) ? (A) : (B))
#define PKP_MASK ((1<<(MAX(8*SER_BYTES + 0 - 448,0)))-1)
#if PKP_MASK != 0
static DECAF_INLINE mask_t plus_k_p (
uint8_t x[SER_BYTES],
uint32_t factor_
) {
uint32_t carry = 0;
uint64_t factor = factor_;
const uint8_t p[SER_BYTES] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
for (unsigned int i=0; i<SER_BYTES; i++) {
uint64_t tmp = carry + p[i] * factor + x[i];
/* tmp <= 2^32-1 + (2^32-1)*(2^8-1) + (2^8-1) = 2^40-1 */
x[i] = tmp; carry = tmp>>8;
}
return word_is_zero(carry);
}
#endif

decaf_error_t
API_NS(invert_elligator_nonuniform) (
@@ -133,60 +121,73 @@ API_NS(invert_elligator_nonuniform) (
) {
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_t_over_s = -(hint>>1 & 1),
sgn_altx = -(hint>>1 & 1),
sgn_r0 = -(hint>>2 & 1),
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0,
* change this mask extraction.
*/
sgn_ed_T = -(hint>>3 & 1);
gf a, b, c, d;
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T);
gf a,b,c;
API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T);
#if 448 == 8*SER_BYTES + 1 /* p521. */
sgn_r0 = 0;
mask_t is_identity = gf_eq(p->t,ZERO);
#if COFACTOR==4
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#elif IMAGINE_TWIST
/* Terrible, terrible special casing due to lots of 0/0 is deisogenize
* Basically we need to generate -D and +- i*RISTRETTO_FACTOR
*/
gf_mul_i(a,RISTRETTO_FACTOR);
gf_cond_sel(b,b,ONE,is_identity);
gf_cond_neg(a,sgn_altx);
gf_cond_sel(c,c,a,is_identity & sgn_ed_T);
gf_cond_sel(c,c,ZERO,is_identity & ~sgn_ed_T);
gf_mulw(a,ONE,-EDWARDS_D);
gf_cond_sel(c,c,a,is_identity & ~sgn_ed_T &~ sgn_altx);
#else
#error "Different special-casing goes here!"
#endif
/* ok, a = s; c = -t/s */
#if IMAGINE_TWIST
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
#endif
gf_add(b,a,b);
gf_sub(a,a,c);
gf_add(b,b,c);
gf_cond_swap(a,b,sgn_s);
gf_mul_qnr(c,b);
gf_mul(b,c,a);
mask_t succ = gf_isr(c,b);
succ |= gf_eq(b,ZERO);
gf_mul(b,c,a);
gf_sub(b,ONE,b); /* t+1 */
gf_sqr(c,a); /* s^2 */
mask_t is_identity = gf_eq(p->t,ZERO);

/* identity adjustments */
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */
/* if hint is 0, -> 0 */
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s);
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s);
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */
gf_add(a,b,d); /* num? */
gf_sub(d,d,b); /* den? */
gf_mul(b,a,d); /* n*d */
gf_cond_sel(a,d,a,sgn_s);
gf_mul_qnr(d,b);
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO);
gf_mul(b,a,c);
gf_cond_neg(b, sgn_r0^gf_hibit(b));
succ &= ~(gf_eq(b,ZERO) & sgn_r0);
#if COFACTOR == 8
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
#endif
#if 448 == 8*SER_BYTES + 1 /* p521. */
#error "this won't work because it needs to adjust high bit, not low bit"
sgn_r0 = 0;
#endif
gf_cond_neg(b, sgn_r0^gf_lobit(b));
/* Eliminate duplicate values for identity ... */
succ &= ~(gf_eq(b,ZERO) & (sgn_r0 | sgn_s));
// #if COFACTOR == 8
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
// #endif
#if 448 == 8*SER_BYTES + 1 /* p521 */
gf_serialize(recovered_hash,b,0);
#else
gf_serialize(recovered_hash,b,1);
#if PKP_MASK != 0
/* Add a multiple of p to make the result either almost-onto or completely onto. */
#if COFACTOR == 8
succ &= plus_k_p(recovered_hash, (hint >> 4) & PKP_MASK);
#else
succ &= plus_k_p(recovered_hash, (hint >> 3) & PKP_MASK);
#endif
#endif
#endif
#if 0
#if COFACTOR==8
recovered_hash[SER_BYTES-1] ^= (hint>>4)<<0;
#else
recovered_hash[SER_BYTES-1] ^= (hint>>3)<<0;
#endif
#endif
return decaf_succeed_if(mask_to_bool(succ));
}



+ 3
- 1
src/GENERATED/c/p25519/f_field.h View File

@@ -38,6 +38,7 @@ typedef struct gf_25519_s {
#define gf_s gf_25519_s
#define gf_eq gf_25519_eq
#define gf_hibit gf_25519_hibit
#define gf_lobit gf_25519_lobit
#define gf_copy gf_25519_copy
#define gf_add gf_25519_add
#define gf_sub gf_25519_sub
@@ -81,10 +82,11 @@ void gf_mulw_unsigned (gf_s *__restrict__ out, const gf a, uint32_t b);
void gf_sqr (gf_s *__restrict__ out, const gf a);
mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */
mask_t gf_eq (const gf x, const gf y);
mask_t gf_lobit (const gf x);
mask_t gf_hibit (const gf x);

void gf_serialize (uint8_t *serial, const gf x,int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_hibit,uint8_t hi_nmask);


#ifdef __cplusplus


+ 14
- 3
src/GENERATED/c/p25519/f_generic.c View File

@@ -52,14 +52,25 @@ mask_t gf_hibit(const gf x) {
return -(y->limb[0]&1);
}

/** Return high bit of x = low bit of 2x mod p */
mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** Deserialize from wire format; return -1 on success and 0 on failure. */
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) {
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit, uint8_t hi_nmask) {
unsigned int j=0, fill=0;
dword_t buffer = 0;
dsword_t scarry = 0;
const unsigned nbytes = with_hibit ? X_SER_BYTES : SER_BYTES;
UNROLL for (unsigned int i=0; i<NLIMBS; i++) {
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < (with_hibit ? X_SER_BYTES : SER_BYTES)) {
buffer |= ((dword_t)serial[j]) << fill;
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < nbytes) {
uint8_t sj = serial[j];
if (j==nbytes-1) sj &= ~hi_nmask;
buffer |= ((dword_t)sj) << fill;
fill += 8;
j++;
}


+ 3
- 1
src/GENERATED/c/p448/f_field.h View File

@@ -38,6 +38,7 @@ typedef struct gf_448_s {
#define gf_s gf_448_s
#define gf_eq gf_448_eq
#define gf_hibit gf_448_hibit
#define gf_lobit gf_448_lobit
#define gf_copy gf_448_copy
#define gf_add gf_448_add
#define gf_sub gf_448_sub
@@ -81,10 +82,11 @@ void gf_mulw_unsigned (gf_s *__restrict__ out, const gf a, uint32_t b);
void gf_sqr (gf_s *__restrict__ out, const gf a);
mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */
mask_t gf_eq (const gf x, const gf y);
mask_t gf_lobit (const gf x);
mask_t gf_hibit (const gf x);

void gf_serialize (uint8_t *serial, const gf x,int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_hibit,uint8_t hi_nmask);


#ifdef __cplusplus


+ 14
- 3
src/GENERATED/c/p448/f_generic.c View File

@@ -52,14 +52,25 @@ mask_t gf_hibit(const gf x) {
return -(y->limb[0]&1);
}

/** Return high bit of x = low bit of 2x mod p */
mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** Deserialize from wire format; return -1 on success and 0 on failure. */
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) {
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit, uint8_t hi_nmask) {
unsigned int j=0, fill=0;
dword_t buffer = 0;
dsword_t scarry = 0;
const unsigned nbytes = with_hibit ? X_SER_BYTES : SER_BYTES;
UNROLL for (unsigned int i=0; i<NLIMBS; i++) {
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < (with_hibit ? X_SER_BYTES : SER_BYTES)) {
buffer |= ((dword_t)serial[j]) << fill;
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < nbytes) {
uint8_t sj = serial[j];
if (j==nbytes-1) sj &= ~hi_nmask;
buffer |= ((dword_t)sj) << fill;
fill += 8;
j++;
}


+ 1
- 1
src/GENERATED/include/decaf.hxx View File

@@ -21,7 +21,7 @@
namespace decaf {
template <template<typename Group> class Run>
void run_for_all_curves() {
Run<IsoEd25519>::run();
Run<Ristretto>::run();
Run<Ed448Goldilocks>::run();
}
}


+ 30
- 6
src/GENERATED/include/decaf/ed255.h View File

@@ -42,6 +42,12 @@ extern const uint8_t * const DECAF_ED25519_NO_CONTEXT DECAF_API_VIS;
#define decaf_ed25519_prehash_update decaf_sha512_update
#define decaf_ed25519_prehash_destroy decaf_sha512_destroy

/** EdDSA encoding ratio. */
#define DECAF_255_EDDSA_ENCODE_RATIO 4

/** EdDSA decoding ratio. */
#define DECAF_255_EDDSA_DECODE_RATIO (8 / 4)

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -169,25 +175,43 @@ decaf_error_t decaf_ed25519_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by DECAF_255_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* DECAF_255_EDDSA_DECODE_RATIO when decoding, and by
* DECAF_255_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor 8, so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get DECAF_255_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void decaf_255_point_mul_by_cofactor_and_encode_like_eddsa (
void decaf_255_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES],
const decaf_255_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by DECAF_255_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on decaf_255_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t decaf_255_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t decaf_255_point_decode_like_eddsa_and_mul_by_ratio (
decaf_255_point_t p,
const uint8_t enc[DECAF_EDDSA_25519_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 5
- 5
src/GENERATED/include/decaf/ed255.hxx View File

@@ -43,8 +43,8 @@ namespace decaf {
/** A public key for crypto over some Group */
template <typename Group> struct EdDSA;

/** A public key for crypto over Iso-Ed25519 */
template<> struct EdDSA<IsoEd25519> {
/** A public key for crypto over Ristretto */
template<> struct EdDSA<Ristretto> {

/** @cond internal */
template<class CRTP, Prehashed> class Signing;
@@ -190,7 +190,7 @@ private:
public:
/** Underlying group */
typedef IsoEd25519 Group;
typedef Ristretto Group;
/** Signature size. */
static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
@@ -364,7 +364,7 @@ public:
/* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
/** Underlying group */
typedef IsoEd25519 Group;
typedef Ristretto Group;
/** Signature size. */
static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
@@ -417,7 +417,7 @@ public:
}
}; /* class PublicKey */

}; /* template<> struct EdDSA<IsoEd25519> */
}; /* template<> struct EdDSA<Ristretto> */

#undef DECAF_NOEXCEPT
} /* namespace decaf */


+ 30
- 6
src/GENERATED/include/decaf/ed448.h View File

@@ -41,6 +41,12 @@ extern "C" {
#define decaf_ed448_prehash_update decaf_shake256_update
#define decaf_ed448_prehash_destroy decaf_shake256_destroy

/** EdDSA encoding ratio. */
#define DECAF_448_EDDSA_ENCODE_RATIO 4

/** EdDSA decoding ratio. */
#define DECAF_448_EDDSA_DECODE_RATIO (4 / 4)

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -168,25 +174,43 @@ decaf_error_t decaf_ed448_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by DECAF_448_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* DECAF_448_EDDSA_DECODE_RATIO when decoding, and by
* DECAF_448_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor 4, so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get DECAF_448_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void decaf_448_point_mul_by_cofactor_and_encode_like_eddsa (
void decaf_448_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES],
const decaf_448_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by DECAF_448_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on decaf_448_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t decaf_448_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t decaf_448_point_decode_like_eddsa_and_mul_by_ratio (
decaf_448_point_t p,
const uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 41
- 0
src/GENERATED/include/decaf/point_255.h View File

@@ -52,6 +52,12 @@ typedef struct gf_25519_s {
/** Number of bits in the "which" field of an elligator inverse */
#define DECAF_255_INVERT_ELLIGATOR_WHICH_BITS 5

/** The cofactor the curve would have, if we hadn't removed it */
#define DECAF_255_REMOVED_COFACTOR 8

/** X25519 encoding ratio. */
#define DECAF_X25519_ENCODE_RATIO 4

/** Number of bytes in an x25519 public key */
#define DECAF_X25519_PUBLIC_BYTES 32

@@ -397,6 +403,31 @@ decaf_error_t decaf_x25519 (
const uint8_t scalar[DECAF_X25519_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by DECAF_X25519_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X25519_ENCODE_RATIO times the X25519
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void decaf_255_point_mul_by_ratio_and_encode_like_x25519 (
uint8_t out[DECAF_X25519_PUBLIC_BYTES],
const decaf_255_point_t p
) DECAF_API_VIS DECAF_NONNULL;

/** The base point for X25519 Diffie-Hellman */
extern const uint8_t decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] DECAF_API_VIS;

@@ -656,6 +687,16 @@ void decaf_255_point_from_hash_uniform (
* inverse sampling, this function succeeds or fails
* independently for different "which" values.
*
* This function isn't guaranteed to find every possible
* preimage, but it finds all except a small finite number.
* In particular, when the number of bits in the modulus isn't
* a multiple of 8 (i.e. for curve25519), it sets the high bits
* independently, which enables the generated data to be uniform.
* But it doesn't add p, so you'll never get exactly p from this
* function. This might change in the future, especially if
* we ever support eg Brainpool curves, where this could cause
* real nonuniformity.
*
* @param [out] recovered_hash Encoded data.
* @param [in] pt The point to encode.
* @param [in] which A value determining which inverse point


+ 65
- 18
src/GENERATED/include/decaf/point_255.hxx View File

@@ -53,10 +53,13 @@ namespace decaf {
/**
* Curve25519/Decaf instantiation of group.
*/
struct IsoEd25519 {
struct Ristretto {

/** The name of the curve */
static inline const char *name() { return "Iso-Ed25519"; }
static inline const char *name() { return "Ristretto"; }

/** The name of the curve */
static inline int bits() { return 255; }

/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = 8;
@@ -252,6 +255,21 @@ public:
/** Bytes required for hash */
static const size_t HASH_BYTES = DECAF_255_HASH_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t EDDSA_BYTES = DECAF_EDDSA_25519_PUBLIC_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X25519_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = DECAF_255_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = DECAF_255_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X25519_ENCODE_RATIO;

/**
* Size of a stegged element.
*
@@ -336,25 +354,51 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_25519_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return decaf_255_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return decaf_255_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_25519_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_25519_PUBLIC_BYTES);
decaf_255_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
decaf_255_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> &out
) const {
decaf_255_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_255_point_mul_by_ratio_and_encode_like_x25519(ret.data(),p);
return ret;
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
decaf_255_point_mul_by_ratio_and_encode_like_x25519(out.data(),p);
}

/**
* Map uniformly to the curve from a hash buffer.
* The empty or all-zero string maps to the identity, as does the string "\\x01".
@@ -578,7 +622,7 @@ public:
* initializer for points which makes this equal to the identity.
*/
inline Precomputed (
const Precomputed_U &yours = *default_value()
const Precomputed_U &yours = *decaf_255_precomputed_base
) DECAF_NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>(yours) {}


@@ -723,15 +767,15 @@ public:
}
};

}; /* struct IsoEd25519 */
}; /* struct Ristretto */

/** @cond internal */
inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul (
const FixedBlock<IsoEd25519::Point::SER_BYTES> &in,
inline SecureBuffer Ristretto::Scalar::direct_scalarmul (
const FixedBlock<Ristretto::Point::SER_BYTES> &in,
decaf_bool_t allow_identity,
decaf_bool_t short_circuit
) const /*throw(CryptoException)*/ {
SecureBuffer out(IsoEd25519::Point::SER_BYTES);
SecureBuffer out(Ristretto::Point::SER_BYTES);
if (DECAF_SUCCESS !=
decaf_255_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit)
) {
@@ -740,9 +784,9 @@ inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul (
return out;
}

inline decaf_error_t IsoEd25519::Scalar::direct_scalarmul_noexcept (
FixedBuffer<IsoEd25519::Point::SER_BYTES> &out,
const FixedBlock<IsoEd25519::Point::SER_BYTES> &in,
inline decaf_error_t Ristretto::Scalar::direct_scalarmul_noexcept (
FixedBuffer<Ristretto::Point::SER_BYTES> &out,
const FixedBlock<Ristretto::Point::SER_BYTES> &in,
decaf_bool_t allow_identity,
decaf_bool_t short_circuit
) const DECAF_NOEXCEPT {
@@ -750,6 +794,9 @@ inline decaf_error_t IsoEd25519::Scalar::direct_scalarmul_noexcept (
}
/** @endcond */

typedef Ristretto IsoEd25519;


#undef DECAF_NOEXCEPT
} /* namespace decaf */



+ 41
- 0
src/GENERATED/include/decaf/point_448.h View File

@@ -52,6 +52,12 @@ typedef struct gf_448_s {
/** Number of bits in the "which" field of an elligator inverse */
#define DECAF_448_INVERT_ELLIGATOR_WHICH_BITS 3

/** The cofactor the curve would have, if we hadn't removed it */
#define DECAF_448_REMOVED_COFACTOR 4

/** X448 encoding ratio. */
#define DECAF_X448_ENCODE_RATIO 2

/** Number of bytes in an x448 public key */
#define DECAF_X448_PUBLIC_BYTES 56

@@ -397,6 +403,31 @@ decaf_error_t decaf_x448 (
const uint8_t scalar[DECAF_X448_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by DECAF_X448_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X448_ENCODE_RATIO times the X448
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void decaf_448_point_mul_by_ratio_and_encode_like_x448 (
uint8_t out[DECAF_X448_PUBLIC_BYTES],
const decaf_448_point_t p
) DECAF_API_VIS DECAF_NONNULL;

/** The base point for X448 Diffie-Hellman */
extern const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] DECAF_API_VIS;

@@ -656,6 +687,16 @@ void decaf_448_point_from_hash_uniform (
* inverse sampling, this function succeeds or fails
* independently for different "which" values.
*
* This function isn't guaranteed to find every possible
* preimage, but it finds all except a small finite number.
* In particular, when the number of bits in the modulus isn't
* a multiple of 8 (i.e. for curve25519), it sets the high bits
* independently, which enables the generated data to be uniform.
* But it doesn't add p, so you'll never get exactly p from this
* function. This might change in the future, especially if
* we ever support eg Brainpool curves, where this could cause
* real nonuniformity.
*
* @param [out] recovered_hash Encoded data.
* @param [in] pt The point to encode.
* @param [in] which A value determining which inverse point


+ 55
- 9
src/GENERATED/include/decaf/point_448.hxx View File

@@ -58,6 +58,9 @@ struct Ed448Goldilocks {
/** The name of the curve */
static inline const char *name() { return "Ed448-Goldilocks"; }

/** The name of the curve */
static inline int bits() { return 448; }

/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = 4;

@@ -252,6 +255,21 @@ public:
/** Bytes required for hash */
static const size_t HASH_BYTES = DECAF_448_HASH_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t EDDSA_BYTES = DECAF_EDDSA_448_PUBLIC_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X448_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = DECAF_448_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = DECAF_448_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X448_ENCODE_RATIO;

/**
* Size of a stegged element.
*
@@ -336,25 +354,51 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_448_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return decaf_448_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return decaf_448_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_448_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_448_PUBLIC_BYTES);
decaf_448_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
decaf_448_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> &out
) const {
decaf_448_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
decaf_448_point_mul_by_ratio_and_encode_like_x448(ret.data(),p);
return ret;
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
decaf_448_point_mul_by_ratio_and_encode_like_x448(out.data(),p);
}

/**
* Map uniformly to the curve from a hash buffer.
* The empty or all-zero string maps to the identity, as does the string "\\x01".
@@ -578,7 +622,7 @@ public:
* initializer for points which makes this equal to the identity.
*/
inline Precomputed (
const Precomputed_U &yours = *default_value()
const Precomputed_U &yours = *decaf_448_precomputed_base
) DECAF_NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>(yours) {}


@@ -750,6 +794,8 @@ inline decaf_error_t Ed448Goldilocks::Scalar::direct_scalarmul_noexcept (
}
/** @endcond */



#undef DECAF_NOEXCEPT
} /* namespace decaf */



+ 20
- 4
src/generator/curve_data.py View File

@@ -1,4 +1,5 @@
from collections import namedtuple
from binascii import unhexlify

comb_config = namedtuple("comb_config",["n","t","s"])
wnaf_config = namedtuple("wnaf_config",["fixed","var"])
@@ -22,14 +23,18 @@ field_data = {

curve_data = {
"curve25519" : {
"altname" : "IsoEd25519",
"iso_to" : "Curve25519",
"name" : "Iso-Ed25519",
"name" : "Ristretto",
"cofactor" : 8,
"field" : "p25519",
"scalar_bits" : 253,
"d": -121665,
"trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a,
"mont_base": 9,
"rist_base": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"eddsa_encode_ratio": 4,
"x_encode_ratio": 4,
"combs":comb_config(3,5,17),
"wnaf":wnaf_config(5,3),
@@ -41,12 +46,16 @@ curve_data = {
"eddsa_sigma_iso": 1
},
"ed448goldilocks" : {
"eddsa_encode_ratio": 4,
"x_encode_ratio": 2,
"altname": None,
"name" : "Ed448-Goldilocks",
"cofactor" : 4,
"field" : "p448",
"scalar_bits" : 446,
"d": -39081,
"trace": 0x10cd77058eec492d944a725bf7a4cf635c8e9c2ab721cf5b5529eec34,
"rist_base": "6666666666666666666666666666666666666666666666666666666633333333333333333333333333333333333333333333333333333333",
"mont_base": 5,
"combs":comb_config(5,5,18),
@@ -71,7 +80,7 @@ def ser(x,bits,paren=None):
first = False
return out

def msqrt(x,p,hi_bit_clear = True):
def msqrt(x,p,hi_bit_clear = True, lo_bit_clear = False):
if p % 4 == 3: ret = pow(x,(p+1)//4,p)
elif p % 8 == 5:
for u in range(1,1000):
@@ -83,6 +92,8 @@ def msqrt(x,p,hi_bit_clear = True):
if (ret**2-x) % p != 0: raise Exception("No sqrt")
if hi_bit_clear and ret > p//2: ret = p-ret
# lo_bit_clear overrides hi_bit_clear because it's not default
if lo_bit_clear and (ret & 1): ret = p-ret
return ret
def ceil_log2(x):
@@ -120,13 +131,18 @@ for curve,data in curve_data.items():
if "eddsa_sigma_iso" not in data:
data["eddsa_sigma_iso"] = 0
if "rist_base_decoded" not in data:
data["rist_base_decoded"] = sum(
ord(b)<<(8*i) for i,b in enumerate(unhexlify(data["rist_base"]))
)

if "imagine_twist" not in data:
# This is a HACK. The real problem is that iso-Ed25519
# has points at infinity unless you IMAGINE_TWIST.
#
# Also there are lots of bugs when cofactor=8 && !IMAGINE_TWIST.
# (FIXME, eventually)
# Also there are lots of bugs when cofactor=8 != IMAGINE_TWIST.
# (FUTURE: fix all this to support other curves, eventually)
if data["modulus"]%4 == 3: data["imagine_twist"] = 0
else: data["imagine_twist"] = 1
# data["imagine_twist"] = 0


+ 5
- 0
src/include/field.h View File

@@ -103,5 +103,10 @@ static DECAF_INLINE void gf_div_qnr(gf_s *__restrict__ out, const gf x) {
#endif
}

#if P_MOD_8 == 5
#define gf_mul_i gf_mul_qnr
#define gf_div_i gf_div_qnr
#endif


#endif // __GF_H__

+ 185
- 229
src/per_curve/decaf.tmpl.c View File

@@ -37,10 +37,23 @@ static const scalar_t point_scalarmul_adjustment = {{{

const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] = { $(ser(mont_base,8)) };

#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL(
$(ser(msqrt(1-d,modulus),gf_lit_limb_bits) if cofactor == 8 else "/* NONE */")
)};
#define RISTRETTO_FACTOR $(C_NS)_RISTRETTO_FACTOR
const gf RISTRETTO_FACTOR = {{{
$(ser(msqrt(d-1 if imagine_twist else -d,modulus,hi_bit_clear=True),gf_lit_limb_bits))
}}};

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

/* End of template stuff */
@@ -98,128 +111,112 @@ gf_invert(gf y, const gf x, int assert_nonzero) {
gf_copy(y, t2);
}

/** Return high bit of x = low bit of 2x mod p */
static mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** identity = (0,1) */
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}};

/* Predeclare because not static: called by elligator */
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_s,
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void) toggle_rotation;
gf b, d;
gf_s *c = s, *a = minus_t_over_s;
gf_mulw(a, p->y, 1-EDWARDS_D);
gf_mul(c, a, p->t); /* -dYT, with EDWARDS_D = d-1 */
gf_mul(a, p->x, p->z);
gf_sub(d, c, a); /* aXZ-dYT with a=-1 */
gf_add(a, p->z, p->y);
gf_sub(b, p->z, p->y);
gf_mul(c, b, a);
gf_mulw(b, c, -EDWARDS_D); /* (a-d)(Z+Y)(Z-Y) */
mask_t ok = gf_isr (a,b); /* r in the paper */
(void)ok; assert(ok | gf_eq(b,ZERO));
gf_mulw (b, a, -EDWARDS_D); /* u in the paper */

gf_mul(c,a,d); /* r(aZX-dYT) */
gf_mul(a,b,p->z); /* uZ */
gf_add(a,a,a); /* 2uZ */
mask_t tg = toggle_hibit_t_over_s ^ ~gf_hibit(minus_t_over_s);
gf_cond_neg(minus_t_over_s, tg); /* t/s <-? -t/s */
gf_cond_neg(c, tg); /* u <- -u if negative. */
gf_add(d,c,p->y);
gf_mul(s,b,d);
gf_cond_neg(s, toggle_hibit_s ^ gf_hibit(s));
#else
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1;
gf_add(t1,p->x,p->t);
gf_sub(t2,p->x,p->t);
gf_mul(t3,t1,t2); /* t3 = num */
gf_sqr(t2,p->x);
gf_mul(t1,t2,t3);
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */
gf_isr(t1,t2); /* t1 = isr */
gf_mul(t2,t1,t3); /* t2 = ratio */
gf_mul(t4,t2,RISTRETTO_FACTOR);
mask_t negx = gf_lobit(t4) ^ toggle_altx;
gf_cond_neg(t2, negx);
gf_mul(t3,t2,p->z);
gf_sub(t3,t3,p->t);
gf_mul(t2,t3,p->x);
gf_mulw(t4,t2,-1-TWISTED_D);
gf_mul(s,t4,t1);
mask_t lobs = gf_lobit(s);
gf_cond_neg(s,lobs);
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
#elif COFACTOR == 8 && IMAGINE_TWIST
/* More complicated because of rotation */
/* MAGIC This code is wrong for certain non-Curve25519 curves;
* check if it's because of Cofactor==8 or IMAGINE_TWIST */
gf c, d;
gf_s *b = s, *a = minus_t_over_s;

#if IMAGINE_TWIST
gf x, t;
gf_div_qnr(x,p->x);
gf_div_qnr(t,p->t);
gf_add ( a, p->z, x );
gf_sub ( b, p->z, x );
gf_mul ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 - X^2 */
#else
const gf_s *x = p->x, *t = p->t;
gf_sqr ( a, p->z );
gf_sqr ( b, p->x );
gf_add ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 + X^2 */
#endif
/* Here: c = "zx" in the SAGE code = Z^2 - aX^2 */
gf_mul ( a, p->z, t ); /* "tz" = T*Z */
gf_sqr ( b, a );
gf_mul ( d, b, c ); /* (TZ)^2 * (Z^2-aX^2) */
mask_t ok = gf_isr(b, d);
(void)ok; assert(ok | gf_eq(d,ZERO));
gf_mul ( d, b, a ); /* "osx" = 1 / sqrt(z^2-ax^2) */
gf_mul ( a, b, c );
gf_mul ( b, a, d ); /* 1/tz */

mask_t rotate;
#if (COFACTOR == 8)
gf e;
gf_sqr(e, p->z);
gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */
rotate = gf_hibit(a) ^ toggle_rotation;
/* Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x */
gf_mul ( a, b, c );
gf_cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate );
gf_cond_sel ( e, p->y, x, rotate );
#else
const gf_s *e = x;
(void)toggle_rotation;
rotate = 0;
#endif
gf_mul ( c, a, d ); // new "osx"
gf_mul ( a, c, p->z );
gf_add ( minus_t_over_s, a, a ); // 2 * "osx" * Z
gf_mul ( d, b, p->z );
mask_t tg = toggle_hibit_t_over_s ^~ gf_hibit(minus_t_over_s);
gf_cond_neg ( minus_t_over_s, tg );
gf_cond_neg ( c, rotate ^ tg );
gf_add ( d, d, c );
gf_mul ( s, d, e ); /* here "x" = y unless rotate */
gf_cond_neg ( s, toggle_hibit_s ^ gf_hibit(s) );
gf t1,t2,t3,t4,t5;
gf_add(t1,p->z,p->y);
gf_sub(t2,p->z,p->y);
gf_mul(t3,t1,t2); /* t3 = num */
gf_mul(t2,p->x,p->y); /* t2 = den */
gf_sqr(t1,t2);
gf_mul(t4,t1,t3);
gf_mulw(t1,t4,-1-TWISTED_D);
gf_isr(t4,t1); /* isqrt(num*(a-d)*den^2) */
gf_mul(t1,t2,t4);
gf_mul(t2,t1,RISTRETTO_FACTOR); /* t2 = "iden" in ristretto.sage */
gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */

/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_i(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */
mask_t rotate = toggle_rotation ^ gf_lobit(t3);
/* Rotate if altxy is negative */
gf_cond_swap(t1,t2,rotate);
gf_mul_i(t4,p->x);
gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */
gf_mul_i(t5,RISTRETTO_FACTOR); /* t5 = imi */
gf_mul(t3,t5,t2); /* iden * imi */
gf_mul(t2,t5,t1);
gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */
mask_t negx = gf_lobit(t5) ^ toggle_altx;
gf_cond_neg(t1,negx^rotate);
gf_mul(t2,t1,p->z);
gf_add(t2,t2,ONE);
gf_mul(inv_el_sum,t2,t4);
gf_mul(s,inv_el_sum,t3);
mask_t negs = gf_lobit(s);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
gf_cond_neg(inv_el_m1,negz);
gf_sub(inv_el_m1,inv_el_m1,t4);
#else
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
}

void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
gf s, mtos;
API_NS(deisogenize)(s,mtos,p,0,0,0);
gf_serialize(ser,s,0);
gf s,ie1,ie2;
API_NS(deisogenize)(s,ie1,ie2,p,0,0,0);
gf_serialize(ser,s,1);
}

decaf_error_t API_NS(point_decode) (
@@ -227,89 +224,54 @@ decaf_error_t API_NS(point_decode) (
const unsigned char ser[SER_BYTES],
decaf_bool_t allow_identity
) {
gf s, a, b, c, d, e, f;
mask_t succ = gf_deserialize(s, ser, 0);
mask_t zero = gf_eq(s, ZERO);
succ &= bool_to_mask(allow_identity) | ~zero;
gf_sqr ( a, s ); /* s^2 */
gf s, s2, num, tmp;
gf_s *tmp2=s2, *ynum=p->z, *isr=p->x, *den=p->t;
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
gf_sqr(s2,s); /* s^2 = -as^2 */
#if IMAGINE_TWIST
gf_sub ( f, ONE, a ); /* f = 1-as^2 = 1-s^2*/
#else
gf_add ( f, ONE, a ); /* f = 1-as^2 = 1+s^2 */
gf_sub(s2,ZERO,s2); /* -as^2 */
#endif
succ &= ~ gf_eq( f, ZERO );
gf_sqr ( b, f ); /* (1-as^2)^2 = 1 - 2as^2 + a^2 s^4 */
gf_mulw ( c, a, 4*IMAGINE_TWIST-4*EDWARDS_D );
gf_add ( c, c, b ); /* t^2 = 1 + (2a-4d) s^2 + s^4 */
gf_mul ( d, f, s ); /* s * (1-as^2) for denoms */
gf_sqr ( e, d ); /* s^2 * (1-as^2)^2 */
gf_mul ( b, c, e ); /* t^2 * s^2 * (1-as^2)^2 */
succ &= gf_isr(e,b) | gf_eq(b,ZERO); /* e = 1/(t s (1-as^2)) */
gf_mul ( b, e, d ); /* 1 / t */
gf_mul ( d, e, c ); /* t / (s(1-as^2)) */
gf_mul ( e, d, f ); /* t / s */
mask_t negtos = gf_hibit(e);
gf_cond_neg(b, negtos);
gf_cond_neg(d, negtos);

#if IMAGINE_TWIST
gf_add ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
#else
gf_sub ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */
gf_sub(den,ONE,s2); /* 1+as^2 */
gf_add(ynum,ONE,s2); /* 1-as^2 */
gf_mulw(num,s2,-4*TWISTED_D);
gf_sqr(tmp,den); /* tmp = den^2 */
gf_add(num,tmp,num); /* num = den^2 - 4*d*s^2 */
gf_mul(tmp2,num,tmp); /* tmp2 = num*den^2 */
succ &= gf_isr(isr,tmp2); /* isr = 1/sqrt(num*den^2) */
gf_mul(tmp,isr,den); /* isr*den */
gf_mul(p->y,tmp,ynum); /* isr*den*(1-as^2) */
gf_mul(tmp2,tmp,s); /* s*isr*den */
gf_add(tmp2,tmp2,tmp2); /* 2*s*isr*den */
gf_mul(tmp,tmp2,isr); /* 2*s*isr^2*den */
gf_mul(p->x,tmp,num); /* 2*s*isr^2*den*num */
gf_mul(tmp,tmp2,RISTRETTO_FACTOR); /* 2*s*isr*den*magic */
gf_cond_neg(p->x,gf_lobit(tmp)); /* flip x */
#if COFACTOR==8
/* Additionally check y != 0 and x*y*isomagic nonegative */
succ &= ~gf_eq(p->y,ZERO);
gf_mul(tmp,p->x,p->y);
gf_mul(tmp2,tmp,RISTRETTO_FACTOR);
succ &= ~gf_lobit(tmp2);
#endif

#if COFACTOR == 8
gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */
succ &= ~gf_lobit(a); /* = ~gf_hibit(a/2), since gf_hibit(x) = gf_lobit(2x) */
#endif
gf_mul ( a, f, b ); /* y = (1-s^2) / t */
gf_mul ( p->y, p->z, a ); /* Y = yZ */
#if IMAGINE_TWIST
gf_add ( b, s, s );
gf_mul(p->x, b, SQRT_MINUS_ONE); /* Curve25519 */
#else
gf_add ( p->x, s, s );
#endif
gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */
#if UNSAFE_CURVE_HAS_POINTS_AT_INFINITY
/* This can't happen for any of the supported configurations.
*
* If it can happen (because s=1), it's because the curve has points
* at infinity, which means that there may be critical security bugs
* elsewhere in the library. In that case, it's better that you hit
* the assertion in point_valid, which will happen in the test suite
* since it tests s=1.
*
* This debugging option is to allow testing of IMAGINE_TWIST = 0 on
* Ed25519, without hitting that assertion. Don't use it in
* production.
*/
succ &= ~gf_eq(p->z,ZERO);
gf_copy(tmp,p->x);
gf_mul_i(p->x,tmp);
#endif

/* Fill in z and t */
gf_copy(p->z,ONE);
gf_mul(p->t,p->x,p->y);
p->y->limb[0] -= zero;
assert(API_NS(point_valid)(p) | ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

#if IMAGINE_TWIST
#define TWISTED_D (-(EDWARDS_D))
#else
#define TWISTED_D ((EDWARDS_D)-1)
#endif

#if TWISTED_D < 0
#define EFF_D (-(TWISTED_D))
#define NEG_D 1
#else
#define EFF_D TWISTED_D
#define NEG_D 0
#endif

void API_NS(point_sub) (
point_t p,
const point_t q,
@@ -854,7 +816,7 @@ void API_NS(point_debugging_pscale) (
) {
gf gfac,tmp;
/* NB this means you'll never pscale by negative numbers for p521 */
ignore_result(gf_deserialize(gfac,factor,0));
ignore_result(gf_deserialize(gfac,factor,0,0));
gf_cond_sel(gfac,gfac,ONE,gf_eq(gfac,ZERO));
gf_mul(tmp,p->x,gfac);
gf_copy(q->x,tmp);
@@ -1067,7 +1029,7 @@ decaf_error_t API_NS(direct_scalarmul) (
return succ;
}

void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
void API_NS(point_mul_by_ratio_and_encode_like_eddsa) (
uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
const point_t p
) {
@@ -1105,15 +1067,20 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_mul ( y, u, t ); // (x^2+y^2)(2z^2-y^2+x^2)
gf_mul ( u, z, t );
gf_copy( z, u );
gf_mul ( u, x, SQRT_ONE_MINUS_D );
gf_mul ( u, x, RISTRETTO_FACTOR );
#if IMAGINE_TWIST
gf_mul_i( x, u );
#else
#error "... probably wrong"
gf_copy( x, u );
#endif
decaf_bzero(u,sizeof(u));
}
#elif IMAGINE_TWIST
{
API_NS(point_double)(q,q);
API_NS(point_double)(q,q);
gf_mul_qnr(x, q->x);
gf_mul_i(x, q->x);
gf_copy(y, q->y);
gf_copy(z, q->z);
}
@@ -1126,7 +1093,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
gf_add( u, x, t );
gf_add( z, q->y, q->x );
gf_sqr ( y, z);
gf_sub ( y, u, y );
gf_sub ( y, y, u );
gf_sub ( z, t, x );
gf_sqr ( x, q->z );
gf_add ( t, x, x);
@@ -1155,7 +1122,7 @@ void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) (
}


decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_error_t API_NS(point_decode_like_eddsa_and_mul_by_ratio) (
point_t p,
const uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES]
) {
@@ -1165,7 +1132,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
mask_t low = ~word_is_zero(enc2[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES-1] & 0x80);
enc2[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES-1] &= ~0x80;
mask_t succ = gf_deserialize(p->y, enc2, 1);
mask_t succ = gf_deserialize(p->y, enc2, 1, 0);
#if $(gf_bits % 8) == 0
succ &= word_is_zero(enc2[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES-1]);
#endif
@@ -1185,7 +1152,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
succ &= gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */
gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */
gf_cond_neg(p->x,~gf_lobit(p->x)^low);
gf_cond_neg(p->x,gf_lobit(p->x)^low);
gf_copy(p->z,ONE);
#if EDDSA_USE_SIGMA_ISOGENY
@@ -1210,8 +1177,9 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
gf_sub ( p->t, a, c ); // y^2 - x^2
gf_sqr ( p->x, p->z );
gf_add ( p->z, p->x, p->x );
gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_mul ( c, a, SQRT_ONE_MINUS_D );
gf_sub ( c, p->z, p->t ); // 2z^2 - y^2 + x^2
gf_div_i ( a, c );
gf_mul ( c, a, RISTRETTO_FACTOR );
gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2)
gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2)
gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2)
@@ -1254,6 +1222,7 @@ decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) (
decaf_bzero(enc2,sizeof(enc2));
assert(API_NS(point_valid)(p) || ~succ);
return decaf_succeed_if(mask_to_bool(succ));
}

@@ -1263,7 +1232,7 @@ decaf_error_t decaf_x$(gf_shortname) (
const uint8_t scalar[X_PRIVATE_BYTES]
) {
gf x1, x2, z2, x3, z3, t1, t2;
ignore_result(gf_deserialize(x1,base,1));
ignore_result(gf_deserialize(x1,base,1,0));
gf_copy(x2,ONE);
gf_copy(z2,ZERO);
gf_copy(x3,x1);
@@ -1334,15 +1303,8 @@ void decaf_ed$(gf_shortname)_convert_public_key_to_x$(gf_shortname) (
const uint8_t ed[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES]
) {
gf y;
{
uint8_t enc2[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES];
memcpy(enc2,ed,sizeof(enc2));

/* retrieve y from the ed compressed point */
enc2[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES-1] &= ~0x80;
ignore_result(gf_deserialize(y, enc2, 0));
decaf_bzero(enc2,sizeof(enc2));
}
const uint8_t mask = (uint8_t)(0xFE<<($((gf_bits-1)%8)));
ignore_result(gf_deserialize(y, ed, 1, mask));
{
gf n,d;
@@ -1379,6 +1341,26 @@ void decaf_x$(gf_shortname)_generate_key (
decaf_x$(gf_shortname)_derive_public_key(out,scalar);
}

void API_NS(point_mul_by_ratio_and_encode_like_x$(gf_shortname)) (
uint8_t out[X_PUBLIC_BYTES],
const point_t p
) {
point_t q;
#if COFACTOR == 8
point_double_internal(q,p,1);
#else
API_NS(point_copy)(q,p);
#endif
gf_invert(q->t,q->x,0); /* 1/x */
gf_mul(q->z,q->t,q->y); /* y/x */
gf_sqr(q->y,q->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(q->y,ZERO,q->y);
#endif
gf_serialize(out,q->y,1);
API_NS(point_destroy(q));
}

void decaf_x$(gf_shortname)_derive_public_key (
uint8_t out[X_PUBLIC_BYTES],
const uint8_t scalar[X_PRIVATE_BYTES]
@@ -1394,39 +1376,13 @@ void decaf_x$(gf_shortname)_derive_public_key (
scalar_t the_scalar;
API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2));
/* We're gonna isogenize by 2, so divide by 2.
*
* Why by 2, even though it's a 4-isogeny?
*
* The isogeny map looks like
* Montgomery <-2-> Jacobi <-2-> Edwards
*
* Since the Jacobi base point is the PREimage of the iso to
* the Montgomery curve, and we're going
* Jacobi -> Edwards -> Jacobi -> Montgomery,
* we pick up only a factor of 2 over Jacobi -> Montgomery.
*/
API_NS(scalar_halve)(the_scalar,the_scalar);
/* Compensate for the encoding ratio */
for (unsigned i=1; i<DECAF_X$(gf_shortname)_ENCODE_RATIO; i<<=1) {
API_NS(scalar_halve)(the_scalar,the_scalar);
}
point_t p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar);
/* Isogenize to Montgomery curve.
*
* Why isn't this just a separate function, eg decaf_encode_like_x$(gf_shortname)?
* Basically because in general it does the wrong thing if there is a cofactor
* component in the input. In this function though, there isn't a cofactor
* component in the input.
*/
gf_invert(p->t,p->x,0); /* 1/x */
gf_mul(p->z,p->t,p->y); /* y/x */
gf_sqr(p->y,p->z); /* (y/x)^2 */
#if IMAGINE_TWIST
gf_sub(p->y,ZERO,p->y);
#endif
gf_serialize(out,p->y,1);
decaf_bzero(scalar2,sizeof(scalar2));
API_NS(scalar_destroy)(the_scalar);
API_NS(point_mul_by_ratio_and_encode_like_x$(gf_shortname))(out,p);
API_NS(point_destroy)(p);
}



+ 13
- 4
src/per_curve/decaf_gen_tables.tmpl.c View File

@@ -10,7 +10,7 @@

#define API_NS(_id) $(c_ns)_##_id
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = {
$(ser(msqrt(mont_base,modulus),8))
$(ser(rist_base_decoded,8))
};

/* To satisfy linker. */
@@ -52,16 +52,25 @@ int main(int argc, char **argv) {
API_NS(point_t) real_point_base;
int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0);
if (ret != DECAF_SUCCESS) return 1;
if (ret != DECAF_SUCCESS) {
fprintf(stderr, "Can't decode base point!\n");
return 1;
}
API_NS(precomputed_s) *pre;
ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s));
if (ret || !pre) return 1;
if (ret || !pre) {
fprintf(stderr, "Can't allocate space for precomputed table\n");
return 1;
}
API_NS(precompute)(pre, real_point_base);
struct niels_s *pre_wnaf;
ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs));
if (ret || !pre_wnaf) return 1;
if (ret || !pre_wnaf) {
fprintf(stderr, "Can't allocate space for precomputed WNAF table\n");
return 1;
}
API_NS(precompute_wnafs)(pre_wnaf, real_point_base);

const gf_s *output;


+ 13
- 17
src/per_curve/eddsa.tmpl.c View File

@@ -22,18 +22,13 @@
#define NO_CONTEXT DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY $(eddsa_sigma_iso)
#define COFACTOR $(cofactor)
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t NO_CONTEXT_POINTS_HERE = 0;
const uint8_t * const DECAF_ED$(gf_shortname)_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
#endif

/* EDDSA_BASE_POINT_RATIO = 1 or 2
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)

static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES]
) {
@@ -119,14 +114,14 @@ void decaf_ed$(gf_shortname)_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<$(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
@@ -182,13 +177,13 @@ void decaf_ed$(gf_shortname)_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < $(C_NS)_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}
API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
@@ -228,7 +223,7 @@ void decaf_ed$(gf_shortname)_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed$(gf_shortname)_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
@@ -250,10 +245,10 @@ decaf_error_t decaf_ed$(gf_shortname)_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (DECAF_SUCCESS != error) { return error; }
error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (DECAF_SUCCESS != error) { return error; }
API_NS(scalar_t) challenge_scalar;
@@ -278,9 +273,10 @@ decaf_error_t decaf_ed$(gf_shortname)_verify (
&signature[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
#endif
for (unsigned c=1; c<$(C_NS)_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}
/* pk_point = -c(x(P)) + (cx + k)G = kG */
@@ -303,7 +299,7 @@ decaf_error_t decaf_ed$(gf_shortname)_verify_prehash (
) {
decaf_error_t ret;
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
decaf_ed$(gf_shortname)_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));


+ 30
- 6
src/per_curve/eddsa.tmpl.h View File

@@ -26,6 +26,12 @@ $("extern const uint8_t * const DECAF_ED" + gf_shortname + "_NO_CONTEXT DECAF_AP
#define decaf_ed$(gf_shortname)_prehash_update decaf_$(eddsa_hash)_update
#define decaf_ed$(gf_shortname)_prehash_destroy decaf_$(eddsa_hash)_destroy

/** EdDSA encoding ratio. */
#define $(C_NS)_EDDSA_ENCODE_RATIO $(eddsa_encode_ratio)

/** EdDSA decoding ratio. */
#define $(C_NS)_EDDSA_DECODE_RATIO ($(cofactor) / $(eddsa_encode_ratio))

/**
* @brief EdDSA key generation. This function uses a different (non-Decaf)
* encoding.
@@ -153,25 +159,43 @@ decaf_error_t decaf_ed$(gf_shortname)_verify_prehash (

/**
* @brief EdDSA point encoding. Used internally, exposed externally.
* Multiplies the point by the current cofactor first.
* Multiplies by $(C_NS)_EDDSA_ENCODE_RATIO first.
*
* The multiplication is required because the EdDSA encoding represents
* the cofactor information, but the Decaf encoding ignores it (which
* is the whole point). So if you decode from EdDSA and re-encode to
* EdDSA, the cofactor info must get cleared, because the intermediate
* representation doesn't track it.
*
* The way libdecaf handles this is to multiply by
* $(C_NS)_EDDSA_DECODE_RATIO when decoding, and by
* $(C_NS)_EDDSA_ENCODE_RATIO when encoding. The product of these
* ratios is always exactly the cofactor $(cofactor), so the cofactor
* ends up cleared one way or another. But exactly how that shakes
* out depends on the base points specified in RFC 8032.
*
* The upshot is that if you pass the Decaf/Ristretto base point to
* this function, you will get $(C_NS)_EDDSA_ENCODE_RATIO times the
* EdDSA base point.
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
void $(c_ns)_point_mul_by_cofactor_and_encode_like_eddsa (
void $(c_ns)_point_mul_by_ratio_and_encode_like_eddsa (
uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES],
const $(c_ns)_point_t p
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;

/**
* @brief EdDSA point decoding. Remember that while points on the
* EdDSA curves have cofactor information, Decaf ignores (quotients
* out) all cofactor information.
* @brief EdDSA point decoding. Multiplies by $(C_NS)_EDDSA_DECODE_RATIO,
* and ignores cofactor information.
*
* See notes on $(c_ns)_point_mul_by_ratio_and_encode_like_eddsa
*
* @param [out] enc The encoded point.
* @param [in] p The point.
*/
decaf_error_t $(c_ns)_point_decode_like_eddsa_and_ignore_cofactor (
decaf_error_t $(c_ns)_point_decode_like_eddsa_and_mul_by_ratio (
$(c_ns)_point_t p,
const uint8_t enc[DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;


+ 62
- 61
src/per_curve/elligator.tmpl.c View File

@@ -10,14 +10,18 @@
#define IMAGINE_TWIST $(imagine_twist)
#define COFACTOR $(cofactor)
static const int EDWARDS_D = $(d);
/* End of template stuff */

extern void API_NS(deisogenize) (
#define RISTRETTO_FACTOR $(C_NS)_RISTRETTO_FACTOR
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */
extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ minus_t_over_s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
const point_t p,
mask_t toggle_hibit_s,
mask_t toggle_hibit_t_over_s,
mask_t toggle_altx,
mask_t toggle_rotation
);

@@ -26,7 +30,8 @@ void API_NS(point_from_hash_nonuniform) (
const unsigned char ser[SER_BYTES]
) {
gf r0,r,a,b,c,N,e;
ignore_result(gf_deserialize(r0,ser,0));
const uint8_t mask = (uint8_t)(0xFE<<($((gf_bits-1)%8)));
ignore_result(gf_deserialize(r0,ser,0,mask));
gf_strong_reduce(r0);
gf_sqr(a,r0);
gf_mul_qnr(r,a);
@@ -50,7 +55,7 @@ void API_NS(point_from_hash_nonuniform) (
/* s@a = +-|N.e| */
gf_mul(a,N,e);
gf_cond_neg(a,gf_hibit(a)^square); /* NB this is - what is listed in the paper */
gf_cond_neg(a,gf_lobit(a) ^ ~square);
/* t@b = -+ cN(r-1)((a-2d)e)^2 - 1 */
gf_mulw(c,e,1-2*EDWARDS_D); /* (a-2d)e */
@@ -96,23 +101,6 @@ void API_NS(point_from_hash_uniform) (
* log p == 1 mod 8 brainpool curves maybe?
*/
#define MAX(A,B) (((A)>(B)) ? (A) : (B))
#define PKP_MASK ((1<<(MAX(8*SER_BYTES + $(elligator_onto) - $(gf_bits),0)))-1)
#if PKP_MASK != 0
static DECAF_INLINE mask_t plus_k_p (
uint8_t x[SER_BYTES],
uint32_t factor_
) {
uint32_t carry = 0;
uint64_t factor = factor_;
const uint8_t p[SER_BYTES] = { $(ser(modulus,8)) };
for (unsigned int i=0; i<SER_BYTES; i++) {
uint64_t tmp = carry + p[i] * factor + x[i];
/* tmp <= 2^32-1 + (2^32-1)*(2^8-1) + (2^8-1) = 2^40-1 */
x[i] = tmp; carry = tmp>>8;
}
return word_is_zero(carry);
}
#endif

decaf_error_t
API_NS(invert_elligator_nonuniform) (
@@ -122,60 +110,73 @@ API_NS(invert_elligator_nonuniform) (
) {
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_t_over_s = -(hint>>1 & 1),
sgn_altx = -(hint>>1 & 1),
sgn_r0 = -(hint>>2 & 1),
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0,
* change this mask extraction.
*/
sgn_ed_T = -(hint>>3 & 1);
gf a, b, c, d;
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T);
gf a,b,c;
API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T);
#if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */
sgn_r0 = 0;
mask_t is_identity = gf_eq(p->t,ZERO);
#if COFACTOR==4
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#elif IMAGINE_TWIST
/* Terrible, terrible special casing due to lots of 0/0 is deisogenize
* Basically we need to generate -D and +- i*RISTRETTO_FACTOR
*/
gf_mul_i(a,RISTRETTO_FACTOR);
gf_cond_sel(b,b,ONE,is_identity);
gf_cond_neg(a,sgn_altx);
gf_cond_sel(c,c,a,is_identity & sgn_ed_T);
gf_cond_sel(c,c,ZERO,is_identity & ~sgn_ed_T);
gf_mulw(a,ONE,-EDWARDS_D);
gf_cond_sel(c,c,a,is_identity & ~sgn_ed_T &~ sgn_altx);
#else
#error "Different special-casing goes here!"
#endif
/* ok, a = s; c = -t/s */
#if IMAGINE_TWIST
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
#endif
gf_add(b,a,b);
gf_sub(a,a,c);
gf_add(b,b,c);
gf_cond_swap(a,b,sgn_s);
gf_mul_qnr(c,b);
gf_mul(b,c,a);
mask_t succ = gf_isr(c,b);
succ |= gf_eq(b,ZERO);
gf_mul(b,c,a);
gf_sub(b,ONE,b); /* t+1 */
gf_sqr(c,a); /* s^2 */
mask_t is_identity = gf_eq(p->t,ZERO);

/* identity adjustments */
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */
/* if hint is 0, -> 0 */
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s);
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s);
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */
gf_add(a,b,d); /* num? */
gf_sub(d,d,b); /* den? */
gf_mul(b,a,d); /* n*d */
gf_cond_sel(a,d,a,sgn_s);
gf_mul_qnr(d,b);
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO);
gf_mul(b,a,c);
gf_cond_neg(b, sgn_r0^gf_hibit(b));
succ &= ~(gf_eq(b,ZERO) & sgn_r0);
#if COFACTOR == 8
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
#endif
#if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */
#error "this won't work because it needs to adjust high bit, not low bit"
sgn_r0 = 0;
#endif
gf_cond_neg(b, sgn_r0^gf_lobit(b));
/* Eliminate duplicate values for identity ... */
succ &= ~(gf_eq(b,ZERO) & (sgn_r0 | sgn_s));
// #if COFACTOR == 8
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
// #endif
#if $(gf_bits) == 8*SER_BYTES + 1 /* p521 */
gf_serialize(recovered_hash,b,0);
#else
gf_serialize(recovered_hash,b,1);
#if PKP_MASK != 0
/* Add a multiple of p to make the result either almost-onto or completely onto. */
#if COFACTOR == 8
succ &= plus_k_p(recovered_hash, (hint >> 4) & PKP_MASK);
#else
succ &= plus_k_p(recovered_hash, (hint >> 3) & PKP_MASK);
#endif
#endif
#endif
#if $(gf_bits%8)
#if COFACTOR==8
recovered_hash[SER_BYTES-1] ^= (hint>>4)<<$(gf_bits%8);
#else
recovered_hash[SER_BYTES-1] ^= (hint>>3)<<$(gf_bits%8);
#endif
#endif
return decaf_succeed_if(mask_to_bool(succ));
}



+ 41
- 0
src/per_curve/point.tmpl.h View File

@@ -37,6 +37,12 @@ typedef struct gf_$(gf_shortname)_s {
/** Number of bits in the "which" field of an elligator inverse */
#define $(C_NS)_INVERT_ELLIGATOR_WHICH_BITS $(ceil_log2(cofactor) + 7 + elligator_onto - ((gf_bits-2) % 8))

/** The cofactor the curve would have, if we hadn't removed it */
#define $(C_NS)_REMOVED_COFACTOR $(cofactor)

/** X$(gf_shortname) encoding ratio. */
#define DECAF_X$(gf_shortname)_ENCODE_RATIO $(x_encode_ratio)

/** Number of bytes in an x$(gf_shortname) public key */
#define DECAF_X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)//8 + 1)

@@ -382,6 +388,31 @@ decaf_error_t decaf_x$(gf_shortname) (
const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;

/**
* @brief Multiply a point by DECAF_X$(gf_shortname)_ENCODE_RATIO,
* then encode it like RFC 7748.
*
* This function is mainly used internally, but is exported in case
* it will be useful.
*
* The ratio is necessary because the internal representation doesn't
* track the cofactor information, so on output we must clear the cofactor.
* This would multiply by the cofactor, but in fact internally libdecaf's
* points are always even, so it multiplies by half the cofactor instead.
*
* As it happens, this aligns with the base point definitions; that is,
* if you pass the Decaf/Ristretto base point to this function, the result
* will be DECAF_X$(gf_shortname)_ENCODE_RATIO times the X$(gf_shortname)
* base point.
*
* @param [out] out The scaled and encoded point.
* @param [in] p The point to be scaled and encoded.
*/
void $(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname) (
uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
const $(c_ns)_point_t p
) DECAF_API_VIS DECAF_NONNULL;

/** The base point for X$(gf_shortname) Diffie-Hellman */
extern const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] DECAF_API_VIS;

@@ -641,6 +672,16 @@ void $(c_ns)_point_from_hash_uniform (
* inverse sampling, this function succeeds or fails
* independently for different "which" values.
*
* This function isn't guaranteed to find every possible
* preimage, but it finds all except a small finite number.
* In particular, when the number of bits in the modulus isn't
* a multiple of 8 (i.e. for curve25519), it sets the high bits
* independently, which enables the generated data to be uniform.
* But it doesn't add p, so you'll never get exactly p from this
* function. This might change in the future, especially if
* we ever support eg Brainpool curves, where this could cause
* real nonuniformity.
*
* @param [out] recovered_hash Encoded data.
* @param [in] pt The point to encode.
* @param [in] which A value determining which inverse point


+ 55
- 9
src/per_curve/point.tmpl.hxx View File

@@ -45,6 +45,9 @@ struct $(cxx_ns) {
/** The name of the curve */
static inline const char *name() { return "$(name)"; }

/** The name of the curve */
static inline int bits() { return $(gf_bits); }

/** The curve's cofactor (removed, but useful for testing) */
static const int REMOVED_COFACTOR = $(cofactor);

@@ -239,6 +242,21 @@ public:
/** Bytes required for hash */
static const size_t HASH_BYTES = $(C_NS)_HASH_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t EDDSA_BYTES = DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES;

/** Bytes required for EdDSA encoding */
static const size_t LADDER_BYTES = DECAF_X$(gf_shortname)_PUBLIC_BYTES;
/** Ratio due to EdDSA encoding */
static const int EDDSA_ENCODE_RATIO = $(C_NS)_EDDSA_ENCODE_RATIO;
/** Ratio due to EdDSA decoding */
static const int EDDSA_DECODE_RATIO = $(C_NS)_EDDSA_DECODE_RATIO;
/** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X$(gf_shortname)_ENCODE_RATIO;

/**
* Size of a stegged element.
*
@@ -323,25 +341,51 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point.
* Contents of the point are undefined.
*/
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_ignore_cofactor_noexcept (
inline decaf_error_t DECAF_WARN_UNUSED decode_like_eddsa_and_mul_by_ratio_noexcept (
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &buffer
) DECAF_NOEXCEPT {
return $(c_ns)_point_decode_like_eddsa_and_ignore_cofactor(p,buffer.data());
return $(c_ns)_point_decode_like_eddsa_and_mul_by_ratio(p,buffer.data());
}

inline void decode_like_eddsa_and_ignore_cofactor (
/**
* Decode from EDDSA, multiply by EDDSA_DECODE_RATIO, and ignore any
* remaining cofactor information.
* @throw CryptoException if the input point was invalid.
*/
inline void decode_like_eddsa_and_mul_by_ratio(
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &buffer
) /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode_like_eddsa_and_ignore_cofactor_noexcept(buffer)) throw(CryptoException());
if (DECAF_SUCCESS != decode_like_eddsa_and_mul_by_ratio_noexcept(buffer)) throw(CryptoException());
}

/** Multiply out cofactor and encode like EdDSA. */
inline SecureBuffer mul_by_cofactor_and_encode_like_eddsa() const {
/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline SecureBuffer mul_by_ratio_and_encode_like_eddsa() const {
SecureBuffer ret(DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES);
$(c_ns)_point_mul_by_cofactor_and_encode_like_eddsa(ret.data(),p);
$(c_ns)_point_mul_by_ratio_and_encode_like_eddsa(ret.data(),p);
return ret;
}

/** Multiply by EDDSA_ENCODE_RATIO and encode like EdDSA. */
inline void mul_by_ratio_and_encode_like_eddsa(
FixedBuffer<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> &out
) const {
$(c_ns)_point_mul_by_ratio_and_encode_like_eddsa(out.data(),p);
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline SecureBuffer mul_by_ratio_and_encode_like_ladder() const {
SecureBuffer ret(LADDER_BYTES);
$(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(ret.data(),p);
return ret;
}

/** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
$(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(out.data(),p);
}

/**
* Map uniformly to the curve from a hash buffer.
* The empty or all-zero string maps to the identity, as does the string "\\x01".
@@ -565,7 +609,7 @@ public:
* initializer for points which makes this equal to the identity.
*/
inline Precomputed (
const Precomputed_U &yours = *default_value()
const Precomputed_U &yours = *$(c_ns)_precomputed_base
) DECAF_NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>(yours) {}


@@ -737,5 +781,7 @@ inline decaf_error_t $(cxx_ns)::Scalar::direct_scalarmul_noexcept (
}
/** @endcond */

$("typedef %s %s;\n" % (cxx_ns,altname) if altname else "")

#undef DECAF_NOEXCEPT
} /* namespace decaf */

+ 3
- 1
src/per_field/f_field.tmpl.h View File

@@ -23,6 +23,7 @@ typedef struct gf_$(gf_shortname)_s {
#define gf_s gf_$(gf_shortname)_s
#define gf_eq gf_$(gf_shortname)_eq
#define gf_hibit gf_$(gf_shortname)_hibit
#define gf_lobit gf_$(gf_shortname)_lobit
#define gf_copy gf_$(gf_shortname)_copy
#define gf_add gf_$(gf_shortname)_add
#define gf_sub gf_$(gf_shortname)_sub
@@ -66,10 +67,11 @@ void gf_mulw_unsigned (gf_s *__restrict__ out, const gf a, uint32_t b);
void gf_sqr (gf_s *__restrict__ out, const gf a);
mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */
mask_t gf_eq (const gf x, const gf y);
mask_t gf_lobit (const gf x);
mask_t gf_hibit (const gf x);

void gf_serialize (uint8_t *serial, const gf x,int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_hibit,uint8_t hi_nmask);


#ifdef __cplusplus


+ 14
- 3
src/per_field/f_generic.tmpl.c View File

@@ -41,14 +41,25 @@ mask_t gf_hibit(const gf x) {
return -(y->limb[0]&1);
}

/** Return high bit of x = low bit of 2x mod p */
mask_t gf_lobit(const gf x) {
gf y;
gf_copy(y,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}

/** Deserialize from wire format; return -1 on success and 0 on failure. */
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) {
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit, uint8_t hi_nmask) {
unsigned int j=0, fill=0;
dword_t buffer = 0;
dsword_t scarry = 0;
const unsigned nbytes = with_hibit ? X_SER_BYTES : SER_BYTES;
UNROLL for (unsigned int i=0; i<NLIMBS; i++) {
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < (with_hibit ? X_SER_BYTES : SER_BYTES)) {
buffer |= ((dword_t)serial[j]) << fill;
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < nbytes) {
uint8_t sj = serial[j];
if (j==nbytes-1) sj &= ~hi_nmask;
buffer |= ((dword_t)sj) << fill;
fill += 8;
j++;
}


+ 214
- 0
test/ristretto.cxx View File

@@ -0,0 +1,214 @@
/**
* @file ristretto.cxx
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* @brief Ristretto implementation widget
*/

#include <decaf.hxx>
#include <stdio.h>
using namespace decaf;

inline int hexi(char c) {
if (c >= '0' && c <= '9') return c-'0';
if (c >= 'a' && c <= 'f') return c-'a'+0xa;
if (c >= 'A' && c <= 'F') return c-'A'+0xa;
return -1;
}

int parsehex(uint8_t *out, size_t sizeof_out, const char *hex) {
size_t l = strlen(hex);
if (l%2 != 0) {
fprintf(stderr,"String should be hex, but has odd length\n: %s\n", hex);
return -1;
} else if (l/2 > sizeof_out) {
fprintf(stderr,"Argument is too long: %s\n", hex);
return -1;
}
memset(out,0,sizeof_out);
int ret1,ret2;
for (size_t i=0; i<l/2; i++) {
if ( (ret1 = hexi(hex[2*i ])) < 0
|| (ret2 = hexi(hex[2*i+1])) < 0) {
fprintf(stderr,"Invalid hex %s\n",hex);
return -1;
}
out[i] = ret1*16+ret2;
}
return 0;
}

void printhex(const uint8_t *in, size_t sizeof_in) {
for (; sizeof_in > 0; in++,sizeof_in--) {
printf("%02x",*in);
}
}


static int g_argc = 0;
static char **g_argv = NULL;
static int error = 0;
static int done = 0;

void usage() {
const char *me=g_argv[0];
if (!me) me = "ristretto";
for (unsigned i=0; g_argv[0][i]; i++) {
if (g_argv[0][i] == '/' && g_argv[0][i+1] != 0 && g_argv[0][i+1] != '/') {
me = &g_argv[0][i];
}
}
fprintf(stderr,"Usage: %s [points] [operations] ...\n", me);
fprintf(stderr," -b 255|448: Set which group to use (sometimes inferred from lengths)\n");
fprintf(stderr," -E: Display output as Elligator inverses\n");
fprintf(stderr," -D: Display output in EdDSA format (times clearing ratio)\n");
fprintf(stderr," -R: Display raw xyzt\n");
fprintf(stderr," -C: Display output in X[25519|448] format\n");
fprintf(stderr," -H: ... divide by encoding ratio first\n");
fprintf(stderr,"\n");
fprintf(stderr," Ways to create points:\n");
fprintf(stderr," [hex]: Point from point data as hex\n");
fprintf(stderr," -e [hex]: Create point by hashing to curve using elligator\n");
fprintf(stderr," base: Base point of curve\n");
fprintf(stderr," identity: Identity point of curve\n");
fprintf(stderr,"\n");
fprintf(stderr," Operations:\n");
fprintf(stderr," -n [point]: negative of point\n");
fprintf(stderr," -s [scalar] * [point]: Hash to curve using elligator\n");
fprintf(stderr," [point] + [point]: Add two points\n");
fprintf(stderr,"\n");
fprintf(stderr," NB: this is a debugging widget. It doesn't yet have order of operations.\n");
fprintf(stderr," *** DON'T USE THIS UTILITY FOR ACTUAL CRYPTO! ***\n");
fprintf(stderr," It's only for debugging!\n");
fprintf(stderr,"\n");
exit(-2);
}

template<typename Group> class Run {
public:
static void run() {
uint8_t tmp[Group::Point::SER_BYTES];
typename Group::Point a,b;
typename Group::Scalar s;
bool plus=false, empty=true, elligator=false, mul=false, scalar=false, div=false, torque=false,
scalarempty=true, neg=false, einv=false, like_eddsa=false, like_x=false, decoeff=false, raw=false;
if (done || error) return;
for (int i=1; i<g_argc && !error; i++) {
bool point = false;
if (!strcmp(g_argv[i],"-b") && ++i<g_argc) {
if (atoi(g_argv[i]) == Group::bits()) continue;
else return;
} else if (!strcmp(g_argv[i],"+")) {
if (elligator || scalar || empty) usage();
plus = true;
} else if (!strcmp(g_argv[i],"-n")) {
neg = !neg;
} else if (!strcmp(g_argv[i],"-E")) {
einv = true;
} else if (!strcmp(g_argv[i],"-R")) {
raw = true;
} else if (!strcmp(g_argv[i],"-D")) {
like_eddsa = true;
} else if (!strcmp(g_argv[i],"-C")) {
like_x = true;
} else if (!strcmp(g_argv[i],"-H")) {
decoeff = true;
} else if (!strcmp(g_argv[i],"-T")) {
torque = true;
} else if (!strcmp(g_argv[i],"*")) {
if (elligator || scalar || scalarempty || div) usage();
mul = true;
} else if (!strcmp(g_argv[i],"/")) {
if (elligator || scalar || scalarempty || mul) usage();
div = true;
} else if (!strcmp(g_argv[i],"-s")) {
if (elligator || scalar || !scalarempty) usage();
scalar = true;
} else if (!strcmp(g_argv[i],"-e")) {
if (elligator || scalar) usage();
elligator = true;
} else if (!strcmp(g_argv[i],"base")) {
if (elligator || scalar) usage();
b = b.base();
point = true;
} else if (!strcmp(g_argv[i],"identity")) {
if (elligator || scalar) usage();
b = b.identity();
point = true;
} else if ((strlen(g_argv[i]) == 2*sizeof(tmp)
|| ((scalar || elligator) && strlen(g_argv[i]) <= 2*sizeof(tmp)))
&& !(error=parsehex(tmp,sizeof(tmp),g_argv[i]))) {
if (scalar) {
s = Block(tmp,sizeof(tmp)); scalar=false; scalarempty=false;
} else if (elligator) {
point = true;
b.set_to_hash(Block(tmp,sizeof(tmp))); elligator=false;
} else if (DECAF_SUCCESS != b.decode(Block(tmp,sizeof(tmp)))) {
fprintf(stderr,"Error: %s isn't in the group\n",g_argv[i]);
error = -1;
} else {
point = true;
}
} else if (error || !empty) usage();

if (point) {
if (neg) { b = -b; neg = false; }
if (div) { b /= s; div=false; }
if (torque) { b = b.debugging_torque(); torque=false; }
if (mul) { b *= s; mul=false; }
if (empty) { a = b; empty=false; }
else if (plus) { a += b; plus=false; }
else usage();
}
}
if (!error && !empty) {
if (einv) {
uint8_t buffer[Group::Point::HASH_BYTES];
for (int h=0; h<1<<Group::Point::INVERT_ELLIGATOR_WHICH_BITS; h++) {
if (DECAF_SUCCESS == a.invert_elligator(
Buffer(buffer,sizeof(buffer)), h
)) {
printhex(buffer,sizeof(buffer));
printf("\n");
}
}
} else if (raw) {
printhex((const uint8_t *)&a, sizeof(a));
printf("\n");
} else if (like_eddsa) {
if (decoeff) a /= (Group::Point::EDDSA_ENCODE_RATIO);
SecureBuffer b = a.mul_by_ratio_and_encode_like_eddsa();
printhex(b.data(),b.size());
printf("\n");
} else if (like_x) {
if (decoeff) a /= (Group::Point::LADDER_ENCODE_RATIO);
SecureBuffer b = a.mul_by_ratio_and_encode_like_ladder();
printhex(b.data(),b.size());
printf("\n");
} else {
a.serialize_into(tmp);
printhex(tmp,sizeof(tmp));
printf("\n");
}
done = true;
}
}
};

int main(int argc, char **argv) {
g_argc = argc;
g_argv = argv;
run_for_all_curves<Run>();
if (!done) usage();
return (error<0) ? -error : error;
}

+ 290
- 0
test/ristretto_vectors.inc.cxx View File

@@ -0,0 +1,290 @@
template <typename Group> struct base_multiples;

/* Examples for multiples of base point */
template <> struct base_multiples<Ristretto> {
static const int count = 16;
static const uint8_t values[count][Ristretto::Point::SER_BYTES];
};
const uint8_t base_multiples<Ristretto>::values
[base_multiples<Ristretto>::count][Ristretto::Point::SER_BYTES] = {
/* Copy-pasted from Dalek, thanks Isis Lovecruft and Henry de Valence */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{226, 242, 174, 10, 106, 188, 78, 113, 168, 132, 169, 97, 197, 0, 81, 95, 88, 227, 11, 106, 165, 130, 221, 141, 182, 166, 89, 69, 224, 141, 45, 118},
{106, 73, 50, 16, 247, 73, 156, 209, 127, 236, 181, 16, 174, 12, 234, 35, 161, 16, 232, 213, 185, 1, 248, 172, 173, 211, 9, 92, 115, 163, 185, 25},
{148, 116, 31, 93, 93, 82, 117, 94, 206, 79, 35, 240, 68, 238, 39, 213, 209, 234, 30, 43, 209, 150, 180, 98, 22, 107, 22, 21, 42, 157, 2, 89},
{218, 128, 134, 39, 115, 53, 139, 70, 111, 250, 223, 224, 179, 41, 58, 179, 217, 253, 83, 197, 234, 108, 149, 83, 88, 245, 104, 50, 45, 175, 106, 87},
{232, 130, 177, 49, 1, 107, 82, 193, 211, 51, 112, 128, 24, 124, 247, 104, 66, 62, 252, 203, 181, 23, 187, 73, 90, 184, 18, 196, 22, 15, 244, 78},
{246, 71, 70, 211, 201, 43, 19, 5, 14, 216, 216, 2, 54, 167, 240, 0, 124, 59, 63, 150, 47, 91, 167, 147, 209, 154, 96, 30, 187, 29, 244, 3},
{68, 245, 53, 32, 146, 110, 200, 31, 189, 90, 56, 120, 69, 190, 183, 223, 133, 169, 106, 36, 236, 225, 135, 56, 189, 207, 166, 167, 130, 42, 23, 109},
{144, 50, 147, 216, 242, 40, 126, 190, 16, 226, 55, 77, 193, 165, 62, 11, 200, 135, 229, 146, 105, 159, 2, 208, 119, 213, 38, 60, 221, 85, 96, 28},
{2, 98, 42, 206, 143, 115, 3, 163, 28, 175, 198, 63, 143, 196, 143, 220, 22, 225, 200, 200, 210, 52, 178, 240, 214, 104, 82, 130, 169, 7, 96, 49},
{32, 112, 111, 215, 136, 178, 114, 10, 30, 210, 165, 218, 212, 149, 43, 1, 244, 19, 188, 240, 231, 86, 77, 232, 205, 200, 22, 104, 158, 45, 185, 95},
{188, 232, 63, 139, 165, 221, 47, 165, 114, 134, 76, 36, 186, 24, 16, 249, 82, 43, 198, 0, 74, 254, 149, 135, 122, 199, 50, 65, 202, 253, 171, 66},
{228, 84, 158, 225, 107, 154, 160, 48, 153, 202, 32, 140, 103, 173, 175, 202, 250, 76, 63, 62, 78, 83, 3, 222, 96, 38, 227, 202, 143, 248, 68, 96},
{170, 82, 224, 0, 223, 46, 22, 245, 95, 177, 3, 47, 195, 59, 196, 39, 66, 218, 214, 189, 90, 143, 192, 190, 1, 103, 67, 108, 89, 72, 80, 31},
{70, 55, 107, 128, 244, 9, 178, 157, 194, 181, 246, 240, 197, 37, 145, 153, 8, 150, 229, 113, 111, 65, 71, 124, 211, 0, 133, 171, 127, 16, 48, 30},
{224, 196, 24, 247, 200, 217, 196, 205, 215, 57, 91, 147, 234, 18, 79, 58, 217, 144, 33, 187, 104, 29, 252, 51, 2, 169, 217, 154, 46, 83, 230, 78}
};

template <> struct base_multiples<Ed448Goldilocks> {
static const int count = 16;
static const uint8_t values[count][Ed448Goldilocks::Point::SER_BYTES];
};
const uint8_t base_multiples<Ed448Goldilocks>::values[][Ed448Goldilocks::Point::SER_BYTES] = {
/* Computed using SAGE script */
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33},
{0xc8,0x98,0xeb,0x4f,0x87,0xf9,0x7c,0x56,0x4c,0x6f,0xd6,0x1f,0xc7,0xe4,
0x96,0x89,0x31,0x4a,0x1f,0x81,0x8e,0xc8,0x5e,0xeb,0x3b,0xd5,0x51,0x4a,
0xc8,0x16,0xd3,0x87,0x78,0xf6,0x9e,0xf3,0x47,0xa8,0x9f,0xca,0x81,0x7e,
0x66,0xde,0xfd,0xed,0xce,0x17,0x8c,0x7c,0xc7,0x09,0xb2,0x11,0x6e,0x75},
{0xa0,0xc0,0x9b,0xf2,0xba,0x72,0x08,0xfd,0xa0,0xf4,0xbf,0xe3,0xd0,0xf5,
0xb2,0x9a,0x54,0x30,0x12,0x30,0x6d,0x43,0x83,0x1b,0x5a,0xdc,0x6f,0xe7,
0xf8,0x59,0x6f,0xa3,0x08,0x76,0x3d,0xb1,0x54,0x68,0x32,0x3b,0x11,0xcf,
0x6e,0x4a,0xeb,0x8c,0x18,0xfe,0x44,0x67,0x8f,0x44,0x54,0x5a,0x69,0xbc},
{0xb4,0x6f,0x18,0x36,0xaa,0x28,0x7c,0x0a,0x5a,0x56,0x53,0xf0,0xec,0x5e,
0xf9,0xe9,0x03,0xf4,0x36,0xe2,0x1c,0x15,0x70,0xc2,0x9a,0xd9,0xe5,0xf5,
0x96,0xda,0x97,0xee,0xaf,0x17,0x15,0x0a,0xe3,0x0b,0xcb,0x31,0x74,0xd0,
0x4b,0xc2,0xd7,0x12,0xc8,0xc7,0x78,0x9d,0x7c,0xb4,0xfd,0xa1,0x38,0xf4},
{0x1c,0x5b,0xbe,0xcf,0x47,0x41,0xdf,0xaa,0xe7,0x9d,0xb7,0x2d,0xfa,0xce,
0x00,0xea,0xaa,0xc5,0x02,0xc2,0x06,0x09,0x34,0xb6,0xea,0xae,0xca,0x6a,
0x20,0xbd,0x3d,0xa9,0xe0,0xbe,0x87,0x77,0xf7,0xd0,0x20,0x33,0xd1,0xb1,
0x58,0x84,0x23,0x22,0x81,0xa4,0x1f,0xc7,0xf8,0x0e,0xed,0x04,0xaf,0x5e},
{0x86,0xff,0x01,0x82,0xd4,0x0f,0x7f,0x9e,0xdb,0x78,0x62,0x51,0x58,0x21,
0xbd,0x67,0xbf,0xd6,0x16,0x5a,0x3c,0x44,0xde,0x95,0xd7,0xdf,0x79,0xb8,
0x77,0x9c,0xcf,0x64,0x60,0xe3,0xc6,0x8b,0x70,0xc1,0x6a,0xaa,0x28,0x0f,
0x2d,0x7b,0x3f,0x22,0xd7,0x45,0xb9,0x7a,0x89,0x90,0x6c,0xfc,0x47,0x6c},
{0x50,0x2b,0xcb,0x68,0x42,0xeb,0x06,0xf0,0xe4,0x90,0x32,0xba,0xe8,0x7c,
0x55,0x4c,0x03,0x1d,0x6d,0x4d,0x2d,0x76,0x94,0xef,0xbf,0x9c,0x46,0x8d,
0x48,0x22,0x0c,0x50,0xf8,0xca,0x28,0x84,0x33,0x64,0xd7,0x0c,0xee,0x92,
0xd6,0xfe,0x24,0x6e,0x61,0x44,0x8f,0x9d,0xb9,0x80,0x8b,0x3b,0x24,0x08},
{0x0c,0x98,0x10,0xf1,0xe2,0xeb,0xd3,0x89,0xca,0xa7,0x89,0x37,0x4d,0x78,
0x00,0x79,0x74,0xef,0x4d,0x17,0x22,0x73,0x16,0xf4,0x0e,0x57,0x8b,0x33,
0x68,0x27,0xda,0x3f,0x6b,0x48,0x2a,0x47,0x94,0xeb,0x6a,0x39,0x75,0xb9,
0x71,0xb5,0xe1,0x38,0x8f,0x52,0xe9,0x1e,0xa2,0xf1,0xbc,0xb0,0xf9,0x12},
{0x20,0xd4,0x1d,0x85,0xa1,0x8d,0x56,0x57,0xa2,0x96,0x40,0x32,0x15,0x63,
0xbb,0xd0,0x4c,0x2f,0xfb,0xd0,0xa3,0x7a,0x7b,0xa4,0x3a,0x4f,0x7d,0x26,
0x3c,0xe2,0x6f,0xaf,0x4e,0x1f,0x74,0xf9,0xf4,0xb5,0x90,0xc6,0x92,0x29,
0xae,0x57,0x1f,0xe3,0x7f,0xa6,0x39,0xb5,0xb8,0xeb,0x48,0xbd,0x9a,0x55},
{0xe6,0xb4,0xb8,0xf4,0x08,0xc7,0x01,0x0d,0x06,0x01,0xe7,0xed,0xa0,0xc3,
0x09,0xa1,0xa4,0x27,0x20,0xd6,0xd0,0x6b,0x57,0x59,0xfd,0xc4,0xe1,0xef,
0xe2,0x2d,0x07,0x6d,0x6c,0x44,0xd4,0x2f,0x50,0x8d,0x67,0xbe,0x46,0x29,
0x14,0xd2,0x8b,0x8e,0xdc,0xe3,0x2e,0x70,0x94,0x30,0x51,0x64,0xaf,0x17},
{0xbe,0x88,0xbb,0xb8,0x6c,0x59,0xc1,0x3d,0x8e,0x9d,0x09,0xab,0x98,0x10,
0x5f,0x69,0xc2,0xd1,0xdd,0x13,0x4d,0xbc,0xd3,0xb0,0x86,0x36,0x58,0xf5,
0x31,0x59,0xdb,0x64,0xc0,0xe1,0x39,0xd1,0x80,0xf3,0xc8,0x9b,0x82,0x96,
0xd0,0xae,0x32,0x44,0x19,0xc0,0x6f,0xa8,0x7f,0xc7,0xda,0xaf,0x34,0xc1},
{0xa4,0x56,0xf9,0x36,0x97,0x69,0xe8,0xf0,0x89,0x02,0x12,0x4a,0x03,0x14,
0xc7,0xa0,0x65,0x37,0xa0,0x6e,0x32,0x41,0x1f,0x4f,0x93,0x41,0x59,0x50,
0xa1,0x7b,0xad,0xfa,0x74,0x42,0xb6,0x21,0x74,0x34,0xa3,0xa0,0x5e,0xf4,
0x5b,0xe5,0xf1,0x0b,0xd7,0xb2,0xef,0x8e,0xa0,0x0c,0x43,0x1e,0xde,0xc5},
{0x18,0x6e,0x45,0x2c,0x44,0x66,0xaa,0x43,0x83,0xb4,0xc0,0x02,0x10,0xd5,
0x2e,0x79,0x22,0xdb,0xf9,0x77,0x1e,0x8b,0x47,0xe2,0x29,0xa9,0xb7,0xb7,
0x3c,0x8d,0x10,0xfd,0x7e,0xf0,0xb6,0xe4,0x15,0x30,0xf9,0x1f,0x24,0xa3,
0xed,0x9a,0xb7,0x1f,0xa3,0x8b,0x98,0xb2,0xfe,0x47,0x46,0xd5,0x1d,0x68},
{0x4a,0xe7,0xfd,0xca,0xe9,0x45,0x3f,0x19,0x5a,0x8e,0xad,0x5c,0xbe,0x1a,
0x7b,0x96,0x99,0x67,0x3b,0x52,0xc4,0x0a,0xb2,0x79,0x27,0x46,0x48,0x87,
0xbe,0x53,0x23,0x7f,0x7f,0x3a,0x21,0xb9,0x38,0xd4,0x0d,0x0e,0xc9,0xe1,
0x5b,0x1d,0x51,0x30,0xb1,0x3f,0xfe,0xd8,0x13,0x73,0xa5,0x3e,0x2b,0x43},
{0x84,0x19,0x81,0xc3,0xbf,0xee,0xc3,0xf6,0x0c,0xfe,0xca,0x75,0xd9,0xd8,
0xdc,0x17,0xf4,0x6c,0xf0,0x10,0x6f,0x24,0x22,0xb5,0x9a,0xec,0x58,0x0a,
0x58,0xf3,0x42,0x27,0x2e,0x3a,0x5e,0x57,0x5a,0x05,0x5d,0xdb,0x05,0x13,
0x90,0xc5,0x4c,0x24,0xc6,0xec,0xb1,0xe0,0xac,0xeb,0x07,0x5f,0x60,0x56},
};

template <typename Group> struct elligator_examples;

/* Examples for Elligator */
template <> struct elligator_examples<Ristretto> {
static const int count = 16;
static const uint8_t inputs[count][Ristretto::Point::HASH_BYTES];
static const uint8_t outputs[count][Ristretto::Point::SER_BYTES];
};
const uint8_t elligator_examples<Ristretto>::inputs
[elligator_examples<Ristretto>::count][Ristretto::Point::HASH_BYTES] = {
/* Copy-pasted from Dalek, thanks Isis Lovecruft and Henry de Valence */
{184, 249, 135, 49, 253, 123, 89, 113, 67, 160, 6, 239, 7, 105, 211, 41, 192, 249, 185, 57, 9, 102, 70, 198, 15, 127, 7, 26, 160, 102, 134, 71},
{229, 14, 241, 227, 75, 9, 118, 60, 128, 153, 226, 21, 183, 217, 91, 136, 98, 0, 231, 156, 124, 77, 82, 139, 142, 134, 164, 169, 169, 62, 250, 52},
{115, 109, 36, 220, 180, 223, 99, 6, 204, 169, 19, 29, 169, 68, 84, 23, 21, 109, 189, 149, 127, 205, 91, 102, 172, 35, 112, 35, 134, 69, 186, 34},
{16, 49, 96, 107, 171, 199, 164, 9, 129, 16, 64, 62, 241, 63, 132, 173, 209, 160, 112, 215, 105, 50, 157, 81, 253, 105, 1, 154, 229, 25, 120, 83},
{156, 131, 161, 162, 236, 251, 5, 187, 167, 171, 17, 178, 148, 210, 90, 207, 86, 21, 79, 161, 167, 215, 234, 1, 136, 242, 182, 248, 38, 85, 79, 86},
{251, 177, 124, 54, 18, 101, 75, 235, 245, 186, 19, 46, 133, 157, 229, 64, 10, 136, 181, 185, 78, 144, 254, 167, 137, 49, 107, 10, 61, 10, 21, 25},
{232, 193, 20, 68, 240, 77, 186, 77, 183, 40, 44, 86, 150, 31, 198, 212, 76, 81, 3, 217, 197, 8, 126, 128, 126, 152, 164, 208, 153, 44, 189, 77},
{173, 229, 149, 177, 37, 230, 30, 69, 61, 56, 172, 190, 219, 115, 167, 194, 71, 134, 59, 75, 28, 244, 118, 26, 162, 97, 64, 16, 15, 189, 30, 64},
{106, 71, 61, 107, 250, 117, 42, 151, 91, 202, 212, 100, 52, 188, 190, 21, 125, 218, 31, 18, 253, 241, 160, 133, 57, 242, 3, 164, 189, 68, 111, 75},
{112, 204, 182, 90, 220, 198, 120, 73, 173, 107, 193, 17, 227, 40, 162, 36, 150, 141, 235, 55, 172, 183, 12, 39, 194, 136, 43, 153, 244, 118, 91, 89},
{111, 24, 203, 123, 254, 189, 11, 162, 51, 196, 163, 136, 204, 143, 10, 222, 33, 112, 81, 205, 34, 35, 8, 66, 90, 6, 164, 58, 170, 177, 34, 25},
{225, 183, 30, 52, 236, 82, 6, 183, 109, 25, 227, 181, 25, 82, 41, 193, 80, 77, 161, 80, 242, 203, 79, 204, 136, 245, 131, 110, 237, 106, 3, 58},
{207, 246, 38, 56, 30, 86, 176, 90, 27, 200, 61, 42, 221, 27, 56, 210, 79, 178, 189, 120, 68, 193, 120, 167, 77, 185, 53, 197, 124, 128, 191, 126},
{1, 136, 215, 80, 240, 46, 63, 147, 16, 244, 230, 207, 82, 189, 74, 50, 106, 169, 138, 86, 30, 131, 214, 202, 166, 125, 251, 228, 98, 24, 36, 21},
{210, 207, 228, 56, 155, 116, 207, 54, 84, 195, 251, 215, 249, 199, 116, 75, 109, 239, 196, 251, 194, 246, 252, 228, 70, 146, 156, 35, 25, 39, 241, 4},
{34, 116, 123, 9, 8, 40, 93, 189, 9, 103, 57, 103, 66, 227, 3, 2, 157, 107, 134, 219, 202, 74, 230, 154, 78, 107, 219, 195, 214, 14, 84, 80}
};
const uint8_t elligator_examples<Ristretto>::outputs
[elligator_examples<Ristretto>::count][Ristretto::Point::SER_BYTES] = {
/* Copy-pasted from Dalek, thanks Isis Lovecruft and Henry de Valence */
{176, 157, 237, 97, 66, 29, 140, 166, 168, 94, 26, 157, 212, 216, 229, 160, 195, 246, 232, 239, 169, 112, 63, 193, 64, 32, 152, 69, 11, 190, 246, 86},
{234, 141, 77, 203, 181, 225, 250, 74, 171, 62, 15, 118, 78, 212, 150, 19, 131, 14, 188, 238, 194, 244, 141, 138, 166, 162, 83, 122, 228, 201, 19, 26},
{232, 231, 51, 92, 5, 168, 80, 36, 173, 179, 104, 68, 186, 149, 68, 40, 140, 170, 27, 103, 99, 140, 21, 242, 43, 62, 250, 134, 208, 255, 61, 89},
{208, 120, 140, 129, 177, 179, 237, 159, 252, 160, 28, 13, 206, 5, 211, 241, 192, 218, 1, 97, 130, 241, 20, 169, 119, 46, 246, 29, 79, 80, 77, 84},
{202, 11, 236, 145, 58, 12, 181, 157, 209, 6, 213, 88, 75, 147, 11, 119, 191, 139, 47, 142, 33, 36, 153, 193, 223, 183, 178, 8, 205, 120, 248, 110},
{26, 66, 231, 67, 203, 175, 116, 130, 32, 136, 62, 253, 215, 46, 5, 214, 166, 248, 108, 237, 216, 71, 244, 173, 72, 133, 82, 6, 143, 240, 104, 41},
{40, 157, 102, 96, 201, 223, 200, 197, 150, 181, 106, 83, 103, 126, 143, 33, 145, 230, 78, 6, 171, 146, 210, 143, 112, 5, 245, 23, 183, 138, 18, 120},
{220, 37, 27, 203, 239, 196, 176, 131, 37, 66, 188, 243, 185, 250, 113, 23, 167, 211, 154, 243, 168, 215, 54, 171, 159, 36, 195, 81, 13, 150, 43, 43},
{232, 121, 176, 222, 183, 196, 159, 90, 238, 193, 105, 52, 101, 167, 244, 170, 121, 114, 196, 6, 67, 152, 80, 185, 221, 7, 83, 105, 176, 208, 224, 121},
{226, 181, 183, 52, 241, 163, 61, 179, 221, 207, 220, 73, 245, 242, 25, 236, 67, 84, 179, 222, 167, 62, 167, 182, 32, 9, 92, 30, 165, 127, 204, 68},
{226, 119, 16, 242, 200, 139, 240, 87, 11, 222, 92, 146, 156, 243, 46, 119, 65, 59, 1, 248, 92, 183, 50, 175, 87, 40, 206, 53, 208, 220, 148, 13},
{70, 240, 79, 112, 54, 157, 228, 146, 74, 122, 216, 88, 232, 62, 158, 13, 14, 146, 115, 117, 176, 222, 90, 225, 244, 23, 94, 190, 150, 7, 136, 96},
{22, 71, 241, 103, 45, 193, 195, 144, 183, 101, 154, 50, 39, 68, 49, 110, 51, 44, 62, 0, 229, 113, 72, 81, 168, 29, 73, 106, 102, 40, 132, 24},
{196, 133, 107, 11, 130, 105, 74, 33, 204, 171, 133, 221, 174, 193, 241, 36, 38, 179, 196, 107, 219, 185, 181, 253, 228, 47, 155, 42, 231, 73, 41, 78},
{58, 255, 225, 197, 115, 208, 160, 143, 39, 197, 82, 69, 143, 235, 92, 170, 74, 40, 57, 11, 171, 227, 26, 185, 217, 207, 90, 185, 197, 190, 35, 60},
{88, 43, 92, 118, 223, 136, 105, 145, 238, 186, 115, 8, 214, 112, 153, 253, 38, 108, 205, 230, 157, 130, 11, 66, 101, 85, 253, 110, 110, 14, 148, 112}
};

template <> struct elligator_examples<Ed448Goldilocks> {
static const int count = 16;
static const uint8_t inputs[count] [Ed448Goldilocks::Point::HASH_BYTES];
static const uint8_t outputs[count][Ed448Goldilocks::Point::SER_BYTES];
};
const uint8_t elligator_examples<Ed448Goldilocks>::inputs
[elligator_examples<Ed448Goldilocks>::count][Ed448Goldilocks::Point::HASH_BYTES] = {
/* Computed using SAGE script */
{0x2d,0x86,0xa1,0x42,0x33,0x8d,0xe2,0x74,0x80,0x63,0x54,0xc4,0x3e,0x29,
0xaf,0x70,0x5a,0xa9,0xa1,0x89,0x3e,0x6f,0xd3,0xee,0x2e,0x95,0x22,0xc9,
0xce,0xb4,0x0b,0xe2,0x44,0x1b,0xac,0x8a,0x4f,0x78,0x06,0x43,0x43,0x89,
0x25,0xd7,0x91,0x46,0x98,0x8b,0x1c,0xa1,0x12,0xda,0x71,0x4d,0xe9,0x2a},
{0xee,0x79,0x8e,0xe0,0x86,0xde,0x1f,0x5a,0x57,0xa2,0xca,0x28,0xdb,0x84,
0x51,0xd3,0x06,0xcb,0xb9,0xee,0x22,0x27,0xc4,0x97,0xf4,0xa6,0x7a,0x69,
0x06,0xd7,0xeb,0xbc,0x7a,0xa8,0x5f,0x94,0x6f,0xf9,0xdf,0xf7,0x9e,0x1b,
0x7e,0x88,0xd9,0x7e,0x3a,0xd4,0xa4,0xe0,0xa1,0x20,0x32,0x32,0x3a,0xb7},
{0x2e,0x1b,0x10,0x93,0xb3,0x47,0x75,0x97,0x66,0x46,0x49,0xb0,0xb7,0xc6,
0xac,0x1f,0x9b,0xb7,0x5d,0xd9,0xfd,0xb5,0x08,0x96,0xcb,0xaa,0x06,0x15,
0xc5,0x25,0x43,0x6d,0x62,0x54,0xec,0x13,0xd9,0x19,0x0e,0xa4,0x25,0xe5,
0xba,0x80,0xee,0xfc,0x25,0x9b,0xcd,0x1e,0x2a,0x5a,0xf0,0x0e,0x8a,0x9e},
{0x8a,0x59,0x3f,0xb9,0x9c,0x04,0xb5,0xc0,0x50,0xc9,0x0d,0xc7,0x90,0x93,
0x65,0x89,0x41,0x5b,0x9b,0xd6,0x78,0x3d,0x9e,0x92,0x5e,0x63,0x4b,0x87,
0x81,0x4f,0xd1,0xda,0x2a,0x36,0xcd,0x80,0x45,0xbb,0x6c,0x36,0xd6,0x7e,
0xb8,0x2c,0x17,0x84,0x01,0x35,0x6b,0xe8,0x40,0x42,0x9c,0x78,0x0c,0x70},
{0x80,0xb2,0x5f,0xfc,0xfb,0xd8,0x0b,0x83,0xa7,0x86,0xc1,0x07,0x6d,0x3a,
0x23,0xd8,0x50,0x49,0xfd,0x4c,0x51,0x91,0x92,0xa7,0xd1,0xe8,0x52,0x38,
0x93,0x6e,0x1c,0x09,0x22,0x15,0xc8,0x0b,0x2d,0x9d,0xd1,0x3d,0x88,0x49,
0x82,0x9d,0x7f,0x6a,0x38,0x2a,0x5a,0xce,0x05,0x16,0x6e,0x4b,0x08,0x5b},
{0xc1,0x15,0x77,0x32,0xc6,0xd2,0xba,0xf4,0x48,0x88,0x7a,0x1c,0x4a,0x2a,
0x90,0xb4,0x0b,0x07,0x84,0x0f,0xf9,0x62,0xda,0x1f,0x71,0x91,0x05,0x8c,
0xb9,0x37,0xdf,0xe5,0xce,0xb2,0x5e,0x34,0x4e,0x33,0xfc,0x9d,0xf0,0xc6,
0x8e,0x99,0xcb,0x35,0x07,0xaa,0xfe,0xb9,0xa6,0xc9,0x66,0x75,0xbb,0xf1},
{0xa5,0x50,0x98,0x77,0xa2,0xbb,0xe8,0x0d,0x07,0xc2,0x3b,0x26,0x46,0x73,
0x85,0xf9,0x7c,0x16,0xbe,0x48,0x82,0x40,0x0f,0x31,0x80,0x0e,0x15,0xdd,
0x43,0x9e,0x52,0x34,0x43,0xcf,0x94,0x68,0x88,0x59,0xb7,0x62,0x64,0x3d,
0x64,0xbe,0xda,0x91,0xf7,0x50,0xac,0x6e,0x00,0x16,0xaf,0xaf,0xd3,0x09},
{0xbd,0x9b,0xe4,0xe9,0x20,0x93,0xcf,0x24,0x40,0x79,0xa6,0xff,0x63,0xad,
0x01,0xe1,0x9c,0xae,0x6d,0x80,0x65,0xed,0x83,0xbb,0x05,0x2e,0x14,0xe2,
0x39,0x04,0x8e,0x3b,0x8a,0xeb,0x90,0xe9,0x35,0xbe,0xbe,0x29,0x24,0x1e,
0x34,0x4d,0xc9,0x0d,0x31,0xd0,0x4e,0x99,0xd6,0xa1,0xad,0xca,0x8b,0x38},
{0xc3,0x5e,0xfb,0xe1,0xab,0xee,0x01,0xf9,0xe4,0x5e,0x03,0x84,0xfa,0x2f,
0x94,0x3a,0x6e,0x8f,0x56,0x11,0x86,0x4b,0x55,0x5f,0x18,0x6c,0x7c,0xf8,
0xe3,0x4c,0xc6,0x27,0xcb,0xa5,0x85,0xfb,0xcf,0xc4,0x26,0x84,0xeb,0x30,
0xbe,0x62,0x23,0x5c,0x1e,0x10,0xe8,0x82,0xca,0x42,0x19,0xa8,0xc4,0x85},
{0x3c,0x30,0x0f,0xed,0xd9,0x86,0x6f,0x6a,0xfa,0xbc,0x14,0x3e,0x1f,0x73,
0x0a,0xf6,0xea,0xda,0xc0,0x20,0x7e,0x00,0x88,0x88,0xb6,0xeb,0x79,0xa2,
0xf7,0xe6,0xe6,0x7e,0xd0,0x1e,0x71,0xaf,0x64,0x77,0x7b,0x90,0xbf,0x61,
0x0a,0x5e,0x36,0xca,0xd0,0xcd,0x88,0xef,0x88,0x3a,0x9b,0x6a,0xb8,0x13},
{0x11,0xf8,0x2f,0x21,0xe4,0x61,0x64,0x36,0xe6,0x9e,0xd8,0xe3,0x57,0x03,
0xcc,0xcd,0x1f,0x65,0xaa,0x75,0xf0,0x7e,0x8a,0xfa,0xa3,0x35,0x29,0xcc,
0x22,0x58,0xeb,0x2b,0x0f,0xb1,0x82,0x71,0x0f,0xfc,0x67,0xd1,0xe0,0xd0,
0xde,0x37,0x3d,0x4f,0xd2,0xd5,0xb1,0x7b,0x58,0xb3,0xc7,0xd4,0x73,0x12},
{0x3d,0xbd,0xcf,0x91,0xe8,0x35,0xa8,0x30,0xfd,0x8a,0xf9,0xc6,0x9d,0xc1,
0x30,0x66,0xdf,0x1e,0x24,0x44,0x8b,0x91,0x78,0xa0,0x99,0xbb,0x07,0x57,
0x3e,0xfe,0xc4,0x8e,0xab,0x2c,0x11,0x9b,0xcb,0xbb,0x82,0x8d,0x20,0xc1,
0x64,0x7d,0x42,0x31,0xdf,0xeb,0x9b,0xd0,0x86,0xf2,0x6d,0xb7,0x7e,0x71},
{0xac,0x8b,0xf3,0x02,0x0a,0x1c,0x73,0x3a,0x59,0x10,0x92,0xb6,0x7a,0x32,
0x23,0xca,0x2f,0xab,0x64,0x53,0xd2,0x25,0xba,0x83,0x2e,0x34,0xd0,0xc4,
0xbf,0xca,0x95,0x2b,0xe3,0x2d,0x39,0x76,0xca,0x73,0x8c,0x5a,0xb3,0xdd,
0xc9,0xc7,0x62,0x70,0x78,0x41,0x83,0x72,0xdb,0x77,0x0f,0x17,0xb5,0x5c},
{0xf6,0xc5,0x5d,0x6b,0x46,0x97,0xd6,0xf8,0x3d,0x6e,0xcc,0xc4,0xdb,0x2f,
0x72,0xf8,0xf2,0xf6,0x7e,0x75,0x24,0xff,0x91,0xd6,0xf6,0xc8,0xa7,0x56,
0xab,0x03,0x96,0x7a,0x64,0x89,0x42,0x71,0xe7,0x1e,0x71,0xd8,0x95,0x72,
0x9f,0x06,0x31,0xfd,0x7c,0x0d,0xe1,0xc2,0x73,0xc0,0x90,0x92,0x43,0x23},
{0x9b,0x30,0x03,0x76,0xa4,0xb9,0x5e,0xa2,0x02,0x4b,0xdb,0xd9,0x7a,0x96,
0x93,0xc3,0xf6,0x0a,0xe0,0xbb,0xdb,0xda,0xfc,0x47,0x09,0x27,0x8b,0x65,
0x34,0xc8,0xa2,0xd5,0xff,0x9b,0xb3,0xd2,0x10,0xd9,0x49,0xd5,0xbf,0x09,
0x49,0x19,0xb9,0x0d,0x2f,0x0f,0xf9,0x82,0xed,0x92,0x79,0x95,0xdc,0x60},
{0x90,0x95,0x7d,0x59,0x78,0x10,0xb2,0x7b,0x84,0x9a,0x69,0x1f,0x5d,0x27,
0xd5,0x48,0x96,0x3d,0x35,0x4a,0xe9,0xe2,0x9a,0xd5,0x9a,0x23,0x0a,0x15,
0x5a,0xaa,0x6f,0xe7,0xc5,0x4c,0x82,0xd5,0x08,0x14,0xd8,0xfd,0xcd,0x2d,
0x3b,0xb1,0xe5,0x53,0xa8,0x41,0xf9,0x71,0xd7,0x24,0xa4,0x64,0x7a,0xba}
};
const uint8_t elligator_examples<Ed448Goldilocks>::outputs
[elligator_examples<Ed448Goldilocks>::count][Ed448Goldilocks::Point::SER_BYTES] = {
/* Computed using SAGE script */
{0xa6,0x99,0x3b,0x5a,0x6c,0xbb,0x40,0x71,0x6e,0xb2,0xaf,0xa1,0x53,0x05,
0x27,0x75,0xd2,0x55,0xff,0x2f,0x64,0x4e,0x2f,0x91,0x32,0xb4,0x04,0xfc,
0x80,0x68,0x08,0x09,0x40,0x43,0xf7,0xa2,0xe4,0x7c,0x0a,0xd9,0x27,0x2f,
0x53,0x33,0x2d,0x21,0xf4,0x07,0x70,0xd6,0x60,0xa8,0xf1,0xf1,0xed,0x23},
{0xde,0x6a,0x92,0x82,0xee,0x9f,0x8f,0xa9,0xb0,0x2c,0xa9,0x5e,0xd4,0xbf,
0x7f,0x87,0xb7,0x1f,0xc3,0x64,0xbc,0x75,0xd5,0x71,0xf2,0xe9,0xa7,0x07,
0xf7,0x16,0x66,0xb2,0xdf,0x06,0x55,0xf2,0x00,0x2e,0x1c,0x84,0x23,0x9e,
0xed,0x70,0xde,0xd8,0xa6,0x92,0xaf,0x39,0x52,0x03,0x38,0xc7,0xc9,0xef},
{0x02,0x51,0x0b,0x4c,0x16,0xa7,0x01,0xa1,0x68,0x82,0xb5,0x1e,0xc5,0xd1,
0x4e,0x25,0x18,0x5b,0x7a,0x8c,0xd3,0x12,0xc3,0xcf,0xc0,0x7c,0x11,0x00,
0x40,0xd0,0x01,0xad,0x59,0x0a,0xd7,0x2d,0xc3,0x07,0x74,0xd8,0x2b,0x1a,
0x91,0xb9,0xe3,0x6c,0x42,0x3e,0x93,0x7d,0x26,0x4b,0x2d,0x99,0xd6,0xb6},
{0x9c,0x64,0x7b,0x77,0x1c,0x28,0x82,0x64,0xe8,0x0f,0xc8,0x11,0x4c,0x58,
0xdb,0x46,0xe8,0xf0,0x66,0x6c,0x10,0xd7,0xf5,0x6b,0xa8,0x56,0xae,0x67,
0x09,0x2a,0xa8,0x8c,0x42,0x16,0x65,0x2e,0x6a,0x12,0x9c,0x1b,0x40,0x90,
0xca,0xab,0xe3,0x9a,0xfd,0x35,0x2b,0xe4,0xdc,0x40,0x99,0x81,0x9c,0x59},
{0x06,0xe9,0x16,0x29,0xce,0x93,0x48,0x6a,0xd3,0xa7,0xe7,0x29,0xf0,0x1c,
0x4d,0x29,0x4a,0x4b,0xde,0xef,0xaf,0x48,0x32,0x04,0xc1,0x67,0xdf,0xe8,
0xf0,0xc9,0xd2,0x32,0x50,0x6f,0xa5,0x21,0xf5,0x30,0x0e,0x19,0xa0,0x00,
0x43,0x24,0x50,0x8b,0x39,0x0a,0x6f,0x25,0x81,0x4f,0xc8,0x68,0x3a,0xa4},
{0x68,0x11,0x77,0xb0,0x76,0xc9,0xe5,0x53,0xc7,0xe5,0x7a,0x22,0xe7,0x59,
0x05,0x96,0xe3,0x48,0x2d,0xe2,0x3f,0x28,0x55,0xa8,0xaf,0x82,0xcc,0x51,
0x6c,0x52,0xa9,0x37,0x35,0xed,0x3d,0xde,0x91,0xb8,0x21,0x0b,0xad,0x64,
0xb1,0x7d,0x0c,0x1d,0x7c,0x14,0xcc,0xc1,0x52,0x6c,0xc4,0x14,0x0f,0x11},
{0x68,0x05,0x63,0x1c,0x06,0xf6,0xd0,0xb5,0xcc,0xf7,0x1f,0xea,0x2e,0x4c,
0xdf,0x3e,0xa3,0x10,0x4a,0x44,0xa8,0x21,0x20,0x5a,0x25,0x01,0x4c,0x9a,
0x17,0xac,0x43,0x33,0xbb,0xf6,0xbb,0x28,0x9b,0x42,0x57,0xcc,0xd7,0xf7,
0xbb,0x11,0xe5,0xc4,0xdd,0xd8,0x6d,0xa9,0x53,0x19,0xdc,0x47,0x04,0x4d},
{0x4c,0x0e,0x89,0x30,0xee,0x39,0xf2,0xa7,0x43,0xd1,0x79,0x74,0x5b,0x4c,
0x94,0x0f,0xf5,0x8f,0x53,0x99,0x57,0x32,0x31,0x3d,0x7e,0xe7,0x8c,0xa2,
0xde,0xca,0x42,0xa4,0x8f,0x00,0x40,0xc7,0x9a,0x7e,0xd5,0x47,0x00,0x0b,
0x20,0x8b,0x95,0x94,0xce,0xc4,0xe3,0xe9,0xdf,0x5c,0x01,0x38,0xb8,0xaa},
{0x48,0xc3,0x3a,0x47,0x66,0x05,0xfe,0x0f,0xbb,0x33,0xd3,0x7b,0x67,0x2a,
0xac,0x14,0xd7,0xc6,0x2b,0x84,0x56,0xd2,0x77,0x60,0x8f,0xc2,0x90,0x6d,
0x03,0x87,0x1d,0x39,0x59,0xdd,0x4a,0x4c,0xaf,0xab,0xe7,0xc2,0x5b,0x6f,
0x59,0xc9,0xa9,0xd1,0x7c,0x72,0x4d,0x97,0x55,0x52,0x98,0xc9,0xdf,0x3f},
{0x0a,0x0c,0x08,0x9d,0x50,0x5d,0x30,0xd1,0xce,0x91,0xcf,0x36,0x96,0xca,
0x76,0x10,0xa4,0xe5,0x4a,0xf6,0xf6,0x05,0xcd,0x68,0xff,0x30,0x3c,0xb5,
0x0b,0xbd,0xba,0xb9,0x90,0x36,0x51,0xed,0x6b,0xdc,0x35,0xf2,0xa8,0x0b,
0xc7,0x64,0xe3,0x50,0xf8,0xa2,0x3f,0x70,0x03,0xdc,0xd3,0xaa,0x36,0x4f},
{0x56,0x21,0x3f,0x80,0x39,0x79,0xce,0x00,0x33,0xa2,0xaa,0x9b,0xcc,0xb8,
0x51,0x3b,0x82,0x0b,0x15,0x52,0xe8,0x14,0x75,0x86,0x4a,0x48,0xfe,0x60,
0xe9,0x22,0x73,0xa8,0xf2,0xe5,0x7a,0x77,0xb8,0x1a,0xf1,0x74,0x6e,0x42,
0xe6,0x47,0xcc,0xc6,0xfa,0x54,0xe0,0xd0,0x7c,0xdd,0x33,0x76,0xc2,0x39},
{0xf4,0x8f,0xa8,0x82,0xb5,0x2f,0x79,0xf1,0x8f,0x33,0xac,0xfc,0x23,0x71,
0x5e,0x8f,0x3e,0x6c,0xcf,0x8e,0xa8,0x7a,0x3f,0xc0,0x71,0xcd,0xb1,0xeb,
0xd2,0x96,0xf2,0x9e,0x83,0x15,0x78,0xa9,0x21,0x29,0x1d,0x3c,0x80,0x13,
0x52,0x59,0x45,0x96,0xa1,0x7d,0x27,0x68,0xe2,0xc2,0x86,0x32,0x13,0x7d},
{0xaa,0x3b,0x6c,0x33,0xc2,0x7a,0x5a,0x25,0xf9,0x45,0x20,0x30,0x56,0x73,
0x32,0xe1,0x70,0x5b,0xdf,0x72,0x45,0xef,0xd8,0x98,0x60,0x2c,0xcf,0x79,
0x93,0x4c,0xa7,0x40,0xed,0x8a,0x12,0xc7,0xee,0x82,0x1e,0x99,0x22,0x52,
0x1a,0xb8,0xbf,0xca,0x3a,0x1d,0xb9,0x16,0xe4,0x66,0x78,0xc5,0x1f,0x81},
{0xba,0x1c,0xfd,0xca,0x84,0x4f,0x16,0x71,0x6a,0x77,0xba,0x74,0x7a,0x1f,
0x46,0xd2,0x9f,0xfa,0x90,0x3a,0x74,0xe5,0xf2,0x14,0xfb,0xef,0x06,0x67,
0x67,0x7d,0xcf,0x9b,0xb0,0x2a,0xf7,0xe3,0x4d,0x27,0x02,0xea,0xdb,0xbe,
0x80,0xeb,0xcf,0x94,0x4c,0x2a,0x54,0x2a,0x98,0x35,0x59,0xd9,0x24,0x8a},
{0x50,0xdf,0xb7,0xe7,0x92,0x92,0xf3,0xb0,0x4e,0x0d,0x5c,0x73,0x8a,0xf2,
0xba,0xc6,0xda,0xdf,0x00,0xe5,0x37,0x7b,0xbf,0xc1,0xe7,0x13,0xe1,0xda,
0x5f,0xa1,0xa3,0xc2,0xfd,0x4b,0x10,0x81,0x0d,0x99,0xcf,0x8f,0xca,0x91,
0x37,0x3e,0x47,0x8a,0x84,0xab,0xcd,0x65,0xdf,0xf9,0x27,0x3c,0x13,0xf1},
{0xe4,0xe1,0xa4,0x8d,0x1d,0x72,0xe2,0x72,0x3b,0x09,0x09,0xf9,0x7f,0xcd,
0x57,0x0d,0xdf,0x8c,0xdc,0x47,0xdf,0x6d,0xfa,0x6a,0x8d,0x67,0x45,0x4f,
0x6b,0x44,0x6d,0xbf,0xf3,0x41,0x1c,0x57,0x1c,0xf0,0x77,0x14,0x06,0xf6,
0x8c,0xb9,0xa3,0x40,0x34,0x70,0xd6,0x36,0xe5,0xa6,0xce,0x1b,0x84,0xcc}
};

+ 57
- 13
test/test_decaf.cxx View File

@@ -20,6 +20,8 @@ using namespace decaf;
static bool passing = true;
static const long NTESTS = 10000;

#include "ristretto_vectors.inc.cxx"

class Test {
public:
bool passing_now;
@@ -219,7 +221,6 @@ static void test_elligator() {
if (i==4 && elli_patho.size()) b1 = elli_patho;
len = b1.size();
Point s = Point::from_hash(b1), ss=s;
for (unsigned int j=0; j<(i&3); j++) ss = ss.debugging_torque();
@@ -292,6 +293,14 @@ static void test_elligator() {
Point t(rng);
point_check(test,t,t,t,0,0,t,Point::from_hash(t.steg_encode(rng)),"steg round-trip");
FixedArrayBuffer<Point::HASH_BYTES> b3(rng), b4(b3);
t = Point::from_hash(b3);
for (unsigned j=0; j<256; j+=2<<((Group::bits()-1)%8)) {
b4[Point::HASH_BYTES-1] = b3[Point::HASH_BYTES-1] ^ j;
Point u = Point::from_hash(b4);
point_check(test,t,t,t,0,0,t,u,"elligator twiddle high bits");
}
}
}

@@ -406,8 +415,8 @@ static void test_ec() {
q=p;
for (int j=1; j<Group::REMOVED_COFACTOR; j<<=1) q = q.times_two();
decaf_error_t error = r.decode_like_eddsa_and_ignore_cofactor_noexcept(
p.mul_by_cofactor_and_encode_like_eddsa()
decaf_error_t error = r.decode_like_eddsa_and_mul_by_ratio_noexcept(
p.mul_by_ratio_and_encode_like_eddsa()
);
if (error != DECAF_SUCCESS) {
test.fail();
@@ -457,12 +466,15 @@ static void test_cfrg_crypto() {
printf(" Shared secrets disagree on iteration %d.\n",i);
}
if (!memeq(
DhLadder::shared_secret(DhLadder::base_point(),s1),
DhLadder::derive_public_key(s1)
)) {
p1 = DhLadder::shared_secret(DhLadder::base_point(),s1);
p2 = DhLadder::derive_public_key(s1);
if (!memeq(p1,p2)) {
test.fail();
printf(" Public keys disagree on iteration %d.\n",i);
printf(" Public keys disagree on iteration %d.\n Ladder public key: ",i);
for (unsigned j=0; j<s1.size(); j++) { printf("%02x",p1[j]); }
printf("\n Derive public key: ");
for (unsigned j=0; j<s1.size(); j++) { printf("%02x",p2[j]); }
printf("\n");
}
}
}
@@ -483,7 +495,7 @@ static void test_cfrg_vectors() {
SecureBuffer eddsa_pk2 = priv.pub().serialize();
if (!memeq(SecureBuffer(eddsa_pk[t]), eddsa_pk2)) {
test.fail();
printf(" EdDSA PK vectors disagree.");
printf(" EdDSA PK vectors #%d disagree.", t);
printf("\n Correct: ");
for (unsigned i=0; i<eddsa_pk[t].size(); i++) printf("%02x", eddsa_pk[t][i]);
printf("\n Incorrect: ");
@@ -540,7 +552,6 @@ static void test_eddsa() {
SpongeRng rng(Block("test_eddsa"),SpongeRng::DETERMINISTIC);
for (int i=0; i<NTESTS && test.passing_now; i++) {
typename EdDSA<Group>::PrivateKey priv(rng);
typename EdDSA<Group>::PublicKey pub(priv);
@@ -557,7 +568,22 @@ static void test_eddsa() {
} catch(CryptoException) {
test.fail();
printf(" Signature validation failed on sig %d\n", i);
}
}
/* Test encode_like and torque */
Point p(rng);
SecureBuffer p1 = p.mul_by_ratio_and_encode_like_eddsa();
SecureBuffer p2 = p.debugging_torque().mul_by_ratio_and_encode_like_eddsa();
if (!memeq(p1,p2)) {
test.fail();
printf(" Torque and encode like EdDSA failed\n");
}
SecureBuffer p3 = p.mul_by_ratio_and_encode_like_ladder();
SecureBuffer p4 = p.debugging_torque().mul_by_ratio_and_encode_like_ladder();
if (!memeq(p3,p4)) {
test.fail();
printf(" Torque and encode like ladder failed\n");
}
}
}

@@ -581,14 +607,14 @@ static void test_convert_eddsa_to_x() {
SecureBuffer alice_pub_x_generated = DhLadder::derive_public_key(alice_priv_x);
if (!memeq(alice_pub_x_conversion, alice_pub_x_generated)) {
test.fail();
printf(" Ed2X Public key convertion and regeneration from converted private key differs.\n");
printf(" Ed2X Public key conversion and regeneration from converted private key differs.\n");
}
SecureBuffer bob_priv_x = bob_priv.convert_to_x();
SecureBuffer bob_pub_x_conversion = bob_pub.convert_to_x();
SecureBuffer bob_pub_x_generated = DhLadder::derive_public_key(bob_priv_x);
if (!memeq(bob_pub_x_conversion, bob_pub_x_generated)) {
test.fail();
printf(" Ed2X Public key convertion and regeneration from converted private key differs.\n");
printf(" Ed2X Public key conversion and regeneration from converted private key differs.\n");
}

/* compute shared secrets and check they match */
@@ -602,6 +628,23 @@ static void test_convert_eddsa_to_x() {
}
}

static void test_dalek_vectors() {
Test test("Test vectors from Dalek");
Point p = Point::base(), q;
for (unsigned i=0; i<base_multiples<Group>::count; i++) {
if (!decaf_memeq(q.serialize().data(),base_multiples<Group>::values[i],Point::SER_BYTES)) {
test.fail();
printf(" Failed test vector for %d * base point.\n", i);
}
q += p;
}
for (unsigned i=0; i<elligator_examples<Group>::count; i++) {
Point r = Point::from_hash(FixedBlock<Point::HASH_BYTES>(elligator_examples<Group>::inputs[i]));
Point s = Point(FixedBlock<Point::SER_BYTES>(elligator_examples<Group>::outputs[i]));
point_check(test,r,r,r,0,0,r,s,"elligator test vector");
}
}

static void run() {
printf("Testing %s:\n",Group::name());
test_arithmetic();
@@ -611,6 +654,7 @@ static void run() {
test_convert_eddsa_to_x();
test_cfrg_crypto();
test_cfrg_vectors();
test_dalek_vectors();
printf("\n");
}



+ 15
- 15
test/vectors.inc.cxx View File

@@ -1,18 +1,18 @@

/* X25519, X448 test vectors */
template<> const uint8_t Tests<IsoEd25519>::rfc7748_1[32] = {
template<> const uint8_t Tests<Ristretto>::rfc7748_1[32] = {
0x42,0x2c,0x8e,0x7a,0x62,0x27,0xd7,0xbc,
0xa1,0x35,0x0b,0x3e,0x2b,0xb7,0x27,0x9f,
0x78,0x97,0xb8,0x7b,0xb6,0x85,0x4b,0x78,
0x3c,0x60,0xe8,0x03,0x11,0xae,0x30,0x79
};
template<> const uint8_t Tests<IsoEd25519>::rfc7748_1000[32] = {
template<> const uint8_t Tests<Ristretto>::rfc7748_1000[32] = {
0x68,0x4c,0xf5,0x9b,0xa8,0x33,0x09,0x55,
0x28,0x00,0xef,0x56,0x6f,0x2f,0x4d,0x3c,
0x1c,0x38,0x87,0xc4,0x93,0x60,0xe3,0x87,
0x5f,0x2e,0xb9,0x4d,0x99,0x53,0x2c,0x51
};
template<> const uint8_t Tests<IsoEd25519>::rfc7748_1000000[32] = {
template<> const uint8_t Tests<Ristretto>::rfc7748_1000000[32] = {
0x7c,0x39,0x11,0xe0,0xab,0x25,0x86,0xfd,
0x86,0x44,0x97,0x29,0x7e,0x57,0x5e,0x6f,
0x3b,0xc6,0x01,0xc0,0x88,0x3c,0x30,0xdf,
@@ -53,7 +53,7 @@ const uint8_t sm1_25519[32] = {
0xa7,0xd7,0xfb,0x3d,0x99,0x00,0x4d,0x2b,
0x0b,0xdf,0xc1,0x4f,0x80,0x24,0x83,0x2b
};
template<> const Block Tests<IsoEd25519>::sqrt_minus_one(sm1_25519,32);
template<> const Block Tests<Ristretto>::sqrt_minus_one(sm1_25519,32);

template<> const Block Tests<Ed448Goldilocks>::minus_sqrt_minus_one(NULL,0);
const uint8_t msm1_25519[32] = {
@@ -62,7 +62,7 @@ const uint8_t msm1_25519[32] = {
0x58,0x28,0x04,0xc2,0x66,0xff,0xb2,0xd4,
0xf4,0x20,0x3e,0xb0,0x7f,0xdb,0x7c,0x54
};
template<> const Block Tests<IsoEd25519>::minus_sqrt_minus_one(msm1_25519,32);
template<> const Block Tests<Ristretto>::minus_sqrt_minus_one(msm1_25519,32);

const uint8_t elli_patho_448[56] = {
0x14,0xf0,0x70,0x58,0x41,0xc7,0xf9,0xa5,
@@ -74,7 +74,7 @@ const uint8_t elli_patho_448[56] = {
0x86,0xa9,0x2e,0xc9,0x17,0x68,0x9b,0x20
};
template<> const Block Tests<Ed448Goldilocks>::elli_patho(elli_patho_448,56);
template<> const Block Tests<IsoEd25519>::elli_patho(NULL,0);
template<> const Block Tests<Ristretto>::elli_patho(NULL,0);

/* EdDSA test vectors */
const uint8_t ed448_eddsa_sk[][57] = {{
@@ -481,7 +481,7 @@ const uint8_t ed25519_eddsa_sig[][64] = {{
0x91,0xc2,0x04,0x3d,0x4e,0xb3,0xe9,0x0d
}};

template<> const bool Tests<IsoEd25519>::eddsa_prehashed[] = {
template<> const bool Tests<Ristretto>::eddsa_prehashed[] = {
false,
false,
false,
@@ -489,7 +489,7 @@ template<> const bool Tests<IsoEd25519>::eddsa_prehashed[] = {
false,
false
};
template<> const Block Tests<IsoEd25519>::eddsa_sk[] = {
template<> const Block Tests<Ristretto>::eddsa_sk[] = {
Block(ed25519_eddsa_sk[0],32),
Block(ed25519_eddsa_sk[1],32),
Block(ed25519_eddsa_sk[2],32),
@@ -498,7 +498,7 @@ template<> const Block Tests<IsoEd25519>::eddsa_sk[] = {
Block(ed25519_eddsa_sk[4],32),
Block(NULL,0)
};
template<> const Block Tests<IsoEd25519>::eddsa_pk[] = {
template<> const Block Tests<Ristretto>::eddsa_pk[] = {
Block(ed25519_eddsa_pk[0],32),
Block(ed25519_eddsa_pk[1],32),
Block(ed25519_eddsa_pk[2],32),
@@ -506,15 +506,15 @@ template<> const Block Tests<IsoEd25519>::eddsa_pk[] = {
Block(ed25519_eddsa_pk[4],32),
Block(ed25519_eddsa_pk[4],32)
};
template<> const Block Tests<IsoEd25519>::eddsa_context[] = {
EdDSA<IsoEd25519>::NO_CONTEXT(),
EdDSA<IsoEd25519>::NO_CONTEXT(),
EdDSA<IsoEd25519>::NO_CONTEXT(),
template<> const Block Tests<Ristretto>::eddsa_context[] = {
EdDSA<Ristretto>::NO_CONTEXT(),
EdDSA<Ristretto>::NO_CONTEXT(),
EdDSA<Ristretto>::NO_CONTEXT(),
Block(NULL,0),
Block(ed25519_eddsa_context[0],3),
Block(ed25519_eddsa_context[1],3)
};
template<> const Block Tests<IsoEd25519>::eddsa_message[] = {
template<> const Block Tests<Ristretto>::eddsa_message[] = {
Block(ed25519_eddsa_message[0],0),
Block(ed25519_eddsa_message[1],1),
Block(ed25519_eddsa_message[2],2),
@@ -522,7 +522,7 @@ template<> const Block Tests<IsoEd25519>::eddsa_message[] = {
Block(ed25519_eddsa_message[4],16),
Block(ed25519_eddsa_message[4],16)
};
template<> const Block Tests<IsoEd25519>::eddsa_sig[] = {
template<> const Block Tests<Ristretto>::eddsa_sig[] = {
Block(ed25519_eddsa_sig[0],64),
Block(ed25519_eddsa_sig[1],64),
Block(ed25519_eddsa_sig[2],64),


Loading…
Cancel
Save