@@ -305,9 +305,8 @@ class Decaf_1_1_Point(QuotientEdwardsPoint): | |||||
return cls(x,y) | return cls(x,y) | ||||
@optimized_version_of("encodeSpec") | |||||
def encode(self): | |||||
"""Encode, optimized version""" | |||||
def toJacobiQuartic(self,toggle_rotation=False,toggle_altx=False,toggle_s=False): | |||||
"Return s,t on jacobi curve" | |||||
a,d = self.a,self.d | a,d = self.a,self.d | ||||
x,y,z,t = self.xyzt() | x,y,z,t = self.xyzt() | ||||
@@ -327,50 +326,88 @@ class Decaf_1_1_Point(QuotientEdwardsPoint): | |||||
iden = isr * den * self.isoMagic | iden = isr * den * self.isoMagic | ||||
inum = isr * num | inum = isr * num | ||||
if negative(iden*inum*self.i*t^2*(d-a)): | |||||
if negative(iden*inum*self.i*t^2*(d-a)) != toggle_rotation: | |||||
iden,inum = inum,iden | iden,inum = inum,iden | ||||
fac = x*sqrt(a) | fac = x*sqrt(a) | ||||
toggle = (-a==1) | |||||
toggle=(a==-1) | |||||
else: | else: | ||||
fac = y | fac = y | ||||
toggle = False | |||||
toggle=False | |||||
imi = self.isoMagic * self.i | imi = self.isoMagic * self.i | ||||
altx = inum*t*imi | altx = inum*t*imi | ||||
if negative(altx) != toggle: inum =- inum | |||||
s = fac*iden*(inum*z + 1)*imi | |||||
neg_altx = negative(altx) != toggle_altx | |||||
if neg_altx != toggle: inum =- inum | |||||
tmp = fac*(inum*z + 1) | |||||
s = iden*tmp*imi | |||||
# Version without the above IMAGINE_TWIST hack | |||||
# num = (z+y)*(z-y) | |||||
# den = x*y | |||||
# isr = isqrt(num*(a-d)*den^2) | |||||
# | |||||
# imi = self.isoMagic * self.i | |||||
# iden = isr * den * imi | |||||
# inum = isr * num | |||||
# if isr: assert iden*inum == 1/imi/den | |||||
# | |||||
# if negative(iden*inum*self.i*t^2*(d-a)): | |||||
# iden,inum = inum,iden | |||||
# fac = x*sqrt(a) | |||||
# toggle = (a==1) | |||||
# else: | |||||
# fac = y | |||||
# toggle = False | |||||
# | |||||
# altx = inum*t*self.isoMagic | |||||
# if negative(altx) != toggle: inum =- inum | |||||
# s = fac*iden*imi*(inum*z - 1) | |||||
negm1 = (negative(s) != toggle_s) != neg_altx | |||||
if negm1: m1 = a*fac + z | |||||
else: m1 = a*fac - z | |||||
swap = toggle_s | |||||
else: | else: | ||||
# Much simpler cofactor 4 version | # Much simpler cofactor 4 version | ||||
num = (x+t)*(x-t) | num = (x+t)*(x-t) | ||||
isr = isqrt(num*(a-d)*x^2) | isr = isqrt(num*(a-d)*x^2) | ||||
ratio = isr*num | ratio = isr*num | ||||
if negative(ratio*self.isoMagic): ratio=-ratio | |||||
s = (a-d)*isr*x*(ratio*z - t) | |||||
altx = ratio*self.isoMagic | |||||
neg_altx = negative(altx) != toggle_altx | |||||
if neg_altx: ratio =- ratio | |||||
tmp = ratio*z - t | |||||
s = (a-d)*isr*x*tmp | |||||
negx = (negative(s) != toggle_s) != neg_altx | |||||
if negx: m1 = -a*t + x | |||||
else: m1 = -a*t - x | |||||
swap = toggle_s | |||||
if negative(s): s = -s | |||||
return self.gfToBytes(s,mustBePositive=True) | |||||
return s,m1,a*tmp,swap | |||||
def invertElligator(self,toggle_r=False,*args,**kwargs): | |||||
"Produce preimage of self under elligator, or None" | |||||
a,d = self.a,self.d | |||||
rets = [] | |||||
tr = [False,True] if self.cofactor == 8 else [False] | |||||
for toggle_rotation in tr: | |||||
for toggle_altx in [False,True]: | |||||
for toggle_s in [False,True]: | |||||
for toggle_r in [False,True]: | |||||
s,m1,m12,swap = self.toJacobiQuartic(toggle_rotation,toggle_altx,toggle_s) | |||||
if self == self.__class__(): | |||||
# Hacks for identity! | |||||
if toggle_altx: m12 = 1 | |||||
elif toggle_s: m1 = 1 | |||||
elif toggle_r: continue | |||||
## BOTH??? | |||||
rnum = (d*a*m12-m1) | |||||
rden = ((d*a-1)*m12+m1) | |||||
if swap: rnum,rden = rden,rnum | |||||
ok,sr = isqrt_i(rnum*rden*self.qnr) | |||||
if not ok: continue | |||||
sr *= rnum | |||||
if negative(sr) != toggle_r: sr = -sr | |||||
ret = self.gfToBytes(sr) | |||||
assert self.elligator(ret) == self or self.elligator(ret) == -self | |||||
if self.elligator(ret) == -self and self != -self: print "Negated!",[toggle_rotation,toggle_altx,toggle_s,toggle_r] | |||||
rets.append(bytes(ret)) | |||||
return rets | |||||
@optimized_version_of("encodeSpec") | |||||
def encode(self): | |||||
"""Encode, optimized version""" | |||||
return self.gfToBytes(self.toJacobiQuartic()[0]) | |||||
@classmethod | @classmethod | ||||
@optimized_version_of("decodeSpec") | @optimized_version_of("decodeSpec") | ||||
@@ -404,9 +441,10 @@ class Decaf_1_1_Point(QuotientEdwardsPoint): | |||||
return cls(x,sgn*y) | return cls(x,sgn*y) | ||||
@classmethod | @classmethod | ||||
def elligatorSpec(cls,r0): | |||||
def elligatorSpec(cls,r0,fromR=False): | |||||
a,d = cls.a,cls.d | a,d = cls.a,cls.d | ||||
r = cls.qnr * cls.bytesToGf(r0)^2 | |||||
if fromR: r = r0 | |||||
else: r = cls.qnr * cls.bytesToGf(r0)^2 | |||||
den = (d*r-(d-a))*((d-a)*r-d) | den = (d*r-(d-a))*((d-a)*r-d) | ||||
if den == 0: return cls() | if den == 0: return cls() | ||||
@@ -608,9 +646,27 @@ test(Ed448GoldilocksPoint,100) | |||||
def testElligator(cls,n): | def testElligator(cls,n): | ||||
print "Testing elligator on %s" % cls.__name__ | print "Testing elligator on %s" % cls.__name__ | ||||
for i in xrange(n): | for i in xrange(n): | ||||
cls.elligator(randombytes(cls.encLen)) | |||||
r = randombytes(cls.encLen) | |||||
P = cls.elligator(r) | |||||
if hasattr(P,"invertElligator"): | |||||
iv = P.invertElligator() | |||||
modr = bytes(cls.gfToBytes(cls.bytesToGf(r))) | |||||
iv2 = P.torque().invertElligator() | |||||
if modr not in iv: print "Failed to invert Elligator!" | |||||
if len(iv) != len(set(iv)): | |||||
print "Elligator inverses not unique!", len(set(iv)), len(iv) | |||||
if iv != iv2: | |||||
print "Elligator is untorqueable!" | |||||
#print [binascii.hexlify(j) for j in iv] | |||||
#print [binascii.hexlify(j) for j in iv2] | |||||
#break | |||||
else: | |||||
pass # TODO | |||||
testElligator(Ed25519Point,100) | testElligator(Ed25519Point,100) | ||||
testElligator(NegEd25519Point,100) | testElligator(NegEd25519Point,100) | ||||
testElligator(IsoEd25519Point,100) | |||||
testElligator(IsoEd448Point,100) | testElligator(IsoEd448Point,100) | ||||
testElligator(Ed448GoldilocksPoint,100) | testElligator(Ed448GoldilocksPoint,100) | ||||
testElligator(TwistedEd448GoldilocksPoint,100) | testElligator(TwistedEd448GoldilocksPoint,100) | ||||
@@ -131,27 +131,30 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
/* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
); | ); | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
) { | ) { | ||||
#if COFACTOR == 4 | |||||
#if COFACTOR == 4 && !IMAGINE_TWIST | |||||
(void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
gf t1,t2,t3; | |||||
gf t1; | |||||
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1; | |||||
gf_add(t1,p->x,p->t); | gf_add(t1,p->x,p->t); | ||||
gf_sub(t2,p->x,p->t); | gf_sub(t2,p->x,p->t); | ||||
@@ -161,20 +164,27 @@ void API_NS(deisogenize) ( | |||||
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | ||||
gf_isr(t1,t2); /* t1 = isr */ | gf_isr(t1,t2); /* t1 = isr */ | ||||
gf_mul(t2,t1,t3); /* t2 = ratio */ | gf_mul(t2,t1,t3); /* t2 = ratio */ | ||||
gf_mul(altx,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_mul(t4,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(t4) ^ toggle_altx; | |||||
gf_cond_neg(t2, negx); | gf_cond_neg(t2, negx); | ||||
gf_cond_neg(altx, negx); | |||||
gf_mul(t3,t2,p->z); | gf_mul(t3,t2,p->z); | ||||
gf_sub(t3,t3,p->t); | gf_sub(t3,t3,p->t); | ||||
gf_mul(t2,t3,p->x); | gf_mul(t2,t3,p->x); | ||||
gf_mulw(t3,t2,-1-TWISTED_D); | |||||
gf_mul(s,t3,t1); | |||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
gf_mulw(t4,t2,-1-TWISTED_D); | |||||
gf_mul(s,t4,t1); | |||||
mask_t lobs = gf_lobit(s); | |||||
gf_cond_neg(s,lobs); | |||||
gf_copy(inv_el_m1,p->x); | |||||
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | |||||
gf_add(inv_el_m1,inv_el_m1,p->t); | |||||
return toggle_s; | |||||
#elif COFACTOR == 8 && IMAGINE_TWIST | |||||
gf_s *altx = inv_el_sum; // TODO | |||||
(void)inv_el_m1; | |||||
#elif COFACTOR == 8 | |||||
/* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
gf t1,t2,t3,t4; | |||||
gf t1,t2,t3,t4,t5; | |||||
gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
gf_sub(t2,p->z,p->y); | gf_sub(t2,p->z,p->y); | ||||
gf_mul(t3,t1,t2); /* t3 = num */ | gf_mul(t3,t1,t2); /* t3 = num */ | ||||
@@ -196,27 +206,34 @@ void API_NS(deisogenize) ( | |||||
mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
gf_cond_sel(t4,p->y,t4,rotate); /* ix if rotate, else y */ | |||||
gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
gf_mul(t3,t2,t4); /* "fac*iden" */ | gf_mul(t3,t2,t4); /* "fac*iden" */ | ||||
gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | ||||
gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | ||||
gf_mul(t3,t2,p->t); | |||||
gf_mul(altx,t3,t1); | |||||
mask_t negx = rotate ^ gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(altx,negx); | |||||
gf_cond_neg(t1,negx); | |||||
gf_mul(t5,t2,p->t); | |||||
gf_mul(altx,t5,t1); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(t1,negx^rotate); | |||||
gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
gf_mul(s,t2,t4); | gf_mul(s,t2,t4); | ||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
mask_t negs = gf_lobit(s); | |||||
gf_cond_neg(s,negs); | |||||
mask_t negz = ~negs ^ toggle_s ^ negx; | |||||
gf_copy(inv_el_m1,p->z); | |||||
gf_cond_neg(inv_el_m1,negz); | |||||
gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
return toggle_s; | |||||
#else | #else | ||||
#error "Cofactor must be 4 or 8" | |||||
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | |||||
#endif | #endif | ||||
} | } | ||||
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
gf s, mtos; | |||||
API_NS(deisogenize)(s,mtos,p,0,0,0); | |||||
gf s,ie1,ie2; | |||||
(void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
} | } | ||||
@@ -23,9 +23,10 @@ | |||||
static const int EDWARDS_D = -121665; | static const int EDWARDS_D = -121665; | ||||
/* End of template stuff */ | /* End of template stuff */ | ||||
extern void API_NS(deisogenize) ( | |||||
extern mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | mask_t toggle_hibit_s, | ||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
@@ -131,48 +132,48 @@ API_NS(invert_elligator_nonuniform) ( | |||||
const point_t p, | const point_t p, | ||||
uint32_t hint_ | uint32_t hint_ | ||||
) { | ) { | ||||
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */ | |||||
mask_t hint = hint_; | mask_t hint = hint_; | ||||
mask_t sgn_s = -(hint & 1), | mask_t sgn_s = -(hint & 1), | ||||
sgn_t_over_s = -(hint>>1 & 1), | |||||
sgn_altx = -(hint>>1 & 1), | |||||
sgn_r0 = -(hint>>2 & 1), | sgn_r0 = -(hint>>2 & 1), | ||||
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | ||||
* change this mask extraction. | * change this mask extraction. | ||||
*/ | */ | ||||
sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
gf a, b, c, d; | |||||
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); | |||||
gf a,b,c; | |||||
mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
(void)is_identity; | |||||
gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | |||||
#if IMAGINE_TWIST | |||||
gf_mulw(a,b,EDWARDS_D); | |||||
gf_sub(b,a,b); | |||||
#else | |||||
gf_mulw(a,b,EDWARDS_D-1); | |||||
gf_add(b,a,b); | |||||
#endif | |||||
gf_sub(a,a,c); | |||||
gf_add(b,b,c); | |||||
gf_cond_swap(a,b,swap); | |||||
gf_mul_qnr(c,b); | |||||
gf_mul(b,c,a); | |||||
mask_t succ = gf_isr(c,b); | |||||
succ |= gf_eq(b,ZERO); | |||||
gf_mul(b,c,a); | |||||
#if 255 == 8*SER_BYTES + 1 /* p521. */ | #if 255 == 8*SER_BYTES + 1 /* p521. */ | ||||
sgn_r0 = 0; | sgn_r0 = 0; | ||||
#endif | #endif | ||||
/* ok, a = s; c = -t/s */ | |||||
gf_mul(b,c,a); | |||||
gf_sub(b,ONE,b); /* t+1 */ | |||||
gf_sqr(c,a); /* s^2 */ | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
/* identity adjustments */ | |||||
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */ | |||||
/* if hint is 0, -> 0 */ | |||||
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */ | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s); | |||||
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s); | |||||
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */ | |||||
gf_add(a,b,d); /* num? */ | |||||
gf_sub(d,d,b); /* den? */ | |||||
gf_mul(b,a,d); /* n*d */ | |||||
gf_cond_sel(a,d,a,sgn_s); | |||||
gf_mul_qnr(d,b); | |||||
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO); | |||||
gf_mul(b,a,c); | |||||
gf_cond_neg(b, sgn_r0^gf_hibit(b)); | gf_cond_neg(b, sgn_r0^gf_hibit(b)); | ||||
succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
#if COFACTOR == 8 | |||||
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
#endif | |||||
// #if COFACTOR == 8 | |||||
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
// #endif | |||||
#if 255 == 8*SER_BYTES + 1 /* p521 */ | #if 255 == 8*SER_BYTES + 1 /* p521 */ | ||||
gf_serialize(recovered_hash,b,0); | gf_serialize(recovered_hash,b,0); | ||||
@@ -131,27 +131,30 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
/* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
); | ); | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
) { | ) { | ||||
#if COFACTOR == 4 | |||||
#if COFACTOR == 4 && !IMAGINE_TWIST | |||||
(void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
gf t1,t2,t3; | |||||
gf t1; | |||||
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1; | |||||
gf_add(t1,p->x,p->t); | gf_add(t1,p->x,p->t); | ||||
gf_sub(t2,p->x,p->t); | gf_sub(t2,p->x,p->t); | ||||
@@ -161,20 +164,27 @@ void API_NS(deisogenize) ( | |||||
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | ||||
gf_isr(t1,t2); /* t1 = isr */ | gf_isr(t1,t2); /* t1 = isr */ | ||||
gf_mul(t2,t1,t3); /* t2 = ratio */ | gf_mul(t2,t1,t3); /* t2 = ratio */ | ||||
gf_mul(altx,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_mul(t4,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(t4) ^ toggle_altx; | |||||
gf_cond_neg(t2, negx); | gf_cond_neg(t2, negx); | ||||
gf_cond_neg(altx, negx); | |||||
gf_mul(t3,t2,p->z); | gf_mul(t3,t2,p->z); | ||||
gf_sub(t3,t3,p->t); | gf_sub(t3,t3,p->t); | ||||
gf_mul(t2,t3,p->x); | gf_mul(t2,t3,p->x); | ||||
gf_mulw(t3,t2,-1-TWISTED_D); | |||||
gf_mul(s,t3,t1); | |||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
gf_mulw(t4,t2,-1-TWISTED_D); | |||||
gf_mul(s,t4,t1); | |||||
mask_t lobs = gf_lobit(s); | |||||
gf_cond_neg(s,lobs); | |||||
gf_copy(inv_el_m1,p->x); | |||||
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | |||||
gf_add(inv_el_m1,inv_el_m1,p->t); | |||||
return toggle_s; | |||||
#elif COFACTOR == 8 && IMAGINE_TWIST | |||||
gf_s *altx = inv_el_sum; // TODO | |||||
(void)inv_el_m1; | |||||
#elif COFACTOR == 8 | |||||
/* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
gf t1,t2,t3,t4; | |||||
gf t1,t2,t3,t4,t5; | |||||
gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
gf_sub(t2,p->z,p->y); | gf_sub(t2,p->z,p->y); | ||||
gf_mul(t3,t1,t2); /* t3 = num */ | gf_mul(t3,t1,t2); /* t3 = num */ | ||||
@@ -196,27 +206,34 @@ void API_NS(deisogenize) ( | |||||
mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
gf_cond_sel(t4,p->y,t4,rotate); /* ix if rotate, else y */ | |||||
gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
gf_mul(t3,t2,t4); /* "fac*iden" */ | gf_mul(t3,t2,t4); /* "fac*iden" */ | ||||
gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | ||||
gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | ||||
gf_mul(t3,t2,p->t); | |||||
gf_mul(altx,t3,t1); | |||||
mask_t negx = rotate ^ gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(altx,negx); | |||||
gf_cond_neg(t1,negx); | |||||
gf_mul(t5,t2,p->t); | |||||
gf_mul(altx,t5,t1); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(t1,negx^rotate); | |||||
gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
gf_mul(s,t2,t4); | gf_mul(s,t2,t4); | ||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
mask_t negs = gf_lobit(s); | |||||
gf_cond_neg(s,negs); | |||||
mask_t negz = ~negs ^ toggle_s ^ negx; | |||||
gf_copy(inv_el_m1,p->z); | |||||
gf_cond_neg(inv_el_m1,negz); | |||||
gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
return toggle_s; | |||||
#else | #else | ||||
#error "Cofactor must be 4 or 8" | |||||
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | |||||
#endif | #endif | ||||
} | } | ||||
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
gf s, mtos; | |||||
API_NS(deisogenize)(s,mtos,p,0,0,0); | |||||
gf s,ie1,ie2; | |||||
(void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
} | } | ||||
@@ -23,9 +23,10 @@ | |||||
static const int EDWARDS_D = -39081; | static const int EDWARDS_D = -39081; | ||||
/* End of template stuff */ | /* End of template stuff */ | ||||
extern void API_NS(deisogenize) ( | |||||
extern mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | mask_t toggle_hibit_s, | ||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
@@ -131,48 +132,48 @@ API_NS(invert_elligator_nonuniform) ( | |||||
const point_t p, | const point_t p, | ||||
uint32_t hint_ | uint32_t hint_ | ||||
) { | ) { | ||||
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */ | |||||
mask_t hint = hint_; | mask_t hint = hint_; | ||||
mask_t sgn_s = -(hint & 1), | mask_t sgn_s = -(hint & 1), | ||||
sgn_t_over_s = -(hint>>1 & 1), | |||||
sgn_altx = -(hint>>1 & 1), | |||||
sgn_r0 = -(hint>>2 & 1), | sgn_r0 = -(hint>>2 & 1), | ||||
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | ||||
* change this mask extraction. | * change this mask extraction. | ||||
*/ | */ | ||||
sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
gf a, b, c, d; | |||||
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); | |||||
gf a,b,c; | |||||
mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
(void)is_identity; | |||||
gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | |||||
#if IMAGINE_TWIST | |||||
gf_mulw(a,b,EDWARDS_D); | |||||
gf_sub(b,a,b); | |||||
#else | |||||
gf_mulw(a,b,EDWARDS_D-1); | |||||
gf_add(b,a,b); | |||||
#endif | |||||
gf_sub(a,a,c); | |||||
gf_add(b,b,c); | |||||
gf_cond_swap(a,b,swap); | |||||
gf_mul_qnr(c,b); | |||||
gf_mul(b,c,a); | |||||
mask_t succ = gf_isr(c,b); | |||||
succ |= gf_eq(b,ZERO); | |||||
gf_mul(b,c,a); | |||||
#if 448 == 8*SER_BYTES + 1 /* p521. */ | #if 448 == 8*SER_BYTES + 1 /* p521. */ | ||||
sgn_r0 = 0; | sgn_r0 = 0; | ||||
#endif | #endif | ||||
/* ok, a = s; c = -t/s */ | |||||
gf_mul(b,c,a); | |||||
gf_sub(b,ONE,b); /* t+1 */ | |||||
gf_sqr(c,a); /* s^2 */ | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
/* identity adjustments */ | |||||
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */ | |||||
/* if hint is 0, -> 0 */ | |||||
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */ | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s); | |||||
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s); | |||||
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */ | |||||
gf_add(a,b,d); /* num? */ | |||||
gf_sub(d,d,b); /* den? */ | |||||
gf_mul(b,a,d); /* n*d */ | |||||
gf_cond_sel(a,d,a,sgn_s); | |||||
gf_mul_qnr(d,b); | |||||
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO); | |||||
gf_mul(b,a,c); | |||||
gf_cond_neg(b, sgn_r0^gf_hibit(b)); | gf_cond_neg(b, sgn_r0^gf_hibit(b)); | ||||
succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
#if COFACTOR == 8 | |||||
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
#endif | |||||
// #if COFACTOR == 8 | |||||
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
// #endif | |||||
#if 448 == 8*SER_BYTES + 1 /* p521 */ | #if 448 == 8*SER_BYTES + 1 /* p521 */ | ||||
gf_serialize(recovered_hash,b,0); | gf_serialize(recovered_hash,b,0); | ||||
@@ -120,27 +120,30 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
/* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
); | ); | ||||
void API_NS(deisogenize) ( | |||||
mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | |||||
mask_t toggle_s, | |||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
mask_t toggle_rotation | mask_t toggle_rotation | ||||
) { | ) { | ||||
#if COFACTOR == 4 | |||||
#if COFACTOR == 4 && !IMAGINE_TWIST | |||||
(void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
gf t1,t2,t3; | |||||
gf t1; | |||||
gf_s *t2 = s, *t3=inv_el_sum, *t4=inv_el_m1; | |||||
gf_add(t1,p->x,p->t); | gf_add(t1,p->x,p->t); | ||||
gf_sub(t2,p->x,p->t); | gf_sub(t2,p->x,p->t); | ||||
@@ -150,20 +153,27 @@ void API_NS(deisogenize) ( | |||||
gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | gf_mulw(t2,t1,-1-TWISTED_D); /* -x^2 * (a-d) * num */ | ||||
gf_isr(t1,t2); /* t1 = isr */ | gf_isr(t1,t2); /* t1 = isr */ | ||||
gf_mul(t2,t1,t3); /* t2 = ratio */ | gf_mul(t2,t1,t3); /* t2 = ratio */ | ||||
gf_mul(altx,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_mul(t4,t2,RISTRETTO_ISOMAGIC); | |||||
mask_t negx = gf_lobit(t4) ^ toggle_altx; | |||||
gf_cond_neg(t2, negx); | gf_cond_neg(t2, negx); | ||||
gf_cond_neg(altx, negx); | |||||
gf_mul(t3,t2,p->z); | gf_mul(t3,t2,p->z); | ||||
gf_sub(t3,t3,p->t); | gf_sub(t3,t3,p->t); | ||||
gf_mul(t2,t3,p->x); | gf_mul(t2,t3,p->x); | ||||
gf_mulw(t3,t2,-1-TWISTED_D); | |||||
gf_mul(s,t3,t1); | |||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
gf_mulw(t4,t2,-1-TWISTED_D); | |||||
gf_mul(s,t4,t1); | |||||
mask_t lobs = gf_lobit(s); | |||||
gf_cond_neg(s,lobs); | |||||
gf_copy(inv_el_m1,p->x); | |||||
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | |||||
gf_add(inv_el_m1,inv_el_m1,p->t); | |||||
return toggle_s; | |||||
#elif COFACTOR == 8 && IMAGINE_TWIST | |||||
gf_s *altx = inv_el_sum; // TODO | |||||
(void)inv_el_m1; | |||||
#elif COFACTOR == 8 | |||||
/* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
gf t1,t2,t3,t4; | |||||
gf t1,t2,t3,t4,t5; | |||||
gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
gf_sub(t2,p->z,p->y); | gf_sub(t2,p->z,p->y); | ||||
gf_mul(t3,t1,t2); /* t3 = num */ | gf_mul(t3,t1,t2); /* t3 = num */ | ||||
@@ -185,27 +195,34 @@ void API_NS(deisogenize) ( | |||||
mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
gf_cond_sel(t4,p->y,t4,rotate); /* ix if rotate, else y */ | |||||
gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
gf_mul(t3,t2,t4); /* "fac*iden" */ | gf_mul(t3,t2,t4); /* "fac*iden" */ | ||||
gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | ||||
gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | ||||
gf_mul(t3,t2,p->t); | |||||
gf_mul(altx,t3,t1); | |||||
mask_t negx = rotate ^ gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(altx,negx); | |||||
gf_cond_neg(t1,negx); | |||||
gf_mul(t5,t2,p->t); | |||||
gf_mul(altx,t5,t1); | |||||
mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
gf_cond_neg(t1,negx^rotate); | |||||
gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
gf_mul(s,t2,t4); | gf_mul(s,t2,t4); | ||||
gf_cond_neg(s,gf_lobit(s)^toggle_hibit_s); | |||||
mask_t negs = gf_lobit(s); | |||||
gf_cond_neg(s,negs); | |||||
mask_t negz = ~negs ^ toggle_s ^ negx; | |||||
gf_copy(inv_el_m1,p->z); | |||||
gf_cond_neg(inv_el_m1,negz); | |||||
gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
return toggle_s; | |||||
#else | #else | ||||
#error "Cofactor must be 4 or 8" | |||||
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | |||||
#endif | #endif | ||||
} | } | ||||
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
gf s, mtos; | |||||
API_NS(deisogenize)(s,mtos,p,0,0,0); | |||||
gf s,ie1,ie2; | |||||
(void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
} | } | ||||
@@ -12,9 +12,10 @@ | |||||
static const int EDWARDS_D = $(d); | static const int EDWARDS_D = $(d); | ||||
/* End of template stuff */ | /* End of template stuff */ | ||||
extern void API_NS(deisogenize) ( | |||||
extern mask_t API_NS(deisogenize) ( | |||||
gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
gf_s *__restrict__ altx, | |||||
gf_s *__restrict__ inv_el_sum, | |||||
gf_s *__restrict__ inv_el_m1, | |||||
const point_t p, | const point_t p, | ||||
mask_t toggle_hibit_s, | mask_t toggle_hibit_s, | ||||
mask_t toggle_altx, | mask_t toggle_altx, | ||||
@@ -120,48 +121,48 @@ API_NS(invert_elligator_nonuniform) ( | |||||
const point_t p, | const point_t p, | ||||
uint32_t hint_ | uint32_t hint_ | ||||
) { | ) { | ||||
/* TODO: test that this can produce sqrt((d-a)/ud) etc. */ | |||||
mask_t hint = hint_; | mask_t hint = hint_; | ||||
mask_t sgn_s = -(hint & 1), | mask_t sgn_s = -(hint & 1), | ||||
sgn_t_over_s = -(hint>>1 & 1), | |||||
sgn_altx = -(hint>>1 & 1), | |||||
sgn_r0 = -(hint>>2 & 1), | sgn_r0 = -(hint>>2 & 1), | ||||
/* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, | ||||
* change this mask extraction. | * change this mask extraction. | ||||
*/ | */ | ||||
sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
gf a, b, c, d; | |||||
API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); | |||||
gf a,b,c; | |||||
mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
(void)is_identity; | |||||
gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | |||||
#if IMAGINE_TWIST | |||||
gf_mulw(a,b,EDWARDS_D); | |||||
gf_sub(b,a,b); | |||||
#else | |||||
gf_mulw(a,b,EDWARDS_D-1); | |||||
gf_add(b,a,b); | |||||
#endif | |||||
gf_sub(a,a,c); | |||||
gf_add(b,b,c); | |||||
gf_cond_swap(a,b,swap); | |||||
gf_mul_qnr(c,b); | |||||
gf_mul(b,c,a); | |||||
mask_t succ = gf_isr(c,b); | |||||
succ |= gf_eq(b,ZERO); | |||||
gf_mul(b,c,a); | |||||
#if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */ | #if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */ | ||||
sgn_r0 = 0; | sgn_r0 = 0; | ||||
#endif | #endif | ||||
/* ok, a = s; c = -t/s */ | |||||
gf_mul(b,c,a); | |||||
gf_sub(b,ONE,b); /* t+1 */ | |||||
gf_sqr(c,a); /* s^2 */ | |||||
mask_t is_identity = gf_eq(p->t,ZERO); | |||||
/* identity adjustments */ | |||||
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */ | |||||
/* if hint is 0, -> 0 */ | |||||
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */ | |||||
gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s); | |||||
gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s); | |||||
gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */ | |||||
gf_add(a,b,d); /* num? */ | |||||
gf_sub(d,d,b); /* den? */ | |||||
gf_mul(b,a,d); /* n*d */ | |||||
gf_cond_sel(a,d,a,sgn_s); | |||||
gf_mul_qnr(d,b); | |||||
mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO); | |||||
gf_mul(b,a,c); | |||||
gf_cond_neg(b, sgn_r0^gf_hibit(b)); | gf_cond_neg(b, sgn_r0^gf_hibit(b)); | ||||
succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
#if COFACTOR == 8 | |||||
succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
#endif | |||||
// #if COFACTOR == 8 | |||||
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | |||||
// #endif | |||||
#if $(gf_bits) == 8*SER_BYTES + 1 /* p521 */ | #if $(gf_bits) == 8*SER_BYTES + 1 /* p521 */ | ||||
gf_serialize(recovered_hash,b,0); | gf_serialize(recovered_hash,b,0); | ||||
@@ -75,7 +75,7 @@ void usage() { | |||||
fprintf(stderr," Operations:\n"); | fprintf(stderr," Operations:\n"); | ||||
fprintf(stderr," -n [point]: negative of point\n"); | fprintf(stderr," -n [point]: negative of point\n"); | ||||
fprintf(stderr," -s [scalar] * [point]: Hash to curve using elligator\n"); | fprintf(stderr," -s [scalar] * [point]: Hash to curve using elligator\n"); | ||||
fprintf(stderr," [point] + [point]: Add two poitns\n"); | |||||
fprintf(stderr," [point] + [point]: Add two points\n"); | |||||
fprintf(stderr,"\n"); | fprintf(stderr,"\n"); | ||||
fprintf(stderr," NB: this is a debugging widget. It doesn't yet have order of operations.\n"); | fprintf(stderr," NB: this is a debugging widget. It doesn't yet have order of operations.\n"); | ||||
fprintf(stderr," *** DON'T USE THIS UTILITY FOR ACTUAL CRYPTO! ***\n"); | fprintf(stderr," *** DON'T USE THIS UTILITY FOR ACTUAL CRYPTO! ***\n"); | ||||
@@ -483,7 +483,7 @@ static void test_cfrg_vectors() { | |||||
SecureBuffer eddsa_pk2 = priv.pub().serialize(); | SecureBuffer eddsa_pk2 = priv.pub().serialize(); | ||||
if (!memeq(SecureBuffer(eddsa_pk[t]), eddsa_pk2)) { | if (!memeq(SecureBuffer(eddsa_pk[t]), eddsa_pk2)) { | ||||
test.fail(); | test.fail(); | ||||
printf(" EdDSA PK vectors disagree."); | |||||
printf(" EdDSA PK vectors #%d disagree.", t); | |||||
printf("\n Correct: "); | printf("\n Correct: "); | ||||
for (unsigned i=0; i<eddsa_pk[t].size(); i++) printf("%02x", eddsa_pk[t][i]); | for (unsigned i=0; i<eddsa_pk[t].size(); i++) printf("%02x", eddsa_pk[t][i]); | ||||
printf("\n Incorrect: "); | printf("\n Incorrect: "); | ||||