1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <stdint.h> // for intptr_t
4 #include <stdlib.h>
5 #include <string.h>
6 #include <gmp.h>
7 #include "pbc_utils.h"
8 #include "pbc_field.h"
9 #include "pbc_poly.h"
10 #include "pbc_curve.h"
11 #include "pbc_param.h"
12 #include "pbc_pairing.h"
13 #include "pbc_memory.h"
14 
generic_is_almost_coddh(element_ptr a,element_ptr b,element_ptr c,element_ptr d,pairing_t pairing)15 static int generic_is_almost_coddh(element_ptr a, element_ptr b,
16     element_ptr c, element_ptr d, pairing_t pairing) {
17   int res = 0;
18   element_t t0, t1;
19 
20   element_init(t0, pairing->GT);
21   element_init(t1, pairing->GT);
22   element_pairing(t0, a, d);
23   element_pairing(t1, b, c);
24   if (!element_cmp(t0, t1)) {
25     res = 1;
26   } else {
27     element_mul(t0, t0, t1);
28     if (element_is1(t0)) res = 1;
29   }
30   element_clear(t0);
31   element_clear(t1);
32   return res;
33 }
34 
generic_prod_pairings(element_ptr out,element_t in1[],element_t in2[],int n,pairing_t pairing)35 static void generic_prod_pairings(element_ptr out, element_t in1[],
36     element_t in2[], int n, pairing_t pairing) {
37   pairing->map(out, in1[0], in2[0], pairing);
38   element_t tmp;
39   element_init_same_as(tmp, out);
40   int i;
41   for(i = 1; i < n; i++) {
42     pairing->map(tmp, in1[i], in2[i], pairing);
43     element_mul(out, out, tmp);
44   }
45   element_clear(tmp);
46 }
47 
phi_warning(element_ptr out,element_ptr in,pairing_ptr pairing)48 static void phi_warning(element_ptr out, element_ptr in, pairing_ptr pairing) {
49   UNUSED_VAR(out);
50   UNUSED_VAR(in);
51   UNUSED_VAR(pairing);
52   printf("Phi() not implemented for this pairing type yet!\n");
53 }
54 
default_option_set(struct pairing_s * pairing,char * key,char * value)55 static void default_option_set(struct pairing_s *pairing, char *key, char *value) {
56   UNUSED_VAR(pairing);
57   UNUSED_VAR(key);
58   UNUSED_VAR(value);
59 }
60 
default_pp_init(pairing_pp_t p,element_ptr in1,pairing_t pairing)61 static void default_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
62   UNUSED_VAR(pairing);
63   p->data = (void *) in1;
64 }
65 
default_pp_apply(element_ptr out,element_ptr in2,pairing_pp_t p)66 static void default_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
67   p->pairing->map(out, p->data, in2, p->pairing);
68 }
69 
default_pp_clear(pairing_pp_t p)70 static void default_pp_clear(pairing_pp_t p) {
71   UNUSED_VAR(p);
72 }
73 
pairing_init_pbc_param(pairing_t pairing,pbc_param_ptr p)74 void pairing_init_pbc_param(pairing_t pairing, pbc_param_ptr p) {
75   pairing->option_set = default_option_set;
76   pairing->pp_init = default_pp_init;
77   pairing->pp_clear = default_pp_clear;
78   pairing->pp_apply = default_pp_apply;
79   pairing->is_almost_coddh = generic_is_almost_coddh;
80   pairing->phi = phi_warning;
81   pairing->prod_pairings = generic_prod_pairings;
82   p->api->init_pairing(pairing, p->data);
83   pairing->G1->pairing = pairing;
84   pairing->G2->pairing = pairing;
85   pairing->GT->pairing = pairing;
86 }
87 
pairing_init_set_buf(pairing_t pairing,const char * input,size_t len)88 int pairing_init_set_buf(pairing_t pairing, const char *input, size_t len) {
89   pbc_param_t par;
90   int res = pbc_param_init_set_buf(par, input, len);
91   if (res) {
92     pbc_error("error initializing pairing");
93     return 1;
94   }
95   pairing_init_pbc_param(pairing, par);
96   pbc_param_clear(par);
97   return 0;
98 }
99 
pairing_init_set_str(pairing_t pairing,const char * s)100 int pairing_init_set_str(pairing_t pairing, const char *s) {
101   return pairing_init_set_buf(pairing, s, 0);
102 }
103 
pairing_clear(pairing_t pairing)104 void pairing_clear(pairing_t pairing) {
105   pairing->clear_func(pairing);
106 }
107 
108 // TODO: it's most likely better to add extra stuff to field_t
109 // so no new data structures are needed to create mulitplicative subgroups.
110 // Additionally the same code could be used with curve_t
111 // Will consider it later, especially if timings turn out bad
112 
gt_out_info(FILE * out,field_ptr f)113 static void gt_out_info(FILE *out, field_ptr f) {
114   gmp_fprintf(out, "roots of unity, order %Zd, ", f->order);
115   field_out_info(out, f->data);
116 }
117 
gt_from_hash(element_ptr e,void * data,int len)118 static void gt_from_hash(element_ptr e, void *data, int len) {
119   pairing_ptr pairing = e->field->pairing;
120   element_from_hash(e->data, data, len);
121   pairing->finalpow(e);
122 }
123 
gt_random(element_ptr e)124 static void gt_random(element_ptr e) {
125   pairing_ptr pairing = e->field->pairing;
126   element_random(e->data);
127   pairing->finalpow(e);
128 }
129 
130 // multiplicative subgroup of a field
mulg_field_clear(field_t f)131 static void mulg_field_clear(field_t f) {
132   UNUSED_VAR(f);
133 }
134 
mulg_init(element_ptr e)135 static void mulg_init(element_ptr e) {
136   e->data = pbc_malloc(sizeof(element_t));
137   field_ptr f = e->field->data;
138   element_init(e->data, f);
139   element_set1(e->data);
140 }
141 
mulg_clear(element_ptr e)142 static void mulg_clear(element_ptr e) {
143   element_clear(e->data);
144   pbc_free(e->data);
145 }
146 
mulg_set(element_ptr x,element_t a)147 static void mulg_set(element_ptr x, element_t a) {
148   element_set(x->data, a->data);
149 }
150 
mulg_cmp(element_ptr x,element_t a)151 static int mulg_cmp(element_ptr x, element_t a) {
152   return element_cmp(x->data, a->data);
153 }
154 
mulg_out_str(FILE * stream,int base,element_ptr e)155 static size_t mulg_out_str(FILE *stream, int base, element_ptr e) {
156   return element_out_str(stream, base, e->data);
157 }
158 
mulg_set_multiz(element_ptr e,multiz m)159 static void mulg_set_multiz(element_ptr e, multiz m) {
160   return element_set_multiz(e->data, m);
161 }
162 
mulg_set_str(element_ptr e,const char * s,int base)163 static int mulg_set_str(element_ptr e, const char *s, int base) {
164   return element_set_str(e->data, s, base);
165 }
166 
mulg_item_count(element_ptr e)167 static int mulg_item_count(element_ptr e) {
168   return element_item_count(e->data);
169 }
170 
mulg_item(element_ptr e,int i)171 static element_ptr mulg_item(element_ptr e, int i) {
172   return element_item(e->data, i);
173 }
174 
mulg_to_bytes(unsigned char * data,element_ptr e)175 static int mulg_to_bytes(unsigned char *data, element_ptr e) {
176   return element_to_bytes(data, e->data);
177 }
178 
mulg_from_bytes(element_ptr e,unsigned char * data)179 static int mulg_from_bytes(element_ptr e, unsigned char *data) {
180   return element_from_bytes(e->data, data);
181 }
182 
mulg_length_in_bytes(element_ptr e)183 static int mulg_length_in_bytes(element_ptr e) {
184   return element_length_in_bytes(e->data);
185 }
186 
mulg_snprint(char * s,size_t n,element_ptr e)187 static int mulg_snprint(char *s, size_t n, element_ptr e) {
188   return element_snprint(s, n, e->data);
189 }
190 
mulg_to_mpz(mpz_ptr z,element_ptr e)191 static void mulg_to_mpz(mpz_ptr z, element_ptr e) {
192   element_to_mpz(z, e->data);
193 }
194 
mulg_set1(element_t e)195 static void mulg_set1(element_t e) {
196   element_set1(e->data);
197 }
198 
mulg_mul(element_ptr x,element_t a,element_t b)199 static void mulg_mul(element_ptr x, element_t a, element_t b) {
200   element_mul(x->data, a->data, b->data);
201 }
202 
mulg_div(element_ptr x,element_t a,element_t b)203 static void mulg_div(element_ptr x, element_t a, element_t b) {
204   element_div(x->data, a->data, b->data);
205 }
206 
mulg_invert(element_ptr x,element_t a)207 static void mulg_invert(element_ptr x, element_t a) {
208   element_invert(x->data, a->data);
209 }
210 
mulg_is1(element_ptr x)211 static int mulg_is1(element_ptr x) {
212   return element_is1(x->data);
213 }
214 
mulg_pow_mpz(element_t x,element_t a,mpz_t n)215 static void mulg_pow_mpz(element_t x, element_t a, mpz_t n) {
216   element_pow_mpz(x->data, a->data, n);
217 }
218 
mulg_pp_init(element_pp_t p,element_t in)219 static void mulg_pp_init(element_pp_t p, element_t in) {
220   p->data = pbc_malloc(sizeof(element_pp_t));
221   element_pp_init(p->data, in->data);
222 }
223 
mulg_pp_clear(element_pp_t p)224 static void mulg_pp_clear(element_pp_t p) {
225   element_pp_clear(p->data);
226   pbc_free(p->data);
227 }
228 
mulg_pp_pow(element_t out,mpz_ptr power,element_pp_t p)229 static void mulg_pp_pow(element_t out, mpz_ptr power, element_pp_t p) {
230   element_pp_pow(out->data, power, p->data);
231 }
232 
pairing_GT_init(pairing_ptr pairing,field_t f)233 void pairing_GT_init(pairing_ptr pairing, field_t f) {
234   field_ptr gt = pairing->GT;
235   field_init(gt);
236   gt->data = f;
237   f->pairing = pairing;
238   mpz_set(gt->order, pairing->r);
239   gt->field_clear = mulg_field_clear;
240   gt->out_info = gt_out_info;
241 
242   gt->init = mulg_init;
243   gt->clear = mulg_clear;
244   gt->set = mulg_set;
245   gt->cmp = mulg_cmp;
246 
247   gt->out_str = mulg_out_str;
248   gt->set_multiz = mulg_set_multiz;
249   gt->set_str = mulg_set_str;
250   gt->to_bytes = mulg_to_bytes;
251   gt->from_bytes = mulg_from_bytes;
252   gt->length_in_bytes = mulg_length_in_bytes;
253   gt->fixed_length_in_bytes = f->fixed_length_in_bytes;
254   gt->to_mpz = mulg_to_mpz;
255   gt->snprint = mulg_snprint;
256   gt->item = mulg_item;
257   gt->item_count = mulg_item_count;
258 
259   // TODO: set gt->nqr to something?
260   // set is_sqr, sqrt to something?
261 
262   // additive notation
263   gt->set0 = mulg_set1;
264   gt->add = mulg_mul;
265   gt->sub = mulg_div;
266   gt->mul_mpz = mulg_pow_mpz;
267   gt->neg = mulg_invert;
268   gt->is0 = mulg_is1;
269 
270   // multiplicative notation
271   gt->set1 = mulg_set1;
272   gt->mul = mulg_mul;
273   gt->div = mulg_div;
274   gt->pow_mpz = mulg_pow_mpz;
275   gt->invert = mulg_invert;
276   gt->is1 = mulg_is1;
277   gt->pp_init = mulg_pp_init;
278   gt->pp_clear = mulg_pp_clear;
279   gt->pp_pow = mulg_pp_pow;
280 
281   gt->random = gt_random;
282   gt->from_hash = gt_from_hash;
283 }
284