Browse Source

decaf in and working for untwisted curve

master
Michael Hamburg 10 years ago
parent
commit
a9e16440a2
5 changed files with 115 additions and 23 deletions
  1. +27
    -23
      src/ec_point.c
  2. +15
    -0
      src/include/ec_point.h
  3. +3
    -0
      test/test.c
  4. +2
    -0
      test/test.h
  5. +68
    -0
      test/test_pointops.c

+ 27
- 23
src/ec_point.c View File

@@ -457,26 +457,30 @@ decaf_serialize_extensible (
) {
/* FIXME: IF32...? */
struct field_t L0, L1, L2, L3;
field_mulw_scc ( &L2, &a->y, EDWARDS_D );
field_mul ( &L3, &L2, &a->t );
field_mul ( &L2, &L3, &a->u );
field_mul ( &L0, &a->x, &a->z );
field_sub ( &L3, &L2, &L0 );
field_add ( &L0, &a->y, &a->z );
field_mulw_scc ( &L2, &a->y, EDWARDS_D ); // L2 = d*y
field_mul ( &L3, &L2, &a->t ); // L3 = d*y*t_
field_mul ( &L2, &L3, &a->u ); // L2 = d*y*t
field_mul ( &L0, &a->x, &a->z ); // L0 = x*z
field_sub ( &L3, &L2, &L0 );
field_bias ( &L3, 2 );
IF32( field_weak_reduce( &L3 ) ); // L3 = d*y*t - x*z
field_add ( &L0, &a->y, &a->z ); // L0 = y+z
field_sub ( &L1, &a->y, &a->z );
field_bias ( &L1, 2 );
field_mul ( &L2, &L1, &L0 );
field_isr ( &L2, &L2 );
field_sqr ( &L1, &L2 );
field_mul ( &L0, &L1, &L3 );
field_mul ( &L1, &L2, &sqrt_d_minus_1 );
field_add ( &L3, &L1, &L1 );
field_neg ( &L3, &L3 );
IF32( field_weak_reduce( &L1 ) ); // L1 = y-z
field_mul ( &L2, &L1, &L0 ); // L2 = y^2-z^2
field_isr ( &L2, &L2 ); // L2 = 1/sqrt(y^2-z^2)
field_sqr ( &L1, &L2 ); // L1 = 1/(y^2-z^2)
field_mul ( &L0, &L1, &L3 ); // L0 = (d*y*t - z*x)/(y^2-z^2) = 1/x
field_mul ( &L1, &L2, &sqrt_d_minus_1 ); // L1 = sy
field_add ( &L3, &L1, &L1 ); // L3 = 2*sy
field_neg ( &L3, &L3 );
field_bias ( &L3, 2 );
field_mul ( &L3, &L0, &a->z );
field_cond_neg ( &L1, field_low_bit(&L3) );
field_mul ( &L2, &L1, &a->y );
field_add ( b, &L2, &L3 );
IF32( field_weak_reduce( &L3 ) ); // L3 = -2*sy
field_mul ( &L2, &L3, &a->z ); // L2 = -2*sy*z
field_cond_neg ( &L1, field_low_bit(&L2) ); // cond-neg sy
field_mul ( &L2, &L1, &a->y ); // L2 = 2*sy*y
field_add ( b, &L0, &L2 );
decaf_make_even ( b );
}

