Browse Source

simple extended form is in. Probably simplify it more...

master
Mike Hamburg 10 years ago
parent
commit
e251453d15
7 changed files with 444 additions and 15 deletions
  1. +181
    -6
      src/ec_point.c
  2. +79
    -1
      src/include/ec_point.h
  3. +17
    -0
      src/include/scalarmul.h
  4. +70
    -0
      src/scalarmul.c
  5. +28
    -0
      test/bench.c
  6. +56
    -6
      test/test_pointops.c
  7. +13
    -2
      test/test_scalarmul.c

+ 181
- 6
src/ec_point.c View File

@@ -7,6 +7,11 @@
* @author Mike Hamburg * @author Mike Hamburg
* @warning This file was automatically generated. * @warning This file was automatically generated.
* Then it was edited by hand. Good luck, have fun. * Then it was edited by hand. Good luck, have fun.
*
* This file contains a huge number of different options for EC point arithmetic,
* but only a few of them will be used by any given library. They are here for
* reference and for consistency checks. The Goldilocks library link step strips
* out unused functions.
*/ */


#include "ec_point.h" #include "ec_point.h"
@@ -19,7 +24,7 @@ add_tw_niels_to_tw_extensible (
) { ) {
ANALYZE_THIS_ROUTINE_CAREFULLY; ANALYZE_THIS_ROUTINE_CAREFULLY;
field_a_t L0, L1; field_a_t L0, L1;
field_sub ( L1, d->y, d->x );
field_subx_nr ( L1, d->y, d->x );
field_mul ( L0, e->a, L1 ); field_mul ( L0, e->a, L1 );
field_add_nr ( L1, d->x, d->y ); field_add_nr ( L1, d->x, d->y );
field_mul ( d->y, e->b, L1 ); field_mul ( d->y, e->b, L1 );
@@ -34,6 +39,62 @@ add_tw_niels_to_tw_extensible (
field_mul ( d->y, L0, d->u ); field_mul ( d->y, L0, d->u );
} }


void
add_tw_extended (
tw_extended_a_t d,
const tw_extended_a_t e
) {
ANALYZE_THIS_ROUTINE_CAREFULLY;
field_a_t L0, L1, L2;
field_subx_nr ( L1, d->y, d->x );
field_subx_nr ( L2, e->y, e->x );
field_mul ( L0, L2, L1 );
field_add_nr ( L1, d->y, d->x );
field_add_nr ( L2, e->y, e->x );
field_mul ( d->y, L2, L1 );
field_mul ( L1, e->t, d->t );
field_mulw_scc_wr ( d->x, L1, 2-2*EDWARDS_D );
field_add_nr ( L1, L0, d->y );
field_subx_nr ( L2, d->y, L0 );
field_mul ( L0, d->z, e->z );
field_add_nr ( L0, L0, L0 );
field_add_nr ( d->y, L0, d->x );
field_subx_nr ( L0, L0, d->x );
field_mul ( d->z, L0, d->y );
field_mul ( d->x, d->y, L2 );
field_mul ( d->y, L0, L1 );
field_mul ( d->t, L1, L2 );
}

void
add_sub_tw_extended (
tw_extended_a_t d,
const tw_extended_a_t e,
mask_t sub
) {
field_a_t L0, L1, L2, L3;
field_sub ( L1, d->y, d->x );
field_sub ( L2, e->y, e->x );
field_add ( L3, e->y, e->x );
constant_time_cond_swap(L2,L3,sizeof(L2),sub);
field_mul ( L0, L2, L1 );
field_add ( L1, d->y, d->x );
field_mul ( d->y, L3, L1 );
field_mul ( L1, e->t, d->t );
field_mulw_scc_wr ( d->x, L1, 2-2*EDWARDS_D );
field_add ( L1, L0, d->y );
field_sub ( L2, d->y, L0 );
field_mul ( L0, d->z, e->z );
field_add ( L0, L0, L0 );
field_add ( d->y, L0, d->x );
field_sub ( L0, L0, d->x );
constant_time_cond_swap(L0,d->y,sizeof(L0),sub);
field_mul ( d->z, L0, d->y );
field_mul ( d->x, d->y, L2 );
field_mul ( d->y, L0, L1 );
field_mul ( d->t, L1, L2 );
}

