Пример #1
0
/**
 * Multiplies a binary elliptic curve point by an integer using the w-NAF mixed coordinate
 * method.
 *
 * @param[out] r 				- the result.
 * @param[in] t					- the precomputed table.
 * @param[in] k					- the integer.
 */
static void ed_mul_fix_plain_mixed(ed_t r, const ed_t *t, const bn_t k) {
	int l, i, n;
	int8_t naf[FP_BITS + 1], *_k;

	/* Compute the w-TNAF representation of k. */
	l = FP_BITS + 1;
	bn_rec_naf(naf, &l, k, ED_DEPTH);

	_k = naf + l - 1;
	ed_set_infty(r);
	for (i = l - 1; i >= 0; i--, _k--) {
		n = *_k;
		if (n == 0) {
			/* doubling is followed by another doubling */
			if (i > 0) {
				ed_dbl_short(r, r);
			} else {
				/* use full extended coordinate doubling for last step */
				ed_dbl(r, r);
			}
		} else {
			ed_dbl(r, r);
			if (n > 0) {
				ed_add(r, r, t[n / 2]);
			} else if (n < 0) {
				ed_sub(r, r, t[-n / 2]);
			}
		}
	}
	/* Convert r to affine coordinates. */
	ed_norm(r, r);
}
Пример #2
0
/**
 * Multiplies a binary elliptic curve point by an integer using the w-NAF
 * method.
 *
 * @param[out] r 				- the result.
 * @param[in] p					- the point to multiply.
 * @param[in] k					- the integer.
 */
static void ep2_mul_fix_ordin(ep2_t r, ep2_t *table, bn_t k) {
	int len, i, n;
	int8_t naf[2 * RLC_FP_BITS + 1], *t;

	if (bn_is_zero(k)) {
		ep2_set_infty(r);
		return;
	}

	/* Compute the w-TNAF representation of k. */
	len = 2 * RLC_FP_BITS + 1;
	bn_rec_naf(naf, &len, k, EP_DEPTH);

	t = naf + len - 1;
	ep2_set_infty(r);
	for (i = len - 1; i >= 0; i--, t--) {
		ep2_dbl(r, r);

		n = *t;
		if (n > 0) {
			ep2_add(r, r, table[n / 2]);
		}
		if (n < 0) {
			ep2_sub(r, r, table[-n / 2]);
		}
	}
	/* Convert r to affine coordinates. */
	ep2_norm(r, r);
	if (bn_sign(k) == RLC_NEG) {
		ep2_neg(r, r);
	}
}
Пример #3
0
void ep2_mul_fix_nafwi(ep2_t r, ep2_t *t, bn_t k) {
	int i, j, l, d, m;
	ep2_t a;
	int8_t naf[2 * FP_BITS + 1];
	char w;

	ep2_null(a);

	TRY {
		ep2_new(a);

		ep2_set_infty(r);
		ep2_set_infty(a);

		l = 2 * FP_BITS + 1;
		bn_rec_naf(naf, &l, k, 2);

		d = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1);

		for (i = 0; i < d; i++) {
			w = 0;
			for (j = EP_DEPTH - 1; j >= 0; j--) {
				if (i * EP_DEPTH + j < l) {
					w = (char)(w << 1);
					w = (char)(w + naf[i * EP_DEPTH + j]);
				}
			}
			naf[i] = w;
		}

		if (EP_DEPTH % 2 == 0) {
			m = ((1 << (EP_DEPTH + 1)) - 2) / 3;
		} else {
			m = ((1 << (EP_DEPTH + 1)) - 1) / 3;
		}

		for (j = m; j >= 1; j--) {
			for (i = 0; i < d; i++) {
				if (naf[i] == j) {
					ep2_add(a, a, t[i]);
				}
				if (naf[i] == -j) {
					ep2_sub(a, a, t[i]);
				}
			}
			ep2_add(r, r, a);
		}
		ep2_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ep2_free(a);
	}
}
Пример #4
0
/**
 * Multiplies a binary elliptic curve point by an integer using the w-NAF
 * method.
 *
 * @param[out] r 				- the result.
 * @param[in] t					- the precomputed table.
 * @param[in] k					- the integer.
 */
