Exemplo n.º 1
0
int fp2_srt(fp2_t c, fp2_t a) {
	int r = 0;
	fp_t t1;
	fp_t t2;
	fp_t t3;

	fp_null(t1);
	fp_null(t2);
	fp_null(t3);

	TRY {
		fp_new(t1);
		fp_new(t2);
		fp_new(t3);

		/* t1 = a[0]^2 - u^2 * a[1]^2 */
		fp_sqr(t1, a[0]);
		fp_sqr(t2, a[1]);
		for (int i = -1; i > fp_prime_get_qnr(); i--) {
			fp_add(t1, t1, t2);
		}
		for (int i = 0; i <= fp_prime_get_qnr(); i++) {
			fp_sub(t1, t1, t2);
		}		
		fp_add(t1, t1, t2);

		if (fp_srt(t2, t1)) {
			/* t1 = (a_0 + sqrt(t1)) / 2 */
			fp_add(t1, a[0], t2);
			fp_set_dig(t3, 2);
			fp_inv(t3, t3);
			fp_mul(t1, t1, t3);

			if (!fp_srt(t3, t1)) {
				/* t1 = (a_0 - sqrt(t1)) / 2 */
				fp_sub(t1, a[0], t2);
				fp_set_dig(t3, 2);
				fp_inv(t3, t3);
				fp_mul(t1, t1, t3);
				fp_srt(t3, t1);
			}
			/* c_0 = sqrt(t1) */
			fp_copy(c[0], t3);
			/* c_1 = a_1 / (2 * sqrt(t1)) */
			fp_dbl(t3, t3);
			fp_inv(t3, t3);
			fp_mul(c[1], a[1], t3);
			r = 1;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fp_free(t1);
		fp_free(t2);
		fp_free(t3);
	}
	return r;
}
Exemplo n.º 2
0
int fp2_upk(fp2_t c, fp2_t a) {
	int result, b = fp_get_bit(a[1], 0);
	fp_t t;

	fp_null(t);

	TRY {
		fp_new(t);

		/* a_0^2 + a_1^2 = 1, thus a_1^2 = 1 - a_0^2. */
		fp_sqr(t, a[0]);
		fp_sub_dig(t, t, 1);
		fp_neg(t, t);

		/* a1 = sqrt(a_0^2). */
		result = fp_srt(t, t);

		if (result) {
			/* Verify if least significant bit of the result matches the
			 * compressed second coordinate. */
			if (fp_get_bit(t, 0) != b) {
				fp_neg(t, t);
			}
			fp_copy(c[0], a[0]);
			fp_copy(c[1], t);
		}
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		fp_free(t);
	}

	return result;
}
Exemplo n.º 3
0
int ep_upk(ep_t r, const ep_t p) {
	fp_t t;
	int result = 0;

	fp_null(t);

	TRY {
		fp_new(t);

		ep_rhs(t, p);

		/* t0 = sqrt(x1^3 + a * x1 + b). */
		result = fp_srt(t, t);

		if (result) {
			/* Verify if least significant bit of the result matches the
			 * compressed y-coordinate. */
			if (fp_get_bit(t, 0) != fp_get_bit(p->y, 0)) {
				fp_neg(t, t);
			}
			fp_copy(r->x, p->x);
			fp_copy(r->y, t);
			fp_set_dig(r->z, 1);
			r->norm = 1;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fp_free(t);
	}
	return result;
}