4 #include <nettle/hkdf.h>
5 #include <nettle/hmac.h>
6 #include <sys/random.h>
7 #include <nettle/gcm.h>
8 #include <nettle/memops.h>
23 struct dipe_master_publickey
{
29 struct dipe_master_secretkey
{
35 struct dipe_secretkey
{
49 size_t dipe_h_length(element_t elem
, size_t dimension
) {
50 return 16 /*cid*/ + dimension
* element_length_in_bytes(elem
);
53 void dipe_generate_h(char* cid
, element_t
* y
, size_t dimension
, unsigned char* result
) {
54 memcpy(result
, cid
, 16);
55 unsigned char* next_element
= result
+16;
56 for (size_t i
= 0; i
< dimension
; ++i
) {
57 element_to_bytes(next_element
, y
[i
]);
58 next_element
+= element_length_in_bytes(y
[0]);
62 void dipe_generate_aeskey(element_t encapkey
, uint8_t* aeskey
) {
63 struct hmac_sha256_ctx ctx
;
64 uint8_t salt
[SHA256_DIGEST_SIZE
];
65 memset(salt
, 0, SHA256_DIGEST_SIZE
);
66 size_t elen
= element_length_in_bytes(encapkey
);
68 element_to_bytes(coded
, encapkey
);
70 hmac_sha256_set_key(&ctx
, SHA256_DIGEST_SIZE
, salt
);
72 (nettle_hash_update_func
*)hmac_sha256_update
,
73 (nettle_hash_digest_func
*)hmac_sha256_digest
,
79 /* Data format is iv | enc(4 byte len | ptxt | 0 padding) | tag
81 int dipe_aes_encrypt(uint8_t* key
, size_t ptxt_len
, uint8_t* ptxt
, size_t ctxt_len
, uint8_t* ctxt
) {
82 struct gcm_aes128_ctx ctx
;
85 uint32_t coded_ptxtlen
;
87 ctxt_len
-= (12 + 16); /* IV + Tag */
88 if (ctxt_len
< ptxt_len
) return -1;
94 gcm_aes128_set_key(&ctx
, key
);
95 gcm_aes128_set_iv(&ctx
, 12, iv
);
98 coded_ptxtlen
= htonl(ptxt_len
);
99 memcpy(block
, &coded_ptxtlen
, 4);
100 memcpy(block
+4, ptxt
, min((size_t)12, ptxt_len
));
101 ptxt_len
-= min((size_t)12, ptxt_len
);
104 while (ctxt_len
>= 16) {
105 gcm_aes128_encrypt(&ctx
, 16, ctxt
, block
);
106 memset(block
, 0, 16);
111 memcpy(block
, ptxt
, min((size_t)16, ptxt_len
));
113 ptxt_len
-= min((size_t)16, ptxt_len
);
118 gcm_aes128_encrypt(&ctx
, ctxt_len
, ctxt
, block
);
122 gcm_aes128_digest(&ctx
, 16, ctxt
);
126 int dipe_aes_decrypt(uint8_t* key
, size_t len
, uint8_t* ctxt
, uint8_t* ptxt
) {
127 struct gcm_aes128_ctx ctx
;
130 gcm_aes128_set_key(&ctx
, key
);
131 gcm_aes128_set_iv(&ctx
, 12, ctxt
);
132 ctxt
+= 12; len
-= 12;
133 len
-= 16; /* GCM tag */
136 gcm_aes128_decrypt(&ctx
, min((size_t)16, len
), block
, ctxt
);
137 uint32_t ptxtlen
= 0;
138 memcpy(&ptxtlen
, block
, 4);
139 memcpy(ptxt
, block
+4, min((size_t)12, len
-4));
140 ptxtlen
= ntohl(ptxtlen
);
141 ctxt
+= min((size_t)16, len
); len
-= min((size_t)16, len
);
145 gcm_aes128_decrypt(&ctx
, len
, ptxt
, ctxt
);
148 gcm_aes128_digest(&ctx
, 16, block
);
150 /* error case is with return code 0, see manual
151 * https://www.lysator.liu.se/~nisse/nettle/nettle.html#Miscellaneous-functions
153 if (memeql_sec(ctxt
, block
, 16) == 0)
160 /* Note: we need a curve where membership checking is hard for all
161 * group elements. See also https://ia.cr/2015/247 and followups
163 void dipe_init(FILE* configfp
, dipe_param_t
* param
) {
165 (*param
) = (dipe_param_t
)malloc(sizeof(dipe_param
));
166 fread(buffer
, 1, 2<<16, configfp
);
168 pairing_init_set_buf((*param
)->pairing
, buffer
, 2<<16);
170 element_init_G1((*param
)->g1
, (*param
)->pairing
);
171 element_init_G2((*param
)->g2
, (*param
)->pairing
);
172 element_init_GT((*param
)->gt
, (*param
)->pairing
);
174 element_random((*param
)->g1
);
175 element_random((*param
)->g2
);
176 pairing_apply((*param
)->gt
, (*param
)->g1
, (*param
)->g2
, (*param
)->pairing
);
179 pairing_t
* dipe_get_pairing(dipe_param_t param
) {
180 return &(param
->pairing
);
183 void dipe_master_keygen(dipe_param_t param
, size_t dimension
, dipe_master_publickey_t
* pk
, dipe_master_secretkey_t
* sk
) {
184 *pk
= (dipe_master_publickey_t
)malloc(sizeof(dipe_master_publickey
));
185 *sk
= (dipe_master_secretkey_t
)malloc(sizeof(dipe_master_secretkey
));
187 (*sk
)->dimension
= (*pk
)->dimension
= dimension
;
189 element_init_Zr((*sk
)->a
, param
->pairing
);
190 element_init_GT((*pk
)->a
, param
->pairing
);
191 element_random((*sk
)->a
);
192 element_pow_zn((*pk
)->a
, param
->gt
, (*sk
)->a
);
194 (*sk
)->k
= (element_t
*)calloc(dimension
, sizeof(element_t
));
195 (*pk
)->k
= (element_t
*)calloc(dimension
, sizeof(element_t
));
196 for (size_t i
= 0; i
< dimension
; ++i
) {
197 element_init_Zr((*sk
)->k
[i
], param
->pairing
);
198 element_init_G1((*pk
)->k
[i
], param
->pairing
);
199 element_random((*sk
)->k
[i
]);
200 element_pow_zn((*pk
)->k
[i
], param
->g1
, (*sk
)->k
[i
]);
204 void dipe_keygen(dipe_param_t param
, dipe_master_secretkey_t msk
, char* cid
, element_t
* y
, dipe_secretkey_t
* sk
) {
205 *sk
= (dipe_secretkey_t
)malloc(sizeof(dipe_secretkey
));
206 (*sk
)->dimension
= msk
->dimension
;
207 element_init_G2((*sk
)->d
, param
->pairing
);
209 size_t hash_input_length
= dipe_h_length(y
[0], msk
->dimension
);
210 unsigned char hash_input
[hash_input_length
];
212 element_init_G2(h
, param
->pairing
);
214 dipe_generate_h(cid
, y
, msk
->dimension
, hash_input
);
215 element_from_hash(h
, hash_input
, hash_input_length
);
220 element_init_Zr(innerp
, param
->pairing
);
221 element_init_Zr(tmp
, param
->pairing
);
222 element_set0(innerp
);
224 element_from_hash(h
, hash_input
, hash_input_length
);
226 for (size_t i
= 0; i
< msk
->dimension
; ++i
) {
227 element_mul(tmp
, y
[i
], msk
->k
[i
]);
228 element_add(innerp
, innerp
, tmp
);
232 element_init_G2(a2
, param
->pairing
);
233 element_pow_zn(h
, h
, innerp
);
234 element_pow_zn(a2
, param
->g2
, msk
->a
);
235 element_mul((*sk
)->d
, a2
, h
);
238 element_clear(innerp
);
243 void dipe_encap(dipe_param_t param
, dipe_master_publickey_t mpk
, element_t
* x
, element_t ptxt
, dipe_ctxt_t
* ctxt
) {
244 *ctxt
= (dipe_ctxt_t
)malloc(sizeof(dipe_ctxt
));
245 (*ctxt
)->dimension
= mpk
->dimension
;
249 element_init_Zr(r
, param
->pairing
);
250 element_init_Zr(s
, param
->pairing
);
255 element_init_G1((*ctxt
)->s
, param
->pairing
);
256 element_pow_zn((*ctxt
)->s
, param
->g1
, s
);
260 element_init_G1(k1
, param
->pairing
);
261 element_init_G1(x1
, param
->pairing
);
263 (*ctxt
)->cx
= (element_t
*)calloc(mpk
->dimension
, sizeof(element_t
));
264 for (size_t i
= 0; i
< mpk
->dimension
; ++i
){
265 element_pow_zn(x1
, param
->g1
, x
[i
]);
266 element_pow_zn(x1
, x1
, r
);
268 element_pow_zn(k1
, mpk
->k
[i
], s
);
270 element_init_G1((*ctxt
)->cx
[i
], param
->pairing
);
271 element_mul((*ctxt
)->cx
[i
], k1
, x1
);
275 element_init_GT(at
, param
->pairing
);
276 element_pow_zn(at
, mpk
->a
, s
);
277 element_init_GT((*ctxt
)->c
, param
->pairing
);
278 element_mul((*ctxt
)->c
, at
, ptxt
);
288 void dipe_decap(dipe_param_t param
, dipe_secretkey_t sk
, char* cid
, element_t
* y
, dipe_ctxt_t ctxt
, element_t ptxt
) {
289 size_t hash_input_length
= dipe_h_length(y
[0], sk
->dimension
);
290 unsigned char hash_input
[hash_input_length
];
292 element_init_G2(h
, param
->pairing
);
294 dipe_generate_h(cid
, y
, sk
->dimension
, hash_input
);
295 element_from_hash(h
, hash_input
, hash_input_length
);
300 element_init_GT(tmp
, param
->pairing
);
301 element_init_GT(innerp
, param
->pairing
);
302 element_init_G2(hy
, param
->pairing
);
304 element_set1(innerp
);
305 for (size_t i
= 0; i
< sk
->dimension
; ++i
) {
306 element_pow_zn(hy
, h
, y
[i
]);
307 pairing_apply(tmp
, ctxt
->cx
[i
], hy
, param
->pairing
);
308 element_mul(innerp
, innerp
, tmp
);
311 pairing_apply(ptxt
, ctxt
->s
, sk
->d
, param
->pairing
);
312 element_invert(ptxt
, ptxt
);
313 element_mul(ptxt
, ptxt
, ctxt
->c
);
314 element_mul(ptxt
, ptxt
, innerp
);
318 element_clear(innerp
);
322 void dipe_encrypt(dipe_param_t param
, dipe_master_publickey_t mpk
, element_t
* x
, size_t ptxt_len
, char* ptxt
, size_t ctxt_len
, char* ctxt
) {
328 element_init_GT(key
, param
->pairing
);
330 dipe_generate_aeskey(key
, aes
);
331 dipe_encap(param
, mpk
, x
, key
, &cap
);
332 cap_len
= dipe_serialize_ctxt(param
, cap
, (uint8_t*)ctxt
);
333 ctxt
+= cap_len
; ctxt_len
-= cap_len
;
335 dipe_aes_encrypt(aes
, ptxt_len
, (uint8_t*)ptxt
, ctxt_len
, (uint8_t*)ctxt
);
341 size_t dipe_decrypt(dipe_param_t param
, dipe_secretkey_t sk
, char* cid
, element_t
* y
, size_t ctxt_len
, char* ctxt
, char* ptxt
) {
347 element_init_GT(key
, param
->pairing
);
348 cap_len
= dipe_deserialize_ctxt(param
, sk
->dimension
, &cap
, (uint8_t*)ctxt
);
351 dipe_decap(param
, sk
, cid
, y
, cap
, key
);
352 dipe_generate_aeskey(key
, aes
);
357 return dipe_aes_decrypt(aes
, ctxt_len
, (uint8_t*)ctxt
, (uint8_t*)ptxt
);
360 /* Note: we're generating random-looking bytes here. Therefore we
361 * can't encode the dimension of the predicate vector (supposed to be
362 * set as system parameter) or information about the secret sharing
363 * (needs to be retrieved by some sort of trial decryption).
365 size_t dipe_serialize_ctxt(__attribute__((unused
)) dipe_param_t param
, dipe_ctxt_t ctxt
, uint8_t* buffer
) {
366 size_t bytes_written
= 0;
367 element_to_bytes_compressed(buffer
, ctxt
->s
);
368 buffer
+= element_length_in_bytes_compressed(ctxt
->s
);
369 bytes_written
+= element_length_in_bytes_compressed(ctxt
->s
);
371 for (size_t i
= 0; i
< ctxt
->dimension
; ++i
) {
372 element_to_bytes_compressed(buffer
, ctxt
->cx
[i
]);
373 buffer
+= element_length_in_bytes_compressed(ctxt
->cx
[i
]);
374 bytes_written
+= element_length_in_bytes_compressed(ctxt
->cx
[i
]);
377 element_to_bytes(buffer
, ctxt
->c
);
378 buffer
+= element_length_in_bytes(ctxt
->c
);
379 bytes_written
+= element_length_in_bytes(ctxt
->c
);
381 return bytes_written
;
384 size_t dipe_deserialize_ctxt(dipe_param_t param
, size_t dimension
, dipe_ctxt_t
* ctxt
, uint8_t* buffer
) {
385 size_t bytes_read
= 0;
386 *ctxt
= (dipe_ctxt_t
)malloc(sizeof(dipe_ctxt
));
387 (*ctxt
)->dimension
= dimension
;
389 element_init_G1((*ctxt
)->s
, param
->pairing
);
390 element_from_bytes_compressed((*ctxt
)->s
, buffer
);
391 buffer
+= element_length_in_bytes_compressed((*ctxt
)->s
);
392 bytes_read
+= element_length_in_bytes_compressed((*ctxt
)->s
);
394 (*ctxt
)->cx
= (element_t
*)calloc(dimension
, sizeof(element_t
));
395 for (size_t i
= 0; i
< dimension
; ++i
) {
396 element_init_G1((*ctxt
)->cx
[i
], param
->pairing
);
397 element_from_bytes_compressed((*ctxt
)->cx
[i
], buffer
);
398 buffer
+= element_length_in_bytes_compressed((*ctxt
)->cx
[i
]);
399 bytes_read
+= element_length_in_bytes_compressed((*ctxt
)->cx
[i
]);
402 element_init_GT((*ctxt
)->c
, param
->pairing
);
403 element_from_bytes((*ctxt
)->c
, buffer
);
404 buffer
+= element_length_in_bytes((*ctxt
)->c
);
405 bytes_read
+= element_length_in_bytes((*ctxt
)->c
);
410 size_t dipe_ciphertext_overhead(dipe_param_t param
, size_t dimension
) {
411 size_t overhead
= 12 + 16 + 4 /* IV + Tag + Size */;
414 element_init_G1(t
, param
->pairing
);
415 overhead
+= element_length_in_bytes_compressed(t
);
416 overhead
+= dimension
* element_length_in_bytes_compressed(t
);
418 element_init_GT(t
, param
->pairing
);
419 overhead
+= element_length_in_bytes(t
);
425 void dipe_free_param(dipe_param_t param
) {
426 element_clear(param
->g1
);
427 element_clear(param
->g2
);
428 element_clear(param
->gt
);
429 pairing_clear(param
->pairing
);
433 void dipe_free_master_secretkey(dipe_master_secretkey_t sk
) {
434 for (size_t i
= 0; i
< sk
->dimension
; ++i
) {
435 element_clear(sk
->k
[i
]);
437 element_clear(sk
->a
);
442 void dipe_free_master_publickey(dipe_master_publickey_t pk
) {
443 for (size_t i
= 0; i
< pk
->dimension
; ++i
) {
444 element_clear(pk
->k
[i
]);
446 element_clear(pk
->a
);
451 void dipe_free_secretkey(dipe_secretkey_t sk
) {
452 element_clear(sk
->d
);
456 void dipe_free_ctxt(dipe_ctxt_t ctxt
) {
457 for (size_t i
= 0; i
< ctxt
->dimension
; ++i
) {
458 element_clear(ctxt
->cx
[i
]);
460 element_clear(ctxt
->c
);
461 element_clear(ctxt
->s
);