• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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