/**
 * 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);
}
Esempio n. 4
0
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;
    }
}
Esempio n. 5
0
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;
            }
        }
    }
}