static void table_init (const struct ecc_curve *ecc, mp_limb_t *table, unsigned bits, int initial, const mp_limb_t *p, mp_limb_t *scratch) { unsigned size = 1 << bits; unsigned j; mpn_zero (TABLE(0), 3*ecc->size); ecc_a_to_j (ecc, initial, TABLE(1), p); for (j = 2; j < size; j += 2) { ecc_dup_jj (ecc, TABLE(j), TABLE(j/2), scratch); ecc_add_jja (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch); } }
static void table_init (const struct ecc_curve *ecc, mp_limb_t *table, unsigned bits, const mp_limb_t *p, mp_limb_t *scratch) { unsigned size = 1 << bits; unsigned j; mpn_zero (TABLE(0), 3*ecc->p.size); TABLE(0)[ecc->p.size] = TABLE(0)[2*ecc->p.size] = 1; ecc_a_to_j (ecc, TABLE(1), p); for (j = 2; j < size; j += 2) { ecc_dup_eh (ecc, TABLE(j), TABLE(j/2), scratch); ecc_add_ehh (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch); } }
void ecc_mul_a (const struct ecc_curve *ecc, int initial, mp_limb_t *r, const mp_limb_t *np, const mp_limb_t *p, mp_limb_t *scratch) { #define tp scratch #define pj (scratch + 3*ecc->size) #define scratch_out (scratch + 6*ecc->size) int is_zero; unsigned i; ecc_a_to_j (ecc, initial, pj, p); mpn_zero (r, 3*ecc->size); for (i = ecc->size, is_zero = 1; i-- > 0; ) { mp_limb_t w = np[i]; mp_limb_t bit; for (bit = (mp_limb_t) 1 << (GMP_NUMB_BITS - 1); bit > 0; bit >>= 1) { int digit; ecc_dup_jj (ecc, r, r, scratch_out); ecc_add_jja (ecc, tp, r, pj, scratch_out); digit = (w & bit) > 0; /* If is_zero is set, r is the zero point, and ecc_add_jja produced garbage. */ cnd_copy (is_zero, tp, pj, 3*ecc->size); is_zero &= ~digit; /* If we had a one-bit, use the sum. */ cnd_copy (digit, r, tp, 3*ecc->size); } } }
void ecc_mul_a_eh (const struct ecc_curve *ecc, mp_limb_t *r, const mp_limb_t *np, const mp_limb_t *p, mp_limb_t *scratch) { #define pe scratch #define tp (scratch + 3*ecc->p.size) #define scratch_out (scratch + 6*ecc->p.size) unsigned i; ecc_a_to_j (ecc, pe, p); /* x = 0, y = 1, z = 1 */ mpn_zero (r, 3*ecc->p.size); r[ecc->p.size] = r[2*ecc->p.size] = 1; for (i = ecc->p.size; i-- > 0; ) { mp_limb_t w = np[i]; mp_limb_t bit; for (bit = (mp_limb_t) 1 << (GMP_NUMB_BITS - 1); bit > 0; bit >>= 1) { int digit; ecc_dup_eh (ecc, r, r, scratch_out); ecc_add_ehh (ecc, tp, r, pe, scratch_out); digit = (w & bit) > 0; /* If we had a one-bit, use the sum. */ cnd_copy (digit, r, tp, 3*ecc->p.size); } } }
void test_main (void) { unsigned i; for (i = 0; ecc_curves[i]; i++) { const struct ecc_curve *ecc = ecc_curves[i]; mp_limb_t *g = xalloc_limbs (ecc_size_j (ecc)); mp_limb_t *g2 = xalloc_limbs (ecc_size_j (ecc)); mp_limb_t *g3 = xalloc_limbs (ecc_size_j (ecc)); mp_limb_t *p = xalloc_limbs (ecc_size_j (ecc)); mp_limb_t *scratch = xalloc_limbs (ECC_ADD_JJJ_ITCH(ecc->p.size)); if (ecc->p.bit_size == 255) { mp_limb_t *z = xalloc_limbs (ecc_size_j (ecc)); /* Zero point has x = 0, y = 1, z = 1 */ mpn_zero (z, 3*ecc->p.size); z[ecc->p.size] = z[2*ecc->p.size] = 1; ecc_a_to_j (ecc, g, ecc->g); ecc_add_ehh (ecc, p, z, z, scratch); test_ecc_mul_h (i, 0, p); ecc_add_eh (ecc, p, z, z, scratch); test_ecc_mul_h (i, 0, p); ecc_add_ehh (ecc, p, g, p, scratch); test_ecc_mul_h (i, 1, p); ecc_add_eh (ecc, p, z, g, scratch); test_ecc_mul_h (i, 1, p); ecc_add_ehh (ecc, g2, g, p, scratch); test_ecc_mul_h (i, 2, g2); ecc_add_eh (ecc, g2, g, g, scratch); test_ecc_mul_h (i, 2, g2); ecc_add_ehh (ecc, g3, g, g2, scratch); test_ecc_mul_h (i, 3, g3); ecc_add_eh (ecc, g3, g2, g, scratch); test_ecc_mul_h (i, 3, g3); ecc_add_ehh (ecc, p, g, g3, scratch); test_ecc_mul_h (i, 4, p); ecc_add_eh (ecc, p, g3, g, scratch); test_ecc_mul_h (i, 4, p); ecc_add_ehh (ecc, p, g2, g2, scratch); test_ecc_mul_h (i, 4, p); free (z); } else { ecc_a_to_j (ecc, g, ecc->g); ecc_dup_jj (ecc, g2, g, scratch); test_ecc_mul_h (i, 2, g2); ecc_add_jjj (ecc, g3, g, g2, scratch); test_ecc_mul_h (i, 3, g3); ecc_add_jjj (ecc, g3, g2, g, scratch); test_ecc_mul_h (i, 3, g3); ecc_add_jjj (ecc, p, g, g3, scratch); test_ecc_mul_h (i, 4, p); ecc_add_jjj (ecc, p, g3, g, scratch); test_ecc_mul_h (i, 4, p); ecc_dup_jj (ecc, p, g2, scratch); test_ecc_mul_h (i, 4, p); } free (g); free (g2); free (g3); free (p); free (scratch); } }