Пример #1
0
void fp_rdcn_low(dig_t *c, dig_t *a) {
	int i;
	dig_t r, c0, c1, u, *tmp;
	const dig_t *m;

	u = *(fp_prime_get_rdc());
	m = fp_prime_get();

	tmp = a;

	c1 = 0;
	for (i = 0; i < FP_DIGS; i++, tmp++) {
		r = (dig_t)(*tmp * u);
		c0 = mpn_addmul_1(tmp, m, FP_DIGS, r);
		c1 += mpn_add_1(tmp + FP_DIGS, tmp + FP_DIGS, FP_DIGS - i, c0);
	}
	for (i = 0; i < FP_DIGS; i++, tmp++) {
		c[i] = *tmp;
	}
	for (i = 0; i < c1; i++) {
		fp_subn_low(c, c, m);
	}
	if (fp_cmp(c, m) != CMP_LT) {
		fp_subn_low(c, c, m);
	}
}
Пример #2
0
void fp_rdc_monty_basic(fp_t c, dv_t a) {
	int i;
	dig_t r, c0, c1, *tmp, u0;
	const dig_t *p = NULL;

	tmp = a;

	u0 = *(fp_prime_get_rdc());
	p = fp_prime_get();

	c1 = 0;
	for (i = 0; i < FP_DIGS; i++, tmp++) {
		r = (dig_t)(*tmp * u0);
		c0 = fp_mula_low(tmp, fp_prime_get(), r);
		/* We must use this because the size (FP_DIGS - i) is variable. */
		c1 += bn_add1_low(tmp + FP_DIGS, tmp + FP_DIGS, c0, FP_DIGS - i);
	}
	fp_copy(c, a + FP_DIGS);

	for (i = 0; i < c1; i++) {
		fp_subn_low(c, c, p);
	}
	if (fp_cmpn_low(c, p) != CMP_LT) {
		fp_subn_low(c, c, p);
	}
}
Пример #3
0
void fp_rdcn_low2(dig_t *c, dig_t *a) {
	int i, j;
	dig_t r0, r1, r2, u;
	dig_t *m, *tmp, *tmpm, *tmpc;

	u = *(fp_prime_get_rdc());
	m = fp_prime_get();
	tmpc = c;

	r0 = r1 = r2 = 0;
	for (i = 0; i < FP_DIGS; i++, tmpc++, a++) {
		tmp = c;
		tmpm = m + i;
		for (j = 0; j < i; j++, tmp++, tmpm--) {
			COMBA_STEP(r2, r1, r0, *tmp, *tmpm);
		}
		COMBA_ADD(r2, r1, r0, *a);
		*tmpc = (dig_t)(r0 * u);
		COMBA_STEP(r2, r1, r0, *tmpc, *m);
		r0 = r1;
		r1 = r2;
		r2 = 0;
	}

	for (i = FP_DIGS; i < 2 * FP_DIGS - 1; i++, a++) {
		tmp = c + (i - FP_DIGS + 1);
		tmpm = m + FP_DIGS - 1;
		for (j = i - FP_DIGS + 1; j < FP_DIGS; j++, tmp++, tmpm--) {
			COMBA_STEP(r2, r1, r0, *tmp, *tmpm);
		}
		COMBA_ADD(r2, r1, r0, *a);
		c[i - FP_DIGS] = r0;
		r0 = r1;
		r1 = r2;
		r2 = 0;
	}
	COMBA_ADD(r2, r1, r0, *a);
	c[FP_DIGS - 1] = r0;

	if (r1 || fp_cmpn_low(c, m) != CMP_LT) {
		fp_subn_low(c, c, m);
	}
}