2 #include "DIPE_Internal.h"
5 #include <nettle/hkdf.h>
6 #include <nettle/hmac.h>
7 #include <sys/random.h>
8 #include <nettle/gcm.h>
9 #include <nettle/memops.h>
10 #include <arpa/inet.h>
20 size_t dipe_h_length(element_t elem
, size_t dimension
) {
21 return 16 /*cid*/ + dimension
* element_length_in_bytes(elem
);
24 void dipe_generate_h(const char* cid
, element_t
* y
, size_t dimension
, unsigned char* result
) {
25 memcpy(result
, cid
, 16);
26 unsigned char* next_element
= result
+16;
27 for (size_t i
= 0; i
< dimension
; ++i
) {
28 element_to_bytes(next_element
, y
[i
]);
29 next_element
+= element_length_in_bytes(y
[0]);
33 void dipe_generate_aeskey(element_t encapkey
, uint8_t* aeskey
) {
34 struct hmac_sha256_ctx ctx
;
35 uint8_t salt
[SHA256_DIGEST_SIZE
];
36 memset(salt
, 0, SHA256_DIGEST_SIZE
);
37 size_t elen
= element_length_in_bytes(encapkey
);
39 element_to_bytes(coded
, encapkey
);
41 hmac_sha256_set_key(&ctx
, SHA256_DIGEST_SIZE
, salt
);
43 (nettle_hash_update_func
*)hmac_sha256_update
,
44 (nettle_hash_digest_func
*)hmac_sha256_digest
,
50 /* Data format is iv | enc(4 byte len | ptxt | 0 padding) | tag
52 int dipe_aes_encrypt(uint8_t* key
, uint8_t* iv
, size_t ptxt_len
, uint8_t* ptxt
, size_t ctxt_len
, uint8_t* ctxt
) {
53 struct gcm_aes128_ctx ctx
;
55 uint32_t coded_ptxtlen
;
57 ctxt_len
-= 16; /* Tag */
58 if (ctxt_len
< ptxt_len
+ 4) return 0;
61 gcm_aes128_set_key(&ctx
, key
);
62 gcm_aes128_set_iv(&ctx
, 12, iv
);
65 coded_ptxtlen
= htonl(ptxt_len
);
66 memcpy(block
, &coded_ptxtlen
, 4);
67 memcpy(block
+4, ptxt
, min((size_t)12, ptxt_len
));
68 ptxt_len
-= min((size_t)12, ptxt_len
);
71 while (ctxt_len
>= 16) {
72 gcm_aes128_encrypt(&ctx
, 16, ctxt
, block
);
78 memcpy(block
, ptxt
, min((size_t)16, ptxt_len
));
80 ptxt_len
-= min((size_t)16, ptxt_len
);
85 gcm_aes128_encrypt(&ctx
, ctxt_len
, ctxt
, block
);
89 gcm_aes128_digest(&ctx
, 16, ctxt
);
93 int dipe_aes_decrypt(uint8_t* key
, uint8_t* iv
, size_t len
, uint8_t* ctxt
, uint8_t* ptxt
) {
94 struct gcm_aes128_ctx ctx
;
97 gcm_aes128_set_key(&ctx
, key
);
98 gcm_aes128_set_iv(&ctx
, 12, iv
);
99 len
-= 16; /* GCM tag */
102 gcm_aes128_decrypt(&ctx
, min((size_t)16, len
), block
, ctxt
);
103 uint32_t ptxtlen
= 0;
104 memcpy(&ptxtlen
, block
, 4);
105 memcpy(ptxt
, block
+4, min((size_t)12, len
-4));
106 ptxtlen
= ntohl(ptxtlen
);
107 ctxt
+= min((size_t)16, len
); len
-= min((size_t)16, len
);
111 gcm_aes128_decrypt(&ctx
, len
, ptxt
, ctxt
);
114 gcm_aes128_digest(&ctx
, 16, block
);
116 /* error case is with return code 0, see manual
117 * https://www.lysator.liu.se/~nisse/nettle/nettle.html#Miscellaneous-functions
119 if (memeql_sec(ctxt
, block
, 16) == 0)
126 /* Note: we need a curve where membership checking is hard for all
127 * group elements. See also https://ia.cr/2015/247 and followups
129 void dipe_init(FILE* configfp
, dipe_param_t
* param
) {
131 (*param
) = (dipe_param_t
)malloc(sizeof(dipe_param
));
132 fread(buffer
, 1, 2<<16, configfp
);
134 pairing_init_set_buf((*param
)->pairing
, buffer
, 2<<16);
136 element_init_G1((*param
)->g1
, (*param
)->pairing
);
137 element_init_G2((*param
)->g2
, (*param
)->pairing
);
138 element_init_GT((*param
)->gt
, (*param
)->pairing
);
140 element_random((*param
)->g1
);
141 element_random((*param
)->g2
);
142 pairing_apply((*param
)->gt
, (*param
)->g1
, (*param
)->g2
, (*param
)->pairing
);
145 pairing_t
* dipe_get_pairing(dipe_param_t param
) {
146 return &(param
->pairing
);
149 void dipe_master_keygen(dipe_param_t param
, size_t dimension
, dipe_master_publickey_t
* pk
, dipe_master_secretkey_t
* sk
) {
150 *pk
= (dipe_master_publickey_t
)malloc(sizeof(dipe_master_publickey
));
151 *sk
= (dipe_master_secretkey_t
)malloc(sizeof(dipe_master_secretkey
));
153 (*sk
)->dimension
= (*pk
)->dimension
= dimension
;
154 element_init_Zr((*pk
)->aid
, param
->pairing
);
155 element_init_Zr((*sk
)->aid
, param
->pairing
);
156 element_random((*pk
)->aid
);
157 element_set((*sk
)->aid
, (*pk
)->aid
);
159 element_init_Zr((*sk
)->a
, param
->pairing
);
160 element_init_GT((*pk
)->a
, param
->pairing
);
161 element_random((*sk
)->a
);
162 element_pow_zn((*pk
)->a
, param
->gt
, (*sk
)->a
);
164 (*sk
)->k
= (element_t
*)calloc(dimension
, sizeof(element_t
));
165 (*pk
)->k
= (element_t
*)calloc(dimension
, sizeof(element_t
));
166 for (size_t i
= 0; i
< dimension
; ++i
) {
167 element_init_Zr((*sk
)->k
[i
], param
->pairing
);
168 element_init_G1((*pk
)->k
[i
], param
->pairing
);
169 element_random((*sk
)->k
[i
]);
170 element_pow_zn((*pk
)->k
[i
], param
->g1
, (*sk
)->k
[i
]);
174 void dipe_keygen(dipe_param_t param
, dipe_master_secretkey_t msk
, const char* cid
, element_t
* y
, dipe_secretkey_t
* sk
) {
175 *sk
= (dipe_secretkey_t
)malloc(sizeof(dipe_secretkey
));
176 (*sk
)->dimension
= msk
->dimension
;
177 element_init_G2((*sk
)->d
, param
->pairing
);
178 element_init_Zr((*sk
)->aid
, param
->pairing
);
179 element_set((*sk
)->aid
, msk
->aid
);
181 size_t hash_input_length
= dipe_h_length(y
[0], msk
->dimension
);
182 unsigned char hash_input
[hash_input_length
];
184 element_init_G2(h
, param
->pairing
);
186 dipe_generate_h(cid
, y
, msk
->dimension
, hash_input
);
187 element_from_hash(h
, hash_input
, hash_input_length
);
192 element_init_Zr(innerp
, param
->pairing
);
193 element_init_Zr(tmp
, param
->pairing
);
194 element_set0(innerp
);
196 element_from_hash(h
, hash_input
, hash_input_length
);
198 for (size_t i
= 0; i
< msk
->dimension
; ++i
) {
199 element_mul(tmp
, y
[i
], msk
->k
[i
]);
200 element_add(innerp
, innerp
, tmp
);
204 element_init_G2(a2
, param
->pairing
);
205 element_pow_zn(h
, h
, innerp
);
206 element_pow_zn(a2
, param
->g2
, msk
->a
);
207 element_mul((*sk
)->d
, a2
, h
);
210 element_clear(innerp
);
215 void dipe_encap(dipe_param_t param
, size_t mpkcount
, dipe_master_publickey_t
* mpk
, size_t threshold
, element_t
* x
, element_t ptxt
, dipe_ctxt_t
* ctxt
) {
216 *ctxt
= (dipe_ctxt_t
)malloc(sizeof(dipe_ctxt
));
217 (*ctxt
)->dimension
= mpk
[0]->dimension
;
218 (*ctxt
)->sharecount
= mpkcount
- threshold
/* TODO */;
220 element_t r
[(*ctxt
)->sharecount
];
222 element_t faid
[(*ctxt
)->sharecount
];
223 element_t aid
[mpkcount
];
226 element_init_Zr(s
, param
->pairing
);
228 element_init_Zr(r0
, param
->pairing
);
231 element_init_G1((*ctxt
)->s
, param
->pairing
);
232 element_pow_zn((*ctxt
)->s
, param
->g1
, s
);
234 (*ctxt
)->cx
= (element_t
*)calloc((*ctxt
)->dimension
, sizeof(element_t
));
235 (*ctxt
)->shares
= (struct dipe_ctxt_share
*)calloc((*ctxt
)->sharecount
, sizeof(struct dipe_ctxt_share
));
236 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
237 element_init_Zr((*ctxt
)->shares
[i
].aid
, param
->pairing
);
238 element_init_Zr(faid
[i
], param
->pairing
);
239 element_random((*ctxt
)->shares
[i
].aid
);
240 element_set(faid
[i
], (*ctxt
)->shares
[i
].aid
);
242 element_init_Zr(r
[i
], param
->pairing
);
243 element_random(r
[i
]);
246 element_t
* ashares
[mpkcount
];
247 for (size_t i
= 0; i
< mpkcount
; ++i
) {
248 ashares
[i
] = &(mpk
[i
]->a
);
249 element_init_Zr(aid
[i
], param
->pairing
);
250 element_set(aid
[i
], mpk
[i
]->aid
);
252 element_t
* adummyshares
[(*ctxt
)->sharecount
];
253 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
254 adummyshares
[i
] = &((*ctxt
)->shares
[i
].c
);
256 dipe_ss_share(param
, mpkcount
, aid
, (*ctxt
)->sharecount
, faid
, 1, ashares
, &((*ctxt
)->c
), adummyshares
);
258 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
259 element_pow_zn((*ctxt
)->shares
[i
].c
, (*ctxt
)->shares
[i
].c
, s
);
261 element_pow_zn((*ctxt
)->c
, (*ctxt
)->c
, s
);
262 element_mul((*ctxt
)->c
, (*ctxt
)->c
, ptxt
);
265 element_t
* kshares
[mpkcount
];
266 for (size_t i
= 0; i
< mpkcount
; ++i
) {
267 kshares
[i
] = mpk
[i
]->k
;
269 element_t
* kdummyshares
[(*ctxt
)->sharecount
];
270 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
271 kdummyshares
[i
] = (*ctxt
)->shares
[i
].cx
= (element_t
*)calloc((*ctxt
)->dimension
, sizeof(element_t
));
275 element_init_G1(tmp
, param
->pairing
);
276 dipe_ss_share(param
, mpkcount
, aid
, (*ctxt
)->sharecount
, faid
, (*ctxt
)->dimension
, kshares
, (*ctxt
)->cx
, kdummyshares
);
278 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
279 for (size_t j
= 0; j
< (*ctxt
)->dimension
; ++j
) {
280 element_pow_zn((*ctxt
)->shares
[i
].cx
[j
], (*ctxt
)->shares
[i
].cx
[j
], s
);
281 element_pow_zn(tmp
, param
->g1
, x
[j
]);
282 element_pow_zn(tmp
, tmp
, r
[i
]);
283 element_mul((*ctxt
)->shares
[i
].cx
[j
], (*ctxt
)->shares
[i
].cx
[j
], tmp
);
286 for (size_t j
= 0; j
< (*ctxt
)->dimension
; ++j
) {
287 element_pow_zn((*ctxt
)->cx
[j
], (*ctxt
)->cx
[j
], s
);
288 element_pow_zn(tmp
, param
->g1
, x
[j
]);
289 element_pow_zn(tmp
, tmp
, r0
);
290 element_mul((*ctxt
)->cx
[j
], (*ctxt
)->cx
[j
], tmp
);
294 for (size_t i
= 0; i
< (*ctxt
)->sharecount
; ++i
) {
296 element_clear(faid
[i
]);
298 for (size_t i
= 0; i
< mpkcount
; ++i
) {
299 element_clear(aid
[i
]);
307 void dipe_decap(dipe_param_t param
, size_t skcount
, dipe_secretkey_t
* sk
, const char* cid
, element_t
* y
, dipe_ctxt_t ctxt
, element_t ptxt
) {
308 size_t hash_input_length
= dipe_h_length(y
[0], sk
[0]->dimension
);
309 unsigned char hash_input
[hash_input_length
];
311 element_init_G2(h
, param
->pairing
);
313 dipe_generate_h(cid
, y
, sk
[0]->dimension
, hash_input
);
314 element_from_hash(h
, hash_input
, hash_input_length
);
319 element_init_GT(tmp
, param
->pairing
);
320 element_init_GT(innerp
, param
->pairing
);
321 element_init_G2(hy
, param
->pairing
);
323 element_t aid
[skcount
+ ctxt
->sharecount
];
324 element_t
* beta
[skcount
+ ctxt
->sharecount
];
325 for (size_t i
= 0; i
< skcount
; ++i
) {
326 beta
[i
] = (element_t
*)calloc(1, sizeof(element_t
));
327 element_init_GT(*(beta
[i
]), param
->pairing
);
328 element_init_Zr(aid
[i
], param
->pairing
);
329 element_set(aid
[i
], sk
[i
]->aid
);
330 pairing_apply(*(beta
[i
]), ctxt
->s
, sk
[i
]->d
, param
->pairing
);
332 for (size_t i
= 0; i
< ctxt
->sharecount
; ++i
) {
333 beta
[skcount
+i
] = (element_t
*)calloc(1, sizeof(element_t
));
334 element_init_GT(*(beta
[skcount
+i
]), param
->pairing
);
335 element_init_Zr(aid
[skcount
+i
], param
->pairing
);
336 element_set(aid
[skcount
+i
], ctxt
->shares
[i
].aid
);
338 element_set1(innerp
);
339 for (size_t j
= 0; j
< sk
[0]->dimension
; ++j
) {
340 element_pow_zn(hy
, h
, y
[j
]);
341 pairing_apply(tmp
, ctxt
->shares
[i
].cx
[j
], hy
, param
->pairing
);
342 element_mul(innerp
, innerp
, tmp
);
344 element_mul(*(beta
[skcount
+i
]), ctxt
->shares
[i
].c
, innerp
);
347 element_t recover
[1];
348 dipe_ss_recover(param
, skcount
+ ctxt
->sharecount
, aid
, 1, beta
, recover
);
349 element_set(ptxt
, recover
[0]);
350 element_clear(recover
[0]);
352 element_set1(innerp
);
353 for (size_t i
= 0; i
< sk
[0]->dimension
; ++i
) {
354 element_pow_zn(hy
, h
, y
[i
]);
355 pairing_apply(tmp
, ctxt
->cx
[i
], hy
, param
->pairing
);
356 element_mul(innerp
, innerp
, tmp
);
359 element_invert(ptxt
, ptxt
);
360 element_mul(ptxt
, ptxt
, ctxt
->c
);
361 element_mul(ptxt
, ptxt
, innerp
); /* innerp */
363 for (size_t i
= 0; i
< skcount
+ ctxt
->sharecount
; ++i
) {
364 element_clear(aid
[i
]);
365 element_clear(*(beta
[i
]));
371 element_clear(innerp
);
375 void dipe_encrypt(dipe_param_t param
, size_t mpkcount
, dipe_master_publickey_t
* mpk
, size_t threshold
, element_t
* x
, size_t ptxt_len
, char* ptxt
, size_t ctxt_len
, char* ctxt
) {
381 element_init_GT(key
, param
->pairing
);
383 dipe_generate_aeskey(key
, aes
);
384 dipe_encap(param
, mpkcount
, mpk
, threshold
, x
, key
, &cap
);
385 cap_len
= dipe_serialize_ctxt(param
, cap
, (uint8_t*)ctxt
);
386 ctxt
+= cap_len
; ctxt_len
-= cap_len
;
388 dipe_aes_encrypt(aes
, aes
+16, ptxt_len
, (uint8_t*)ptxt
, ctxt_len
, (uint8_t*)ctxt
);
394 size_t dipe_decrypt(dipe_param_t param
, size_t skcount
, dipe_secretkey_t
* sk
, size_t sharecount
, const char* cid
, element_t
* y
, size_t ctxt_len
, char* ctxt
, char* ptxt
) {
400 element_init_GT(key
, param
->pairing
);
401 cap_len
= dipe_deserialize_ctxt(param
, sk
[0]->dimension
, sharecount
, &cap
, (uint8_t*)ctxt
);
404 dipe_decap(param
, skcount
, sk
, cid
, y
, cap
, key
);
405 dipe_generate_aeskey(key
, aes
);
410 return dipe_aes_decrypt(aes
, aes
+16, ctxt_len
, (uint8_t*)ctxt
, (uint8_t*)ptxt
);
413 /* Note: we're generating random-looking bytes here. Therefore we
414 * can't encode the dimension of the predicate vector (supposed to be
415 * set as system parameter) or information about the secret sharing
416 * (needs to be retrieved by some sort of trial decryption).
418 size_t dipe_serialize_ctxt(__attribute__((unused
)) dipe_param_t param
, dipe_ctxt_t ctxt
, uint8_t* buffer
) {
419 size_t bytes_written
= 0;
420 element_to_bytes_compressed(buffer
, ctxt
->s
);
421 buffer
+= element_length_in_bytes_compressed(ctxt
->s
);
422 bytes_written
+= element_length_in_bytes_compressed(ctxt
->s
);
424 for (size_t i
= 0; i
< ctxt
->dimension
; ++i
) {
425 element_to_bytes_compressed(buffer
, ctxt
->cx
[i
]);
426 buffer
+= element_length_in_bytes_compressed(ctxt
->cx
[i
]);
427 bytes_written
+= element_length_in_bytes_compressed(ctxt
->cx
[i
]);
430 element_to_bytes(buffer
, ctxt
->c
);
431 buffer
+= element_length_in_bytes(ctxt
->c
);
432 bytes_written
+= element_length_in_bytes(ctxt
->c
);
434 for (size_t j
= 0; j
< ctxt
->sharecount
; ++j
) {
435 element_to_bytes(buffer
, ctxt
->shares
[j
].aid
);
436 buffer
+= element_length_in_bytes(ctxt
->shares
[j
].aid
);
437 bytes_written
+= element_length_in_bytes(ctxt
->shares
[j
].aid
);
439 for (size_t i
= 0; i
< ctxt
->dimension
; ++i
) {
440 element_to_bytes_compressed(buffer
, ctxt
->shares
[j
].cx
[i
]);
441 buffer
+= element_length_in_bytes_compressed(ctxt
->shares
[j
].cx
[i
]);
442 bytes_written
+= element_length_in_bytes_compressed(ctxt
->shares
[j
].cx
[i
]);
445 element_to_bytes(buffer
, ctxt
->shares
[j
].c
);
446 buffer
+= element_length_in_bytes(ctxt
->shares
[j
].c
);
447 bytes_written
+= element_length_in_bytes(ctxt
->shares
[j
].c
);
450 return bytes_written
;
453 size_t dipe_deserialize_ctxt(dipe_param_t param
, size_t dimension
, size_t shares
, dipe_ctxt_t
* ctxt
, uint8_t* buffer
) {
454 size_t bytes_read
= 0;
455 *ctxt
= (dipe_ctxt_t
)malloc(sizeof(dipe_ctxt
));
456 (*ctxt
)->dimension
= dimension
;
457 (*ctxt
)->sharecount
= shares
;
459 element_init_G1((*ctxt
)->s
, param
->pairing
);
460 element_from_bytes_compressed((*ctxt
)->s
, buffer
);
461 buffer
+= element_length_in_bytes_compressed((*ctxt
)->s
);
462 bytes_read
+= element_length_in_bytes_compressed((*ctxt
)->s
);
464 (*ctxt
)->cx
= (element_t
*)calloc(dimension
, sizeof(element_t
));
465 for (size_t i
= 0; i
< dimension
; ++i
) {
466 element_init_G1((*ctxt
)->cx
[i
], param
->pairing
);
467 element_from_bytes_compressed((*ctxt
)->cx
[i
], buffer
);
468 buffer
+= element_length_in_bytes_compressed((*ctxt
)->cx
[i
]);
469 bytes_read
+= element_length_in_bytes_compressed((*ctxt
)->cx
[i
]);
472 element_init_GT((*ctxt
)->c
, param
->pairing
);
473 element_from_bytes((*ctxt
)->c
, buffer
);
474 buffer
+= element_length_in_bytes((*ctxt
)->c
);
475 bytes_read
+= element_length_in_bytes((*ctxt
)->c
);
478 (*ctxt
)->shares
= (struct dipe_ctxt_share
*)calloc(shares
, sizeof(struct dipe_ctxt_share
));
479 for (size_t j
= 0; j
< shares
; ++j
) {
480 element_init_Zr((*ctxt
)->shares
[j
].aid
, param
->pairing
);
481 element_from_bytes((*ctxt
)->shares
[j
].aid
, buffer
);
482 buffer
+= element_length_in_bytes((*ctxt
)->shares
[j
].aid
);
483 bytes_read
+= element_length_in_bytes((*ctxt
)->shares
[j
].aid
);
485 (*ctxt
)->shares
[j
].cx
= (element_t
*)calloc(dimension
, sizeof(element_t
));
486 for (size_t i
= 0; i
< dimension
; ++i
) {
487 element_init_G1((*ctxt
)->shares
[j
].cx
[i
], param
->pairing
);
488 element_from_bytes_compressed((*ctxt
)->shares
[j
].cx
[i
], buffer
);
489 buffer
+= element_length_in_bytes_compressed((*ctxt
)->shares
[j
].cx
[i
]);
490 bytes_read
+= element_length_in_bytes_compressed((*ctxt
)->shares
[j
].cx
[i
]);
493 element_init_GT((*ctxt
)->shares
[j
].c
, param
->pairing
);
494 element_from_bytes((*ctxt
)->shares
[j
].c
, buffer
);
495 buffer
+= element_length_in_bytes((*ctxt
)->shares
[j
].c
);
496 bytes_read
+= element_length_in_bytes((*ctxt
)->shares
[j
].c
);
502 size_t dipe_ciphertext_overhead(dipe_param_t param
, size_t dimension
, size_t shares
) {
503 size_t overhead
= 16 + 4 /* IV + Tag + Size */;
507 element_init_G1(t
, param
->pairing
);
508 overhead
+= element_length_in_bytes_compressed(t
);
511 overhead
+= (1+shares
) * dimension
* element_length_in_bytes_compressed(t
);
515 element_init_GT(t
, param
->pairing
);
516 overhead
+= (1+shares
) * element_length_in_bytes(t
);
520 element_init_Zr(t
, param
->pairing
);
521 overhead
+= shares
* element_length_in_bytes(t
);
527 void dipe_free_param(dipe_param_t param
) {
528 element_clear(param
->g1
);
529 element_clear(param
->g2
);
530 element_clear(param
->gt
);
531 pairing_clear(param
->pairing
);
535 void dipe_free_master_secretkey(dipe_master_secretkey_t sk
) {
536 for (size_t i
= 0; i
< sk
->dimension
; ++i
) {
537 element_clear(sk
->k
[i
]);
539 element_clear(sk
->a
);
541 element_clear(sk
->aid
);
545 void dipe_free_master_publickey(dipe_master_publickey_t pk
) {
546 for (size_t i
= 0; i
< pk
->dimension
; ++i
) {
547 element_clear(pk
->k
[i
]);
549 element_clear(pk
->a
);
551 element_clear(pk
->aid
);
555 void dipe_free_secretkey(dipe_secretkey_t sk
) {
556 element_clear(sk
->d
);
557 element_clear(sk
->aid
);
561 void dipe_free_ctxt(dipe_ctxt_t ctxt
) {
562 for (size_t j
= 0; j
< ctxt
->dimension
; ++j
) {
563 element_clear(ctxt
->cx
[j
]);
565 element_clear(ctxt
->c
);
568 for (size_t i
= 0; i
< ctxt
->sharecount
; ++i
) {
569 for (size_t j
= 0; j
< ctxt
->dimension
; ++j
) {
570 element_clear(ctxt
->shares
[i
].cx
[j
]);
572 element_clear(ctxt
->shares
[i
].c
);
573 element_clear(ctxt
->shares
[i
].aid
);
574 free(ctxt
->shares
[i
].cx
);
578 element_clear(ctxt
->s
);