Esempio n. 1
0
void ep_curve_set_endom(const fp_t b, const ep_t g, const bn_t r, const bn_t h,
		const fp_t beta, const bn_t l) {
	int bits = bn_bits(r);
	ctx_t *ctx = core_get();
	ctx->ep_is_endom = 1;
	ctx->ep_is_super = 0;

	fp_zero(ctx->ep_a);
	fp_copy(ctx->ep_b, b);

	detect_opt(&(ctx->ep_opt_a), ctx->ep_a);
	detect_opt(&(ctx->ep_opt_b), ctx->ep_b);

#if EP_MUL == LWNAF || EP_FIX == COMBS || EP_FIX == LWNAF || EP_SIM == INTER || !defined(STRIP)
	fp_copy(ctx->beta, beta);
	bn_gcd_ext_mid(&(ctx->ep_v1[1]), &(ctx->ep_v1[2]), &(ctx->ep_v2[1]),
			&(ctx->ep_v2[2]), l, r);
	/* l = v1[1] * v2[2] - v1[2] * v2[1], r = l / 2. */
	bn_mul(&(ctx->ep_v1[0]), &(ctx->ep_v1[1]), &(ctx->ep_v2[2]));
	bn_mul(&(ctx->ep_v2[0]), &(ctx->ep_v1[2]), &(ctx->ep_v2[1]));
	bn_sub(&(ctx->ep_r), &(ctx->ep_v1[0]), &(ctx->ep_v2[0]));
	bn_hlv(&(ctx->ep_r), &(ctx->ep_r));
	/* v1[0] = round(v2[2] * 2^|n| / l). */
	bn_lsh(&(ctx->ep_v1[0]), &(ctx->ep_v2[2]), bits + 1);
	if (bn_sign(&(ctx->ep_v1[0])) == BN_POS) {
		bn_add(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r));
	} else {
		bn_sub(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r));
	}
	bn_dbl(&(ctx->ep_r), &(ctx->ep_r));
	bn_div(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r));
	if (bn_sign(&ctx->ep_v1[0]) == BN_NEG) {
		bn_add_dig(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), 1);
	}
	/* v2[0] = round(v1[2] * 2^|n| / l). */
	bn_lsh(&(ctx->ep_v2[0]), &(ctx->ep_v1[2]), bits + 1);
	if (bn_sign(&(ctx->ep_v2[0])) == BN_POS) {
		bn_add(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r));
	} else {
		bn_sub(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r));
	}
	bn_div(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r));
	if (bn_sign(&ctx->ep_v2[0]) == BN_NEG) {
		bn_add_dig(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), 1);
	}
	bn_neg(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]));
#endif

	ep_norm(&(ctx->ep_g), g);
	bn_copy(&(ctx->ep_r), r);
	bn_copy(&(ctx->ep_h), h);

#if defined(EP_PRECO)
	ep_mul_pre((ep_t *)ep_curve_get_tab(), &(ctx->ep_g));
#endif
}
Esempio n. 2
0
void ep2_curve_get_vs(bn_t *v) {
	bn_t x, t;

	bn_null(x);
	bn_null(t);

	TRY {
		bn_new(x);
		bn_new(t);

		fp_param_get_var(x);

		bn_mul_dig(v[0], x, 3);
		bn_add_dig(v[0], v[0], 1);

		bn_copy(v[1], x);
		bn_copy(v[2], x);
		bn_copy(v[3], x);

		bn_sqr(x, x);
		bn_lsh(t, x, 1);
		bn_add(v[0], v[0], t);
		bn_add(v[3], v[3], t);
		bn_lsh(t, t, 1);
		bn_add(v[2], v[2], t);
		bn_lsh(t, t, 1);
		bn_add(v[1], v[1], t);

		fp_param_get_var(t);
		bn_mul(x, x, t);
		bn_mul_dig(t, x, 6);
		bn_add(v[2], v[2], t);
		bn_lsh(t, t, 1);
		bn_add(v[1], v[1], t);
		bn_neg(v[3], v[3]);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		bn_free(x);
		bn_free(t);
	}
}
Esempio n. 3
0
status_t element_neg(element_t c, element_t a)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(a, c);

	if(type == ZR) {
		bn_neg(c->bn, a->bn);
	}
	else if(type == G1) {
		g1_neg(c->g1, a->g1);
	}
	else if(type == G2) {
		g2_neg(c->g2, a->g2);
	}
	else if(type == GT) {
		gt_inv(c->gt, a->gt);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}
	return ELEMENT_OK;
}
Esempio n. 4
0
/**
 * Precomputes additional parameters for Koblitz curves used by the w-TNAF
 * multiplication algorithm.
 */
