示例#1
0
文件: ge25519.c 项目: Alexey-T/SynFTP
/* return 0 on success, -1 otherwise */
int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
{
    unsigned char par;

    fe25519 t, chk, num, den, den2, den4, den6;
    fe25519_setone(&r->z);
    par = p[31] >> 7;
    fe25519_unpack(&r->y, p);
    fe25519_square(&num, &r->y); /* x = y^2 */
    fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
    fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
    fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */

    /* Computation of sqrt(num/den) */
    /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
    fe25519_square(&den2, &den);
    fe25519_square(&den4, &den2);
    fe25519_mul(&den6, &den4, &den2);
    fe25519_mul(&t, &den6, &num);
    fe25519_mul(&t, &t, &den);

    fe25519_pow2523(&t, &t);
    /* 2. computation of r->x = t * num * den^3 */
    fe25519_mul(&t, &t, &num);
    fe25519_mul(&t, &t, &den);
    fe25519_mul(&t, &t, &den);
    fe25519_mul(&r->x, &t, &den);

    /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
    fe25519_square(&chk, &r->x);
    fe25519_mul(&chk, &chk, &den);
    if (!fe25519_iseq_vartime(&chk, &num)) {
        fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
    }

    /* 4. Now we have one of the two square roots, except if input was not a square */
    fe25519_square(&chk, &r->x);
    fe25519_mul(&chk, &chk, &den);
    if (!fe25519_iseq_vartime(&chk, &num)) {
        return -1;
    }

    /* 5. Choose the desired square root according to parity: */
    if(fe25519_getparity(&r->x) != (1-par)) {
        fe25519_neg(&r->x, &r->x);
    }

    fe25519_mul(&r->t, &r->x, &r->y);

    return 0;
}
void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
                  const uint8_t point[32]) {
  uint8_t e[32];
  OPENSSL_memcpy(e, scalar, sizeof(e));

  e[0] &= 248;
  e[31] &= 127;
  e[31] |= 64;

  fe25519 t;
  fe25519 z;
  fe25519_unpack(&t, point);
  mladder(&t, &z, e);
  fe25519_invert(&z, &z);
  x25519_x86_64_mul(&t, &t, &z);
  fe25519_pack(out, &t);
}
int edmont_conv(unsigned char r[crypto_scalarmult_curve25519_BYTES],
                const unsigned char p[ED25519_PUBLICKEYBYTES]) {
  fe25519 u, y, num, den, inv, one;

  fe25519_unpack(&y, p);

  // u = (1 + y) / (1 -y)

  fe25519_setone(&one);
  fe25519_add(&num, &one, &y);

  fe25519_sub(&den, &one, &y);
  fe25519_invert(&inv, &den);

  fe25519_mul(&u, &num, &inv);

  fe25519_pack(r, &u);
  return 0;
}