Example #1
0
int fp_bits(const fp_t a) {
	int i = RLC_FP_DIGS - 1;

	while (i >= 0 && a[i] == 0) {
		i--;
	}

	if (i > 0) {
		return (i << RLC_DIG_LOG) + util_bits_dig(a[i]);
	} else {
		return util_bits_dig(a[0]);
	}
}
Example #2
0
void ep2_mul_dig(ep2_t r, ep2_t p, dig_t k) {
	int i, l;
	ep2_t t;

	ep2_null(t);

	if (k == 0) {
		ep2_set_infty(r);
		return;
	}

	TRY {
		ep2_new(t);

		l = util_bits_dig(k);

		ep2_copy(t, p);

		for (i = l - 2; i >= 0; i--) {
			ep2_dbl(t, t);
			if (k & ((dig_t)1 << i)) {
				ep2_add(t, t, p);
			}
		}

		ep2_norm(r, t);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ep2_free(t);
	}
}
Example #3
0
void bn_mxp_dig(bn_t c, const bn_t a, dig_t b, const bn_t m) {
	int i, l;
	bn_t t, u, r;

	if (b == 0) {
		bn_set_dig(c, 1);
		return;
	}

	bn_null(t);
	bn_null(u);
	bn_null(r);

	TRY {
		bn_new(t);
		bn_new(u);
		bn_new(r);

		bn_mod_pre(u, m);

		l = util_bits_dig(b);

#if BN_MOD == MONTY
		bn_mod_monty_conv(t, a, m);
#else
		bn_copy(t, a);
#endif

		bn_copy(r, t);

		for (i = l - 2; i >= 0; i--) {
			bn_sqr(r, r);
			bn_mod(r, r, m, u);
			if (b & ((dig_t)1 << i)) {
				bn_mul(r, r, t);
				bn_mod(r, r, m, u);
			}
		}

#if BN_MOD == MONTY
		bn_mod_monty_back(c, r, m);
#else
		bn_copy(c, r);
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t);
		bn_free(u);
		bn_free(r);
	}
}
Example #4
0
int bn_bits(const bn_t a) {
	int bits;

	if (a->used == 0) {
		return 0;
	}

	/* Bits in lower digits. */
	bits = (a->used - 1) * BN_DIGIT;

	return bits + util_bits_dig(a->dp[a->used - 1]);
}
Example #5
0
void bn_mxp_slide(bn_t c, const bn_t a, const bn_t b, const bn_t m) {
	bn_t tab[TABLE_SIZE], t, u, r;
	int i, j, l, w = 1;
	uint8_t win[BN_BITS];

	bn_null(t);
	bn_null(u);
	bn_null(r);
	/* Initialize table. */
	for (i = 0; i < TABLE_SIZE; i++) {
		bn_null(tab[i]);
	}

	TRY {

		/* Find window size. */
		i = bn_bits(b);
		if (i <= 21) {
			w = 2;
		} else if (i <= 32) {
			w = 3;
		} else if (i <= 128) {
			w = 4;
		} else if (i <= 256) {
			w = 5;
		} else {
			w = 6;
		}

		for (i = 1; i < (1 << w); i += 2) {
			bn_new(tab[i]);
		}

		bn_new(t);
		bn_new(u);
		bn_new(r);
		bn_mod_pre(u, m);

#if BN_MOD == MONTY
		bn_set_dig(r, 1);
		bn_mod_monty_conv(r, r, m);
		bn_mod_monty_conv(t, a, m);
#else /* BN_MOD == BARRT || BN_MOD == RADIX */
		bn_set_dig(r, 1);
		bn_copy(t, a);
#endif

		bn_copy(tab[1], t);
		bn_sqr(t, tab[1]);
		bn_mod(t, t, m, u);
		/* Create table. */
		for (i = 1; i < 1 << (w - 1); i++) {
			bn_mul(tab[2 * i + 1], tab[2 * i - 1], t);
			bn_mod(tab[2 * i + 1], tab[2 * i + 1], m, u);
		}

		l = BN_BITS + 1;
		bn_rec_slw(win, &l, b, w);
		for (i = 0; i < l; i++) {
			if (win[i] == 0) {
				bn_sqr(r, r);
				bn_mod(r, r, m, u);
			} else {
				for (j = 0; j < util_bits_dig(win[i]); j++) {
					bn_sqr(r, r);
					bn_mod(r, r, m, u);
				}
				bn_mul(r, r, tab[win[i]]);
				bn_mod(r, r, m, u);
			}
		}
		bn_trim(r);
#if BN_MOD == MONTY
		bn_mod_monty_back(c, r, m);
#else
		bn_copy(c, r);
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		for (i = 1; i < (1 << w); i++) {
			bn_free(tab[i]);
		}
		bn_free(u);
		bn_free(t);
		bn_free(r);
	}
}
Example #6
0
int cp_bdpe_gen(bdpe_t pub, bdpe_t prv, dig_t block, int bits) {
	bn_t t, r;
	int result = STS_OK;

	bn_null(t);
	bn_null(r);

	TRY {
		bn_new(t);
		bn_new(r);

		prv->t = pub->t = block;

		/* Make sure that block size is prime. */
		bn_set_dig(t, block);
		if (bn_is_prime_basic(t) == 0) {
			THROW(ERR_NO_VALID);
		}

		/* Generate prime q such that gcd(block, (q - 1)) = 1. */
		do {
			bn_gen_prime(prv->q, bits / 2);
			bn_sub_dig(prv->q, prv->q, 1);
			bn_gcd_dig(t, prv->q, block);
			bn_add_dig(prv->q, prv->q, 1);
		} while (bn_cmp_dig(t, 1) != CMP_EQ);

		/* Generate different primes p and q. */
		do {
			/* Compute p = block * (x * block + b) + 1, 0 < b < block random. */
			bn_rand(prv->p, BN_POS, bits / 2 - 2 * util_bits_dig(block));
			bn_mul_dig(prv->p, prv->p, block);
			bn_rand(t, BN_POS, util_bits_dig(block));
			bn_add_dig(prv->p, prv->p, t->dp[0]);

			/* We know that block divides (p-1). */
			bn_gcd_dig(t, prv->p, block);
			bn_mul_dig(prv->p, prv->p, block);
			bn_add_dig(prv->p, prv->p, 1);
		} while (bn_cmp_dig(t, 1) != CMP_EQ || bn_is_prime(prv->p) == 0);

		/* Compute t = (p-1)*(q-1). */
		bn_sub_dig(prv->q, prv->q, 1);
		bn_sub_dig(prv->p, prv->p, 1);
		bn_mul(t, prv->p, prv->q);
		bn_div_dig(t, t, block);

		/* Restore factors p and q and compute n = p * q. */
		bn_add_dig(prv->p, prv->p, 1);
		bn_add_dig(prv->q, prv->q, 1);
		bn_mul(pub->n, prv->p, prv->q);
		bn_copy(prv->n, pub->n);

		/* Select random y such that y^{(p-1)(q-1)}/block \neq 1 mod N. */
		do {
			bn_rand(pub->y, BN_POS, bits);
			bn_mxp(r, pub->y, t, pub->n);
		} while (bn_cmp_dig(r, 1) == CMP_EQ);

		bn_copy(prv->y, pub->y);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(t);
		bn_free(r);
	}

	return result;
}
void fb_invn_low(dig_t *c, const dig_t *a) {
	int j, d, lu, lv, lt, l1, l2, bu, bv;
	align dig_t _u[2 * FB_DIGS], _v[2 * FB_DIGS];
	align dig_t _g1[2 * FB_DIGS], _g2[2 * FB_DIGS];
	dig_t *t = NULL, *u = NULL, *v = NULL, *g1 = NULL, *g2 = NULL, carry;

	dv_zero(_g1, FB_DIGS + 1);
	dv_zero(_g2, FB_DIGS + 1);

	u = _u;
	v = _v;
	g1 = _g1;
	g2 = _g2;

	/* u = a, v = f, g1 = 1, g2 = 0. */
	dv_copy(u, a, FB_DIGS);
	dv_copy(v, fb_poly_get(), FB_DIGS);
	g1[0] = 1;

	lu = lv = FB_DIGS;
	l1 = l2 = 1;

	bu = fb_bits(u);
	bv = FB_BITS + 1;
	j = bu - bv;

	/* While (u != 1). */
	while (1) {
		/* If j < 0 then swap(u, v), swap(g1, g2), j = -j. */
		if (j < 0) {
			t = u;
			u = v;
			v = t;

			lt = lu;
			lu = lv;
			lv = lt;

			t = g1;
			g1 = g2;
			g2 = t;

			lt = l1;
			l1 = l2;
			l2 = lt;

			j = -j;
		}

		SPLIT(j, d, j, FB_DIG_LOG);

		/* u = u + v * z^j. */
		if (j > 0) {
			carry = fb_lsha_low(u + d, v, j, lv);
			u[d + lv] ^= carry;
		} else {
			fb_addd_low(u + d, u + d, v, lv);
		}

		/* g1 = g1 + g2 * z^j. */
		if (j > 0) {
			carry = fb_lsha_low(g1 + d, g2, j, l2);
			l1 = (l2 + d >= l1 ? l2 + d : l1);
			if (carry) {
				g1[d + l2] ^= carry;
				l1 = (l2 + d >= l1 ? l1 + 1 : l1);
			}
		} else {
			fb_addd_low(g1 + d, g1 + d, g2, l2);
			l1 = (l2 + d > l1 ? l2 + d : l1);
		}

		while (u[lu - 1] == 0)
			lu--;
		while (v[lv - 1] == 0)
			lv--;

		if (lu == 1 && u[0] == 1)
			break;

		/* j = deg(u) - deg(v). */
		lt = util_bits_dig(u[lu - 1]) - util_bits_dig(v[lv - 1]);
		j = ((lu - lv) << FB_DIG_LOG) + lt;
	}
	/* Return g1. */
	fb_copy(c, g1);
}
Example #8
0
void ed_mul_slide(ed_t r, const ed_t p, const bn_t k) {
	ed_t t[1 << (EP_WIDTH - 1)], q;
	int i, j, l;
	uint8_t win[RLC_FP_BITS + 1];

	ed_null(q);

	if (bn_is_zero(k) || ed_is_infty(p)) {
		ed_set_infty(r);
		return;
	}

	TRY {
		for (i = 0; i < (1 << (EP_WIDTH - 1)); i ++) {
			ed_null(t[i]);
			ed_new(t[i]);
		}

		ed_new(q);

		ed_copy(t[0], p);
		ed_dbl(q, p);

#if defined(EP_MIXED)
		ed_norm(q, q);
#endif

		/* Create table. */
		for (i = 1; i < (1 << (EP_WIDTH - 1)); i++) {
			ed_add(t[i], t[i - 1], q);
		}

#if defined(EP_MIXED)
		ed_norm_sim(t + 1, (const ed_t *)t + 1, (1 << (EP_WIDTH - 1)) - 1);
#endif

		ed_set_infty(q);
		l = RLC_FP_BITS + 1;
		bn_rec_slw(win, &l, k, EP_WIDTH);
		for (i = 0; i < l; i++) {
			if (win[i] == 0) {
				ed_dbl(q, q);
			} else {
				for (j = 0; j < util_bits_dig(win[i]); j++) {
					ed_dbl(q, q);
				}
				ed_add(q, q, t[win[i] >> 1]);
			}
		}

		ed_norm(r, q);
		if (bn_sign(k) == RLC_NEG) {
			ed_neg(r, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		for (i = 0; i < (1 << (EP_WIDTH - 1)); i++) {
			ed_free(t[i]);
		}
		ed_free(q);
	}
}
Example #9
0
void fp_exp_slide(fp_t c, const fp_t a, const bn_t b) {
	fp_t t[1 << (FP_WIDTH - 1)], r;
	int i, j, l;
	uint8_t win[FP_BITS + 1];

	fp_null(r);

	if (bn_is_zero(b)) {
		fp_set_dig(c, 1);
		return;
	}


	/* Initialize table. */
	for (i = 0; i < (1 << (FP_WIDTH - 1)); i++) {
		fp_null(t[i]);
	}

	TRY {
		for (i = 0; i < (1 << (FP_WIDTH - 1)); i ++) {
			fp_new(t[i]);
		}
		fp_new(r);

		fp_copy(t[0], a);
		fp_sqr(r, a);

		/* Create table. */
		for (i = 1; i < 1 << (FP_WIDTH - 1); i++) {
			fp_mul(t[i], t[i - 1], r);
		}

		fp_set_dig(r, 1);
		l = FP_BITS + 1;
		bn_rec_slw(win, &l, b, FP_WIDTH);
		for (i = 0; i < l; i++) {
			if (win[i] == 0) {
				fp_sqr(r, r);
			} else {
				for (j = 0; j < util_bits_dig(win[i]); j++) {
					fp_sqr(r, r);
				}
				fp_mul(r, r, t[win[i] >> 1]);
			}
		}

		if (bn_sign(b) == BN_NEG) {
			fp_inv(c, r);
		} else {
			fp_copy(c, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		for (i = 0; i < (1 << (FP_WIDTH - 1)); i++) {
			fp_free(t[i]);
		}
		fp_free(r);
	}
}
void bn_divn_low(dig_t *c, dig_t *d, dig_t *a, int sa, dig_t *b, int sb) {
	int norm, i, n, t, sd;
	dig_t carry, t1[3], t2[3];

	/* Normalize x and y so that the leading digit of y is bigger than
	 * 2^(BN_DIGIT-1). */
	norm = util_bits_dig(b[sb - 1]) % BN_DIGIT;

	if (norm < (int)(BN_DIGIT - 1)) {
		norm = (BN_DIGIT - 1) - norm;
		carry = bn_lshb_low(a, a, sa, norm);
		if (carry) {
			a[sa++] = carry;
		}
		carry = bn_lshb_low(b, b, sb, norm);
		if (carry) {
			b[sb++] = carry;
		}
	} else {
		norm = 0;
	}

	n = sa - 1;
	t = sb - 1;

	/* Shift y so that the most significant digit of y is aligned with the
	 * most significant digit of x. */
	bn_lshd_low(b, b, sb, (n - t));

	/* Find the most significant digit of the quotient. */
	while (bn_cmpn_low(a, b, sa) != CMP_LT) {
		c[n - t]++;
		bn_subn_low(a, a, b, sa);
	}
	/* Shift y back. */

	bn_rshd_low(b, b, sb + (n - t), (n - t));

	/* Find the remaining digits. */
	for (i = n; i >= (t + 1); i--) {
		if (i > sa) {
			continue;
		}

		if (a[i] == b[t]) {
			c[i - t - 1] = ((((dbl_t)1) << BN_DIGIT) - 1);
		} else {
			dbl_t tmp;
			tmp = ((dbl_t)a[i]) << ((dbl_t)BN_DIGIT);
			tmp |= (dbl_t)(a[i - 1]);
			tmp /= (dbl_t)(b[t]);
			c[i - t - 1] = (dig_t)tmp;
		}

		c[i - t - 1]++;
		do {
			c[i - t - 1]--;
			t1[0] = (t - 1 < 0) ? 0 : b[t - 1];
			t1[1] = b[t];

			carry = bn_mul1_low(t1, t1, c[i - t - 1], 2);
			t1[2] = carry;

			t2[0] = (i - 2 < 0) ? 0 : a[i - 2];
			t2[1] = (i - 1 < 0) ? 0 : a[i - 1];
			t2[2] = a[i];
		} while (bn_cmpn_low(t1, t2, 3) == CMP_GT);

		carry = bn_mul1_low(d, b, c[i - t - 1], sb);
		sd = sb;
		if (carry) {
			d[sd++] = carry;
		}

		carry = bn_subn_low(a + (i - t - 1), a + (i - t - 1), d, sd);
		sd += (i - t - 1);
		if (sa - sd > 0) {
			carry = bn_sub1_low(a + sd, a + sd, carry, sa - sd);
		}

		if (carry) {
			sd = sb + (i - t - 1);
			carry = bn_addn_low(a + (i - t - 1), a + (i - t - 1), b, sb);
			carry = bn_add1_low(a + sd, a + sd, carry, sa - sd);
			c[i - t - 1]--;
		}
	}
	/* Remainder should be not be longer than the divisor. */
	bn_rshb_low(d, a, sb, norm);
}