/** * Supposes data is in Montgomery form prior to being called */ void add_point_point(struct curve_point *p3, struct curve_point *p1, struct curve_point *p2, unsigned int num_limbs) { struct curve_point p_out; limb_t numer[num_limbs]; limb_t denom[num_limbs]; limb_t lambda[num_limbs]; /* lambda = (y2 - y1) / (x2 - x1) */ sub_mod_num_num(numer, p2->y, p1->y, m_glo, num_limbs); sub_mod_num_num(denom, p2->x, p1->x, m_glo, num_limbs); montgomery_inverse_num(denom, denom, m_glo, num_limbs); mul_montgomery_num_num(lambda, numer, denom, m_glo, m_prime_glo, num_limbs); /* x */ mul_montgomery_num_num(p_out.x, lambda, lambda, m_glo, m_prime_glo, num_limbs); sub_mod_num_num(p_out.x, p_out.x, p1->x, m_glo, num_limbs); sub_mod_num_num(p_out.x, p_out.x, p2->x, m_glo, num_limbs); /* y */ sub_mod_num_num(p_out.y, p1->x, p_out.x, m_glo, num_limbs); mul_montgomery_num_num(p_out.y, lambda, p_out.y, m_glo, m_prime_glo, num_limbs); sub_mod_num_num(p_out.y, p_out.y, p1->y, m_glo, num_limbs); copy_num(p3->x, p_out.x, num_limbs); copy_num(p3->y, p_out.y, num_limbs); }
/** * Supposes data is in Montgomery form prior to being called */ void double_point(struct curve_point *p2, struct curve_point *p1, unsigned int num_limbs) { struct curve_point p_out; limb_t x1_squared[num_limbs]; limb_t numer[num_limbs]; limb_t denom[num_limbs]; limb_t lambda[num_limbs]; /* lambda = (3 * (x1^2) + a) / (2 * y1) */ mul_montgomery_num_num(x1_squared, p1->x, p1->x, m_glo, m_prime_glo, num_limbs); add_mod_num_num(numer, x1_squared, x1_squared, m_glo, num_limbs); add_mod_num_num(numer, numer, x1_squared, m_glo, num_limbs); add_mod_num_num(numer, numer, a_glo, m_glo, num_limbs); add_mod_num_num(denom, p1->y, p1->y, m_glo, num_limbs); montgomery_inverse_num(denom, denom, m_glo, num_limbs); mul_montgomery_num_num(lambda, numer, denom, m_glo, m_prime_glo, num_limbs); /* x */ mul_montgomery_num_num(p_out.x, lambda, lambda, m_glo, m_prime_glo, num_limbs); sub_mod_num_num(p_out.x, p_out.x, p1->x, m_glo, num_limbs); sub_mod_num_num(p_out.x, p_out.x, p1->x, m_glo, num_limbs); /* y */ sub_mod_num_num(p_out.y, p1->x, p_out.x, m_glo, num_limbs); mul_montgomery_num_num(p_out.y, lambda, p_out.y, m_glo, m_prime_glo, num_limbs); sub_mod_num_num(p_out.y, p_out.y, p1->y, m_glo, num_limbs); copy_num(p2->x, p_out.x, num_limbs); copy_num(p2->y, p_out.y, num_limbs); }
/** * Supposes data is in Montgomery form prior to being called */ void neg_point(struct curve_point *p2, struct curve_point *p1, unsigned int num_limbs) { struct curve_point p_out; limb_t zero[NUM_LIMBS]; zero_num(zero, num_limbs); copy_num(p_out.x, p1->x, num_limbs); sub_mod_num_num(p_out.y, zero, p1->y, m_glo, num_limbs); copy_num(p2->x, p_out.x, num_limbs); copy_num(p2->y, p_out.y, num_limbs); }
void new_pow(long long n, int result[]) { int i; copy_num(ZERO, result); result[0] = 1; for (i = 0; n != 0; i++) { if ((n & 0x1) != 0) { int temp[NUM_DIGITS]; mult(result, powtab[i], temp); copy_num(temp, result); } n >>= 1; } }
void mult(int a[], int b[], int result[]) { int i, j, r; copy_num(ZERO, result); for (i = 0; i < NUM_DIGITS; i++) { if (a[i] == 0) continue; for (j = 0; j < NUM_DIGITS; j++) { if(b[j] == 0) continue; r = i + j; if (r < NUM_DIGITS) { result[r] += a[i] * b[j]; } if (r < NUM_DIGITS - 1 && result[r] > 9) { result[r + 1] += result[r] / 10; } if (r < NUM_DIGITS) { result[r] %= 10; } } } }