@@ -24,6 +24,8 @@ | |||||
typedef uint64_t decaf_word_t, decaf_bool_t; | 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 */ | /* TODO: perfield, so when 25519 hits this will change */ | ||||
#define DECAF_FIELD_BITS 448 | #define DECAF_FIELD_BITS 448 | ||||
#define DECAF_LIMBS (512/8/sizeof(decaf_word_t)) | #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. | * A factor of 2 because we quotient out the 2-torsion. | ||||
* // TODO: check that it isn't more, especially for the identity point. | * // 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. | * This function isn't quite indifferentiable from a random oracle. | ||||
* However, it is suitable for many protocols, including SPEKE and SPAKE2 EE. | * However, it is suitable for many protocols, including SPEKE and SPAKE2 EE. | ||||
* Furthermore, calling it twice with independent seeds and adding the results | * Furthermore, calling it twice with independent seeds and adding the results | ||||
@@ -397,10 +397,10 @@ void decaf_nonuniform_map_to_curve ( | |||||
mask_t square = gf_eq(e,ONE); | mask_t square = gf_eq(e,ONE); | ||||
gf_mul(a,b,r); | gf_mul(a,b,r); | ||||
cond_sel(b,a,b,square); | cond_sel(b,a,b,square); | ||||
cond_neg(b,hibit(b)); | |||||
gf_mlw(a,b,EDWARDS_D+1); | gf_mlw(a,b,EDWARDS_D+1); | ||||
cond_swap(ur2_d,udr2_1,~square); | cond_swap(ur2_d,udr2_1,~square); | ||||
gf_mul(e,ur2_d,a); | gf_mul(e,ur2_d,a); | ||||
cond_neg(e,hibit(e)^square); | |||||
gf_mul(b,udr2_1,a); | gf_mul(b,udr2_1,a); | ||||
gf_sqr(c,b); | gf_sqr(c,b); | ||||
gf_sqr(a,e); | gf_sqr(a,e); | ||||
@@ -414,7 +414,6 @@ void decaf_nonuniform_map_to_curve ( | |||||
gf_mul(p->t,b,e); | gf_mul(p->t,b,e); | ||||
} | } | ||||
void decaf_uniform_map_to_curve ( | void decaf_uniform_map_to_curve ( | ||||
decaf_point_t pt, | decaf_point_t pt, | ||||
const unsigned char hashed_data[2*DECAF_SER_BYTES] | const unsigned char hashed_data[2*DECAF_SER_BYTES] | ||||
@@ -363,9 +363,27 @@ int test_decaf_evil (void) { | |||||
mask_t succ_dec = decaf_decode(pt_dec2, ser_de, -1); | mask_t succ_dec = decaf_decode(pt_dec2, ser_de, -1); | ||||
field_serialize(ser_ed, out_ed); | 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 (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); | 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) | if ((care_should && should != s_m) | ||||
|| ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te | || ~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 & ~succ_dec) | ||||
|| (s_e & ~decaf_eq(pt_dec, pt_dec2) | || (s_e & ~decaf_eq(pt_dec, pt_dec2) | ||||
|| (s_e & ~decaf_valid(pt_dec)) | || (s_e & ~decaf_valid(pt_dec)) | ||||
|| ~succ_nur) | |||||
|| ~succ_nur | |||||
|| ~eq_neg | |||||
|| ~eq_pos) | |||||
) { | ) { | ||||
youfail(); | youfail(); | ||||
field_print(" base", base); | field_print(" base", base); | ||||
@@ -383,9 +403,9 @@ int test_decaf_evil (void) { | |||||
field_print(" oute", out_e); | field_print(" oute", out_e); | ||||
field_print(" outE", out_ed); | field_print(" outE", out_ed); | ||||
field_print(" outm", out_m); | 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)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 | -(int)should,-(int)care_should | ||||
); | ); | ||||
ret = -1; | ret = -1; | ||||