Example #1
0
// Inversion is slower than in a naive Fp implementation because of an extra
// multiplication.
// Requires nonzero a.
static void fp_invert(element_ptr c, element_ptr a) {
	eptr ad = (eptr)a->data;
	eptr cd = (eptr)c->data;
	fptr p = (fptr)a->field->data;

#ifdef _MSC_VER		// for VC++ compatibility
	mp_limb_t tmp[MAX_LIMBS];
#else
	mp_limb_t tmp[p->limbs];
#endif

	mpz_t z;

	mpz_init(z);

	// Copy the limbs into a regular mpz_t so we can invert using the standard
	// mpz_invert().

	mpz_import(z, p->limbs, -1, sizeof(mp_limb_t), 0, 0, ad->d);	
	mpz_invert(z, z, a->field->order);
	set_limbs(tmp, z, p->limbs);

	// Normalize.
	mont_mul(cd->d, tmp, p->R3, p);
	cd->flag = 2;
	mpz_clear(z);
}
Example #2
0
void setup()
{
  set_limbs(0);
  set_race_size(2);

  set_long("Un animal salvaje.\n");
  set_name("animal");
  set_short("Animal");
  set_light_limits(LHUMANL, LHUMANH);

  set_playable(0);
}
Example #3
0
static void fp_set_mpz(element_ptr e, mpz_ptr z) {
	fptr p = (fptr)e->field->data;
	eptr ep = (eptr)e->data;
	if (!mpz_sgn(z)) ep->flag = 0;
	else {
		mpz_t tmp;
		mpz_init(tmp);
		mpz_mul_2exp(tmp, z, p->bytes * 8);
		mpz_mod(tmp, tmp, e->field->order);
		if (!mpz_sgn(tmp)) ep->flag = 0;
		else {
			set_limbs(ep->d, tmp, p->limbs);
			ep->flag = 2;
		}
		mpz_clear(tmp);
	}
}
Example #4
0
static void fp_random(element_ptr a) {
	fptr p = (fptr)a->field->data;
	eptr ad = (eptr)a->data;
	mpz_t z;
	mpz_init(z);
	pbc_mpz_random(z, a->field->order);
	if (mpz_sgn(z)) {
		mpz_mul_2exp(z, z, p->bytes * 8);
		mpz_mod(z, z, a->field->order);
		set_limbs(ad->d, z, p->limbs);
		ad->flag = 2;
	}
	else {
		ad->flag = 0;
	}
	mpz_clear(z);
}
Example #5
0
static void fp_pow_mpz(element_ptr c, element_ptr a, mpz_ptr op) {
	// Alternative: rewrite GMP mpz_powm().
	fptr p = (fptr)a->field->data;
	eptr ad = (eptr)a->data;
	eptr cd = (eptr)c->data;
	if (!ad->flag) cd->flag = 0;
	else {
		mpz_t z;
		mpz_init(z);
		fp_to_mpz(z, a);
		mpz_powm(z, z, op, a->field->order);
		mpz_mul_2exp(z, z, p->bytes * 8);
		mpz_mod(z, z, a->field->order);
		set_limbs(cd->d, z, p->limbs);
		mpz_clear(z);
		cd->flag = 2;
	}
}
Example #6
0
static void fp_set_si(element_ptr e, signed long int op) {
	fptr p = (fptr)e->field->data;
	eptr ep = (eptr)e->data;
	if (!op) ep->flag = 0;
	else {
		mpz_t tmp;
		mpz_init(tmp);
		// TODO: Could be optimized.
		mpz_set_si(tmp, op);
		mpz_mul_2exp(tmp, tmp, p->bytes * 8);
		mpz_mod(tmp, tmp, e->field->order);
		if (!mpz_sgn(tmp)) ep->flag = 0;
		else {
			set_limbs(ep->d, tmp, p->limbs);
			ep->flag = 2;
		}
		mpz_clear(tmp);
	}
}
Example #7
0
static int fp_from_bytes(element_t a, unsigned char *data) {
	fptr p = (fptr)a->field->data;
	eptr ad = (eptr)a->data;
	int n;
	mpz_t z;

	mpz_init(z);

	n = a->field->fixed_length_in_bytes;

	mpz_import(z, n, 1, 1, 1, 0, data);
	if (!mpz_sgn(z)) ad->flag = 0;
	else {
		ad->flag = 2;
		mpz_mul_2exp(z, z, p->bytes * 8);
		mpz_mod(z, z, a->field->order);
		set_limbs(ad->d, z, p->limbs);
	}
	mpz_clear(z);
	return n;
}
Example #8
0
void field_init_mont_fp(field_ptr f, mpz_t prime) {
	PBC_ASSERT(!mpz_fits_ulong_p(prime), "modulus too small");
	fptr p;
	field_init(f);
	f->init = fp_init;
	f->clear = fp_clear;
	f->set_si = fp_set_si;
	f->set_mpz = fp_set_mpz;
	f->out_str = fp_out_str;
	f->snprint = fp_snprint;
	f->set_str = fp_set_str;
	f->add = fp_add;
	f->sub = fp_sub;
	f->set = fp_set;
	f->mul = fp_mul;
	f->doub = fp_double;
	f->halve = fp_halve;
	f->pow_mpz = fp_pow_mpz;
	f->neg = fp_neg;
	f->sign = fp_sgn_odd;
	f->cmp = fp_cmp;
	f->invert = fp_invert;
	f->random = fp_random;
	f->from_hash = fp_from_hash;
	f->is1 = fp_is1;
	f->is0 = fp_is0;
	f->set0 = fp_set0;
	f->set1 = fp_set1;
	f->is_sqr = fp_is_sqr;
	f->sqrt = element_tonelli;
	f->field_clear = fp_field_clear;
	f->to_bytes = fp_to_bytes;
	f->from_bytes = fp_from_bytes;
	f->to_mpz = fp_to_mpz;
	f->out_info = fp_out_info;

	// Initialize per-field data specific to this implementation.
	f->data = pbc_malloc(sizeof(*p));
	p = (fptr)f->data;
	p->limbs = mpz_size(prime);
	p->bytes = p->limbs * sizeof(mp_limb_t);
	p->primelimbs = (mp_limb_t*)pbc_malloc(p->bytes);
	mpz_export(p->primelimbs, &p->limbs, -1, sizeof(mp_limb_t), 0, 0, prime);
	mpz_set(f->order, prime);
	f->fixed_length_in_bytes = (mpz_sizeinbase(prime, 2) + 7) / 8;

	// Compute R, R3 and negpinv.
	mpz_t z;
	mpz_init(z);

	p->R = (mp_limb_t*)pbc_malloc(p->bytes);
	p->R3 = (mp_limb_t*)pbc_malloc(p->bytes);
	mpz_setbit(z, p->bytes * 8);
	mpz_mod(z, z, prime);
	set_limbs(p->R, z, p->limbs);

	mpz_powm_ui(z, z, 3, prime);
	set_limbs(p->R3, z, p->limbs);

	mpz_set_ui(z, 0);

	// Algorithm II.5 in Blake, Seroussi and Smart is better but this suffices
	// since we're only doing it once.
	mpz_setbit(z, p->bytes * 8);
	mpz_invert(z, prime, z);

#ifdef _MSC_VER		// for VC++ compatibility
	int tmp = mpz_get_ui(z);
	p->negpinv = -tmp;
#else
	p->negpinv = -mpz_get_ui(z);
#endif

	mpz_clear(z);
}