void ep2_curve_clean(void) {
	ctx_t *ctx = core_get();
#ifdef EP_PRECO
	for (int i = 0; i < EP_TABLE; i++) {
		fp2_free(ctx->ep2_pre[i].x);
		fp2_free(ctx->ep2_pre[i].y);
		fp2_free(ctx->ep2_pre[i].z);
	}
#endif
	bn_clean(&(ctx->ep2_r));
	bn_clean(&(ctx->ep2_h));
}
Example #2
0
void bench_compute(int benches) {
	ctx_t *ctx = core_get();
#if TIMER != NONE
	ctx->total = ctx->total / benches;
#ifdef OVERH
	ctx->total = ctx->total - ctx->over;
#endif /* OVERH */
#else
	(void)benches;
	(void)ctx;
#endif /* TIMER != NONE */
}
Example #3
0
/**
 * Find non-zero bits for fast trace computation.
 *
 * @throw ERR_NO_MEMORY if there is no available memory.
 * @throw ERR_NO_VALID if the polynomial is invalid.
 */
static void find_trace() {
	fb_t t0, t1;
	int counter;
	ctx_t *ctx = core_get();

	fb_null(t0);
	fb_null(t1);

	ctx->fb_ta = ctx->fb_tb = ctx->fb_tc = -1;

	TRY {
		fb_new(t0);
		fb_new(t1);

		counter = 0;
		for (int i = 0; i < FB_BITS; i++) {
			fb_zero(t0);
			fb_set_bit(t0, i, 1);
			fb_copy(t1, t0);
			for (int j = 1; j < FB_BITS; j++) {
				fb_sqr(t1, t1);
				fb_add(t0, t0, t1);
			}
			if (!fb_is_zero(t0)) {
				switch (counter) {
					case 0:
						ctx->fb_ta = i;
						ctx->fb_tb = ctx->fb_tc = -1;
						break;
					case 1:
						ctx->fb_tb = i;
						ctx->fb_tc = -1;
						break;
					case 2:
						ctx->fb_tc = i;
						break;
					default:
						THROW(ERR_NO_VALID);
						break;
				}
				counter++;
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fb_free(t0);
		fb_free(t1);
	}
}
Example #4
0
void fp_prime_clean() {
	ctx_t *ctx = core_get();
	ctx->fp_id = 0;
#if FP_RDC == QUICK || !defined(STRIP)	
	ctx->sps_len = 0;
	memset(ctx->sps, 0, sizeof(ctx->sps));
#endif
#if FP_RDC == MONTY || !defined(STRIP)
	bn_clean(&(ctx->one));
	bn_clean(&(ctx->conv));
#endif
	bn_clean(&(ctx->prime));
}
Example #5
0
const dig_t *fb_poly_tab_srz(int i) {
#if FB_SRT == QUICK || !defined(STRIP)

#ifdef FB_PRECO
	return core_get()->fb_tab_srz[i];
#else
	return NULL;
#endif

#else
	return NULL;
#endif
}
Example #6
0
int ed_affine_is_valid(const fp_t x, const fp_t y) {
	fp_t tmpFP0;
	fp_t tmpFP1;
	fp_t tmpFP2;

	fp_null(tmpFP0);
	fp_null(tmpFP1);
	fp_null(tmpFP2);

	int r = 0;

	TRY {
		fp_new(tmpFP0);
		fp_new(tmpFP1);
		fp_new(tmpFP2);

		// a * X^2 + Y^2 - 1 - d * X^2 * Y^2 =?= 0
		fp_sqr(tmpFP0, x);
		fp_mul(tmpFP0, core_get()->ed_a, tmpFP0);
		fp_sqr(tmpFP1, y);
		fp_add(tmpFP1, tmpFP0, tmpFP1);
		fp_sub_dig(tmpFP1, tmpFP1, 1);
		fp_sqr(tmpFP0, x);
		fp_mul(tmpFP0, core_get()->ed_d, tmpFP0);
		fp_sqr(tmpFP2, y);
		fp_mul(tmpFP2, tmpFP0, tmpFP2);
		fp_sub(tmpFP0, tmpFP1, tmpFP2);

		r = fp_is_zero(tmpFP0);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		fp_free(tmpFP0);
		fp_free(tmpFP1);
		fp_free(tmpFP2);
	}
	return r;
}
Example #7
0
void rand_seed(uint8_t *buf, int size) {
	int i;
	ctx_t *ctx = core_get();

	if (size < MD_LEN_SHONE) {
		THROW(ERR_NO_VALID);
	}

	/* XKEY = SEED, throws away additional bytes. */
	for (i = 0; i < MD_LEN_SHONE; i++) {
		ctx->rand[i] = buf[i];
	}
	ctx->seeded = 1;
}
const int *fp_prime_get_sps(int *len) {
	ctx_t *ctx = core_get();
	if (ctx->sps_len > 0 && ctx->sps_len < MAX_TERMS) {
		if (len != NULL) {
			*len = ctx->sps_len;
		}
		return ctx->sps;
	} else {
		if (len != NULL) {
			*len = 0;
		}
		return NULL;
	}
}
Example #9
0
void fp_prime_set_pmers(const int *f, int len) {
	bn_t p, t;

	bn_null(p);
	bn_null(t);

	TRY {
		bn_new(p);
		bn_new(t);

		if (len >= MAX_TERMS) {
			THROW(ERR_NO_VALID);
		}

		bn_set_2b(p, f[len - 1]);
		for (int i = len - 2; i > 0; i--) {
			if (f[i] > 0) {
				bn_set_2b(t, f[i]);
				bn_add(p, p, t);
			} else {
				bn_set_2b(t, -f[i]);
				bn_sub(p, p, t);
			}
		}
		if (f[0] > 0) {
			bn_add_dig(p, p, f[0]);
		} else {
			bn_sub_dig(p, p, -f[0]);
		}

#if FP_RDC == QUICK || !defined(STRIP)
		ctx_t *ctx = core_get();
		for (int i = 0; i < len; i++) {
			ctx->sps[i] = f[i];
		}
		ctx->sps[len] = 0;
		ctx->sps_len = len;
#endif /* FP_RDC == QUICK */

		fp_prime_set(p);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(p);
		bn_free(t);
	}
}
Example #10
0
/**
 * Precomputes the square root of z.
 */
static void find_srz() {
	ctx_t *ctx = core_get();

	fb_set_dig(ctx->fb_srz, 2);

	for (int i = 1; i < FB_BITS; i++) {
		fb_sqr(ctx->fb_srz, ctx->fb_srz);
	}

#ifdef FB_PRECO
	for (int i = 0; i <= 255; i++) {
		fb_mul_dig(ctx->fb_tab_srz[i], ctx->fb_srz, i);
	}
#endif
}
void ep2_curve_set(fp2_t a, fp2_t b, ep2_t g, bn_t r, bn_t h) {
	ctx_t *ctx = core_get();
	ctx->ep2_is_twist = 0;

	fp2_copy(ctx->ep2_a, a);
	fp2_copy(ctx->ep2_b, b);

	ep2_norm(&(ctx->ep2_g), g);
	bn_copy(&(ctx->ep2_r), r);
	bn_copy(&(ctx->ep2_h), h);

#if defined(EP_PRECO)
	ep2_mul_pre((ep2_t *)ep2_curve_get_tab(), &(ctx->ep2_g));
#endif
}
Example #12
0
/**
 * Configures the irreducible polynomial of the binary field.
 *
 * @param[in] f				- the new irreducible polynomial.
 */
static void fb_poly_set(const fb_t f) {
	fb_copy(core_get()->fb_poly, f);
#if FB_TRC == QUICK || !defined(STRIP)
	find_trace();
#endif
#if FB_SLV == QUICK || !defined(STRIP)
	find_solve();
#endif
#if FB_SRT == QUICK || !defined(STRIP)
	find_srz();
#endif
#if FB_INV == ITOHT || !defined(STRIP)
	find_chain();
#endif
}
Example #13
0
void bench_print(void) {
	ctx_t *ctx = core_get();

#if TIMER == POSIX || TIMER == ANSI || (OPSYS == DUINO && TIMER == HREAL)
	util_print("%lld microsec", ctx->total);
#elif TIMER == CYCLE
	util_print("%lld cycles", ctx->total);
#else
	util_print("%lld nanosec", ctx->total);
#endif
	if (ctx->total < 0) {
		util_print(" (overflow or bad overhead estimation)\n");
	} else {
		util_print("\n");
	}
}
Example #14
0
void bench_overhead(void) {
	ctx_t *ctx = core_get();
	int a[BENCH + 1];
	int *tmpa;

	do {
		ctx->over = 0;
		for (int l = 0; l < BENCH; l++) {
			ctx->total = 0;
			/* Measure the cost of (n^2 + over). */
			bench_before();
			for (int i = 0; i < BENCH; i++) {
				tmpa = a;
				for (int j = 0; j < BENCH; j++) {
					empty(tmpa++);
				}
			}
			bench_after();
			/* Add the cost of (n^2 + over). */
			ctx->over += ctx->total;
		}
		/* Overhead stores the cost of n*(n^2 + over) = n^3 + n*over. */
		ctx->total = 0;
		/* Measure the cost of (n^3 + over). */
		bench_before();
		for (int i = 0; i < BENCH; i++) {
			for (int k = 0; k < BENCH; k++) {
				tmpa = a;
				for (int j = 0; j < BENCH; j++) {
					empty(tmpa++);
				}
			}
		}
		bench_after();
		/* Subtract the cost of (n^3 + over). */
		ctx->over -= ctx->total;
		/* Now overhead stores (n - 1)*over, so take the average to obtain the
		 * overhead to execute BENCH operations inside a benchmark. */
		ctx->over /= (BENCH - 1);
		/* Divide to obtain the overhead of one operation pair. */
		ctx->over /= BENCH;
	} while (ctx->over < 0);
	ctx->total = ctx->over;
	bench_print();
}
Example #15
0
const int *fp_prime_get_sps(int *len) {
#if FP_RDC == QUICK || !defined(STRIP)
	ctx_t *ctx = core_get();
	if (ctx->sps_len > 0 && ctx->sps_len < MAX_TERMS) {
		if (len != NULL) {
			*len = ctx->sps_len;
		}
		return ctx->sps;
	} else {
		if (len != NULL) {
			*len = 0;
		}
		return NULL;
	}
#else
	return NULL;
#endif
}
Example #16
0
/**
 * Generates pseudo-random bytes by iterating the hash function.
 *
 * @param[out] out 			- the buffer to write.
 * @param[in] out_len		- the number of bytes to write.
 */
static void rand_gen(uint8_t *out, int out_len) {
	int m = CEIL(out_len, MD_LEN);
	uint8_t hash[MD_LEN], data[(RAND_SIZE - 1)/2];
	ctx_t *ctx = core_get();

	/* data = V */
	memcpy(data, ctx->rand + 1, (RAND_SIZE - 1)/2);
	for (int i = 0; i < m; i++) {
		/* w_i = Hash(data) */
		md_map(hash, data, sizeof(data));
		/* W = W || w_i */
		memcpy(out, hash, MIN(MD_LEN, out_len));
		out += MD_LEN;
		out_len -= MD_LEN;
		/* data = data + 1 mod 2^b. */
		rand_inc(data, (RAND_SIZE - 1)/2, 1);
	}
}
Example #17
0
const int *fb_poly_get_chain(int *len) {
#if FB_INV == ITOHT || !defined(STRIP)
	ctx_t *ctx = core_get();
	if (ctx->chain_len > 0 && ctx->chain_len < MAX_TERMS) {
		if (len != NULL) {
			*len = ctx->chain_len;
		}
		return ctx->chain;
	} else {
		if (len != NULL) {
			*len = 0;
		}
		return NULL;
	}
#else
	return NULL;
#endif
}
Example #18
0
void eb_param_print() {
	switch (core_get()->eb_id) {
		case NIST_B163:
			util_banner("Curve NIST-B163:", 0);
			break;
		case NIST_K163:
			util_banner("Curve NIST-K163:", 0);
			break;
		case NIST_B233:
			util_banner("Curve NIST-B233:", 0);
			break;
		case NIST_K233:
			util_banner("Curve NIST-K233:", 0);
			break;
		case SECG_K239:
			util_banner("Curve SECG-K239:", 0);
			break;
		case EBACS_B251:
			util_banner("Curve EBACS-B251:", 0);
			break;
		case HALVE_B257:
			util_banner("Curve HALVE-B257:", 0);
			break;
		case NIST_B283:
			util_banner("Curve NIST-B283:", 0);
			break;
		case NIST_K283:
			util_banner("Curve NIST-K283:", 0);
			break;
		case NIST_B409:
			util_banner("Curve NIST-B409:", 0);
			break;
		case NIST_K409:
			util_banner("Curve NIST-K409:", 0);
			break;
		case NIST_B571:
			util_banner("Curve NIST-B571:", 0);
			break;
		case NIST_K571:
			util_banner("Curve NIST-K571:", 0);
			break;
	}
}
Example #19
0
void eb_curve_clean(void) {
	ctx_t *ctx = core_get();
#if ALLOC == STATIC
	fb_free(ctx->eb_g.x);
	fb_free(ctx->eb_g.y);
	fb_free(ctx->eb_g.z);
	for (int i = 0; i < EB_TABLE; i++) {
		fb_free(ctx->eb_pre[i].x);
		fb_free(ctx->eb_pre[i].y);
		fb_free(ctx->eb_pre[i].z);
	}
#endif
	bn_clean(&(ctx->eb_r));
	bn_clean(&(ctx->eb_h));
#if defined(EB_KBLTZ) && (EB_MUL == LWNAF || !defined(STRIP))
	bn_clean(&(ctx->eb_vm));
	bn_clean(&(ctx->eb_s0));
	bn_clean(&(ctx->eb_s1));
#endif
}
Example #20
0
void ep_curve_set_super(const fp_t a, const fp_t b, const ep_t g, const bn_t r,
		const bn_t h) {
	ctx_t *ctx = core_get();
	ctx->ep_is_endom = 0;
	ctx->ep_is_super = 1;

	fp_copy(ctx->ep_a, 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);

	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
}
void rand_clean() {

#if RAND == UDEV
	int *fd = (int *)&(core_get()->rand);
	close(*fd);
#endif

#if RAND != CALL
	memset(core_get()->rand, 0, sizeof(core_get()->rand));
#else
	core_get()->rand_call = NULL;
	core_get()->rand_args = NULL;
#endif
	core_get()->seeded = 0;
}
Example #22
0
void rand_bytes(uint8_t *buf, int size) {
	uint8_t hash[MD_LEN];
	int carry, len  = (RAND_SIZE - 1)/2;
	ctx_t *ctx = core_get();

	if (sizeof(int) > 2 && size > (1 << 16)) {
		THROW(ERR_NO_VALID);
	}

	/* buf = hash_gen(size) */
	rand_gen(buf, size);
	/* H = hash(03 || V) */
	ctx->rand[0] = 0x3;
	md_map(hash, ctx->rand, 1 + len);
	/* V = V + H + C  + reseed_counter. */
	rand_add(ctx->rand + 1, ctx->rand + 1 + len, len);
	carry = rand_add(ctx->rand + 1 + (len - MD_LEN), hash, MD_LEN);
	rand_inc(ctx->rand, len - MD_LEN + 1, carry);
	rand_inc(ctx->rand, len + 1, ctx->counter);
	ctx->counter = ctx->counter + 1;
}
void ep2_curve_init(void) {
	ctx_t *ctx = core_get();

#ifdef EP_PRECO
	for (int i = 0; i < EP_TABLE; i++) {
		ctx->ep2_ptr[i] = &(ctx->ep2_pre[i]);
	}
#endif

#if ALLOC == STATIC || ALLOC == DYNAMIC || ALLOC == STACK
	ctx->ep2_g.x[0] = ctx->ep2_gx[0];
	ctx->ep2_g.x[1] = ctx->ep2_gx[1];
	ctx->ep2_g.y[0] = ctx->ep2_gy[0];
	ctx->ep2_g.y[1] = ctx->ep2_gy[1];
	ctx->ep2_g.z[0] = ctx->ep2_gz[0];
	ctx->ep2_g.z[1] = ctx->ep2_gz[1];
#endif

#ifdef EP_PRECO
#if ALLOC == STATIC || ALLOC == DYNAMIC
	for (int i = 0; i < EP_TABLE; i++) {
		fp2_new(ctx->ep2_pre[i].x);
		fp2_new(ctx->ep2_pre[i].y);
		fp2_new(ctx->ep2_pre[i].z);
	}
#elif ALLOC == STACK
	for (int i = 0; i < EP_TABLE; i++) {
		ctx->ep2_pre[i].x[0] = ctx->_ep2_pre[3 * i][0];
		ctx->ep2_pre[i].x[1] = ctx->_ep2_pre[3 * i][1];
		ctx->ep2_pre[i].y[0] = ctx->_ep2_pre[3 * i + 1][0];
		ctx->ep2_pre[i].y[1] = ctx->_ep2_pre[3 * i + 1][1];
		ctx->ep2_pre[i].z[0] = ctx->_ep2_pre[3 * i + 2][0];
		ctx->ep2_pre[i].z[1] = ctx->_ep2_pre[3 * i + 2][1];
	}
#endif
#endif
	ep2_set_infty(&(ctx->ep2_g));
	bn_init(&(ctx->ep2_r), FP_DIGS);
	bn_init(&(ctx->ep2_h), FP_DIGS);
}
Example #24
0
void eb_curve_set_kbltz(const fb_t a, const eb_t g, const bn_t r, const bn_t h) {
	ctx_t *ctx = core_get();

	ctx->eb_is_kbltz = 1;
	ctx->eb_is_super = 0;

	fb_copy(ctx->eb_a, a);
	fb_set_dig(ctx->eb_b, 1);

	detect_opt(&(ctx->eb_opt_a), ctx->eb_a);
	detect_opt(&(ctx->eb_opt_b), ctx->eb_b);

#if EB_MUL == LWNAF || EB_FIX == LWNAF || EB_SIM == INTER || !defined(STRIP)
	compute_kbltz();
#endif
	eb_norm(&(ctx->eb_g), g);
	bn_copy(&(ctx->eb_r), r);
	bn_copy(&(ctx->eb_h), h);
#if defined(EB_PRECO)
	eb_mul_pre((eb_t *)eb_curve_get_tab(), &(ctx->eb_g));
#endif
}
Example #25
0
void eb_curve_set_super(const fb_t a, const fb_t b, const fb_t c, const eb_t g,
		const bn_t r, const bn_t h) {
	ctx_t *ctx = core_get();

	ctx->eb_is_kbltz = 0;
	ctx->eb_is_super = 1;

	fb_copy(ctx->eb_a, a);
	fb_copy(ctx->eb_b, b);
	fb_copy(ctx->eb_c, c);

	detect_opt(&(ctx->eb_opt_a), ctx->eb_a);
	detect_opt(&(ctx->eb_opt_b), ctx->eb_b);
	detect_opt(&(ctx->eb_opt_c), ctx->eb_c);

	eb_norm(&(ctx->eb_g), g);
	bn_copy(&(ctx->eb_r), r);
	bn_copy(&(ctx->eb_h), h);
#if defined(EB_PRECO)
	eb_mul_pre((eb_t *)eb_curve_get_tab(), &(ctx->eb_g));
#endif
}
Example #26
0
void fp2_mul_frb(fp2_t c, fp2_t a, int i, int j) {
	ctx_t *ctx = core_get();

	if (i == 2) {
		fp_mul(c[0], a[0], ctx->fp2_p2[j - 1]);
		fp_mul(c[1], a[1], ctx->fp2_p2[j - 1]);
	} else {
#if ALLOC == AUTO
		if (i == 1) {
			fp2_mul(c, a, ctx->fp2_p[j - 1]);
		} else {
			fp2_mul(c, a, ctx->fp2_p3[j - 1]);
		}
#else
		fp2_t t;

		fp2_null(t);

		TRY {
			fp2_new(t);
			if (i == 1) {
				fp_copy(t[0], ctx->fp2_p[j - 1][0]);
				fp_copy(t[1], ctx->fp2_p[j - 1][1]);
			} else {
				fp_copy(t[0], ctx->fp2_p3[j - 1][0]);
				fp_copy(t[1], ctx->fp2_p3[j - 1][1]);
			}
			fp2_mul(c, a, t);
		}
		CATCH_ANY {
			THROW(ERR_CAUGHT);
		}
		FINALLY {
			fp2_free(t);
		}
#endif
	}
}
Example #27
0
int eb_param_level() {
	switch (core_get()->eb_id) {
		case NIST_B163:
		case NIST_K163:
			return 80;
		case NIST_B233:
		case NIST_K233:
		case SECG_K239:
			return 112;
		case EBACS_B251:
		case HALVE_B257:
		case NIST_B283:
		case NIST_K283:
			return 128;
		case NIST_B409:
		case NIST_K409:
			return 192;
		case NIST_B571:
		case NIST_K571:
			return 256;
	}
	return 0;
}
Example #28
0
void ep_curve_clean(void) {
	ctx_t *ctx = core_get();
#if ALLOC == STATIC
	fp_free(ctx->ep_g.x);
	fp_free(ctx->ep_g.y);
	fp_free(ctx->ep_g.z);
#ifdef EP_PRECO
	for (int i = 0; i < RELIC_EP_TABLE; i++) {
		fp_free(ctx->ep_pre[i].x);
		fp_free(ctx->ep_pre[i].y);
		fp_free(ctx->ep_pre[i].z);
	}
#endif
#endif
	bn_clean(&ctx->ep_r);
	bn_clean(&ctx->ep_h);
#if defined(EP_ENDOM) && (EP_MUL == LWNAF || EP_FIX == LWNAF || !defined(STRIP))
	for (int i = 0; i < 3; i++) {
		bn_clean(&(ctx->ep_v1[i]));
		bn_clean(&(ctx->ep_v2[i]));
	}
#endif
}
Example #29
0
/**
 * Precomputes half-traces for z^i with odd i.
 *
 * @throw ERR_NO_MEMORY if there is no available memory.
 */
static void find_solve() {
	int i, j, k, l;
	fb_t t0;
	ctx_t *ctx = core_get();

	fb_null(t0);

	TRY {
		fb_new(t0);

		l = 0;
		for (i = 0; i < FB_BITS; i += 8, l++) {
			for (j = 0; j < 16; j++) {
				fb_zero(t0);
				for (k = 0; k < 4; k++) {
					if (j & (1 << k)) {
						fb_set_bit(t0, i + 2 * k + 1, 1);
					}
				}
				fb_copy(ctx->fb_half[l][j], t0);
				for (k = 0; k < (FB_BITS - 1) / 2; k++) {
					fb_sqr(ctx->fb_half[l][j], ctx->fb_half[l][j]);
					fb_sqr(ctx->fb_half[l][j], ctx->fb_half[l][j]);
					fb_add(ctx->fb_half[l][j], ctx->fb_half[l][j], t0);
				}
			}
			fb_rsh(ctx->fb_half[l][j], ctx->fb_half[l][j], 1);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fb_free(t0);
	}
}
Example #30
0
void ep_param_set(int param) {
	int plain = 0, endom = 0, super = 0;
	char str[2 * FP_BYTES + 2];
	fp_t a, b, beta;
	ep_t g;
	bn_t r, h, lamb;

	fp_null(a);
	fp_null(b);
	fp_null(beta);
	bn_null(lamb);
	ep_null(g);
	bn_null(r);
	bn_null(h);

	TRY {
		fp_new(a);
		fp_new(b);
		fp_new(beta);
		bn_new(lamb);
		ep_new(g);
		bn_new(r);
		bn_new(h);

		core_get()->ep_id = 0;

		switch (param) {
#if defined(EP_ENDOM) && FP_PRIME == 158
			case BN_P158:
				ASSIGNK(BN_P158, BN_158);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 160
			case SECG_P160:
				ASSIGN(SECG_P160, SECG_160);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 160
			case SECG_K160:
				ASSIGNK(SECG_K160, SECG_160D);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 192
			case NIST_P192:
				ASSIGN(NIST_P192, NIST_192);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 192
			case SECG_K192:
				ASSIGNK(SECG_K192, SECG_192);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 221
			case CURVE_22103:
				ASSIGN(CURVE_22103, PRIME_22103);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 224
			case NIST_P224:
				ASSIGN(NIST_P224, NIST_224);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 224
			case SECG_K224:
				ASSIGNK(SECG_K224, SECG_224);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 226
			case CURVE_4417:
				ASSIGN(CURVE_4417, PRIME_22605);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 254
			case BN_P254:
				ASSIGNK(BN_P254, BN_254);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 251
			case CURVE_1174:
				ASSIGN(CURVE_1174, PRIME_25109);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 255
			case CURVE_25519:
				ASSIGN(CURVE_25519, PRIME_25519);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 256
			case NIST_P256:
				ASSIGN(NIST_P256, NIST_256);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 256
			case SECG_K256:
				ASSIGNK(SECG_K256, SECG_256);
				endom = 1;
				break;
			case BN_P256:
				ASSIGNK(BN_P256, BN_256);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) & FP_PRIME == 382
			case CURVE_67254:
				ASSIGN(CURVE_67254, PRIME_382105);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 383
			case CURVE_383187:
				ASSIGN(CURVE_383187, PRIME_383187);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 384
			case NIST_P384:
				ASSIGN(NIST_P384, NIST_384);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 477
			case B24_P477:
				ASSIGN(B24_P477, B24_477);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 508
			case KSS_P508:
				ASSIGNK(KSS_P508, KSS_508);
				endom = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 511
			case CURVE_511187:
				ASSIGN(CURVE_511187, PRIME_511187);
				plain = 1;
				break;
#endif
#if defined(EP_PLAIN) && FP_PRIME == 521
			case NIST_P521:
				ASSIGN(NIST_P521, NIST_521);
				plain = 1;
				break;
#endif
#if defined(EP_ENDOM) && FP_PRIME == 638
			case BN_P638:
				ASSIGNK(BN_P638, BN_638);
				endom = 1;
				break;
			case B12_P638:
				ASSIGNK(B12_P638, B12_638);
				endom = 1;
				break;
#endif
#if defined(EP_SUPER) && FP_PRIME == 1536
			case SS_P1536:
				ASSIGN(SS_P1536, SS_1536);
				super = 1;
				break;
#endif
			default:
				(void)str;
				THROW(ERR_NO_VALID);
				break;
		}

		/* Do not generate warnings. */
		(void)endom;
		(void)plain;
		(void)beta;

		fp_zero(g->z);
		fp_set_dig(g->z, 1);
		g->norm = 1;

#if defined(EP_PLAIN)
		if (plain) {
			ep_curve_set_plain(a, b, g, r, h);
			core_get()->ep_id = param;
		}
#endif

#if defined(EP_ENDOM)
		if (endom) {
			ep_curve_set_endom(b, g, r, h, beta, lamb);
			core_get()->ep_id = param;
		}
#endif

#if defined(EP_SUPER)
		if (super) {
			ep_curve_set_super(a, b, g, r, h);
			core_get()->ep_id = param;
		}
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fp_free(a);
		fp_free(b);
		fp_free(beta);
		bn_free(lamb);
		ep_free(g);
		bn_free(r);
		bn_free(h);
	}
}