static void ed_mul_fix_plain(ed_t r, const ed_t *t, const bn_t k) {
	int l, i, n;
	int8_t naf[FP_BITS + 1], *_k;

	/* Compute the w-TNAF representation of k. */
	l = FP_BITS + 1;
	bn_rec_naf(naf, &l, k, ED_DEPTH);

	_k = naf + l - 1;
	ed_set_infty(r);
	for (i = l - 1; i >= 0; i--, _k--) {
		ed_dbl(r, r);

		n = *_k;
		if (n > 0) {
			ed_add(r, r, t[n / 2]);
		}
		if (n < 0) {
			ed_sub(r, r, t[-n / 2]);
		}
	}
	/* Convert r to affine coordinates. */
	ed_norm(r, r);
}
Пример #5
0
/**
 * Multiplies and adds two binary elliptic curve points simultaneously,
 * optionally choosing the first point as the generator depending on an optional
 * table of precomputed points.
 *
 * @param[out] r 				- the result.
 * @param[in] p					- the first point to multiply.
 * @param[in] k					- the first integer.
 * @param[in] q					- the second point to multiply.
 * @param[in] m					- the second integer.
 * @param[in] t					- the pointer to a precomputed table.
 */
static void eb_mul_sim_plain(eb_t r, const eb_t p, const bn_t k, const eb_t q,
		const bn_t m, const eb_t *t) {
	int l, l0, l1, i, n0, n1, w, g;
	int8_t naf0[FB_BITS + 1], naf1[FB_BITS + 1], *_k, *_m;
	eb_t t0[1 << (EB_WIDTH - 2)];
	eb_t t1[1 << (EB_WIDTH - 2)];

	for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) {
		eb_null(t0[i]);
		eb_null(t1[i]);
	}

	TRY {
		g = (t == NULL ? 0 : 1);
		if (!g) {
			for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) {
				eb_new(t0[i]);
			}
			eb_tab(t0, p, EB_WIDTH);
			t = (const eb_t *)t0;
		}

		/* Prepare the precomputation table. */
		for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) {
			eb_new(t1[i]);
		}
		/* Compute the precomputation table. */
		eb_tab(t1, q, EB_WIDTH);

		/* Compute the w-NAF representation of k. */
		if (g) {
			w = EB_DEPTH;
		} else {
			w = EB_WIDTH;
		}

		l0 = l1 = FB_BITS + 1;
		bn_rec_naf(naf0, &l0, k, w);
		bn_rec_naf(naf1, &l1, m, EB_WIDTH);

		l = MAX(l0, l1);
		_k = naf0 + l - 1;
		_m = naf1 + l - 1;
		for (i = l0; i < l; i++) {
			naf0[i] = 0;
		}
		for (i = l1; i < l; i++) {
			naf1[i] = 0;
		}

		eb_set_infty(r);
		for (i = l - 1; i >= 0; i--, _k--, _m--) {
			eb_dbl(r, r);

			n0 = *_k;
			n1 = *_m;
			if (n0 > 0) {
				eb_add(r, r, t[n0 / 2]);
			}
			if (n0 < 0) {
				eb_sub(r, r, t[-n0 / 2]);
			}
			if (n1 > 0) {
				eb_add(r, r, t1[n1 / 2]);
			}
			if (n1 < 0) {
				eb_sub(r, r, t1[-n1 / 2]);
			}
		}
		/* Convert r to affine coordinates. */
		eb_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		/* Free the precomputation tables. */
		if (!g) {
			for (i = 0; i < 1 << (EB_WIDTH - 2); i++) {
				eb_free(t0[i]);
			}
		}
		for (i = 0; i < 1 << (EB_WIDTH - 2); i++) {
			eb_free(t1[i]);
		}
	}
}
Пример #6
0
/**
 * Multiplies and adds two prime elliptic curve points simultaneously,
 * optionally choosing the first point as the generator depending on an optional
 * table of precomputed points.
 *
 * @param[out] r 				- the result.
 * @param[in] p					- the first point to multiply.
 * @param[in] k					- the first integer.
 * @param[in] q					- the second point to multiply.
 * @param[in] m					- the second integer.
 * @param[in] t					- the pointer to the precomputed table.
 */
