From 4de924c78606ac6eedd281b72d664afd697e08ba Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Fri, 13 Oct 2017 17:14:38 -0700 Subject: [PATCH] Incorporate test vectors from Dalek --- aux/ristretto/ristretto.sage | 48 ++-- src/GENERATED/c/curve25519/decaf.c | 19 +- src/GENERATED/c/curve25519/elligator.c | 37 +-- src/GENERATED/c/ed448goldilocks/decaf.c | 19 +- src/GENERATED/c/ed448goldilocks/elligator.c | 37 +-- src/GENERATED/c/p25519/f_field.h | 2 +- src/GENERATED/c/p25519/f_generic.c | 9 +- src/GENERATED/c/p448/f_field.h | 2 +- src/GENERATED/c/p448/f_generic.c | 9 +- src/GENERATED/include/decaf/point_255.h | 10 + src/GENERATED/include/decaf/point_448.h | 10 + src/per_curve/decaf.tmpl.c | 19 +- src/per_curve/elligator.tmpl.c | 37 +-- src/per_curve/point.tmpl.h | 10 + src/per_field/f_field.tmpl.h | 2 +- src/per_field/f_generic.tmpl.c | 9 +- test/ristretto_vectors.inc.cxx | 290 ++++++++++++++++++++ test/test_decaf.cxx | 29 +- 18 files changed, 440 insertions(+), 158 deletions(-) create mode 100644 test/ristretto_vectors.inc.cxx diff --git a/aux/ristretto/ristretto.sage b/aux/ristretto/ristretto.sage index a0138db..4bb08cc 100644 --- a/aux/ristretto/ristretto.sage +++ b/aux/ristretto/ristretto.sage @@ -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) diff --git a/src/GENERATED/c/curve25519/decaf.c b/src/GENERATED/c/curve25519/decaf.c index f7885e7..de5d3e7 100644 --- a/src/GENERATED/c/curve25519/decaf.c +++ b/src/GENERATED/c/curve25519/decaf.c @@ -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; diff --git a/src/GENERATED/c/curve25519/elligator.c b/src/GENERATED/c/curve25519/elligator.c index 0e58baf..2f47840 100644 --- a/src/GENERATED/c/curve25519/elligator.c +++ b/src/GENERATED/c/curve25519/elligator.c @@ -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>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)); } diff --git a/src/GENERATED/c/ed448goldilocks/decaf.c b/src/GENERATED/c/ed448goldilocks/decaf.c index 12c039f..a500db5 100644 --- a/src/GENERATED/c/ed448goldilocks/decaf.c +++ b/src/GENERATED/c/ed448goldilocks/decaf.c @@ -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; diff --git a/src/GENERATED/c/ed448goldilocks/elligator.c b/src/GENERATED/c/ed448goldilocks/elligator.c index ae71639..247e435 100644 --- a/src/GENERATED/c/ed448goldilocks/elligator.c +++ b/src/GENERATED/c/ed448goldilocks/elligator.c @@ -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>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)); } diff --git a/src/GENERATED/c/p25519/f_field.h b/src/GENERATED/c/p25519/f_field.h index 8818fd3..675cbd1 100644 --- a/src/GENERATED/c/p25519/f_field.h +++ b/src/GENERATED/c/p25519/f_field.h @@ -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 diff --git a/src/GENERATED/c/p25519/f_generic.c b/src/GENERATED/c/p25519/f_generic.c index c4b081a..5f52d7b 100644 --- a/src/GENERATED/c/p25519/f_generic.c +++ b/src/GENERATED/c/p25519/f_generic.c @@ -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; iz, *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; diff --git a/src/per_curve/elligator.tmpl.c b/src/per_curve/elligator.tmpl.c index f5a8fcd..2e24743 100644 --- a/src/per_curve/elligator.tmpl.c +++ b/src/per_curve/elligator.tmpl.c @@ -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>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)); } diff --git a/src/per_curve/point.tmpl.h b/src/per_curve/point.tmpl.h index 9744b2b..56f0a57 100644 --- a/src/per_curve/point.tmpl.h +++ b/src/per_curve/point.tmpl.h @@ -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 diff --git a/src/per_field/f_field.tmpl.h b/src/per_field/f_field.tmpl.h index 9d51d4b..5c04d3d 100644 --- a/src/per_field/f_field.tmpl.h +++ b/src/per_field/f_field.tmpl.h @@ -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 diff --git a/src/per_field/f_generic.tmpl.c b/src/per_field/f_generic.tmpl.c index bbcdb5a..2dfc920 100644 --- a/src/per_field/f_generic.tmpl.c +++ b/src/per_field/f_generic.tmpl.c @@ -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 struct base_multiples; + +/* Examples for multiples of base point */ +template <> struct base_multiples { + static const int count = 16; + static const uint8_t values[count][IsoEd25519::Point::SER_BYTES]; +}; +const uint8_t base_multiples::values + [base_multiples::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 { + static const int count = 16; + static const uint8_t values[count][Ed448Goldilocks::Point::SER_BYTES]; +}; +const uint8_t base_multiples::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 struct elligator_examples; + +/* Examples for Elligator */ +template <> struct elligator_examples { + 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::inputs + [elligator_examples::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::outputs + [elligator_examples::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 { + 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::inputs + [elligator_examples::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::outputs + [elligator_examples::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} +}; diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index c52747d..8dbadb0 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -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 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::count; i++) { + if (!decaf_memeq(q.serialize().data(),base_multiples::values[i],Point::SER_BYTES)) { + test.fail(); + printf(" Failed test vector for %d * base point.\n", i); + } + q += p; + } + for (unsigned i=0; i::count; i++) { + Point r = Point::from_hash(FixedBlock(elligator_examples::inputs[i])); + Point s = Point(FixedBlock(elligator_examples::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"); }