From 0dc21dd9d7c8073dd8288da6c655075385b7120f Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Wed, 28 Jan 2015 17:19:15 -0800 Subject: [PATCH] negation properties for elligator --- include/decaf.h | 5 +++++ src/decaf.c | 3 +-- test/test_pointops.c | 28 ++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/decaf.h b/include/decaf.h index a8ffe7d..6cdd862 100644 --- a/include/decaf.h +++ b/include/decaf.h @@ -24,6 +24,8 @@ typedef uint64_t decaf_word_t, decaf_bool_t; +/* TODO: prefix all these operations and factor to support multiple curves. */ + /* TODO: perfield, so when 25519 hits this will change */ #define DECAF_FIELD_BITS 448 #define DECAF_LIMBS (512/8/sizeof(decaf_word_t)) @@ -186,6 +188,9 @@ decaf_bool_t decaf_valid ( * A factor of 2 because we quotient out the 2-torsion. * // TODO: check that it isn't more, especially for the identity point. * + * Negating the input (mod q) results in the same point. Inverting the input + * (mod q) results in the negative point. This is the same as Elligator. + * * This function isn't quite indifferentiable from a random oracle. * However, it is suitable for many protocols, including SPEKE and SPAKE2 EE. * Furthermore, calling it twice with independent seeds and adding the results diff --git a/src/decaf.c b/src/decaf.c index fbb92fc..9ae0677 100644 --- a/src/decaf.c +++ b/src/decaf.c @@ -397,10 +397,10 @@ void decaf_nonuniform_map_to_curve ( mask_t square = gf_eq(e,ONE); gf_mul(a,b,r); cond_sel(b,a,b,square); - cond_neg(b,hibit(b)); gf_mlw(a,b,EDWARDS_D+1); cond_swap(ur2_d,udr2_1,~square); gf_mul(e,ur2_d,a); + cond_neg(e,hibit(e)^square); gf_mul(b,udr2_1,a); gf_sqr(c,b); gf_sqr(a,e); @@ -414,7 +414,6 @@ void decaf_nonuniform_map_to_curve ( gf_mul(p->t,b,e); } - void decaf_uniform_map_to_curve ( decaf_point_t pt, const unsigned char hashed_data[2*DECAF_SER_BYTES] diff --git a/test/test_pointops.c b/test/test_pointops.c index 8f302a2..7d36a00 100644 --- a/test/test_pointops.c +++ b/test/test_pointops.c @@ -363,9 +363,27 @@ int test_decaf_evil (void) { mask_t succ_dec = decaf_decode(pt_dec2, ser_de, -1); field_serialize(ser_ed, out_ed); - decaf_point_t p; + decaf_point_t p,q,m; + uint8_t oo_base_ser[56], n_base_ser[56]; + field_a_t oo_base,tmp,tmp2; + field_isr(tmp,base); + field_sqr(tmp2,tmp); // 1/+-s_base + field_sqr(tmp,tmp2); // = 1/s_base^2 + field_mul(oo_base,tmp,base); // = 1/s_base + field_serialize(oo_base_ser,oo_base); + field_neg(tmp,base); + field_serialize(n_base_ser,tmp); // = -base decaf_nonuniform_map_to_curve (p,random_input); + decaf_nonuniform_map_to_curve (q,oo_base_ser); + decaf_nonuniform_map_to_curve (m,n_base_ser); mask_t succ_nur = decaf_valid(p); + succ_nur &= decaf_valid(q); + succ_nur &= decaf_valid(m); + + mask_t eq_neg, eq_pos; + eq_neg = decaf_eq(m,p); + decaf_add(m,p,q); + eq_pos = decaf_eq(m,decaf_identity); if ((care_should && should != s_m) || ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te @@ -375,7 +393,9 @@ int test_decaf_evil (void) { || (s_e & ~succ_dec) || (s_e & ~decaf_eq(pt_dec, pt_dec2) || (s_e & ~decaf_valid(pt_dec)) - || ~succ_nur) + || ~succ_nur + || ~eq_neg + || ~eq_pos) ) { youfail(); field_print(" base", base); @@ -383,9 +403,9 @@ int test_decaf_evil (void) { field_print(" oute", out_e); field_print(" outE", out_ed); field_print(" outm", out_m); - printf(" succ: m=%d, e=%d, t=%d, b=%d, T=%d, D=%d, nur=%d, should=%d[%d]\n", + printf(" succ: m=%d, e=%d, t=%d, b=%d, T=%d, D=%d, nur=%d, e+=%d, e-=%d, should=%d[%d]\n", -(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)s_ed,-(int)succ_dec, - -(int)succ_nur, + -(int)succ_nur, -(int)eq_neg, -(int)eq_pos, -(int)should,-(int)care_should ); ret = -1;