@@ -492,7 +496,7 @@ decaf_deserialize_affine (
succ = allow_identity | ~zero;
succ &= ~field_low_bit(s);
field_sqr ( &L0, s );
field_copy ( &L1, &L1 );
field_copy ( &L1, &L0 );
field_addw ( &L1, 1 );
field_make_nonzero ( &L1 );
field_sqr ( &L2, &L1 );
@@ -502,19 +506,19 @@ decaf_deserialize_affine (
field_mul ( &L2, &L4, &L0 );
field_isr ( &L4, &L2 );
field_sqr ( &L5, &L4 );
field_mul ( &L4, &L5, &L2 );
field_addw( &L4, 1 );
succ &= ~field_is_zero( &L4 );
field_mul ( &L0, &L5, &L2 );
field_addw( &L0, 1 );
succ &= ~field_is_zero( &L0 );
field_mul ( &L2, &L3, &L1 );
field_mul ( &L3, &L2, &L4 );
field_cond_neg ( &L4, field_low_bit(&L3) );
field_mul ( &L3, &L4, s );
field_sqr ( &L4, &L3 );
field_mul ( &L0, &L1, &L4 );
field_mul ( &L0, &L2, &L4 );
field_add ( &L0, &L0, &L0 );
field_mul ( &a->x, &L0, s );
field_mul ( &L2, &L1, &L3 );
field_neg ( &L1, &L1 );
field_neg ( &L1, &L1 );
field_bias ( &L1, 2 );
field_addw ( &L1, 2 );
field_mul ( &a->y, &L1, &L2 );


+ 15
- 0
src/include/ec_point.h View File

@@ -379,6 +379,21 @@ deserialize_and_twist_approx (
struct tw_extensible_t* a,
const struct field_t* sdm1,
const struct field_t* sz
)
__attribute__((warn_unused_result));

mask_t
decaf_deserialize_affine (
struct affine_t *a,
const struct field_t *s,
mask_t allow_identity
)
__attribute__((warn_unused_result));
void
decaf_serialize_extensible (
struct field_t* b,
const struct extensible_t* a
);

void


+ 3
- 0
test/test.c View File

@@ -118,6 +118,9 @@ int main(int argc, char **argv) {

begin_test("EC point operations");
test_pointops();

begin_test("Decaf point encoding");
test_decaf();
begin_test("Scalarmul compatibility");
test_scalarmul_compatibility();


+ 2
- 0
test/test.h View File

@@ -45,4 +45,6 @@ int test_goldilocks (void);

int test_pointops (void);

int test_decaf (void);

#endif // __GOLDILOCKS_TEST_H__

+ 68
- 0
test/test_pointops.c View File

@@ -250,6 +250,74 @@ single_twisting_test (
return succ ? 0 : -1;
}

int test_decaf (void) {
struct affine_t base;
struct field_t serf;
struct crandom_state_t crand;
crandom_init_from_buffer(&crand, "my test_decaf random initializer");
int i, hits = 0, fails = 0;
for (i=0; i<1000; i++) {
uint8_t ser[FIELD_BYTES];
crandom_generate(&crand, ser, sizeof(ser));
#if (FIELD_BITS % 8)
ser[FIELD_BYTES-1] &= (1<<(FIELD_BITS%8)) - 1;
#endif
ser[0] &= ~1;

mask_t succ = field_deserialize(&serf, ser);
if (!succ) {
youfail();
printf(" Unlikely: fail at field_deserialize\n");
return -1;
}
succ &= decaf_deserialize_affine(&base, &serf, 0);
if (!succ) continue;
hits++;
struct field_t serf2;
struct extensible_t ext;
convert_affine_to_extensible(&ext, &base);
decaf_serialize_extensible(&serf2, &ext);
if (~validate_affine(&base)) {
youfail();
printf("Invalid decaf deser:\n");
field_print(" s", &serf);
field_print(" x", &base.x);
field_print(" y", &base.y);
fails ++;
} else if (~field_eq(&serf, &serf2)) {
youfail();
printf("Fail round-trip through decaf ser:\n");
field_print(" s", &serf);
field_print(" x", &base.x);
field_print(" y", &base.y);
printf(" deser is %s\n", validate_affine(&base) ? "valid" : "invalid");
field_print(" S", &serf2);
fails ++;
} else if (~is_even_pt(&ext)) {
youfail();
printf("Decaf deser isn't even:\n");
field_print(" s", &serf);
field_print(" x", &base.x);
field_print(" y", &base.y);
fails ++;
}
}
if (hits < 350) {
youfail();
printf(" Unlikely: only %d successes in decaf_deser\n", hits);
return -1;
} else if (fails) {
return -1;
} else {
return 0;
}
}

int test_pointops (void) {
struct affine_t base, pbase;
struct field_t serf;


Loading…
Cancel
Save