Browse Source

Incorporate test vectors from Dalek

master
Michael Hamburg 7 years ago
parent
commit
4de924c786
18 changed files with 440 additions and 158 deletions
  1. +26
    -22
      aux/ristretto/ristretto.sage
  2. +6
    -13
      src/GENERATED/c/curve25519/decaf.c
  3. +9
    -28
      src/GENERATED/c/curve25519/elligator.c
  4. +6
    -13
      src/GENERATED/c/ed448goldilocks/decaf.c
  5. +9
    -28
      src/GENERATED/c/ed448goldilocks/elligator.c
  6. +1
    -1
      src/GENERATED/c/p25519/f_field.h
  7. +6
    -3
      src/GENERATED/c/p25519/f_generic.c
  8. +1
    -1
      src/GENERATED/c/p448/f_field.h
  9. +6
    -3
      src/GENERATED/c/p448/f_generic.c
  10. +10
    -0
      src/GENERATED/include/decaf/point_255.h
  11. +10
    -0
      src/GENERATED/include/decaf/point_448.h
  12. +6
    -13
      src/per_curve/decaf.tmpl.c
  13. +9
    -28
      src/per_curve/elligator.tmpl.c
  14. +10
    -0
      src/per_curve/point.tmpl.h
  15. +1
    -1
      src/per_field/f_field.tmpl.h
  16. +6
    -3
      src/per_field/f_generic.tmpl.c
  17. +290
    -0
      test/ristretto_vectors.inc.cxx
  18. +28
    -1
      test/test_decaf.cxx

+ 26
- 22
aux/ristretto/ristretto.sage View File

@@ -124,13 +124,15 @@ class QuotientEdwardsPoint(object):

# Utility functions
@classmethod
def bytesToGf(cls,bytes,mustBeProper=True,mustBePositive=False):
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.modulus():
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)
@@ -242,7 +244,7 @@ class RistrettoPoint(QuotientEdwardsPoint):
@classmethod
def elligatorSpec(cls,r0):
a,d = cls.a,cls.d
r = cls.qnr * cls.bytesToGf(r0)^2
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
@@ -258,7 +260,7 @@ class RistrettoPoint(QuotientEdwardsPoint):
@optimized_version_of("elligatorSpec")
def elligator(cls,r0):
a,d = cls.a,cls.d
r0 = cls.bytesToGf(r0)
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)
@@ -469,7 +471,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint):
def elligatorSpec(cls,r0,fromR=False):
a,d = cls.a,cls.d
if fromR: r = r0
else: r = cls.qnr * cls.bytesToGf(r0)^2
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()
@@ -486,7 +488,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint):
@optimized_version_of("elligatorSpec")
def elligator(cls,r0):
a,d = cls.a,cls.d
r0 = cls.bytesToGf(r0)
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)
@@ -693,13 +695,6 @@ def test(cls,n):
Q2 = Q0*(r+1)
if Q1 + Q0 != Q2: raise TestFailedException("Scalarmul doesn't work")
Q = Q1

#test(Ed25519Point,100)
#test(NegEd25519Point,100)
#test(IsoEd25519Point,100)
#test(IsoEd448Point,100)
#test(TwistedEd448GoldilocksPoint,100)
#test(Ed448GoldilocksPoint,100)
def testElligator(cls,n):
@@ -709,7 +704,7 @@ def testElligator(cls,n):
P = cls.elligator(r)
if hasattr(P,"invertElligator"):
iv = P.invertElligator()
modr = bytes(cls.gfToBytes(cls.bytesToGf(r)))
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)):
@@ -723,12 +718,7 @@ def testElligator(cls,n):
pass # TODO

#testElligator(Ed25519Point,100)
#testElligator(NegEd25519Point,100)
#testElligator(IsoEd25519Point,100)
#testElligator(IsoEd448Point,100)
#testElligator(Ed448GoldilocksPoint,100)
#testElligator(TwistedEd448GoldilocksPoint,100)


def gangtest(classes,n):
print "Gang test",[cls.__name__ for cls in classes]
@@ -756,5 +746,19 @@ def gangtest(classes,n):
for c,ret in zip(classes,rets):
print c,binascii.hexlify(ret)
print
#gangtest([IsoEd448Point,TwistedEd448GoldilocksPoint,Ed448GoldilocksPoint],100)
#gangtest([Ed25519Point,IsoEd25519Point],100)


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)

