Exemple #1
0
void fp3_sqrn_low(dv3_t c, fp3_t a) {
	align dig_t t0[2 * FP_DIGS], t1[2 * FP_DIGS], t2[2 * FP_DIGS];
	align dig_t t3[2 * FP_DIGS], t4[2 * FP_DIGS], t5[2 * FP_DIGS];

	/* t0 = a_0^2. */
	fp_sqrn_low(t0, a[0]);

	/* t1 = 2 * a_1 * a_2. */
#ifdef FP_SPACE
	fp_dbln_low(t2, a[1]);
#else
	fp_dblm_low(t2, a[1]);
#endif

	fp_muln_low(t1, t2, a[2]);

	/* t2 = a_2^2. */
	fp_sqrn_low(t2, a[2]);

	/* t3 = (a_0 + a_2 + a_1)^2, t4 = (a_0 + a_2 - a_1)^2. */
#ifdef FP_SPACE
	fp_addn_low(t3, a[0], a[2]);
	fp_addn_low(t4, t3, a[1]);
#else
	fp_addm_low(t3, a[0], a[2]);
	fp_addm_low(t4, t3, a[1]);
#endif
	fp_subm_low(t5, t3, a[1]);
	fp_sqrn_low(t3, t4);
	fp_sqrn_low(t4, t5);

	/* t4 = (t4 + t3)/2. */
	fp_addd_low(t4, t4, t3);
	fp_hlvd_low(t4, t4);

	/* t3 = t3 - t4 - t1. */
	fp_addc_low(t5, t1, t4);
	fp_subc_low(t3, t3, t5);

	/* c_2 = t4 - t0 - t2. */
	fp_addc_low(t5, t0, t2);
	fp_subc_low(c[2], t4, t5);

	/* c_0 = t0 + t1 * B. */
	fp_subc_low(c[0], t0, t1);
	for (int i = -1; i > fp_prime_get_cnr(); i--) {
		fp_subc_low(c[0], c[0], t1);
	}

	/* c_1 = t3 + t2 * B. */
	fp_subc_low(c[1], t3, t2);
	for (int i = -1; i > fp_prime_get_cnr(); i--) {
		fp_subc_low(c[1], c[1], t2);
	}
}
Exemple #2
0
void fp3_muln_low(dv3_t c, fp3_t a, fp3_t b) {
	align dig_t t0[2 * FP_DIGS], t1[2 * FP_DIGS], t2[2 * FP_DIGS], t3[2 * FP_DIGS];
	align dig_t t4[2 * FP_DIGS], t5[2 * FP_DIGS], t6[2 * FP_DIGS];

	/* Karatsuba algorithm. */

	/* t0 = a_0 * b_0, t1 = a_1 * b_1, t2 = a_2 * b_2. */
	fp_muln_low(t0, a[0], b[0]);
	fp_muln_low(t1, a[1], b[1]);
	fp_muln_low(t2, a[2], b[2]);

	/* t3 = (a_1 + a_2) * (b_1 + b_2). */
#ifdef FP_SPACE
	fp_addn_low(t3, a[1], a[2]);
	fp_addn_low(t4, b[1], b[2]);
#else
	fp_addm_low(t3, a[1], a[2]);
	fp_addm_low(t4, b[1], b[2]);
#endif
	fp_muln_low(t5, t3, t4);
	fp_addd_low(t6, t1, t2);
	fp_subc_low(t4, t5, t6);
	fp_subc_low(c[0], t0, t4);
	for (int i = -1; i > fp_prime_get_cnr(); i--) {
		fp_subc_low(c[0], c[0], t4);
	}

#ifdef FP_SPACE
	fp_addn_low(t4, a[0], a[1]);
	fp_addn_low(t5, b[0], b[1]);
#else
	fp_addm_low(t4, a[0], a[1]);
	fp_addm_low(t5, b[0], b[1]);
#endif
	fp_muln_low(t6, t4, t5);
	fp_addd_low(t4, t0, t1);
	fp_subc_low(t4, t6, t4);
	fp_subc_low(c[1], t4, t2);
	for (int i = -1; i > fp_prime_get_cnr(); i--) {
		fp_subc_low(c[1], c[1], t2);
	}

#ifdef FP_SPACE
	fp_addn_low(t5, a[0], a[2]);
	fp_addn_low(t6, b[0], b[2]);
#else
	fp_addm_low(t5, a[0], a[2]);
	fp_addm_low(t6, b[0], b[2]);
#endif
	fp_muln_low(t4, t5, t6);
	fp_addd_low(t6, t0, t2);
	fp_subc_low(t5, t4, t6);
	fp_addc_low(c[2], t5, t1);
}
Exemple #3
0
void fp_prime_calc() {
#ifdef WITH_FPX
	if (fp_prime_get_qnr() != 0) {
		fp2_calc();
	}
	if (fp_prime_get_cnr() != 0) {
		fp3_calc();
	}
#endif
}
void fp3_sqr_basic(fp3_t c, fp3_t a) {
	dv_t t0, t1, t2, t3, t4, t5;

	dv_null(t0);
	dv_null(t1);
	dv_null(t2);
	dv_null(t3);
	dv_null(t4);
	dv_null(t5);

	TRY {
		dv_new(t0);
		dv_new(t1);
		dv_new(t2);
		dv_new(t3);
		dv_new(t4);
		dv_new(t5);

		/* t0 = a_0^2. */
		fp_sqrn_low(t0, a[0]);

		/* t1 = 2 * a_1 * a_2. */
		fp_dbl(t2, a[1]);
		fp_muln_low(t1, t2, a[2]);

		/* t2 = a_2^2. */
		fp_sqrn_low(t2, a[2]);

		/* t3 = (a_0 + a_2 + a_1)^2, t4 = (a_0 + a_2 - a_1)^2. */
		fp_add(t3, a[0], a[2]);
		fp_add(t4, t3, a[1]);
		fp_sub(t5, t3, a[1]);
		fp_sqrn_low(t3, t4);
		fp_sqrn_low(t4, t5);

		/* t4 = (t4 + t3)/2. */
		fp_addd_low(t4, t4, t3);
		fp_hlvd_low(t4, t4);

		/* t3 = t3 - t4 - t1. */
		fp_addc_low(t5, t1, t4);
		fp_subc_low(t3, t3, t5);

		/* c_2 = t4 - t0 - t2. */
		fp_addc_low(t5, t0, t2);
		fp_subc_low(t4, t4, t5);
		fp_rdc(c[2], t4);

		/* c_0 = t0 + t1 * B. */
		fp_subc_low(t0, t0, t1);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_subc_low(t0, t0, t1);
		}
		fp_rdc(c[0], t0);

		/* c_1 = t3 + t2 * B. */
		fp_subc_low(t3, t3, t2);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_subc_low(t3, t3, t2);
		}
		fp_rdc(c[1], t3);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t0);
		dv_free(t1);
		dv_free(t2);
		dv_free(t3);
		dv_free(t4);
		dv_free(t5);
	}
}
Exemple #5
0
/**
 * Computes the constants required for evaluating Frobenius maps.
 */
