#include "test.h" #include #include "scalarmul.h" #include "ec_point.h" #include "field.h" #include "crandom.h" #define STRIDE 7 /* 0 = succeed, 1 = inval, -1 = fail */ static int single_scalarmul_compatibility_test ( const field_a_t base, const word_t *scalar, int nbits ) { struct tw_extensible_t text, work; field_a_t mont, ct, vl, vt; int ret = 0, i; mask_t succ, succm; succ = deserialize_and_twist_approx(&text, base); succm = montgomery_ladder(mont,base,scalar,nbits,1); if (succ != succm) { youfail(); printf(" Deserialize_and_twist_approx succ=%d, montgomery_ladder succ=%d\n", (int)-succ, (int)-succm); printf(" nbits = %d\n", nbits); field_print(" base", base); scalar_print(" scal", scalar, (nbits+WORD_BITS-1)/WORD_BITS); return -1; } if (!succ) { return 1; } #if FIELD_BITS == 448 struct { int n,t,s; } params[] = {{5,5,18},{3,5,30},{4,4,28},{1,2,224}}; #elif FIELD_BITS == 480 struct { int n,t,s; } params[] = {{5,6,16},{6,5,16},{4,5,24},{4,4,30},{1,2,240}}; #elif FIELD_BITS == 521 struct { int n,t,s; } params[] = {{5,8,13},{4,5,26},{1,2,(SCALAR_BITS+1)/2}}; #else struct { int n,t,s; } params[] = {{5,5,(SCALAR_BITS+24)/25},{1,2,(SCALAR_BITS+1)/2}}; #endif const int nparams = sizeof(params)/sizeof(params[0]); struct fixed_base_table_t fbt; const int nsizes = 6; field_a_t fbout[nparams], wout[nsizes]; memset(&fbt, 0, sizeof(fbt)); memset(&fbout, 0, sizeof(fbout)); memset(&wout, 0, sizeof(wout)); /* compute using combs */ for (i=0; i= FIELD_BYTES) { scalar[FIELD_BYTES-1] &= (1<<(FIELD_BITS%8)) - 1; } #endif } int test_scalarmul_commutativity (void) { int i,j,k,got; struct crandom_state_t crand; crandom_init_from_buffer(&crand, "scalarmul_commutativity_test RNG"); for (i=0; i<=FIELD_BITS; i+=STRIDE) { for (j=0; j<=FIELD_BITS; j+=STRIDE) { got = 0; for (k=0; k<128 && !got; k++) { uint8_t ser[FIELD_BYTES]; word_t scalar1[SCALAR_WORDS], scalar2[SCALAR_WORDS]; crandom_generate_f(&crand, ser, sizeof(ser)); crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1)); crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2)); field_t base; mask_t succ = field_deserialize(&base, ser); if (!succ) continue; int ret = single_scalarmul_commutativity_test (&base, scalar1, i, i%3, scalar2, j, j%3); got = !ret; if (ret == -1) return -1; } if (!got) { youfail(); printf(" Unlikely: rejected 128 scalars in a row.\n"); return -1; } } } return 0; } int test_linear_combo (void) { int i,j,k,got; struct crandom_state_t crand; crandom_init_from_buffer(&crand, "scalarmul_linear_combos_test RNG"); for (i=0; i<=FIELD_BITS; i+=STRIDE) { for (j=0; j<=FIELD_BITS; j+=STRIDE) { got = 0; for (k=0; k<128 && !got; k++) { uint8_t ser[FIELD_BYTES]; word_t scalar1[SCALAR_WORDS], scalar2[SCALAR_WORDS]; crandom_generate(&crand, (uint8_t *)scalar1, sizeof(scalar1)); crandom_generate(&crand, (uint8_t *)scalar2, sizeof(scalar2)); field_t base1; crandom_generate_f(&crand, ser, sizeof(ser)); mask_t succ = field_deserialize(&base1, ser); if (!succ) continue; field_t base2; crandom_generate(&crand, ser, sizeof(ser)); succ = field_deserialize(&base2, ser); if (!succ) continue; int ret = single_linear_combo_test (&base1, scalar1, i, &base2, scalar2, j); got = !ret; if (ret == -1) return -1; } if (!got) { youfail(); printf(" Unlikely: rejected 128 scalars in a row.\n"); return -1; } } } return 0; } int test_scalarmul_compatibility (void) { int i,j,k,got; struct crandom_state_t crand; crandom_init_from_buffer(&crand, "scalarmul_compatibility_test RNG"); for (i=0; i<=FIELD_BITS; i+=STRIDE) { for (j=0; j<=20; j++) { got = 0; for (k=0; k<128 && !got; k++) { uint8_t ser[FIELD_BYTES]; word_t scalar[SCALAR_WORDS]; crandom_generate_f(&crand, ser, sizeof(ser)); crandom_generate(&crand, (uint8_t *)scalar, sizeof(scalar)); field_t base; mask_t succ = field_deserialize(&base, ser); if (!succ) continue; int ret = single_scalarmul_compatibility_test (&base, scalar, i); got = !ret; if (ret == -1) return -1; } if (!got) { youfail(); printf(" Unlikely: rejected 128 scalars in a row.\n"); return -1; } } } return 0; }