void void
sub_tw_niels_from_tw_extensible ( sub_tw_niels_from_tw_extensible (
tw_extensible_a_t d, tw_extensible_a_t d,
@@ -194,6 +255,17 @@ convert_tw_affine_to_tw_extensible (
field_copy ( b->u, a->y ); field_copy ( b->u, a->y );
} }


void
convert_tw_extensible_to_tw_extended (
tw_extended_a_t b,
const tw_extensible_a_t a
) {
field_copy ( b->x, a->x );
field_copy ( b->y, a->y );
field_copy ( b->z, a->z );
field_mul ( b->t, a->t, a->u );
}

void void
convert_affine_to_extensible ( convert_affine_to_extensible (
extensible_a_t b, extensible_a_t b,
@@ -523,6 +595,90 @@ decaf_serialize_tw_extensible (
decaf_abs ( b ); decaf_abs ( b );
} }


void
decaf_serialize_tw_extended (
field_a_t b,
const tw_extended_a_t a
) {
field_a_t L0, L1, L2, L3;
field_mulw_scc ( L0, a->y, 1-EDWARDS_D );
field_mul ( L2, L0, a->t );
field_mul ( L0, a->x, a->z );
field_sub ( L3, L2, L0 );
field_add ( L0, a->z, a->y );
field_sub ( L1, a->z, a->y );
field_mul ( L2, L1, L0 );
field_mulw_scc ( L1, L2, -EDWARDS_D );
field_isr ( L0, L1 );
field_mulw_scc ( L1, L0, -EDWARDS_D );
field_mul ( L2, L1, L0 );
field_mul ( L0, L2, L3 );
field_add ( L3, L1, L1 );
field_mul ( L2, L3, a->z );
field_cond_neg ( L1, ~field_high_bit(L2) );
field_mul ( L2, L1, a->y );
field_add ( b, L0, L2 );
decaf_abs ( b );
}

/*
static void
tw_extended_efgh (
tw_extended_a_t a,
field_a_t x,
field_a_t xz,
field_a_t y,
field_a_t yz
) {
field_mul(a->x,x,yz);
field_mul(a->y,y,xz);
field_mul(a->z,xz,yz);
field_mul(a->t,x,y);
}
*/

mask_t
decaf_deserialize_tw_extended (
tw_extended_a_t a,
const field_a_t s,
mask_t allow_identity
) {
field_a_t L0, L1, L2, L3, L4;
mask_t succ, zero;
zero = field_is_zero(s);
succ = allow_identity | ~zero;
succ &= ~field_high_bit(s);

field_sqr ( L0, s ); // L0 = s^2
field_neg ( a->z, L0 );
field_addw ( a->z, 1 );
field_sqr ( L1, a->z );
field_mulw_scc_wr ( L2, L0, 4-4*EDWARDS_D );
field_add ( L2, L2, L1 ); // L2 = [t^2]
field_mul ( L1, L2, L0 ); // L1 = [t^2] s^2

field_isr ( L3, L1 ); // L3 =? 1/ts; check it
field_sqr ( L4, L3 );
field_mul ( L0, L4, L1 );
field_addw( L0, 1 );
succ &= ~field_is_zero( L0 );

field_mul ( L1, L2, L3 ); // L1 = t^2 * 1/ts = t/s
field_cond_neg ( L3, field_high_bit(L1) ); // negate 1/ts?

field_add( a->x, s, s );
field_mul ( L2, L3, s );

field_neg ( L1, a->z );
field_addw ( L1, 2 );
field_mul ( L0, L1, L2 );
field_mul(a->y,L0,a->z);
field_mul(a->t,a->x,L0);
field_addw ( a->y, -zero );

return succ;
}

mask_t mask_t
decaf_deserialize_affine ( decaf_deserialize_affine (
affine_a_t a, affine_a_t a,
@@ -803,6 +959,16 @@ set_identity_extensible (
field_set_ui( a->u, 0 ); field_set_ui( a->u, 0 );
} }


void
set_identity_tw_extended (
tw_extended_a_t a
) {
field_set_ui( a->x, 0 );
field_set_ui( a->y, 1 );
field_set_ui( a->z, 1 );
field_set_ui( a->t, 0 );
}

void void
set_identity_tw_extensible ( set_identity_tw_extensible (
tw_extensible_a_t a tw_extensible_a_t a
@@ -827,12 +993,21 @@ decaf_eq_extensible (
const struct extensible_t* a, const struct extensible_t* a,
const struct extensible_t* b const struct extensible_t* b
) { ) {
field_a_t L0, L1, L2;
field_mul ( L2, b->y, a->x );
field_a_t L0, L1;
field_mul ( L0, b->y, a->x );
field_mul ( L1, a->y, b->x ); field_mul ( L1, a->y, b->x );
field_sub ( L0, L2, L1 );
field_bias ( L0, 2 );
return field_is_zero ( L0 );
return field_eq(L0,L1);
}

mask_t
decaf_eq_tw_extended (
const tw_extended_a_t a,
const tw_extended_a_t b
) {
field_a_t L0, L1;
field_mul ( L0, b->y, a->x );
field_mul ( L1, a->y, b->x );
return field_eq(L0,L1);
} }


mask_t mask_t


+ 79
- 1
src/include/ec_point.h View File

@@ -4,7 +4,11 @@
* Copyright (c) 2014 Cryptography Research, Inc. \n * Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information. * Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg * @author Mike Hamburg
* @warning This file was automatically generated.
*
* This file contains a huge number of different options for EC point arithmetic,
* but only a few of them will be used by any given library. They are here for
* reference and for consistency checks. The Goldilocks library link step strips
* out unused functions.
*/ */


#ifndef __CC_INCLUDED_EC_POINT_H__ #ifndef __CC_INCLUDED_EC_POINT_H__
@@ -75,6 +79,14 @@ typedef struct tw_extensible_t {
field_a_t x, y, z, t, u; field_a_t x, y, z, t, u;
} tw_extensible_a_t[1]; } tw_extensible_a_t[1];


/**
* Extended coordinates for twisted Edwards curves.
* Jack of all trades, master of none.
*/
typedef struct tw_extended_t {
field_a_t x, y, z, t;
} tw_extended_a_t[1];

/** /**
* Niels coordinates for twisted Edwards curves. * Niels coordinates for twisted Edwards curves.
* *
@@ -140,6 +152,15 @@ copy_tw_extensible (
const tw_extensible_a_t ds const tw_extensible_a_t ds
) __attribute__((unused,always_inline)); ) __attribute__((unused,always_inline));


/**
* Auto-generated copy method.
*/
static __inline__ void
copy_tw_extended (
tw_extended_a_t a,
const tw_extended_a_t ds
) __attribute__((unused,always_inline));

/** /**
* Auto-generated copy method. * Auto-generated copy method.
*/ */
@@ -272,6 +293,25 @@ convert_tw_niels_to_tw_extensible (
const tw_niels_a_t d const tw_niels_a_t d
); );


void
convert_tw_extensible_to_tw_extended (
tw_extended_a_t b,
const tw_extensible_a_t a
);

void
add_tw_extended (
tw_extended_a_t d,
const tw_extended_a_t e
);

void
add_sub_tw_extended (
tw_extended_a_t d,
const tw_extended_a_t e,
mask_t sub
);

void void
montgomery_step ( montgomery_step (
montgomery_a_t a montgomery_a_t a
@@ -435,6 +475,21 @@ decaf_serialize_tw_extensible (
const tw_extensible_a_t a const tw_extensible_a_t a
); );



mask_t
decaf_deserialize_tw_extended (
tw_extended_a_t a,
const field_a_t s,
mask_t allow_identity
)
__attribute__((warn_unused_result));

void
decaf_serialize_tw_extended (
field_a_t b,
const tw_extended_a_t a
);

void void
set_identity_extensible ( set_identity_extensible (
extensible_a_t a extensible_a_t a
@@ -445,6 +500,11 @@ set_identity_tw_extensible (
tw_extensible_a_t a tw_extensible_a_t a
); );


void
set_identity_tw_extended (
tw_extended_a_t a
);

void void
set_identity_affine ( set_identity_affine (
affine_a_t a affine_a_t a
@@ -486,6 +546,13 @@ decaf_eq_tw_extensible (
) )
__attribute__((warn_unused_result)); __attribute__((warn_unused_result));


mask_t
decaf_eq_tw_extended (
const tw_extended_a_t a,
const tw_extended_a_t b
)
__attribute__((warn_unused_result));

mask_t mask_t
decaf_eq_extensible ( decaf_eq_extensible (
const extensible_a_t a, const extensible_a_t a,
@@ -592,6 +659,17 @@ copy_tw_extensible (
field_copy ( a->u, ds->u ); field_copy ( a->u, ds->u );
} }


void
copy_tw_extended (
tw_extended_a_t a,
const tw_extended_a_t ds
) {
field_copy ( a->x, ds->x );
field_copy ( a->y, ds->y );
field_copy ( a->z, ds->z );
field_copy ( a->t, ds->t );
}

void void
copy_tw_niels ( copy_tw_niels (
tw_niels_a_t a, tw_niels_a_t a,


+ 17
- 0
src/include/scalarmul.h View File

@@ -145,6 +145,23 @@ scalarmul (
/* TODO? int nbits */ /* TODO? int nbits */
); );
/**
* Scalar multiply a twisted Edwards-form point, simply, in extended coordinates.
*
* This function takes constant time.
*
* Currently the scalar is always exactly 448 bits long.
*
* @param [inout] working The point to multply.
* @param [in] scalar The scalar, in little-endian form.
*/
void
scalarmul_ed (
tw_extended_a_t working,
const word_t scalar[SCALAR_WORDS]
/* TODO? int nbits */
);
/** /**
* Scalar multiply a twisted Edwards-form point. Use the same * Scalar multiply a twisted Edwards-form point. Use the same
* algorithm as scalarmul(), but uses variable array indices. * algorithm as scalarmul(), but uses variable array indices.


+ 70
- 0
src/scalarmul.c View File

@@ -88,6 +88,17 @@ constant_time_lookup_tw_pniels (
constant_time_lookup(out,in,sizeof(*out),nin,idx); constant_time_lookup(out,in,sizeof(*out),nin,idx);
} }


static __inline__ void
__attribute__((unused,always_inline))
constant_time_lookup_tw_extended (
tw_extended_a_t out,
const tw_extended_a_t *in,
int nin,
int idx
) {
constant_time_lookup(out,in,sizeof(*out),nin,idx);
}

static __inline__ void static __inline__ void
__attribute__((unused,always_inline)) __attribute__((unused,always_inline))
constant_time_lookup_tw_niels ( constant_time_lookup_tw_niels (
@@ -189,6 +200,65 @@ scalarmul (
} }
} }


void
scalarmul_ed (
tw_extended_a_t working,
const word_t scalar[SCALAR_WORDS]
) {
const int WINDOW = SCALARMUL_FIXED_WINDOW_SIZE,
WINDOW_MASK = (1<<WINDOW)-1, WINDOW_T_MASK = WINDOW_MASK >> 1,
NTABLE = 1<<(WINDOW-1),
nbits = ROUND_UP(SCALAR_BITS,WINDOW);
word_t scalar2[SCALAR_WORDS];
convert_to_signed_window_form (
scalar2, scalar, SCALAR_WORDS,
SCALARMUL_FIXED_WINDOW_ADJUSTMENT, SCALAR_WORDS
);

tw_extended_a_t
tmp VECTOR_ALIGNED,
multiples[NTABLE] VECTOR_ALIGNED;

copy_tw_extended(tmp, working);
add_tw_extended(tmp, tmp);
copy_tw_extended(multiples[0], working);

int i,j;
for (i=1; i<NTABLE; i++) {
add_tw_extended(working, tmp);
copy_tw_extended(multiples[i], working);
}

i = nbits - WINDOW;
int bits = scalar2[i/WORD_BITS] >> (i%WORD_BITS) & WINDOW_MASK,
inv = (bits>>(WINDOW-1))-1;
bits ^= inv;
set_identity_tw_extended(working);

for (; i>=0; i-=WINDOW) {
if (i != nbits-WINDOW) {
for (j=0; j<WINDOW; j++) {
add_tw_extended(working,working);
}
}

bits = scalar2[i/WORD_BITS] >> (i%WORD_BITS);
if (i/WORD_BITS < SCALAR_WORDS-1 && i%WORD_BITS >= WORD_BITS-WINDOW) {
bits ^= scalar2[i/WORD_BITS+1] << (WORD_BITS - (i%WORD_BITS));
}
bits &= WINDOW_MASK;
inv = (bits>>(WINDOW-1))-1;
bits ^= inv;
constant_time_lookup_tw_extended(tmp, (const tw_extended_a_t*)multiples, NTABLE, bits & WINDOW_T_MASK);
add_sub_tw_extended(working, tmp, inv);
}
}

void void
scalarmul_vlook ( scalarmul_vlook (
tw_extensible_a_t working, tw_extensible_a_t working,


+ 28
- 0
test/bench.c View File

@@ -267,12 +267,23 @@ int main(int argc, char **argv) {
memset(&ext,0,sizeof(ext)); memset(&ext,0,sizeof(ext));
memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */ memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */

tw_extended_a_t ed;
convert_tw_extensible_to_tw_extended(ed,&ext);

when = now(); when = now();
for (i=0; i<nbase*100; i++) { for (i=0; i<nbase*100; i++) {
add_tw_niels_to_tw_extensible(&ext, &niels); add_tw_niels_to_tw_extensible(&ext, &niels);
} }
when = now() - when; when = now() - when;
printf("exti+niels: %5.1fns\n", when * 1e9 / i); printf("exti+niels: %5.1fns\n", when * 1e9 / i);

when = now();
for (i=0; i<nbase*100; i++) {
add_tw_extended(ed,ed);
}
when = now() - when;
printf("txt + txt : %5.1fns\n", when * 1e9 / i);
convert_tw_extensible_to_tw_pniels(&pniels, &ext); convert_tw_extensible_to_tw_pniels(&pniels, &ext);
when = now(); when = now();
@@ -347,6 +358,23 @@ int main(int argc, char **argv) {
when = now() - when; when = now() - when;
printf("edwards svl: %5.1fµs\n", when * 1e6 / i); printf("edwards svl: %5.1fµs\n", when * 1e6 / i);
when = now();
for (i=0; i<nbase/10; i++) {
scalarmul_ed(ed,sk);
}
when = now() - when;
printf("edwards txt: %5.1fµs\n", when * 1e6 / i);
field_set_ui(a,0);
when = now();
for (i=0; i<nbase/10; i++) {
ignore_result(decaf_deserialize_tw_extended(ed,a,-1));
scalarmul_ed(ed,sk);
decaf_serialize_tw_extended(a,ed);
}
when = now() - when;
printf("simple ECDH: %5.1fµs\n", when * 1e6 / i);
when = now(); when = now();
for (i=0; i<nbase/10; i++) { for (i=0; i<nbase/10; i++) {
scalarmul(&ext,sk); scalarmul(&ext,sk);


+ 56
- 6
test/test_pointops.c View File

@@ -134,6 +134,7 @@ add_double_test (
mask_t succ = MASK_SUCCESS; mask_t succ = MASK_SUCCESS;
struct extensible_t exb; struct extensible_t exb;
struct tw_extensible_t text1, text2, texta, textb; struct tw_extensible_t text1, text2, texta, textb;
struct tw_extended_t ted1, ted2;
struct tw_pniels_t pn; struct tw_pniels_t pn;
/* Convert to ext */ /* Convert to ext */
@@ -154,6 +155,25 @@ add_double_test (
convert_tw_extensible_to_tw_pniels(&pn, &text2); convert_tw_extensible_to_tw_pniels(&pn, &text2);
copy_tw_extensible(&textb, &text1); copy_tw_extensible(&textb, &text1);
add_tw_pniels_to_tw_extensible(&textb, &pn); add_tw_pniels_to_tw_extensible(&textb, &pn);

convert_tw_extensible_to_tw_extended(&ted1, &text1);
convert_tw_extensible_to_tw_extended(&ted2, &text2);
add_tw_extended(&ted1, &ted2);
convert_tw_extensible_to_tw_extended(&ted2, &textb);
if (~decaf_eq_tw_extended(&ted1, &ted2)) {
youfail();
succ = 0;
printf(" Tw extended simple compat:\n");
field_print(" x1",ted1.x);
field_print(" y1",ted1.y);
field_print(" z1",ted1.z);
field_print(" t1",ted1.t);
field_print(" x2",ted2.x);
field_print(" y2",ted2.y);
field_print(" z2",ted2.z);
field_print(" t2",ted2.t);
}
succ &= fail_if_different_tw(&texta,&textb,"Addition commutativity","a+b","b+a"); succ &= fail_if_different_tw(&texta,&textb,"Addition commutativity","a+b","b+a");
@@ -161,7 +181,7 @@ add_double_test (
add_tw_pniels_to_tw_extensible(&textb, &pn); add_tw_pniels_to_tw_extensible(&textb, &pn);
copy_tw_extensible(&texta, &text2); copy_tw_extensible(&texta, &text2);
double_tw_extensible(&texta); double_tw_extensible(&texta);
succ &= fail_if_different_tw(&texta,&textb,"Doubling test","2b","b+b"); succ &= fail_if_different_tw(&texta,&textb,"Doubling test","2b","b+b");
if (~succ) { if (~succ) {
@@ -307,31 +327,39 @@ int test_decaf_evil (void) {
random_input[55] &= 0x7F; random_input[55] &= 0x7F;
} }
field_a_t base, out_m, out_e;
field_a_t base, out_m, out_e, out_ed;
mask_t s_base = field_deserialize(base,random_input); mask_t s_base = field_deserialize(base,random_input);
affine_a_t pt_e; affine_a_t pt_e;
tw_affine_a_t pt_te; tw_affine_a_t pt_te;
tw_extended_a_t pt_ed;
// TODO: test don't allow identity // TODO: test don't allow identity
mask_t s_e = decaf_deserialize_affine(pt_e,base,-1); mask_t s_e = decaf_deserialize_affine(pt_e,base,-1);
mask_t s_te = decaf_deserialize_tw_affine(pt_te,base,-1); mask_t s_te = decaf_deserialize_tw_affine(pt_te,base,-1);
mask_t s_ed = decaf_deserialize_tw_extended(pt_ed,base,-1);
mask_t s_m = decaf_montgomery_ladder(out_m, base, random_scalar, 448); mask_t s_m = decaf_montgomery_ladder(out_m, base, random_scalar, 448);
tw_extensible_a_t work; tw_extensible_a_t work;
convert_tw_affine_to_tw_extensible(work,pt_te); convert_tw_affine_to_tw_extensible(work,pt_te);
scalarmul(work, random_scalar); scalarmul(work, random_scalar);
decaf_serialize_tw_extensible(out_e, work); decaf_serialize_tw_extensible(out_e, work);

scalarmul_ed(pt_ed, random_scalar);
decaf_serialize_tw_extended(out_ed, pt_ed);
if ((care_should && should != s_m) if ((care_should && should != s_m)
|| ~s_base || s_e != s_te || s_m != s_te || (s_te && ~field_eq(out_e,out_m))
|| ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te
|| (s_te && ~field_eq(out_e,out_m))
|| (s_ed && ~field_eq(out_e,out_ed))
) { ) {
youfail(); youfail();
field_print(" base", base); field_print(" base", base);
scalar_print(" scal", random_scalar, (448+WORD_BITS-1)/WORD_BITS); scalar_print(" scal", random_scalar, (448+WORD_BITS-1)/WORD_BITS);
field_print(" oute", out_e); field_print(" oute", out_e);
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, should=%d[%d]\n",
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)should,-(int)care_should
printf(" succ: m=%d, e=%d, t=%d, b=%d, T=%d, should=%d[%d]\n",
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)s_ed,-(int)should,-(int)care_should
); );
ret = -1; ret = -1;
fails++; fails++;
@@ -452,7 +480,29 @@ int test_decaf (void) {
field_print(" Y2", tw_ext2.y); field_print(" Y2", tw_ext2.y);
fails ++; fails ++;
} }

tw_extended_a_t ed;
succ = decaf_deserialize_tw_extended(ed, serf, 0);
decaf_serialize_tw_extended(serf2, ed);

if (~succ) {
youfail();
printf("Invalid decaf ed deser:\n");
field_print(" s", serf);
fails ++;
} else if (~field_eq(serf, serf2)) {
youfail();
printf("Fail round-trip through decaf ser:\n");
field_print(" s", serf);
field_print(" x", ed->x);
field_print(" y", ed->y);
field_print(" z", ed->z);
field_print(" t", ed->t);
printf(" tw deser is %s\n", validate_tw_extensible(&tw_ext) ? "valid" : "invalid");
field_print(" S", serf2);
fails ++;
}

word_t scalar = 1; word_t scalar = 1;
mask_t res = decaf_montgomery_ladder(serf2,serf,&scalar,1+(i%31)); mask_t res = decaf_montgomery_ladder(serf2,serf,&scalar,1+(i%31));
if (~res | ~field_eq(serf2,serf)) { if (~res | ~field_eq(serf2,serf)) {


+ 13
- 2
test/test_scalarmul.c View File

@@ -17,7 +17,7 @@ single_scalarmul_compatibility_test (
int nbits int nbits
) { ) {
struct tw_extensible_t text, work; struct tw_extensible_t text, work;
field_a_t mont, ct, vl, vt, decaf_s, decaf_m, decaf_te;
field_a_t mont, ct, vl, vt, sced, decaf_s, decaf_m, decaf_te;
int ret = 0, i; int ret = 0, i;
mask_t succ, succm; mask_t succ, succm;
@@ -110,11 +110,21 @@ single_scalarmul_compatibility_test (
scalarmul_vt(&work, scalar, nbits); scalarmul_vt(&work, scalar, nbits);
untwist_and_double_and_serialize(vt, &work); untwist_and_double_and_serialize(vt, &work);
tw_extended_a_t ed;
convert_tw_extensible_to_tw_extended(ed, &text);
scalarmul_ed(ed, scalar);
field_copy(work.x, ed->x);
field_copy(work.y, ed->y);
field_copy(work.z, ed->z);
field_copy(work.t, ed->t);
field_set_ui(work.u, 1);
untwist_and_double_and_serialize(sced, &work);

/* check consistency mont vs window */ /* check consistency mont vs window */
consistent &= field_eq(mont, ct); consistent &= field_eq(mont, ct);
consistent &= field_eq(mont, vl); consistent &= field_eq(mont, vl);
consistent &= field_eq(mont, vt); consistent &= field_eq(mont, vt);
consistent &= field_eq(mont, sced);
} }
/* check consistency mont vs combs */ /* check consistency mont vs combs */
@@ -163,6 +173,7 @@ single_scalarmul_compatibility_test (
field_print(" ct ", ct); field_print(" ct ", ct);
field_print(" vl ", vl); field_print(" vl ", vl);
field_print(" vt ", vt); field_print(" vt ", vt);
field_print(" ed ", sced);
} }
printf("decaf: succ = %d, %d\n", (int)succ_dm, (int)succ_dta); printf("decaf: succ = %d, %d\n", (int)succ_dm, (int)succ_dta);


Loading…
Cancel
Save