#include "field.h" #include "test.h" #include #include #include mpz_t mp_field; static mask_t mpz_to_field ( struct field_t *out, const mpz_t in ) { uint8_t ser[FIELD_BYTES]; mpz_t modded; memset(ser,0,sizeof(ser)); mpz_init(modded); mpz_mod(modded, in, mp_field); mpz_export(ser, NULL, -1, 1, -1, 0, modded); mask_t succ = field_deserialize(out, ser); return succ; } static mask_t field_assert_eq_gmp( const char *descr, const struct field_t *a, const struct field_t *b, const struct field_t *x, const mpz_t y, float lowBound, float highBound ) { uint8_t xser[FIELD_BYTES], yser[FIELD_BYTES]; mpz_t modded; memset(yser,0,sizeof(yser)); field_serialize(xser, x); mpz_init(modded); mpz_mod(modded, y, mp_field); mpz_export(yser, NULL, -1, 1, -1, 0, modded); unsigned int i; for (i=0; ilimb[0]); i++) { int radix_bits = 1 + (sizeof(x->limb[0]) * FIELD_BITS - 1) / sizeof(*x); word_t yardstick = (i==sizeof(*x)/sizeof(x->limb[0])/2) ? (1ull<limb[i] < yardstick * lowBound || x->limb[i] > yardstick * highBound) { youfail(); printf(" Limb %d -> " PRIxWORDfull " is out of bounds (%0.2f, %0.2f) for test %s (yardstick = " PRIxWORDfull ")\n", i, x->limb[i], lowBound, highBound, descr, yardstick); break; } } if (memcmp(xser,yser,FIELD_BYTES)) { youfail(); printf(" Failed arithmetic test %s\n", descr); field_print(" a", a); field_print(" b", b); field_print(" goldi", x); printf(" gmp = 0x"); int j; for (j=FIELD_BYTES-1; j>=0; j--) { printf("%02x", yser[j]); } printf("\n"); return MASK_FAILURE; } mpz_clear(modded); return MASK_SUCCESS; } static mask_t test_add_sub ( const mpz_t x, const mpz_t y, word_t word ) { struct field_t xx,yy,tt; mpz_t t; mask_t succ = MASK_SUCCESS; succ = mpz_to_field(&xx,x); succ &= mpz_to_field(&yy,y); mpz_init(t); field_add(&tt,&xx,&yy); mpz_add(t,x,y); succ &= field_assert_eq_gmp("add",&xx,&yy,&tt,t,0,2.1); field_sub(&tt,&xx,&yy); field_bias(&tt,2); mpz_sub(t,x,y); succ &= field_assert_eq_gmp("sub",&xx,&yy,&tt,t,0,3.1); field_copy(&tt,&xx); field_addw(&tt,word); mpz_add_ui(t,x,word); succ &= field_assert_eq_gmp("addw",&xx,&yy,&tt,t,0,2.1); field_copy(&tt,&xx); field_subw(&tt,word); field_bias(&tt,1); mpz_sub_ui(t,x,word); succ &= field_assert_eq_gmp("subw",&xx,&yy,&tt,t,0,2.1); /* if (!succ) { field_print(" x", &xx); field_print(" y", &yy); } */ mpz_clear(t); return succ; } static mask_t test_mul_sqr ( const mpz_t x, const mpz_t y, word_t word ) { struct field_t xx,yy,tt; mpz_t t; mask_t succ = MASK_SUCCESS; succ = mpz_to_field(&xx,x); succ &= mpz_to_field(&yy,y); mpz_init(t); field_mul(&tt,&xx,&yy); mpz_mul(t,x,y); succ &= field_assert_eq_gmp("mul",&xx,&yy,&tt,t,0,1.1); field_mulw(&tt,&xx,word); mpz_mul_ui(t,x,word); succ &= field_assert_eq_gmp("mulw",&xx,&yy,&tt,t,0,1.1); field_sqr(&tt,&xx); mpz_mul(t,x,x); succ &= field_assert_eq_gmp("sqrx",&xx,&yy,&tt,t,0,1.1); field_sqr(&tt,&yy); mpz_mul(t,y,y); succ &= field_assert_eq_gmp("sqy",&xx,&yy,&tt,t,0,1.1); if (!succ) { field_print(" x", &xx); field_print(" y", &yy); } mpz_clear(t); return succ; } static mask_t test_isr ( const mpz_t x ) { struct field_t xx,yy,ss,tt; mask_t succ = 0; succ = mpz_to_field(&xx,x); field_isr(&ss,&xx); field_sqr(&tt,&ss); field_mul(&yy,&xx,&tt); field_addw(&tt,1); succ |= field_is_zero(&tt); field_subw(&tt,2); field_bias(&tt,1); succ |= field_is_zero(&tt); field_addw(&tt,1); if (~succ) { youfail(); printf("ISR failure.\n"); field_print(" x", &xx); field_print(" s", &ss); field_print(" t", &tt); } return succ; } void dbg_gmp_printf(const mpz_t x); void dbg_gmp_printf(const mpz_t x) { gmp_printf("DEBUG: 0x%Zx\n", x); } int test_arithmetic (void) { int j, ntests = 100000; gmp_randstate_t state; gmp_randinit_mt(state); mpz_init(mp_field); mpz_import(mp_field, FIELD_BYTES, -1, 1, -1, 0, FIELD_MODULUS); mpz_t x,y; mpz_init(x); mpz_init(y); mask_t succ = MASK_SUCCESS; int radix_bits = sizeof(word_t) * FIELD_BITS / sizeof(field_t); for (j=0; j