@@ -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 | ||||
@@ -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, | ||||
@@ -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. | ||||
@@ -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, | ||||
@@ -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); | ||||
@@ -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)) { | ||||
@@ -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); | ||||