aboutsummaryrefslogtreecommitdiffstats
path: root/moon-abe/pbc-0.5.14/arith/z.c
diff options
context:
space:
mode:
Diffstat (limited to 'moon-abe/pbc-0.5.14/arith/z.c')
-rw-r--r--moon-abe/pbc-0.5.14/arith/z.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/moon-abe/pbc-0.5.14/arith/z.c b/moon-abe/pbc-0.5.14/arith/z.c
new file mode 100644
index 00000000..ff5a4a97
--- /dev/null
+++ b/moon-abe/pbc-0.5.14/arith/z.c
@@ -0,0 +1,263 @@
+// The ring Z.
+//
+// Wrappers around GMP mpz functions.
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h> // for intptr_t
+#include <stdlib.h>
+#include <gmp.h>
+#include "pbc_utils.h"
+#include "pbc_field.h"
+#include "pbc_z.h"
+#include "pbc_random.h"
+#include "pbc_fp.h"
+#include "pbc_memory.h"
+
+static void z_init(element_ptr e) {
+ e->data = pbc_malloc(sizeof(mpz_t));
+ mpz_init(e->data);
+}
+
+static void z_clear(element_ptr e) {
+ mpz_clear(e->data);
+ pbc_free(e->data);
+}
+
+static void z_set_si(element_ptr e, signed long int op) {
+ mpz_set_si(e->data, op);
+}
+
+static void z_set_mpz(element_ptr e, mpz_ptr z) {
+ mpz_set(e->data, z);
+}
+
+static void z_set0(element_ptr e) {
+ mpz_set_ui(e->data, 0);
+}
+
+static void z_set1(element_ptr e) {
+ mpz_set_ui(e->data, 1);
+}
+
+static size_t z_out_str(FILE *stream, int base, element_ptr e) {
+ return mpz_out_str(stream, base, e->data);
+}
+
+static int z_sgn(element_ptr a) {
+ mpz_ptr z = a->data;
+ return mpz_sgn(z);
+}
+
+static void z_add(element_ptr n, element_ptr a, element_ptr b) {
+ mpz_add(n->data, a->data, b->data);
+}
+
+static void z_sub(element_ptr n, element_ptr a, element_ptr b) {
+ mpz_sub(n->data, a->data, b->data);
+}
+
+static void z_square(element_ptr c, element_ptr a) {
+ mpz_mul(c->data, a->data, a->data);
+}
+
+static void z_double(element_ptr n, element_ptr a) {
+ mpz_mul_2exp(n->data, a->data, 1);
+}
+
+static void z_halve(element_ptr n, element_ptr a) {
+ mpz_tdiv_q_2exp(n->data, a->data, -1);
+}
+
+static void z_mul(element_ptr n, element_ptr a, element_ptr b) {
+ mpz_mul(n->data, a->data, b->data);
+}
+
+static void z_mul_mpz(element_ptr n, element_ptr a, mpz_ptr z) {
+ mpz_mul(n->data, a->data, z);
+}
+
+static void z_mul_si(element_ptr n, element_ptr a, signed long int z) {
+ mpz_mul_si(n->data, a->data, z);
+}
+
+static void z_pow_mpz(element_ptr n, element_ptr a, mpz_ptr z) {
+ mpz_pow_ui(n->data, a->data, mpz_get_ui(z));
+}
+
+static void z_set(element_ptr n, element_ptr a) {
+ mpz_set(n->data, a->data);
+}
+
+static void z_neg(element_ptr n, element_ptr a) {
+ mpz_neg(n->data, a->data);
+}
+
+static void z_invert(element_ptr n, element_ptr a) {
+ if (!mpz_cmpabs_ui(a->data, 1)) {
+ mpz_set(n->data, a->data);
+ } else mpz_set_ui(n->data, 0);
+}
+
+static void z_div(element_ptr c, element_ptr a, element_ptr b) {
+ mpz_tdiv_q(c->data, a->data, b->data);
+}
+
+//(doesn't make sense if order is infinite)
+static void z_random(element_ptr n) {
+ mpz_set_ui(n->data, 0);
+}
+
+static void z_from_hash(element_ptr n, void *data, int len) {
+ mpz_import(n->data, len, -1, 1, -1, 0, data);
+}
+
+static int z_is1(element_ptr n) {
+ return !mpz_cmp_ui((mpz_ptr) n->data, 1);
+}
+
+static int z_is0(element_ptr n) {
+ return mpz_is0(n->data);
+}
+
+static int z_cmp(element_ptr a, element_ptr b) {
+ return mpz_cmp((mpz_ptr) a->data, (mpz_ptr) b->data);
+}
+
+static int z_is_sqr(element_ptr a) {
+ return mpz_perfect_power_p(a->data);
+}
+
+static void z_sqrt(element_ptr c, element_ptr a) {
+ mpz_sqrt(c->data, a->data);
+}
+
+static void z_field_clear(field_t f) {
+ UNUSED_VAR (f);
+}
+
+// OpenSSL convention:
+// 4 bytes containing length
+// followed by number in big-endian, most-significant bit set if negative
+// (prepending null byte if necessary)
+// Positive numbers also the same as mpz_out_raw.
+static int z_to_bytes(unsigned char *data, element_t e) {
+ mpz_ptr z = e->data;
+ size_t msb = mpz_sizeinbase(z, 2);
+ size_t n = 4;
+ size_t i;
+
+ if (!(msb % 8)) {
+ data[4] = 0;
+ n++;
+ }
+ if (mpz_sgn(z) < 0) {
+ mpz_export(data + n, NULL, 1, 1, 1, 0, z);
+ data[4] |= 128;
+ } else {
+ mpz_export(data + n, NULL, 1, 1, 1, 0, z);
+ }
+ n += (msb + 7) / 8 - 4;
+ for (i=0; i<4; i++) {
+ data[i] = (n >> 8 * (3 - i));
+ }
+ n += 4;
+
+ return n;
+}
+
+static int z_from_bytes(element_t e, unsigned char *data) {
+ unsigned char *ptr;
+ size_t i, n;
+ mpz_ptr z = e->data;
+ mpz_t z1;
+ int neg = 0;
+
+ mpz_init(z1);
+ mpz_set_ui(z, 0);
+
+ ptr = data;
+ n = 0;
+ for (i=0; i<4; i++) {
+ n += ((unsigned int) *ptr) << 8 * (3 - i);
+ ptr++;
+ }
+ if (data[4] & 128) {
+ neg = 1;
+ data[4] &= 127;
+ }
+ for (i=0; i<n; i++) {
+ mpz_set_ui(z1, *ptr);
+ mpz_mul_2exp(z1, z1, 8 * (n - 1 - i));
+ ptr++;
+ mpz_add(z, z, z1);
+ }
+ mpz_clear(z1);
+ if (neg) mpz_neg(z, z);
+ return n;
+}
+
+static void z_to_mpz(mpz_ptr z, element_ptr a) {
+ mpz_set(z, a->data);
+}
+
+static int z_length_in_bytes(element_ptr a) {
+ return (mpz_sizeinbase(a->data, 2) + 7) / 8 + 4;
+}
+
+static void z_out_info(FILE *out, field_ptr f) {
+ UNUSED_VAR(f);
+ fprintf(out, "Z: wrapped GMP");
+}
+
+static int z_set_str(element_ptr e, const char *s, int base) {
+ mpz_t z;
+ mpz_init(z);
+ int result = pbc_mpz_set_str(z, s, base);
+ z_set_mpz(e, z);
+ mpz_clear(z);
+ return result;
+}
+
+void field_init_z(field_ptr f) {
+ field_init(f);
+ f->init = z_init;
+ f->clear = z_clear;
+ f->set_si = z_set_si;
+ f->set_mpz = z_set_mpz;
+ f->set_str = z_set_str;
+ f->out_str = z_out_str;
+ f->sign = z_sgn;
+ f->add = z_add;
+ f->sub = z_sub;
+ f->set = z_set;
+ f->square = z_square;
+ f->doub = z_double;
+ f->halve = z_halve;
+ f->mul = z_mul;
+ f->mul_mpz = z_mul_mpz;
+ f->mul_si = z_mul_si;
+ f->pow_mpz = z_pow_mpz;
+ f->neg = z_neg;
+ f->cmp = z_cmp;
+ f->invert = z_invert;
+ f->div = z_div;
+ f->random = z_random;
+ f->from_hash = z_from_hash;
+ f->is1 = z_is1;
+ f->is0 = z_is0;
+ f->set0 = z_set0;
+ f->set1 = z_set1;
+ f->is_sqr = z_is_sqr;
+ f->sqrt = z_sqrt;
+ f->field_clear = z_field_clear;
+ f->to_bytes = z_to_bytes;
+ f->from_bytes = z_from_bytes;
+ f->to_mpz = z_to_mpz;
+ f->length_in_bytes = z_length_in_bytes;
+
+ f->out_info = z_out_info;
+
+ mpz_set_ui(f->order, 0);
+ f->data = NULL;
+ f->fixed_length_in_bytes = -1;
+}