void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l) {
	ep2_t t[5];
	int u_i, len, offset;
	int8_t jsf[4 * (FP_BITS + 1)];
	int i;

	ep2_null(t[0]);
	ep2_null(t[1]);
	ep2_null(t[2]);
	ep2_null(t[3]);
	ep2_null(t[4]);

	TRY {
		for (i = 0; i < 5; i++) {
			ep2_new(t[i]);
		}

		ep2_set_infty(t[0]);
		ep2_copy(t[1], q);
		ep2_copy(t[2], p);
		ep2_add(t[3], p, q);
		ep2_sub(t[4], p, q);

		len = 4 * (FP_BITS + 1);
		bn_rec_jsf(jsf, &len, k, l);

		ep2_set_infty(r);

		i = bn_bits(k);
		offset = MAX(i, bn_bits(l)) + 1;
		for (i = len - 1; i >= 0; i--) {
			ep2_dbl(r, r);
			if (jsf[i] != 0 && jsf[i] == -jsf[i + offset]) {
				u_i = jsf[i] * 2 + jsf[i + offset];
				if (u_i < 0) {
					ep2_sub(r, r, t[4]);
				} else {
					ep2_add(r, r, t[4]);
				}
			} else {
				u_i = jsf[i] * 2 + jsf[i + offset];
				if (u_i < 0) {
					ep2_sub(r, r, t[-u_i]);
				} else {
					ep2_add(r, r, t[u_i]);
				}
			}
		}
		ep2_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		for (i = 0; i < 5; i++) {
			ep2_free(t[i]);
		}
	}
}
Esempio n. 2
0
/**
 * Multiplies a point on a Barreto-Lynn-Soctt curve by the cofactor.
 *
 * @param[out] r			- the result.
 * @param[in] p				- the point to multiply.
 */
void ep2_mul_cof_b12(ep2_t r, ep2_t p) {
	bn_t x;
	ep2_t t0, t1, t2, t3;

	ep2_null(t0);
	ep2_null(t1);
	ep2_null(t2);
	ep2_null(t3);
	bn_null(x);

	TRY {
		ep2_new(t0);
		ep2_new(t1);
		ep2_new(t2);
		ep2_new(t3);
		bn_new(x);

		fp_param_get_var(x);

		/* Compute t0 = xP. */
		ep2_mul(t0, p, x);
		if (bn_sign(x) == BN_NEG) {
			ep2_neg(t0, t0);
		}
		/* Compute t1 = [x^2]P. */
		ep2_mul(t1, t0, x);
		if (bn_sign(x) == BN_NEG) {
			ep2_neg(t1, t1);
		}

		/* t2 = (x^2 - x - 1)P = x^2P - x*P - P. */
		ep2_sub(t2, t1, t0);
		ep2_sub(t2, t2, p);
		/* t3 = \psi(x - 1)P. */
		ep2_sub(t3, t0, p);
		ep2_norm(t3, t3);
		ep2_frb(t3, t3, 1);
		ep2_add(t2, t2, t3);
		/* t3 = \psi^2(2P). */
		ep2_dbl(t3, p);
		ep2_norm(t3, t3);
		ep2_frb(t3, t3, 2);
		ep2_add(t2, t2, t3);
		ep2_norm(r, t2);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ep2_free(t0);
		ep2_free(t1);
		ep2_free(t2);
		ep2_free(t3);
		bn_free(x);
	}
}
Esempio n. 3
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);
	}
}
Esempio n. 4
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);
	}
}
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]);
		}
	}
}
Esempio n. 6
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]);
	}
}