static void fp3_calc() {
	bn_t e;
	fp3_t t0, t1, t2;
	ctx_t *ctx = core_get();

	bn_null(e);
	fp3_null(t0);
	fp3_null(t1);
	fp3_null(t2);

	TRY {
		bn_new(e);
		fp3_new(t0);
		fp3_new(t1);
		fp3_new(t2);

		fp_set_dig(ctx->fp3_base[0], -fp_prime_get_cnr());
		fp_neg(ctx->fp3_base[0], ctx->fp3_base[0]);
		e->used = FP_DIGS;
		dv_copy(e->dp, fp_prime_get(), FP_DIGS);
		bn_sub_dig(e, e, 1);
		bn_div_dig(e, e, 3);
		fp_exp(ctx->fp3_base[0], ctx->fp3_base[0], e);
		fp_sqr(ctx->fp3_base[1], ctx->fp3_base[0]);

		fp3_zero(t0);
		fp_set_dig(t0[1], 1);
		dv_copy(e->dp, fp_prime_get(), FP_DIGS);
		bn_sub_dig(e, e, 1);
		bn_div_dig(e, e, 6);

		/* t0 = u^((p-1)/6). */
		fp3_exp(t0, t0, e);
		fp_copy(ctx->fp3_p[0], t0[2]);
		fp3_sqr(t1, t0);
		fp_copy(ctx->fp3_p[1], t1[1]);
		fp3_mul(t2, t1, t0);
		fp_copy(ctx->fp3_p[2], t2[0]);
		fp3_sqr(t2, t1);
		fp_copy(ctx->fp3_p[3], t2[2]);
		fp3_mul(t2, t2, t0);
		fp_copy(ctx->fp3_p[4], t2[1]);

		fp_mul(ctx->fp3_p2[0], ctx->fp3_p[0], ctx->fp3_base[1]);
		fp_mul(t0[0], ctx->fp3_p2[0], ctx->fp3_p[0]);
		fp_neg(ctx->fp3_p2[0], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p2[0], ctx->fp3_p2[0], t0[0]);
		}
		fp_mul(ctx->fp3_p2[1], ctx->fp3_p[1], ctx->fp3_base[0]);
		fp_mul(ctx->fp3_p2[1], ctx->fp3_p2[1], ctx->fp3_p[1]);
		fp_sqr(ctx->fp3_p2[2], ctx->fp3_p[2]);
		fp_mul(ctx->fp3_p2[3], ctx->fp3_p[3], ctx->fp3_base[1]);
		fp_mul(t0[0], ctx->fp3_p2[3], ctx->fp3_p[3]);
		fp_neg(ctx->fp3_p2[3], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p2[3], ctx->fp3_p2[3], t0[0]);
		}
		fp_mul(ctx->fp3_p2[4], ctx->fp3_p[4], ctx->fp3_base[0]);
		fp_mul(ctx->fp3_p2[4], ctx->fp3_p2[4], ctx->fp3_p[4]);

		fp_mul(ctx->fp3_p3[0], ctx->fp3_p[0], ctx->fp3_base[0]);
		fp_mul(t0[0], ctx->fp3_p3[0], ctx->fp3_p2[0]);
		fp_neg(ctx->fp3_p3[0], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p3[0], ctx->fp3_p3[0], t0[0]);
		}
		fp_mul(ctx->fp3_p3[1], ctx->fp3_p[1], ctx->fp3_base[1]);
		fp_mul(t0[0], ctx->fp3_p3[1], ctx->fp3_p2[1]);
		fp_neg(ctx->fp3_p3[1], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p3[1], ctx->fp3_p3[1], t0[0]);
		}
		fp_mul(ctx->fp3_p3[2], ctx->fp3_p[2], ctx->fp3_p2[2]);
		fp_mul(ctx->fp3_p3[3], ctx->fp3_p[3], ctx->fp3_base[0]);
		fp_mul(t0[0], ctx->fp3_p3[3], ctx->fp3_p2[3]);
		fp_neg(ctx->fp3_p3[3], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p3[3], ctx->fp3_p3[3], t0[0]);
		}
		fp_mul(ctx->fp3_p3[4], ctx->fp3_p[4], ctx->fp3_base[1]);
		fp_mul(t0[0], ctx->fp3_p3[4], ctx->fp3_p2[4]);
		fp_neg(ctx->fp3_p3[4], t0[0]);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(ctx->fp3_p3[4], ctx->fp3_p3[4], t0[0]);
		}
		for (int i = 0; i < 5; i++) {
			fp_mul(ctx->fp3_p4[i], ctx->fp3_p[i], ctx->fp3_p3[i]);
			fp_mul(ctx->fp3_p5[i], ctx->fp3_p2[i], ctx->fp3_p3[i]);
		}
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		bn_free(e);
		fp3_free(t0);
		fp3_free(t1);
		fp3_free(t2);
	}
}
Exemple #6
0
void fp3_mul_basic(fp3_t c, fp3_t a, fp3_t b) {
	dv_t t, t0, t1, t2, t3, t4, t5, t6;

	dv_null(t);
	dv_null(t0);
	dv_null(t1);
	dv_null(t2);
	dv_null(t3);
	dv_null(t4);
	dv_null(t5);
	dv_null(t6);

	TRY {
		dv_new(t);
		dv_new(t0);
		dv_new(t1);
		dv_new(t2);
		dv_new(t3);
		dv_new(t4);
		dv_new(t5);
		dv_new(t6);

		/* Karatsuba algorithm. */

		/* t0 = a_0 * b_0, t1 = a_1 * b_1, t2 = a_2 * b_2. */
		fp_muln_low(t0, a[0], b[0]);
		fp_muln_low(t1, a[1], b[1]);
		fp_muln_low(t2, a[2], b[2]);

		/* t3 = (a_1 + a_2) * (b_1 + b_2). */
		fp_add(t3, a[1], a[2]);
		fp_add(t4, b[1], b[2]);
		fp_muln_low(t, t3, t4);
		fp_addd_low(t6, t1, t2);
		fp_subc_low(t4, t, t6);
		fp_subc_low(t3, t0, t4);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_subc_low(t3, t3, t4);
		}

		fp_add(t4, a[0], a[1]);
		fp_add(t5, b[0], b[1]);
		fp_muln_low(t, t4, t5);
		fp_addd_low(t4, t0, t1);
		fp_subc_low(t4, t, t4);
		fp_subc_low(t4, t4, t2);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_subc_low(t4, t4, t2);
		}

		fp_add(t5, a[0], a[2]);
		fp_add(t6, b[0], b[2]);
		fp_muln_low(t, t5, t6);
		fp_addd_low(t6, t0, t2);
		fp_subc_low(t5, t, t6);
		fp_addc_low(t5, t5, t1);

		/* c_0 = t3 mod p. */
		fp_rdc(c[0], t3);

		/* c_1 = t4 mod p. */
		fp_rdc(c[1], t4);

		/* c_2 = t5 mod p. */
		fp_rdc(c[2], t5);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
		dv_free(t0);
		dv_free(t1);
		dv_free(t2);
		dv_free(t3);
		dv_free(t4);
		dv_free(t5);
		dv_free(t6);
	}
}
Exemple #7
0
void fp3_inv(fp3_t c, fp3_t a) {
	fp_t v0;
	fp_t v1;
	fp_t v2;
	fp_t t0;

	fp_null(v0);
	fp_null(v1);
	fp_null(v2);
	fp_null(t0);

	TRY {
		fp_new(v0);
		fp_new(v1);
		fp_new(v2);
		fp_new(t0);

		/* v0 = a_0^2 - B * a_1 * a_2. */
		fp_sqr(t0, a[0]);
		fp_mul(v0, a[1], a[2]);
		fp_neg(v2, v0);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(v2, v2, v0);
		}
		fp_sub(v0, t0, v2);

		/* v1 = B * a_2^2 - a_0 * a_1. */
		fp_sqr(t0, a[2]);
		fp_neg(v2, t0);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(v2, v2, t0);
		}
		fp_mul(v1, a[0], a[1]);
		fp_sub(v1, v2, v1);

		/* v2 = a_1^2 - a_0 * a_2. */
		fp_sqr(t0, a[1]);
		fp_mul(v2, a[0], a[2]);
		fp_sub(v2, t0, v2);

		fp_mul(t0, a[1], v2);
		fp_neg(c[1], t0);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(c[1], c[1], t0);
		}

		fp_mul(c[0], a[0], v0);

		fp_mul(t0, a[2], v1);
		fp_neg(c[2], t0);
		for (int i = -1; i > fp_prime_get_cnr(); i--) {
			fp_sub(c[2], c[2], t0);
		}

		fp_add(t0, c[0], c[1]);
		fp_add(t0, t0, c[2]);
		fp_inv(t0, t0);

		fp_mul(c[0], v0, t0);
		fp_mul(c[1], v1, t0);
		fp_mul(c[2], v2, t0);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		fp_free(v0);
		fp_free(v1);
		fp_free(v2);
		fp_free(t0);
	}
}