@@ -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) | |||
#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) |
@@ -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; | |||
@@ -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)); | |||
} | |||
@@ -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; | |||
@@ -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)); | |||
} | |||
@@ -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 | |||
@@ -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++; | |||
} | |||
@@ -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 | |||
@@ -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++; | |||
} | |||
@@ -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 | |||
@@ -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 | |||
@@ -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; | |||
@@ -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)); | |||
} | |||
@@ -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 | |||
@@ -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 | |||
@@ -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++; | |||
} | |||
@@ -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} | |||
}; |
@@ -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"); | |||
} | |||