1 // Requires:
2 // * stdio.h
3 // * gmp.h
4 // * utils.h
5 // * field.h
6 // * param.h
7 #ifndef __PBC_PAIRING_H__
8 #define __PBC_PAIRING_H__
9
10 struct pairing_pp_s {
11 struct pairing_s *pairing;
12 void *data;
13 };
14 typedef struct pairing_pp_s pairing_pp_t[1];
15 typedef struct pairing_pp_s *pairing_pp_ptr;
16
17 struct pairing_s {
18 mpz_t r; // order of G1, G2, GT
19 field_t Zr; // the field Z_r
20 field_ptr G1, G2;
21 field_t GT; // group of rth roots of unity
22
23 mpz_t phikonr;
24 // Phi_k(q)/r where Phi_k is the kth cyclotomic polynomial,
25 // q as in F_q, is the base field
26
27 void (*phi)(element_ptr out, element_ptr in, struct pairing_s *pairing); //isomorphism G2 --> G1
28 void (*map)(element_ptr out, element_ptr in1, element_ptr in2,
29 struct pairing_s *p);
30 void (*prod_pairings)(element_ptr out, element_t in1[], element_t in2[], int n_prod,
31 struct pairing_s *p); //calculate a product of pairings at one time.
32 // is_almost coddh returns true given (g, g^x, h, h^x) or (g, g^x, h, h^-x)
33 // order is important: a, b are from G1, c, d are from G2
34 int (*is_almost_coddh)(element_ptr a, element_ptr b,
35 element_ptr c, element_ptr d,
36 struct pairing_s *p);
37 void (*clear_func)(struct pairing_s *);
38 void (*pp_init)(pairing_pp_t p, element_t in1, struct pairing_s *);
39 void (*pp_clear)(pairing_pp_t p);
40 void (*pp_apply)(element_t out, element_t in2, pairing_pp_t p);
41 void (*finalpow)(element_t e);
42 void (*option_set)(struct pairing_s *, char *key, char *value);
43 void *data;
44 };
45
46 typedef struct pairing_s pairing_t[1];
47 typedef struct pairing_s *pairing_ptr;
48
49 // TODO: The 'pairing' argument is redundant.
50 /*@manual pairing_apply
51 Get ready to perform a pairing whose first input is 'in1',
52 and store the results of time-saving precomputation in 'p'.
53 */
pairing_pp_init(pairing_pp_t p,element_t in1,pairing_t pairing)54 static inline void pairing_pp_init(pairing_pp_t p, element_t in1, pairing_t pairing) {
55 if (element_is0(in1)) {
56 p->pairing = NULL;
57 return;
58 }
59 p->pairing = pairing;
60 pairing->pp_init(p, in1, pairing);
61 }
62
63 /*@manual pairing_apply
64 Clear 'p'. This should be called after 'p' is no longer needed.
65 */
pairing_pp_clear(pairing_pp_t p)66 static inline void pairing_pp_clear(pairing_pp_t p) {
67 if (!p->pairing) {
68 // happens when p was initialized with identity
69 return;
70 }
71 p->pairing->pp_clear(p);
72 }
73
74 /*@manual pairing_apply
75 Compute a pairing using 'in2' and the preprocessed information stored in 'p'
76 and store the output in 'out'. The inputs to the pairing are the element
77 previously used to initialize 'p' and the element 'in2'.
78 */
pairing_pp_apply(element_t out,element_t in2,pairing_pp_t p)79 static inline void pairing_pp_apply(element_t out, element_t in2, pairing_pp_t p) {
80 if (!p->pairing) {
81 element_set0(out);
82 return;
83 }
84 if (element_is0(in2)) {
85 element_set0(out);
86 return;
87 }
88 p->pairing->pp_apply((element_ptr) out->data, in2, p);
89 }
90
91 /*@manual pairing_init
92 Initialize pairing from parameters in a ASCIIZ string 'str'
93 Returns 0 on success, 1 on failure.
94 */
95 int pairing_init_set_str(pairing_t pairing, const char *s);
96
97 /*@manual pairing_init
98 Same, but read at most 'len' bytes.
99 If 'len' is 0, it behaves as the previous function.
100 Returns 0 on success, 1 on failure.
101 */
102 int pairing_init_set_buf(pairing_t pairing, const char *s, size_t len);
103
104 /*@manual pairing_init
105 Initialize a pairing with pairing parameters 'p'.
106 */
107 void pairing_init_pbc_param(struct pairing_s *pairing, pbc_param_ptr p);
108
109 /*@manual pairing_init
110 Free the space occupied by 'pairing'. Call
111 whenever a +pairing_t+ variable is no longer needed.
112 Only call this after all elements associated with 'pairing'
113 have been cleared, as they need information stored in the 'pairing'
114 structure.
115 */
116 void pairing_clear(pairing_t pairing);
117
pairing_apply(element_t out,element_t in1,element_t in2,pairing_t pairing)118 static inline void pairing_apply(element_t out, element_t in1, element_t in2,
119 pairing_t pairing) {
120 PBC_ASSERT(pairing->GT == out->field, "pairing output mismatch");
121 PBC_ASSERT(pairing->G1 == in1->field, "pairing 1st input mismatch");
122 PBC_ASSERT(pairing->G2 == in2->field, "pairing 2nd input mismatch");
123 if (element_is0(in1)) {
124 element_set0(out);
125 return;
126 }
127 if (element_is0(in2)) {
128 element_set0(out);
129 return;
130 }
131 // TODO: 'out' is an element of a multiplicative subgroup, but the
132 // pairing routine expects it to be an element of the full group, hence
133 // the 'out->data'. I should make this clearer.
134 pairing->map((element_ptr) out->data, in1, in2, pairing);
135 }
136
137 /*@manual pairing_apply
138 Computes a pairing: 'out' = 'e'('in1', 'in2'),
139 where 'in1', 'in2', 'out' must be in the groups G1, G2, GT.
140 */
element_pairing(element_t out,element_t in1,element_t in2)141 static inline void element_pairing(element_t out, element_t in1, element_t in2) {
142 pairing_ptr pairing = out->field->pairing;
143 PBC_ASSERT(pairing != NULL, "pairing output mismatch");
144 pairing_apply(out, in1, in2, pairing);
145 }
146
147 /*@manual pairing_apply
148 Computes the product of pairings, that is
149 'out' = 'e'('in1'[0], 'in2'[0]) ... 'e'('in1'[n-1], 'in2'[n-1]).
150 The arrays 'in1', 'in2' must have at least 'n' elements belonging to
151 the groups G1, G2 respectively, and 'out' must belong to the group GT.
152 */
element_prod_pairing(element_t out,element_t in1[],element_t in2[],int n)153 static inline void element_prod_pairing(
154 element_t out, element_t in1[], element_t in2[], int n) {
155 pairing_ptr pairing = out->field->pairing;
156 int i;
157 PBC_ASSERT(pairing->GT == out->field, "pairing output mismatch");
158 for(i = 0; i < n; i++) {
159 PBC_ASSERT(pairing->G1 == in1[i]->field, "pairing 1st input mismatch");
160 PBC_ASSERT(pairing->G2 == in2[i]->field, "pairing 2nd input mismatch");
161 if (element_is0(in1[i])) {
162 element_set0(out);
163 return;
164 }
165 if (element_is0(in2[i])) {
166 element_set0(out);
167 return;
168 }
169 }
170 pairing->prod_pairings((element_ptr) out->data, in1, in2, n, pairing);
171 }
172
173 /*@manual pairing_op
174 Returns true if G1 and G2 are the same group.
175 */
pairing_is_symmetric(pairing_t pairing)176 static inline int pairing_is_symmetric(pairing_t pairing) {
177 return pairing->G1 == pairing->G2;
178 }
179
180 /*@manual pairing_op
181 Returns the length in bytes needed to represent an element of G1.
182 */
pairing_length_in_bytes_G1(pairing_t pairing)183 static inline int pairing_length_in_bytes_G1(pairing_t pairing) {
184 return pairing->G1->fixed_length_in_bytes;
185 }
186
187 /*@manual pairing_op
188 Returns the length in bytes needed to represent the x-coordinate of
189 an element of G1.
190 */
pairing_length_in_bytes_x_only_G1(pairing_t pairing)191 static inline int pairing_length_in_bytes_x_only_G1(pairing_t pairing) {
192 return pairing->G1->fixed_length_in_bytes / 2;
193 }
194
195 /*@manual pairing_op
196 Returns the length in bytes needed to represent a compressed form of
197 an element of G1. There is some overhead in decompressing.
198 */
pairing_length_in_bytes_compressed_G1(pairing_t pairing)199 static inline int pairing_length_in_bytes_compressed_G1(pairing_t pairing) {
200 return pairing->G1->fixed_length_in_bytes / 2 + 1;
201 }
202
203 /*@manual pairing_op
204 Returns the length in bytes needed to represent an element of G2.
205 */
pairing_length_in_bytes_G2(pairing_t pairing)206 static inline int pairing_length_in_bytes_G2(pairing_t pairing) {
207 return pairing->G2->fixed_length_in_bytes;
208 }
209
210 /*@manual pairing_op
211 Returns the length in bytes needed to represent a compressed form of
212 an element of G2. There is some overhead in decompressing.
213 */
pairing_length_in_bytes_compressed_G2(pairing_t pairing)214 static inline int pairing_length_in_bytes_compressed_G2(pairing_t pairing) {
215 return pairing->G2->fixed_length_in_bytes / 2 + 1;
216 }
217
218 /*@manual pairing_op
219 Returns the length in bytes needed to represent the x-coordinate of
220 an element of G2.
221 */
pairing_length_in_bytes_x_only_G2(pairing_t pairing)222 static inline int pairing_length_in_bytes_x_only_G2(pairing_t pairing) {
223 return pairing->G2->fixed_length_in_bytes / 2;
224 }
225
226 /*@manual pairing_op
227 Returns the length in bytes needed to represent an element of GT.
228 */
pairing_length_in_bytes_GT(pairing_t pairing)229 static inline int pairing_length_in_bytes_GT(pairing_t pairing) {
230 return pairing->GT->fixed_length_in_bytes;
231 }
232
233 /*@manual pairing_op
234 Returns the length in bytes needed to represent an element of Zr.
235 */
pairing_length_in_bytes_Zr(pairing_t pairing)236 static inline int pairing_length_in_bytes_Zr(pairing_t pairing) {
237 return pairing->Zr->fixed_length_in_bytes;
238 }
239
is_almost_coddh(element_t a,element_t b,element_t c,element_t d,pairing_t pairing)240 static inline int is_almost_coddh(element_t a, element_t b,
241 element_t c, element_t d, pairing_t pairing) {
242 return pairing->is_almost_coddh(a, b, c, d, pairing);
243 }
244
245 /*@manual einit.1
246 */
element_init_G1(element_t e,pairing_t pairing)247 static inline void element_init_G1(element_t e, pairing_t pairing) {
248 element_init(e, pairing->G1);
249 }
250
251 /*@manual einit.1
252 */
element_init_G2(element_t e,pairing_t pairing)253 static inline void element_init_G2(element_t e, pairing_t pairing) {
254 element_init(e, pairing->G2);
255 }
256
257 /*@manual einit.1
258 Initialize 'e' to be an element of the group G1, G2 or GT of 'pairing'.
259 */
element_init_GT(element_t e,pairing_t pairing)260 static inline void element_init_GT(element_t e, pairing_t pairing) {
261 element_init(e, pairing->GT);
262 }
263
264 /*@manual einit.1
265 Initialize 'e' to be an element of the ring Z_r of 'pairing'.
266 r is the order of the groups G1, G2 and GT that are involved in the pairing.
267 */
element_init_Zr(element_t e,pairing_t pairing)268 static inline void element_init_Zr(element_t e, pairing_t pairing) {
269 element_init(e, pairing->Zr);
270 }
271
pairing_option_set(pairing_t pairing,char * key,char * value)272 static inline void pairing_option_set(pairing_t pairing, char *key, char *value) {
273 pairing->option_set(pairing, key, value);
274 }
275
276 // Initialize GT = group of rth roots of unity in f.
277 // Requires pairing->r has been set.
278 void pairing_GT_init(pairing_ptr pairing, field_t f);
279
280 #endif //__PBC_PAIRING_H__
281