static void compute_kbltz(void) {
	int u, i;
	bn_t a, b, c;

	bn_null(a);
	bn_null(b);
	bn_null(c);

	TRY {
		bn_new(a);
		bn_new(b);
		bn_new(c);

		if (curve_opt_a == OPT_ZERO) {
			u = -1;
		} else {
			u = 1;
		}

		bn_set_dig(a, 2);
		bn_set_dig(b, 1);
		if (u == -1) {
			bn_neg(b, b);
		}
		for (i = 2; i <= FB_BITS; i++) {
			bn_copy(c, b);
			if (u == -1) {
				bn_neg(b, b);
			}
			bn_dbl(a, a);
			bn_sub(b, b, a);
			bn_copy(a, c);
		}
		bn_copy(&curve_vm, b);

		bn_zero(a);
		bn_set_dig(b, 1);
		for (i = 2; i <= FB_BITS; i++) {
			bn_copy(c, b);
			if (u == -1) {
				bn_neg(b, b);
			}
			bn_dbl(a, a);
			bn_sub(b, b, a);
			bn_add_dig(b, b, 1);
			bn_copy(a, c);
		}
		bn_copy(&curve_s0, b);

		bn_zero(a);
		bn_zero(b);
		for (i = 2; i <= FB_BITS; i++) {
			bn_copy(c, b);
			if (u == -1) {
				bn_neg(b, b);
			}
			bn_dbl(a, a);
			bn_sub(b, b, a);
			bn_sub_dig(b, b, 1);
			bn_copy(a, c);
		}
		bn_copy(&curve_s1, b);

	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(a);
		bn_free(b);
		bn_free(c);
	}
}
Esempio n. 5
0
/**
 * Divides two multiple precision integers, computing the quotient and the
 * remainder.
 *
 * @param[out] c		- the quotient.
 * @param[out] d		- the remainder.
 * @param[in] a			- the dividend.
 * @param[in] b			- the the divisor.
 */
