static EdwardsPoint *eddsa_decode(ptrlen encoded, const struct ec_curve *curve) { assert(curve->type == EC_EDWARDS); assert(curve->fieldBits % 8 == 7); mp_int *y = mp_from_bytes_le(encoded); if (mp_get_nbits(y) > curve->fieldBits+1) { mp_free(y); return NULL; } /* The topmost bit of the encoding isn't part of y, so it stores * the bottom bit of x. Extract it, and zero that bit in y. */ unsigned desired_x_parity = mp_get_bit(y, curve->fieldBits); mp_set_bit(y, curve->fieldBits, 0); EdwardsPoint *P = ecc_edwards_point_new_from_y( curve->e.ec, y, desired_x_parity); mp_free(y); /* A point constructed in this way will always satisfy the curve * equation, unless ecc.c wasn't able to construct one at all, in * which case P is now NULL. Either way, return it. */ return P; }
unsigned int * msqrt(unsigned int *n) { int i, k, kk; unsigned int m, *x, *y; if (MLENGTH(n) == 1 && n[0] == 0) { x = mint(0); return x; } // count number of bits k = 32 * (MLENGTH(n) - 1); m = n[MLENGTH(n) - 1]; while (m) { m >>= 1; k++; } k = (k - 1) / 2; // initial guess kk = k / 32 + 1; x = mnew(kk); MSIGN(x) = 1; MLENGTH(x) = kk; for (i = 0; i < kk; i++) x[i] = 0; mp_set_bit(x, k); while (--k >= 0) { mp_set_bit(x, k); y = mmul(x, x); if (mcmp(y, n) == 1) mp_clr_bit(x, k); mfree(y); } return x; }
unsigned int * mroot(unsigned int *n, unsigned int index) { int i, j, k; unsigned int m, *x, *y; if (index == 0) stop("root index is zero"); // count number of bits k = 32 * (MLENGTH(n) - 1); m = n[MLENGTH(n) - 1]; while (m) { m >>= 1; k++; } if (k == 0) return mint(0); // initial guess k = (k - 1) / index; j = k / 32 + 1; x = mnew(j); MSIGN(x) = 1; MLENGTH(x) = j; for (i = 0; i < j; i++) x[i] = 0; while (k >= 0) { mp_set_bit(x, k); y = mpow(x, index); switch (mcmp(y, n)) { case -1: break; case 0: mfree(y); return x; case 1: mp_clr_bit(x, k); break; } mfree(y); k--; } mfree(x); return 0; }
static mp_int *eddsa_exponent_from_hash( ptrlen hash, const struct ec_curve *curve) { /* * Make an integer out of the hash data, little-endian. */ assert(hash.len >= curve->fieldBytes); mp_int *e = mp_from_bytes_le(make_ptrlen(hash.ptr, curve->fieldBytes)); /* * Set the highest bit that fits in the modulus, and clear any * above that. */ mp_set_bit(e, curve->fieldBits - 1, 1); mp_reduce_mod_2to(e, curve->fieldBits); /* * Clear exactly three low bits. */ for (size_t bit = 0; bit < 3; bit++) mp_set_bit(e, bit, 0); return e; }
unsigned int * mgcd(unsigned int *u, unsigned int *v) { int i, k, n; unsigned int *t; if (MZERO(u)) { t = mcopy(v); MSIGN(t) = 1; return t; } if (MZERO(v)) { t = mcopy(u); MSIGN(t) = 1; return t; } u = mcopy(u); v = mcopy(v); MSIGN(u) = 1; MSIGN(v) = 1; k = 0; while ((u[0] & 1) == 0 && (v[0] & 1) == 0) { mshiftright(u); mshiftright(v); k++; } if (u[0] & 1) { t = mcopy(v); MSIGN(t) *= -1; } else t = mcopy(u); while (1) { while ((t[0] & 1) == 0) mshiftright(t); if (MSIGN(t) == 1) { mfree(u); u = mcopy(t); } else { mfree(v); v = mcopy(t); MSIGN(v) *= -1; } mfree(t); t = msub(u, v); if (MZERO(t)) { mfree(t); mfree(v); n = (k / 32) + 1; v = mnew(n); MSIGN(v) = 1; MLENGTH(v) = n; for (i = 0; i < n; i++) v[i] = 0; mp_set_bit(v, k); t = mmul(u, v); mfree(u); mfree(v); return t; } } }