void ep_mul_sim_endom(ep_t r, const ep_t p, const bn_t k, const ep_t q,
		const bn_t m, const ep_t *t) {
	int len, len0, len1, len2, len3, i, n, sk0, sk1, sl0, sl1, w, g = 0;
	int8_t naf0[FP_BITS + 1], naf1[FP_BITS + 1], *t0, *t1;
	int8_t naf2[FP_BITS + 1], naf3[FP_BITS + 1], *t2, *t3;
	bn_t k0, k1, l0, l1;
	bn_t ord, v1[3], v2[3];
	ep_t u;
	ep_t tab0[1 << (EP_WIDTH - 2)];
	ep_t tab1[1 << (EP_WIDTH - 2)];

	bn_null(ord);
	bn_null(k0);
	bn_null(k1);
	bn_null(l0);
	bn_null(l1);
	ep_null(u);

	for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
		ep_null(tab0[i]);
		ep_null(tab1[i]);
	}

	bn_new(ord);
	bn_new(k0);
	bn_new(k1);
	bn_new(l0);
	bn_new(l1);
	ep_new(u);

	TRY {
		for (i = 0; i < 3; i++) {
			bn_null(v1[i]);
			bn_null(v2[i]);
			bn_new(v1[i]);
			bn_new(v2[i]);
		}

		ep_curve_get_ord(ord);
		ep_curve_get_v1(v1);
		ep_curve_get_v2(v2);

		bn_rec_glv(k0, k1, k, ord, (const bn_t *)v1, (const bn_t *)v2);
		sk0 = bn_sign(k0);
		sk1 = bn_sign(k1);
		bn_abs(k0, k0);
		bn_abs(k1, k1);

		bn_rec_glv(l0, l1, m, ord, (const bn_t *)v1, (const bn_t *)v2);
		sl0 = bn_sign(l0);
		sl1 = bn_sign(l1);
		bn_abs(l0, l0);
		bn_abs(l1, l1);

		g = (t == NULL ? 0 : 1);
		if (!g) {
			for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
				ep_new(tab0[i]);
			}
			ep_tab(tab0, p, EP_WIDTH);
			t = (const ep_t *)tab0;
		}

		/* Prepare the precomputation table. */
		for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
			ep_new(tab1[i]);
		}
		/* Compute the precomputation table. */
		ep_tab(tab1, q, EP_WIDTH);

		/* Compute the w-TNAF representation of k and l */
		if (g) {
			w = EP_DEPTH;
		} else {
			w = EP_WIDTH;
		}
		len0 = len1 = len2 = len3 = FP_BITS + 1;
		bn_rec_naf(naf0, &len0, k0, w);
		bn_rec_naf(naf1, &len1, k1, w);
		bn_rec_naf(naf2, &len2, l0, EP_WIDTH);
		bn_rec_naf(naf3, &len3, l1, EP_WIDTH);

		len = MAX(MAX(len0, len1), MAX(len2, len3));
		t0 = naf0 + len - 1;
		t1 = naf1 + len - 1;
		t2 = naf2 + len - 1;
		t3 = naf3 + len - 1;
		for (i = len0; i < len; i++) {
			naf0[i] = 0;
		}
		for (i = len1; i < len; i++) {
			naf1[i] = 0;
		}
		for (i = len2; i < len; i++) {
			naf2[i] = 0;
		}
		for (i = len3; i < len; i++) {
			naf3[i] = 0;
		}

		ep_set_infty(r);
		for (i = len - 1; i >= 0; i--, t0--, t1--, t2--, t3--) {
			ep_dbl(r, r);

			n = *t0;
			if (n > 0) {
				if (sk0 == BN_POS) {
					ep_add(r, r, t[n / 2]);
				} else {
					ep_sub(r, r, t[n / 2]);
				}
			}
			if (n < 0) {
				if (sk0 == BN_POS) {
					ep_sub(r, r, t[-n / 2]);
				} else {
					ep_add(r, r, t[-n / 2]);
				}
			}
			n = *t1;
			if (n > 0) {
				ep_copy(u, t[n / 2]);
				fp_mul(u->x, u->x, ep_curve_get_beta());
				if (sk1 == BN_NEG) {
					ep_neg(u, u);
				}
				ep_add(r, r, u);
			}
			if (n < 0) {
				ep_copy(u, t[-n / 2]);
				fp_mul(u->x, u->x, ep_curve_get_beta());
				if (sk1 == BN_NEG) {
					ep_neg(u, u);
				}
				ep_sub(r, r, u);
			}

			n = *t2;
			if (n > 0) {
				if (sl0 == BN_POS) {
					ep_add(r, r, tab1[n / 2]);
				} else {
					ep_sub(r, r, tab1[n / 2]);
				}
			}
			if (n < 0) {
				if (sl0 == BN_POS) {
					ep_sub(r, r, tab1[-n / 2]);
				} else {
					ep_add(r, r, tab1[-n / 2]);
				}
			}
			n = *t3;
			if (n > 0) {
				ep_copy(u, tab1[n / 2]);
				fp_mul(u->x, u->x, ep_curve_get_beta());
				if (sl1 == BN_NEG) {
					ep_neg(u, u);
				}
				ep_add(r, r, u);
			}
			if (n < 0) {
				ep_copy(u, tab1[-n / 2]);
				fp_mul(u->x, u->x, ep_curve_get_beta());
				if (sl1 == BN_NEG) {
					ep_neg(u, u);
				}
				ep_sub(r, r, u);
			}
		}
		/* Convert r to affine coordinates. */
		ep_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(ord);
		bn_free(k0);
		bn_free(k1);
		bn_free(l0);
		bn_free(l1);
		ep_free(u);

		if (!g) {
			for (i = 0; i < 1 << (EP_WIDTH - 2); i++) {
				ep_free(tab0[i]);
			}
		}
		/* Free the precomputation tables. */
		for (i = 0; i < 1 << (EP_WIDTH - 2); i++) {
			ep_free(tab1[i]);
		}
		for (i = 0; i < 3; i++) {
			bn_free(v1[i]);
			bn_free(v2[i]);
		}
	}
}
Пример #7
0
static void ep2_mul_sim_plain(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l,
		ep2_t *t) {
	int len, l0, l1, i, n0, n1, w, gen;
	int8_t naf0[2 * FP_BITS + 1], naf1[2 * FP_BITS + 1], *_k, *_m;
	ep2_t t0[1 << (EP_WIDTH - 2)];
	ep2_t t1[1 << (EP_WIDTH - 2)];

	for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
		ep2_null(t0[i]);
		ep2_null(t1[i]);
	}

	TRY {
		gen = (t == NULL ? 0 : 1);
		if (!gen) {
			for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
				ep2_new(t0[i]);
			}
			ep2_tab(t0, p, EP_WIDTH);
			t = (ep2_t *)t0;
		}

		/* Prepare the precomputation table. */
		for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
			ep2_new(t1[i]);
		}
		/* Compute the precomputation table. */
		ep2_tab(t1, q, EP_WIDTH);

		/* Compute the w-TNAF representation of k. */
		if (gen) {
			w = EP_DEPTH;
		} else {
			w = EP_WIDTH;
		}

		l0 = l1 = 2 * FP_BITS + 1;
		bn_rec_naf(naf0, &l0, k, w);
		bn_rec_naf(naf1, &l1, l, EP_WIDTH);

		len = MAX(l0, l1);
		_k = naf0 + len - 1;
		_m = naf1 + len - 1;
		for (i = l0; i < len; i++)
			naf0[i] = 0;
		for (i = l1; i < len; i++)
			naf1[i] = 0;

		ep2_set_infty(r);
		for (i = len - 1; i >= 0; i--, _k--, _m--) {
			ep2_dbl(r, r);

			n0 = *_k;
			n1 = *_m;
			if (n0 > 0) {
				ep2_add(r, r, t[n0 / 2]);
			}
			if (n0 < 0) {
				ep2_sub(r, r, t[-n0 / 2]);
			}
			if (n1 > 0) {
				ep2_add(r, r, t1[n1 / 2]);
			}
			if (n1 < 0) {
				ep2_sub(r, r, t1[-n1 / 2]);
			}
		}
		/* Convert r to affine coordinates. */
		ep2_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		/* Free the precomputation tables. */
		if (!gen) {
			for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
				ep2_free(t0[i]);
			}
		}
		for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
			ep2_free(t1[i]);
		}
	}
}
Пример #8
0
static void ed_mul_naf_imp(ed_t r, const ed_t p, const bn_t k) {
	int l, i, n;
	int8_t naf[RLC_FP_BITS + 1];
	ed_t t[1 << (ED_WIDTH - 2)];

	if (bn_is_zero(k)) {
		ed_set_infty(r);
		return;
	}

	TRY {
		/* Prepare the precomputation table. */
		for (i = 0; i < (1 << (ED_WIDTH - 2)); i++) {
			ed_null(t[i]);
			ed_new(t[i]);
		}
		/* Compute the precomputation table. */
		ed_tab(t, p, ED_WIDTH);

		/* Compute the w-NAF representation of k. */
		l = sizeof(naf);
		bn_rec_naf(naf, &l, k, EP_WIDTH);

		ed_set_infty(r);
		for (i = l - 1; i > 0; i--) {
			n = naf[i];
			if (n == 0) {
				/* This point will be doubled in the previous iteration. */
				r->norm = 2;
				ed_dbl(r, r);
			} else {
				ed_dbl(r, r);
				if (n > 0) {
					ed_add(r, r, t[n / 2]);
				} else if (n < 0) {
					ed_sub(r, r, t[-n / 2]);
				}
			}
		}

		/* Last iteration. */
		n = naf[0];
		ed_dbl(r, r);
		if (n > 0) {
			ed_add(r, r, t[n / 2]);
		} else if (n < 0) {
			ed_sub(r, r, t[-n / 2]);
		}

		/* Convert r to affine coordinates. */
		ed_norm(r, r);
		if (bn_sign(k) == RLC_NEG) {
			ed_neg(r, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		/* Free the precomputation table. */
		for (i = 0; i < (1 << (ED_WIDTH - 2)); i++) {
			ed_free(t[i]);
		}
	}
}
Пример #9
0
static void ep2_mul_sim_ordin(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l, int gen) {
	int len, l0, l1, i, n0, n1, w;
	signed char naf0[FP_BITS + 1], naf1[FP_BITS + 1], *t0, *t1;
	ep2_t table0[1 << (EP_WIDTH - 2)];
	ep2_t table1[1 << (EP_WIDTH - 2)];
	ep2_t *t = NULL;

	for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
		ep2_null(table0[i]);
		ep2_null(table1[i]);
	}

	if (gen) {
#if defined(EP_PRECO)
		t = ep2_curve_get_tab();
#endif
	} else {
		for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
			ep2_new(table0[i]);
		}
		ep2_tab(table0, p, EP_WIDTH);
		t = table0;
	}

	/* Prepare the precomputation table. */
	for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) {
		ep2_new(table1[i]);
	}
	/* Compute the precomputation table. */
	ep2_tab(table1, q, EP_WIDTH);

	/* Compute the w-TNAF representation of k. */
	if (gen) {
		w = EP_DEPTH;
	} else {
		w = EP_WIDTH;
	}

	l0 = l1 = FP_BITS + 1;
	bn_rec_naf(naf0, &l0, k, w);
	bn_rec_naf(naf1, &l1, l, EP_WIDTH);

	len = MAX(l0, l1);
	t0 = naf0 + len - 1;
	t1 = naf1 + len - 1;
	for (i = l0; i < len; i++)
		naf0[i] = 0;
	for (i = l1; i < len; i++)
		naf1[i] = 0;

	ep2_set_infty(r);
	for (i = len - 1; i >= 0; i--, t0--, t1--) {
		ep2_dbl(r, r);

		n0 = *t0;
		n1 = *t1;
		if (n0 > 0) {
			ep2_add(r, r, t[n0 / 2]);
		}
		if (n0 < 0) {
			ep2_sub(r, r, t[-n0 / 2]);
		}
		if (n1 > 0) {
			ep2_add(r, r, table1[n1 / 2]);
		}
		if (n1 < 0) {
			ep2_sub(r, r, table1[-n1 / 2]);
		}
	}
	/* Convert r to affine coordinates. */
	ep2_norm(r, r);

	/* Free the precomputation table. */
	for (i = 0; i < 1 << (EP_WIDTH - 2); i++) {
		ep2_free(table0[i]);
		ep2_free(table1[i]);
	}
}