static void bn_div_imp(bn_t c, bn_t d, const bn_t a, const bn_t b) {
	bn_t q, x, y, r;
	int sign;

	bn_null(q);
	bn_null(x);
	bn_null(y);
	bn_null(r);

	/* If a < b, we're done. */
	if (bn_cmp_abs(a, b) == CMP_LT) {
		if (bn_sign(a) == BN_POS) {
			if (c != NULL) {
				bn_zero(c);
			}
			if (d != NULL) {
				bn_copy(d, a);
			}
		} else {
			if (c != NULL) {
				bn_set_dig(c, 1);
				if (bn_sign(b) == BN_POS) {
					bn_neg(c, c);
				}
			}
			if (d != NULL) {
				if (bn_sign(b) == BN_POS) {
					bn_add(d, a, b);	
				} else {
					bn_sub(d, a, b);
				}
			}
		}
		return;
	}

	TRY {
		bn_new(x);
		bn_new(y);
		bn_new_size(q, a->used + 1);
		bn_new(r);
		bn_zero(q);
		bn_zero(r);
		bn_abs(x, a);
		bn_abs(y, b);

		/* Find the sign. */
		sign = (a->sign == b->sign ? BN_POS : BN_NEG);

		bn_divn_low(q->dp, r->dp, x->dp, a->used, y->dp, b->used);

		/* We have the quotient in q and the remainder in r. */
		if (c != NULL) {
			q->used = a->used - b->used + 1;
			q->sign = sign;
			bn_trim(q);
			if (bn_sign(a) == BN_NEG) {
				bn_sub_dig(c, q, 1);
			} else {
				bn_copy(c, q);
			}
		}

		if (d != NULL) {
			r->used = b->used;
			r->sign = a->sign;
			bn_trim(r);
			if (bn_sign(a) == BN_NEG) {
				bn_add(d, r, b);
			} else {
				bn_copy(d, r);
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(r);
		bn_free(q);
		bn_free(x);
		bn_free(y);
	}
}
Esempio n. 6
0
void fp_param_get_var(bn_t x) {
	bn_t a;

	bn_null(a);

	TRY {
		bn_new(a);

		switch (fp_param_get()) {
			case BN_158:
				/* x = 4000000031. */
				bn_set_2b(x, 38);
				bn_add_dig(x, x, 0x31);
				break;
			case BN_254:
				/* x = -4080000000000001. */
				bn_set_2b(x, 62);
				bn_set_2b(a, 55);
				bn_add(x, x, a);
				bn_add_dig(x, x, 1);
				bn_neg(x, x);
				break;
			case BN_256:
				/* x = -600000000000219B. */
				bn_set_2b(x, 62);
				bn_set_2b(a, 61);
				bn_add(x, x, a);
				bn_set_dig(a, 0x21);
				bn_lsh(a, a, 8);
				bn_add(x, x, a);
				bn_add_dig(x, x, 0x9B);
				bn_neg(x, x);
				break;
			case B24_477:
				/* x = -2^48 + 2^45 + 2^31 - 2^7. */
				bn_set_2b(x, 48);
				bn_set_2b(a, 45);
				bn_sub(x, x, a);
				bn_set_2b(a, 31);
				bn_sub(x, x, a);
				bn_set_2b(a, 7);
				bn_add(x, x, a);
				bn_neg(x, x);
				break;
			case KSS_508:
				/* x = -(2^64 + 2^51 - 2^46 - 2^12). */
				bn_set_2b(x, 64);
				bn_set_2b(a, 51);
				bn_add(x, x, a);
				bn_set_2b(a, 46);
				bn_sub(x, x, a);
				bn_set_2b(a, 12);
				bn_sub(x, x, a);
				bn_neg(x, x);
				break;
			case BN_638:
				/* x = 2^158 - 2^128 - 2^68 + 1. */
				bn_set_2b(x, 158);
				bn_set_2b(a, 128);
				bn_sub(x, x, a);
				bn_set_2b(a, 68);
				bn_sub(x, x, a);
				bn_add_dig(x, x, 1);
				break;
			case B12_638:
				/* x = -2^107 + 2^105 + 2^93 + 2^5. */
				bn_set_2b(x, 107);
				bn_set_2b(a, 105);
				bn_sub(x, x, a);
				bn_set_2b(a, 93);
				bn_sub(x, x, a);
				bn_set_2b(a, 5);
				bn_sub(x, x, a);
				bn_neg(x, x);
				break;
			case SS_1536:
				/* x = 2^255 + 2^41 + 1. */
				bn_set_2b(x, 255);
				bn_set_2b(a, 41);
				bn_add(x, x, a);
				bn_add_dig(x, x, 1);
				break;
			default:
				THROW(ERR_NO_VALID);
				break;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(a);
	}
}
Esempio n. 7
0
void fp_param_get_sps(int *s, int *len) {
	bn_t a;

	bn_null(a);

	if (*len < MAX_TERMS) {
		THROW(ERR_NO_BUFFER);
	}

	TRY {
		bn_new(a);

		*len = 0;

		switch (fp_param_get()) {
			case BN_158:
			case BN_254:
			case BN_256:
				fp_param_get_var(a);
				if (bn_sign(a) == BN_NEG) {
					bn_neg(a, a);
				}
				*len = bn_ham(a);
				for (int i = 0, j = 0; j < bn_bits(a); j++) {
					if (bn_test_bit(a, j)) {
						s[i++] = j;
					}
				}
				break;
			case B24_477:
				s[0] = 7;
				s[1] = -31;
				s[2] = -45;
				s[3] = 48;
				*len = 4;
				break;
			case KSS_508:
				s[0] = -12;
				s[1] = -46;
				s[2] = 51;
				s[3] = 64;
				*len = 4;
				break;
			case BN_638:
				s[0] = 0;
				s[1] = -68;
				s[2] = -128;
				s[3] = 158;
				*len = 4;
				break;
			case B12_638:
				s[0] = -5;
				s[1] = -93;
				s[2] = -105;
				s[3] = 107;
				*len = 4;
				break;
			case SS_1536:
				s[0] = 0;
				s[1] = 41;
				s[2] = 255;
				*len = 3;
				break;
			default:
				THROW(ERR_NO_VALID);
				break;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(a);
	}
}