Example #1
0
/**
 * Multiplies two binary field elements using shift-and-add multiplication.
 *
 * @param c					- the result.
 * @param a					- the first binary field element.
 * @param b					- the second binary field element.
 * @param size				- the number of digits to multiply.
 */
static void fb_mul_basic_imp(dig_t *c, const dig_t *a, const dig_t *b, int size) {
	int i;
	dv_t s;

	dv_null(s);

	TRY {
		/* We need a temporary variable so that c can be a or b. */
		dv_new(s);
		dv_zero(s, 2 * FB_DIGS);

		dv_copy(s, b, size);
		dv_zero(c, 2 * size);

		if (a[0] & 1) {
			dv_copy(c, b, size);
		}
		for (i = 1; i <= (FB_DIGIT * size) - 1; i++) {
			fb_lsh1_low(s, s);
			fb_rdc(s, s);
			if (fb_get_bit(a, i)) {
				fb_add(c, c, s);
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(s);
	}
}
Example #2
0
void fb_mul_lcomb(fb_t c, const fb_t a, const fb_t b) {
	dv_t t;
	dig_t carry;

	dv_null(t);

	TRY {
		dv_new(t);
		dv_zero(t, 2 * FB_DIGS);

		for (int i = FB_DIGIT - 1; i >= 0; i--) {
			for (int j = 0; j < FB_DIGS; j++) {
				if (a[j] & ((dig_t)1 << i)) {
					/* This cannot use fb_addn_low() because there is no
					 * guarantee that operands will be aligned. */
					fb_addd_low(t + j, t + j, b, FB_DIGS);
				}
			}
			if (i != 0) {
				carry = fb_lsh1_low(t, t);
				fb_lsh1_low(t + FB_DIGS, t + FB_DIGS);
				t[FB_DIGS] |= carry;
			}
		}

		fb_rdc(c, t);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
	}
}
Example #3
0
void fb_sqr_table(fb_t c, const fb_t a) {
	dv_t t;

	dv_null(t);

	TRY {
		/* We need a temporary variable so that c can be a or b. */
		dv_new(t);
		fb_sqrl_low(t, a);
		fb_rdc(c, t);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
	}
}
Example #4
0
void fb_mul_lodah(fb_t c, const fb_t a, const fb_t b) {
	dv_t t;

	dv_null(t);

	TRY {
		dv_new(t);

		fb_muln_low(t, a, b);

		fb_rdc(c, t);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
	}
}
Example #5
0
void fb_mul_basic(fb_t c, const fb_t a, const fb_t b) {
	int i;
	dv_t s;
	fb_t t;

	dv_null(s);
	fb_null(t);

	TRY {
		/* We need a temporary variable so that c can be a or b. */
		fb_new(t);
		dv_new(s);
		fb_zero(t);
		dv_zero(s + FB_DIGS, FB_DIGS);
		fb_copy(s, b);

		if (a[0] & 1) {
			fb_copy(t, b);
		}
		for (i = 1; i < FB_BITS; i++) {
			/* We are already shifting a temporary value, so this is more efficient
			 * than calling fb_lsh(). */
			s[FB_DIGS] = fb_lsh1_low(s, s);
			fb_rdc(s, s);
			if (fb_get_bit(a, i)) {
				fb_add(t, t, s);
			}
		}

		if (fb_bits(t) > FB_BITS) {
			fb_poly_add(c, t);
		} else {
			fb_copy(c, t);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		fb_free(t);
		fb_free(s);
	}
}
Example #6
0
void fb_mul_karat(fb_t c, const fb_t a, const fb_t b) {
	dv_t t;

	dv_null(t);

	TRY {
		/* We need a temporary variable so that c can be a or b. */
		dv_new(t);
		dv_zero(t, 2 * FB_DIGS);

		fb_mul_karat_imp(t, a, b, FB_DIGS, FB_KARAT);

		fb_rdc(c, t);
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
	}
}
Example #7
0
void fb_mul_rcomb(fb_t c, const fb_t a, const fb_t b) {
	dv_t t, _b;
	dig_t carry;

	dv_null(t);
	dv_null(_b);

	TRY {
		dv_new(t);
		dv_new(_b);
		dv_zero(t, 2 * FB_DIGS);
		dv_zero(_b, FB_DIGS + 1);

		fb_copy(_b, b);

		for (int i = 0; i < FB_DIGIT; i++) {
			for (int j = 0; j < FB_DIGS; j++) {
				if (a[j] & ((dig_t)1 << i)) {
					fb_addd_low(t + j, t + j, _b, FB_DIGS + 1);
				}
			}
			if (i != FB_DIGIT - 1) {
				carry = fb_lsh1_low(_b, _b);
				_b[FB_DIGS] = (_b[FB_DIGS] << 1) | carry;
			}
		}

		fb_rdc(c, t);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		dv_free(t);
		dv_free(_b);
	}
}