void field_init_tiny_fp(field_ptr f, mpz_t prime) { pbc_mpui *p; PBC_ASSERT(mpz_fits_ulong_p(prime), "modulus too big"); 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->add = fp_add; f->sub = fp_sub; f->set = fp_set; f->mul = fp_mul; f->mul_si = fp_mul_si; f->square = fp_square; f->doub = fp_double; f->pow_mpz = fp_pow_mpz; f->neg = fp_neg; f->cmp = fp_cmp; f->sign = fp_sgn_odd; 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; p = f->data = pbc_malloc(sizeof(pbc_mpui)); *p = mpz_get_ui(prime); { pbc_mpui l = 255; f->fixed_length_in_bytes = 1; while (l < *p) { f->fixed_length_in_bytes++; l <<= 8; l += 255; } } mpz_set(f->order, prime); }
void field_init_fast_fp(field_ptr f, mpz_t prime) { PBC_ASSERT(!mpz_fits_ulong_p(prime), "modulus too small"); fp_field_data_ptr 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->add = fp_add; f->sub = fp_sub; f->set = fp_set; f->mul = fp_mul; f->mul_si = fp_mul_si; f->square = fp_square; f->doub = fp_double; f->halve = fp_halve; f->pow_mpz = fp_pow_mpz; f->neg = fp_neg; f->cmp = fp_cmp; f->sign = mpz_odd_p(prime) ? fp_sgn_odd : fp_sgn_even; 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; p = f->data = pbc_malloc(sizeof(fp_field_data_t)); p->limbs = mpz_size(prime); p->bytes = p->limbs * sizeof(mp_limb_t); p->primelimbs = 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; }
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); }