This is an automated email from the ASF dual-hosted git repository. sandreoli pushed a commit to branch issue51 in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-c.git
View the commit online: https://github.com/apache/incubator-milagro-crypto-c/commit/c4506dd623e3578b1b6eb18c782a5b44c4e80cb0 commit c4506dd623e3578b1b6eb18c782a5b44c4e80cb0 Author: samuele-andreoli <[email protected]> AuthorDate: Wed Nov 20 10:47:13 2019 +0000 use custom double exponentiation for paillier encryption --- include/ff.h.in | 11 ++++++++++ src/ff.c.in | 38 +++++++++++++++++++++++++++++++++++ src/paillier.c | 62 ++++++++++----------------------------------------------- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/include/ff.h.in b/include/ff.h.in index c3be699..d69b819 100644 --- a/include/ff.h.in +++ b/include/ff.h.in @@ -292,5 +292,16 @@ extern int FF_WWW_prime(BIG_XXX *x,csprng *R,int n); @param n size of FF in BIGs */ extern void FF_WWW_pow2(BIG_XXX *r,BIG_XXX *x,BIG_XXX e,BIG_XXX *y,BIG_XXX f,BIG_XXX *m,int n); +/** @brief Calculate r=x^e.y^f mod m for big e and f + * + @param r FF instance, on exit = x^e.y^f mod p + @param x FF instance + @param e FF exponent + @param y FF instance + @param f FF exponent + @param m FF modulus + @param n size of FF in BIGs + */ +extern void FF_WWW_bpow2(BIG_XXX *r,BIG_XXX *x,BIG_XXX *e,BIG_XXX *y,BIG_XXX *f,BIG_XXX *p,int n); #endif diff --git a/src/ff.c.in b/src/ff.c.in index 8f07849..1d495bf 100644 --- a/src/ff.c.in +++ b/src/ff.c.in @@ -921,6 +921,44 @@ void FF_WWW_pow2(BIG_XXX r[],BIG_XXX x[],BIG_XXX e,BIG_XXX y[],BIG_XXX f,BIG_XXX FF_WWW_redc(r,p,ND,n); } +/* double exponentiation r=x^e.y^f mod p */ +void FF_WWW_bpow2(BIG_XXX r[],BIG_XXX x[],BIG_XXX e[],BIG_XXX y[],BIG_XXX f[],BIG_XXX p[],int n) +{ + int i,eb,fb; +#ifndef C99 + BIG_XXX xn[FFLEN_WWW],yn[FFLEN_WWW],xy[FFLEN_WWW],ND[FFLEN_WWW]; +#else + BIG_XXX xn[n],yn[n],xy[n],ND[n]; +#endif + + FF_WWW_invmod2m(ND,p,n); + + FF_WWW_copy(xn,x,n); + FF_WWW_copy(yn,y,n); + FF_WWW_nres(xn,p,n); + FF_WWW_nres(yn,p,n); + FF_WWW_modmul(xy,xn,yn,p,ND,n); + FF_WWW_one(r,n); + FF_WWW_nres(r,p,n); + + for (i=8*MODBYTES_XXX*(n-1); i>=0; i--) + { + eb=BIG_XXX_bit(e[i/BIGBITS_XXX],i%BIGBITS_XXX); + fb=BIG_XXX_bit(f[i/BIGBITS_XXX],i%BIGBITS_XXX); + FF_WWW_modsqr(r,r,p,ND,n); + if (eb==1) + { + if (fb==1) FF_WWW_modmul(r,r,xy,p,ND,n); + else FF_WWW_modmul(r,r,xn,p,ND,n); + } + else + { + if (fb==1) FF_WWW_modmul(r,r,yn,p,ND,n); + } + } + FF_WWW_redc(r,p,ND,n); +} + static sign32 igcd(sign32 x,sign32 y) { /* integer GCD, returns GCD of x and y */ diff --git a/src/paillier.c b/src/paillier.c index faf9548..15a901c 100644 --- a/src/paillier.c +++ b/src/paillier.c @@ -236,8 +236,6 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, octet* PT, octet* CT, octe OCT_joctet(&GOCT, G); FF_4096_fromOctet(g,&GOCT,FFLEN_4096); - // n2 = n^2 - FF_4096_sqr(n2, n, FFLEN_4096); // In production generate R from RNG if (RNG!=NULL) @@ -265,59 +263,19 @@ int PAILLIER_ENCRYPT(csprng *RNG, octet* N, octet* G, octet* PT, octet* CT, octe FF_4096_fromOctet(r,&ROCT,FFLEN_4096); } - // Convert pt from FF_2048 to FF_4096 - char ptoct[FS_4096] = {0}; - octet PTOCT = {FS_2048,FS_4096,ptoct}; - OCT_joctet(&PTOCT, PT); - FF_4096_fromOctet(pt,&PTOCT,FFLEN_4096); + FF_4096_zero(pt, FFLEN_4096); + FF_4096_fromOctet(pt,PT,HFLEN_4096); - // g^pt mod n^2 - FF_4096_pow(gpt,g,pt,n2,FFLEN_4096); - // r^n mod n^2 - FF_4096_pow(rn,r,n,n2,FFLEN_4096); - - // Convert gpt from FF_4096 to FF_8192 - char gpt1[FS_4096] = {0}; - octet GPT1 = {0,FS_4096,gpt1}; - FF_4096_toOctet(&GPT1, gpt, FFLEN_4096); - - char gpt2[FS_8192] = {0}; - octet GPT2 = {FS_4096,FS_8192,gpt2}; - OCT_joctet(&GPT2, &GPT1); - FF_8192_fromOctet(gpt8,&GPT2,FFLEN_8192); - - // Convert rn from FF_4096 to FF_8192 - char rn1[FS_4096] = {0}; - octet RN1 = {0,FS_4096,rn1}; - FF_4096_toOctet(&RN1, rn, FFLEN_4096); - - char rn2[FS_8192] = {0}; - octet RN2 = {FS_4096,FS_8192,rn2}; - OCT_joctet(&RN2, &RN1); - FF_8192_fromOctet(rn8,&RN2,FFLEN_8192); - - // Convert n2 from FF_4096 to FF_8192 - char n21[FS_4096] = {0}; - octet N21 = {0,FS_4096,n21}; - FF_4096_toOctet(&N21, n2, FFLEN_4096); - - char n22[FS_8192] = {0}; - octet N22 = {FS_4096,FS_8192,n22}; - OCT_joctet(&N22, &N21); - FF_8192_fromOctet(n28,&N22,FFLEN_8192); - - // ct = g^{pt}.r^n mod n^2 - FF_8192_mul(ct,gpt8,rn8,FFLEN_8192); - FF_8192_mod(ct,n28,FFLEN_8192); + // n2 = n^2 + FF_4096_sqr(n2, n, HFLEN_4096); + FF_4096_norm(n2, FFLEN_4096); - // Output. Convert ct from FF_8192 to FF_4096 - char ct2[FS_8192] = {0}; - octet CT2 = {0,FS_8192,ct2}; - FF_8192_toOctet(&CT2, ct, FFLEN_8192); - CT->len = FS_4096; - CT2.len = FS_4096; - OCT_truncate(CT,&CT2); + // ct = g^pt * r^n mod n2 + FF_4096_bpow2(ct, g, pt, r, n, n2, FFLEN_4096); + + // Output + FF_4096_toOctet(CT, ct, FFLEN_4096); // Output R for Debug if (R!=NULL)
