Example #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);
}
Example #2
0
void ed_mul_fix_nafwi(ed_t r, const ed_t *t, const bn_t k) {
	int i, j, l, d, m;
	ed_t a;
	int8_t naf[FP_BITS + 1];
	char w;

	ed_null(a);

	TRY {
		ed_new(a);

		ed_set_infty(r);
		ed_set_infty(a);

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

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

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

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

		for (j = m; j >= 1; j--) {
			for (i = 0; i < d; i++) {
				if (naf[i] == j) {
					ed_add(a, a, t[i]);
				}
				if (naf[i] == -j) {
					ed_sub(a, a, t[i]);
				}
			}
			ed_add(r, r, a);
		}
		ed_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ed_free(a);
	}
}
Example #3
0
static void ed_mul_reg_imp(ed_t r, const ed_t p, const bn_t k) {
	int l, i, j, n;
	int8_t reg[RLC_CEIL(RLC_FP_BITS + 1, ED_WIDTH - 1)], *_k;
	ed_t t[1 << (ED_WIDTH - 2)];

	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 = RLC_CEIL(RLC_FP_BITS + 1, ED_WIDTH - 1);
		bn_rec_reg(reg, &l, k, RLC_FP_BITS, ED_WIDTH);

		_k = reg + l - 1;

		ed_set_infty(r);
		for (i = l - 1; i >= 0; i--, _k--) {
			for (j = 0; j < ED_WIDTH - 1; j++) {
				r->norm = 2;
				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);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		/* Free the precomputation table. */
		for (i = 0; i < (1 << (ED_WIDTH - 2)); i++) {
			ed_free(t[i]);
		}
	}
}
Example #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);
}
Example #5
0
/**
 * Multiplies a prime elliptic curve point by an integer using the COMBS
 * method.
 *
 * @param[out] r 				- the result.
 * @param[in] t					- the precomputed table.
 * @param[in] k					- the integer.
 */
static void ed_mul_combs_endom(ed_t r, const ed_t *t, const bn_t k) {
	int i, j, l, w0, w1, n0, n1, p0, p1, s0, s1;
	bn_t n, k0, k1, v1[3], v2[3];
	ed_t u;

	bn_null(n);
	bn_null(k0);
	bn_null(k1);
	ed_null(u);

	TRY {
		bn_new(n);
		bn_new(k0);
		bn_new(k1);
		ed_new(u);
		for (i = 0; i < 3; i++) {
			bn_null(v1[i]);
			bn_null(v2[i]);
			bn_new(v1[i]);
			bn_new(v2[i]);
		}

		ed_curve_get_ord(n);
		ed_curve_get_v1(v1);
		ed_curve_get_v2(v2);
		l = bn_bits(n);
		l = ((l % (2 * ED_DEPTH)) ==
				0 ? (l / (2 * ED_DEPTH)) : (l / (2 * ED_DEPTH)) + 1);

		bn_rec_glv(k0, k1, k, n, (const bn_t *)v1, (const bn_t *)v2);
		s0 = bn_sign(k0);
		s1 = bn_sign(k1);
		bn_abs(k0, k0);
		bn_abs(k1, k1);

		n0 = bn_bits(k0);
		n1 = bn_bits(k1);

		p0 = (ED_DEPTH) * l - 1;

		ed_set_infty(r);

		for (i = l - 1; i >= 0; i--) {
			ed_dbl(r, r);

			w0 = 0;
			w1 = 0;
			p1 = p0--;
			for (j = ED_DEPTH - 1; j >= 0; j--, p1 -= l) {
				w0 = w0 << 1;
				w1 = w1 << 1;
				if (p1 < n0 && bn_get_bit(k0, p1)) {
					w0 = w0 | 1;
				}
				if (p1 < n1 && bn_get_bit(k1, p1)) {
					w1 = w1 | 1;
				}
			}
			if (w0 > 0) {
				if (s0 == BN_POS) {
					ed_add(r, r, t[w0]);
				} else {
					ed_sub(r, r, t[w0]);
				}
			}
			if (w1 > 0) {
				ed_copy(u, t[w1]);
				fp_mul(u->x, u->x, ed_curve_get_beta());
				if (s1 == BN_NEG) {
					ed_neg(u, u);
				}
				ed_add(r, r, u);
			}
		}
		ed_norm(r, r);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
		bn_free(k0);
		bn_free(k1);
		ed_free(u);
		for (i = 0; i < 3; i++) {
			bn_free(v1[i]);
			bn_free(v2[i]);
		}
	}
}
Example #6
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]);
		}
	}
}