1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_PAILLIER
18
19 #include "crypt_paillier.h"
20 #include "paillier_local.h"
21 #include "crypt_errno.h"
22 #include "crypt_utils.h"
23 #include "securec.h"
24 #include "bsl_sal.h"
25 #include "bsl_err_internal.h"
26 #include "crypt_utils.h"
27 #include "crypt_params_key.h"
28
CRYPT_PAILLIER_NewCtx(void)29 CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_NewCtx(void)
30 {
31 CRYPT_PAILLIER_Ctx *ctx = NULL;
32
33 ctx = (CRYPT_PAILLIER_Ctx *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Ctx));
34 if (ctx == NULL) {
35 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
36 return NULL;
37 }
38
39 (void)memset_s(ctx, sizeof(CRYPT_PAILLIER_Ctx), 0, sizeof(CRYPT_PAILLIER_Ctx));
40 BSL_SAL_ReferencesInit(&(ctx->references));
41 return ctx;
42 }
43
CRYPT_PAILLIER_NewCtxEx(void * libCtx)44 CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_NewCtxEx(void *libCtx)
45 {
46 CRYPT_PAILLIER_Ctx *ctx = CRYPT_PAILLIER_NewCtx();
47 if (ctx == NULL) {
48 return NULL;
49 }
50 ctx->libCtx = libCtx;
51 return ctx;
52 }
53
PaillierPubKeyDupCtx(CRYPT_PAILLIER_PubKey * pubKey)54 static CRYPT_PAILLIER_PubKey *PaillierPubKeyDupCtx(CRYPT_PAILLIER_PubKey *pubKey)
55 {
56 CRYPT_PAILLIER_PubKey *newPubKey = (CRYPT_PAILLIER_PubKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PubKey));
57 if (newPubKey == NULL) {
58 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
59 return NULL;
60 }
61
62 (void)memset_s(newPubKey, sizeof(CRYPT_PAILLIER_PubKey), 0, sizeof(CRYPT_PAILLIER_PubKey));
63
64 GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->n, pubKey->n, BN_Dup(pubKey->n), CRYPT_MEM_ALLOC_FAIL);
65 GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->g, pubKey->g, BN_Dup(pubKey->g), CRYPT_MEM_ALLOC_FAIL);
66 GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->n2, pubKey->n2, BN_Dup(pubKey->n2), CRYPT_MEM_ALLOC_FAIL);
67
68 return newPubKey;
69
70 ERR:
71 PAILLIER_FREE_PUB_KEY(newPubKey);
72 return NULL;
73 }
74
PaillierPrvKeyDupCtx(CRYPT_PAILLIER_PrvKey * prvKey)75 static CRYPT_PAILLIER_PrvKey *PaillierPrvKeyDupCtx(CRYPT_PAILLIER_PrvKey *prvKey)
76 {
77 CRYPT_PAILLIER_PrvKey *newPrvKey = (CRYPT_PAILLIER_PrvKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PrvKey));
78 if (newPrvKey == NULL) {
79 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
80 return NULL;
81 }
82
83 (void)memset_s(newPrvKey, sizeof(CRYPT_PAILLIER_PrvKey), 0, sizeof(CRYPT_PAILLIER_PrvKey));
84
85 GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->n, prvKey->n, BN_Dup(prvKey->n), CRYPT_MEM_ALLOC_FAIL);
86 GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->lambda, prvKey->lambda, BN_Dup(prvKey->lambda), CRYPT_MEM_ALLOC_FAIL);
87 GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->mu, prvKey->mu, BN_Dup(prvKey->mu), CRYPT_MEM_ALLOC_FAIL);
88 GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->n2, prvKey->n2, BN_Dup(prvKey->n2), CRYPT_MEM_ALLOC_FAIL);
89
90 return newPrvKey;
91 ERR:
92 PAILLIER_FREE_PRV_KEY(newPrvKey);
93 return NULL;
94 }
95
PaillierParaDupCtx(CRYPT_PAILLIER_Para * para)96 static CRYPT_PAILLIER_Para *PaillierParaDupCtx(CRYPT_PAILLIER_Para *para)
97 {
98 CRYPT_PAILLIER_Para *newPara = (CRYPT_PAILLIER_Para *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para));
99 if (newPara == NULL) {
100 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
101 return NULL;
102 }
103
104 (void)memset_s(newPara, sizeof(CRYPT_PAILLIER_Para), 0, sizeof(CRYPT_PAILLIER_Para));
105
106 newPara->bits = para->bits;
107 GOTO_ERR_IF_SRC_NOT_NULL(newPara->p, para->p, BN_Dup(para->p), CRYPT_MEM_ALLOC_FAIL);
108 GOTO_ERR_IF_SRC_NOT_NULL(newPara->q, para->q, BN_Dup(para->q), CRYPT_MEM_ALLOC_FAIL);
109
110 return newPara;
111
112 ERR:
113 PAILLIER_FREE_PARA(newPara);
114 return NULL;
115 }
116
CRYPT_PAILLIER_DupCtx(CRYPT_PAILLIER_Ctx * keyCtx)117 CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_DupCtx(CRYPT_PAILLIER_Ctx *keyCtx)
118 {
119 if (keyCtx == NULL) {
120 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
121 return NULL;
122 }
123 CRYPT_PAILLIER_Ctx *newKeyCtx = NULL;
124 newKeyCtx = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Ctx));
125 if (newKeyCtx == NULL) {
126 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
127 return NULL;
128 }
129
130 (void)memset_s(newKeyCtx, sizeof(CRYPT_PAILLIER_Ctx), 0, sizeof(CRYPT_PAILLIER_Ctx));
131
132 GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->prvKey, keyCtx->prvKey, PaillierPrvKeyDupCtx(keyCtx->prvKey), CRYPT_MEM_ALLOC_FAIL);
133 GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->pubKey, keyCtx->pubKey, PaillierPubKeyDupCtx(keyCtx->pubKey), CRYPT_MEM_ALLOC_FAIL);
134 GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->para, keyCtx->para, PaillierParaDupCtx(keyCtx->para), CRYPT_MEM_ALLOC_FAIL);
135 BSL_SAL_ReferencesInit(&(newKeyCtx->references));
136 return newKeyCtx;
137
138 ERR:
139 CRYPT_PAILLIER_FreeCtx(newKeyCtx);
140 return NULL;
141 }
142
GetPaillierParam(const BSL_Param * params,int32_t type,const uint8_t ** value,uint32_t * valueLen)143 static int32_t GetPaillierParam(const BSL_Param *params, int32_t type, const uint8_t **value, uint32_t *valueLen)
144 {
145 const BSL_Param *temp = BSL_PARAM_FindConstParam(params, type);
146 if (temp == NULL || temp->valueLen == 0 || temp->value == NULL) {
147 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
148 return CRYPT_INVALID_ARG;
149 }
150
151 *value = temp->value;
152 *valueLen = temp->valueLen;
153 return CRYPT_SUCCESS;
154 }
155
GetPaillierBits(const BSL_Param * params,uint32_t * bits)156 static int32_t GetPaillierBits(const BSL_Param *params, uint32_t *bits)
157 {
158 uint32_t bitsLen = sizeof(*bits);
159 const BSL_Param *temp = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_PAILLIER_BITS);
160 if (temp == NULL) {
161 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
162 return CRYPT_INVALID_ARG;
163 }
164
165 int32_t ret = BSL_PARAM_GetValue(temp, CRYPT_PARAM_PAILLIER_BITS, BSL_PARAM_TYPE_UINT32, bits, &bitsLen);
166 if (ret != BSL_SUCCESS || *bits == 0 || *bits > PAILLIER_MAX_MODULUS_BITS) {
167 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
168 return CRYPT_INVALID_ARG;
169 }
170
171 return CRYPT_SUCCESS;
172 }
173
ValidatePaillierParams(uint32_t pLen,uint32_t qLen,uint32_t bits)174 static int32_t ValidatePaillierParams(uint32_t pLen, uint32_t qLen, uint32_t bits)
175 {
176 if (pLen != BN_BITS_TO_BYTES(bits) || qLen != BN_BITS_TO_BYTES(bits)) {
177 BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS);
178 return CRYPT_PAILLIER_ERR_KEY_BITS;
179 }
180 return CRYPT_SUCCESS;
181 }
182
CRYPT_PAILLIER_NewPara(const BSL_Param * params)183 CRYPT_PAILLIER_Para *CRYPT_PAILLIER_NewPara(const BSL_Param *params)
184 {
185 if (params == NULL) {
186 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
187 return NULL;
188 }
189
190 const uint8_t *p = NULL, *q = NULL;
191 uint32_t pLen = 0, qLen = 0;
192 int32_t ret = GetPaillierParam(params, CRYPT_PARAM_PAILLIER_P, &p, &pLen);
193 if (ret != CRYPT_SUCCESS) {
194 return NULL;
195 }
196
197 ret = GetPaillierParam(params, CRYPT_PARAM_PAILLIER_Q, &q, &qLen);
198 if (ret != CRYPT_SUCCESS) {
199 return NULL;
200 }
201
202 uint32_t bits = 0;
203 ret = GetPaillierBits(params, &bits);
204 if (ret != CRYPT_SUCCESS) {
205 return NULL;
206 }
207
208 ret = ValidatePaillierParams(pLen, qLen, bits);
209 if (ret != CRYPT_SUCCESS) {
210 return NULL;
211 }
212
213 CRYPT_PAILLIER_Para *retPara = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para));
214 if (retPara == NULL) {
215 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
216 return NULL;
217 }
218
219 retPara->bits = bits;
220 retPara->p = BN_Create(bits);
221 retPara->q = BN_Create(bits);
222 if (retPara->p == NULL || retPara->q == NULL) {
223 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
224 CRYPT_PAILLIER_FreePara(retPara);
225 return NULL;
226 }
227 return retPara;
228 }
229
CRYPT_PAILLIER_FreeCtx(CRYPT_PAILLIER_Ctx * ctx)230 void CRYPT_PAILLIER_FreeCtx(CRYPT_PAILLIER_Ctx *ctx)
231 {
232 if (ctx == NULL) {
233 return;
234 }
235 int i = 0;
236 BSL_SAL_AtomicDownReferences(&(ctx->references), &i);
237 if (i > 0) {
238 return;
239 }
240
241 BSL_SAL_ReferencesFree(&(ctx->references));
242 PAILLIER_FREE_PRV_KEY(ctx->prvKey);
243 PAILLIER_FREE_PUB_KEY(ctx->pubKey);
244 PAILLIER_FREE_PARA(ctx->para);
245 BSL_SAL_Free(ctx);
246 }
247
CRYPT_PAILLIER_FreePara(CRYPT_PAILLIER_Para * para)248 void CRYPT_PAILLIER_FreePara(CRYPT_PAILLIER_Para *para)
249 {
250 if (para == NULL) {
251 return;
252 }
253 BN_Destroy(para->p);
254 BN_Destroy(para->q);
255 BSL_SAL_Free(para);
256 }
257
PAILLIER_FreePrvKey(CRYPT_PAILLIER_PrvKey * prvKey)258 void PAILLIER_FreePrvKey(CRYPT_PAILLIER_PrvKey *prvKey)
259 {
260 if (prvKey == NULL) {
261 return;
262 }
263 BN_Destroy(prvKey->n);
264 BN_Destroy(prvKey->lambda);
265 BN_Destroy(prvKey->mu);
266 BN_Destroy(prvKey->n2);
267 BSL_SAL_Free(prvKey);
268 }
269
PAILLIER_FreePubKey(CRYPT_PAILLIER_PubKey * pubKey)270 void PAILLIER_FreePubKey(CRYPT_PAILLIER_PubKey *pubKey)
271 {
272 if (pubKey == NULL) {
273 return;
274 }
275 BN_Destroy(pubKey->n);
276 BN_Destroy(pubKey->g);
277 BN_Destroy(pubKey->n2);
278 BSL_SAL_Free(pubKey);
279 }
280
IsPAILLIERSetParaVaild(const CRYPT_PAILLIER_Ctx * ctx,const CRYPT_PAILLIER_Para * para)281 static int32_t IsPAILLIERSetParaVaild(const CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PAILLIER_Para *para)
282 {
283 if (ctx == NULL || para == NULL || para->p == NULL) {
284 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
285 return CRYPT_NULL_INPUT;
286 }
287 if (para->bits > PAILLIER_MAX_MODULUS_BITS || para->bits <= 0) {
288 BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS);
289 return CRYPT_PAILLIER_ERR_KEY_BITS;
290 }
291 return CRYPT_SUCCESS;
292 }
293
CRYPT_Paillier_DupPara(const CRYPT_PAILLIER_Para * para)294 CRYPT_PAILLIER_Para *CRYPT_Paillier_DupPara(const CRYPT_PAILLIER_Para *para)
295 {
296 CRYPT_PAILLIER_Para *paraCopy = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para));
297 if (paraCopy == NULL) {
298 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
299 return NULL;
300 }
301 paraCopy->bits = para->bits;
302 paraCopy->p = BN_Dup(para->p);
303 paraCopy->q = BN_Dup(para->q);
304 if (paraCopy->p == NULL || paraCopy->q == NULL) {
305 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
306 PAILLIER_FREE_PARA(paraCopy);
307 return NULL;
308 }
309
310 return paraCopy;
311 }
312
CRYPT_PAILLIER_SetPara(CRYPT_PAILLIER_Ctx * ctx,const BSL_Param * param)313 int32_t CRYPT_PAILLIER_SetPara(CRYPT_PAILLIER_Ctx *ctx, const BSL_Param *param)
314 {
315 if (ctx == NULL) {
316 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
317 return CRYPT_NULL_INPUT;
318 }
319 CRYPT_PAILLIER_Para *para = CRYPT_PAILLIER_NewPara(param);
320 if (para == NULL) {
321 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
322 return CRYPT_MEM_ALLOC_FAIL;
323 }
324 int32_t ret = IsPAILLIERSetParaVaild(ctx, para);
325 if (ret != CRYPT_SUCCESS) {
326 CRYPT_PAILLIER_FreePara(para);
327 return ret;
328 }
329
330 PAILLIER_FREE_PARA(ctx->para);
331 PAILLIER_FREE_PUB_KEY(ctx->pubKey);
332 PAILLIER_FREE_PRV_KEY(ctx->prvKey);
333 ctx->para = para;
334 return CRYPT_SUCCESS;
335 }
336
CRYPT_PAILLIER_GetBits(const CRYPT_PAILLIER_Ctx * ctx)337 uint32_t CRYPT_PAILLIER_GetBits(const CRYPT_PAILLIER_Ctx *ctx)
338 {
339 if (ctx == NULL) {
340 return 0;
341 }
342 if (ctx->para != NULL) {
343 return ctx->para->bits;
344 }
345 if (ctx->prvKey != NULL) {
346 return BN_Bits(ctx->prvKey->lambda);
347 }
348 if (ctx->pubKey != NULL) {
349 return BN_Bits(ctx->pubKey->n);
350 }
351 return 0;
352 }
353
Paillier_NewPrvKey(uint32_t bits)354 CRYPT_PAILLIER_PrvKey *Paillier_NewPrvKey(uint32_t bits)
355 {
356 CRYPT_PAILLIER_PrvKey *prvKey = (CRYPT_PAILLIER_PrvKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PrvKey));
357 if (prvKey == NULL) {
358 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
359 return NULL;
360 }
361 prvKey->n = BN_Create(bits);
362 prvKey->lambda = BN_Create(bits);
363 prvKey->mu = BN_Create(bits);
364 prvKey->n2 = BN_Create(bits);
365 if (prvKey->n == NULL || prvKey->lambda == NULL || prvKey->mu == NULL || prvKey->n2 == NULL) {
366 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
367 PAILLIER_FREE_PRV_KEY(prvKey);
368 }
369 return prvKey;
370 }
371
Paillier_NewPubKey(uint32_t bits)372 CRYPT_PAILLIER_PubKey *Paillier_NewPubKey(uint32_t bits)
373 {
374 CRYPT_PAILLIER_PubKey *pubKey = (CRYPT_PAILLIER_PubKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PubKey));
375 if (pubKey == NULL) {
376 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
377 return NULL;
378 }
379 pubKey->n = BN_Create(bits);
380 pubKey->g = BN_Create(bits);
381 pubKey->n2 = BN_Create(bits);
382 if (pubKey->n == NULL || pubKey->g == NULL || pubKey->n2 == NULL) {
383 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
384 PAILLIER_FREE_PUB_KEY(pubKey);
385 }
386 return pubKey;
387 }
388
Paillier_GenPQ(CRYPT_PAILLIER_Para * para,BN_Optimizer * optimizer)389 static int32_t Paillier_GenPQ(CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer)
390 {
391 uint32_t bits = para->bits;
392 int32_t ret = BN_GenPrime(para->p, NULL, bits, true, optimizer, NULL);
393 if (ret != CRYPT_SUCCESS) {
394 BSL_ERR_PUSH_ERROR(ret);
395 return ret;
396 }
397 ret = BN_GenPrime(para->q, NULL, bits, true, optimizer, NULL);
398 if (ret != CRYPT_SUCCESS) {
399 BSL_ERR_PUSH_ERROR(ret);
400 }
401 return ret;
402 }
403
Paillier_CalcPubKey(CRYPT_PAILLIER_PubKey * pubKey,CRYPT_PAILLIER_Para * para,BN_Optimizer * optimizer)404 static int32_t Paillier_CalcPubKey(CRYPT_PAILLIER_PubKey *pubKey, CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer)
405 {
406 int32_t ret = BN_Mul(pubKey->n, para->p, para->q, optimizer);
407 if (ret != CRYPT_SUCCESS) {
408 BSL_ERR_PUSH_ERROR(ret);
409 return ret;
410 }
411 ret = BN_AddLimb(pubKey->g, pubKey->n, 1); // g = n + 1
412 if (ret != CRYPT_SUCCESS) {
413 BSL_ERR_PUSH_ERROR(ret);
414 return ret;
415 }
416 ret = BN_Sqr(pubKey->n2, pubKey->n, optimizer);
417 if (ret != CRYPT_SUCCESS) {
418 BSL_ERR_PUSH_ERROR(ret);
419 }
420 return ret;
421 }
422
Paillier_CalcLambda(BN_BigNum * lambda,CRYPT_PAILLIER_Para * para,BN_Optimizer * optimizer)423 static int32_t Paillier_CalcLambda(BN_BigNum *lambda, CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer)
424 {
425 uint32_t bits = para->bits;
426 BN_BigNum *pMinus1 = BN_Create(bits);
427 BN_BigNum *qMinus1 = BN_Create(bits);
428 int32_t ret = CRYPT_MEM_ALLOC_FAIL;
429 if (pMinus1 == NULL || qMinus1 == NULL) {
430 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
431 goto EXIT;
432 }
433 ret = BN_SubLimb(pMinus1, para->p, 1);
434 if (ret != CRYPT_SUCCESS) {
435 BSL_ERR_PUSH_ERROR(ret);
436 goto EXIT;
437 }
438 ret = BN_SubLimb(qMinus1, para->q, 1);
439 if (ret != CRYPT_SUCCESS) {
440 BSL_ERR_PUSH_ERROR(ret);
441 goto EXIT;
442 }
443 ret = BN_Lcm(lambda, pMinus1, qMinus1, optimizer);
444 if (ret != CRYPT_SUCCESS) {
445 BSL_ERR_PUSH_ERROR(ret);
446 }
447 EXIT:
448 BN_Destroy(pMinus1);
449 BN_Destroy(qMinus1);
450 return ret;
451 }
452
Paillier_CalcMu(BN_BigNum * mu,const BN_BigNum * lambda,CRYPT_PAILLIER_PubKey * pubKey,uint32_t bits,BN_Optimizer * optimizer)453 static int32_t Paillier_CalcMu(BN_BigNum *mu, const BN_BigNum *lambda, CRYPT_PAILLIER_PubKey *pubKey, uint32_t bits, BN_Optimizer *optimizer)
454 {
455 BN_BigNum *x = BN_Create(bits);
456 BN_BigNum *xMinus1 = BN_Create(bits);
457 BN_BigNum *Lx = BN_Create(bits);
458
459 int32_t ret;
460 if (x == NULL || xMinus1 == NULL || Lx == NULL) {
461 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
462 ret = CRYPT_MEM_ALLOC_FAIL;
463 goto EXIT;
464 }
465
466 ret = BN_ModExp(x, pubKey->g, lambda, pubKey->n2, optimizer);
467 if (ret != CRYPT_SUCCESS) {
468 BSL_ERR_PUSH_ERROR(ret);
469 goto EXIT;
470 }
471
472 ret = BN_SubLimb(xMinus1, x, 1);
473 if (ret != CRYPT_SUCCESS) {
474 BSL_ERR_PUSH_ERROR(ret);
475 goto EXIT;
476 }
477
478 ret = BN_Div(Lx, NULL, xMinus1, pubKey->n, optimizer);
479 if (ret != CRYPT_SUCCESS) {
480 BSL_ERR_PUSH_ERROR(ret);
481 goto EXIT;
482 }
483
484 ret = BN_ModInv(mu, Lx, pubKey->n, optimizer);
485 if (ret != CRYPT_SUCCESS) {
486 BSL_ERR_PUSH_ERROR(ret);
487 }
488 EXIT:
489 BN_Destroy(x);
490 BN_Destroy(xMinus1);
491 BN_Destroy(Lx);
492
493 return ret;
494 }
495
Paillier_CalcPrvKey(CRYPT_PAILLIER_Ctx * ctx,BN_Optimizer * optimizer)496 int32_t Paillier_CalcPrvKey(CRYPT_PAILLIER_Ctx *ctx, BN_Optimizer *optimizer)
497 {
498 int32_t ret = Paillier_CalcLambda(ctx->prvKey->lambda, ctx->para, optimizer);
499 if (ret != CRYPT_SUCCESS) {
500 BSL_ERR_PUSH_ERROR(ret);
501 return ret;
502 }
503
504 ret = Paillier_CalcMu(ctx->prvKey->mu, ctx->prvKey->lambda, ctx->pubKey, ctx->para->bits, optimizer);
505 if (ret != CRYPT_SUCCESS) {
506 BSL_ERR_PUSH_ERROR(ret);
507 }
508 return ret;
509 }
510
CRYPT_PAILLIER_Gen(CRYPT_PAILLIER_Ctx * ctx)511 int32_t CRYPT_PAILLIER_Gen(CRYPT_PAILLIER_Ctx *ctx)
512 {
513 if (ctx == NULL || ctx->para == NULL) {
514 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
515 return CRYPT_NULL_INPUT;
516 }
517
518 int32_t ret = CRYPT_MEM_ALLOC_FAIL;
519 BN_Optimizer *optimizer = NULL;
520 CRYPT_PAILLIER_Ctx *newCtx = CRYPT_PAILLIER_NewCtx();
521
522 if (newCtx == NULL) {
523 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
524 return CRYPT_MEM_ALLOC_FAIL;
525 }
526
527 newCtx->para = CRYPT_Paillier_DupPara(ctx->para);
528 if (newCtx->para == NULL) {
529 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
530 goto ERR;
531 }
532
533 newCtx->prvKey = Paillier_NewPrvKey(newCtx->para->bits);
534 newCtx->pubKey = Paillier_NewPubKey(newCtx->para->bits);
535 optimizer = BN_OptimizerCreate();
536 if (optimizer == NULL || newCtx->prvKey == NULL || newCtx->pubKey == NULL) {
537 ret = CRYPT_MEM_ALLOC_FAIL;
538 BSL_ERR_PUSH_ERROR(ret);
539 goto ERR;
540 }
541 BN_OptimizerSetLibCtx(ctx->libCtx, optimizer);
542 ret = Paillier_GenPQ(newCtx->para, optimizer);
543 if (ret != CRYPT_SUCCESS) {
544 BSL_ERR_PUSH_ERROR(ret);
545 goto ERR;
546 }
547
548 ret = Paillier_CalcPubKey(newCtx->pubKey, newCtx->para, optimizer);
549 if (ret != CRYPT_SUCCESS) {
550 BSL_ERR_PUSH_ERROR(ret);
551 goto ERR;
552 }
553
554 ret = Paillier_CalcPrvKey(newCtx, optimizer);
555 if (ret != CRYPT_SUCCESS) {
556 BSL_ERR_PUSH_ERROR(ret);
557 goto ERR;
558 }
559
560 GOTO_ERR_IF(BN_Copy(newCtx->prvKey->n, newCtx->pubKey->n), ret);
561 GOTO_ERR_IF(BN_Copy(newCtx->prvKey->n2, newCtx->pubKey->n2), ret);
562
563 PAILLIER_FREE_PARA(ctx->para);
564 PAILLIER_FREE_PRV_KEY(ctx->prvKey);
565 PAILLIER_FREE_PUB_KEY(ctx->pubKey);
566 BSL_SAL_ReferencesFree(&(newCtx->references));
567
568 ctx->prvKey = newCtx->prvKey;
569 ctx->pubKey = newCtx->pubKey;
570 ctx->para = newCtx->para;
571 BSL_SAL_FREE(newCtx);
572 BN_OptimizerDestroy(optimizer);
573
574 return ret;
575
576 ERR:
577 CRYPT_PAILLIER_FreeCtx(newCtx);
578 BN_OptimizerDestroy(optimizer);
579 return ret;
580 }
581
582
583 #endif // HITLS_CRYPTO_PAILLIER