@@ -486,7 +486,7 @@ decaf_bool_t decaf_255_point_valid ( | |||||
* @param [out] q The point to torque. | * @param [out] q The point to torque. | ||||
* @param [in] p The point to torque. | * @param [in] p The point to torque. | ||||
*/ | */ | ||||
void decaf_255_point_debugging_2torque ( | |||||
void decaf_255_point_debugging_torque ( | |||||
decaf_255_point_t q, | decaf_255_point_t q, | ||||
const decaf_255_point_t p | const decaf_255_point_t p | ||||
) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
@@ -580,7 +580,7 @@ public: | |||||
} | } | ||||
inline Point& debugging_torque_in_place() { | inline Point& debugging_torque_in_place() { | ||||
decaf_255_point_debugging_2torque(p,p); | |||||
decaf_255_point_debugging_torque(p,p); | |||||
return *this; | return *this; | ||||
} | } | ||||
@@ -486,7 +486,7 @@ decaf_bool_t decaf_448_point_valid ( | |||||
* @param [out] q The point to torque. | * @param [out] q The point to torque. | ||||
* @param [in] p The point to torque. | * @param [in] p The point to torque. | ||||
*/ | */ | ||||
void decaf_448_point_debugging_2torque ( | |||||
void decaf_448_point_debugging_torque ( | |||||
decaf_448_point_t q, | decaf_448_point_t q, | ||||
const decaf_448_point_t p | const decaf_448_point_t p | ||||
) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
@@ -580,7 +580,7 @@ public: | |||||
} | } | ||||
inline Point& debugging_torque_in_place() { | inline Point& debugging_torque_in_place() { | ||||
decaf_448_point_debugging_2torque(p,p); | |||||
decaf_448_point_debugging_torque(p,p); | |||||
return *this; | return *this; | ||||
} | } | ||||
@@ -891,7 +891,7 @@ decaf_448_invert_elligator_nonuniform ( | |||||
return succ; | return succ; | ||||
} | } | ||||
void decaf_448_point_debugging_2torque ( | |||||
void decaf_448_point_debugging_torque ( | |||||
decaf_448_point_t q, | decaf_448_point_t q, | ||||
const decaf_448_point_t p | const decaf_448_point_t p | ||||
) { | ) { | ||||
@@ -481,7 +481,8 @@ static void deisogenize ( | |||||
gf_s *__restrict__ minus_t_over_s, | gf_s *__restrict__ minus_t_over_s, | ||||
const point_t p, | const point_t p, | ||||
decaf_bool_t toggle_hibit_s, | decaf_bool_t toggle_hibit_s, | ||||
decaf_bool_t toggle_hibit_t_over_s | |||||
decaf_bool_t toggle_hibit_t_over_s, | |||||
decaf_bool_t toggle_rotation | |||||
) { | ) { | ||||
gf c, d, x, t; | gf c, d, x, t; | ||||
gf_s *b = s, *a = minus_t_over_s; | gf_s *b = s, *a = minus_t_over_s; | ||||
@@ -514,7 +515,7 @@ static void deisogenize ( | |||||
* Pink bike shed: frob = zx * 1/tz | * Pink bike shed: frob = zx * 1/tz | ||||
*/ | */ | ||||
gf_mul ( a, b, c ); /* this is the case for PinkBikeShed */ | gf_mul ( a, b, c ); /* this is the case for PinkBikeShed */ | ||||
cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate ); | |||||
cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate^toggle_rotation ); | |||||
gf_sub ( e, ZERO, x ); | gf_sub ( e, ZERO, x ); | ||||
cond_sel ( x, p->y, e, rotate ); | cond_sel ( x, p->y, e, rotate ); | ||||
} | } | ||||
@@ -534,7 +535,7 @@ static void deisogenize ( | |||||
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; | gf s, mtos; | ||||
deisogenize(s,mtos,p,0,0); | |||||
deisogenize(s,mtos,p,0,0,0); | |||||
gf_encode ( ser, s ); | gf_encode ( ser, s ); | ||||
} | } | ||||
@@ -1165,7 +1166,7 @@ uint16_t API_NS(point_from_hash_nonuniform) ( | |||||
assert(API_NS(point_valid)(p)); | assert(API_NS(point_valid)(p)); | ||||
return (~square & 1) | (sgn_t_over_s & 2) | (sgn_r0 & 4) | (over & 8); | |||||
return (~square & 1) | (sgn_t_over_s & 2) | (sgn_r0 & 4) | (over & 16); | |||||
} | } | ||||
decaf_bool_t | decaf_bool_t | ||||
@@ -1176,9 +1177,10 @@ API_NS(invert_elligator_nonuniform) ( | |||||
) { | ) { | ||||
decaf_bool_t sgn_s = -(hint & 1), | decaf_bool_t sgn_s = -(hint & 1), | ||||
sgn_t_over_s = -(hint>>1 & 1), | sgn_t_over_s = -(hint>>1 & 1), | ||||
sgn_r0 = -(hint>>2 & 1); | |||||
sgn_r0 = -(hint>>2 & 1), | |||||
sgn_ed_T = -(hint>>3 & 1); | |||||
gf a, b, c, d; | gf a, b, c, d; | ||||
deisogenize(a,c,p,sgn_s,sgn_t_over_s); | |||||
deisogenize(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); | |||||
/* ok, a = s; c = -t/s */ | /* ok, a = s; c = -t/s */ | ||||
gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
@@ -1254,14 +1256,23 @@ decaf_bool_t API_NS(point_valid) ( | |||||
return out; | return out; | ||||
} | } | ||||
void API_NS(point_debugging_2torque) ( | |||||
void API_NS(point_debugging_torque) ( | |||||
point_t q, | point_t q, | ||||
const point_t p | const point_t p | ||||
) { | ) { | ||||
#if 0 | |||||
gf_sub(q->x,ZERO,p->x); | gf_sub(q->x,ZERO,p->x); | ||||
gf_sub(q->y,ZERO,p->y); | gf_sub(q->y,ZERO,p->y); | ||||
gf_cpy(q->z,p->z); | gf_cpy(q->z,p->z); | ||||
gf_cpy(q->t,p->t); | gf_cpy(q->t,p->t); | ||||
#else | |||||
gf tmp; | |||||
gf_mul(tmp,p->x,SQRT_MINUS_ONE); | |||||
gf_mul(q->x,p->y,SQRT_MINUS_ONE); | |||||
gf_cpy(q->y,tmp); | |||||
gf_cpy(q->z,p->z); | |||||
gf_sub(q->t,ZERO,p->t); | |||||
#endif | |||||
} | } | ||||
static void gf_batch_invert ( | static void gf_batch_invert ( | ||||
@@ -156,10 +156,10 @@ static void test_elligator() { | |||||
decaf::SpongeRng rng(decaf::Block("test_elligator")); | decaf::SpongeRng rng(decaf::Block("test_elligator")); | ||||
Test test("Elligator"); | Test test("Elligator"); | ||||
for (int i=0; i<16; i++) { | |||||
for (int i=0; i<32; i++) { | |||||
decaf::SecureBuffer b1(Point::HASH_BYTES); | decaf::SecureBuffer b1(Point::HASH_BYTES); | ||||
Point p = Point::identity(); | Point p = Point::identity(); | ||||
if (i>=8) p.debugging_torque_in_place(); | |||||
for (int j=0; j<i/8; j++) p.debugging_torque_in_place(); | |||||
bool succ = p.invert_elligator(b1,i&7); | bool succ = p.invert_elligator(b1,i&7); | ||||
Point q; | Point q; | ||||
unsigned char hint = q.set_to_hash(b1); | unsigned char hint = q.set_to_hash(b1); | ||||
@@ -172,7 +172,7 @@ static void test_elligator() { | |||||
} | } | ||||
} | } | ||||
for (int i=0; i<NTESTS && test.passing_now; i++) { | |||||
for (int i=0; i<NTESTS && (i<16 || test.passing_now); i++) { | |||||
size_t len = (i % (2*Point::HASH_BYTES + 3)); | size_t len = (i % (2*Point::HASH_BYTES + 3)); | ||||
decaf::SecureBuffer b1(len), b2(len); | decaf::SecureBuffer b1(len), b2(len); | ||||
rng.read(b1); | rng.read(b1); | ||||
@@ -181,7 +181,7 @@ static void test_elligator() { | |||||
memcpy(&b2[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES); | memcpy(&b2[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES); | ||||
Point s; | Point s; | ||||
unsigned char hint = s.set_to_hash(b1); | unsigned char hint = s.set_to_hash(b1); | ||||
if (i&1) s.debugging_torque_in_place(); | |||||
for (int j=0; j<(i&3); j++) s.debugging_torque_in_place(); | |||||
bool succ = s.invert_elligator(b2,hint); | bool succ = s.invert_elligator(b2,hint); | ||||
if (!succ || memcmp(b1,b2,len)) { | if (!succ || memcmp(b1,b2,len)) { | ||||
test.fail(); | test.fail(); | ||||