+ 6
- 13
src/GENERATED/c/curve25519/decaf.c View File

@@ -238,7 +238,7 @@ decaf_error_t API_NS(point_decode) (
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);
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
@@ -827,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);
@@ -1143,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
@@ -1243,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);
@@ -1314,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;


+ 9
- 28
src/GENERATED/c/curve25519/elligator.c View File

@@ -26,7 +26,6 @@ static const int EDWARDS_D = -121665;
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */

extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
@@ -42,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);
@@ -112,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) (
@@ -136,7 +119,6 @@ API_NS(invert_elligator_nonuniform) (
const point_t p,
uint32_t hint_
) {
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_altx = -(hint>>1 & 1),
@@ -198,15 +180,14 @@ API_NS(invert_elligator_nonuniform) (
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));
}



+ 6
- 13
src/GENERATED/c/ed448goldilocks/decaf.c View File

@@ -238,7 +238,7 @@ decaf_error_t API_NS(point_decode) (
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);
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
@@ -827,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);
@@ -1143,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
@@ -1243,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);
@@ -1314,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;


+ 9
- 28
src/GENERATED/c/ed448goldilocks/elligator.c View File

@@ -26,7 +26,6 @@ static const int EDWARDS_D = -39081;
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */

extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
@@ -42,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);
@@ -112,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) (
@@ -136,7 +119,6 @@ API_NS(invert_elligator_nonuniform) (
const point_t p,
uint32_t hint_
) {
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_altx = -(hint>>1 & 1),
@@ -198,15 +180,14 @@ API_NS(invert_elligator_nonuniform) (
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));
}



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

@@ -86,7 +86,7 @@ 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


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

@@ -61,13 +61,16 @@ mask_t gf_lobit(const gf x) {
}

/** 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/c/p448/f_field.h View File

@@ -86,7 +86,7 @@ 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


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

@@ -61,13 +61,16 @@ mask_t gf_lobit(const gf x) {
}

/** 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++;
}


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

@@ -670,6 +670,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


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

@@ -670,6 +670,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


+ 6
- 13
src/per_curve/decaf.tmpl.c View File

@@ -227,7 +227,7 @@ decaf_error_t API_NS(point_decode) (
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);
mask_t succ = gf_deserialize(s, ser, 1, 0);
succ &= bool_to_mask(allow_identity) | ~gf_eq(s, ZERO);
succ &= ~gf_lobit(s);
@@ -816,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);
@@ -1132,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
@@ -1232,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);
@@ -1303,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;


+ 9
- 28
src/per_curve/elligator.tmpl.c View File

@@ -15,7 +15,6 @@ static const int EDWARDS_D = $(d);
extern const gf RISTRETTO_FACTOR;

/* End of template stuff */

extern mask_t API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
@@ -31,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);
@@ -101,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) (
@@ -125,7 +108,6 @@ API_NS(invert_elligator_nonuniform) (
const point_t p,
uint32_t hint_
) {
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */
mask_t hint = hint_;
mask_t sgn_s = -(hint & 1),
sgn_altx = -(hint>>1 & 1),
@@ -187,15 +169,14 @@ API_NS(invert_elligator_nonuniform) (
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));
}



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

@@ -655,6 +655,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


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

@@ -71,7 +71,7 @@ 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


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

@@ -50,13 +50,16 @@ mask_t gf_lobit(const gf x) {
}

/** 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++;
}


+ 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<IsoEd25519> {
static const int count = 16;
static const uint8_t values[count][IsoEd25519::Point::SER_BYTES];
};
const uint8_t base_multiples<IsoEd25519>::values
[base_multiples<IsoEd25519>::count][IsoEd25519::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<IsoEd25519> {
static const int count = 16;
static const uint8_t inputs[count][IsoEd25519::Point::HASH_BYTES];
static const uint8_t outputs[count][IsoEd25519::Point::SER_BYTES];
};
const uint8_t elligator_examples<IsoEd25519>::inputs
[elligator_examples<IsoEd25519>::count][IsoEd25519::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<IsoEd25519>::outputs
[elligator_examples<IsoEd25519>::count][IsoEd25519::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}
};

+ 28
- 1
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");
}
}
}

@@ -605,6 +614,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();
@@ -614,6 +640,7 @@ static void run() {
test_convert_eddsa_to_x();
test_cfrg_crypto();
test_cfrg_vectors();
test_dalek_vectors();
printf("\n");
}



Loading…
Cancel
Save