diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info index d87944c2..5ac994bc 100644 --- a/crypto/sm2/build.info +++ b/crypto/sm2/build.info @@ -1,7 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=sm2_err.c sm2_asn1.c sm2_id.c sm2_sign.c sm2_enc.c \ - sm2_oct.c sm2_exch.c sm2_kmeth.c sm2_standard_enc.c sm2_standard_exch.c \ - sm2_standard_sign.c ./miracl/mralloc.c ./miracl/mrarth0.c \ - ./miracl/mrarth1.c ./miracl/mrarth2.c ./miracl/mrarth3.c ./miracl/mrbits.c \ - ./miracl/mrcore.c ./miracl/mrcurve.c ./miracl/mrjack.c ./miracl/mrlucas.c\ - ./miracl/mrmonty.c ./miracl/mrmuldv.c ./miracl/mrsroot.c ./miracl/mrxgcd.c + sm2_oct.c sm2_exch.c sm2_kmeth.c \ diff --git a/crypto/sm2/miracl/mralloc.c b/crypto/sm2/miracl/mralloc.c deleted file mode 100644 index f3855ad5..00000000 --- a/crypto/sm2/miracl/mralloc.c +++ /dev/null @@ -1,85 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL memory allocation routines - * mralloc.c - * - * MIRACL C Memory allocation/deallocation - * Can be replaced with special user-defined routines - * Default is to standard system routines - * - * NOTE: uses calloc() which initialises memory to Zero, so make sure - * any substituted routine does the same! - */ - -#include -#include - -#ifndef MR_STATIC - -miracl *mr_first_alloc() -{ - return (miracl *)calloc(1,sizeof(miracl)); -} - -void *mr_alloc(_MIPD_ int num,int size) -{ - char *p; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip==NULL) - { - p=(char *)calloc(num,size); - return (void *)p; - } - - if (mr_mip->ERNUM) return NULL; - - p=(char *)calloc(num,size); - if (p==NULL) mr_berror(_MIPP_ MR_ERR_OUT_OF_MEMORY); - return (void *)p; - -} - -void mr_free(void *addr) -{ - if (addr==NULL) return; - free(addr); - return; -} - -#endif diff --git a/crypto/sm2/miracl/mrarth0.c b/crypto/sm2/miracl/mrarth0.c deleted file mode 100644 index 2016a1d4..00000000 --- a/crypto/sm2/miracl/mrarth0.c +++ /dev/null @@ -1,320 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL arithmetic routines 0 - Add and subtract routines - * mrarth0.c - * - */ -#include - -void mr_padd(_MIPD_ big x,big y,big z) -{ /* add two big numbers, z=x+y where * - * x and y are positive */ - int i,lx,ly,lz,la; - mr_small carry,psum; - mr_small *gx,*gy,*gz; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - lx = (int)x->len; - ly = (int)y->len; - - if (ly>lx) - { - lz=ly; - la=lx; - if (x!=z) copy(y,z); - else la=ly; - } - else - { - lz=lx; - la=ly; - if (y!=z) copy(x,z); - else la=lx; - } - carry=0; - z->len=lz; - gx=x->w; gy=y->w; gz=z->w; - if (lznib || !mr_mip->check) z->len++; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif - for (i=0;igx[i]) carry=0; - else if (psum0;i++ ) - { /* add by columns to the length of larger number (if there is a carry) */ - psum=gx[i]+gy[i]+carry; - if (psum>gx[i]) carry=0; - else if (psumcheck && i>=mr_mip->nib) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - return; - } - gz[i]=carry; - } -#ifndef MR_SIMPLE_BASE - } - else - { - for (i=0;i=mr_mip->base) - { /* set carry */ - carry=1; - psum-=mr_mip->base; - } - gz[i]=psum; - } - for (;i0;i++) - { - psum=gx[i]+gy[i]+carry; - carry=0; - if (psum>=mr_mip->base) - { /* set carry */ - carry=1; - psum-=mr_mip->base; - } - gz[i]=psum; - } - if (carry) - { /* carry left over - possible overflow */ - if (mr_mip->check && i>=mr_mip->nib) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - return; - } - gz[i]=carry; - } - } -#endif - if (gz[z->len-1]==0) z->len--; - -} - -void mr_psub(_MIPD_ big x,big y,big z) -{ /* subtract two big numbers z=x-y * - * where x and y are positive and x>y */ - int i,lx,ly; - mr_small borrow,pdiff; - mr_small *gx,*gy,*gz; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - lx = (int)x->len; - ly = (int)y->len; - if (ly>lx) - { - mr_berror(_MIPP_ MR_ERR_NEG_RESULT); - return; - } - if (y!=z) copy(x,z); - else ly=lx; - z->len=lx; - gx=x->w; gy=y->w; gz=z->w; - borrow=0; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif - for (i=0;i0;i++) - { /* subtract by columns */ - if (i>lx) - { - mr_berror(_MIPP_ MR_ERR_NEG_RESULT); - return; - } - pdiff=gx[i]-gy[i]-borrow; - if (pdiffgx[i]) borrow=1; - gz[i]=pdiff; - } -#ifndef MR_SIMPLE_BASE - } - else for (i=0;i0;i++) - { /* subtract by columns */ - if (i>lx) - { - mr_berror(_MIPP_ MR_ERR_NEG_RESULT); - return; - } - pdiff=gy[i]+borrow; - borrow=0; - if (gx[i]>=pdiff) pdiff=gx[i]-pdiff; - else - { /* set borrow */ - pdiff=mr_mip->base+gx[i]-pdiff; - borrow=1; - } - gz[i]=pdiff; - } -#endif - mr_lzero(z); -} - -static void mr_select(_MIPD_ big x,int d,big y,big z) -{ /* perform required add or subtract operation */ - int sx,sy,sz,jf,xgty; -#ifdef MR_FLASH - if (mr_notint(x) || mr_notint(y)) - { - mr_berror(_MIPP_ MR_ERR_INT_OP); - return; - } -#endif - sx=exsign(x); - sy=exsign(y); - sz=0; - x->len&=MR_OBITS; /* force operands to be positive */ - y->len&=MR_OBITS; - xgty=mr_compare(x,y); - jf=(1+sx)+(1+d*sy)/2; - switch (jf) - { /* branch according to signs of operands */ - case 0: - if (xgty>=0) - mr_padd(_MIPP_ x,y,z); - else - mr_padd(_MIPP_ y,x,z); - sz=MINUS; - break; - case 1: - if (xgty<=0) - { - mr_psub(_MIPP_ y,x,z); - sz=PLUS; - } - else - { - mr_psub(_MIPP_ x,y,z); - sz=MINUS; - } - break; - case 2: - if (xgty>=0) - { - mr_psub(_MIPP_ x,y,z); - sz=PLUS; - } - else - { - mr_psub(_MIPP_ y,x,z); - sz=MINUS; - } - break; - case 3: - if (xgty>=0) - mr_padd(_MIPP_ x,y,z); - else - mr_padd(_MIPP_ y,x,z); - sz=PLUS; - break; - } - if (sz<0) z->len^=MR_MSBIT; /* set sign of result */ - if (x!=z && sx<0) x->len^=MR_MSBIT; /* restore signs to operands */ - if (y!=z && y!=x && sy<0) y->len^=MR_MSBIT; -} - -void add(_MIPD_ big x,big y,big z) -{ /* add two signed big numbers together z=x+y */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(27) - - mr_select(_MIPP_ x,PLUS,y,z); - - MR_OUT -} - -void subtract(_MIPD_ big x,big y,big z) -{ /* subtract two big signed numbers z=x-y */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(28) - - mr_select(_MIPP_ x,MINUS,y,z); - - MR_OUT -} - -void incr(_MIPD_ big x,int n,big z) -{ /* add int to big number: z=x+n */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(7) - - convert(_MIPP_ n,mr_mip->w0); - mr_select(_MIPP_ x,PLUS,mr_mip->w0,z); - - MR_OUT -} - -void decr(_MIPD_ big x,int n,big z) -{ /* subtract int from big number: z=x-n */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(8) - - convert(_MIPP_ n,mr_mip->w0); - mr_select(_MIPP_ x,MINUS,mr_mip->w0,z); - - MR_OUT -} - diff --git a/crypto/sm2/miracl/mrarth1.c b/crypto/sm2/miracl/mrarth1.c deleted file mode 100644 index f43b798a..00000000 --- a/crypto/sm2/miracl/mrarth1.c +++ /dev/null @@ -1,1068 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ - -/* - * - * MIRACL arithmetic routines 1 - multiplying and dividing BIG NUMBERS by - * integer numbers. - * mrarth1.c - * - */ - -#include - -#ifdef MR_FP -#include -#endif - -#ifdef MR_WIN64 -#include -#endif - -#ifdef MR_FP_ROUNDING -#ifdef __GNUC__ -#include -#endif - -/* Invert n and set FP rounding. - * Set to round up - * Calculate 1/n - * set to round down (towards zero) - * If rounding cannot be controlled, this function returns 0.0 */ - -mr_large mr_invert(mr_small n) -{ - mr_large inn; - int up= 0x1BFF; - -#ifdef _MSC_VER - #ifdef MR_NOASM -#define NO_EXTENDED - #endif -#endif - -#ifdef NO_EXTENDED - int down=0x1EFF; -#else - int down=0x1FFF; -#endif - -#ifdef __TURBOC__ - asm - { - fldcw WORD PTR up - fld1 - fld QWORD PTR n; - fdiv - fstp TBYTE PTR inn; - fldcw WORD PTR down; - } - return inn; -#endif -#ifdef _MSC_VER - _asm - { - fldcw WORD PTR up - fld1 - fld QWORD PTR n; - fdiv - fstp QWORD PTR inn; - fldcw WORD PTR down; - } - return inn; -#endif -#ifdef __GNUC__ -#ifdef i386 - __asm__ __volatile__ ( - "fldcw %2\n" - "fld1\n" - "fldl %1\n" - "fdivrp\n" - "fstpt %0\n" - "fldcw %3\n" - : "=m"(inn) - : "m"(n),"m"(up),"m"(down) - : "memory" - ); - return inn; -#else - fpsetround(FP_RP); - inn=(mr_large)1.0/n; - fpsetround(FP_RZ); - return inn; -#endif -#endif - return 0.0L; -} - -#endif - -void mr_pmul(_MIPD_ big x,mr_small sn,big z) -{ - int m,xl; - mr_lentype sx; - mr_small carry,*xg,*zg; - -#ifdef MR_ITANIUM - mr_small tm; -#endif -#ifdef MR_WIN64 - mr_small tm; -#endif -#ifdef MR_NOASM - union doubleword dble; - mr_large dbled; - mr_large ldres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (x!=z) - { - zero(z); - if (sn==0) return; - } - else if (sn==0) - { - zero(z); - return; - } - m=0; - carry=0; - sx=x->len&MR_MSBIT; - xl=(int)(x->len&MR_OBITS); - -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - xg=x->w; zg=z->w; -/* inline 8086 assembly - substitutes for loop below */ -#ifdef INLINE_ASM -#if INLINE_ASM == 1 - ASM cld - ASM mov cx,xl - ASM or cx,cx - ASM je out1 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les di,DWORD PTR zg - ASM lds si,DWORD PTR xg -#else - ASM mov ax,ds - ASM mov es,ax - ASM mov di,zg - ASM mov si,xg -#endif - ASM mov bx,sn - ASM push bp - ASM xor bp,bp - tcl1: - ASM lodsw - ASM mul bx - ASM add ax,bp - ASM adc dx,0 - ASM stosw - ASM mov bp,dx - ASM loop tcl1 - - ASM mov ax,bp - ASM pop bp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov carry,ax - out1: -#endif -#if INLINE_ASM == 2 - ASM cld - ASM mov cx,xl - ASM or cx,cx - ASM je out1 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les di,DWORD PTR zg - ASM lds si,DWORD PTR xg -#else - ASM mov ax,ds - ASM mov es,ax - ASM mov di,zg - ASM mov si,xg -#endif - ASM mov ebx,sn - ASM push ebp - ASM xor ebp,ebp - tcl1: - ASM lodsd - ASM mul ebx - ASM add eax,ebp - ASM adc edx,0 - ASM stosd - ASM mov ebp,edx - ASM loop tcl1 - - ASM mov eax,ebp - ASM pop ebp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov carry,eax - out1: -#endif -#if INLINE_ASM == 3 - ASM mov ecx,xl - ASM or ecx,ecx - ASM je out1 - ASM mov ebx,sn - ASM mov edi,zg - ASM mov esi,xg - ASM push ebp - ASM xor ebp,ebp - tcl1: - ASM mov eax,[esi] - ASM add esi,4 - ASM mul ebx - ASM add eax,ebp - ASM adc edx,0 - ASM mov [edi],eax - ASM add edi,4 - ASM mov ebp,edx - ASM dec ecx - ASM jnz tcl1 - - ASM mov eax,ebp - ASM pop ebp - ASM mov carry,eax - out1: -#endif -#if INLINE_ASM == 4 - - ASM ( - "movl %4,%%ecx\n" - "orl %%ecx,%%ecx\n" - "je 1f\n" - "movl %3,%%ebx\n" - "movl %1,%%edi\n" - "movl %2,%%esi\n" - "pushl %%ebp\n" - "xorl %%ebp,%%ebp\n" - "0:\n" - "movl (%%esi),%%eax\n" - "addl $4,%%esi\n" - "mull %%ebx\n" - "addl %%ebp,%%eax\n" - "adcl $0,%%edx\n" - "movl %%eax,(%%edi)\n" - "addl $4,%%edi\n" - "movl %%edx,%%ebp\n" - "decl %%ecx\n" - "jnz 0b\n" - - "movl %%ebp,%%eax\n" - "popl %%ebp\n" - "movl %%eax,%0\n" - "1:" - :"=m"(carry) - :"m"(zg),"m"(xg),"m"(sn),"m"(xl) - :"eax","edi","esi","ebx","ecx","edx","memory" - ); - -#endif -#endif -#ifndef INLINE_ASM - for (m=0;mw[m]*sn+carry; - carry=dble.h[MR_TOP]; - z->w[m]=dble.h[MR_BOT]; - } -#else - carry=muldvd(x->w[m],sn,carry,&z->w[m]); -#endif -#endif - if (carry>0) - { - m=xl; - if (m>=mr_mip->nib && mr_mip->check) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - return; - } - z->w[m]=carry; - z->len=m+1; - } - else z->len=xl; -#endif -#ifndef MR_SIMPLE_BASE - } - else while (m0) - { /* multiply each digit of x by n */ - - if (m>mr_mip->nib && mr_mip->check) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - return; - } -#ifdef MR_NOASM - dbled=(mr_large)x->w[m]*sn+carry; - #ifdef MR_FP_ROUNDING - carry=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); - #else - #ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - carry=(mr_small)(dbled>>mr_mip->lg2b); - else - #endif - carry=(mr_small)MR_LROUND(dbled/mr_mip->base); - #endif - z->w[m]=(mr_small)(dbled-(mr_large)carry*mr_mip->base); -#else - #ifdef MR_FP_ROUNDING - carry=imuldiv(x->w[m],sn,carry,mr_mip->base,mr_mip->inverse_base,&z->w[m]); - #else - carry=muldiv(x->w[m],sn,carry,mr_mip->base,&z->w[m]); - #endif -#endif - - m++; - z->len=m; - } -#endif - if (z->len!=0) z->len|=sx; -} - -void premult(_MIPD_ big x,int n,big z) -{ /* premultiply a big number by an int z=x.n */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(9) - - -#ifdef MR_FLASH - if (mr_notint(x)) - { - mr_berror(_MIPP_ MR_ERR_INT_OP); - MR_OUT - return; - } -#endif - if (n==0) /* test for some special cases */ - { - zero(z); - MR_OUT - return; - } - if (n==1) - { - copy(x,z); - MR_OUT - return; - } - if (n<0) - { - n=(-n); - mr_pmul(_MIPP_ x,(mr_small)n,z); - if (z->len!=0) z->len^=MR_MSBIT; - } - else mr_pmul(_MIPP_ x,(mr_small)n,z); - MR_OUT -} - -#ifdef MR_FP_ROUNDING -mr_small mr_sdiv(_MIPD_ big x,mr_small sn,mr_large isn,big z) -#else -mr_small mr_sdiv(_MIPD_ big x,mr_small sn,big z) -#endif -{ - int i,xl; - mr_small sr,*xg,*zg; -#ifdef MR_NOASM - union doubleword dble; - mr_large dbled; - mr_large ldres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - sr=0; - xl=(int)(x->len&MR_OBITS); - if (x!=z) zero(z); -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - xg=x->w; zg=z->w; -/* inline - substitutes for loop below */ -#ifdef INLINE_ASM -#if INLINE_ASM == 1 - ASM std - ASM mov cx,xl - ASM or cx,cx - ASM je out2 - ASM mov bx,cx - ASM shl bx,1 - ASM sub bx,2 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les di,DWORD PTR zg - ASM lds si,DWORD PTR xg -#else - ASM mov ax,ds - ASM mov es,ax - ASM mov di,zg - ASM mov si,xg -#endif - ASM add si,bx - ASM add di,bx - ASM mov bx,sn - ASM push bp - ASM xor bp,bp - tcl2: - ASM mov dx,bp - ASM lodsw - ASM div bx - ASM mov bp,dx - ASM stosw - ASM loop tcl2 - - ASM mov ax,bp - ASM pop bp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov sr,ax - out2: - ASM cld -#endif -#if INLINE_ASM == 2 - ASM std - ASM mov cx,xl - ASM or cx,cx - ASM je out2 - ASM mov bx,cx - ASM shl bx,2 - ASM sub bx,4 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les di,DWORD PTR zg - ASM lds si,DWORD PTR xg -#else - ASM mov ax,ds - ASM mov es,ax - ASM mov di, zg - ASM mov si, xg -#endif - ASM add si,bx - ASM add di,bx - ASM mov ebx,sn - ASM push ebp - ASM xor ebp,ebp - tcl2: - ASM mov edx,ebp - ASM lodsd - ASM div ebx - ASM mov ebp,edx - ASM stosd - ASM loop tcl2 - - ASM mov eax,ebp - ASM pop ebp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov sr,eax - out2: - ASM cld -#endif -#if INLINE_ASM == 3 - ASM mov ecx,xl - ASM or ecx,ecx - ASM je out2 - ASM mov ebx,ecx - ASM shl ebx,2 - ASM mov esi, xg - ASM add esi,ebx - ASM mov edi, zg - ASM add edi,ebx - ASM mov ebx,sn - ASM push ebp - ASM xor ebp,ebp - tcl2: - ASM sub esi,4 - ASM mov edx,ebp - ASM mov eax,[esi] - ASM div ebx - ASM sub edi,4 - ASM mov ebp,edx - ASM mov [edi],eax - ASM dec ecx - ASM jnz tcl2 - - ASM mov eax,ebp - ASM pop ebp - ASM mov sr,eax - out2: - ASM nop -#endif -#if INLINE_ASM == 4 - - ASM ( - "movl %4,%%ecx\n" - "orl %%ecx,%%ecx\n" - "je 3f\n" - "movl %%ecx,%%ebx\n" - "shll $2,%%ebx\n" - "movl %2,%%esi\n" - "addl %%ebx,%%esi\n" - "movl %1,%%edi\n" - "addl %%ebx,%%edi\n" - "movl %3,%%ebx\n" - "pushl %%ebp\n" - "xorl %%ebp,%%ebp\n" - "2:\n" - "subl $4,%%esi\n" - "movl %%ebp,%%edx\n" - "movl (%%esi),%%eax\n" - "divl %%ebx\n" - "subl $4,%%edi\n" - "movl %%edx,%%ebp\n" - "movl %%eax,(%%edi)\n" - "decl %%ecx\n" - "jnz 2b\n" - - "movl %%ebp,%%eax\n" - "popl %%ebp\n" - "movl %%eax,%0\n" - "3:" - "nop" - :"=m"(sr) - :"m"(zg),"m"(xg),"m"(sn),"m"(xl) - :"eax","edi","esi","ebx","ecx","edx","memory" - ); -#endif -#endif -#ifndef INLINE_ASM - for (i=xl-1;i>=0;i--) - { -#ifdef MR_NOASM - dble.h[MR_BOT]=x->w[i]; - dble.h[MR_TOP]=sr; - z->w[i]=(mr_small)(dble.d/sn); - sr=(mr_small)(dble.d-(mr_large)z->w[i]*sn); -#else - z->w[i]=muldvm(sr,x->w[i],sn,&sr); -#endif - } -#endif -#endif -#ifndef MR_SIMPLE_BASE - } - else for (i=xl-1;i>=0;i--) - { /* divide each digit of x by n */ -#ifdef MR_NOASM - dbled=(mr_large)sr*mr_mip->base+x->w[i]; -#ifdef MR_FP_ROUNDING - z->w[i]=(mr_small)MR_LROUND(dbled*isn); -#else - z->w[i]=(mr_small)MR_LROUND(dbled/sn); -#endif - sr=(mr_small)(dbled-(mr_large)z->w[i]*sn); -#else -#ifdef MR_FP_ROUNDING - z->w[i]=imuldiv(sr,mr_mip->base,x->w[i],sn,isn,&sr); -#else - z->w[i]=muldiv(sr,mr_mip->base,x->w[i],sn,&sr); -#endif -#endif - } -#endif - z->len=x->len; - mr_lzero(z); - return sr; -} - -int subdiv(_MIPD_ big x,int n,big z) -{ /* subdivide a big number by an int z=x/n * - * returns int remainder */ - mr_lentype sx; -#ifdef MR_FP_ROUNDING - mr_large in; -#endif - int r,i,msb; - mr_small lsb; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return 0; - - MR_IN(10) -#ifdef MR_FLASH - if (mr_notint(x)) mr_berror(_MIPP_ MR_ERR_INT_OP); -#endif - if (n==0) mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - if (mr_mip->ERNUM) - { - MR_OUT - return 0; - } - - if (x->len==0) - { - zero(z); - MR_OUT - return 0; - } - if (n==1) /* special case */ - { - copy(x,z); - MR_OUT - return 0; - } - sx=(x->len&MR_MSBIT); - if (n==2 && mr_mip->base==0) - { /* fast division by 2 using shifting */ -#ifndef MR_NOFULLWIDTH - -/* I don't want this code upsetting the compiler ... */ -/* mr_mip->base==0 can't happen with MR_NOFULLWIDTH */ - - copy(x,z); - msb=(int)(z->len&MR_OBITS)-1; - r=(int)z->w[0]&1; - for (i=0;;i++) - { - z->w[i]>>=1; - if (i==msb) - { - if (z->w[i]==0) mr_lzero(z); - break; - } - lsb=z->w[i+1]&1; - z->w[i]|=(lsb<<(MIRACL-1)); - } - - MR_OUT - if (sx==0) return r; - else return (-r); -#endif - } - -#ifdef MR_FP_ROUNDING - in=mr_invert(n); -#endif - if (n<0) - { - n=(-n); -#ifdef MR_FP_ROUNDING - r=(int)mr_sdiv(_MIPP_ x,(mr_small)n,in,z); -#else - r=(int)mr_sdiv(_MIPP_ x,(mr_small)n,z); -#endif - if (z->len!=0) z->len^=MR_MSBIT; - } -#ifdef MR_FP_ROUNDING - else r=(int)mr_sdiv(_MIPP_ x,(mr_small)n,in,z); -#else - else r=(int)mr_sdiv(_MIPP_ x,(mr_small)n,z); -#endif - MR_OUT - if (sx==0) return r; - else return (-r); -} - -int remain(_MIPD_ big x,int n) -{ /* return integer remainder when x divided by n */ - int r; - mr_lentype sx; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(88); - - sx=(x->len&MR_MSBIT); - - if (n==2 && MR_REMAIN(mr_mip->base,2)==0) - { /* fast odd/even check if base is even */ - MR_OUT - if ((int)MR_REMAIN(x->w[0],2)==0) return 0; - else - { - if (sx==0) return 1; - else return (-1); - } - } - if (n==8 && MR_REMAIN(mr_mip->base,8)==0) - { /* fast check */ - MR_OUT - r=(int)MR_REMAIN(x->w[0],8); - if (sx!=0) r=-r; - return r; - } - - copy(x,mr_mip->w0); - r=subdiv(_MIPP_ mr_mip->w0,n,mr_mip->w0); - MR_OUT - return r; -} - -BOOL subdivisible(_MIPD_ big x,int n) -{ - if (remain(_MIPP_ x,n)==0) return TRUE; - else return FALSE; -} - -int hamming(_MIPD_ big x) -{ - int h; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return 0; - MR_IN(148); - h=0; - copy(x,mr_mip->w1); - absol(mr_mip->w1,mr_mip->w1); - while (size(mr_mip->w1)!=0) - h+=subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); - - MR_OUT - return h; -} - -void bytes_to_big(_MIPD_ int len,const char *ptr,big x) -{ /* convert len bytes into a big * - * The first byte is the Most significant */ - int i,j,m,n,r; - unsigned int dig; - unsigned char ch; - mr_small wrd; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - MR_IN(140); - - zero(x); - - if (len<=0) - { - MR_OUT - return; - } -/* remove leading zeros.. */ - - while (*ptr==0) - { - ptr++; len--; - if (len==0) - { - MR_OUT - return; - } - } - -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { /* pack bytes directly into big */ -#endif -#ifndef MR_NOFULLWIDTH - m=MIRACL/8; - n=len/m; - - r=len%m; - wrd=(mr_small)0; - if (r!=0) - { - n++; - for (j=0;jlen=n; - if (n>mr_mip->nib && mr_mip->check) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - MR_OUT - return; - } - if (r!=0) - { - n--; - x->w[n]=wrd; - } - - for (i=n-1;i>=0;i--) - { - for (j=0;jw[i]=wrd; - } - mr_lzero(x); /* needed */ -#endif -#ifndef MR_SIMPLE_BASE - } - else - { - for (i=0;iERNUM) break; -#if MIRACL==8 - mr_shift(_MIPP_ x,1,x); -#else - premult(_MIPP_ x,256,x); -#endif - ch=MR_TOBYTE(ptr[i]); - dig=ch; - incr(_MIPP_ x,(int)dig,x); - } - } -#endif - MR_OUT -} - -int big_to_bytes(_MIPD_ int max,big x,char *ptr,BOOL justify) -{ /* convert positive big into octet string */ - int i,j,r,m,n,len,start; - unsigned int dig; - unsigned char ch; - mr_small wrd; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM || max<0) return 0; - - if (max==0 && justify) return 0; - if (size(x)==0) - { - if (justify) - { - for (i=0;ibase==0) - { -#endif -#ifndef MR_NOFULLWIDTH - m=MIRACL/8; - n=(int)(x->len&MR_OBITS); - n--; - len=n*m; - wrd=x->w[n]; /* most significant */ - r=0; - while (wrd!=(mr_small)0) { r++; wrd>>=8; len++;} - r%=m; - - if (max>0 && len>max) - { - mr_berror(_MIPP_ MR_ERR_TOO_BIG); - MR_OUT - return 0; - } - - if (justify) - { - start=max-len; - for (i=0;iw[n--]; - for (i=r-1;i>=0;i--) - { - ptr[start+i]=(char)(wrd&0xFF); - wrd>>=8; - } - } - - for (i=r;iw[n--]; - for (j=m-1;j>=0;j--) - { - ptr[start+i+j]=(char)(wrd&0xFF); - wrd>>=8; - } - } -#endif -#ifndef MR_SIMPLE_BASE - } - else - { - copy(x,mr_mip->w1); - for (len=0;;len++) - { - if (mr_mip->ERNUM) break; - - if (size(mr_mip->w1)==0) - { - if (justify) - { - if (len==max) break; - } - else break; - } - - if (max>0 && len>=max) - { - mr_berror(_MIPP_ MR_ERR_TOO_BIG); - MR_OUT - return 0; - } -#if MIRACL==8 - ch=mr_mip->w1->w[0]; - mr_shift(_MIPP_ mr_mip->w1,-1,mr_mip->w1); -#else - dig=(unsigned int)subdiv(_MIPP_ mr_mip->w1,256,mr_mip->w1); - ch=MR_TOBYTE(dig); -#endif - for (i=len;i>0;i--) ptr[i]=ptr[i-1]; - ptr[0]=MR_TOBYTE(ch); - } - } -#endif - MR_OUT - if (justify) return max; - else return len; -} - -#ifndef MR_NO_ECC_MULTIADD - -/* Solinas's Joint Sparse Form */ - -void mr_jsf(_MIPD_ big k0,big k1,big u0p,big u0m,big u1p,big u1m) -{ - int j,u0,u1,d0,d1,l0,l1; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(191) - - d0=d1=0; - - convert(_MIPP_ 1,mr_mip->w1); - copy(k0,mr_mip->w2); - copy(k1,mr_mip->w3); - zero(u0p); zero(u0m); zero(u1p); zero(u1m); - - j=0; - while (!mr_mip->ERNUM) - { - if (size(mr_mip->w2)==0 && d0==0 && size(mr_mip->w3)==0 && d1==0) break; - l0=remain(_MIPP_ mr_mip->w2,8); - l0=(l0+d0)&0x7; - l1=remain(_MIPP_ mr_mip->w3,8); - l1=(l1+d1)&0x7; - - if (l0%2==0) u0=0; - else - { - u0=2-(l0%4); - if ((l0==3 || l0==5) && l1%4==2) u0=-u0; - } - if (l1%2==0) u1=0; - else - { - u1=2-(l1%4); - if ((l1==3 || l1==5) && l0%4==2) u1=-u1; - } -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - if (u0>0) mr_addbit(_MIPP_ u0p,j); - if (u0<0) mr_addbit(_MIPP_ u0m,j); - if (u1>0) mr_addbit(_MIPP_ u1p,j); - if (u1<0) mr_addbit(_MIPP_ u1m,j); - -#ifndef MR_ALWAYS_BINARY - } - else - { - if (u0>0) add(_MIPP_ u0p,mr_mip->w1,u0p); - if (u0<0) add(_MIPP_ u0m,mr_mip->w1,u0m); - if (u1>0) add(_MIPP_ u1p,mr_mip->w1,u1p); - if (u1<0) add(_MIPP_ u1m,mr_mip->w1,u1m); - } -#endif - - if (d0+d0==1+u0) d0=1-d0; - if (d1+d1==1+u1) d1=1-d1; - - subdiv(_MIPP_ mr_mip->w2,2,mr_mip->w2); - subdiv(_MIPP_ mr_mip->w3,2,mr_mip->w3); - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) -#endif - j++; -#ifndef MR_ALWAYS_BINARY - else - premult(_MIPP_ mr_mip->w1,2,mr_mip->w1); -#endif - } - MR_OUT - return; -} - -#endif diff --git a/crypto/sm2/miracl/mrarth2.c b/crypto/sm2/miracl/mrarth2.c deleted file mode 100644 index 6daed161..00000000 --- a/crypto/sm2/miracl/mrarth2.c +++ /dev/null @@ -1,1584 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL arithmetic routines 2 - multiplying and dividing BIG NUMBERS. - * mrarth2.c - * - */ - -#include - -#ifdef MR_FP -#include -#endif - -#ifdef MR_WIN64 -#include -#endif - - -/* If a number has more than this number of digits, then squaring is faster */ - -#define SQR_FASTER_THRESHOLD 5 - -mr_small normalise(_MIPD_ big x,big y) -{ /* normalise divisor */ - mr_small norm,r; -#ifdef MR_FP - mr_small dres; -#endif - int len; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(4) - - if (x!=y) copy(x,y); - len=(int)(y->len&MR_OBITS); -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - if ((r=y->w[len-1]+1)==0) norm=1; -#ifdef MR_NOASM - else norm=(mr_small)(((mr_large)1 << MIRACL)/r); -#else - else norm=muldvm((mr_small)1,(mr_small)0,r,&r); -#endif - if (norm!=1) mr_pmul(_MIPP_ y,norm,y); -#endif -#ifndef MR_SIMPLE_BASE - } - else - { - norm=MR_DIV(mr_mip->base,(mr_small)(y->w[len-1]+1)); - if (norm!=1) mr_pmul(_MIPP_ y,norm,y); - } -#endif - MR_OUT - return norm; -} - -void multiply(_MIPD_ big x,big y,big z) -{ /* multiply two big numbers: z=x.y */ - int i,xl,yl,j,ti; - mr_small carry,*xg,*yg,*w0g; - -#ifdef MR_ITANIUM - mr_small tm; -#endif -#ifdef MR_WIN64 - mr_small tm,tr; -#endif - mr_lentype sz; - big w0; -#ifdef MR_NOASM - union doubleword dble; - mr_large dbled; - mr_large ldres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - if (y->len==0 || x->len==0) - { - zero(z); - return; - } - if (x!=mr_mip->w5 && y!=mr_mip->w5 && z==mr_mip->w5) w0=mr_mip->w5; - else w0=mr_mip->w0; /* local pointer */ - - MR_IN(5) - -#ifdef MR_FLASH - if (mr_notint(x) || mr_notint(y)) - { - mr_berror(_MIPP_ MR_ERR_INT_OP); - MR_OUT - return; - } -#endif - sz=((x->len&MR_MSBIT)^(y->len&MR_MSBIT)); - xl=(int)(x->len&MR_OBITS); - yl=(int)(y->len&MR_OBITS); - zero(w0); - if (mr_mip->check && xl+yl>mr_mip->nib) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - MR_OUT - return; - } -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - xg=x->w; yg=y->w; w0g=w0->w; - if (x==y && xl>SQR_FASTER_THRESHOLD) - /* extra hassle make it not */ - /* worth it for small numbers */ - { /* fast squaring */ - for (i=0;iw[i]*x->w[j]+carry+w0->w[i+j]; - w0->w[i+j]=dble.h[MR_BOT]; - carry=dble.h[MR_TOP]; -#else - muldvd2(x->w[i],x->w[j],&carry,&w0->w[i+j]); -#endif - } - w0->w[xl+i]=carry; -#endif - } -#ifdef INLINE_ASM -#if INLINE_ASM == 1 - ASM mov cx,xl - ASM shl cx,1 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les bx,DWORD PTR w0g -#else - ASM mov bx,w0g -#endif - tcl5: -#ifdef MR_LMM - ASM rcl WORD PTR es:[bx],1 -#else - ASM rcl WORD PTR [bx],1 -#endif - ASM inc bx - ASM inc bx - ASM loop tcl5 - - ASM cld - ASM mov cx,xl -#ifdef MR_LMM - ASM les di,DWORD PTR w0g - ASM lds si,DWORD PTR xg -#else - ASM mov di,w0g - ASM mov si,xg -#endif - - ASM xor bx,bx - tcl7: - ASM lodsw - ASM mul ax - ASM add ax,bx - ASM adc dx,0 -#ifdef MR_LMM - ASM add es:[di],ax -#else - ASM add [di],ax -#endif - ASM adc dx,0 - ASM xor bx,bx - ASM inc di - ASM inc di -#ifdef MR_LMM - ASM add es:[di],dx -#else - ASM add [di],dx -#endif - ASM adc bx,0 - ASM inc di - ASM inc di - ASM loop tcl7 -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif -#endif -#if INLINE_ASM == 2 - ASM mov cx,xl - ASM shl cx,1 -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les bx,DWORD PTR w0g -#else - ASM mov bx,w0g -#endif - tcl5: -#ifdef MR_LMM - ASM rcl DWORD PTR es:[bx],1 -#else - ASM rcl DWORD PTR [bx],1 -#endif - ASM inc bx - ASM inc bx - ASM inc bx - ASM inc bx - ASM loop tcl5 - - ASM cld - ASM mov cx,xl -#ifdef MR_LMM - ASM les di,DWORD PTR w0g - ASM lds si,DWORD PTR xg -#else - ASM mov di,w0g - ASM mov si,xg -#endif - ASM xor ebx,ebx - tcl7: - ASM lodsd - ASM mul eax - ASM add eax,ebx - ASM adc edx,0 -#ifdef MR_LMM - ASM add es:[di],eax -#else - ASM add [di],eax -#endif - ASM adc edx,0 - ASM xor ebx,ebx - ASM add di,4 -#ifdef MR_LMM - ASM add es:[di],edx -#else - ASM add [di],edx -#endif - ASM adc ebx,0 - ASM add di,4 - ASM loop tcl7 -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif -#endif -#if INLINE_ASM == 3 - ASM mov ecx,xl - ASM shl ecx,1 - ASM mov edi,w0g - tcl5: - ASM rcl DWORD PTR [edi],1 - ASM inc edi - ASM inc edi - ASM inc edi - ASM inc edi - ASM loop tcl5 - - ASM mov ecx,xl - ASM mov esi,xg - ASM mov edi,w0g - ASM xor ebx,ebx - tcl7: - ASM mov eax,[esi] - ASM add esi,4 - ASM mul eax - ASM add eax,ebx - ASM adc edx,0 - ASM add [edi],eax - ASM adc edx,0 - ASM xor ebx,ebx - ASM add edi,4 - ASM add [edi],edx - ASM adc ebx,0 - ASM add edi,4 - ASM dec ecx - ASM jnz tcl7 -#endif -#if INLINE_ASM == 4 - ASM ( - "movl %0,%%ecx\n" - "shll $1,%%ecx\n" - "movl %1,%%edi\n" - "tcl5:\n" - "rcll $1,(%%edi)\n" - "incl %%edi\n" - "incl %%edi\n" - "incl %%edi\n" - "incl %%edi\n" - "loop tcl5\n" - - "movl %0,%%ecx\n" - "movl %2,%%esi\n" - "movl %1,%%edi\n" - "xorl %%ebx,%%ebx\n" - "tcl7:\n" - "movl (%%esi),%%eax\n" - "addl $4,%%esi\n" - "mull %%eax\n" - "addl %%ebx,%%eax\n" - "adcl $0,%%edx\n" - "addl %%eax,(%%edi)\n" - "adcl $0,%%edx\n" - "xorl %%ebx,%%ebx\n" - "addl $4,%%edi\n" - "addl %%edx,(%%edi)\n" - "adcl $0,%%ebx\n" - "addl $4,%%edi\n" - "decl %%ecx\n" - "jnz tcl7\n" - : - :"m"(xl),"m"(w0g),"m"(xg) - :"eax","edi","esi","ebx","ecx","edx","memory" - ); -#endif -#endif -#ifndef INLINE_ASM - w0->len=xl+xl-1; - mr_padd(_MIPP_ w0,w0,w0); /* double it */ - carry=0; - for (i=0;iw[i]*x->w[i]+carry+w0->w[ti]; - w0->w[ti]=dble.h[MR_BOT]; - carry=dble.h[MR_TOP]; -#else - muldvd2(x->w[i],x->w[i],&carry,&w0->w[ti]); -#endif - w0->w[ti+1]+=carry; - if (w0->w[ti+1]w[i]*y->w[j]+carry+w0->w[i+j]; - w0->w[i+j]=dble.h[MR_BOT]; - carry=dble.h[MR_TOP]; -#else - muldvd2(x->w[i],y->w[j],&carry,&w0->w[i+j]); -#endif - } - w0->w[yl+i]=carry; -#endif - } -#endif -#ifndef MR_SIMPLE_BASE - } - else - { - if (x==y && xl>SQR_FASTER_THRESHOLD) - { /* squaring can be done nearly twice as fast */ - for (i=0;iw[i]*x->w[j]+w0->w[i+j]+carry; - #ifdef MR_FP_ROUNDING - carry=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); - #else - #ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - carry=(mr_small)(dbled>>mr_mip->lg2b); - else - #endif - carry=(mr_small)MR_LROUND(dbled/mr_mip->base); - #endif - w0->w[i+j]=(mr_small)(dbled-(mr_large)carry*mr_mip->base); -#else - - #ifdef MR_FP_ROUNDING - carry=imuldiv(x->w[i],x->w[j],w0->w[i+j]+carry,mr_mip->base,mr_mip->inverse_base,&w0->w[i+j]); - #else - carry=muldiv(x->w[i],x->w[j],w0->w[i+j]+carry,mr_mip->base,&w0->w[i+j]); - #endif -#endif - } - w0->w[xl+i]=carry; - } - w0->len=xl+xl-1; - mr_padd(_MIPP_ w0,w0,w0); /* double it */ - carry=0; - for (i=0;iw[i]*x->w[i]+w0->w[ti]+carry; -#ifdef MR_FP_ROUNDING - carry=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); -#else -#ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - carry=(mr_small)(dbled>>mr_mip->lg2b); - else -#endif - carry=(mr_small)MR_LROUND(dbled/mr_mip->base); -#endif - w0->w[ti]=(mr_small)(dbled-(mr_large)carry*mr_mip->base); -#else - -#ifdef MR_FP_ROUNDING - carry=imuldiv(x->w[i],x->w[i],w0->w[ti]+carry,mr_mip->base,mr_mip->inverse_base,&w0->w[ti]); -#else - carry=muldiv(x->w[i],x->w[i],w0->w[ti]+carry,mr_mip->base,&w0->w[ti]); -#endif - -#endif - w0->w[ti+1]+=carry; - carry=0; - if (w0->w[ti+1]>=mr_mip->base) - { - carry=1; - w0->w[ti+1]-=mr_mip->base; - } - } - } - else for (i=0;iw[i]*y->w[j]+w0->w[i+j]+carry; - -#ifdef MR_FP_ROUNDING - carry=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); -#else -#ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - carry=(mr_small)(dbled>>mr_mip->lg2b); - else -#endif - carry=(mr_small)MR_LROUND(dbled/mr_mip->base); -#endif - w0->w[i+j]=(mr_small)(dbled-(mr_large)carry*mr_mip->base); -#else - -#ifdef MR_FP_ROUNDING - carry=imuldiv(x->w[i],y->w[j],w0->w[i+j]+carry,mr_mip->base,mr_mip->inverse_base,&w0->w[i+j]); -#else - carry=muldiv(x->w[i],y->w[j],w0->w[i+j]+carry,mr_mip->base,&w0->w[i+j]); -#endif - -#endif - } - w0->w[yl+i]=carry; - } - } -#endif - w0->len=(sz|(xl+yl)); /* set length and sign of result */ - - mr_lzero(w0); - copy(w0,z); - MR_OUT -} - -void divide(_MIPD_ big x,big y,big z) -{ /* divide two big numbers z=x/y : x=x mod y * - * returns quotient only if divide(x,y,x) * - * returns remainder only if divide(x,y,y) */ - mr_small carry,attemp,ldy,sdy,ra,r,d,tst,psum; -#ifdef MR_FP - mr_small dres; -#endif - mr_lentype sx,sy,sz; - mr_small borrow,dig,*w0g,*yg; - int i,k,m,x0,y0,w00; - big w0; - -#ifdef MR_ITANIUM - mr_small tm; -#endif -#ifdef MR_WIN64 - mr_small tm; -#endif -#ifdef MR_NOASM - union doubleword dble; - mr_large dbled; - mr_large ldres; -#endif - BOOL check; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - w0=mr_mip->w0; - - MR_IN(6) - - if (x==y) mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); -#ifdef MR_FLASH - if (mr_notint(x) || mr_notint(y)) mr_berror(_MIPP_ MR_ERR_INT_OP); -#endif - if (y->len==0) mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - if (mr_mip->ERNUM) - { - MR_OUT - return; - } - sx=(x->len&MR_MSBIT); /* extract signs ... */ - sy=(y->len&MR_MSBIT); - sz=(sx^sy); - x->len&=MR_OBITS; /* ... and force operands to positive */ - y->len&=MR_OBITS; - x0=(int)x->len; - y0=(int)y->len; - copy(x,w0); - w00=(int)w0->len; - if (mr_mip->check && (w00-y0+1>mr_mip->nib)) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - MR_OUT - return; - } - d=0; - if (x0==y0) - { - if (x0==1) /* special case - x and y are both mr_smalls */ - { - d=MR_DIV(w0->w[0],y->w[0]); - w0->w[0]=MR_REMAIN(w0->w[0],y->w[0]); - mr_lzero(w0); - } - else if (MR_DIV(w0->w[x0-1],4)w[x0-1]) - while (mr_compare(w0,y)>=0) - { /* mr_small quotient - so do up to four subtracts instead */ - mr_psub(_MIPP_ w0,y,w0); - d++; - } - } - if (mr_compare(w0,y)<0) - { /* x less than y - so x becomes remainder */ - if (x!=z) /* testing parameters */ - { - copy(w0,x); - if (x->len!=0) x->len|=sx; - } - if (y!=z) - { - zero(z); - z->w[0]=d; - if (d>0) z->len=(sz|1); - } - y->len|=sy; - MR_OUT - return; - } - - if (y0==1) - { /* y is int - so use subdiv instead */ -#ifdef MR_FP_ROUNDING - r=mr_sdiv(_MIPP_ w0,y->w[0],mr_invert(y->w[0]),w0); -#else - r=mr_sdiv(_MIPP_ w0,y->w[0],w0); -#endif - if (y!=z) - { - copy(w0,z); - z->len|=sz; - } - if (x!=z) - { - zero(x); - x->w[0]=r; - if (r>0) x->len=(sx|1); - } - y->len|=sy; - MR_OUT - return; - } - if (y!=z) zero(z); - d=normalise(_MIPP_ y,y); - check=mr_mip->check; - mr_mip->check=OFF; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - if (d!=1) mr_pmul(_MIPP_ w0,d,w0); - ldy=y->w[y0-1]; - sdy=y->w[y0-2]; - w0g=w0->w; yg=y->w; - for (k=w00-1;k>=y0-1;k--) - { /* long division */ -#ifdef INLINE_ASM -#if INLINE_ASM == 1 -#ifdef MR_LMM - ASM push ds - ASM lds bx,DWORD PTR w0g -#else - ASM mov bx,w0g -#endif - ASM mov si,k - ASM shl si,1 - ASM add bx,si - ASM mov dx,[bx+2] - ASM mov ax,[bx] - ASM cmp dx,ldy - ASM jne tcl8 - ASM mov di,0xffff - ASM mov si,ax - ASM add si,ldy - ASM jc tcl12 - ASM jmp tcl10 - tcl8: - ASM div WORD PTR ldy - ASM mov di,ax - ASM mov si,dx - tcl10: - ASM mov ax,sdy - ASM mul di - ASM cmp dx,si - ASM jb tcl12 - ASM jne tcl11 - ASM cmp ax,[bx-2] - ASM jbe tcl12 - tcl11: - ASM dec di - ASM add si,ldy - ASM jnc tcl10 - tcl12: - ASM mov attemp,di -#ifdef MR_LMM - ASM pop ds -#endif -#endif -/* NOTE push and pop of esi/edi should not be necessary - Borland C bug * - * These pushes are needed here even if register variables are disabled */ -#if INLINE_ASM == 2 - ASM push esi - ASM push edi -#ifdef MR_LMM - ASM push ds - ASM lds bx,DWORD PTR w0g -#else - ASM mov bx,w0g -#endif - ASM mov si,k - ASM shl si,2 - ASM add bx,si - ASM mov edx,[bx+4] - ASM mov eax,[bx] - ASM cmp edx,ldy - ASM jne tcl8 - ASM mov edi,0xffffffff - ASM mov esi,eax - ASM add esi,ldy - ASM jc tcl12 - ASM jmp tcl10 - tcl8: - ASM div DWORD PTR ldy - ASM mov edi,eax - ASM mov esi,edx - tcl10: - ASM mov eax,sdy - ASM mul edi - ASM cmp edx,esi - ASM jb tcl12 - ASM jne tcl11 - ASM cmp eax,[bx-4] - ASM jbe tcl12 - tcl11: - ASM dec edi - ASM add esi,ldy - ASM jnc tcl10 - tcl12: - ASM mov attemp,edi -#ifdef MR_LMM - ASM pop ds -#endif - ASM pop edi - ASM pop esi -#endif -#if INLINE_ASM == 3 - ASM push esi - ASM push edi - ASM mov ebx,w0g - ASM mov esi,k - ASM shl esi,2 - ASM add ebx,esi - ASM mov edx,[ebx+4] - ASM mov eax,[ebx] - ASM cmp edx,ldy - ASM jne tcl8 - ASM mov edi,0xffffffff - ASM mov esi,eax - ASM add esi,ldy - ASM jc tcl12 - ASM jmp tcl10 - tcl8: - ASM div DWORD PTR ldy - ASM mov edi,eax - ASM mov esi,edx - tcl10: - ASM mov eax,sdy - ASM mul edi - ASM cmp edx,esi - ASM jb tcl12 - ASM jne tcl11 - ASM cmp eax,[ebx-4] - ASM jbe tcl12 - tcl11: - ASM dec edi - ASM add esi,ldy - ASM jnc tcl10 - tcl12: - ASM mov attemp,edi - ASM pop edi - ASM pop esi -#endif -#if INLINE_ASM == 4 - ASM ( - "movl %1,%%ebx\n" - "movl %2,%%esi\n" - "shll $2,%%esi\n" - "addl %%esi,%%ebx\n" - "movl 4(%%ebx),%%edx\n" - "movl (%%ebx),%%eax\n" - "cmpl %3,%%edx\n" - "jne tcl8\n" - "movl $0xffffffff,%%edi\n" - "movl %%eax,%%esi\n" - "addl %3,%%esi\n" - "jc tcl12\n" - "jmp tcl10\n" - "tcl8:\n" - "divl %3\n" - "movl %%eax,%%edi\n" - "movl %%edx,%%esi\n" - "tcl10:\n" - "movl %4,%%eax\n" - "mull %%edi\n" - "cmpl %%esi,%%edx\n" - "jb tcl12\n" - "jne tcl11\n" - "cmpl -4(%%ebx),%%eax\n" - "jbe tcl12\n" - "tcl11:\n" - "decl %%edi\n" - "addl %3,%%esi\n" - "jnc tcl10\n" - "tcl12:\n" - "movl %%edi,%0\n" - :"=m"(attemp) - :"m"(w0g),"m"(k),"m"(ldy),"m"(sdy) - :"eax","edi","esi","ebx","ecx","edx","memory" - ); -#endif -#endif -#ifndef INLINE_ASM - carry=0; - if (w0->w[k+1]==ldy) /* guess next quotient digit */ - { - attemp=(mr_small)(-1); - ra=ldy+w0->w[k]; - if (raw[k]; - dble.h[MR_TOP]=w0->w[k+1]; - attemp=(mr_small)(dble.d/ldy); - ra=(mr_small)(dble.d-(mr_large)attemp*ldy); - } -#else - else attemp=muldvm(w0->w[k+1],w0->w[k],ldy,&ra); -#endif - while (carry==0) - { -#ifdef MR_NOASM - dble.d=(mr_large)attemp*sdy; - r=dble.h[MR_BOT]; - tst=dble.h[MR_TOP]; -#else - tst=muldvd(sdy,attemp,(mr_small)0,&r); -#endif - if (tst< ra || (tst==ra && r<=w0->w[k-1])) break; - attemp--; /* refine guess */ - ra+=ldy; - if (ra0) - { /* do partial subtraction */ - borrow=0; - /* inline - substitutes for loop below */ -#ifdef INLINE_ASM -#if INLINE_ASM == 1 - ASM cld - ASM mov cx,y0 - ASM mov si,m - ASM shl si,1 - ASM mov di,attemp -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les bx,DWORD PTR w0g - ASM add bx,si - ASM sub bx,2 - ASM lds si,DWORD PTR yg -#else - ASM mov bx,w0g - ASM add bx,si - ASM sub bx,2 - ASM mov si,yg -#endif - ASM push bp - ASM xor bp,bp - - tcl3: - ASM lodsw - ASM mul di - ASM add ax,bp - ASM adc dx,0 - ASM inc bx - ASM inc bx -#ifdef MR_LMM - ASM sub es:[bx],ax -#else - ASM sub [bx],ax -#endif - ASM adc dx,0 - ASM mov bp,dx - ASM loop tcl3 - - ASM mov ax,bp - ASM pop bp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov borrow,ax -#endif -/* NOTE push and pop of esi/edi should not be necessary - Borland C bug * - * These pushes are needed here even if register variables are disabled */ -#if INLINE_ASM == 2 - ASM push esi - ASM push edi - ASM cld - ASM mov cx,y0 - ASM mov si,m - ASM shl si,2 - ASM mov edi,attemp -#ifdef MR_LMM - ASM push ds - ASM push es - ASM les bx,DWORD PTR w0g - ASM add bx,si - ASM sub bx,4 - ASM lds si,DWORD PTR yg -#else - ASM mov bx,w0g - ASM add bx,si - ASM sub bx,4 - ASM mov si,yg -#endif - ASM push ebp - ASM xor ebp,ebp - - tcl3: - ASM lodsd - ASM mul edi - ASM add eax,ebp - ASM adc edx,0 - ASM add bx,4 -#ifdef MR_LMM - ASM sub es:[bx],eax -#else - ASM sub [bx],eax -#endif - ASM adc edx,0 - ASM mov ebp,edx - ASM loop tcl3 - - ASM mov eax,ebp - ASM pop ebp -#ifdef MR_LMM - ASM pop es - ASM pop ds -#endif - ASM mov borrow,eax - ASM pop edi - ASM pop esi -#endif -#if INLINE_ASM == 3 - ASM push esi - ASM push edi - ASM mov ecx,y0 - ASM mov esi,m - ASM shl esi,2 - ASM mov edi,attemp - ASM mov ebx,w0g - ASM add ebx,esi - ASM mov esi,yg - ASM sub ebx,esi - ASM sub ebx,4 - ASM push ebp - ASM xor ebp,ebp - - tcl3: - ASM mov eax,[esi] - ASM add esi,4 - ASM mul edi - ASM add eax,ebp - ASM mov ebp,[esi+ebx] - ASM adc edx,0 - ASM sub ebp,eax - ASM adc edx,0 - ASM mov [esi+ebx],ebp - ASM dec ecx - ASM mov ebp,edx - ASM jnz tcl3 - - ASM mov eax,ebp - ASM pop ebp - ASM mov borrow,eax - ASM pop edi - ASM pop esi -#endif -#if INLINE_ASM == 4 - ASM ( - "movl %1,%%ecx\n" - "movl %2,%%esi\n" - "shll $2,%%esi\n" - "movl %3,%%edi\n" - "movl %4,%%ebx\n" - "addl %%esi,%%ebx\n" - "movl %5,%%esi\n" - "subl %%esi,%%ebx\n" - "subl $4,%%ebx\n" - "pushl %%ebp\n" - "xorl %%ebp,%%ebp\n" - "tcl3:\n" - "movl (%%esi),%%eax\n" - "addl $4,%%esi\n" - "mull %%edi\n" - "addl %%ebp,%%eax\n" - "movl (%%esi,%%ebx),%%ebp\n" - "adcl $0,%%edx\n" - "subl %%eax,%%ebp\n" - "adcl $0,%%edx\n" - "movl %%ebp,(%%esi,%%ebx)\n" - "decl %%ecx\n" - "movl %%edx,%%ebp\n" - "jnz tcl3\n" - - "movl %%ebp,%%eax\n" - "popl %%ebp\n" - "movl %%eax,%0\n" - - :"=m"(borrow) - :"m"(y0),"m"(m),"m"(attemp),"m"(w0g),"m"(yg) - :"eax","edi","esi","ebx","ecx","edx","memory" - ); -#endif -#endif -#ifndef INLINE_ASM - for (i=0;iw[i]+borrow; - dig=dble.h[MR_BOT]; - borrow=dble.h[MR_TOP]; -#else - borrow=muldvd(attemp,y->w[i],borrow,&dig); -#endif - if (w0->w[m+i]w[m+i]-=dig; - } -#endif - - if (w0->w[k+1]w[k+1]=0; - carry=0; - for (i=0;iw[m+i]+y->w[i]+carry; - if (psum>y->w[i]) carry=0; - if (psumw[i]) carry=1; - w0->w[m+i]=psum; - } - attemp--; /* ... and adjust guess */ - } - else w0->w[k+1]-=borrow; - } - if (k==w00-1 && attemp==0) w00--; - else if (y!=z) z->w[m]=attemp; - } -#endif -#ifndef MR_SIMPLE_BASE - } - else - { /* have to do it the hard way */ - if (d!=1) mr_pmul(_MIPP_ w0,d,w0); - ldy=y->w[y0-1]; - sdy=y->w[y0-2]; - - for (k=w00-1;k>=y0-1;k--) - { /* long division */ - - - if (w0->w[k+1]==ldy) /* guess next quotient digit */ - { - attemp=mr_mip->base-1; - ra=ldy+w0->w[k]; - } -#ifdef MR_NOASM - else - { - dbled=(mr_large)w0->w[k+1]*mr_mip->base+w0->w[k]; - attemp=(mr_small)MR_LROUND(dbled/ldy); - ra=(mr_small)(dbled-(mr_large)attemp*ldy); - } -#else - else attemp=muldiv(w0->w[k+1],mr_mip->base,w0->w[k],ldy,&ra); -#endif - while (rabase) - { -#ifdef MR_NOASM - dbled=(mr_large)sdy*attemp; -#ifdef MR_FP_ROUNDING - tst=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); -#else -#ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - tst=(mr_small)(dbled>>mr_mip->lg2b); - else -#endif - tst=(mr_small)MR_LROUND(dbled/mr_mip->base); -#endif - r=(mr_small)(dbled-(mr_large)tst*mr_mip->base); -#else -#ifdef MR_FP_ROUNDING - tst=imuldiv(sdy,attemp,(mr_small)0,mr_mip->base,mr_mip->inverse_base,&r); -#else - tst=muldiv(sdy,attemp,(mr_small)0,mr_mip->base,&r); -#endif -#endif - if (tst< ra || (tst==ra && r<=w0->w[k-1])) break; - attemp--; /* refine guess */ - ra+=ldy; - } - m=k-y0+1; - if (attemp>0) - { /* do partial subtraction */ - borrow=0; - for (i=0;iw[i]+borrow; -#ifdef MR_FP_ROUNDING - borrow=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); -#else -#ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - borrow=(mr_small)(dbled>>mr_mip->lg2b); - else -#endif - borrow=(mr_small)MR_LROUND(dbled/mr_mip->base); -#endif - dig=(mr_small)(dbled-(mr_large)borrow*mr_mip->base); -#else -#ifdef MR_FP_ROUNDING - borrow=imuldiv(attemp,y->w[i],borrow,mr_mip->base,mr_mip->inverse_base,&dig); -#else - borrow=muldiv(attemp,y->w[i],borrow,mr_mip->base,&dig); -#endif -#endif - if (w0->w[m+i]w[m+i]+=(mr_mip->base-dig); - } - else w0->w[m+i]-=dig; - } - if (w0->w[k+1]w[k+1]=0; - carry=0; - for (i=0;iw[m+i]+y->w[i]+carry; - carry=0; - if (psum>=mr_mip->base) - { - carry=1; - psum-=mr_mip->base; - } - w0->w[m+i]=psum; - } - attemp--; /* ... and adjust guess */ - } - else - w0->w[k+1]-=borrow; - } - if (k==w00-1 && attemp==0) w00--; - else if (y!=z) z->w[m]=attemp; - } - } -#endif - if (y!=z) z->len=((w00-y0+1)|sz); /* set sign and length of result */ - - w0->len=y0; - - mr_lzero(y); - mr_lzero(z); - - if (x!=z) - { - mr_lzero(w0); -#ifdef MR_FP_ROUNDING - if (d!=1) mr_sdiv(_MIPP_ w0,d,mr_invert(d),x); -#else - if (d!=1) mr_sdiv(_MIPP_ w0,d,x); -#endif - else copy(w0,x); - if (x->len!=0) x->len|=sx; - } -#ifdef MR_FP_ROUNDING - if (d!=1) mr_sdiv(_MIPP_ y,d,mr_invert(d),y); -#else - if (d!=1) mr_sdiv(_MIPP_ y,d,y); -#endif - y->len|=sy; - mr_mip->check=check; - - MR_OUT -} - -BOOL divisible(_MIPD_ big x,big y) -{ /* returns y|x, that is TRUE if y divides x exactly */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(87) - - copy (x,mr_mip->w0); - divide(_MIPP_ mr_mip->w0,y,y); - - MR_OUT - if (size(mr_mip->w0)==0) return TRUE; - else return FALSE; -} - -void mad(_MIPD_ big x,big y,big z,big w,big q,big r) -{ /* Multiply, Add and Divide; q=(x*y+z)/w remainder r * - * returns remainder only if w=q, quotient only if q=r * - * add done only if x, y and z are distinct. */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - BOOL check; - if (mr_mip->ERNUM) return; - - MR_IN(24) - if (w==r) - { - mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - MR_OUT - return; - } - check=mr_mip->check; - mr_mip->check=OFF; /* turn off some error checks */ - - multiply(_MIPP_ x,y,mr_mip->w0); - if (x!=z && y!=z) add(_MIPP_ mr_mip->w0,z,mr_mip->w0); - - divide(_MIPP_ mr_mip->w0,w,q); - if (q!=r) copy(mr_mip->w0,r); - mr_mip->check=check; - MR_OUT -} - diff --git a/crypto/sm2/miracl/mrarth3.c b/crypto/sm2/miracl/mrarth3.c deleted file mode 100644 index 5f4deb74..00000000 --- a/crypto/sm2/miracl/mrarth3.c +++ /dev/null @@ -1,231 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL arithmetic routines 3 - simple powers and roots - * mrarth3.c - */ - -#include -#include - -void expint(_MIPD_ int b,int n,big x) -{ /* sets x=b^n */ - unsigned int bit,un; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - convert(_MIPP_ 1,x); - if (n==0) return; - - MR_IN(50) - - if (n<0) - { - mr_berror(_MIPP_ MR_ERR_NEG_POWER); - MR_OUT - return; - } - if (b==2) expb2(_MIPP_ n,x); - else - { - bit=1; - un=(unsigned int)n; - while (un>=bit) bit<<=1; - bit>>=1; - while (bit>0) - { /* ltr method */ - multiply(_MIPP_ x,x,x); - if ((bit&un)!=0) premult(_MIPP_ x,b,x); - bit>>=1; - } - } - MR_OUT -} - -void power(_MIPD_ big x,long n,big z,big w) -{ /* raise big number to int power w=x^n * - * (mod z if z and w distinct) */ - mr_small norm; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - copy(x,mr_mip->w5); - zero(w); - if(mr_mip->ERNUM || size(mr_mip->w5)==0) return; - convert(_MIPP_ 1,w); - if (n==0L) return; - - MR_IN(17) - - if (n<0L) - { - mr_berror(_MIPP_ MR_ERR_NEG_POWER); - MR_OUT - return; - } - - if (w==z) forever - { /* "Russian peasant" exponentiation */ - if (n%2!=0L) - multiply(_MIPP_ w,mr_mip->w5,w); - n/=2L; - if (mr_mip->ERNUM || n==0L) break; - multiply(_MIPP_ mr_mip->w5,mr_mip->w5,mr_mip->w5); - } - else - { - norm=normalise(_MIPP_ z,z); - divide(_MIPP_ mr_mip->w5,z,z); - forever - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - if (n%2!=0L) mad(_MIPP_ w,mr_mip->w5,mr_mip->w5,z,z,w); - n/=2L; - if (mr_mip->ERNUM || n==0L) break; - mad(_MIPP_ mr_mip->w5,mr_mip->w5,mr_mip->w5,z,z,mr_mip->w5); - } - if (norm!=1) - { -#ifdef MR_FP_ROUNDING - mr_sdiv(_MIPP_ z,norm,mr_invert(norm),z); -#else - mr_sdiv(_MIPP_ z,norm,z); -#endif - divide(_MIPP_ w,z,z); - } - } - - MR_OUT -} - -BOOL nroot(_MIPD_ big x,int n,big w) -{ /* extract lower approximation to nth root * - * w=x^(1/n) returns TRUE for exact root * - * uses Newtons method */ - int sx,dif,s,p,d,lg2,lgx,rem; - BOOL full; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - if (size(x)==0 || n==1) - { - copy(x,w); - return TRUE; - } - - MR_IN(16) - - if (n<1) mr_berror(_MIPP_ MR_ERR_BAD_ROOT); - sx=exsign(x); - if (n%2==0 && sx==MINUS) mr_berror(_MIPP_ MR_ERR_NEG_ROOT); - if (mr_mip->ERNUM) - { - MR_OUT - return FALSE; - } - insign(PLUS,x); - lgx=logb2(_MIPP_ x); - if (n>=lgx) - { /* root must be 1 */ - insign(sx,x); - convert(_MIPP_ sx,w); - MR_OUT - if (lgx==1) return TRUE; - else return FALSE; - } - expb2(_MIPP_ 1+(lgx-1)/n,mr_mip->w2); /* guess root as 2^(log2(x)/n) */ - s=(-(((int)x->len-1)/n)*n); - mr_shift(_MIPP_ mr_mip->w2,s/n,mr_mip->w2); - lg2=logb2(_MIPP_ mr_mip->w2)-1; - full=FALSE; - if (s==0) full=TRUE; - d=0; - p=1; - while (!mr_mip->ERNUM) - { /* Newtons method */ - copy(mr_mip->w2,mr_mip->w3); - mr_shift(_MIPP_ x,s,mr_mip->w4); - mr_mip->check=OFF; - power(_MIPP_ mr_mip->w2,n-1,mr_mip->w6,mr_mip->w6); - mr_mip->check=ON; - divide(_MIPP_ mr_mip->w4,mr_mip->w6,mr_mip->w2); - rem=size(mr_mip->w4); - subtract(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w2); - dif=size(mr_mip->w2); - subdiv(_MIPP_ mr_mip->w2,n,mr_mip->w2); - add(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w2); - p*=2; - if(plg2b) continue; - if (full && mr_abs(dif)w2,1,mr_mip->w2); - mr_mip->check=OFF; - power(_MIPP_ mr_mip->w2,n,mr_mip->w6,mr_mip->w6); - mr_mip->check=ON; - dif=mr_compare(x,mr_mip->w6); - } - copy(mr_mip->w2,w); - insign(sx,w); - insign(sx,x); - MR_OUT - if (rem==0 && dif==0) return TRUE; - else return FALSE; - } - else - { /* adjust precision */ - d*=2; - if (d==0) d=1; - s+=d*n; - if (s>=0) - { - d-=s/n; - s=0; - full=TRUE; - } - mr_shift(_MIPP_ mr_mip->w2,d,mr_mip->w2); - } - p/=2; - } - MR_OUT - return FALSE; -} - diff --git a/crypto/sm2/miracl/mrbits.c b/crypto/sm2/miracl/mrbits.c deleted file mode 100644 index b14021f8..00000000 --- a/crypto/sm2/miracl/mrbits.c +++ /dev/null @@ -1,245 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL bit manipulation routines - * mrbits.c - */ - -#include -#include - -#ifdef MR_FP -#include -#endif - -int logb2(_MIPD_ big x) -{ /* returns number of bits in x */ - int xl,lg2; - mr_small top; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM || size(x)==0) return 0; - - MR_IN(49) - - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - xl=(int)(x->len&MR_OBITS); - lg2=mr_mip->lg2b*(xl-1); - top=x->w[xl-1]; - while (top>=1) - { - lg2++; - top/=2; - } - -#ifndef MR_ALWAYS_BINARY - } - else - { - copy(x,mr_mip->w0); - insign(PLUS,mr_mip->w0); - lg2=0; - while (mr_mip->w0->len>1) - { -#ifdef MR_FP_ROUNDING - mr_sdiv(_MIPP_ mr_mip->w0,mr_mip->base2,mr_invert(mr_mip->base2),mr_mip->w0); -#else - mr_sdiv(_MIPP_ mr_mip->w0,mr_mip->base2,mr_mip->w0); -#endif - lg2+=mr_mip->lg2b; - } - - while (mr_mip->w0->w[0]>=1) - { - lg2++; - mr_mip->w0->w[0]/=2; - } - } -#endif - MR_OUT - return lg2; -} - -void sftbit(_MIPD_ big x,int n,big z) -{ /* shift x by n bits */ - int m; - mr_small sm; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - copy(x,z); - if (n==0) return; - - MR_IN(47) - - m=mr_abs(n); - sm=mr_shiftbits((mr_small)1,m%mr_mip->lg2b); - if (n>0) - { /* shift left */ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - mr_shift(_MIPP_ z,n/mr_mip->lg2b,z); - mr_pmul(_MIPP_ z,sm,z); -#ifndef MR_ALWAYS_BINARY - } - else - { - expb2(_MIPP_ m,mr_mip->w1); - multiply(_MIPP_ z,mr_mip->w1,z); - } -#endif - } - else - { /* shift right */ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - mr_shift(_MIPP_ z,n/mr_mip->lg2b,z); -#ifdef MR_FP_ROUNDING - mr_sdiv(_MIPP_ z,sm,mr_invert(sm),z); -#else - mr_sdiv(_MIPP_ z,sm,z); -#endif - -#ifndef MR_ALWAYS_BINARY - } - else - { - expb2(_MIPP_ m,mr_mip->w1); - divide(_MIPP_ z,mr_mip->w1,z); - } -#endif - } - MR_OUT -} - -void expb2(_MIPD_ int n,big x) -{ /* sets x=2^n */ - int r,p; -#ifndef MR_ALWAYS_BINARY - int i; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - convert(_MIPP_ 1,x); - if (n==0) return; - - MR_IN(149) - - if (n<0) - { - mr_berror(_MIPP_ MR_ERR_NEG_POWER); - MR_OUT - return; - } - r=n/mr_mip->lg2b; - p=n%mr_mip->lg2b; - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - mr_shift(_MIPP_ x,r,x); - x->w[x->len-1]=mr_shiftbits(x->w[x->len-1],p); -#ifndef MR_ALWAYS_BINARY - } - else - { - for (i=1;i<=r;i++) - mr_pmul(_MIPP_ x,mr_mip->base2,x); - mr_pmul(_MIPP_ x,mr_shiftbits((mr_small)1,p),x); - } -#endif - MR_OUT -} - -#ifndef MR_NO_RAND - -void bigbits(_MIPD_ int n,big x) -{ /* sets x as random < 2^n */ - mr_small r; - mr_lentype wlen; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - zero(x); - if (mr_mip->ERNUM || n<=0) return; - - MR_IN(150) - - expb2(_MIPP_ n,mr_mip->w1); - wlen=mr_mip->w1->len; - do - { - r=brand(_MIPPO_ ); - if (mr_mip->base==0) x->w[x->len++]=r; - else x->w[x->len++]=MR_REMAIN(r,mr_mip->base); - } while (x->lenbase==mr_mip->base2) - { -#endif - - x->w[wlen-1]=MR_REMAIN(x->w[wlen-1],mr_mip->w1->w[wlen-1]); - mr_lzero(x); - -#ifndef MR_ALWAYS_BINARY - } - else - { - divide(_MIPP_ x,mr_mip->w1,mr_mip->w1); - } -#endif - - MR_OUT -} - -#endif diff --git a/crypto/sm2/miracl/mrcore.c b/crypto/sm2/miracl/mrcore.c deleted file mode 100644 index 855b063f..00000000 --- a/crypto/sm2/miracl/mrcore.c +++ /dev/null @@ -1,2290 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * - * MIRACL Core module - contains initialisation code and general purpose - * utilities - * mrcore.c - * - * Space can be saved by removing unneeded functions (mr_and ?) - * - */ - -#include -#include -#include - - -#ifdef MR_FP -#include -#endif - - -/*** Multi-Threaded Support ***/ - -#ifndef MR_GENERIC_MT - - #ifdef MR_OPENMP_MT - #include - -#define MR_MIP_EXISTS - - miracl *mr_mip; - #pragma omp threadprivate(mr_mip) - - miracl *get_mip() - { - return mr_mip; - } - - void mr_init_threading() - { - } - - void mr_end_threading() - { - } - - #endif - - #ifdef MR_WINDOWS_MT - #include - DWORD mr_key; - - miracl *get_mip() - { - return (miracl *)TlsGetValue(mr_key); - } - - void mr_init_threading() - { - mr_key=TlsAlloc(); - } - - void mr_end_threading() - { - TlsFree(mr_key); - } - - #endif - - #ifdef MR_UNIX_MT - #include - pthread_key_t mr_key; - - miracl *get_mip() - { - return (miracl *)pthread_getspecific(mr_key); - } - - void mr_init_threading() - { - pthread_key_create(&mr_key,(void(*)(void *))NULL); - } - - void mr_end_threading() - { - pthread_key_delete(mr_key); - } - #endif - - #ifndef MR_WINDOWS_MT - #ifndef MR_UNIX_MT - #ifndef MR_OPENMP_MT - #ifdef MR_STATIC - miracl mip; - miracl *mr_mip=&mip; - #else - miracl *mr_mip=NULL; /* MIRACL's one and only global variable */ - #endif -#define MR_MIP_EXISTS - miracl *get_mip() - { - return (miracl *)mr_mip; - } - #endif - #endif - #endif - -#ifdef MR_MIP_EXISTS - void set_mip(miracl *mip) - { - mr_mip=mip; - } -#endif - -#endif - -/* See Advanced Windows by Jeffrey Richter, Chapter 12 for methods for - creating different instances of this global for each executing thread - when using Windows '95/NT -*/ - -#ifdef MR_STATIC - -#if MIRACL==8 - -static const int mr_small_primes[]= -{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103, -107,109,113,127,0}; - -#else - -static const int mr_small_primes[]= -{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103, -107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211, -223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331, -337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449, -457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587, -593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709, -719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853, -857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991, -997,0}; - -#endif - -#endif - -#ifndef MR_STRIPPED_DOWN -#ifndef MR_NO_STANDARD_IO - -static char *names[] = -{(char *)"your program",(char *)"innum",(char *)"otnum",(char *)"jack",(char *)"normalise", -(char *)"multiply",(char *)"divide",(char *)"incr",(char *)"decr",(char *)"premult", -(char *)"subdiv",(char *)"fdsize",(char *)"egcd",(char *)"cbase", -(char *)"cinnum",(char *)"cotnum",(char *)"nroot",(char *)"power", -(char *)"powmod",(char *)"bigdig",(char *)"bigrand",(char *)"nxprime",(char *)"isprime", -(char *)"mirvar",(char *)"mad",(char *)"multi_inverse",(char *)"putdig", -(char *)"add",(char *)"subtract",(char *)"mirsys",(char *)"xgcd", -(char *)"fpack",(char *)"dconv",(char *)"mr_shift",(char *)"mround",(char *)"fmul", -(char *)"fdiv",(char *)"fadd",(char *)"fsub",(char *)"fcomp",(char *)"fconv", -(char *)"frecip",(char *)"fpmul",(char *)"fincr",(char *)"",(char *)"ftrunc", -(char *)"frand",(char *)"sftbit",(char *)"build",(char *)"logb2",(char *)"expint", -(char *)"fpower",(char *)"froot",(char *)"fpi",(char *)"fexp",(char *)"flog",(char *)"fpowf", -(char *)"ftan",(char *)"fatan",(char *)"fsin",(char *)"fasin",(char *)"fcos",(char *)"facos", -(char *)"ftanh",(char *)"fatanh",(char *)"fsinh",(char *)"fasinh",(char *)"fcosh", -(char *)"facosh",(char *)"flop",(char *)"gprime",(char *)"powltr",(char *)"fft_mult", -(char *)"crt_init",(char *)"crt",(char *)"otstr",(char *)"instr",(char *)"cotstr",(char *)"cinstr",(char *)"powmod2", -(char *)"prepare_monty",(char *)"nres",(char *)"redc",(char *)"nres_modmult",(char *)"nres_powmod", -(char *)"nres_moddiv",(char *)"nres_powltr",(char *)"divisible",(char *)"remain", -(char *)"fmodulo",(char *)"nres_modadd",(char *)"nres_modsub",(char *)"nres_negate", -(char *)"ecurve_init",(char *)"ecurve_add",(char *)"ecurve_mult", -(char *)"epoint_init",(char *)"epoint_set",(char *)"epoint_get",(char *)"nres_powmod2", -(char *)"nres_sqroot",(char *)"sqroot",(char *)"nres_premult",(char *)"ecurve_mult2", -(char *)"ecurve_sub",(char *)"trial_division",(char *)"nxsafeprime",(char *)"nres_lucas",(char *)"lucas", -(char *)"brick_init",(char *)"pow_brick",(char *)"set_user_function", -(char *)"nres_powmodn",(char *)"powmodn",(char *)"ecurve_multn", -(char *)"ebrick_init",(char *)"mul_brick",(char *)"epoint_norm",(char *)"nres_multi_inverse",(char *)"", -(char *)"nres_dotprod",(char *)"epoint_negate",(char *)"ecurve_multi_add", -(char *)"ecurve2_init",(char *)"",(char *)"epoint2_set",(char *)"epoint2_norm",(char *)"epoint2_get", -(char *)"epoint2_comp",(char *)"ecurve2_add",(char *)"epoint2_negate",(char *)"ecurve2_sub", -(char *)"ecurve2_multi_add",(char *)"ecurve2_mult",(char *)"ecurve2_multn",(char *)"ecurve2_mult2", -(char *)"ebrick2_init",(char *)"mul2_brick",(char *)"prepare_basis",(char *)"strong_bigrand", -(char *)"bytes_to_big",(char *)"big_to_bytes",(char *)"set_io_buffer_size", -(char *)"epoint_getxyz",(char *)"epoint_double_add",(char *)"nres_double_inverse", -(char *)"double_inverse",(char *)"epoint_x",(char *)"hamming",(char *)"expb2",(char *)"bigbits", -(char *)"nres_lazy",(char *)"zzn2_imul",(char *)"nres_double_modadd",(char *)"nres_double_modsub", -/*155*/(char *)"",(char *)"zzn2_from_int",(char *)"zzn2_negate",(char *)"zzn2_conj",(char *)"zzn2_add", -(char *)"zzn2_sub",(char *)"zzn2_smul",(char *)"zzn2_mul",(char *)"zzn2_inv",(char *)"zzn2_timesi",(char *)"zzn2_powl", -(char *)"zzn2_from_bigs",(char *)"zzn2_from_big",(char *)"zzn2_from_ints", -(char *)"zzn2_sadd",(char *)"zzn2_ssub",(char *)"zzn2_times_irp",(char *)"zzn2_div2", -(char *)"zzn3_from_int",(char *)"zzn3_from_ints",(char *)"zzn3_from_bigs", -(char *)"zzn3_from_big",(char *)"zzn3_negate",(char *)"zzn3_powq",(char *)"zzn3_init", -(char *)"zzn3_add",(char *)"zzn3_sadd",(char *)"zzn3_sub",(char *)"zzn3_ssub",(char *)"zzn3_smul", -(char *)"zzn3_imul",(char *)"zzn3_mul",(char *)"zzn3_inv",(char *)"zzn3_div2",(char *)"zzn3_timesi", -(char *)"epoint_multi_norm",(char *)"mr_jsf",(char *)"epoint2_multi_norm", -(char *)"ecn2_compare",(char *)"ecn2_norm",(char *)"ecn2_set",(char *)"zzn2_txx", -(char *)"zzn2_txd",(char *)"nres_div2",(char *)"nres_div3",(char *)"zzn2_div3", -(char *)"ecn2_setx",(char *)"ecn2_rhs",(char *)"zzn2_qr",(char *)"zzn2_sqrt",(char *)"ecn2_add",(char *)"ecn2_mul2_jsf",(char *)"ecn2_mul", -(char *)"nres_div5",(char *)"zzn2_div5",(char *)"zzn2_sqr",(char *)"ecn2_add_sub",(char *)"ecn2_psi",(char *)"invmodp", -(char *)"zzn2_multi_inverse",(char *)"ecn2_multi_norm",(char *)"ecn2_precomp",(char *)"ecn2_mul4_gls_v", -(char *)"ecn2_mul2",(char *)"ecn2_precomp_gls",(char *)"ecn2_mul2_gls", -(char *)"ecn2_brick_init",(char *)"ecn2_mul_brick_gls",(char *)"ecn2_multn",(char *)"zzn3_timesi2", -(char *)"nres_complex",(char *)"zzn4_from_int",(char *)"zzn4_negate",(char *)"zzn4_conj",(char *)"zzn4_add",(char *)"zzn4_sadd",(char *)"zzn4_sub",(char *)"zzn4_ssub",(char *)"zzn4_smul",(char *)"zzn4_sqr", -(char *)"zzn4_mul",(char *)"zzn4_inv",(char *)"zzn4_div2",(char *)"zzn4_powq",(char *)"zzn4_tx",(char *)"zzn4_imul",(char *)"zzn4_lmul",(char *)"zzn4_from_big", -(char *)"ecn2_mult4"}; - -/* 0 - 243 (244 in all) */ - -#endif -#endif - -#ifdef MR_NOASM - -/* C only versions of muldiv/muldvd/muldvd2/muldvm */ -/* Note that mr_large should be twice the size of mr_small */ - -mr_small muldiv(mr_small a,mr_small b,mr_small c,mr_small m,mr_small *rp) -{ - mr_small q; - mr_large ldres,p=(mr_large)a*b+c; - q=(mr_small)(MR_LROUND(p/m)); - *rp=(mr_small)(p-(mr_large)q*m); - return q; -} - -#ifdef MR_FP_ROUNDING - -mr_small imuldiv(mr_small a,mr_small b,mr_small c,mr_small m,mr_large im,mr_small *rp) -{ - mr_small q; - mr_large ldres,p=(mr_large)a*b+c; - q=(mr_small)MR_LROUND(p*im); - *rp=(mr_small)(p-(mr_large)q*m); - return q; -} - -#endif - -#ifndef MR_NOFULLWIDTH - -mr_small muldvm(mr_small a,mr_small c,mr_small m,mr_small *rp) -{ - mr_small q; - union doubleword dble; - dble.h[MR_BOT]=c; - dble.h[MR_TOP]=a; - - q=(mr_small)(dble.d/m); - *rp=(mr_small)(dble.d-(mr_large)q*m); - return q; -} - -mr_small muldvd(mr_small a,mr_small b,mr_small c,mr_small *rp) -{ - union doubleword dble; - dble.d=(mr_large)a*b+c; - - *rp=dble.h[MR_BOT]; - return dble.h[MR_TOP]; -} - -void muldvd2(mr_small a,mr_small b,mr_small *c,mr_small *rp) -{ - union doubleword dble; - dble.d=(mr_large)a*b+*c+*rp; - *rp=dble.h[MR_BOT]; - *c=dble.h[MR_TOP]; -} - -#endif -#endif - -#ifdef MR_NOFULLWIDTH - -/* no FULLWIDTH working, so supply dummies */ - -/* - -mr_small muldvd(mr_small a,mr_small b,mr_small c,mr_small *rp) -{ - return (mr_small)0; -} - -mr_small muldvm(mr_small a,mr_small c,mr_small m,mr_small *rp) -{ - return (mr_small)0; -} - -void muldvd2(mr_small a,mr_small b,mr_small *c,mr_small *rp) -{ -} - -*/ - -#endif - -#ifndef MR_NO_STANDARD_IO - -static void mputs(char *s) -{ /* output a string */ - int i=0; - while (s[i]!=0) fputc((int)s[i++],stdout); -} -#endif - -void mr_berror(_MIPD_ int nerr) -{ /* Big number error routine */ -#ifndef MR_STRIPPED_DOWN -int i; -#endif - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - -if (mr_mip->ERCON) -{ - mr_mip->ERNUM=nerr; - return; -} -#ifndef MR_NO_STANDARD_IO - -#ifndef MR_STRIPPED_DOWN -mputs((char *)"\nMIRACL error from routine "); -if (mr_mip->depthtrace[mr_mip->depth]]); -else mputs((char *)"???"); -fputc('\n',stdout); - -for (i=mr_mip->depth-1;i>=0;i--) -{ - mputs((char *)" called from "); - if (itrace[i]]); - else mputs((char *)"???"); - fputc('\n',stdout); -} - -switch (nerr) -{ -case 1 : -mputs((char *)"Number base too big for representation\n"); -break; -case 2 : -mputs((char *)"Division by zero attempted\n"); -break; -case 3 : -mputs((char *)"Overflow - Number too big\n"); -break; -case 4 : -mputs((char *)"Internal result is negative\n"); -break; -case 5 : -mputs((char *)"Input format error\n"); -break; -case 6 : -mputs((char *)"Illegal number base\n"); -break; -case 7 : -mputs((char *)"Illegal parameter usage\n"); -break; -case 8 : -mputs((char *)"Out of space\n"); -break; -case 9 : -mputs((char *)"Even root of a negative number\n"); -break; -case 10: -mputs((char *)"Raising integer to negative power\n"); -break; -case 11: -mputs((char *)"Attempt to take illegal root\n"); -break; -case 12: -mputs((char *)"Integer operation attempted on Flash number\n"); -break; -case 13: -mputs((char *)"Flash overflow\n"); -break; -case 14: -mputs((char *)"Numbers too big\n"); -break; -case 15: -mputs((char *)"Log of a non-positive number\n"); -break; -case 16: -mputs((char *)"Flash to double conversion failure\n"); -break; -case 17: -mputs((char *)"I/O buffer overflow\n"); -break; -case 18: -mputs((char *)"MIRACL not initialised - no call to mirsys()\n"); -break; -case 19: -mputs((char *)"Illegal modulus \n"); -break; -case 20: -mputs((char *)"No modulus defined\n"); -break; -case 21: -mputs((char *)"Exponent too big\n"); -break; -case 22: -mputs((char *)"Unsupported Feature - check mirdef.h\n"); -break; -case 23: -mputs((char *)"Specified double length type isn't double length\n"); -break; -case 24: -mputs((char *)"Specified basis is NOT irreducible\n"); -break; -case 25: -mputs((char *)"Unable to control Floating-point rounding\n"); -break; -case 26: -mputs((char *)"Base must be binary (MR_ALWAYS_BINARY defined in mirdef.h ?)\n"); -break; -case 27: -mputs((char *)"No irreducible basis defined\n"); -break; -case 28: -mputs((char *)"Composite modulus\n"); -break; -case 29: -mputs((char *)"Input/output error when reading from RNG device node\n"); -break; -default: -mputs((char *)"Undefined error\n"); -break; -} -exit(0); -#else -mputs((char *)"MIRACL error\n"); -exit(0); -#endif - -#endif -} - -#ifndef MR_STRIPPED_DOWN - -void mr_track(_MIPDO_ ) -{ /* track course of program execution * - * through the MIRACL routines */ - -#ifndef MR_NO_STANDARD_IO - - int i; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - for (i=0;idepth;i++) fputc('-',stdout); - fputc('>',stdout); - mputs(names[mr_mip->trace[mr_mip->depth]]); - fputc('\n',stdout); -#endif -} - -#endif - -#ifndef MR_NO_RAND - -mr_small brand(_MIPDO_ ) -{ /* Marsaglia & Zaman random number generator */ - int i,k; - mr_unsign32 pdiff,t; - mr_small r; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->lg2b>32) - { /* underlying type is > 32 bits. Assume <= 64 bits */ - mr_mip->rndptr+=2; - if (mr_mip->rndptrira[mr_mip->rndptr]; - r=mr_shiftbits(r,mr_mip->lg2b-32); - r+=(mr_small)mr_mip->ira[mr_mip->rndptr+1]; - return r; - } - } - else - { - mr_mip->rndptr++; - if (mr_mip->rndptrira[mr_mip->rndptr]; - } - mr_mip->rndptr=0; - for (i=0,k=NK-NJ;iira[k]; - pdiff=t - mr_mip->ira[i] - mr_mip->borrow; - if (pdiffborrow=0; - if (pdiff>t) mr_mip->borrow=1; - mr_mip->ira[i]=pdiff; - } - if (mr_mip->lg2b>32) - { /* double up */ - r=(mr_small)mr_mip->ira[0]; - r=mr_shiftbits(r,mr_mip->lg2b-32); - r+=(mr_small)mr_mip->ira[1]; - return r; - } - else return (mr_small)(mr_mip->ira[0]); -} - -void irand(_MIPD_ mr_unsign32 seed) -{ /* initialise random number system */ - int i,in; - mr_unsign32 t,m=1L; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - mr_mip->borrow=0L; - mr_mip->rndptr=0; - mr_mip->ira[0]=seed; - for (i=1;iira[in]=m; - t=m; - m=seed-m; - seed=t; - } - for (i=0;i<1000;i++) brand(_MIPPO_ ); /* "warm-up" & stir the generator */ -} - -#endif - -mr_small mr_shiftbits(mr_small x,int n) -{ -#ifdef MR_FP - int i; - mr_small dres; - if (n==0) return x; - if (n>0) - { - for (i=0;i0) x<<=n; - else x>>=(-n); - return x; -#endif - -} - -mr_small mr_setbase(_MIPD_ mr_small nb) -{ /* set base. Pack as many digits as * - * possible into each computer word */ - mr_small temp; -#ifdef MR_FP - mr_small dres; -#endif -#ifndef MR_NOFULLWIDTH - BOOL fits; - int bits; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - fits=FALSE; - bits=MIRACL; - while (bits>1) - { - bits/=2; - temp=((mr_small)1<apbase=nb; - mr_mip->pack=MIRACL/bits; - mr_mip->base=0; - return 0; - } -#endif - mr_mip->apbase=nb; - mr_mip->pack=1; - mr_mip->base=nb; -#ifdef MR_SIMPLE_BASE - return 0; -#else - if (mr_mip->base==0) return 0; - temp=MR_DIV(MAXBASE,nb); - while (temp>=nb) - { - temp=MR_DIV(temp,nb); - mr_mip->base*=nb; - mr_mip->pack++; - } -#ifdef MR_FP_ROUNDING - mr_mip->inverse_base=mr_invert(mr_mip->base); - return mr_mip->inverse_base; -#else - return 0; -#endif -#endif -} - -#ifdef MR_FLASH - -BOOL fit(big x,big y,int f) -{ /* returns TRUE if x/y would fit flash format of length f */ - int n,d; - n=(int)(x->len&(MR_OBITS)); - d=(int)(y->len&(MR_OBITS)); - if (n==1 && x->w[0]==1) n=0; - if (d==1 && y->w[0]==1) d=0; - if (n+d<=f) return TRUE; - return FALSE; -} - -#endif - -int mr_lent(flash x) -{ /* return length of big or flash in words */ - mr_lentype lx; - lx=(x->len&(MR_OBITS)); -#ifdef MR_FLASH - return (int)((lx&(MR_MSK))+((lx>>(MR_BTS))&(MR_MSK))); -#else - return (int)lx; -#endif -} - -void zero(flash x) -{ /* set big/flash number to zero */ - int i,n; - mr_small *g; - if (x==NULL) return; -#ifdef MR_FLASH - n=mr_lent(x); -#else - n=(x->len&MR_OBITS); -#endif - g=x->w; - - for (i=0;ilen=0; -} - -void uconvert(_MIPD_ unsigned int n ,big x) -{ /* convert unsigned integer n to big number format */ - int m; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - zero(x); - if (n==0) return; - - m=0; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH -#if MR_IBITS > MIRACL - while (n>0) - { - x->w[m++]=(mr_small)(n%((mr_small)1<<(MIRACL))); - n/=((mr_small)1<<(MIRACL)); - } -#else - x->w[m++]=(mr_small)n; -#endif -#endif -#ifndef MR_SIMPLE_BASE - } - else while (n>0) - { - x->w[m++]=MR_REMAIN((mr_small)n,mr_mip->base); - n=(unsigned int)((mr_small)n/mr_mip->base); - } -#endif - x->len=m; -} - -void tconvert(_MIPD_ mr_utype n,big x) -{ - mr_lentype s; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (n==0) {zero(x); return;} - s=0; - if (n<0) - { - s=MR_MSBIT; - n=(-n); - } - x->w[0]=n; - x->len=1; - x->len|=s; -} - -void convert(_MIPD_ int n ,big x) -{ /* convert signed integer n to big number format */ - mr_lentype s; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (n==0) {zero(x); return;} - s=0; - if (n<0) - { - s=MR_MSBIT; - n=(-n); - } - uconvert(_MIPP_ (unsigned int)n,x); - x->len|=s; -} - -#ifndef MR_STATIC -#ifdef mr_dltype - -void dlconv(_MIPD_ mr_dltype n,big x) -{ /* convert double length integer to big number format - rarely needed */ - int m; - mr_lentype s; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - zero(x); - if (n==0) return; - s=0; - if (n<0) - { - s=MR_MSBIT; - n=(-n); - } - m=0; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - while (n>0) - { - x->w[m++]=(mr_small)(n%((mr_dltype)1<<(MIRACL))); - n/=((mr_dltype)1<<(MIRACL)); - } -#endif -#ifndef MR_SIMPLE_BASE - } - else while (n>0) - { - x->w[m++]=(mr_small)MR_REMAIN(n,mr_mip->base); - n/=mr_mip->base; - } -#endif - x->len=(m|s); -} - -#endif - -void ulgconv(_MIPD_ unsigned long n,big x) -{ /* convert unsigned long integer to big number format - rarely needed */ - int m; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - zero(x); - if (n==0) return; - - m=0; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH -#if MR_LBITS > MIRACL - while (n>0) - { - x->w[m++]=(mr_small)(n%(1L<<(MIRACL))); - n/=(1L<<(MIRACL)); - } -#else - x->w[m++]=(mr_small)n; -#endif -#endif -#ifndef MR_SIMPLE_BASE - } - else while (n>0) - { - x->w[m++]=MR_REMAIN(n,mr_mip->base); - n=(unsigned long)((mr_small)n/mr_mip->base); - } -#endif - x->len=m; -} - -void lgconv(_MIPD_ long n,big x) -{ /* convert signed long integer to big number format - rarely needed */ - mr_lentype s; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (n==0) {zero(x); return;} - s=0; - if (n<0) - { - s=MR_MSBIT; - n=(-n); - } - ulgconv(_MIPP_ (unsigned long)n,x); - - x->len|=s; -} - -flash mirvar(_MIPD_ int iv) -{ /* initialize big/flash number */ - flash x; - int align; - char *ptr; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip->ERNUM) return NULL; - MR_IN(23); - - if (!(mr_mip->active)) - { - mr_berror(_MIPP_ MR_ERR_NO_MIRSYS); - MR_OUT - return NULL; - } - -/* OK, now I control alignment.... */ - -/* Allocate space for big, the length, the pointer, and the array */ -/* Do it all in one memory allocation - this is quicker */ -/* Ensure that the array has correct alignment */ - - x=(big)mr_alloc(_MIPP_ mr_size(mr_mip->nib-1),1); - if (x==NULL) - { - MR_OUT - return x; - } - - ptr=(char *)&x->w; - align=(unsigned long)(ptr+sizeof(mr_small *))%sizeof(mr_small); - - x->w=(mr_small *)(ptr+sizeof(mr_small *)+sizeof(mr_small)-align); - - if (iv!=0) convert(_MIPP_ iv,x); - MR_OUT - return x; -} - -#endif - -flash mirvar_mem_variable(char *mem,int index,int sz) -{ - flash x; - int align; - char *ptr; - int offset,r; - -/* alignment */ - offset=0; - r=(unsigned long)mem%MR_SL; - if (r>0) offset=MR_SL-r; - - x=(big)&mem[offset+mr_size(sz)*index]; - ptr=(char *)&x->w; - align=(unsigned long)(ptr+sizeof(mr_small *))%sizeof(mr_small); - x->w=(mr_small *)(ptr+sizeof(mr_small *)+sizeof(mr_small)-align); - - return x; -} - -flash mirvar_mem(_MIPD_ char *mem,int index) -{ /* initialize big/flash number from pre-allocated memory */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip->ERNUM) return NULL; - - return mirvar_mem_variable(mem,index,mr_mip->nib-1); - -} - -void set_user_function(_MIPD_ BOOL (*user)(void)) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(111) - - if (!(mr_mip->active)) - { - mr_berror(_MIPP_ MR_ERR_NO_MIRSYS); - MR_OUT - return; - } - - mr_mip->user=user; - - MR_OUT -} - -#ifndef MR_STATIC - -#ifndef MR_SIMPLE_IO - -void set_io_buffer_size(_MIPD_ int len) -{ - int i; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (len<0) return; - MR_IN(142) - for (i=0;iIOBSIZ;i++) mr_mip->IOBUFF[i]=0; - mr_free(mr_mip->IOBUFF); - if (len==0) - { - MR_OUT - return; - } - mr_mip->IOBSIZ=len; - mr_mip->IOBUFF=(char *)mr_alloc(_MIPP_ len+1,1); - mr_mip->IOBUFF[0]='\0'; - MR_OUT -} -#endif - -#endif - -/* Initialise a big from ROM given its fixed length */ - -BOOL init_big_from_rom(big x,int len,const mr_small *rom,int romsize,int *romptr) -{ - int i; - zero(x); - x->len=len; - for (i=0;i=romsize) return FALSE; -#ifdef MR_AVR - x->w[i]=pgm_read_byte_near(&rom[*romptr]); -#else - x->w[i]=rom[*romptr]; -#endif - (*romptr)++; - } - - mr_lzero(x); - return TRUE; -} - -/* Initialise an elliptic curve point from ROM */ - -BOOL init_point_from_rom(epoint *P,int len,const mr_small *rom,int romsize,int *romptr) -{ - if (!init_big_from_rom(P->X,len,rom,romsize,romptr)) return FALSE; - if (!init_big_from_rom(P->Y,len,rom,romsize,romptr)) return FALSE; - P->marker=MR_EPOINT_NORMALIZED; - return TRUE; -} - -#ifdef MR_GENERIC_AND_STATIC -miracl *mirsys(miracl *mr_mip,int nd,mr_small nb) -#else -miracl *mirsys(int nd,mr_small nb) -#endif -{ /* Initialize MIRACL system to * - * use numbers to base nb, and * - * nd digits or (-nd) bytes long */ - -/* In these cases mr_mip is passed as the first parameter */ - -#ifdef MR_GENERIC_AND_STATIC - return mirsys_basic(mr_mip,nd,nb); -#endif - -#ifdef MR_GENERIC_MT -#ifndef MR_STATIC - miracl *mr_mip=mr_first_alloc(); - return mirsys_basic(mr_mip,nd,nb); -#endif -#endif -/* In these cases mr_mip is a "global" pointer and the mip itself is allocated from the heap. - In fact mr_mip (and mip) may be thread specific if some multi-threading scheme is implemented */ -#ifndef MR_STATIC - #ifdef MR_WINDOWS_MT - miracl *mr_mip=mr_first_alloc(); - TlsSetValue(mr_key,mr_mip); - #endif - - #ifdef MR_UNIX_MT - miracl *mr_mip=mr_first_alloc(); - pthread_setspecific(mr_key,mr_mip); - #endif - - #ifdef MR_OPENMP_MT - mr_mip=mr_first_alloc(); - #endif - - #ifndef MR_WINDOWS_MT - #ifndef MR_UNIX_MT - #ifndef MR_OPENMP_MT - mr_mip=mr_first_alloc(); - #endif - #endif - #endif -#endif - -#ifndef MR_GENERIC_MT - mr_mip=get_mip(); -#endif - return mirsys_basic(mr_mip,nd,nb); -} - -miracl *mirsys_basic(miracl *mr_mip,int nd,mr_small nb) -{ -#ifndef MR_NO_RAND - int i; -#endif - - mr_small b,nw; -#ifdef MR_FP - mr_small dres; -#endif - - if (mr_mip==NULL) return NULL; - -#ifndef MR_STRIPPED_DOWN - mr_mip->depth=0; - mr_mip->trace[0]=0; - mr_mip->depth++; - mr_mip->trace[mr_mip->depth]=29; -#endif - /* digest hardware configuration */ - -#ifdef MR_NO_STANDARD_IO - mr_mip->ERCON=TRUE; -#else - mr_mip->ERCON=FALSE; -#endif -#ifndef MR_STATIC - mr_mip->logN=0; - mr_mip->degree=0; - mr_mip->chin.NP=0; -#endif - - - mr_mip->user=NULL; - mr_mip->same=FALSE; - mr_mip->first_one=FALSE; - mr_mip->debug=FALSE; - mr_mip->AA=0; -#ifndef MR_AFFINE_ONLY - mr_mip->coord=MR_NOTSET; -#endif - -#ifdef MR_NOFULLWIDTH - if (nb==0) - { - mr_berror(_MIPP_ MR_ERR_BAD_BASE); - MR_OUT - return mr_mip; - } -#endif - -#ifndef MR_FP -#ifdef mr_dltype -#ifndef MR_NOFULLWIDTH - if (sizeof(mr_dltype)<2*sizeof(mr_utype)) - { /* double length type, isn't */ - mr_berror(_MIPP_ MR_ERR_NOT_DOUBLE_LEN); - MR_OUT - return mr_mip; - } -#endif -#endif -#endif - - if (nb==1 || nb>MAXBASE) - { - mr_berror(_MIPP_ MR_ERR_BAD_BASE); - MR_OUT - return mr_mip; - } - -#ifdef MR_FP_ROUNDING - if (mr_setbase(_MIPP_ nb)==0) - { /* unable in fact to control FP rounding */ - mr_berror(_MIPP_ MR_ERR_NO_ROUNDING); - MR_OUT - return mr_mip; - } -#else - mr_setbase(_MIPP_ nb); -#endif - - b=mr_mip->base; - -#ifdef MR_SIMPLE_BASE - if (b!=0) - { - mr_berror(_MIPP_ MR_ERR_BAD_BASE); - MR_OUT - return mr_mip; - } -#endif - - mr_mip->lg2b=0; - mr_mip->base2=1; -#ifndef MR_SIMPLE_BASE - if (b==0) - { -#endif - mr_mip->lg2b=MIRACL; - mr_mip->base2=0; -#ifndef MR_SIMPLE_BASE - } - else while (b>1) - { - b=MR_DIV(b,2); - mr_mip->lg2b++; - mr_mip->base2*=2; - } -#endif - -#ifdef MR_ALWAYS_BINARY - if (mr_mip->base!=mr_mip->base2) - { - mr_berror(_MIPP_ MR_ERR_NOT_BINARY); - MR_OUT - return mr_mip; - } -#endif - -/* calculate total space for bigs */ -/* - - big -> |int len|small *ptr| alignment space | size in words +1| alignment up to multiple of 4 | - - -*/ - if (nd>0) nw=MR_ROUNDUP(nd,mr_mip->pack); - else nw=MR_ROUNDUP(8*(-nd),mr_mip->lg2b); - - if (nw<1) nw=1; - mr_mip->nib=(int)(nw+1); /* add one extra word for small overflows */ - -#ifdef MR_STATIC - if (nw>MR_STATIC) - { - mr_berror(_MIPP_ MR_ERR_TOO_BIG); - MR_OUT - return mr_mip; - } -#endif - - /* mr_mip->nib=(int)(nw+1); add one extra word for small overflows */ - -#ifdef MR_FLASH - mr_mip->workprec=mr_mip->nib; - mr_mip->stprec=mr_mip->nib; - while (mr_mip->stprec>2 && mr_mip->stprec>MR_FLASH/mr_mip->lg2b) - mr_mip->stprec=(mr_mip->stprec+1)/2; - if (mr_mip->stprec<2) mr_mip->stprec=2; - -#endif - -#ifndef MR_DOUBLE_BIG - mr_mip->check=ON; -#else - mr_mip->check=OFF; -#endif - -#ifndef MR_SIMPLE_BASE -#ifndef MR_SIMPLE_IO - mr_mip->IOBASE=10; /* defaults */ -#endif -#endif - mr_mip->ERNUM=0; - - mr_mip->NTRY=6; - mr_mip->MONTY=ON; -#ifdef MR_FLASH - mr_mip->EXACT=TRUE; - mr_mip->RPOINT=OFF; -#endif -#ifndef MR_STRIPPED_DOWN - mr_mip->TRACER=OFF; -#endif - -#ifndef MR_SIMPLE_IO - mr_mip->INPLEN=0; - mr_mip->IOBSIZ=MR_DEFAULT_BUFFER_SIZE; -#endif - -#ifdef MR_STATIC - mr_mip->PRIMES=mr_small_primes; -#else - mr_mip->PRIMES=NULL; -#ifndef MR_SIMPLE_IO - mr_mip->IOBUFF=(char *)mr_alloc(_MIPP_ MR_DEFAULT_BUFFER_SIZE+1,1); -#endif -#endif -#ifndef MR_SIMPLE_IO - mr_mip->IOBUFF[0]='\0'; -#endif - mr_mip->qnr=0; - mr_mip->cnr=0; - mr_mip->TWIST=0; - mr_mip->pmod8=0; - mr_mip->pmod9=0; - -/* quick start for rng. irand(.) should be called first before serious use.. */ - -#ifndef MR_NO_RAND - mr_mip->ira[0]=0x55555555; - mr_mip->ira[1]=0x12345678; - - for (i=2;iira[i]=mr_mip->ira[i-1]+mr_mip->ira[i-2]+0x1379BDF1; - mr_mip->rndptr=NK; - mr_mip->borrow=0; -#endif - - mr_mip->nib=2*mr_mip->nib+1; -#ifdef MR_FLASH - if (mr_mip->nib!=(mr_mip->nib&(MR_MSK))) -#else - if (mr_mip->nib!=(int)(mr_mip->nib&(MR_OBITS))) -#endif - { - mr_berror(_MIPP_ MR_ERR_TOO_BIG); - mr_mip->nib=(mr_mip->nib-1)/2; - MR_OUT - return mr_mip; - } -#ifndef MR_STATIC - mr_mip->workspace=(char *)memalloc(_MIPP_ MR_SPACES); /* grab workspace */ -#else - memset(mr_mip->workspace,0,MR_BIG_RESERVE(MR_SPACES)); -#endif - - mr_mip->M=0; - mr_mip->fin=FALSE; - mr_mip->fout=FALSE; - mr_mip->active=ON; - - mr_mip->nib=(mr_mip->nib-1)/2; - -/* allocate memory for workspace variables */ - -#ifndef MR_DOUBLE_BIG - - mr_mip->w0=mirvar_mem(_MIPP_ mr_mip->workspace,0); /* double length */ - mr_mip->w1=mirvar_mem(_MIPP_ mr_mip->workspace,2); - mr_mip->w2=mirvar_mem(_MIPP_ mr_mip->workspace,3); - mr_mip->w3=mirvar_mem(_MIPP_ mr_mip->workspace,4); - mr_mip->w4=mirvar_mem(_MIPP_ mr_mip->workspace,5); - mr_mip->w5=mirvar_mem(_MIPP_ mr_mip->workspace,6); /* double length */ - mr_mip->w6=mirvar_mem(_MIPP_ mr_mip->workspace,8); /* double length */ - mr_mip->w7=mirvar_mem(_MIPP_ mr_mip->workspace,10); /* double length */ - mr_mip->w8=mirvar_mem(_MIPP_ mr_mip->workspace,12); - mr_mip->w9=mirvar_mem(_MIPP_ mr_mip->workspace,13); - mr_mip->w10=mirvar_mem(_MIPP_ mr_mip->workspace,14); - mr_mip->w11=mirvar_mem(_MIPP_ mr_mip->workspace,15); - mr_mip->w12=mirvar_mem(_MIPP_ mr_mip->workspace,16); - mr_mip->w13=mirvar_mem(_MIPP_ mr_mip->workspace,17); - mr_mip->w14=mirvar_mem(_MIPP_ mr_mip->workspace,18); - mr_mip->w15=mirvar_mem(_MIPP_ mr_mip->workspace,19); - mr_mip->sru=mirvar_mem(_MIPP_ mr_mip->workspace,20); - mr_mip->modulus=mirvar_mem(_MIPP_ mr_mip->workspace,21); - mr_mip->pR=mirvar_mem(_MIPP_ mr_mip->workspace,22); /* double length */ - mr_mip->A=mirvar_mem(_MIPP_ mr_mip->workspace,24); - mr_mip->B=mirvar_mem(_MIPP_ mr_mip->workspace,25); - mr_mip->one=mirvar_mem(_MIPP_ mr_mip->workspace,26); -#ifdef MR_KCM - mr_mip->big_ndash=mirvar_mem(_MIPP_ mr_mip->workspace,27); - mr_mip->ws=mirvar_mem(_MIPP_ mr_mip->workspace,28); - mr_mip->wt=mirvar_mem(_MIPP_ mr_mip->workspace,29); /* double length */ -#endif -#ifdef MR_FLASH -#ifdef MR_KCM - mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,31); -#else - mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,27); -#endif -#endif - -#else -/* w0-w7 are double normal length */ - mr_mip->w0=mirvar_mem(_MIPP_ mr_mip->workspace,0); /* quad length */ - mr_mip->w1=mirvar_mem(_MIPP_ mr_mip->workspace,4); /* double length */ - mr_mip->w2=mirvar_mem(_MIPP_ mr_mip->workspace,6); - mr_mip->w3=mirvar_mem(_MIPP_ mr_mip->workspace,8); - mr_mip->w4=mirvar_mem(_MIPP_ mr_mip->workspace,10); - mr_mip->w5=mirvar_mem(_MIPP_ mr_mip->workspace,12); /* quad length */ - mr_mip->w6=mirvar_mem(_MIPP_ mr_mip->workspace,16); /* quad length */ - mr_mip->w7=mirvar_mem(_MIPP_ mr_mip->workspace,20); /* quad length */ - mr_mip->w8=mirvar_mem(_MIPP_ mr_mip->workspace,24); - - mr_mip->w9=mirvar_mem(_MIPP_ mr_mip->workspace,25); - mr_mip->w10=mirvar_mem(_MIPP_ mr_mip->workspace,26); - mr_mip->w11=mirvar_mem(_MIPP_ mr_mip->workspace,27); - mr_mip->w12=mirvar_mem(_MIPP_ mr_mip->workspace,28); - mr_mip->w13=mirvar_mem(_MIPP_ mr_mip->workspace,29); - mr_mip->w14=mirvar_mem(_MIPP_ mr_mip->workspace,30); - mr_mip->w15=mirvar_mem(_MIPP_ mr_mip->workspace,31); - mr_mip->sru=mirvar_mem(_MIPP_ mr_mip->workspace,32); - mr_mip->modulus=mirvar_mem(_MIPP_ mr_mip->workspace,33); - mr_mip->pR=mirvar_mem(_MIPP_ mr_mip->workspace,34); /* double length */ - mr_mip->A=mirvar_mem(_MIPP_ mr_mip->workspace,36); - mr_mip->B=mirvar_mem(_MIPP_ mr_mip->workspace,37); - mr_mip->one=mirvar_mem(_MIPP_ mr_mip->workspace,38); -#ifdef MR_KCM - mr_mip->big_ndash=mirvar_mem(_MIPP_ mr_mip->workspace,39); - mr_mip->ws=mirvar_mem(_MIPP_ mr_mip->workspace,40); - mr_mip->wt=mirvar_mem(_MIPP_ mr_mip->workspace,41); /* double length */ -#endif -#ifdef MR_FLASH -#ifdef MR_KCM - mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,43); -#else - mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,39); -#endif -#endif - -#endif - MR_OUT - return mr_mip; -} - -#ifndef MR_STATIC - -/* allocate space for a number of bigs from the heap */ - -void *memalloc(_MIPD_ int num) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - return mr_alloc(_MIPP_ mr_big_reserve(num,mr_mip->nib-1),1); -} - -#endif - -void memkill(_MIPD_ char *mem,int len) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mem==NULL) return; - memset(mem,0,mr_big_reserve(len,mr_mip->nib-1)); -#ifndef MR_STATIC - mr_free(mem); -#endif -} - -#ifndef MR_STATIC - -void mirkill(big x) -{ /* kill a big/flash variable, that is set it to zero - and free its memory */ - if (x==NULL) return; - zero(x); - mr_free(x); -} - -#endif - -void mirexit(_MIPDO_ ) -{ /* clean up after miracl */ - - int i; -#ifdef MR_WINDOWS_MT - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_UNIX_MT - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_OPENMP_MT - miracl *mr_mip=get_mip(); -#endif - mr_mip->ERCON=FALSE; - mr_mip->active=OFF; - memkill(_MIPP_ mr_mip->workspace,MR_SPACES); -#ifndef MR_NO_RAND - for (i=0;iira[i]=0L; -#endif -#ifndef MR_STATIC -#ifndef MR_SIMPLE_IO - set_io_buffer_size(_MIPP_ 0); -#endif - if (mr_mip->PRIMES!=NULL) mr_free(mr_mip->PRIMES); -#else -#ifndef MR_SIMPLE_IO - for (i=0;i<=MR_DEFAULT_BUFFER_SIZE;i++) - mr_mip->IOBUFF[i]=0; -#endif -#endif - -#ifndef MR_STATIC - mr_free(mr_mip); -#ifdef MR_WINDOWS_MT - TlsSetValue(mr_key, NULL); /* Thank you Thales */ -#endif -#endif - -#ifndef MR_GENERIC_MT -#ifndef MR_WINDOWS_MT -#ifndef MR_UNIX_MT -#ifndef MR_STATIC - mr_mip=NULL; -#endif -#endif -#endif -#endif - -#ifdef MR_OPENMP_MT - mr_mip=NULL; -#endif - -} - -int exsign(flash x) -{ /* extract sign of big/flash number */ - if ((x->len&(MR_MSBIT))==0) return PLUS; - else return MINUS; -} - -void insign(int s,flash x) -{ /* assert sign of big/flash number */ - if (x->len==0) return; - if (s<0) x->len|=MR_MSBIT; - else x->len&=MR_OBITS; -} - -void mr_lzero(big x) -{ /* strip leading zeros from big number */ - mr_lentype s; - int m; - s=(x->len&(MR_MSBIT)); - m=(int)(x->len&(MR_OBITS)); - while (m>0 && x->w[m-1]==0) - m--; - x->len=m; - if (m>0) x->len|=s; -} - -#ifndef MR_SIMPLE_IO - -int getdig(_MIPD_ big x,int i) -{ /* extract a packed digit */ - int k; - mr_small n; -#ifdef MR_FP - mr_small dres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - i--; - n=x->w[i/mr_mip->pack]; - - if (mr_mip->pack==1) return (int)n; - k=i%mr_mip->pack; - for (i=1;i<=k;i++) - n=MR_DIV(n,mr_mip->apbase); - return (int)MR_REMAIN(n,mr_mip->apbase); -} - -int numdig(_MIPD_ big x) -{ /* returns number of digits in x */ - int nd; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (x->len==0) return 0; - - nd=(int)(x->len&(MR_OBITS))*mr_mip->pack; - while (getdig(_MIPP_ x,nd)==0) - nd--; - return nd; -} - -void putdig(_MIPD_ int n,big x,int i) -{ /* insert a digit into a packed word */ - int j,k,lx; - mr_small m,p; - mr_lentype s; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(26) - - s=(x->len&(MR_MSBIT)); - lx=(int)(x->len&(MR_OBITS)); - m=getdig(_MIPP_ x,i); - p=n; - i--; - j=i/mr_mip->pack; - k=i%mr_mip->pack; - for (i=1;i<=k;i++) - { - m*=mr_mip->apbase; - p*=mr_mip->apbase; - } - if (j>=mr_mip->nib && (mr_mip->check || j>=2*mr_mip->nib)) - { - mr_berror(_MIPP_ MR_ERR_OVERFLOW); - MR_OUT - return; - } - - x->w[j]=(x->w[j]-m)+p; - if (j>=lx) x->len=((j+1)|s); - mr_lzero(x); - MR_OUT -} - -#endif - -#ifndef MR_FP - -void mr_and(big x,big y,big z) -{ /* z= bitwise logical AND of x and y */ - int i,nx,ny,nz,nr; - if (x==y) - { - copy(x,z); - return; - } - -#ifdef MR_FLASH - nx=mr_lent(x); - ny=mr_lent(y); - nz=mr_lent(z); -#else - ny=(y->len&(MR_OBITS)); - nx=(x->len&(MR_OBITS)); - nz=(z->len&(MR_OBITS)); -#endif - if (nyw[i]=x->w[i]&y->w[i]; - for (i=nr;iw[i]=0; - z->len=nr; -} - -void mr_xor(big x,big y,big z) -{ - int i,nx,ny,nz,nr; - if (x==y) - { - copy(x,z); - return; - } - -#ifdef MR_FLASH - nx=mr_lent(x); - ny=mr_lent(y); - nz=mr_lent(z); -#else - ny=(y->len&(MR_OBITS)); - nx=(x->len&(MR_OBITS)); - nz=(z->len&(MR_OBITS)); -#endif - if (nyw[i]=x->w[i]^y->w[i]; - for (i=nr;iw[i]=0; - z->len=nr; -} - -#endif - -void copy(flash x,flash y) -{ /* copy x to y: y=x */ - int i,nx,ny; - mr_small *gx,*gy; - if (x==y || y==NULL) return; - - if (x==NULL) - { - zero(y); - return; - } - -#ifdef MR_FLASH - ny=mr_lent(y); - nx=mr_lent(x); -#else - ny=(y->len&(MR_OBITS)); - nx=(x->len&(MR_OBITS)); -#endif - - gx=x->w; - gy=y->w; - - for (i=nx;ilen=x->len; - -} - -void negify(flash x,flash y) -{ /* negate a big/flash variable: y=-x */ - copy(x,y); - if (y->len!=0) y->len^=MR_MSBIT; -} - -void absol(flash x,flash y) -{ /* y=abs(x) */ - copy(x,y); - y->len&=MR_OBITS; -} - -BOOL mr_notint(flash x) -{ /* returns TRUE if x is Flash */ -#ifdef MR_FLASH - if ((((x->len&(MR_OBITS))>>(MR_BTS))&(MR_MSK))!=0) return TRUE; -#endif - return FALSE; -} - -void mr_shift(_MIPD_ big x,int n,big w) -{ /* set w=x.(mr_base^n) by shifting */ - mr_lentype s; - int i,bl; - mr_small *gw=w->w; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - copy(x,w); - if (w->len==0 || n==0) return; - MR_IN(33) - - if (mr_notint(w)) mr_berror(_MIPP_ MR_ERR_INT_OP); - s=(w->len&(MR_MSBIT)); - bl=(int)(w->len&(MR_OBITS))+n; - if (bl<=0) - { - zero(w); - MR_OUT - return; - } - if (bl>mr_mip->nib && mr_mip->check) mr_berror(_MIPP_ MR_ERR_OVERFLOW); - if (mr_mip->ERNUM) - { - MR_OUT - return; - } - if (n>0) - { - for (i=bl-1;i>=n;i--) - gw[i]=gw[i-n]; - for (i=0;ilen=(bl|s); - MR_OUT -} - -int size(big x) -{ /* get size of big number; convert to * - * integer - if possible */ - int n,m; - mr_lentype s; - if (x==NULL) return 0; - s=(x->len&MR_MSBIT); - m=(int)(x->len&MR_OBITS); - if (m==0) return 0; - if (m==1 && x->w[0]<(mr_small)MR_TOOBIG) n=(int)x->w[0]; - else n=MR_TOOBIG; - if (s==MR_MSBIT) return (-n); - return n; -} - -int mr_compare(big x,big y) -{ /* compare x and y: =1 if x>y =-1 if xlen&MR_MSBIT); - sy=(y->len&MR_MSBIT); - if (sx==0) sig=PLUS; - else sig=MINUS; - if (sx!=sy) return sig; - m=(int)(x->len&MR_OBITS); - n=(int)(y->len&MR_OBITS); - if (m>n) return sig; - if (m0) - { /* check digit by digit */ - m--; - if (x->w[m]>y->w[m]) return sig; - if (x->w[m]w[m]) return -sig; - } - return 0; -} - -#ifdef MR_FLASH - -void fpack(_MIPD_ big n,big d,flash x) -{ /* create floating-slash number x=n/d from * - * big integer numerator and denominator */ - mr_lentype s; - int i,ld,ln; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(31) - - ld=(int)(d->len&MR_OBITS); - if (ld==0) mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW); - if (ld==1 && d->w[0]==1) ld=0; - if (x==d) mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - if (mr_notint(n) || mr_notint(d)) mr_berror(_MIPP_ MR_ERR_INT_OP); - s=(n->len&MR_MSBIT); - ln=(int)(n->len&MR_OBITS); - if (ln==1 && n->w[0]==1) ln=0; - if ((ld+ln>mr_mip->nib) && (mr_mip->check || ld+ln>2*mr_mip->nib)) - mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW); - if (mr_mip->ERNUM) - { - MR_OUT - return; - } - copy(n,x); - if (n->len==0) - { - MR_OUT - return; - } - s^=(d->len&MR_MSBIT); - if (ld==0) - { - if (x->len!=0) x->len|=s; - MR_OUT - return; - } - for (i=0;iw[ln+i]=d->w[i]; - x->len=(s|(ln+((mr_lentype)ld<ERNUM) return; - if (mr_notint(x)) - { - s=(x->len&MR_MSBIT); - ly=(x->len&MR_OBITS); - ln=(int)(ly&MR_MSK); - if (ln==0) - { - if(s==MR_MSBIT) convert(_MIPP_ (-1),y); - else convert(_MIPP_ 1,y); - return; - } - ld=(int)((ly>>MR_BTS)&MR_MSK); - if (x!=y) - { - for (i=0;iw[i]=x->w[i]; - for (i=ln;iw[i]=0; - } - else for (i=0;iw[ln+i]=0; - y->len=(ln|s); - } - else copy(x,y); -} - -void denom(_MIPD_ flash x,big y) -{ /* extract denominator of x */ - int i,ln,ld; - mr_lentype ly; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - if (!mr_notint(x)) - { - convert(_MIPP_ 1,y); - return; - } - ly=(x->len&MR_OBITS); - ln=(int)(ly&MR_MSK); - ld=(int)((ly>>MR_BTS)&MR_MSK); - for (i=0;iw[i]=x->w[ln+i]; - if (x==y) for (i=0;iw[ld+i]=0; - else for (i=ld;iw[i]=0; - y->len=ld; -} - -#endif - -unsigned int igcd(unsigned int x,unsigned int y) -{ /* integer GCD, returns GCD of x and y */ - unsigned int r; - if (y==0) return x; - while ((r=x%y)!=0) - x=y,y=r; - return y; -} - -unsigned long lgcd(unsigned long x,unsigned long y) -{ /* long GCD, returns GCD of x and y */ - unsigned long r; - if (y==0) return x; - while ((r=x%y)!=0) - x=y,y=r; - return y; -} - -unsigned int isqrt(unsigned int num,unsigned int guess) -{ /* square root of an integer */ - unsigned int sqr; - unsigned int oldguess=guess; - if (num==0) return 0; - if (num<4) return 1; - - for (;;) - { /* Newtons iteration */ - /* sqr=guess+(((num/guess)-guess)/2); */ - sqr=((num/guess)+guess)/2; - if (sqr==guess || sqr==oldguess) - { - if (sqr*sqr>num) sqr--; - return sqr; - } - oldguess=guess; - guess=sqr; - } -} - -unsigned long mr_lsqrt(unsigned long num,unsigned long guess) -{ /* square root of a long */ - unsigned long sqr; - unsigned long oldguess=guess; - if (num==0) return 0; - if (num<4) return 1; - - for (;;) - { /* Newtons iteration */ - /* sqr=guess+(((num/guess)-guess)/2); */ - sqr=((num/guess)+guess)/2; - if (sqr==guess || sqr==oldguess) - { - if (sqr*sqr>num) sqr--; - return sqr; - } - oldguess=guess; - guess=sqr; - } -} - -mr_small sgcd(mr_small x,mr_small y) -{ /* integer GCD, returns GCD of x and y */ - mr_small r; -#ifdef MR_FP - mr_small dres; -#endif - if (y==(mr_small)0) return x; - while ((r=MR_REMAIN(x,y))!=(mr_small)0) - x=y,y=r; - return y; -} - -/* routines to support sliding-windows exponentiation * - * in various contexts */ - -int mr_testbit(_MIPD_ big x,int n) -{ /* return value of n-th bit of big */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_FP - mr_small m,a,dres; - m=mr_shiftbits((mr_small)1,n%mr_mip->lg2b); - - a=x->w[n/mr_mip->lg2b]; - - a=MR_DIV(a,m); - - if ((MR_DIV(a,2.0)*2.0) != a) return 1; -#else - if ((x->w[n/mr_mip->lg2b] & ((mr_small)1<<(n%mr_mip->lg2b))) >0) return 1; -#endif - return 0; -} - -void mr_addbit(_MIPD_ big x,int n) -{ /* add 2^n to positive x - where you know that bit is zero. Use with care! */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - mr_lentype m=n/mr_mip->lg2b; - x->w[m]+=mr_shiftbits((mr_small)1,n%mr_mip->lg2b); - if (x->lenlen=m+1; -} - -int recode(_MIPD_ big e,int t,int w,int i) -{ /* recode exponent for Comb method */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - int j,r; - r=0; - for (j=w-1;j>=0;j--) - { - r<<=1; - r|=mr_testbit(_MIPP_ e,i+j*t); - } - return r; -} - -int mr_window(_MIPD_ big x,int i,int *nbs,int * nzs,int window_size) -{ /* returns sliding window value, max. of 5 bits, * - * (Note from version 5.23 this can be changed by * - * setting parameter window_size. This can be * - * a useful space-saver) starting at i-th bit of big x. * - * nbs is number of bits processed, nzs is the number of * - * additional trailing zeros detected. Returns valid bit * - * pattern 1x..x1 with no two adjacent 0's. So 10101 * - * will return 21 with nbs=5, nzs=0. 11001 will return 3,* - * with nbs=2, nzs=2, having stopped after the first 11..*/ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - int j,r,w; - w=window_size; - -/* check for leading 0 bit */ - - *nbs=1; - *nzs=0; - if (!mr_testbit(_MIPP_ x,i)) return 0; - -/* adjust window size if not enough bits left */ - - if (i-w+1<0) w=i+1; - - r=1; - for (j=i-1;j>i-w;j--) - { /* accumulate bits. Abort if two 0's in a row */ - (*nbs)++; - r*=2; - if (mr_testbit(_MIPP_ x,j)) r+=1; - if (r%4==0) - { /* oops - too many zeros - shorten window */ - r/=4; - *nbs-=2; - *nzs=2; - break; - } - } - if (r%2==0) - { /* remove trailing 0 */ - r/=2; - *nzs=1; - (*nbs)--; - } - return r; -} - -int mr_window2(_MIPD_ big x,big y,int i,int *nbs,int *nzs) -{ /* two bit window for double exponentiation */ - int r,w; - BOOL a,b,c,d; - w=2; - *nbs=1; - *nzs=0; - -/* check for two leading 0's */ - a=mr_testbit(_MIPP_ x,i); b=mr_testbit(_MIPP_ y,i); - - if (!a && !b) return 0; - if (i<1) w=1; - - if (a) - { - if (b) r=3; - else r=2; - } - else r=1; - if (w==1) return r; - - c=mr_testbit(_MIPP_ x,i-1); d=mr_testbit(_MIPP_ y,i-1); - - if (!c && !d) - { - *nzs=1; - return r; - } - - *nbs=2; - r*=4; - if (c) - { - if (d) r+=3; - else r+=2; - } - else r+=1; - return r; -} - -int mr_naf_window(_MIPD_ big x,big x3,int i,int *nbs,int *nzs,int store) -{ /* returns sliding window value, using fractional windows * - * where "store" precomputed values are precalulated and * - * stored. Scanning starts at the i-th bit of x. nbs is * - * the number of bits processed. nzs is number of * - * additional trailing zeros detected. x and x3 (which is * - * 3*x) are combined to produce the NAF (non-adjacent * - * form). So if x=11011(27) and x3 is 1010001, the LSB is * - * ignored and the value 100T0T (32-4-1=27) processed, * - * where T is -1. Note x.P = (3x-x)/2.P. This value will * - * return +7, with nbs=4 and nzs=1, having stopped after * - * the first 4 bits. If it goes too far, it must backtrack * - * Note in an NAF non-zero elements are never side by side, * - * so 10T10T won't happen. NOTE: return value n zero or * - * odd, -21 <= n <= +21 */ - - int nb,j,r,biggest; - - /* get first bit */ - nb=mr_testbit(_MIPP_ x3,i)-mr_testbit(_MIPP_ x,i); - - *nbs=1; - *nzs=0; - if (nb==0) return 0; - if (i==0) return nb; - - biggest=2*store-1; - - if (nb>0) r=1; - else r=(-1); - - for (j=i-1;j>0;j--) - { - (*nbs)++; - r*=2; - nb=mr_testbit(_MIPP_ x3,j)-mr_testbit(_MIPP_ x,j); - if (nb>0) r+=1; - if (nb<0) r-=1; - if (abs(r)>biggest) break; - } - - if (r%2!=0 && j!=0) - { /* backtrack */ - if (nb>0) r=(r-1)/2; - if (nb<0) r=(r+1)/2; - (*nbs)--; - } - - while (r%2==0) - { /* remove trailing zeros */ - r/=2; - (*nzs)++; - (*nbs)--; - } - return r; -} - -/* Some general purpose elliptic curve stuff */ - -BOOL point_at_infinity(epoint *p) -{ - if (p==NULL) return FALSE; - if (p->marker==MR_EPOINT_INFINITY) return TRUE; - return FALSE; -} - -#ifndef MR_STATIC - -epoint* epoint_init(_MIPDO_ ) -{ /* initialise epoint to general point at infinity. */ - epoint *p; - char *ptr; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return NULL; - - MR_IN(96) - -/* Create space for whole structure in one heap access */ - - p=(epoint *)mr_alloc(_MIPP_ mr_esize(mr_mip->nib-1),1); - - ptr=(char *)p+sizeof(epoint); - p->X=mirvar_mem(_MIPP_ ptr,0); - p->Y=mirvar_mem(_MIPP_ ptr,1); -#ifndef MR_AFFINE_ONLY - p->Z=mirvar_mem(_MIPP_ ptr,2); -#endif - p->marker=MR_EPOINT_INFINITY; - - MR_OUT - - return p; -} - -#endif - -epoint* epoint_init_mem_variable(_MIPD_ char *mem,int index,int sz) -{ - epoint *p; - char *ptr; - int offset,r; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - offset=0; - r=(unsigned long)mem%MR_SL; - if (r>0) offset=MR_SL-r; - -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - p=(epoint *)&mem[offset+index*mr_esize_a(sz)]; - else -#endif - p=(epoint *)&mem[offset+index*mr_esize(sz)]; - - ptr=(char *)p+sizeof(epoint); - p->X=mirvar_mem_variable(ptr,0,sz); - p->Y=mirvar_mem_variable(ptr,1,sz); -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord!=MR_AFFINE) p->Z=mirvar_mem_variable(ptr,2,sz); -#endif - p->marker=MR_EPOINT_INFINITY; - return p; -} - -epoint* epoint_init_mem(_MIPD_ char *mem,int index) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return NULL; - - return epoint_init_mem_variable(_MIPP_ mem,index,mr_mip->nib-1); -} - -#ifndef MR_STATIC - -/* allocate space for a number of epoints from the heap */ - -void *ecp_memalloc(_MIPD_ int num) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - return mr_alloc(_MIPP_ mr_ecp_reserve_a(num,mr_mip->nib-1),1); - else -#endif - return mr_alloc(_MIPP_ mr_ecp_reserve(num,mr_mip->nib-1),1); -} - -#endif - -void ecp_memkill(_MIPD_ char *mem,int num) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mem==NULL) return; - -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - memset(mem,0,mr_ecp_reserve_a(num,mr_mip->nib-1)); - else -#endif - memset(mem,0,mr_ecp_reserve(num,mr_mip->nib-1)); - - -#ifndef MR_STATIC - mr_free(mem); -#endif -} - -#ifndef MR_STATIC - -void epoint_free(epoint *p) -{ /* clean up point */ - - if (p==NULL) return; - zero(p->X); - zero(p->Y); -#ifndef MR_AFFINE_ONLY - if (p->marker==MR_EPOINT_GENERAL) zero(p->Z); -#endif - mr_free(p); -} - -#endif diff --git a/crypto/sm2/miracl/mrcurve.c b/crypto/sm2/miracl/mrcurve.c deleted file mode 100644 index 8cfdeb4f..00000000 --- a/crypto/sm2/miracl/mrcurve.c +++ /dev/null @@ -1,2507 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL elliptic curve routines - * mrcurve.c - * - * Assumes Weierstrass equation y^2 = x^3 + Ax + B - * See IEEE P1363 Draft Standard - * - * (See below for Edwards coordinates implementation) - * - * Uses Montgomery's representation internally - * - * Works particularly well with fixed length Comba multiplier - * e.g. #define MR_COMBA 5 for 5x32 = 160 bit modulus - * on 32-bit computer - * - */ - -#include -#include -#ifdef MR_STATIC -#include -#endif - -#ifndef MR_EDWARDS - -static void epoint_getrhs(_MIPD_ big x,big y) -{ /* x and y must be different */ - - /* find x^3+Ax+B */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - nres_modmult(_MIPP_ x,x,y); - - nres_modmult(_MIPP_ y,x,y); - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) - nres_modmult(_MIPP_ x,mr_mip->A,mr_mip->w1); - else - nres_premult(_MIPP_ x,mr_mip->Asize,mr_mip->w1); - nres_modadd(_MIPP_ y,mr_mip->w1,y); - if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) - nres_modadd(_MIPP_ y,mr_mip->B,y); - else - { - convert(_MIPP_ mr_mip->Bsize,mr_mip->w1); - nres(_MIPP_ mr_mip->w1,mr_mip->w1); - nres_modadd(_MIPP_ y,mr_mip->w1,y); - } -} - -#ifndef MR_NOSUPPORT_COMPRESSION - -BOOL epoint_x(_MIPD_ big x) -{ /* test if x is associated with a point on the * - * currently active curve */ - int j; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(147) - - if (x==NULL) return FALSE; - - nres(_MIPP_ x,mr_mip->w2); - epoint_getrhs(_MIPP_ mr_mip->w2,mr_mip->w3); - - if (size(mr_mip->w3)==0) - { - MR_OUT - return TRUE; - } - - redc(_MIPP_ mr_mip->w3,mr_mip->w4); - j=jack(_MIPP_ mr_mip->w4,mr_mip->modulus); - - MR_OUT - if (j==1) return TRUE; - return FALSE; -} - -#endif - -BOOL epoint_set(_MIPD_ big x,big y,int cb,epoint *p) -{ /* initialise a point on active ecurve * - * if x or y == NULL, set to point at infinity * - * if x==y, a y co-ordinate is calculated - if * - * possible - and cb suggests LSB 0/1 of y * - * (which "decompresses" y). Otherwise, check * - * validity of given (x,y) point, ignoring cb. * - * Returns TRUE for valid point, otherwise FALSE. */ - - BOOL valid; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(97) - - if (x==NULL || y==NULL) - { - copy(mr_mip->one,p->X); - copy(mr_mip->one,p->Y); - p->marker=MR_EPOINT_INFINITY; - MR_OUT - return TRUE; - } - -/* find x^3+Ax+B */ - - nres(_MIPP_ x,p->X); - - epoint_getrhs(_MIPP_ p->X,mr_mip->w3); - - valid=FALSE; - - if (x!=y) - { /* compare with y^2 */ - nres(_MIPP_ y,p->Y); - nres_modmult(_MIPP_ p->Y,p->Y,mr_mip->w1); - - if (mr_compare(mr_mip->w1,mr_mip->w3)==0) valid=TRUE; - } - else - { /* no y supplied - calculate one. Find square root */ -#ifndef MR_NOSUPPORT_COMPRESSION - - valid=nres_sqroot(_MIPP_ mr_mip->w3,p->Y); - /* check LSB - have we got the right root? */ - redc(_MIPP_ p->Y,mr_mip->w1); - if (remain(_MIPP_ mr_mip->w1,2)!=cb) - mr_psub(_MIPP_ mr_mip->modulus,p->Y,p->Y); - -#else - mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); - MR_OUT - return FALSE; -#endif - } - if (valid) - { - p->marker=MR_EPOINT_NORMALIZED; - MR_OUT - return TRUE; - } - - MR_OUT - return FALSE; -} - -#ifndef MR_STATIC - -void epoint_getxyz(_MIPD_ epoint *p,big x,big y,big z) -{ /* get (x,y,z) coordinates */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(143) - convert(_MIPP_ 1,mr_mip->w1); - if (p->marker==MR_EPOINT_INFINITY) - { -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { /* (0,1) or (0,0) = O */ -#endif - if (x!=NULL) zero(x); - if (mr_mip->Bsize==0) - { - if (y!=NULL) copy(mr_mip->w1,y); - } - else - { - if (y!=NULL) zero(y); - } -#ifndef MR_AFFINE_ONLY - } - if (mr_mip->coord==MR_PROJECTIVE) - { /* (1,1,0) = O */ - if (x!=NULL) copy(mr_mip->w1,x); - if (y!=NULL) copy(mr_mip->w1,y); - } -#endif - if (z!=NULL) zero(z); - MR_OUT - return; - } - if (x!=NULL) redc(_MIPP_ p->X,x); - if (y!=NULL) redc(_MIPP_ p->Y,y); -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { -#endif - if (z!=NULL) zero(z); -#ifndef MR_AFFINE_ONLY - } - - if (mr_mip->coord==MR_PROJECTIVE) - { - if (z!=NULL) - { - if (p->marker!=MR_EPOINT_GENERAL) copy(mr_mip->w1,z); - else redc(_MIPP_ p->Z,z); - } - } -#endif - MR_OUT - return; -} - -#endif - -int epoint_get(_MIPD_ epoint* p,big x,big y) -{ /* Get point co-ordinates in affine, normal form * - * (converted from projective, Montgomery form) * - * if x==y, supplies x only. Return value is Least * - * Significant Bit of y (useful for point compression) */ - - int lsb; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (p->marker==MR_EPOINT_INFINITY) - { - zero(x); - zero(y); - return 0; - } - if (mr_mip->ERNUM) return 0; - - MR_IN(98) - - if (!epoint_norm(_MIPP_ p)) - { /* not possible ! */ - MR_OUT - return (-1); - } - - redc(_MIPP_ p->X,x); - redc(_MIPP_ p->Y,mr_mip->w1); - - if (x!=y) copy(mr_mip->w1,y); - lsb=remain(_MIPP_ mr_mip->w1,2); - MR_OUT - return lsb; -} - -BOOL epoint_norm(_MIPD_ epoint *p) -{ /* normalise a point */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - -#ifndef MR_AFFINE_ONLY - - if (mr_mip->coord==MR_AFFINE) return TRUE; - if (p->marker!=MR_EPOINT_GENERAL) return TRUE; - - if (mr_mip->ERNUM) return FALSE; - - MR_IN(117) - - copy(mr_mip->one,mr_mip->w8); - - if (nres_moddiv(_MIPP_ mr_mip->w8,p->Z,mr_mip->w8)>1) /* 1/Z */ - { - epoint_set(_MIPP_ NULL,NULL,0,p); - mr_berror(_MIPP_ MR_ERR_COMPOSITE_MODULUS); - MR_OUT - return FALSE; - } - - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w1);/* 1/ZZ */ - nres_modmult(_MIPP_ p->X,mr_mip->w1,p->X); /* X/ZZ */ - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w8,mr_mip->w1);/* 1/ZZZ */ - nres_modmult(_MIPP_ p->Y,mr_mip->w1,p->Y); /* Y/ZZZ */ - - copy(mr_mip->one,p->Z); - - p->marker=MR_EPOINT_NORMALIZED; - MR_OUT - -#endif - - return TRUE; -} - -BOOL epoint_multi_norm(_MIPD_ int m,big *work,epoint **p) -{ /* Normalise an array of points of length mcoord==MR_AFFINE) return TRUE; - if (mr_mip->ERNUM) return FALSE; - if (m>MR_MAX_M_T_S) return FALSE; - - MR_IN(190) - - for (i=0;imarker==MR_EPOINT_NORMALIZED) w[i]=mr_mip->one; - else w[i]=p[i]->Z; - if (p[i]->marker==MR_EPOINT_INFINITY) {inf=TRUE; break;} /* whoops, one of them is point at infinity */ - } - - if (inf) - { - for (i=0;ione,p[i]->Z); - p[i]->marker=MR_EPOINT_NORMALIZED; - nres_modmult(_MIPP_ work[i],work[i],mr_mip->w1); - nres_modmult(_MIPP_ p[i]->X,mr_mip->w1,p[i]->X); /* X/ZZ */ - nres_modmult(_MIPP_ mr_mip->w1,work[i],mr_mip->w1); - nres_modmult(_MIPP_ p[i]->Y,mr_mip->w1,p[i]->Y); /* Y/ZZZ */ - } - MR_OUT -#endif - return TRUE; -} - -/* adds b+=a, d+=c, and slopes in s1 and s2 */ - -#ifndef MR_NO_ECC_MULTIADD -#ifndef MR_STATIC - -void ecurve_double_add(_MIPD_ epoint *a,epoint*b,epoint *c,epoint *d,big *s1,big *s2) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(144); - -#ifndef MR_AFFINE_ONLY - - if (mr_mip->coord==MR_AFFINE) - { -#endif - if (a->marker==MR_EPOINT_INFINITY || size(a->Y)==0) - { - *s1=NULL; - ecurve_add(_MIPP_ c,d); - *s2=mr_mip->w8; - MR_OUT - return; - } - if (b->marker==MR_EPOINT_INFINITY || size(b->Y)==0) - { - *s1=NULL; - epoint_copy(a,b); - ecurve_add(_MIPP_ c,d); - *s2=mr_mip->w8; - MR_OUT - return; - } - if (c->marker==MR_EPOINT_INFINITY || size(c->Y)==0) - { - ecurve_add(_MIPP_ a,b); - *s1=mr_mip->w8; - *s2=NULL; - MR_OUT - return; - } - if (d->marker==MR_EPOINT_INFINITY || size(d->Y)==0) - { - epoint_copy(c,d); - ecurve_add(_MIPP_ a,b); - *s1=mr_mip->w8; - *s2=NULL; - MR_OUT - return; - } - - if (a==b || (mr_compare(a->X,b->X)==0 && mr_compare(a->Y,b->Y)==0)) - { - nres_modmult(_MIPP_ a->X,a->X,mr_mip->w8); - nres_premult(_MIPP_ mr_mip->w8,3,mr_mip->w8); /* 3x^2 */ - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->A,mr_mip->w8); - else - { - convert(_MIPP_ mr_mip->Asize,mr_mip->w2); - nres(_MIPP_ mr_mip->w2,mr_mip->w2); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w2,mr_mip->w8); - } - nres_premult(_MIPP_ a->Y,2,mr_mip->w10); - } - else - { - if (mr_compare(a->X,b->X)==0) - { - epoint_set(_MIPP_ NULL,NULL,0,b); - *s1=NULL; - ecurve_add(_MIPP_ c,d); - *s2=mr_mip->w8; - MR_OUT - return; - } - nres_modsub(_MIPP_ a->Y,b->Y,mr_mip->w8); - nres_modsub(_MIPP_ a->X,b->X,mr_mip->w10); - } - - if (c==d || (mr_compare(c->X,d->X)==0 && mr_compare(c->Y,d->Y)==0)) - { - nres_modmult(_MIPP_ c->X,c->X,mr_mip->w9); - nres_premult(_MIPP_ mr_mip->w9,3,mr_mip->w9); /* 3x^2 */ - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) - nres_modadd(_MIPP_ mr_mip->w9,mr_mip->A,mr_mip->w9); - else - { - convert(_MIPP_ mr_mip->Asize,mr_mip->w2); - nres(_MIPP_ mr_mip->w2,mr_mip->w2); - nres_modadd(_MIPP_ mr_mip->w9,mr_mip->w2,mr_mip->w9); - } - nres_premult(_MIPP_ c->Y,2,mr_mip->w11); - } - else - { - if (mr_compare(c->X,d->X)==0) - { - epoint_set(_MIPP_ NULL,NULL,0,d); - *s2=NULL; - ecurve_add(_MIPP_ a,b); - *s1=mr_mip->w8; - MR_OUT - return; - } - nres_modsub(_MIPP_ c->Y,d->Y,mr_mip->w9); - nres_modsub(_MIPP_ c->X,d->X,mr_mip->w11); - } - - nres_double_inverse(_MIPP_ mr_mip->w10,mr_mip->w10,mr_mip->w11,mr_mip->w11); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w10,mr_mip->w8); - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w11,mr_mip->w9); - - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w2); /* m^2 */ - nres_modsub(_MIPP_ mr_mip->w2,a->X,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,b->X,mr_mip->w1); - - nres_modsub(_MIPP_ b->X,mr_mip->w1,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w8,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w2,b->Y,b->Y); - copy(mr_mip->w1,b->X); - b->marker=MR_EPOINT_GENERAL; - - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w9,mr_mip->w2); /* m^2 */ - nres_modsub(_MIPP_ mr_mip->w2,c->X,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,d->X,mr_mip->w1); - - nres_modsub(_MIPP_ d->X,mr_mip->w1,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w9,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w2,d->Y,d->Y); - copy(mr_mip->w1,d->X); - d->marker=MR_EPOINT_GENERAL; - - *s1=mr_mip->w8; - *s2=mr_mip->w9; -#ifndef MR_AFFINE_ONLY - } - else - { /* no speed-up */ - ecurve_add(_MIPP_ a,b); - copy(mr_mip->w8,mr_mip->w9); - *s1=mr_mip->w9; - ecurve_add(_MIPP_ c,d); - *s2=mr_mip->w8; - } -#endif - MR_OUT -} - -void ecurve_multi_add(_MIPD_ int m,epoint **x,epoint**w) -{ /* adds m points together simultaneously, w[i]+=x[i] */ - int i,*flag; - big *A,*B,*C; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(122) -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { /* this can be done faster */ -#endif - A=(big *)mr_alloc(_MIPP_ m,sizeof(big)); - B=(big *)mr_alloc(_MIPP_ m,sizeof(big)); - C=(big *)mr_alloc(_MIPP_ m,sizeof(big)); - flag=(int *)mr_alloc(_MIPP_ m,sizeof(int)); - - copy(mr_mip->one,mr_mip->w3); - - for (i=0;iX,w[i]->X)==0 && mr_compare(x[i]->Y,w[i]->Y)==0) - { /* doubling */ - if (x[i]->marker==MR_EPOINT_INFINITY || size(x[i]->Y)==0) - { - flag[i]=1; /* result is infinity */ - copy(mr_mip->w3,B[i]); - continue; - } - nres_modmult(_MIPP_ x[i]->X,x[i]->X,A[i]); - nres_premult(_MIPP_ A[i],3,A[i]); /* 3*x^2 */ - if (mr_abs(mr_mip->Asize) == MR_TOOBIG) - nres_modadd(_MIPP_ A[i],mr_mip->A,A[i]); - else - { - convert(_MIPP_ mr_mip->Asize,mr_mip->w2); - nres(_MIPP_ mr_mip->w2,mr_mip->w2); - nres_modadd(_MIPP_ A[i],mr_mip->w2,A[i]); - } /* 3*x^2+A */ - nres_premult(_MIPP_ x[i]->Y,2,B[i]); - } - else - { - if (x[i]->marker==MR_EPOINT_INFINITY) - { - flag[i]=2; /* w[i] unchanged */ - copy(mr_mip->w3,B[i]); - continue; - } - if (w[i]->marker==MR_EPOINT_INFINITY) - { - flag[i]=3; /* w[i] = x[i] */ - copy(mr_mip->w3,B[i]); - continue; - } - nres_modsub(_MIPP_ x[i]->X,w[i]->X,B[i]); - if (size(B[i])==0) - { /* point at infinity */ - flag[i]=1; /* result is infinity */ - copy(mr_mip->w3,B[i]); - continue; - } - nres_modsub(_MIPP_ x[i]->Y,w[i]->Y,A[i]); - } - } - nres_multi_inverse(_MIPP_ m,B,C); /* only one inversion needed */ - for (i=0;iw8); - - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w2); /* m^2 */ - nres_modsub(_MIPP_ mr_mip->w2,x[i]->X,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,w[i]->X,mr_mip->w1); - - nres_modsub(_MIPP_ w[i]->X,mr_mip->w1,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w8,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w2,w[i]->Y,w[i]->Y); - copy(mr_mip->w1,w[i]->X); - w[i]->marker=MR_EPOINT_NORMALIZED; - - mr_free(C[i]); - mr_free(B[i]); - mr_free(A[i]); - } - mr_free(flag); - mr_free(C); mr_free(B); mr_free(A); -#ifndef MR_AFFINE_ONLY - } - else - { /* no speed-up */ - for (i=0;iERNUM) return; - - if (p->marker==MR_EPOINT_INFINITY) - { /* 2 times infinity == infinity ! */ - return; - } - -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { /* 2 sqrs, 1 mul, 1 div */ -#endif - if (size(p->Y)==0) - { /* set to point at infinity */ - epoint_set(_MIPP_ NULL,NULL,0,p); - return; - } - - nres_modmult(_MIPP_ p->X,p->X,mr_mip->w8); /* w8=x^2 */ - nres_premult(_MIPP_ mr_mip->w8,3,mr_mip->w8); /* w8=3*x^2 */ - if (mr_abs(mr_mip->Asize) == MR_TOOBIG) - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->A,mr_mip->w8); - else - { - convert(_MIPP_ mr_mip->Asize,mr_mip->w2); - nres(_MIPP_ mr_mip->w2,mr_mip->w2); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w2,mr_mip->w8); - } /* w8=3*x^2+A */ - nres_premult(_MIPP_ p->Y,2,mr_mip->w6); /* w6=2y */ - if (nres_moddiv(_MIPP_ mr_mip->w8,mr_mip->w6,mr_mip->w8)>1) - { - epoint_set(_MIPP_ NULL,NULL,0,p); - mr_berror(_MIPP_ MR_ERR_COMPOSITE_MODULUS); - return; - } - -/* w8 is slope m on exit */ - - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w2); /* w2=m^2 */ - nres_premult(_MIPP_ p->X,2,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w1); /* w1=m^2-2x */ - - nres_modsub(_MIPP_ p->X,mr_mip->w1,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w8,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w2,p->Y,p->Y); - copy(mr_mip->w1,p->X); - - return; -#ifndef MR_AFFINE_ONLY - } - - if (size(p->Y)==0) - { /* set to point at infinity */ - epoint_set(_MIPP_ NULL,NULL,0,p); - return; - } - - convert(_MIPP_ 1,mr_mip->w1); - if (mr_abs(mr_mip->Asize) < MR_TOOBIG) - { - if (mr_mip->Asize!=0) - { - if (p->marker==MR_EPOINT_NORMALIZED) - nres(_MIPP_ mr_mip->w1,mr_mip->w6); - else nres_modmult(_MIPP_ p->Z,p->Z,mr_mip->w6); - } - - if (mr_mip->Asize==(-3)) - { /* a is -3. Goody. 4 sqrs, 4 muls */ - nres_modsub(_MIPP_ p->X,mr_mip->w6,mr_mip->w3); - nres_modadd(_MIPP_ p->X,mr_mip->w6,mr_mip->w8); - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->w8,mr_mip->w3); - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w3,mr_mip->w8); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w8); - } - else - { /* a is small */ - if (mr_mip->Asize!=0) - { /* a is non zero! */ - nres_modmult(_MIPP_ mr_mip->w6,mr_mip->w6,mr_mip->w3); - nres_premult(_MIPP_ mr_mip->w3,mr_mip->Asize,mr_mip->w3); - } - nres_modmult(_MIPP_ p->X,p->X,mr_mip->w1); - nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w8); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w1,mr_mip->w8); - if (mr_mip->Asize!=0) nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w8); - } - } - else - { /* a is not special */ - if (p->marker==MR_EPOINT_NORMALIZED) nres(_MIPP_ mr_mip->w1,mr_mip->w6); - else nres_modmult(_MIPP_ p->Z,p->Z,mr_mip->w6); - - nres_modmult(_MIPP_ mr_mip->w6,mr_mip->w6,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->A,mr_mip->w3); - nres_modmult(_MIPP_ p->X,p->X,mr_mip->w1); - nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w8); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w1,mr_mip->w8); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w8); - } - -/* w8 contains numerator of slope 3x^2+A.z^4 * - * denominator is now placed in Z */ - - nres_modmult(_MIPP_ p->Y,p->Y,mr_mip->w2); - nres_modmult(_MIPP_ p->X,mr_mip->w2,mr_mip->w3); - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w3,mr_mip->w3); - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w3,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,p->X); - nres_modsub(_MIPP_ p->X,mr_mip->w3,p->X); - nres_modsub(_MIPP_ p->X,mr_mip->w3,p->X); - - if (p->marker==MR_EPOINT_NORMALIZED) - copy(p->Y,p->Z); - else nres_modmult(_MIPP_ p->Z,p->Y,p->Z); - nres_modadd(_MIPP_ p->Z,p->Z,p->Z); - - nres_modadd(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w7); - nres_modmult(_MIPP_ mr_mip->w7,mr_mip->w7,mr_mip->w2); - nres_modadd(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w3,p->X,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w3,p->Y); - nres_modsub(_MIPP_ p->Y,mr_mip->w2,p->Y); - -/* alternative method - nres_modadd(_MIPP_ p->Y,p->Y,mr_mip->w2); - - if (p->marker==MR_EPOINT_NORMALIZED) - copy(mr_mip->w2,p->Z); - - else nres_modmult(_MIPP_ mr_mip->w2,p->Z,p->Z); - - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w2); - nres_modmult(_MIPP_ p->X,mr_mip->w2,mr_mip->w3); - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w3,p->X); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,p->X,p->X); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w2); - - if (remain(_MIPP_ mr_mip->w2,2)!=0) - mr_padd(_MIPP_ mr_mip->w2,mr_mip->modulus,mr_mip->w2); - subdiv(_MIPP_ mr_mip->w2,2,mr_mip->w2); - - nres_modsub(_MIPP_ mr_mip->w3,p->X,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->w8,mr_mip->w3); - nres_modsub(_MIPP_ mr_mip->w3,mr_mip->w2,p->Y); -*/ - -/* - -Observe that when finished w8 contains the line slope, w7 has 2y^2 and w6 has z^2 -This is useful for calculating line functions in pairings - -*/ - - p->marker=MR_EPOINT_GENERAL; - return; -#endif -} - -static BOOL ecurve_padd(_MIPD_ epoint *p,epoint *pa) -{ /* primitive add two epoints on the active ecurve - pa+=p; * - * note that if p is normalized, its Z coordinate isn't used */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { /* 1 sqr, 1 mul, 1 div */ -#endif - nres_modsub(_MIPP_ p->Y,pa->Y,mr_mip->w8); - nres_modsub(_MIPP_ p->X,pa->X,mr_mip->w6); - if (size(mr_mip->w6)==0) - { /* divide by 0 */ - if (size(mr_mip->w8)==0) - { /* should have doubled ! */ - return FALSE; - } - else - { /* point at infinity */ - epoint_set(_MIPP_ NULL,NULL,0,pa); - return TRUE; - } - } - if (nres_moddiv(_MIPP_ mr_mip->w8,mr_mip->w6,mr_mip->w8)>1) - { - epoint_set(_MIPP_ NULL,NULL,0,pa); - mr_berror(_MIPP_ MR_ERR_COMPOSITE_MODULUS); - return TRUE; - } - - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w2); /* w2=m^2 */ - nres_modsub(_MIPP_ mr_mip->w2,p->X,mr_mip->w1); /* w1=m^2-x1-x2 */ - nres_modsub(_MIPP_ mr_mip->w1,pa->X,mr_mip->w1); - - - nres_modsub(_MIPP_ pa->X,mr_mip->w1,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w8,mr_mip->w2); - nres_modsub(_MIPP_ mr_mip->w2,pa->Y,pa->Y); - copy(mr_mip->w1,pa->X); - - pa->marker=MR_EPOINT_NORMALIZED; - return TRUE; -#ifndef MR_AFFINE_ONLY - } - - if (p->marker!=MR_EPOINT_NORMALIZED) - { - nres_modmult(_MIPP_ p->Z,p->Z,mr_mip->w6); - nres_modmult(_MIPP_ pa->X,mr_mip->w6,mr_mip->w1); - nres_modmult(_MIPP_ mr_mip->w6,p->Z,mr_mip->w6); - nres_modmult(_MIPP_ pa->Y,mr_mip->w6,mr_mip->w8); - } - else - { - copy(pa->X,mr_mip->w1); - copy(pa->Y,mr_mip->w8); - } - if (pa->marker==MR_EPOINT_NORMALIZED) - copy(mr_mip->one,mr_mip->w6); - - else nres_modmult(_MIPP_ pa->Z,pa->Z,mr_mip->w6); - nres_modmult(_MIPP_ p->X,mr_mip->w6,mr_mip->w4); - if (pa->marker!=MR_EPOINT_NORMALIZED) - nres_modmult(_MIPP_ mr_mip->w6,pa->Z,mr_mip->w6); - nres_modmult(_MIPP_ p->Y,mr_mip->w6,mr_mip->w5); - nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w4,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w5,mr_mip->w8); - -/* w8 contains the numerator of the slope */ - - if (size(mr_mip->w1)==0) - { - if (size(mr_mip->w8)==0) - { /* should have doubled ! */ - return FALSE; - } - else - { /* point at infinity */ - epoint_set(_MIPP_ NULL,NULL,0,pa); - return TRUE; - } - } - nres_modadd(_MIPP_ mr_mip->w4,mr_mip->w4,mr_mip->w6); - nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w6,mr_mip->w4); - nres_modadd(_MIPP_ mr_mip->w5,mr_mip->w5,mr_mip->w6); - nres_modadd(_MIPP_ mr_mip->w8,mr_mip->w6,mr_mip->w5); - - if (p->marker!=MR_EPOINT_NORMALIZED) - { - if (pa->marker!=MR_EPOINT_NORMALIZED) - nres_modmult(_MIPP_ pa->Z,p->Z,mr_mip->w3); - else - copy(p->Z,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->w1,pa->Z); - } - else - { - if (pa->marker!=MR_EPOINT_NORMALIZED) - nres_modmult(_MIPP_ pa->Z,mr_mip->w1,pa->Z); - else - copy(mr_mip->w1,pa->Z); - } - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w6); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w6,mr_mip->w1); - nres_modmult(_MIPP_ mr_mip->w6,mr_mip->w4,mr_mip->w6); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w4); - - nres_modsub(_MIPP_ mr_mip->w4,mr_mip->w6,pa->X); - nres_modsub(_MIPP_ mr_mip->w6,pa->X,mr_mip->w6); - nres_modsub(_MIPP_ mr_mip->w6,pa->X,mr_mip->w6); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w6,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w5,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w5); - -/* divide by 2 */ - - nres_div2(_MIPP_ mr_mip->w5,pa->Y); - - pa->marker=MR_EPOINT_GENERAL; - return TRUE; -#endif -} - -void epoint_copy(epoint *a,epoint *b) -{ - if (a==b || b==NULL) return; - - copy(a->X,b->X); - copy(a->Y,b->Y); -#ifndef MR_AFFINE_ONLY - if (a->marker==MR_EPOINT_GENERAL) copy(a->Z,b->Z); -#endif - b->marker=a->marker; - return; -} - -BOOL epoint_comp(_MIPD_ epoint *a,epoint *b) -{ - BOOL result; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - if (a==b) return TRUE; - if (a->marker==MR_EPOINT_INFINITY) - { - if (b->marker==MR_EPOINT_INFINITY) return TRUE; - else return FALSE; - } - if (b->marker==MR_EPOINT_INFINITY) - return FALSE; - -#ifndef MR_AFFINE_ONLY - if (mr_mip->coord==MR_AFFINE) - { -#endif - if (mr_compare(a->X,b->X)==0 && mr_compare(a->Y,b->Y)==0) result=TRUE; - else result=FALSE; - return result; -#ifndef MR_AFFINE_ONLY - } - - if (mr_mip->coord==MR_PROJECTIVE) - { - MR_IN(105) - if (a->marker!=MR_EPOINT_GENERAL) - copy(mr_mip->one,mr_mip->w1); - else copy(a->Z,mr_mip->w1); - - if (b->marker!=MR_EPOINT_GENERAL) - copy(mr_mip->one,mr_mip->w2); - else copy(b->Z,mr_mip->w2); - - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w3); /* Za*Za */ - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w4); /* Zb*Zb */ - - nres_modmult(_MIPP_ a->X,mr_mip->w4,mr_mip->w5); /* Xa*Zb*Zb */ - nres_modmult(_MIPP_ b->X,mr_mip->w3,mr_mip->w6); /* Xb*Za*Za */ - - if (mr_compare(mr_mip->w5,mr_mip->w6)!=0) result=FALSE; - else - { - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w3,mr_mip->w3); - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w4,mr_mip->w4); - - nres_modmult(_MIPP_ a->Y,mr_mip->w4,mr_mip->w5); - nres_modmult(_MIPP_ b->Y,mr_mip->w3,mr_mip->w6); - - if (mr_compare(mr_mip->w5,mr_mip->w6)!=0) result=FALSE; - else result=TRUE; - } - MR_OUT - return result; - } - return FALSE; -#endif -} - -int ecurve_add(_MIPD_ epoint *p,epoint *pa) -{ /* pa=pa+p; */ - /* An ephemeral pointer to the line slope is returned */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return MR_OVER; - - MR_IN(94) - - if (p==pa) - { - ecurve_double(_MIPP_ pa); - MR_OUT - if (pa->marker==MR_EPOINT_INFINITY) return MR_OVER; - return MR_DOUBLE; - } - if (pa->marker==MR_EPOINT_INFINITY) - { - epoint_copy(p,pa); - MR_OUT - return MR_ADD; - } - if (p->marker==MR_EPOINT_INFINITY) - { - MR_OUT - return MR_ADD; - } - - if (!ecurve_padd(_MIPP_ p,pa)) - { - ecurve_double(_MIPP_ pa); - MR_OUT - return MR_DOUBLE; - } - MR_OUT - if (pa->marker==MR_EPOINT_INFINITY) return MR_OVER; - return MR_ADD; -} - -void epoint_negate(_MIPD_ epoint *p) -{ /* negate a point */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - if (p->marker==MR_EPOINT_INFINITY) return; - - MR_IN(121) - if (size(p->Y)!=0) mr_psub(_MIPP_ mr_mip->modulus,p->Y,p->Y); - MR_OUT -} - -int ecurve_sub(_MIPD_ epoint *p,epoint *pa) -{ - int r; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return MR_OVER; - - MR_IN(104) - - if (p==pa) - { - epoint_set(_MIPP_ NULL,NULL,0,pa); - MR_OUT - return MR_OVER; - } - if (p->marker==MR_EPOINT_INFINITY) - { - MR_OUT - return MR_ADD; - } - - epoint_negate(_MIPP_ p); - r=ecurve_add(_MIPP_ p,pa); - epoint_negate(_MIPP_ p); - - MR_OUT - return r; -} - -int ecurve_mult(_MIPD_ big e,epoint *pa,epoint *pt) -{ /* pt=e*pa; */ - int i,j,n,nb,nbs,nzs,nadds; - epoint *table[MR_ECC_STORE_N]; -#ifndef MR_AFFINE_ONLY - big work[MR_ECC_STORE_N]; -#endif - -#ifdef MR_STATIC - char mem[MR_ECP_RESERVE(MR_ECC_STORE_N)]; -#ifndef MR_AFFINE_ONLY - char mem1[MR_BIG_RESERVE(MR_ECC_STORE_N)]; -#endif -#else - char *mem; -#ifndef MR_AFFINE_ONLY - char *mem1; -#endif -#endif - -#ifndef MR_ALWAYS_BINARY - epoint *p; - int ce,ch; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return 0; - - MR_IN(95) - if (size(e)==0) - { /* multiplied by 0 */ - epoint_set(_MIPP_ NULL,NULL,0,pt); - MR_OUT - return 0; - } - copy(e,mr_mip->w9); -/* epoint_norm(_MIPP_ pa); */ - epoint_copy(pa,pt); - - if (size(mr_mip->w9)<0) - { /* pt = -pt */ - negify(mr_mip->w9,mr_mip->w9); - epoint_negate(_MIPP_ pt); - } - - if (size(mr_mip->w9)==1) - { - MR_OUT - return 0; - } - - premult(_MIPP_ mr_mip->w9,3,mr_mip->w10); /* h=3*e */ - -#ifndef MR_STATIC -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif -#endif - -#ifdef MR_STATIC - memset(mem,0,MR_ECP_RESERVE(MR_ECC_STORE_N)); -#ifndef MR_AFFINE_ONLY - memset(mem1,0,MR_BIG_RESERVE(MR_ECC_STORE_N)); -#endif -#else - mem=(char *)ecp_memalloc(_MIPP_ MR_ECC_STORE_N); -#ifndef MR_AFFINE_ONLY - mem1=(char *)memalloc(_MIPP_ MR_ECC_STORE_N); -#endif -#endif - - for (i=0;i<=MR_ECC_STORE_N-1;i++) - { - table[i]=epoint_init_mem(_MIPP_ mem,i); -#ifndef MR_AFFINE_ONLY - work[i]=mirvar_mem(_MIPP_ mem1,i); -#endif - } - - epoint_copy(pt,table[0]); - epoint_copy(table[0],table[MR_ECC_STORE_N-1]); - ecurve_double(_MIPP_ table[MR_ECC_STORE_N-1]); - /* epoint_norm(_MIPP_ table[MR_ECC_STORE_N-1]); */ - - for (i=1;iw10); - nadds=0; - epoint_set(_MIPP_ NULL,NULL,0,pt); - for (i=nb-1;i>=1;) - { /* add/subtract */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - n=mr_naf_window(_MIPP_ mr_mip->w9,mr_mip->w10,i,&nbs,&nzs,MR_ECC_STORE_N); - for (j=0;j0) {ecurve_add(_MIPP_ table[n/2],pt); nadds++;} - if (n<0) {ecurve_sub(_MIPP_ table[(-n)/2],pt); nadds++;} - i-=nbs; - if (nzs) - { - for (j=0;jw10)-1,mr_mip->w11); - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - while (size(mr_mip->w11) > 1) - { /* add/subtract method */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - ecurve_double(_MIPP_ pt); - ce=mr_compare(mr_mip->w9,mr_mip->w11); /* e(i)=1? */ - ch=mr_compare(mr_mip->w10,mr_mip->w11); /* h(i)=1? */ - if (ch>=0) - { /* h(i)=1 */ - if (ce<0) {ecurve_add(_MIPP_ p,pt); nadds++;} - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - } - if (ce>=0) - { /* e(i)=1 */ - if (ch<0) {ecurve_sub(_MIPP_ p,pt); nadds++;} - mr_psub(_MIPP_ mr_mip->w9,mr_mip->w11,mr_mip->w9); - } - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - } - ecp_memkill(_MIPP_ mem,1); - } -#endif -#endif - MR_OUT - return nadds; -} - -#ifndef MR_NO_ECC_MULTIADD -#ifndef MR_STATIC - -void ecurve_multn(_MIPD_ int n,big *y,epoint **x,epoint *w) -{ /* pt=e[o]*p[0]+e[1]*p[1]+ .... e[n-1]*p[n-1] */ - int i,j,k,m,nb,ea; - epoint **G; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(114) - - m=1< nb) nb=k; - - epoint_set(_MIPP_ NULL,NULL,0,w); /* w=0 */ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - for (i=nb-1;i>=0;i--) - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - ea=0; - k=1; - for (j=0;jERNUM) return FALSE; - - if (P->marker==MR_EPOINT_GENERAL || Q->marker==MR_EPOINT_GENERAL) - { - mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - MR_OUT - return FALSE; - } - - if (mr_compare(P->X,Q->X)==0) - { /* P=Q or P=-Q - shouldn't happen */ - epoint_copy(P,PP); - ecurve_add(_MIPP_ Q,PP); - epoint_copy(P,PM); - ecurve_sub(_MIPP_ Q,PM); - - MR_OUT - return TRUE; - } - - t1= mr_mip->w10; - t2= mr_mip->w11; - lam = mr_mip->w13; - - copy(P->X,t2); - nres_modsub(_MIPP_ t2,Q->X,t2); - - redc(_MIPP_ t2,t2); - invmodp(_MIPP_ t2,mr_mip->modulus,t2); - nres(_MIPP_ t2,t2); - - nres_modadd(_MIPP_ P->X,Q->X,PP->X); - copy(PP->X,PM->X); - - copy(P->Y,t1); - nres_modsub(_MIPP_ t1,Q->Y,t1); - copy(t1,lam); - nres_modmult(_MIPP_ lam,t2,lam); - copy(lam,t1); - nres_modmult(_MIPP_ t1,t1,t1); - nres_modsub(_MIPP_ t1,PP->X,PP->X); - copy(Q->X,PP->Y); - nres_modsub(_MIPP_ PP->Y,PP->X,PP->Y); - nres_modmult(_MIPP_ PP->Y,lam,PP->Y); - nres_modsub(_MIPP_ PP->Y,Q->Y,PP->Y); - - copy(P->Y,t1); - nres_modadd(_MIPP_ t1,Q->Y,t1); - copy(t1,lam); - nres_modmult(_MIPP_ lam,t2,lam); - copy(lam,t1); - nres_modmult(_MIPP_ t1,t1,t1); - nres_modsub(_MIPP_ t1,PM->X,PM->X); - copy(Q->X,PM->Y); - nres_modsub(_MIPP_ PM->Y,PM->X,PM->Y); - nres_modmult(_MIPP_ PM->Y,lam,PM->Y); - nres_modadd(_MIPP_ PM->Y,Q->Y,PM->Y); - - PP->marker=MR_EPOINT_NORMALIZED; - PM->marker=MR_EPOINT_NORMALIZED; - - return TRUE; -} - -void ecurve_mult2(_MIPD_ big e,epoint *p,big ea,epoint *pa,epoint *pt) -{ /* pt=e*p+ea*pa; */ - int e1,h1,e2,h2,bb; - epoint *p1,*p2,*ps[2]; -#ifdef MR_STATIC - char mem[MR_ECP_RESERVE(4)]; -#else - char *mem; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip->ERNUM) return; - - MR_IN(103) - - if (size(e)==0) - { - ecurve_mult(_MIPP_ ea,pa,pt); - MR_OUT - return; - } -#ifdef MR_STATIC - memset(mem,0,MR_ECP_RESERVE(4)); -#else - mem=(char *)ecp_memalloc(_MIPP_ 4); -#endif - p2=epoint_init_mem(_MIPP_ mem,0); - p1=epoint_init_mem(_MIPP_ mem,1); - ps[0]=epoint_init_mem(_MIPP_ mem,2); - ps[1]=epoint_init_mem(_MIPP_ mem,3); - - epoint_norm(_MIPP_ pa); - epoint_copy(pa,p2); - copy(ea,mr_mip->w9); - if (size(mr_mip->w9)<0) - { /* p2 = -p2 */ - negify(mr_mip->w9,mr_mip->w9); - epoint_negate(_MIPP_ p2); - } - - epoint_norm(_MIPP_ p); - epoint_copy(p,p1); - copy(e,mr_mip->w12); - if (size(mr_mip->w12)<0) - { /* p1= -p1 */ - negify(mr_mip->w12,mr_mip->w12); - epoint_negate(_MIPP_ p1); - } - - - epoint_set(_MIPP_ NULL,NULL,0,pt); /* pt=0 */ - ecurve_add_sub(_MIPP_ p1,p2,ps[0],ps[1]); /* only one inversion! ps[0]=p1+p2, ps[1]=p1-p2 */ - - mr_jsf(_MIPP_ mr_mip->w9,mr_mip->w12,mr_mip->w10,mr_mip->w9,mr_mip->w13,mr_mip->w12); - -/* To use a simple NAF instead, substitute this for the JSF - premult(_MIPP_ mr_mip->w9,3,mr_mip->w10); 3*ea - premult(_MIPP_ mr_mip->w12,3,mr_mip->w13); 3*e -*/ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - if (mr_compare(mr_mip->w10,mr_mip->w13)>=0) bb=logb2(_MIPP_ mr_mip->w10)-1; - else bb=logb2(_MIPP_ mr_mip->w13)-1; - - while (bb>=0) /* for the simple NAF, this should be 1 */ - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - ecurve_double(_MIPP_ pt); - - e1=h1=e2=h2=0; - if (mr_testbit(_MIPP_ mr_mip->w9,bb)) e2=1; - if (mr_testbit(_MIPP_ mr_mip->w10,bb)) h2=1; - if (mr_testbit(_MIPP_ mr_mip->w12,bb)) e1=1; - if (mr_testbit(_MIPP_ mr_mip->w13,bb)) h1=1; - - if (e1!=h1) - { - if (e2==h2) - { - if (h1==1) ecurve_add(_MIPP_ p1,pt); - else ecurve_sub(_MIPP_ p1,pt); - } - else - { - if (h1==1) - { - if (h2==1) ecurve_add(_MIPP_ ps[0],pt); - else ecurve_add(_MIPP_ ps[1],pt); - } - else - { - if (h2==1) ecurve_sub(_MIPP_ ps[1],pt); - else ecurve_sub(_MIPP_ ps[0],pt); - } - } - } - else if (e2!=h2) - { - if (h2==1) ecurve_add(_MIPP_ p2,pt); - else ecurve_sub(_MIPP_ p2,pt); - } - bb-=1; - } -#ifndef MR_ALWAYS_BINARY - } - else - { - if (mr_compare(mr_mip->w10,mr_mip->w13)>=0) - expb2(_MIPP_ logb2(_MIPP_ mr_mip->w10)-1,mr_mip->w11); - else expb2(_MIPP_ logb2(_MIPP_ mr_mip->w13)-1,mr_mip->w11); - - while (size(mr_mip->w11) > 0) /* for the NAF, this should be 1 */ - { /* add/subtract method */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - ecurve_double(_MIPP_ pt); - - e1=h1=e2=h2=0; - if (mr_compare(mr_mip->w9,mr_mip->w11)>=0) - { /* e1(i)=1? */ - e2=1; - mr_psub(_MIPP_ mr_mip->w9,mr_mip->w11,mr_mip->w9); - } - if (mr_compare(mr_mip->w10,mr_mip->w11)>=0) - { /* h1(i)=1? */ - h2=1; - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - } - if (mr_compare(mr_mip->w12,mr_mip->w11)>=0) - { /* e2(i)=1? */ - e1=1; - mr_psub(_MIPP_ mr_mip->w12,mr_mip->w11,mr_mip->w12); - } - if (mr_compare(mr_mip->w13,mr_mip->w11)>=0) - { /* h2(i)=1? */ - h1=1; - mr_psub(_MIPP_ mr_mip->w13,mr_mip->w11,mr_mip->w13); - } - - if (e1!=h1) - { - if (e2==h2) - { - if (h1==1) ecurve_add(_MIPP_ p1,pt); - else ecurve_sub(_MIPP_ p1,pt); - } - else - { - if (h1==1) - { - if (h2==1) ecurve_add(_MIPP_ ps[0],pt); - else ecurve_add(_MIPP_ ps[1],pt); - } - else - { - if (h2==1) ecurve_sub(_MIPP_ ps[1],pt); - else ecurve_sub(_MIPP_ ps[0],pt); - } - } - } - else if (e2!=h2) - { - if (h2==1) ecurve_add(_MIPP_ p2,pt); - else ecurve_sub(_MIPP_ p2,pt); - } - - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - } - } -#endif - ecp_memkill(_MIPP_ mem,4); - MR_OUT -} - -#endif - -#else - -/* Twisted Inverted Edwards curves - - * Assumes Twisted Inverted Edward's equation x^2+Ay^2 = x^2.y^2 + B - * Assumes points are not of order 2 or 4 -*/ - -static void epoint_getrhs(_MIPD_ big x,big y) -{ - /* find RHS=(x^2-B)/(x^2-A) */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - nres_modmult(_MIPP_ x,x,mr_mip->w6); - nres_modsub(_MIPP_ mr_mip->w6,mr_mip->B,y); - nres_modsub(_MIPP_ mr_mip->w6,mr_mip->A,mr_mip->w6); - - nres_moddiv(_MIPP_ y,mr_mip->w6,y); -} - -#ifndef MR_NOSUPPORT_COMPRESSION - -BOOL epoint_x(_MIPD_ big x) -{ /* test if x is associated with a point on the * - * currently active curve */ - int j; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(147) - - if (x==NULL) return FALSE; - - nres(_MIPP_ x,mr_mip->w2); - epoint_getrhs(_MIPP_ mr_mip->w2,mr_mip->w7); - - if (size(mr_mip->w7)==0) - { - MR_OUT - return TRUE; - } - - redc(_MIPP_ mr_mip->w7,mr_mip->w4); - j=jack(_MIPP_ mr_mip->w4,mr_mip->modulus); - - MR_OUT - if (j==1) return TRUE; - return FALSE; -} - -#endif - -BOOL epoint_set(_MIPD_ big x,big y,int cb,epoint *p) -{ /* initialise a point on active ecurve * - * if x or y == NULL, set to point at infinity * - * if x==y, a y co-ordinate is calculated - if * - * possible - and cb suggests LSB 0/1 of y * - * (which "decompresses" y). Otherwise, check * - * validity of given (x,y) point, ignoring cb. * - * Returns TRUE for valid point, otherwise FALSE. */ - - BOOL valid; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(97) - - if (x==NULL || y==NULL) - { - copy(mr_mip->one,p->X); - zero(p->Y); - p->marker=MR_EPOINT_INFINITY; - MR_OUT - return TRUE; - } - - valid=FALSE; - nres(_MIPP_ x,p->X); - if (x!=y) - { /* Check directly that x^2+Ay^2 == x^2.y^2+B */ - nres(_MIPP_ y,p->Y); - nres_modmult(_MIPP_ p->X,p->X,mr_mip->w1); - nres_modmult(_MIPP_ p->Y,p->Y,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w3); - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->B,mr_mip->w3); - - - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->A,mr_mip->w2); - else - nres_premult(_MIPP_ mr_mip->w2,mr_mip->Asize,mr_mip->w2); - nres_modadd(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w2); - if (mr_compare(mr_mip->w2,mr_mip->w3)==0) valid=TRUE; - } - else - { /* find RHS */ - epoint_getrhs(_MIPP_ p->X,mr_mip->w7); - /* no y supplied - calculate one. Find square root */ -#ifndef MR_NOSUPPORT_COMPRESSION - valid=nres_sqroot(_MIPP_ mr_mip->w7,p->Y); - /* check LSB - have we got the right root? */ - redc(_MIPP_ p->Y,mr_mip->w1); - if (remain(_MIPP_ mr_mip->w1,2)!=cb) - mr_psub(_MIPP_ mr_mip->modulus,p->Y,p->Y); - -#else - mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); - MR_OUT - return FALSE; -#endif - } - if (valid) - { - p->marker=MR_EPOINT_NORMALIZED; - MR_OUT - return TRUE; - } - - MR_OUT - return FALSE; -} - -#ifndef MR_STATIC - -void epoint_getxyz(_MIPD_ epoint *p,big x,big y,big z) -{ /* get (x,y,z) coordinates */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(143) - convert(_MIPP_ 1,mr_mip->w1); - if (p->marker==MR_EPOINT_INFINITY) - { - if (x!=NULL) copy(mr_mip->w1,x); - if (y!=NULL) zero(y); - if (z!=NULL) zero(z); - MR_OUT - return; - } - if (x!=NULL) redc(_MIPP_ p->X,x); - if (y!=NULL) redc(_MIPP_ p->Y,y); - if (z!=NULL) redc(_MIPP_ p->Z,z); - - MR_OUT - return; -} - -#endif - -int epoint_get(_MIPD_ epoint* p,big x,big y) -{ /* Get point co-ordinates in affine, normal form * - * (converted from projective, Montgomery form) * - * if x==y, supplies x only. Return value is Least * - * Significant Bit of y (useful for point compression) */ - - int lsb; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (p->marker==MR_EPOINT_INFINITY) - { - zero(y); - convert(_MIPP_ 1,x); - return 0; - } - if (mr_mip->ERNUM) return 0; - - MR_IN(98) - - if (!epoint_norm(_MIPP_ p)) - { /* not possible ! */ - MR_OUT - return (-1); - } - - redc(_MIPP_ p->X,x); - redc(_MIPP_ p->Y,mr_mip->w1); - - if (x!=y) copy(mr_mip->w1,y); - lsb=remain(_MIPP_ mr_mip->w1,2); - MR_OUT - return lsb; -} - -BOOL epoint_norm(_MIPD_ epoint *p) -{ /* normalise a point */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (p->marker!=MR_EPOINT_GENERAL) return TRUE; - - if (mr_mip->ERNUM) return FALSE; - - MR_IN(117) - - copy(mr_mip->one,mr_mip->w8); - - if (nres_moddiv(_MIPP_ mr_mip->w8,p->Z,mr_mip->w8)>1) /* 1/Z */ - { - epoint_set(_MIPP_ NULL,NULL,0,p); - mr_berror(_MIPP_ MR_ERR_COMPOSITE_MODULUS); - MR_OUT - return FALSE; - } - - nres_modmult(_MIPP_ p->X,mr_mip->w8,p->X); /* X/Z */ - nres_modmult(_MIPP_ p->Y,mr_mip->w8,p->Y); /* Y/Z */ - - copy(mr_mip->one,p->Z); - - p->marker=MR_EPOINT_NORMALIZED; - MR_OUT - - return TRUE; -} - -void ecurve_double(_MIPD_ epoint *p) -{ /* double epoint on active ecurve */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - if (p->marker==MR_EPOINT_INFINITY) - { /* 2 times infinity == infinity ! */ - return; - } - nres_modadd(_MIPP_ p->X,p->Y,mr_mip->w1); - - nres_modmult(_MIPP_ p->X,p->X,p->X); /* A=X1^2 */ - nres_modmult(_MIPP_ p->Y,p->Y,p->Y); /* B=Y1^2 */ - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w1); /* (X+Y)^2 */ - nres_modsub(_MIPP_ mr_mip->w1,p->X,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,p->Y,mr_mip->w1); /* E=(X+Y)^2-A-B */ - - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) /* U = aB */ - nres_modmult(_MIPP_ p->Y,mr_mip->A,p->Y); - else - nres_premult(_MIPP_ p->Y,mr_mip->Asize,p->Y); - - if (p->marker!=MR_EPOINT_NORMALIZED) - nres_modmult(_MIPP_ p->Z,p->Z,p->Z); - else - copy(mr_mip->one,p->Z); - - nres_modadd(_MIPP_ p->Z,p->Z,p->Z); - if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) /* 2dZ^2 */ - nres_modmult(_MIPP_ p->Z,mr_mip->B,p->Z); - else - nres_premult(_MIPP_ p->Z,mr_mip->Bsize,p->Z); - - nres_modadd(_MIPP_ p->X,p->Y,mr_mip->w2); /* C=A+U */ - nres_modsub(_MIPP_ p->X,p->Y,mr_mip->w3); /* D=A-U */ - - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w3,p->X); /* X=C.D */ - - nres_modsub(_MIPP_ mr_mip->w2,p->Z,mr_mip->w2); /* C-2dZ^2 */ - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w1,p->Y); /* Y=E.(C-2dZ^2) */ - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->w1,p->Z); /* Z=D.E */ - - p->marker=MR_EPOINT_GENERAL; - return; -} - -static BOOL ecurve_padd(_MIPD_ epoint *p,epoint *pa) -{ /* primitive add two epoints on the active ecurve - pa+=p; * - * note that if p is normalized, its Z coordinate isn't used */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (p->marker==MR_EPOINT_INFINITY) return TRUE; - if (pa->marker==MR_EPOINT_INFINITY) - { - epoint_copy(p,pa); - return TRUE; - } - - nres_modadd(_MIPP_ p->X,p->Y,mr_mip->w1); - nres_modadd(_MIPP_ pa->X,pa->Y,mr_mip->w2); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); /* I=(X1+Y1)(X2+Y2) */ - if (p->marker!=MR_EPOINT_NORMALIZED) - { - if (pa->marker==MR_EPOINT_NORMALIZED) - copy(p->Z,pa->Z); - else nres_modmult(_MIPP_ p->Z,pa->Z,pa->Z); /* z = A = Z1*Z2 */ - } - else - { - if (pa->marker==MR_EPOINT_NORMALIZED) copy(mr_mip->one,pa->Z); - } - - nres_modmult(_MIPP_ pa->Z,pa->Z,mr_mip->w2); /* w2 = B = dA^2 */ - if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->B,mr_mip->w2); - else - nres_premult(_MIPP_ mr_mip->w2,mr_mip->Bsize,mr_mip->w2); - nres_modmult(_MIPP_ p->X,pa->X,pa->X); /* x = C = X1*X2 */ - nres_modmult(_MIPP_ p->Y,pa->Y,pa->Y); /* y = D = Y1*Y2 */ - nres_modmult(_MIPP_ pa->X,pa->Y,mr_mip->w3); /* w3 = E = C*D */ - - nres_modsub(_MIPP_ mr_mip->w1,pa->X,mr_mip->w1); - nres_modsub(_MIPP_ mr_mip->w1,pa->Y,mr_mip->w1); /* I=(X1+Y1)(X2+Y2)-C-D =X1*Y2+Y1*X2 */ - - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) /* */ - nres_modmult(_MIPP_ pa->Y,mr_mip->A,pa->Y); - else - nres_premult(_MIPP_ pa->Y,mr_mip->Asize,pa->Y); - nres_modsub(_MIPP_ pa->X,pa->Y,pa->X); /* X = H = C-aD */ - - nres_modmult(_MIPP_ pa->Z,pa->X,pa->Z); - nres_modmult(_MIPP_ pa->Z,mr_mip->w1,pa->Z); - - nres_modsub(_MIPP_ mr_mip->w3,mr_mip->w2,pa->Y); - nres_modmult(_MIPP_ pa->Y,mr_mip->w1,pa->Y); - - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w2,mr_mip->w3); - nres_modmult(_MIPP_ pa->X,mr_mip->w3,pa->X); - - if (size(pa->Z)==0) - { - copy(mr_mip->one,pa->X); - zero(pa->Y); - pa->marker=MR_EPOINT_INFINITY; - } - else pa->marker=MR_EPOINT_GENERAL; - - return TRUE; -} - -void epoint_copy(epoint *a,epoint *b) -{ - if (a==b || b==NULL) return; - - copy(a->X,b->X); - copy(a->Y,b->Y); - copy(a->Z,b->Z); - - b->marker=a->marker; - return; -} - -BOOL epoint_comp(_MIPD_ epoint *a,epoint *b) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - if (a==b) return TRUE; - if (a->marker==MR_EPOINT_INFINITY) - { - if (b->marker==MR_EPOINT_INFINITY) return TRUE; - else return FALSE; - } - if (b->marker==MR_EPOINT_INFINITY) - return FALSE; - - MR_IN(105) - copy(a->Z,mr_mip->w1); - copy(b->Z,mr_mip->w2); - - nres_modmult(_MIPP_ a->X,b->Z,mr_mip->w1); - nres_modmult(_MIPP_ b->X,a->Z,mr_mip->w2); - - if (mr_compare(mr_mip->w1,mr_mip->w2)!=0) - { - MR_OUT - return FALSE; - } - - nres_modmult(_MIPP_ a->Y,b->Z,mr_mip->w1); - nres_modmult(_MIPP_ b->Y,a->Z,mr_mip->w2); - - if (mr_compare(mr_mip->w1,mr_mip->w2)!=0) - { - MR_OUT - return FALSE; - } - MR_OUT - return TRUE; - -} - -int ecurve_add(_MIPD_ epoint *p,epoint *pa) -{ /* pa=pa+p; */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return MR_OVER; - - MR_IN(94) - - if (p==pa) - { - ecurve_double(_MIPP_ pa); - MR_OUT - if (pa->marker==MR_EPOINT_INFINITY) return MR_OVER; - return MR_DOUBLE; - } - if (pa->marker==MR_EPOINT_INFINITY) - { - epoint_copy(p,pa); - MR_OUT - return MR_ADD; - } - if (p->marker==MR_EPOINT_INFINITY) - { - MR_OUT - return MR_ADD; - } - - if (!ecurve_padd(_MIPP_ p,pa)) - { - ecurve_double(_MIPP_ pa); - MR_OUT - return MR_DOUBLE; - } - MR_OUT - if (pa->marker==MR_EPOINT_INFINITY) return MR_OVER; - return MR_ADD; -} - -void epoint_negate(_MIPD_ epoint *p) -{ /* negate a point */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - if (p->marker==MR_EPOINT_INFINITY) return; - - MR_IN(121) - if (size(p->X)!=0) mr_psub(_MIPP_ mr_mip->modulus,p->X,p->X); - MR_OUT -} - -int ecurve_sub(_MIPD_ epoint *p,epoint *pa) -{ - int r; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return MR_OVER; - - MR_IN(104) - - if (p==pa) - { - epoint_set(_MIPP_ NULL,NULL,0,pa); - MR_OUT - return MR_OVER; - } - if (p->marker==MR_EPOINT_INFINITY) - { - MR_OUT - return MR_ADD; - } - - epoint_negate(_MIPP_ p); - r=ecurve_add(_MIPP_ p,pa); - epoint_negate(_MIPP_ p); - - MR_OUT - return r; -} - -int ecurve_mult(_MIPD_ big e,epoint *pa,epoint *pt) -{ /* pt=e*pa; */ - int i,j,n,nb,nbs,nzs,nadds; - epoint *table[MR_ECC_STORE_N]; - -#ifdef MR_STATIC - char mem[MR_ECP_RESERVE(MR_ECC_STORE_N)]; -#else - char *mem; -#endif - -#ifndef MR_ALWAYS_BINARY - epoint *p; - int ce,ch; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return 0; - - MR_IN(95) - if (size(e)==0) - { /* multiplied by 0 */ - epoint_set(_MIPP_ NULL,NULL,0,pt); - MR_OUT - return 0; - } - copy(e,mr_mip->w9); - epoint_copy(pa,pt); - - if (size(mr_mip->w9)<0) - { /* pt = -pt */ - negify(mr_mip->w9,mr_mip->w9); - epoint_negate(_MIPP_ pt); - } - - if (size(mr_mip->w9)==1) - { - MR_OUT - return 0; - } - - premult(_MIPP_ mr_mip->w9,3,mr_mip->w10); /* h=3*e */ - -#ifndef MR_STATIC -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif -#endif - -#ifdef MR_STATIC - memset(mem,0,MR_ECP_RESERVE(MR_ECC_STORE_N)); -#else - mem=(char *)ecp_memalloc(_MIPP_ MR_ECC_STORE_N); -#endif - - for (i=0;i<=MR_ECC_STORE_N-1;i++) - table[i]=epoint_init_mem(_MIPP_ mem,i); - - epoint_copy(pt,table[0]); - epoint_copy(table[0],table[MR_ECC_STORE_N-1]); - ecurve_double(_MIPP_ table[MR_ECC_STORE_N-1]); - - for (i=1;iw10); - nadds=0; - epoint_set(_MIPP_ NULL,NULL,0,pt); - for (i=nb-1;i>=1;) - { /* add/subtract */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - n=mr_naf_window(_MIPP_ mr_mip->w9,mr_mip->w10,i,&nbs,&nzs,MR_ECC_STORE_N); - for (j=0;j0) {ecurve_add(_MIPP_ table[n/2],pt); nadds++;} - if (n<0) {ecurve_sub(_MIPP_ table[(-n)/2],pt); nadds++;} - i-=nbs; - if (nzs) - { - for (j=0;jw10)-1,mr_mip->w11); - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - while (size(mr_mip->w11) > 1) - { /* add/subtract method */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - ecurve_double(_MIPP_ pt); - ce=mr_compare(mr_mip->w9,mr_mip->w11); /* e(i)=1? */ - ch=mr_compare(mr_mip->w10,mr_mip->w11); /* h(i)=1? */ - if (ch>=0) - { /* h(i)=1 */ - if (ce<0) {ecurve_add(_MIPP_ p,pt); nadds++;} - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - } - if (ce>=0) - { /* e(i)=1 */ - if (ch<0) {ecurve_sub(_MIPP_ p,pt); nadds++;} - mr_psub(_MIPP_ mr_mip->w9,mr_mip->w11,mr_mip->w9); - } - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - } - ecp_memkill(_MIPP_ mem,1); - } -#endif -#endif - MR_OUT - return nadds; -} - -#ifndef MR_NO_ECC_MULTIADD -#ifndef MR_STATIC - -void ecurve_multn(_MIPD_ int n,big *y,epoint **x,epoint *w) -{ /* pt=e[0]*p[0]+e[1]*p[1]+ .... e[n-1]*p[n-1] */ - int i,j,k,m,nb,ea; - epoint **G; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(114) - - m=1< nb) nb=k; - - epoint_set(_MIPP_ NULL,NULL,0,w); /* w=0 */ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - for (i=nb-1;i>=0;i--) - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - ea=0; - k=1; - for (j=0;jmarker==MR_EPOINT_NORMALIZED) - { - if (Q->marker==MR_EPOINT_NORMALIZED) - copy(mr_mip->one,mr_mip->w1); - else copy(Q->Z,mr_mip->w1); - } - else - { - if (Q->marker==MR_EPOINT_NORMALIZED) - copy(P->Z,mr_mip->w1); - else nres_modmult(_MIPP_ P->Z,Q->Z,mr_mip->w1); /* w1 = A = Z1*Z2 */ - } - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w2); /* w2 = B = dA^2 */ - if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->B,mr_mip->w2); - else - nres_premult(_MIPP_ mr_mip->w2,mr_mip->Bsize,mr_mip->w2); - nres_modmult(_MIPP_ P->X,Q->X,mr_mip->w3); /* w3 = C = X1*X2 */ - nres_modmult(_MIPP_ P->Y,Q->Y,mr_mip->w4); /* w4 = D = Y1*Y2 */ - nres_modmult(_MIPP_ mr_mip->w3,mr_mip->w4,mr_mip->w5); /* w5 = E = C*D */ - nres_modmult(_MIPP_ P->X,Q->Y,mr_mip->w7); /* w7 = F = X1.Y2 */ - nres_modmult(_MIPP_ Q->X,P->Y,mr_mip->w8); /* w8 = G = X2.Y1 */ - - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) /* w4 = aD */ - nres_modmult(_MIPP_ mr_mip->w4,mr_mip->A,mr_mip->w4); - else - nres_premult(_MIPP_ mr_mip->w4,mr_mip->Asize,mr_mip->w4); - -/* P+Q */ - - nres_modsub(_MIPP_ mr_mip->w3,mr_mip->w4,mr_mip->w6); /* w6 = H = C-aD */ - nres_modadd(_MIPP_ mr_mip->w7,mr_mip->w8,PP->Z); /* X1*Y2+X2*Y1 */ - nres_modadd(_MIPP_ mr_mip->w5,mr_mip->w2,PP->X); - nres_modmult(_MIPP_ PP->X,mr_mip->w6,PP->X); - nres_modsub(_MIPP_ mr_mip->w5,mr_mip->w2,PP->Y); - nres_modmult(_MIPP_ PP->Y,PP->Z,PP->Y); - nres_modmult(_MIPP_ PP->Z,mr_mip->w6,PP->Z); - nres_modmult(_MIPP_ PP->Z,mr_mip->w1,PP->Z); - - if (size(PP->Z)==0) - { - copy(mr_mip->one,PP->X); - zero(PP->Y); - PP->marker=MR_EPOINT_INFINITY; - } - else PP->marker=MR_EPOINT_GENERAL; - -/* P-Q */ - - nres_modadd(_MIPP_ mr_mip->w3,mr_mip->w4,mr_mip->w6); /* w6 = C+aD */ - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w7,PM->Z); /* X2*Y1-X1*Y2 */ - nres_modsub(_MIPP_ mr_mip->w5,mr_mip->w2,PM->X); - nres_modmult(_MIPP_ PM->X,mr_mip->w6,PM->X); - nres_modadd(_MIPP_ mr_mip->w5,mr_mip->w2,PM->Y); - nres_modmult(_MIPP_ PM->Y,PM->Z,PM->Y); - nres_modmult(_MIPP_ PM->Z,mr_mip->w6,PM->Z); - nres_modmult(_MIPP_ PM->Z,mr_mip->w1,PM->Z); - - if (size(PM->Z)==0) - { - copy(mr_mip->one,PM->X); - zero(PM->Y); - PM->marker=MR_EPOINT_INFINITY; - } - else PM->marker=MR_EPOINT_GENERAL; - - return TRUE; -} - -void ecurve_mult2(_MIPD_ big e,epoint *p,big ea,epoint *pa,epoint *pt) -{ /* pt=e*p+ea*pa; */ - int e1,h1,e2,h2,bb; - epoint *p1,*p2,*ps[2]; -#ifdef MR_STATIC - char mem[MR_ECP_RESERVE(4)]; -#else - char *mem; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip->ERNUM) return; - - MR_IN(103) - - if (size(e)==0) - { - ecurve_mult(_MIPP_ ea,pa,pt); - MR_OUT - return; - } -#ifdef MR_STATIC - memset(mem,0,MR_ECP_RESERVE(4)); -#else - mem=ecp_memalloc(_MIPP_ 4); -#endif - p2=epoint_init_mem(_MIPP_ mem,0); - p1=epoint_init_mem(_MIPP_ mem,1); - ps[0]=epoint_init_mem(_MIPP_ mem,2); - ps[1]=epoint_init_mem(_MIPP_ mem,3); - - epoint_copy(pa,p2); - copy(ea,mr_mip->w9); - if (size(mr_mip->w9)<0) - { /* p2 = -p2 */ - negify(mr_mip->w9,mr_mip->w9); - epoint_negate(_MIPP_ p2); - } - - epoint_copy(p,p1); - copy(e,mr_mip->w12); - if (size(mr_mip->w12)<0) - { /* p1= -p1 */ - negify(mr_mip->w12,mr_mip->w12); - epoint_negate(_MIPP_ p1); - } - - epoint_set(_MIPP_ NULL,NULL,0,pt); /* pt=0 */ - ecurve_add_sub(_MIPP_ p1,p2,ps[0],ps[1]); /* ps[0]=p1+p2, ps[1]=p1-p2 */ - - mr_jsf(_MIPP_ mr_mip->w9,mr_mip->w12,mr_mip->w10,mr_mip->w9,mr_mip->w13,mr_mip->w12); - -/* To use a simple NAF instead, substitute this for the JSF - premult(_MIPP_ mr_mip->w9,3,mr_mip->w10); 3*ea - premult(_MIPP_ mr_mip->w12,3,mr_mip->w13); 3*e -*/ - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - if (mr_compare(mr_mip->w10,mr_mip->w13)>=0) bb=logb2(_MIPP_ mr_mip->w10)-1; - else bb=logb2(_MIPP_ mr_mip->w13)-1; - - while (bb>=0) /* for the simple NAF, this should be 1 */ - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - ecurve_double(_MIPP_ pt); - - e1=h1=e2=h2=0; - if (mr_testbit(_MIPP_ mr_mip->w9,bb)) e2=1; - if (mr_testbit(_MIPP_ mr_mip->w10,bb)) h2=1; - if (mr_testbit(_MIPP_ mr_mip->w12,bb)) e1=1; - if (mr_testbit(_MIPP_ mr_mip->w13,bb)) h1=1; - - if (e1!=h1) - { - if (e2==h2) - { - if (h1==1) ecurve_add(_MIPP_ p1,pt); - else ecurve_sub(_MIPP_ p1,pt); - } - else - { - if (h1==1) - { - if (h2==1) ecurve_add(_MIPP_ ps[0],pt); - else ecurve_add(_MIPP_ ps[1],pt); - } - else - { - if (h2==1) ecurve_sub(_MIPP_ ps[1],pt); - else ecurve_sub(_MIPP_ ps[0],pt); - } - } - } - else if (e2!=h2) - { - if (h2==1) ecurve_add(_MIPP_ p2,pt); - else ecurve_sub(_MIPP_ p2,pt); - } - bb-=1; - } -#ifndef MR_ALWAYS_BINARY - } - else - { - if (mr_compare(mr_mip->w10,mr_mip->w13)>=0) - expb2(_MIPP_ logb2(_MIPP_ mr_mip->w10)-1,mr_mip->w11); - else expb2(_MIPP_ logb2(_MIPP_ mr_mip->w13)-1,mr_mip->w11); - - while (size(mr_mip->w11) > 0) /* for the NAF, this should be 1 */ - { /* add/subtract method */ - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - ecurve_double(_MIPP_ pt); - - e1=h1=e2=h2=0; - if (mr_compare(mr_mip->w9,mr_mip->w11)>=0) - { /* e1(i)=1? */ - e2=1; - mr_psub(_MIPP_ mr_mip->w9,mr_mip->w11,mr_mip->w9); - } - if (mr_compare(mr_mip->w10,mr_mip->w11)>=0) - { /* h1(i)=1? */ - h2=1; - mr_psub(_MIPP_ mr_mip->w10,mr_mip->w11,mr_mip->w10); - } - if (mr_compare(mr_mip->w12,mr_mip->w11)>=0) - { /* e2(i)=1? */ - e1=1; - mr_psub(_MIPP_ mr_mip->w12,mr_mip->w11,mr_mip->w12); - } - if (mr_compare(mr_mip->w13,mr_mip->w11)>=0) - { /* h2(i)=1? */ - h1=1; - mr_psub(_MIPP_ mr_mip->w13,mr_mip->w11,mr_mip->w13); - } - - if (e1!=h1) - { - if (e2==h2) - { - if (h1==1) ecurve_add(_MIPP_ p1,pt); - else ecurve_sub(_MIPP_ p1,pt); - } - else - { - if (h1==1) - { - if (h2==1) ecurve_add(_MIPP_ ps[0],pt); - else ecurve_add(_MIPP_ ps[1],pt); - } - else - { - if (h2==1) ecurve_sub(_MIPP_ ps[1],pt); - else ecurve_sub(_MIPP_ ps[0],pt); - } - } - } - else if (e2!=h2) - { - if (h2==1) ecurve_add(_MIPP_ p2,pt); - else ecurve_sub(_MIPP_ p2,pt); - } - - subdiv(_MIPP_ mr_mip->w11,2,mr_mip->w11); - } - } -#endif - ecp_memkill(_MIPP_ mem,4); - MR_OUT -} - -#endif - -#endif diff --git a/crypto/sm2/miracl/mrjack.c b/crypto/sm2/miracl/mrjack.c deleted file mode 100644 index 1b77a984..00000000 --- a/crypto/sm2/miracl/mrjack.c +++ /dev/null @@ -1,342 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL Jacobi symbol routine - * mrjack.c - * - * See "A binary algorithm for the Jacobi symbol" - * Shallit and Sorenson - */ -#include -#include - -int jack(_MIPD_ big a,big n) -{ /* find jacobi symbol (a/n), for positive odd n */ - big w; - int nm8,onm8,t; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM || size(a)==0 || size(n) <1) return 0; - MR_IN(3) - - t=1; - copy(n,mr_mip->w2); - nm8=remain(_MIPP_ mr_mip->w2,8); - if (nm8%2==0) - { - MR_OUT - return 0; - } - - if (size(a)<0) - { - if (nm8%4==3) t=-1; - negify(a,mr_mip->w1); - } - else copy(a,mr_mip->w1); - - while (size(mr_mip->w1)!=0) - { - while (remain(_MIPP_ mr_mip->w1,2)==0) - { - subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); - if (nm8==3 || nm8==5) t=-t; - } - if (mr_compare(mr_mip->w1,mr_mip->w2)<0) - { - onm8=nm8; - w=mr_mip->w1; mr_mip->w1=mr_mip->w2; mr_mip->w2=w; - nm8=remain(_MIPP_ mr_mip->w2,8); - if (onm8%4==3 && nm8%4==3) t=-t; - } - mr_psub(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); - subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); - - if (nm8==3 || nm8==5) t=-t; - } - - MR_OUT - if (size(mr_mip->w2)==1) return t; - return 0; -} - -/* - * See "Efficient Algorithms for Computing the Jacobi Symbol" - * Eikenberry & Sorenson - * - * Its turns out this is slower than the binary method above for reasonable sizes - * of parameters (and takes up a lot more space!) - - -#ifdef MR_FP -#include -#endif - - -static void rfind(mr_small u,mr_small v,mr_small k,mr_small sk,mr_utype *a,mr_utype *b) -{ - mr_utype x2,y2,r; - mr_small w,q,x1,y1,sr; -#ifdef MR_FP - mr_small dres; -#endif - - w=invers(v,k); - w=smul(u,w,k); - - x1=k; x2=0; - y1=w; y2=1; - -// NOTE: x1 and y1 are always +ve. x2 and y2 are always small - - while (y1>=sk) - { -#ifndef MR_NOFULLWIDTH - if (x1==0) q=muldvm((mr_small)1,(mr_small)0,y1,&sr); - else -#endif - q=MR_DIV(x1,y1); - r= x1-q*y1; x1=y1; y1=r; - sr=x2-q*y2; x2=y2; y2=sr; - } - if (y2>=0) { *a=y2; *b=0-y1; } - else { *a=-y2; *b=y1; } -} - -int jack(_MIPD_ big U,big V) -{ // find jacobi symbol for U wrt V. Only defined for - // positive V, V odd. Otherwise returns 0 - int i,e,r,m,t,v8,u4; - mr_utype a,b; - mr_small u,v,d,g,k,sk,s; -#ifdef MR_FP - mr_small dres; -#endif - big w; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_FP_ROUNDING - mr_large ik,id; -#endif - if (mr_mip->ERNUM || size(U)==0 || size(V) <1) return 0; - copy(U,mr_mip->w1); - copy(V,mr_mip->w2); - a=0; - MR_IN(3) - - if (remain(_MIPP_ mr_mip->w2,2)==0) - { // V is even - MR_OUT - return 0; - } - - if (mr_mip->base!=0) - { - k=1; - for (m=1;;m++) - { - k*=2; - if (k==MAXBASE) break; - } - if (m%2==1) {m--; k=MR_DIV(k,2);} -#ifdef MR_FP_ROUNDING - ik=mr_invert(k); -#endif - } - else - { - m=MIRACL; - k=0; - } - r=m/2; - sk=1; - for (i=0;iw2,8); - - while (!mr_mip->ERNUM && size(mr_mip->w1)!=0) - { - if (size(mr_mip->w1)<0) - { - negify(mr_mip->w1,mr_mip->w1); - if (v8%4==3) t=-t; - } - - do { // oddify - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - if (mr_mip->base==k) u=mr_mip->w1->w[0]; - else u=MR_REMAIN(mr_mip->w1->w[0],k); -#ifndef MR_ALWAYS_BINARY - } - -#ifdef MR_FP_ROUNDING - else u=mr_sdiv(_MIPP_ mr_mip->w1,k,ik,mr_mip->w3); -#else - else u=mr_sdiv(_MIPP_ mr_mip->w1,k,mr_mip->w3); -#endif - -#endif - if (u==0) {s=k; e=0;} - else - { - s=1; e=0; - while (MR_REMAIN(u,2)==0) {s*=2; e++; u=MR_DIV(u,2);} - } - if (s==mr_mip->base) mr_shift(_MIPP_ mr_mip->w1,-1,mr_mip->w1); -#ifdef MR_FP_ROUNDING - else if (s>1) - { - mr_sdiv(_MIPP_ mr_mip->w1,s,mr_invert(s),mr_mip->w1); - } -#else - else if (s>1) mr_sdiv(_MIPP_ mr_mip->w1,s,mr_mip->w1); -#endif - } while (u==0); - if (e%2!=0 && (v8==3 || v8==5)) t=-t; - if (mr_compare(mr_mip->w1,mr_mip->w2)<0) - { - if (mr_mip->base==mr_mip->base2) u4=(int)MR_REMAIN(mr_mip->w1->w[0],4); - else u4=remain(_MIPP_ mr_mip->w1,4); - if (v8%4==3 && u4==3) t=-t; - w=mr_mip->w1; mr_mip->w1=mr_mip->w2; mr_mip->w2=w; - } - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - if (k==mr_mip->base) - { - u=mr_mip->w1->w[0]; - v=mr_mip->w2->w[0]; - } - else - { - u=MR_REMAIN(mr_mip->w1->w[0],k); - v=MR_REMAIN(mr_mip->w2->w[0],k); - } -#ifndef MR_ALWAYS_BINARY - } - else - { -#ifdef MR_FP_ROUNDING - u=mr_sdiv(_MIPP_ mr_mip->w1,k,ik,mr_mip->w3); - v=mr_sdiv(_MIPP_ mr_mip->w2,k,ik,mr_mip->w3); -#else - u=mr_sdiv(_MIPP_ mr_mip->w1,k,mr_mip->w3); - v=mr_sdiv(_MIPP_ mr_mip->w2,k,mr_mip->w3); -#endif - } -#endif - rfind(u,v,k,sk,&a,&b); - if (a>1) - { -#ifdef MR_FP_ROUNDING - d=mr_sdiv(_MIPP_ mr_mip->w2,a,mr_invert(a),mr_mip->w3); -#else - d=mr_sdiv(_MIPP_ mr_mip->w2,a,mr_mip->w3); -#endif - d=sgcd(d,a); - a=MR_DIV(a,d); - } - else d=1; - - if (d>1) - { -#ifdef MR_FP_ROUNDING - id=mr_invert(d); - mr_sdiv(_MIPP_ mr_mip->w2,d,id,mr_mip->w2); - u=mr_sdiv(_MIPP_ mr_mip->w1,d,id,mr_mip->w3); -#else - mr_sdiv(_MIPP_ mr_mip->w2,d,mr_mip->w2); - u=mr_sdiv(_MIPP_ mr_mip->w1,d,mr_mip->w3); -#endif - } - else u=0; - - g=a; - if (mr_mip->base==mr_mip->base2) v8=(int)MR_REMAIN(mr_mip->w2->w[0],8); - else v8=remain(_MIPP_ mr_mip->w2,8); - while (MR_REMAIN(g,2)==0) - { - g=MR_DIV(g,2); - if (v8==3 || v8==5) t=-t; - } - if (MR_REMAIN(g,4)==3 && v8%4==3) t=-t; -#ifdef MR_FP_ROUNDING - v=mr_sdiv(_MIPP_ mr_mip->w2,g,mr_invert(g),mr_mip->w3); -#else - v=mr_sdiv(_MIPP_ mr_mip->w2,g,mr_mip->w3); -#endif - t*=jac(v,g)*jac(u,d); - if (t==0) - { - MR_OUT - return 0; - } - -// printf("a= %I64d b=%I64d %d\n",a,b,(int)b); - - if (a>1) mr_pmul(_MIPP_ mr_mip->w1,a,mr_mip->w1); - if (b>=0) - mr_pmul(_MIPP_ mr_mip->w2,b,mr_mip->w3); - else - { - b=-b; - mr_pmul(_MIPP_ mr_mip->w2,b,mr_mip->w3); - negify(mr_mip->w3,mr_mip->w3); - } - // premult(_MIPP_ mr_mip->w2,(int)b,mr_mip->w3); <- nasty bug - potential loss of precision in b - add(_MIPP_ mr_mip->w1,mr_mip->w3,mr_mip->w1); - if (k==mr_mip->base) mr_shift(_MIPP_ mr_mip->w1,-1,mr_mip->w1); -#ifdef MR_FP_ROUNDING - else mr_sdiv(_MIPP_ mr_mip->w1,k,ik,mr_mip->w1); -#else - else mr_sdiv(_MIPP_ mr_mip->w1,k,mr_mip->w1); -#endif - } - MR_OUT - if (size(mr_mip->w2)==1) return t; - return 0; -} - -*/ diff --git a/crypto/sm2/miracl/mrlucas.c b/crypto/sm2/miracl/mrlucas.c deleted file mode 100644 index 2a19b49f..00000000 --- a/crypto/sm2/miracl/mrlucas.c +++ /dev/null @@ -1,157 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL methods for evaluating lucas V function - * mrlucas.c (Postl's algorithm) - */ - -#include -#include - -void nres_lucas(_MIPD_ big p,big r,big vp,big v) -{ - int i,nb; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(107) - - if (size(r)==0) - { - zero(vp); - convert(_MIPP_ 2,v); - nres(_MIPP_ v,v); - MR_OUT - return; - } - if (size(r)==1 || size(r)==(-1)) - { /* note - sign of r doesn't matter */ - convert(_MIPP_ 2,vp); - nres(_MIPP_ vp,vp); - copy(p,v); - MR_OUT - return; - } - - copy(p,mr_mip->w3); - - convert(_MIPP_ 2,mr_mip->w4); - nres(_MIPP_ mr_mip->w4,mr_mip->w4); /* w4=2 */ - - copy(mr_mip->w4,mr_mip->w8); - copy(mr_mip->w3,mr_mip->w9); - - copy(r,mr_mip->w1); - insign(PLUS,mr_mip->w1); - decr(_MIPP_ mr_mip->w1,1,mr_mip->w1); - -#ifndef MR_ALWAYS_BINARY - if (mr_mip->base==mr_mip->base2) - { -#endif - nb=logb2(_MIPP_ mr_mip->w1); - for (i=nb-1;i>=0;i--) - { - if (mr_mip->user!=NULL) (*mr_mip->user)(); - - if (mr_testbit(_MIPP_ mr_mip->w1,i)) - { - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w9,mr_mip->w8); - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w8); - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w9,mr_mip->w9); - nres_modsub(_MIPP_ mr_mip->w9,mr_mip->w4,mr_mip->w9); - - } - else - { - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w8,mr_mip->w9); - nres_modsub(_MIPP_ mr_mip->w9,mr_mip->w3,mr_mip->w9); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w8); - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w4,mr_mip->w8); - } - } - -#ifndef MR_ALWAYS_BINARY - } - else - { - expb2(_MIPP_ logb2(_MIPP_ mr_mip->w1)-1,mr_mip->w2); - - while (!mr_mip->ERNUM && size(mr_mip->w2)!=0) - { /* use binary method */ - if (mr_compare(mr_mip->w1,mr_mip->w2)>=0) - { /* vp=v*vp-p, v=v*v-2 */ - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w9,mr_mip->w8); - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w3,mr_mip->w8); - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w9,mr_mip->w9); - nres_modsub(_MIPP_ mr_mip->w9,mr_mip->w4,mr_mip->w9); - subtract(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); - } - else - { /* v=v*vp-p, vp=vp*vp-2 */ - nres_modmult(_MIPP_ mr_mip->w9,mr_mip->w8,mr_mip->w9); - nres_modsub(_MIPP_ mr_mip->w9,mr_mip->w3,mr_mip->w9); - nres_modmult(_MIPP_ mr_mip->w8,mr_mip->w8,mr_mip->w8); - nres_modsub(_MIPP_ mr_mip->w8,mr_mip->w4,mr_mip->w8); - } - subdiv(_MIPP_ mr_mip->w2,2,mr_mip->w2); - } - } -#endif - - copy(mr_mip->w9,v); - if (v!=vp) copy(mr_mip->w8,vp); - MR_OUT - -} - -void lucas(_MIPD_ big p,big r,big n,big vp,big v) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(108) - prepare_monty(_MIPP_ n); - nres(_MIPP_ p,mr_mip->w3); - nres_lucas(_MIPP_ mr_mip->w3,r,mr_mip->w8,mr_mip->w9); - redc(_MIPP_ mr_mip->w9,v); - if (v!=vp) redc(_MIPP_ mr_mip->w8,vp); - MR_OUT -} - diff --git a/crypto/sm2/miracl/mrmonty.c b/crypto/sm2/miracl/mrmonty.c deleted file mode 100644 index 102b4d34..00000000 --- a/crypto/sm2/miracl/mrmonty.c +++ /dev/null @@ -1,1414 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL Montgomery's method for modular arithmetic without division. - * mrmonty.c - * - * Programs to implement Montgomery's method - * See "Modular Multiplication Without Trial Division", Math. Comp. - * Vol 44, Number 170, April 1985, Pages 519-521 - * NOTE - there is an important correction to this paper mentioned as a - * footnote in "Speeding the Pollard and Elliptic Curve Methods", - * Math. Comput., Vol. 48, January 1987, 243-264 - * - * The advantage of this approach is that no division required in order - * to compute a modular reduction - useful if division is slow - * e.g. on a SPARC processor, or a DSP. - * - * The disadvantage is that numbers must first be converted to an internal - * "n-residue" form. - * - */ - -#include -#include - -#ifdef MR_FP -#include -#endif - -#ifdef MR_WIN64 -#include -#endif - -#ifdef MR_COUNT_OPS -extern int fpc,fpa; -#endif - -#ifdef MR_CELL -extern void mod256(_MIPD_ big,big); -#endif - -void kill_monty(_MIPDO_ ) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - zero(mr_mip->modulus); -#ifdef MR_KCM - zero(mr_mip->big_ndash); -#endif -} - -mr_small prepare_monty(_MIPD_ big n) -{ /* prepare Montgomery modulus */ -#ifdef MR_KCM - int nl; -#endif -#ifdef MR_PENTIUM - mr_small ndash; - mr_small base; - mr_small magic=13835058055282163712.0; - int control=0x1FFF; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return (mr_small)0; -/* Is it set-up already? */ - if (size(mr_mip->modulus)!=0) - if (mr_compare(n,mr_mip->modulus)==0) return mr_mip->ndash; - - MR_IN(80) - - if (size(n)<=2) - { - mr_berror(_MIPP_ MR_ERR_BAD_MODULUS); - MR_OUT - return (mr_small)0; - } - - zero(mr_mip->w6); - zero(mr_mip->w15); - -/* set a small negative QNR (on the assumption that n is prime!) */ -/* These defaults can be over-ridden */ - -/* Did you know that for p=2 mod 3, -3 is a QNR? */ - - mr_mip->pmod8=remain(_MIPP_ n,8); - - switch (mr_mip->pmod8) - { - case 0: - case 1: - case 2: - case 4: - case 6: - mr_mip->qnr=0; /* none defined */ - break; - case 3: - mr_mip->qnr=-1; - break; - case 5: - mr_mip->qnr=-2; - break; - case 7: - mr_mip->qnr=-1; - break; - } - mr_mip->pmod9=remain(_MIPP_ n,9); - - mr_mip->NO_CARRY=FALSE; - if (n->w[n->len-1]>>M4 < 5) mr_mip->NO_CARRY=TRUE; - -#ifdef MR_PENTIUM - -mr_mip->ACTIVE=FALSE; -if (mr_mip->base!=0) - if (MR_PENTIUM==n->len) mr_mip->ACTIVE=TRUE; - if (MR_PENTIUM<0) - { - if (n->len<=(-MR_PENTIUM)) mr_mip->ACTIVE=TRUE; - if (logb2(_MIPP_ n)%mr_mip->lg2b==0) mr_mip->ACTIVE=FALSE; - } -#endif - -#ifdef MR_DISABLE_MONTGOMERY - mr_mip->MONTY=OFF; -#else - mr_mip->MONTY=ON; -#endif - -#ifdef MR_COMBA - mr_mip->ACTIVE=FALSE; - - if (MR_COMBA==n->len && mr_mip->base==mr_mip->base2) - { - mr_mip->ACTIVE=TRUE; -#ifdef MR_SPECIAL - mr_mip->MONTY=OFF; /* "special" modulus reduction */ - -#endif /* implemented in mrcomba.c */ - } - -#endif - convert(_MIPP_ 1,mr_mip->one); - if (!mr_mip->MONTY) - { /* Montgomery arithmetic is turned off */ - copy(n,mr_mip->modulus); - mr_mip->ndash=0; - MR_OUT - return (mr_small)0; - } - -#ifdef MR_KCM - -/* test for base==0 & n->len=MR_KCM.2^x */ - - mr_mip->ACTIVE=FALSE; - if (mr_mip->base==0) - { - nl=(int)n->len; - while (nl>=MR_KCM) - { - if (nl==MR_KCM) - { - mr_mip->ACTIVE=TRUE; - break; - } - if (nl%2!=0) break; - nl/=2; - } - } - if (mr_mip->ACTIVE) - { - mr_mip->w6->len=n->len+1; - mr_mip->w6->w[n->len]=1; - if (invmodp(_MIPP_ n,mr_mip->w6,mr_mip->w14)!=1) - { /* problems */ - mr_berror(_MIPP_ MR_ERR_BAD_MODULUS); - MR_OUT - return (mr_small)0; - } - } - else - { -#endif - mr_mip->w6->len=2; - mr_mip->w6->w[0]=0; - mr_mip->w6->w[1]=1; /* w6 = base */ - mr_mip->w15->len=1; - mr_mip->w15->w[0]=n->w[0]; /* w15 = n mod base */ - if (invmodp(_MIPP_ mr_mip->w15,mr_mip->w6,mr_mip->w14)!=1) - { /* problems */ - mr_berror(_MIPP_ MR_ERR_BAD_MODULUS); - MR_OUT - return (mr_small)0; - } -#ifdef MR_KCM - } - copy(mr_mip->w14,mr_mip->big_ndash); -#endif - - mr_mip->ndash=mr_mip->base-mr_mip->w14->w[0]; /* = N' mod b */ - copy(n,mr_mip->modulus); - mr_mip->check=OFF; - mr_shift(_MIPP_ mr_mip->modulus,(int)mr_mip->modulus->len,mr_mip->pR); - mr_mip->check=ON; -#ifdef MR_PENTIUM -/* prime the FP stack */ - if (mr_mip->ACTIVE) - { - ndash=mr_mip->ndash; - base=mr_mip->base; - magic *=base; - ASM - { - finit - fldcw WORD PTR control - fld QWORD PTR ndash - fld1 - fld QWORD PTR base - fdiv - fld QWORD PTR magic - } - } -#endif - nres(_MIPP_ mr_mip->one,mr_mip->one); - MR_OUT - - return mr_mip->ndash; -} - -void nres(_MIPD_ big x,big y) -{ /* convert x to n-residue format */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(81) - - if (size(mr_mip->modulus)==0) - { - mr_berror(_MIPP_ MR_ERR_NO_MODULUS); - MR_OUT - return; - } - copy(x,y); - divide(_MIPP_ y,mr_mip->modulus,mr_mip->modulus); - if (size(y)<0) add(_MIPP_ y,mr_mip->modulus,y); - if (!mr_mip->MONTY) - { - MR_OUT - return; - } - mr_mip->check=OFF; - - mr_shift(_MIPP_ y,(int)mr_mip->modulus->len,mr_mip->w0); - divide(_MIPP_ mr_mip->w0,mr_mip->modulus,mr_mip->modulus); - mr_mip->check=ON; - copy(mr_mip->w0,y); - - MR_OUT -} - -void redc(_MIPD_ big x,big y) -{ /* Montgomery's REDC function p. 520 */ - /* also used to convert n-residues back to normal form */ - mr_small carry,delay_carry,m,ndash,*w0g,*mg; - -#ifdef MR_ITANIUM - mr_small tm; -#endif -#ifdef MR_WIN64 - mr_small tm,tr; -#endif - int i,j,rn,rn2; - big w0,modulus; -#ifdef MR_NOASM - union doubleword dble; - mr_large dbled,ldres; -#endif -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(82) - - w0=mr_mip->w0; /* get these into local variables (for inline assembly) */ - modulus=mr_mip->modulus; - ndash=mr_mip->ndash; - - copy(x,w0); - if (!mr_mip->MONTY) - { -/*#ifdef MR_CELL - mod256(_MIPP_ w0,w0); -#else */ - divide(_MIPP_ w0,modulus,modulus); -/* #endif */ - copy(w0,y); - MR_OUT - return; - } - delay_carry=0; - rn=(int)modulus->len; - rn2=rn+rn; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH - mg=modulus->w; - w0g=w0->w; - for (i=0;iw[i],ndash,0,&m); Note that after this time */ - m=ndash*w0->w[i]; - carry=0; /* around the loop, w0[i]=0 */ - - for (j=0;jw[j]+carry+w0->w[i+j]; - w0->w[i+j]=dble.h[MR_BOT]; - carry=dble.h[MR_TOP]; -#else - muldvd2(m,modulus->w[j],&carry,&w0->w[i+j]); -#endif - } - w0->w[rn+i]+=delay_carry; - if (w0->w[rn+i]w[rn+i]+=carry; - if (w0->w[rn+i]w[i],ndash,0,mr_mip->base,mr_mip->inverse_base,&m); -#else - muldiv(w0->w[i],ndash,0,mr_mip->base,&m); -#endif - carry=0; - for (j=0;jw[j]+carry+w0->w[i+j]; -#ifdef MR_FP_ROUNDING - carry=(mr_small)MR_LROUND(dbled*mr_mip->inverse_base); -#else -#ifndef MR_FP - if (mr_mip->base==mr_mip->base2) - carry=(mr_small)(dbled>>mr_mip->lg2b); - else -#endif - carry=(mr_small)MR_LROUND(dbled/mr_mip->base); -#endif - w0->w[i+j]=(mr_small)(dbled-(mr_large)carry*mr_mip->base); -#else -#ifdef MR_FP_ROUNDING - carry=imuldiv(modulus->w[j],m,w0->w[i+j]+carry,mr_mip->base,mr_mip->inverse_base,&w0->w[i+j]); -#else - carry=muldiv(modulus->w[j],m,w0->w[i+j]+carry,mr_mip->base,&w0->w[i+j]); -#endif -#endif - } - w0->w[rn+i]+=(delay_carry+carry); - delay_carry=0; - if (w0->w[rn+i]>=mr_mip->base) - { - w0->w[rn+i]-=mr_mip->base; - delay_carry=1; - } - } -#endif - w0->w[rn2]=delay_carry; - w0->len=rn2+1; - mr_shift(_MIPP_ w0,(-rn),w0); - mr_lzero(w0); - - if (mr_compare(w0,modulus)>=0) mr_psub(_MIPP_ w0,modulus,w0); - copy(w0,y); - MR_OUT -} - -/* "Complex" method for ZZn2 squaring */ - -void nres_complex(_MIPD_ big a,big b,big r,big i) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - MR_IN(225) - - if (mr_mip->NO_CARRY && mr_mip->qnr==-1) - { /* if modulus is small enough we can ignore carries, and use simple addition and subtraction */ - /* recall that Montgomery reduction can cope as long as product is less than pR */ -#ifdef MR_COMBA -#ifdef MR_COUNT_OPS -fpa+=3; -#endif - if (mr_mip->ACTIVE) - { - comba_add(a,b,mr_mip->w1); - comba_add(a,mr_mip->modulus,mr_mip->w2); /* a-b is p+a-b */ - comba_sub(mr_mip->w2,b,mr_mip->w2); - comba_add(a,a,r); - } - else - { -#endif - mr_padd(_MIPP_ a,b,mr_mip->w1); - mr_padd(_MIPP_ a,mr_mip->modulus,mr_mip->w2); - mr_psub(_MIPP_ mr_mip->w2,b,mr_mip->w2); - mr_padd(_MIPP_ a,a,r); -#ifdef MR_COMBA - } -#endif - nres_modmult(_MIPP_ r,b,i); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w2,r); - } - else - { - nres_modadd(_MIPP_ a,b,mr_mip->w1); - nres_modsub(_MIPP_ a,b,mr_mip->w2); - - if (mr_mip->qnr==-2) - nres_modsub(_MIPP_ mr_mip->w2,b,mr_mip->w2); - - nres_modmult(_MIPP_ a,b,i); - nres_modmult(_MIPP_ mr_mip->w1,mr_mip->w2,r); - - if (mr_mip->qnr==-2) - nres_modadd(_MIPP_ r,i,r); - - nres_modadd(_MIPP_ i,i,i); - } - MR_OUT -} - -#ifndef MR_NO_LAZY_REDUCTION - -/* - -Lazy reduction technique for zzn2 multiplication - competitive if Reduction is more -expensive that Multiplication. This is true for pairing-based crypto. Note that -Lazy reduction can also be used with Karatsuba! Uses w1, w2, w5, and w6. - -Reduction poly is X^2-D=0 - -(a0+a1.X).(b0+b1.X) = (a0.b0 + D.a1.b1) + (a1.b0+a0.b1).X - -Karatsuba - - (a0.b0+D.a1.b1) + ((a0+a1)(b0+b1) - a0.b0 - a1.b1).X -*/ - -void nres_lazy(_MIPD_ big a0,big a1,big b0,big b1,big r,big i) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - mr_mip->check=OFF; -#ifdef MR_COUNT_OPS -fpc+=3; -fpa+=5; -if (mr_mip->qnr==-2) fpa++; -#endif - -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - comba_mult(a0,b0,mr_mip->w0); - comba_mult(a1,b1,mr_mip->w5); - } - else - { -#endif -#ifdef MR_KCM - if (mr_mip->ACTIVE) - { - kcm_mul(_MIPP_ a1,b1,mr_mip->w5); /* this destroys w0! */ - kcm_mul(_MIPP_ a0,b0,mr_mip->w0); - } - else - { -#endif - MR_IN(151) - multiply(_MIPP_ a0,b0,mr_mip->w0); - multiply(_MIPP_ a1,b1,mr_mip->w5); -#ifdef MR_COMBA - } -#endif -#ifdef MR_KCM - } -#endif - - if (mr_mip->NO_CARRY && mr_mip->qnr==-1) - { /* if modulus is small enough we can ignore carries, and use simple addition and subtraction */ -#ifdef MR_COMBA -#ifdef MR_COUNT_OPS -fpa+=2; -#endif - if (mr_mip->ACTIVE) - { - comba_double_add(mr_mip->w0,mr_mip->w5,mr_mip->w6); - comba_add(a0,a1,mr_mip->w1); - comba_add(b0,b1,mr_mip->w2); - } - else - { -#endif - mr_padd(_MIPP_ mr_mip->w0,mr_mip->w5,mr_mip->w6); - mr_padd(_MIPP_ a0,a1,mr_mip->w1); - mr_padd(_MIPP_ b0,b1,mr_mip->w2); -#ifdef MR_COMBA - } -#endif - } - else - { - nres_double_modadd(_MIPP_ mr_mip->w0,mr_mip->w5,mr_mip->w6); /* w6 = a0.b0+a1.b1 */ - if (mr_mip->qnr==-2) - nres_double_modadd(_MIPP_ mr_mip->w5,mr_mip->w5,mr_mip->w5); - nres_modadd(_MIPP_ a0,a1,mr_mip->w1); - nres_modadd(_MIPP_ b0,b1,mr_mip->w2); - } - nres_double_modsub(_MIPP_ mr_mip->w0,mr_mip->w5,mr_mip->w0); /* r = a0.b0+D.a1.b1 */ - -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - comba_redc(_MIPP_ mr_mip->w0,r); - comba_mult(mr_mip->w1,mr_mip->w2,mr_mip->w0); - } - else - { -#endif -#ifdef MR_KCM - if (mr_mip->ACTIVE) - { - kcm_redc(_MIPP_ mr_mip->w0,r); - kcm_mul(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w0); - } - else - { -#endif - redc(_MIPP_ mr_mip->w0,r); - multiply(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w0); /* w0=(a0+a1)*(b0+b1) */ -#ifdef MR_COMBA - } -#endif -#ifdef MR_KCM - } -#endif - - if (mr_mip->NO_CARRY && mr_mip->qnr==-1) - { -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - comba_double_sub(mr_mip->w0,mr_mip->w6,mr_mip->w0); - else -#endif - mr_psub(_MIPP_ mr_mip->w0,mr_mip->w6,mr_mip->w0); - } - else - nres_double_modsub(_MIPP_ mr_mip->w0,mr_mip->w6,mr_mip->w0); /* (a0+a1)*(b0+b1) - w6 */ - -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - comba_redc(_MIPP_ mr_mip->w0,i); - } - else - { -#endif -#ifdef MR_KCM - if (mr_mip->ACTIVE) - { - kcm_redc(_MIPP_ mr_mip->w0,i); - } - else - { -#endif - redc(_MIPP_ mr_mip->w0,i); - MR_OUT -#ifdef MR_COMBA - } -#endif -#ifdef MR_KCM - } -#endif - - mr_mip->check=ON; - -} - -#endif - -#ifndef MR_STATIC - -void nres_dotprod(_MIPD_ int n,big *x,big *y,big w) -{ - int i; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - if (mr_mip->ERNUM) return; - MR_IN(120) - mr_mip->check=OFF; - zero(mr_mip->w7); - for (i=0;iw0); - mr_padd(_MIPP_ mr_mip->w7,mr_mip->w0,mr_mip->w7); - } - copy(mr_mip->pR,mr_mip->w6); - /* w6 = p.R */ - divide(_MIPP_ mr_mip->w7,mr_mip->w6,mr_mip->w6); - redc(_MIPP_ mr_mip->w7,w); - - mr_mip->check=ON; - MR_OUT -} - -#endif - -void nres_negate(_MIPD_ big x, big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (size(x)==0) - { - zero(w); - return; - } -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - comba_negate(_MIPP_ x,w); - return; - } - else - { -#endif - if (mr_mip->ERNUM) return; - - MR_IN(92) - mr_psub(_MIPP_ mr_mip->modulus,x,w); - MR_OUT - -#ifdef MR_COMBA - } -#endif - -} - -void nres_div2(_MIPD_ big x,big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(198) - copy(x,mr_mip->w1); - if (remain(_MIPP_ mr_mip->w1,2)!=0) - add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); - subdiv(_MIPP_ mr_mip->w1,2,mr_mip->w1); - copy(mr_mip->w1,w); - - MR_OUT -} - -void nres_div3(_MIPD_ big x,big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(199) - copy(x,mr_mip->w1); - while (remain(_MIPP_ mr_mip->w1,3)!=0) - add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); - subdiv(_MIPP_ mr_mip->w1,3,mr_mip->w1); - copy(mr_mip->w1,w); - - MR_OUT -} - -void nres_div5(_MIPD_ big x,big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(208) - copy(x,mr_mip->w1); - while (remain(_MIPP_ mr_mip->w1,5)!=0) - add(_MIPP_ mr_mip->w1,mr_mip->modulus,mr_mip->w1); - subdiv(_MIPP_ mr_mip->w1,5,mr_mip->w1); - copy(mr_mip->w1,w); - - MR_OUT -} - -/* mod pR addition and subtraction */ -#ifndef MR_NO_LAZY_REDUCTION - -void nres_double_modadd(_MIPD_ big x,big y,big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_COMBA - - if (mr_mip->ACTIVE) - { - comba_double_modadd(_MIPP_ x,y,w); - return; - } - else - { -#endif - - if (mr_mip->ERNUM) return; - MR_IN(153) - - mr_padd(_MIPP_ x,y,w); - if (mr_compare(w,mr_mip->pR)>=0) - mr_psub(_MIPP_ w,mr_mip->pR,w); - - MR_OUT -#ifdef MR_COMBA - } -#endif -} - -void nres_double_modsub(_MIPD_ big x,big y,big w) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_COMBA - - if (mr_mip->ACTIVE) - { - comba_double_modsub(_MIPP_ x,y,w); - return; - } - else - { -#endif - - if (mr_mip->ERNUM) return; - MR_IN(154) - - if (mr_compare(x,y)>=0) - mr_psub(_MIPP_ x,y,w); - else - { - mr_psub(_MIPP_ y,x,w); - mr_psub(_MIPP_ mr_mip->pR,w,w); - } - - MR_OUT -#ifdef MR_COMBA - } -#endif -} - -#endif - -void nres_modadd(_MIPD_ big x,big y,big w) -{ /* modular addition */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_COUNT_OPS -fpa++; -#endif -#ifdef MR_COMBA - - if (mr_mip->ACTIVE) - { - comba_modadd(_MIPP_ x,y,w); - return; - } - else - { -#endif - if (mr_mip->ERNUM) return; - - MR_IN(90) - mr_padd(_MIPP_ x,y,w); - if (mr_compare(w,mr_mip->modulus)>=0) mr_psub(_MIPP_ w,mr_mip->modulus,w); - - MR_OUT -#ifdef MR_COMBA - } -#endif -} - -void nres_modsub(_MIPD_ big x,big y,big w) -{ /* modular subtraction */ - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif -#ifdef MR_COUNT_OPS -fpa++; -#endif -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - comba_modsub(_MIPP_ x,y,w); - return; - } - else - { -#endif - if (mr_mip->ERNUM) return; - - MR_IN(91) - - if (mr_compare(x,y)>=0) - mr_psub(_MIPP_ x,y,w); - else - { - mr_psub(_MIPP_ y,x,w); - mr_psub(_MIPP_ mr_mip->modulus,w,w); - } - - MR_OUT -#ifdef MR_COMBA - } -#endif - -} - -int nres_moddiv(_MIPD_ big x,big y,big w) -{ /* Modular division using n-residues w=x/y mod n */ - int gcd; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return 0; - - MR_IN(85) - - if (x==y) - { /* Illegal parameter usage */ - mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - MR_OUT - - return 0; - } - redc(_MIPP_ y,mr_mip->w6); - gcd=invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); - - if (gcd!=1) zero(w); /* fails silently and returns 0 */ - else - { - nres(_MIPP_ mr_mip->w6,mr_mip->w6); - nres_modmult(_MIPP_ x,mr_mip->w6,w); - /* mad(_MIPP_ x,mr_mip->w6,x,mr_mip->modulus,mr_mip->modulus,w); */ - } - MR_OUT - return gcd; -} - -void nres_premult(_MIPD_ big x,int k,big w) -{ /* multiply n-residue by small ordinary integer */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - int sign=0; - if (k==0) - { - zero(w); - return; - } - if (k<0) - { - k=-k; - sign=1; - } - if (mr_mip->ERNUM) return; - - MR_IN(102) - - if (k<=6) - { - switch (k) - { - case 1: copy(x,w); - break; - case 2: nres_modadd(_MIPP_ x,x,w); - break; - case 3: - nres_modadd(_MIPP_ x,x,mr_mip->w0); - nres_modadd(_MIPP_ x,mr_mip->w0,w); - break; - case 4: - nres_modadd(_MIPP_ x,x,w); - nres_modadd(_MIPP_ w,w,w); - break; - case 5: - nres_modadd(_MIPP_ x,x,mr_mip->w0); - nres_modadd(_MIPP_ mr_mip->w0,mr_mip->w0,mr_mip->w0); - nres_modadd(_MIPP_ x,mr_mip->w0,w); - break; - case 6: - nres_modadd(_MIPP_ x,x,w); - nres_modadd(_MIPP_ w,w,mr_mip->w0); - nres_modadd(_MIPP_ w,mr_mip->w0,w); - break; - } - if (sign==1) nres_negate(_MIPP_ w,w); - MR_OUT - return; - } - - mr_pmul(_MIPP_ x,(mr_small)k,mr_mip->w0); -#ifdef MR_COMBA -#ifdef MR_SPECIAL - comba_redc(_MIPP_ mr_mip->w0,w); -#else - divide(_MIPP_ mr_mip->w0,mr_mip->modulus,mr_mip->modulus); - copy(mr_mip->w0,w); -#endif -#else - divide(_MIPP_ mr_mip->w0,mr_mip->modulus,mr_mip->modulus); - copy(mr_mip->w0,w); -#endif - - if (sign==1) nres_negate(_MIPP_ w,w); - - MR_OUT -} - -void nres_modmult(_MIPD_ big x,big y,big w) -{ /* Modular multiplication using n-residues w=x*y mod n */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if ((x==NULL || x->len==0) && x==w) return; - if ((y==NULL || y->len==0) && y==w) return; - if (y==NULL || x==NULL || x->len==0 || y->len==0) - { - zero(w); - return; - } -#ifdef MR_COUNT_OPS -fpc++; -#endif -#ifdef MR_COMBA - if (mr_mip->ACTIVE) - { - if (x==y) comba_square(x,mr_mip->w0); - else comba_mult(x,y,mr_mip->w0); - comba_redc(_MIPP_ mr_mip->w0,w); - } - else - { -#endif -#ifdef MR_KCM - if (mr_mip->ACTIVE) - { - if (x==y) kcm_sqr(_MIPP_ x,mr_mip->w0); - else kcm_mul(_MIPP_ x,y,mr_mip->w0); - kcm_redc(_MIPP_ mr_mip->w0,w); - } - else - { -#endif -#ifdef MR_PENTIUM - if (mr_mip->ACTIVE) - { - if (x==y) fastmodsquare(_MIPP_ x,w); - else fastmodmult(_MIPP_ x,y,w); - } - else - { -#endif - if (mr_mip->ERNUM) return; - - MR_IN(83) - - mr_mip->check=OFF; - multiply(_MIPP_ x,y,mr_mip->w0); - redc(_MIPP_ mr_mip->w0,w); - mr_mip->check=ON; - MR_OUT -#ifdef MR_COMBA -} -#endif -#ifdef MR_KCM -} -#endif -#ifdef MR_PENTIUM -} -#endif - -} - -/* Montgomery's trick for finding multiple * - * simultaneous modular inverses * - * Based on the observation that * - * 1/x = yz*(1/xyz) * - * 1/y = xz*(1/xyz) * - * 1/z = xy*(1/xyz) * - * Why are all of Peter Montgomery's clever * - * algorithms always described as "tricks" ??*/ - -BOOL nres_double_inverse(_MIPD_ big x,big y,big w,big z) -{ /* find y=1/x mod n and z=1/w mod n */ - /* 1/x = w/xw, and 1/w = x/xw */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - MR_IN(145) - - nres_modmult(_MIPP_ x,w,mr_mip->w6); /* xw */ - - if (size(mr_mip->w6)==0) - { - mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - MR_OUT - return FALSE; - } - redc(_MIPP_ mr_mip->w6,mr_mip->w6); - redc(_MIPP_ mr_mip->w6,mr_mip->w6); - invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); - - nres_modmult(_MIPP_ w,mr_mip->w6,mr_mip->w5); - nres_modmult(_MIPP_ x,mr_mip->w6,z); - copy(mr_mip->w5,y); - - MR_OUT - return TRUE; -} - -BOOL nres_multi_inverse(_MIPD_ int m,big *x,big *w) -{ /* find w[i]=1/x[i] mod n, for i=0 to m-1 * - * x and w MUST be distinct */ - int i; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (m==0) return TRUE; - if (m<0) return FALSE; - MR_IN(118) - - if (x==w) - { - mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - MR_OUT - return FALSE; - } - - if (m==1) - { - copy(mr_mip->one,w[0]); - nres_moddiv(_MIPP_ w[0],x[0],w[0]); - MR_OUT - return TRUE; - } - - convert(_MIPP_ 1,w[0]); - copy(x[0],w[1]); - for (i=2;iw6); /* y=x[0]*x[1]*x[2]....x[m-1] */ - if (size(mr_mip->w6)==0) - { - mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - MR_OUT - return FALSE; - } - - redc(_MIPP_ mr_mip->w6,mr_mip->w6); - redc(_MIPP_ mr_mip->w6,mr_mip->w6); - - invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); - -/* Now y=1/y */ - - copy(x[m-1],mr_mip->w5); - nres_modmult(_MIPP_ w[m-1],mr_mip->w6,w[m-1]); - - for (i=m-2;;i--) - { - if (i==0) - { - nres_modmult(_MIPP_ mr_mip->w5,mr_mip->w6,w[0]); - break; - } - nres_modmult(_MIPP_ w[i],mr_mip->w5,w[i]); - nres_modmult(_MIPP_ w[i],mr_mip->w6,w[i]); - nres_modmult(_MIPP_ mr_mip->w5,x[i],mr_mip->w5); - } - - MR_OUT - return TRUE; -} - -/* initialise elliptic curve */ - -void ecurve_init(_MIPD_ big a,big b,big p,int type) -{ /* Initialize the active ecurve * - * Asize indicate size of A * - * Bsize indicate size of B */ - int as; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return; - - MR_IN(93) - -#ifndef MR_NO_SS - mr_mip->SS=FALSE; /* no special support for super-singular curves */ -#endif - - prepare_monty(_MIPP_ p); - - mr_mip->Asize=size(a); - if (mr_abs(mr_mip->Asize)==MR_TOOBIG) - { - if (mr_mip->Asize>=0) - { /* big positive number - check it isn't minus something small */ - copy(a,mr_mip->w1); - divide(_MIPP_ mr_mip->w1,p,p); - subtract(_MIPP_ p,mr_mip->w1,mr_mip->w1); - as=size(mr_mip->w1); - if (asAsize=-as; - } - } - nres(_MIPP_ a,mr_mip->A); - - mr_mip->Bsize=size(b); - if (mr_abs(mr_mip->Bsize)==MR_TOOBIG) - { - if (mr_mip->Bsize>=0) - { /* big positive number - check it isn't minus something small */ - copy(b,mr_mip->w1); - divide(_MIPP_ mr_mip->w1,p,p); - subtract(_MIPP_ p,mr_mip->w1,mr_mip->w1); - as=size(mr_mip->w1); - if (asBsize=-as; - } - } - - nres(_MIPP_ b,mr_mip->B); -#ifdef MR_EDWARDS - mr_mip->coord=MR_PROJECTIVE; /* only type supported for Edwards curves */ -#else -#ifndef MR_AFFINE_ONLY - if (type==MR_BEST) mr_mip->coord=MR_PROJECTIVE; - else mr_mip->coord=type; -#else - if (type==MR_PROJECTIVE) - mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); -#endif -#endif - MR_OUT - return; -} diff --git a/crypto/sm2/miracl/mrmuldv.c b/crypto/sm2/miracl/mrmuldv.c deleted file mode 100644 index 0810017d..00000000 --- a/crypto/sm2/miracl/mrmuldv.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Standard C version of mrmuldv.c */ - -#include -#include - -mr_small muldiv(mr_small a,mr_small b,mr_small c,mr_small m,mr_small *rp) -{ - mr_small q; - mr_large dble=(mr_large)a*b+c; - q=(mr_small)MR_LROUND(dble/m); - *rp=(mr_small)(dble-(mr_large)q*m); - return q; -} - -#ifdef MR_FP_ROUNDING - -mr_small imuldiv(mr_small a,mr_small b,mr_small c,mr_small m,mr_large im,mr_small *rp) -{ - mr_small q; - mr_large dble=(mr_large)a*b+c; - q=(mr_small)MR_LROUND(dble*im); - *rp=(mr_small)(dble-(mr_large)q*m); - return q; -} - -#endif - - -#ifndef MR_NOFULLWIDTH - -mr_small muldvm(mr_small a,mr_small c,mr_small m,mr_small *rp) -{ - mr_small q; - union doubleword dble; - dble.h[MR_BOT]=c; - dble.h[MR_TOP]=a; - q=(mr_small)(dble.d/m); - *rp=(mr_small)(dble.d-(mr_large)q*m); - return q; -} - -mr_small muldvd(mr_small a,mr_small b,mr_small c,mr_small *rp) -{ - union doubleword dble; - dble.d=(mr_large)a*b+c; - *rp=dble.h[MR_BOT]; - return dble.h[MR_TOP]; -} - -void muldvd2(mr_small a,mr_small b,mr_small *c,mr_small *rp) -{ - union doubleword dble; - dble.d=(mr_large)a*b+*c+*rp; - *rp=dble.h[MR_BOT]; - *c=dble.h[MR_TOP]; -} - -#endif - diff --git a/crypto/sm2/miracl/mrsroot.c b/crypto/sm2/miracl/mrsroot.c deleted file mode 100644 index ccf6d56b..00000000 --- a/crypto/sm2/miracl/mrsroot.c +++ /dev/null @@ -1,188 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL method for modular square root - * mrsroot.c - * - * Siguna Mueller's O(lg(p)^3) algorithm, Designs Codes and Cryptography, 2004 - * - * This is a little slower for p=1 mod 4 primes, but its not time critical, and - * more importantly it doesn't pull in the large powmod code into elliptic curve programs - * It does require code from mrjack.c and mrlucas.c - * - * If p=3 mod 4, then sqrt(a)=a^[(p+1)/4] mod p. Note that for many elliptic curves - * (p+1)/4 has very low hamming weight. - * - * (was sqrt(a) = V_{(p+1)/4}(a+1/a,1)/(1+1/a)) - * - * Mueller's method is also very simple, uses very little memory, and it works just fine for p=1 mod 8 primes - * (for example the "annoying" NIST modulus 2^224-2^96+1) - * Also doesn't waste time on non-squares, as a jacobi test is done first - * - * If you know that the prime is 3 mod 4, and you know that x is almost certainly a QR - * then the jacobi-dependent code can be deleted with some space savings. - * - * NOTE - IF p IS NOT PRIME, THIS CODE WILL FAIL SILENTLY! - * - */ - -#include -#include - -BOOL nres_sqroot(_MIPD_ big x,big w) -{ /* w=sqrt(x) mod p. This depends on p being prime! */ - int t,js; - -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - copy(x,w); - if (size(w)==0) return TRUE; - - MR_IN(100) - - redc(_MIPP_ w,w); /* get it back into normal form */ - - if (size(w)==1) /* square root of 1 is 1 */ - { - nres(_MIPP_ w,w); - MR_OUT - return TRUE; - } - - if (size(w)==4) /* square root of 4 is 2 */ - { - convert(_MIPP_ 2,w); - nres(_MIPP_ w,w); - MR_OUT - return TRUE; - } - - if (jack(_MIPP_ w,mr_mip->modulus)!=1) - { /* Jacobi test */ - zero(w); - MR_OUT - return FALSE; - } - - js=mr_mip->pmod8%4-2; /* 1 mod 4 or 3 mod 4 prime? */ - - incr(_MIPP_ mr_mip->modulus,js,mr_mip->w10); - subdiv(_MIPP_ mr_mip->w10,4,mr_mip->w10); /* (p+/-1)/4 */ - - if (js==1) - { /* 3 mod 4 primes - do a quick and dirty sqrt(x)=x^(p+1)/4 mod p */ - nres(_MIPP_ w,mr_mip->w2); - copy(mr_mip->one,w); - forever - { /* Simple Right-to-Left exponentiation */ - - if (mr_mip->user!=NULL) (*mr_mip->user)(); - if (subdiv(_MIPP_ mr_mip->w10,2,mr_mip->w10)!=0) - nres_modmult(_MIPP_ w,mr_mip->w2,w); - if (mr_mip->ERNUM || size(mr_mip->w10)==0) break; - nres_modmult(_MIPP_ mr_mip->w2,mr_mip->w2,mr_mip->w2); - } - - /* nres_moddiv(_MIPP_ mr_mip->one,w,mr_mip->w11); - nres_modadd(_MIPP_ mr_mip->w11,w,mr_mip->w3); - nres_lucas(_MIPP_ mr_mip->w3,mr_mip->w10,w,w); - nres_modadd(_MIPP_ mr_mip->w11,mr_mip->one,mr_mip->w11); - nres_moddiv(_MIPP_ w,mr_mip->w11,w); */ - } - else - { /* 1 mod 4 primes */ - for (t=1; ;t++) - { /* t=1.5 on average */ - if (t==1) copy(w,mr_mip->w4); - else - { - premult(_MIPP_ w,t,mr_mip->w4); - divide(_MIPP_ mr_mip->w4,mr_mip->modulus,mr_mip->modulus); - premult(_MIPP_ mr_mip->w4,t,mr_mip->w4); - divide(_MIPP_ mr_mip->w4,mr_mip->modulus,mr_mip->modulus); - } - - decr(_MIPP_ mr_mip->w4,4,mr_mip->w1); - if (jack(_MIPP_ mr_mip->w1,mr_mip->modulus)==js) break; - if (mr_mip->ERNUM) break; - } - - decr(_MIPP_ mr_mip->w4,2,mr_mip->w3); - nres(_MIPP_ mr_mip->w3,mr_mip->w3); - nres_lucas(_MIPP_ mr_mip->w3,mr_mip->w10,w,w); /* heavy lifting done here */ - if (t!=1) - { - convert(_MIPP_ t,mr_mip->w11); - nres(_MIPP_ mr_mip->w11,mr_mip->w11); - nres_moddiv(_MIPP_ w,mr_mip->w11,w); - } - } - - MR_OUT - return TRUE; -} - -BOOL sqroot(_MIPD_ big x,big p,big w) -{ /* w = sqrt(x) mod p */ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (mr_mip->ERNUM) return FALSE; - - MR_IN(101) - - if (subdivisible(_MIPP_ p,2)) - { /* p must be odd */ - zero(w); - MR_OUT - return FALSE; - } - - prepare_monty(_MIPP_ p); - nres(_MIPP_ x,w); - if (nres_sqroot(_MIPP_ w,w)) - { - redc(_MIPP_ w,w); - MR_OUT - return TRUE; - } - - zero(w); - MR_OUT - return FALSE; -} diff --git a/crypto/sm2/miracl/mrxgcd.c b/crypto/sm2/miracl/mrxgcd.c deleted file mode 100644 index 437f6e97..00000000 --- a/crypto/sm2/miracl/mrxgcd.c +++ /dev/null @@ -1,495 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL Extended Greatest Common Divisor module. - * mrxgcd.c - */ - -#include - -#ifdef MR_FP -#include -#endif - -#ifdef MR_COUNT_OPS -extern int fpx; -#endif - -#ifndef MR_USE_BINARY_XGCD - -#ifdef mr_dltype - -static mr_small qdiv(mr_large u,mr_large v) -{ /* fast division - small quotient expected. */ - mr_large lq,x=u; -#ifdef MR_FP - mr_small dres; -#endif - x-=v; - if (x=MAXBASE) return 0; - return (mr_small)lq; -} - -#else - -static mr_small qdiv(mr_small u,mr_small v) -{ /* fast division - small quotient expected */ - mr_small x=u; - x-=v; - if (xERNUM) return 0; - - MR_IN(30) - -#ifdef MR_COUNT_OPS - fpx++; -#endif - - copy(x,mr_mip->w1); - copy(y,mr_mip->w2); - s=exsign(mr_mip->w1); - insign(PLUS,mr_mip->w1); - insign(PLUS,mr_mip->w2); - convert(_MIPP_ 1,mr_mip->w3); - zero(mr_mip->w4); - last=FALSE; - a=b=c=d=0; - iter=0; - - while (size(mr_mip->w2)!=0) - { - if (b==0) - { /* update mr_mip->w1 and mr_mip->w2 */ - - divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5); - t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t; /* swap(mr_mip->w1,mr_mip->w2) */ - multiply(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w0); - add(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3); - t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t; /* swap(xd,yd) */ - iter++; - - } - else - { - - /* printf("a= %I64u b= %I64u c= %I64u d= %I64u \n",a,b,c,d); */ - - mr_pmul(_MIPP_ mr_mip->w1,c,mr_mip->w5); /* c*w1 */ - mr_pmul(_MIPP_ mr_mip->w1,a,mr_mip->w1); /* a*w1 */ - mr_pmul(_MIPP_ mr_mip->w2,b,mr_mip->w0); /* b*w2 */ - mr_pmul(_MIPP_ mr_mip->w2,d,mr_mip->w2); /* d*w2 */ - - if (!dplus) - { - mr_psub(_MIPP_ mr_mip->w0,mr_mip->w1,mr_mip->w1); /* b*w2-a*w1 */ - mr_psub(_MIPP_ mr_mip->w5,mr_mip->w2,mr_mip->w2); /* c*w1-d*w2 */ - } - else - { - mr_psub(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1); /* a*w1-b*w2 */ - mr_psub(_MIPP_ mr_mip->w2,mr_mip->w5,mr_mip->w2); /* d*w2-c*w1 */ - } - mr_pmul(_MIPP_ mr_mip->w3,c,mr_mip->w5); - mr_pmul(_MIPP_ mr_mip->w3,a,mr_mip->w3); - mr_pmul(_MIPP_ mr_mip->w4,b,mr_mip->w0); - mr_pmul(_MIPP_ mr_mip->w4,d,mr_mip->w4); - - if (a==0) copy(mr_mip->w0,mr_mip->w3); - else mr_padd(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3); - mr_padd(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w4); - } - if (mr_mip->ERNUM || size(mr_mip->w2)==0) break; - - - n=(int)mr_mip->w1->len; - if (n==1) - { - last=TRUE; - u=mr_mip->w1->w[0]; - v=mr_mip->w2->w[0]; - } - else - { - m=mr_mip->w1->w[n-1]+1; -#ifndef MR_SIMPLE_BASE - if (mr_mip->base==0) - { -#endif -#ifndef MR_NOFULLWIDTH -#ifdef mr_dltype - /* use double length type if available */ - if (n>2 && m!=0) - { /* squeeze out as much significance as possible */ - uu.h[MR_TOP]=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr); - uu.h[MR_BOT]=muldvm(sr,mr_mip->w1->w[n-3],m,&sr); - vv.h[MR_TOP]=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr); - vv.h[MR_BOT]=muldvm(sr,mr_mip->w2->w[n-3],m,&sr); - } - else - { - uu.h[MR_TOP]=mr_mip->w1->w[n-1]; - uu.h[MR_BOT]=mr_mip->w1->w[n-2]; - vv.h[MR_TOP]=mr_mip->w2->w[n-1]; - vv.h[MR_BOT]=mr_mip->w2->w[n-2]; - if (n==2) last=TRUE; - } - - u=uu.d; - v=vv.d; -#else - if (m==0) - { - u=mr_mip->w1->w[n-1]; - v=mr_mip->w2->w[n-1]; - } - else - { - u=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr); - v=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr); - } -#endif -#endif -#ifndef MR_SIMPLE_BASE - } - else - { -#ifdef mr_dltype - if (n>2) - { /* squeeze out as much significance as possible */ - u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr); - u=u*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w1->w[n-3],m,&sr); - v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr); - v=v*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w2->w[n-3],m,&sr); - } - else - { - u=(mr_large)mr_mip->base*mr_mip->w1->w[n-1]+mr_mip->w1->w[n-2]; - v=(mr_large)mr_mip->base*mr_mip->w2->w[n-1]+mr_mip->w2->w[n-2]; - last=TRUE; - } -#else - u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr); - v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr); -#endif - } -#endif - } - - dplus=TRUE; - a=1; b=0; c=0; d=1; - - forever - { /* work only with most significant piece */ - if (last) - { - if (v==0) break; - q=qdiv(u,v); - if (q==0) break; - } - else - { - if (dplus) - { - if ((mr_small)(v-c)==0 || (mr_small)(v+d)==0) break; - - q=qdiv(u+a,v-c); - - if (q==0) break; - - if (q!=qdiv(u-b,v+d)) break; - } - else - { - if ((mr_small)(v+c)==0 || (mr_small)(v-d)==0) break; - q=qdiv(u-a,v+c); - if (q==0) break; - if (q!=qdiv(u+b,v-d)) break; - } - } - - if (q==1) - { - if ((mr_small)(b+d) >= MAXBASE) break; - r=a+c; a=c; c=r; - r=b+d; b=d; d=r; - lr=u-v; u=v; v=lr; - } - else - { - if (q>=MR_DIV(MAXBASE-b,d)) break; - r=a+q*c; a=c; c=r; - r=b+q*d; b=d; d=r; - lr=u-q*v; u=v; v=lr; - } - iter++; - dplus=!dplus; - } - iter%=2; - - } - - if (s==MINUS) iter++; - if (iter%2==1) subtract(_MIPP_ y,mr_mip->w3,mr_mip->w3); - - if (xd!=yd) - { - negify(x,mr_mip->w2); - mad(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w1,y,mr_mip->w4,mr_mip->w4); - copy(mr_mip->w4,yd); - } - copy(mr_mip->w3,xd); - if (z!=xd && z!=yd) copy(mr_mip->w1,z); - - MR_OUT - return (size(mr_mip->w1)); -} - -int invmodp(_MIPD_ big x,big y,big z) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - int gcd; - - MR_IN(213); - gcd=xgcd(_MIPP_ x,y,z,z,z); - MR_OUT - return gcd; -} - -#else - -/* much smaller, much slower binary inversion algorithm */ -/* fails silently if a is not co-prime to p */ - -/* experimental! At least 3 times slower than standard method.. */ - -int invmodp(_MIPD_ big a,big p,big z) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - big u,v,x1,x2; - - MR_IN(213); - - u=mr_mip->w1; v=mr_mip->w2; x1=mr_mip->w3; x2=mr_mip->w4; - copy(a,u); - copy(p,v); - convert(_MIPP_ 1,x1); - zero(x2); - - while (size(u)!=1 && size(v)!=1) - { - while (remain(_MIPP_ u,2)==0) - { - subdiv(_MIPP_ u,2,u); - if (remain(_MIPP_ x1,2)!=0) add(_MIPP_ x1,p,x1); - subdiv(_MIPP_ x1,2,x1); - } - while (remain(_MIPP_ v,2)==0) - { - subdiv(_MIPP_ v,2,v); - if (remain(_MIPP_ x2,2)!=0) add(_MIPP_ x2,p,x2); - subdiv(_MIPP_ x2,2,x2); - } - if (compare(u,v)>=0) - { - mr_psub(_MIPP_ u,v,u); - subtract(_MIPP_ x1,x2,x1); - } - else - { - mr_psub(_MIPP_ v,u,v); - subtract(_MIPP_ x2,x1,x2); - } - } - if (size(u)==1) copy(x1,z); - else copy(x2,z); - - if (size(z)<0) add(_MIPP_ z,p,z); - - MR_OUT - return 1; /* note - no checking that gcd=1 */ -} - -#endif - -#ifndef MR_STATIC - -/* Montgomery's method for multiple - simultaneous modular inversions */ - -BOOL double_inverse(_MIPD_ big n,big x,big y,big w,big z) -{ -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - - MR_IN(146) - - mad(_MIPP_ x,w,w,n,n,mr_mip->w6); - if (size(mr_mip->w6)==0) - { - mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - MR_OUT - return FALSE; - } - invmodp(_MIPP_ mr_mip->w6,n,mr_mip->w6); - - mad(_MIPP_ w,mr_mip->w6,w,n,n,y); - mad(_MIPP_ x,mr_mip->w6,x,n,n,z); - - MR_OUT - return TRUE; -} - -BOOL multi_inverse(_MIPD_ int m,big *x,big n,big *w) -{ /* find w[i]=1/x[i] mod n, for i=0 to m-1 * - * x and w MUST be distinct */ - int i; -#ifdef MR_OS_THREADS - miracl *mr_mip=get_mip(); -#endif - if (m==0) return TRUE; - if (m<0) return FALSE; - - MR_IN(25) - - if (x==w) - { - mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS); - MR_OUT - return FALSE; - } - if (m==1) - { - invmodp(_MIPP_ x[0],n,w[0]); - MR_OUT - return TRUE; - } - - convert(_MIPP_ 1,w[0]); - copy(x[0],w[1]); - for (i=2;iw6); /* y=x[0]*x[1]*x[2]....x[m-1] */ - if (size(mr_mip->w6)==0) - { - mr_berror(_MIPP_ MR_ERR_DIV_BY_ZERO); - MR_OUT - return FALSE; - } - - invmodp(_MIPP_ mr_mip->w6,n,mr_mip->w6); - -/* Now y=1/y */ - - copy(x[m-1],mr_mip->w5); - mad(_MIPP_ w[m-1],mr_mip->w6,mr_mip->w6,n,n,w[m-1]); - - for (i=m-2;;i--) - { - if (i==0) - { - mad(_MIPP_ mr_mip->w5,mr_mip->w6,mr_mip->w6,n,n,w[0]); - break; - } - mad(_MIPP_ w[i],mr_mip->w5,w[i],n,n,w[i]); - mad(_MIPP_ w[i],mr_mip->w6,w[i],n,n,w[i]); - mad(_MIPP_ mr_mip->w5,x[i],x[i],n,n,mr_mip->w5); - } - - MR_OUT - return TRUE; -} - -#endif diff --git a/crypto/sm2/sm2_standard_enc.c b/crypto/sm2/sm2_standard_enc.c deleted file mode 100644 index 4cfa82a6..00000000 --- a/crypto/sm2/sm2_standard_enc.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2015 - 2017 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include -#include -#include - - -/* test if the given array is all zero */ -int Test_Null(unsigned char array[], int len) -{ - int i; - i = 0; - for (i = 0; i < len; i++) - { - if (array[i] != 0x00) - return 0; - } - return 1; -} - - -/* sm2 encryption */ -int SM2_standard_encrypt(unsigned char* randK, epoint *pubKey, unsigned char M[], int klen, unsigned char C[]) -{ - big C1x, C1y, x2, y2, rand; - epoint *C1, *kP, *S; - int i; - i = 0; - unsigned char x2y2[SM2_NUMWORD * 2] = {0}; - SM3_STATE md; - C1x = mirvar(0); - C1y = mirvar(0); - x2 = mirvar(0); - y2 = mirvar(0); - rand = mirvar(0); - C1 = epoint_init(); - kP = epoint_init(); - S = epoint_init(); - - //step2. calculate C1 = [k]G = (rGx, rGy) - bytes_to_big(SM2_NUMWORD, randK, rand); - ecurve_mult(rand, G, C1); //C1 = [k]G - epoint_get(C1, C1x, C1y); - big_to_bytes(SM2_NUMWORD, C1x, C, 1); - big_to_bytes(SM2_NUMWORD, C1y, C + SM2_NUMWORD, 1); - - //step3. test if S = [h]pubKey if the point at infinity - ecurve_mult(para_h, pubKey, S); - if (point_at_infinity(S)) //if S is point at infinity, return error; - return ERR_INFINITY_POINT; - - //step4. calculate [k]PB = (x2, y2) - ecurve_mult(rand, pubKey, kP); //kP = [k]P - epoint_get(kP, x2, y2); - - //step5. KDF(x2 || y2, klen) - big_to_bytes(SM2_NUMWORD, x2, x2y2, 1); - big_to_bytes(SM2_NUMWORD, y2, x2y2 + SM2_NUMWORD, 1); - SM3_kdf(x2y2, SM2_NUMWORD * 2, klen, C + SM2_NUMWORD * 3); - if (Test_Null(C + SM2_NUMWORD * 3, klen) != 0) - return ERR_ARRAY_NULL; - - //step6. C2 = M^t - for (i = 0; i < klen; i++) - { - C[SM2_NUMWORD * 3 + i] = M[i] ^ C[SM2_NUMWORD * 3 + i]; - } - - //step7. C3 = hash(x2, M, y2) - SM3_init(&md); - SM3_process(&md, x2y2, SM2_NUMWORD); - SM3_process(&md, M, klen); - SM3_process(&md, x2y2 + SM2_NUMWORD, SM2_NUMWORD); - SM3_done(&md, C + SM2_NUMWORD * 2); - return 0; -} - - -/* sm2 decryption */ -int SM2_standard_decrypt(big dB, unsigned char C[], int Clen, unsigned char M[]) -{ - SM3_STATE md; - int i; - i = 0; - unsigned char x2y2[SM2_NUMWORD * 2] = {0}; - unsigned char hash[SM2_NUMWORD] = {0}; - big C1x, C1y, x2, y2; - epoint *C1, *S, *dBC1; - C1x = mirvar(0); - C1y = mirvar(0); - x2 = mirvar(0); - y2 = mirvar(0); - C1 = epoint_init(); - S = epoint_init(); - dBC1 = epoint_init(); - - //step1. test if C1 fits the curve - bytes_to_big(SM2_NUMWORD, C, C1x); - bytes_to_big(SM2_NUMWORD, C + SM2_NUMWORD, C1y); - epoint_set(C1x, C1y, 0, C1); - i = Test_Point(C1); - if (i != 0) - return i; - - //step2. S = [h]C1 and test if S is the point at infinity - ecurve_mult(para_h, C1, S); - if (point_at_infinity(S)) // if S is point at infinity, return error; - return ERR_INFINITY_POINT; - - //step3. [dB]C1 = (x2, y2) - ecurve_mult(dB, C1, dBC1); - epoint_get(dBC1, x2, y2); - big_to_bytes(SM2_NUMWORD, x2, x2y2, 1); - big_to_bytes(SM2_NUMWORD, y2, x2y2 + SM2_NUMWORD, 1); - - //step4. t = KDF(x2 || y2, klen) - SM3_kdf(x2y2, SM2_NUMWORD * 2, Clen - SM2_NUMWORD * 3, M); - if (Test_Null(M, Clen - SM2_NUMWORD * 3) != 0) - return ERR_ARRAY_NULL; - - //step5. M = C2^t - for (i = 0; i < Clen - SM2_NUMWORD * 3; i++) - M[i] = M[i] ^ C[SM2_NUMWORD * 3 + i]; - - //step6. hash(x2, m, y2) - SM3_init(&md); - SM3_process(&md, x2y2, SM2_NUMWORD); - SM3_process(&md, M, Clen - SM2_NUMWORD * 3); - SM3_process(&md, x2y2 + SM2_NUMWORD, SM2_NUMWORD); - SM3_done(&md, hash); - if (memcmp(hash, C + SM2_NUMWORD * 2, SM2_NUMWORD) != 0) - return ERR_C3_MATCH; - else - return 0; -} - - -/* test whether the SM2 calculation is correct by comparing the result with the standard data */ -int SM2_standard_enc_selftest() -{ - int tmp, i; - tmp = 0; - i = 0; - unsigned char Cipher[115] = {0}; - unsigned char M[19] = {0}; - unsigned char kGxy[SM2_NUMWORD * 2] = {0}; - big ks, x, y; - epoint *kG; - - - //standard data - unsigned char std_priKey[32] = {0x39, 0x45, 0x20, 0x8F, 0x7B, 0x21, 0x44, 0xB1, 0x3F, 0x36, 0xE3, 0x8A, 0xC6, 0xD3, 0x9F, 0x95, - 0x88, 0x93, 0x93, 0x69, 0x28, 0x60, 0xB5, 0x1A, 0x42, 0xFB, 0x81, 0xEF, 0x4D, 0xF7, 0xC5, 0xB8}; - unsigned char std_pubKey[64] = {0x09, 0xF9, 0xDF, 0x31, 0x1E, 0x54, 0x21, 0xA1, 0x50, 0xDD, 0x7D, 0x16, 0x1E, 0x4B, 0xC5, 0xC6, - 0x72, 0x17, 0x9F, 0xAD, 0x18, 0x33, 0xFC, 0x07, 0x6B, 0xB0, 0x8F, 0xF3, 0x56, 0xF3, 0x50, 0x20, - 0xCC, 0xEA, 0x49, 0x0C, 0xE2, 0x67, 0x75, 0xA5, 0x2D, 0xC6, 0xEA, 0x71, 0x8C, 0xC1, 0xAA, 0x60, - 0x0A, 0xED, 0x05, 0xFB, 0xF3, 0x5E, 0x08, 0x4A, 0x66, 0x32, 0xF6, 0x07, 0x2D, 0xA9, 0xAD, 0x13}; - unsigned char std_rand[32] = {0x59, 0x27, 0x6E, 0x27, 0xD5, 0x06, 0x86, 0x1A, 0x16, 0x68, 0x0F, 0x3A, 0xD9, 0xC0, 0x2D, 0xCC, - 0xEF, 0x3C, 0xC1, 0xFA, 0x3C, 0xDB, 0xE4, 0xCE, 0x6D, 0x54, 0xB8, 0x0D, 0xEA, 0xC1, 0xBC, 0x21}; - unsigned char std_Message[19] = {0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, - 0x61, 0x72, 0x64}; - unsigned char std_Cipher[115] = {0x04, 0xEB, 0xFC, 0x71, 0x8E, 0x8D, 0x17, 0x98, 0x62, 0x04, 0x32, 0x26, 0x8E, 0x77, 0xFE, 0xB6, - 0x41, 0x5E, 0x2E, 0xDE, 0x0E, 0x07, 0x3C, 0x0F, 0x4F, 0x64, 0x0E, 0xCD, 0x2E, 0x14, 0x9A, 0x73, - 0xE8, 0x58, 0xF9, 0xD8, 0x1E, 0x54, 0x30, 0xA5, 0x7B, 0x36, 0xDA, 0xAB, 0x8F, 0x95, 0x0A, 0x3C, - 0x64, 0xE6, 0xEE, 0x6A, 0x63, 0x09, 0x4D, 0x99, 0x28, 0x3A, 0xFF, 0x76, 0x7E, 0x12, 0x4D, 0xF0, - 0x59, 0x98, 0x3C, 0x18, 0xF8, 0x09, 0xE2, 0x62, 0x92, 0x3C, 0x53, 0xAE, 0xC2, 0x95, 0xD3, 0x03, - 0x83, 0xB5, 0x4E, 0x39, 0xD6, 0x09, 0xD1, 0x60, 0xAF, 0xCB, 0x19, 0x08, 0xD0, 0xBD, 0x87, 0x66, - 0x21, 0x88, 0x6C, 0xA9, 0x89, 0xCA, 0x9C, 0x7D, 0x58, 0x08, 0x73, 0x07, 0xCA, 0x93, 0x09, 0x2D, - 0x65, 0x1E, 0xFA}; - mip= mirsys(1000, 16); - mip->IOBASE = 16; - x = mirvar(0); - y = mirvar(0); - ks = mirvar(0); - kG = epoint_init(); - bytes_to_big(32, std_priKey, ks); //ks is the standard private key - - - //initiate SM2 curve - SM2_standard_init(); - - //generate key pair - tmp = SM2_standard_keygeneration(ks, kG); - if (tmp != 0) - return tmp; - epoint_get(kG, x, y); - big_to_bytes(SM2_NUMWORD, x, kGxy, 1); - big_to_bytes(SM2_NUMWORD, y, kGxy + SM2_NUMWORD, 1); - if (memcmp(kGxy, std_pubKey, SM2_NUMWORD * 2) != 0) - return ERR_SELFTEST_KG; - - //encrypt data and compare the result with the standard data - tmp = SM2_standard_encrypt(std_rand, kG, std_Message, 19, Cipher); - if (tmp != 0) - return tmp; - if (memcmp(Cipher, std_Cipher, 19 + SM2_NUMWORD * 3) != 0) - return ERR_SELFTEST_ENC; - - //decrypt cipher and compare the result with the standard data - tmp = SM2_standard_decrypt(ks, Cipher, 115, M); - if (tmp != 0) - return tmp; - if (memcmp(M, std_Message, 19) != 0) - return ERR_SELFTEST_DEC; - return 0; -} diff --git a/crypto/sm2/sm2_standard_exch.c b/crypto/sm2/sm2_standard_exch.c deleted file mode 100644 index f9065df7..00000000 --- a/crypto/sm2/sm2_standard_exch.c +++ /dev/null @@ -1,491 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - - -#include -#include -#include - - -/* calculation of w */ -int SM2_w(big n) -{ - big n1; - int w = 0; - n1 = mirvar(0); - w = logb2(para_n); //approximate integer log to the base 2 of para_n - expb2(w, n1); //n1 = 2^w - if (mr_compare(para_n, n1) == 1) - w++; - if ((w % 2) == 0) - w = w / 2 - 1; - else - w = (w + 1) / 2 - 1; - return w; -} - - -/* calculation of ZA or ZB */ -void SM3_z(unsigned char ID[], unsigned short int ELAN, epoint* pubKey, unsigned char hash[]) -{ - unsigned char Px[SM2_NUMWORD] = {0}, Py[SM2_NUMWORD] = {0}; - unsigned char IDlen[2] = {0}; - big x, y; - SM3_STATE md; - - x = mirvar(0); - y = mirvar(0); - - epoint_get(pubKey, x, y); - big_to_bytes(SM2_NUMWORD, x, Px, 1); - big_to_bytes(SM2_NUMWORD, y, Py, 1); - memcpy(IDlen, &ELAN + 1, 1); - memcpy(IDlen + 1, &ELAN, 1); - SM3_init(&md); - SM3_process(&md, IDlen, 2); - SM3_process(&md, ID, ELAN / 8); - SM3_process(&md, SM2_a, SM2_NUMWORD); - SM3_process(&md, SM2_b, SM2_NUMWORD); - SM3_process(&md, SM2_Gx, SM2_NUMWORD); - SM3_process(&md, SM2_Gy, SM2_NUMWORD); - SM3_process(&md, Px, SM2_NUMWORD); - SM3_process(&md, Py, SM2_NUMWORD); - SM3_done(&md, hash); - - return; -} - - -/* calculate RA */ -int SM2_standard_keyex_init_i(big ra, epoint* RA) -{ - return SM2_standard_keygeneration(ra, RA); -} - - -/* calculate RB and a secret key */ -int SM2_standard_keyex_re_i(big rb, big dB, epoint* RA, epoint* PA, unsigned char ZA[], unsigned char ZB[], unsigned char K[], int klen, epoint* RB, epoint* V, unsigned char hash[]) -{ - SM3_STATE md; - int i = 0, w = 0; - unsigned char Z[SM2_NUMWORD * 2 + SM3_len / 4] = {0}; - unsigned char x1y1[SM2_NUMWORD * 2] = {0}; - unsigned char x2y2[SM2_NUMWORD * 2] = {0}; - unsigned char temp = 0x02; - big x1, y1, x1_, x2, y2, x2_, tmp, Vx, Vy, temp_x, temp_y; - - //mip = mirsys(1000, 16); - //mip->IOBASE = 16; - x1 = mirvar(0); - y1 = mirvar(0); - x1_ = mirvar(0); - x2 = mirvar(0); - y2 = mirvar(0); - x2_ = mirvar(0); - tmp = mirvar(0); - Vx = mirvar(0); - Vy = mirvar(0); - temp_x = mirvar(0); - temp_y = mirvar(0); - - w = SM2_w(para_n); - - //--------B2: RB = [rb]G = (x2, y2)-------- - SM2_standard_keygeneration(rb, RB); - epoint_get(RB, x2, y2); - big_to_bytes(SM2_NUMWORD, x2, x2y2, 1); - big_to_bytes(SM2_NUMWORD, y2, x2y2 + SM2_NUMWORD, 1); - - //--------B3: x2_ = 2^w + x2 & (2^w - 1)-------- - expb2(w, x2_); //x2_ = 2^w - divide(x2, x2_, tmp); //x2 = x2 mod x2_ = x2 & (2^w - 1) - add(x2_, x2, x2_); - divide(x2_, para_n, tmp); //x2_ = n mod q - - //--------B4: tB = (dB + x2_ * rB) mod n-------- - multiply(x2_, rb, x2_); - add(dB, x2_, x2_); - divide(x2_, para_n, tmp); - - //--------B5: x1_ = 2^w + x1 & (2^w - 1)-------- - if (Test_Point(RA) != 0) - return ERR_KEYEX_RA; - epoint_get(RA, x1, y1); - big_to_bytes(SM2_NUMWORD, x1, x1y1, 1); - big_to_bytes(SM2_NUMWORD, y1, x1y1 + SM2_NUMWORD, 1); - expb2(w, x1_); //x1_ = 2^w - divide(x1, x1_, tmp); //x1 = x1 mod x1_ = x1 & (2^w - 1) - add(x1_,x1, x1_); - divide(x1_, para_n, tmp); //x1_ = n mod q - - //--------B6: V = [h * tB](PA + [x1_]RA)-------- - ecurve_mult(x1_, RA, V); //v = [x1_]RA - epoint_get(V, temp_x, temp_y); - - ecurve_add(PA, V); //V = PA + V - epoint_get(V, temp_x, temp_y); - - multiply(para_h, x2_, x2_); //tB = tB * h - - ecurve_mult(x2_, V, V); - if (point_at_infinity(V) == 1) - return ERR_INFINITY_POINT; - epoint_get(V, Vx, Vy); - big_to_bytes(SM2_NUMWORD, Vx, Z, 1); - big_to_bytes(SM2_NUMWORD, Vy, Z + SM2_NUMWORD, 1); - - //------------B7:KB = KDF(VX, VY, ZA, ZB, KLEN)---------- - memcpy(Z + SM2_NUMWORD * 2, ZA, SM3_len / 8); - memcpy(Z + SM2_NUMWORD * 2 + SM3_len / 8, ZB, SM3_len / 8); - SM3_kdf(Z, SM2_NUMWORD * 2 + SM3_len / 4, klen / 8, K); - - //---------------B8:(optional)SB = hash(0x02 || Vy || HASH(Vx || ZA || ZB || x1 || y1 || x2 || y2)------------- - SM3_init(&md); - SM3_process(&md, Z, SM2_NUMWORD); - SM3_process(&md, ZA, SM3_len / 8); - SM3_process(&md, ZB, SM3_len / 8); - SM3_process(&md, x1y1, SM2_NUMWORD * 2); - SM3_process(&md, x2y2, SM2_NUMWORD * 2); - SM3_done(&md, hash); - - SM3_init(&md); - SM3_process(&md, &temp, 1); - SM3_process(&md, Z + SM2_NUMWORD, SM2_NUMWORD); - SM3_process(&md, hash, SM3_len / 8); - SM3_done(&md, hash); - - return 0; -} - - -/* initiator A calculates the secret key out of RA and RB, and calculates a hash */ -int SM2_standard_keyex_init_ii(big ra, big dA, epoint* RA, epoint* RB, epoint* PB, unsigned char ZA[], unsigned char ZB[], unsigned char SB[], unsigned char K[], int klen, unsigned char SA[]) -{ - SM3_STATE md; - int i = 0, w = 0; - unsigned char Z[SM2_NUMWORD * 2 + SM3_len / 4] = {0}; - unsigned char x1y1[SM2_NUMWORD * 2] = {0}; - unsigned char x2y2[SM2_NUMWORD * 2] = {0}; - unsigned char hash[SM2_NUMWORD], S1[SM2_NUMWORD]; - unsigned char temp[2] = {0x02, 0x03}; - big x1, y1, x1_, x2, y2, x2_, tmp, Ux, Uy, temp_x, temp_y, tA; - epoint* U; - //mip = mirsys(1000, 16); - //mip->IOBASE = 16; - - U = epoint_init(); - x1 = mirvar(0); - y1 = mirvar(0); - x1_ = mirvar(0); - x2 = mirvar(0); - y2 = mirvar(0); - x2_ = mirvar(0); - tmp = mirvar(0); - Ux = mirvar(0); - Uy = mirvar(0); - temp_x = mirvar(0); - temp_y = mirvar(0); - tA=mirvar(0); - - w = SM2_w(para_n); - epoint_get(RA, x1, y1); - big_to_bytes(SM2_NUMWORD, x1, x1y1, TRUE); - big_to_bytes(SM2_NUMWORD, y1, x1y1 + SM2_NUMWORD, TRUE); - - //--------A4: x1_ = 2^w + x2 & (2^w - 1)-------- - expb2(w, x1_); //x1_ = 2^w - divide(x1, x1_, tmp); //x1 = x1 mod x1_ = x1 & (2^w - 1) - add(x1_, x1, x1_); - divide(x1_, para_n, tmp); - - //-------- A5:tA = (dA + x1_ * rA) mod n-------- - multiply(x1_, ra, tA); - divide(tA, para_n, tmp); - add(tA, dA, tA); - divide(tA, para_n, tmp); - - //-------- A6:x2_ = 2^w + x2 & (2^w - 1)----------------- - if (Test_Point(RB) != 0) - return ERR_KEYEX_RB;////////////////////////////////// - epoint_get(RB, x2, y2); - big_to_bytes(SM2_NUMWORD, x2, x2y2, TRUE); - big_to_bytes(SM2_NUMWORD, y2, x2y2 + SM2_NUMWORD, TRUE); - expb2(w, x2_); //x2_ = 2^w - divide(x2, x2_, tmp); //x2 = x2 mod x2_ = x2 & (2^w - 1) - add(x2_, x2, x2_); - divide(x2_, para_n, tmp); - - //--------A7:U = [h * tA](PB + [x2_]RB)----------------- - ecurve_mult(x2_, RB, U); //U = [x2_]RB - epoint_get(U, temp_x, temp_y); - - ecurve_add(PB, U); //U = PB + U - epoint_get(U, temp_x, temp_y); - - multiply(para_h, tA, tA); //tA = tA * h - divide(tA, para_n, tmp); - - ecurve_mult(tA, U, U); - if (point_at_infinity(U) == 1) - return ERR_INFINITY_POINT; - epoint_get(U, Ux, Uy); - big_to_bytes(SM2_NUMWORD, Ux, Z, 1); - big_to_bytes(SM2_NUMWORD, Uy, Z + SM2_NUMWORD, 1); - - //------------A8:KA = KDF(UX, UY, ZA, ZB, KLEN)---------- - memcpy(Z + SM2_NUMWORD * 2, ZA, SM3_len / 8); - memcpy(Z + SM2_NUMWORD * 2 + SM3_len / 8, ZB, SM3_len / 8); - SM3_kdf(Z, SM2_NUMWORD * 2 + SM3_len / 4, klen / 8, K); - - //---------------A9:(optional) S1 = Hash(0x02 || Uy || Hash(Ux || ZA || ZB || x1 || y1 || x2 || y2))----------- - SM3_init (&md); - SM3_process(&md, Z, SM2_NUMWORD); - SM3_process(&md, ZA, SM3_len / 8); - SM3_process(&md, ZB, SM3_len / 8); - SM3_process(&md, x1y1, SM2_NUMWORD * 2); - SM3_process(&md, x2y2, SM2_NUMWORD * 2); - SM3_done(&md, hash); - - SM3_init(&md); - SM3_process(&md, temp, 1); - SM3_process(&md, Z + SM2_NUMWORD, SM2_NUMWORD); - SM3_process(&md, hash, SM3_len / 8); - SM3_done(&md, S1); - - //test S1 = SB? - if (memcmp(S1, SB, SM2_NUMWORD) != 0) - return ERR_EQUAL_S1SB; - - //---------------A10 SA = Hash(0x03 || yU || Hash(xU || ZA || ZB || x1 || y1 || x2 || y2))------------- - SM3_init(&md); - SM3_process(&md, &temp[1], 1); - SM3_process(&md, Z + SM2_NUMWORD, SM2_NUMWORD); - SM3_process(&md, hash, SM3_len / 8); - SM3_done(&md, SA); - - return 0; -} - - -/* (optional)Step B10: verifies the hash value received from initiator A */ -int SM2_standard_keyex_re_ii(epoint *V, epoint *RA, epoint *RB, unsigned char ZA[], unsigned char ZB[], unsigned char SA[]) -{ - big x1, y1, x2, y2, Vx, Vy; - unsigned char hash[SM2_NUMWORD], S2[SM2_NUMWORD]; - unsigned char temp = 0x03; - unsigned char xV[SM2_NUMWORD], yV[SM2_NUMWORD]; - unsigned char x1y1[SM2_NUMWORD * 2] = {0}; - unsigned char x2y2[SM2_NUMWORD * 2] = {0}; - SM3_STATE md; - - x1 = mirvar(0); - y1 = mirvar(0); - x2 = mirvar(0); - y2 = mirvar(0); - Vx = mirvar(0); - Vy = mirvar(0); - - epoint_get(RA, x1, y1); - epoint_get(RB, x2, y2); - epoint_get(V, Vx, Vy); - - big_to_bytes(SM2_NUMWORD, Vx, xV, TRUE); - big_to_bytes(SM2_NUMWORD, Vy, yV, TRUE); - big_to_bytes(SM2_NUMWORD, x1, x1y1, TRUE); - big_to_bytes(SM2_NUMWORD, y1, x1y1 + SM2_NUMWORD, TRUE); - big_to_bytes(SM2_NUMWORD, x2, x2y2, TRUE); - big_to_bytes(SM2_NUMWORD, y2, x2y2 + SM2_NUMWORD, TRUE); - - //---------------B10:(optional) S2 = Hash(0x03 || Vy || Hash(Vx || ZA || ZB || x1 || y1 || x2 || y2)) - SM3_init(&md); - SM3_process(&md, xV, SM2_NUMWORD); - SM3_process(&md, ZA, SM3_len / 8); - SM3_process(&md, ZB, SM3_len / 8); - SM3_process(&md, x1y1, SM2_NUMWORD * 2); - SM3_process(&md, x2y2, SM2_NUMWORD * 2); - SM3_done(&md, hash); - - SM3_init(&md); - SM3_process(&md, &temp, 1); - SM3_process(&md, yV, SM2_NUMWORD); - SM3_process(&md, hash, SM3_len / 8); - SM3_done(&md, S2); - - if (memcmp(S2, SA, SM3_len / 8) != 0) - return ERR_EQUAL_S2SA; - - return 0; -} - - -/* self check of SM2 key exchange */ -int SM2_standard_keyex_selftest() -{ - //standard data - unsigned char std_priKeyA[SM2_NUMWORD] = {0x81, 0xEB, 0x26, 0xE9, 0x41, 0xBB, 0x5A, 0xF1, 0x6D, 0xF1, 0x16, 0x49, 0x5F, 0x90, 0x69, 0x52, - 0x72, 0xAE, 0x2C, 0xD6, 0x3D, 0x6C, 0x4A, 0xE1, 0x67, 0x84, 0x18, 0xBE, 0x48, 0x23, 0x00, 0x29}; - unsigned char std_pubKeyA[SM2_NUMWORD * 2] = {0x16, 0x0E, 0x12, 0x89, 0x7D, 0xF4, 0xED, 0xB6, 0x1D, 0xD8, 0x12, 0xFE, 0xB9, 0x67, 0x48, - 0xFB, 0xD3, 0xCC, 0xF4, 0xFF, 0xE2, 0x6A, 0xA6, 0xF6, 0xDB, 0x95, 0x40, 0xAF, 0x49, 0xC9, - 0x42, 0x32, 0x4A, 0x7D, 0xAD, 0x08, 0xBB, 0x9A, 0x45, 0x95, 0x31, 0x69, 0x4B, 0xEB, 0x20, - 0xAA, 0x48, 0x9D, 0x66, 0x49, 0x97, 0x5E, 0x1B, 0xFC, 0xF8, 0xC4, 0x74, 0x1B, 0x78, 0xB4, - 0xB2, 0x23, 0x00, 0x7F}; - unsigned char std_randA[SM2_NUMWORD] = {0xD4, 0xDE, 0x15, 0x47, 0x4D, 0xB7, 0x4D, 0x06, 0x49, 0x1C, 0x44, 0x0D, 0x30, 0x5E, 0x01, 0x24, - 0x00, 0x99, 0x0F, 0x3E, 0x39, 0x0C, 0x7E, 0x87, 0x15, 0x3C, 0x12, 0xDB, 0x2E, 0xA6, 0x0B, 0xB3}; - unsigned char std_priKeyB[SM2_NUMWORD] = {0x78, 0x51, 0x29, 0x91, 0x7D, 0x45, 0xA9, 0xEA, 0x54, 0x37, 0xA5, 0x93, 0x56, 0xB8, 0x23, 0x38, - 0xEA, 0xAD, 0xDA, 0x6C, 0xEB, 0x19, 0x90, 0x88, 0xF1, 0x4A, 0xE1, 0x0D, 0xEF, 0xA2, 0x29, 0xB5}; - unsigned char std_pubKeyB[SM2_NUMWORD * 2] = {0x6A, 0xE8, 0x48, 0xC5, 0x7C, 0x53, 0xC7, 0xB1, 0xB5, 0xFA, 0x99, 0xEB, 0x22, 0x86, 0xAF, - 0x07, 0x8B, 0xA6, 0x4C, 0x64, 0x59, 0x1B, 0x8B, 0x56, 0x6F, 0x73, 0x57, 0xD5, 0x76, 0xF1, - 0x6D, 0xFB, 0xEE, 0x48, 0x9D, 0x77, 0x16, 0x21, 0xA2, 0x7B, 0x36, 0xC5, 0xC7, 0x99, 0x20, - 0x62, 0xE9, 0xCD, 0x09, 0xA9, 0x26, 0x43, 0x86, 0xF3, 0xFB, 0xEA, 0x54, 0xDF, 0xF6, 0x93, - 0x05, 0x62, 0x1C, 0x4D}; - unsigned char std_randB[SM2_NUMWORD] = {0x7E, 0x07, 0x12, 0x48, 0x14, 0xB3, 0x09, 0x48, 0x91, 0x25, 0xEA, 0xED, 0x10, 0x11, 0x13, 0x16, - 0x4E, 0xBF, 0x0F, 0x34, 0x58, 0xC5, 0xBD, 0x88, 0x33, 0x5C, 0x1F, 0x9D, 0x59, 0x62, 0x43, 0xD6}; - unsigned char std_IDA[16] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}; - unsigned char std_IDB[16] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}; - unsigned short int std_ENTLA = 0x0080; - unsigned short int std_ENTLB = 0x0080; - unsigned char std_ZA[SM3_len] = {0x3B, 0x85, 0xA5, 0x71, 0x79, 0xE1, 0x1E, 0x7E, 0x51, 0x3A, 0xA6, 0x22, 0x99, 0x1F, 0x2C, - 0xA7, 0x4D, 0x18, 0x07, 0xA0, 0xBD, 0x4D, 0x4B, 0x38, 0xF9, 0x09, 0x87, 0xA1, 0x7A, 0xC2, - 0x45, 0xB1}; - unsigned char std_ZB[SM3_len] = {0x79, 0xC9, 0x88, 0xD6, 0x32, 0x29, 0xD9, 0x7E, 0xF1, 0x9F, 0xE0, 0x2C, 0xA1, 0x05, 0x6E, - 0x01, 0xE6, 0xA7, 0x41, 0x1E, 0xD2, 0x46, 0x94, 0xAA, 0x8F, 0x83, 0x4F, 0x4A, 0x4A, 0xB0, - 0x22, 0xF7}; - unsigned char std_RA[SM2_NUMWORD * 2] = {0x64, 0xCE, 0xD1, 0xBD, 0xBC, 0x99, 0xD5, 0x90, 0x04, 0x9B, 0x43, 0x4D, 0x0F, 0xD7, 0x34, 0x28, - 0xCF, 0x60, 0x8A, 0x5D, 0xB8, 0xFE, 0x5C, 0xE0, 0x7F, 0x15, 0x02, 0x69, 0x40, 0xBA, 0xE4, 0x0E, - 0x37, 0x66, 0x29, 0xC7, 0xAB, 0x21, 0xE7, 0xDB, 0x26, 0x09, 0x22, 0x49, 0x9D, 0xDB, 0x11, 0x8F, - 0x07, 0xCE, 0x8E, 0xAA, 0xE3, 0xE7, 0x72, 0x0A, 0xFE, 0xF6, 0xA5, 0xCC, 0x06, 0x20, 0x70, 0xC0}; - unsigned char std_K[16] = {0x6C, 0x89, 0x34, 0x73, 0x54, 0xDE, 0x24, 0x84, 0xC6, 0x0B, 0x4A, 0xB1, 0xFD, 0xE4, 0xC6, 0xE5}; - unsigned char std_RB[SM2_NUMWORD * 2] = {0xAC, 0xC2, 0x76, 0x88, 0xA6, 0xF7, 0xB7, 0x06, 0x09, 0x8B, 0xC9, 0x1F, 0xF3, 0xAD, 0x1B, 0xFF, - 0x7D, 0xC2, 0x80, 0x2C, 0xDB, 0x14, 0xCC, 0xCC, 0xDB, 0x0A, 0x90, 0x47, 0x1F, 0x9B, 0xD7, 0x07, - 0x2F, 0xED, 0xAC, 0x04, 0x94, 0xB2, 0xFF, 0xC4, 0xD6, 0x85, 0x38, 0x76, 0xC7, 0x9B, 0x8F, 0x30, - 0x1C, 0x65, 0x73, 0xAD, 0x0A, 0xA5, 0x0F, 0x39, 0xFC, 0x87, 0x18, 0x1E, 0x1A, 0x1B, 0x46, 0xFE}; - unsigned char std_SB[SM3_len] = {0xD3, 0xA0, 0xFE, 0x15, 0xDE, 0xE1, 0x85, 0xCE, 0xAE, 0x90, 0x7A, 0x6B, 0x59, 0x5C, 0xC3, - 0x2A, 0x26, 0x6E, 0xD7, 0xB3, 0x36, 0x7E, 0x99, 0x83, 0xA8, 0x96, 0xDC, 0x32, 0xFA, 0x20, - 0xF8, 0xEB}; - int std_Klen = 128; //bit len - int temp; - - big x, y, dA, dB, rA, rB; - epoint* pubKeyA, *pubKeyB, *RA, *RB, *V; - - unsigned char hash[SM3_len / 8] = {0}; - unsigned char ZA[SM3_len / 8] = {0}; - unsigned char ZB[SM3_len / 8] = {0}; - unsigned char xy[SM2_NUMWORD * 2] = {0}; - unsigned char *KA, *KB; - unsigned char SA[SM3_len / 8]; - - KA = malloc(std_Klen / 8); - KB = malloc(std_Klen / 8); - - mip = mirsys(1000, 16); - mip->IOBASE = 16; - - x = mirvar(0); - y = mirvar(0); - dA = mirvar(0); - dB = mirvar(0); - rA = mirvar(0); - rB = mirvar(0); - pubKeyA = epoint_init(); - pubKeyB = epoint_init(); - RA = epoint_init(); - RB = epoint_init(); - V = epoint_init(); - - SM2_standard_init(); - - bytes_to_big(SM2_NUMWORD, std_priKeyA, dA); - bytes_to_big(SM2_NUMWORD, std_priKeyB, dB); - bytes_to_big(SM2_NUMWORD, std_randA, rA); - bytes_to_big(SM2_NUMWORD, std_randB, rB); - bytes_to_big(SM2_NUMWORD, std_pubKeyA, x); - bytes_to_big(SM2_NUMWORD, std_pubKeyA + SM2_NUMWORD, y); - epoint_set(x, y, 0, pubKeyA); - bytes_to_big(SM2_NUMWORD, std_pubKeyB, x); - bytes_to_big(SM2_NUMWORD, std_pubKeyB + SM2_NUMWORD, y); - epoint_set(x, y, 0, pubKeyB); - - SM3_z(std_IDA, std_ENTLA, pubKeyA, ZA); - if (memcmp(ZA, std_ZA, SM3_len / 8) != 0) - return ERR_SELFTEST_Z; - SM3_z(std_IDB, std_ENTLB, pubKeyB, ZB); - if (memcmp(ZB, std_ZB, SM3_len / 8) != 0) - return ERR_SELFTEST_Z; - - temp = SM2_standard_keyex_init_i(rA, RA); - if (temp) - return temp; - - epoint_get(RA, x, y); - big_to_bytes(SM2_NUMWORD, x, xy, 1); - big_to_bytes(SM2_NUMWORD, y, xy + SM2_NUMWORD, 1); - if (memcmp(xy, std_RA, SM2_NUMWORD * 2) != 0) - return ERR_SELFTEST_INI_I; - - temp = SM2_standard_keyex_re_i(rB, dB, RA, pubKeyA, ZA, ZB, KA, std_Klen, RB, V, hash); - if (temp) - return temp; - if (memcmp(KA, std_K, std_Klen / 8) != 0) - return ERR_SELFTEST_RES_I; - - temp = SM2_standard_keyex_init_ii(rA, dA, RA, RB, pubKeyB, ZA, ZB, hash, KB, std_Klen, SA); - if (temp) - return temp; - if (memcmp(KB, std_K, std_Klen / 8) != 0) - return ERR_SELFTEST_INI_II; - - if (SM2_standard_keyex_re_ii(V, RA, RB, ZA, ZB, SA) != 0) - return ERR_EQUAL_S2SA; - - free(KA); - free(KB); - return 0; -} diff --git a/crypto/sm2/sm2_standard_sign.c b/crypto/sm2/sm2_standard_sign.c deleted file mode 100644 index 4b447613..00000000 --- a/crypto/sm2/sm2_standard_sign.c +++ /dev/null @@ -1,349 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - - -#include -#include -#include - - - -/* test if the big x is zero */ -int Test_Zero(big x) -{ - big zero; - zero = mirvar(0); - if (mr_compare(x, zero) == 0) - return 1; - else - return 0; -} - - -/* test if the big x is order n */ -int Test_n(big x) -{ - //bytes_to_big(32, SM2_n, n); - if (mr_compare(x, para_n) == 0) - return 1; - else - return 0; -} - - -/* test if the big x belong to the range[1, n-1] */ -int Test_Range(big x) -{ - big one, decr_n; - - one = mirvar(0); - decr_n = mirvar(0); - - convert(1, one); - decr(para_n, 1, decr_n); - - if ((mr_compare(x, one) < 0) | (mr_compare(x, decr_n) > 0)) - return 1; - return 0; -} - - -/* calculate a pubKey out of a given priKey */ -int SM2_standard_sign_keygeneration(unsigned char PriKey[], unsigned char Px[], unsigned char Py[]) -{ - int i = 0; - big d, PAx, PAy; - epoint *PA; - - SM2_standard_init(); - PA = epoint_init(); - - d = mirvar(0); - PAx = mirvar(0); - PAy = mirvar(0); - - bytes_to_big(SM2_NUMWORD, PriKey, d); - - ecurve_mult(d, G, PA); - epoint_get(PA, PAx, PAy); - - big_to_bytes(SM2_NUMWORD, PAx, Px, TRUE); - big_to_bytes(SM2_NUMWORD, PAy, Py, TRUE); - i = Test_PubKey(PA); - if (i) - return i; - else - return 0; -} - - -/* SM2 signature algorithm */ -int SM2_standard_sign(unsigned char *message, int len, unsigned char ZA[], unsigned char rand[], unsigned char d[], unsigned char R[], unsigned char S[]) -{ - unsigned char hash[SM3_len / 8]; - int M_len = len + SM3_len / 8; - unsigned char *M = NULL; - int i; - - big dA, r, s, e, k, KGx, KGy; - big rem, rk, z1, z2; - epoint *KG; - - i = SM2_standard_init(); - if (i) - return i; - //initiate - dA = mirvar(0); - e = mirvar(0); - k = mirvar(0); - KGx = mirvar(0); - KGy = mirvar(0); - r = mirvar(0); - s = mirvar(0); - rem = mirvar(0); - rk = mirvar(0); - z1 = mirvar(0); - z2 = mirvar(0); - - bytes_to_big(SM2_NUMWORD, d, dA); //cinstr(dA, d); - - KG = epoint_init(); - - //step1, set M = ZA || M - M = (char *)malloc(sizeof(char)*(M_len + 1)); - memcpy(M, ZA, SM3_len / 8); - memcpy(M + SM3_len / 8, message, len); - - //step2, generate e = H(M) - SM3_256(M, M_len, hash); - bytes_to_big(SM3_len / 8, hash, e); - - //step3:generate k - bytes_to_big(SM3_len / 8, rand, k); - - //step4:calculate kG - ecurve_mult(k, G, KG); - - //step5:calculate r - epoint_get(KG, KGx, KGy); - add(e, KGx, r); - divide(r, para_n, rem); - - //judge r = 0 or n + k = n? - add(r, k, rk); - if (Test_Zero(r) | Test_n(rk)) - return ERR_GENERATE_R; - - //step6:generate s - incr(dA, 1, z1); - xgcd(z1, para_n, z1, z1, z1); - multiply(r, dA, z2); - divide(z2, para_n, rem); - subtract(k, z2, z2); - add(z2, para_n, z2); - multiply(z1, z2, s); - divide(s, para_n, rem); - - //judge s = 0? - if (Test_Zero(s)) - return ERR_GENERATE_S ; - - big_to_bytes(SM2_NUMWORD, r, R, TRUE); - big_to_bytes(SM2_NUMWORD, s, S, TRUE); - - free(M); - return 0; -} - - -/* SM2 verification algorithm */ -int SM2_standard_verify(unsigned char *message, int len, unsigned char ZA[], unsigned char Px[], unsigned char Py[], unsigned char R[], unsigned char S[]) -{ - unsigned char hash[SM3_len / 8]; - int M_len = len + SM3_len / 8; - unsigned char *M = NULL; - int i; - - big PAx, PAy, r, s, e, t, rem, x1, y1; - big RR; - epoint *PA, *sG, *tPA; - - i = SM2_standard_init(); - if (i) - return i; - - PAx = mirvar(0); - PAy = mirvar(0); - r = mirvar(0); - s = mirvar(0); - e = mirvar(0); - t = mirvar(0); - x1 = mirvar(0); - y1 = mirvar(0); - rem = mirvar(0); - RR = mirvar(0); - - PA = epoint_init(); - sG = epoint_init(); - tPA = epoint_init(); - - bytes_to_big(SM2_NUMWORD, Px, PAx); - bytes_to_big(SM2_NUMWORD, Py, PAy); - - bytes_to_big(SM2_NUMWORD, R, r); - bytes_to_big(SM2_NUMWORD, S, s); - - if (!epoint_set(PAx, PAy, 0, PA)) //initialise public key - { - return ERR_PUBKEY_INIT; - } - - //step1: test if r belong to [1, n-1] - if (Test_Range(r)) - return ERR_OUTRANGE_R; - - //step2: test if s belong to [1, n-1] - if (Test_Range(s)) - return ERR_OUTRANGE_S; - - //step3, generate M - M = (char *)malloc(sizeof(char)*(M_len + 1)); - memcpy(M, ZA, SM3_len / 8); - memcpy(M + SM3_len / 8, message, len); - - //step4, generate e = H(M) - SM3_256(M, M_len, hash); - bytes_to_big(SM3_len / 8, hash, e); - - //step5:generate t - add(r, s, t); - divide(t, para_n, rem); - - if (Test_Zero(t)) - return ERR_GENERATE_T; - - //step 6: generate(x1, y1) - ecurve_mult(s, G, sG); - ecurve_mult(t, PA, tPA); - ecurve_add(sG, tPA); - epoint_get(tPA, x1, y1); - - //step7:generate RR - add(e, x1, RR); - divide(RR, para_n, rem); - - free(M); - if (mr_compare(RR, r) == 0) - return 0; - else - return ERR_DATA_MEMCMP; -} - - -/* SM2 self check */ -int SM2_standard_selfcheck() -{ - //the private key - unsigned char dA[32] = {0x39, 0x45, 0x20, 0x8f, 0x7b, 0x21, 0x44, 0xb1, 0x3f, 0x36, 0xe3, 0x8a, 0xc6, 0xd3, 0x9f, - 0x95, 0x88, 0x93, 0x93, 0x69, 0x28, 0x60, 0xb5, 0x1a, 0x42, 0xfb, 0x81, 0xef, 0x4d, 0xf7, - 0xc5, 0xb8}; - unsigned char rand[32] = {0x59, 0x27, 0x6E, 0x27, 0xD5, 0x06, 0x86, 0x1A, 0x16, 0x68, 0x0F, 0x3A, 0xD9, 0xC0, 0x2D, - 0xCC, 0xEF, 0x3C, 0xC1, 0xFA, 0x3C, 0xDB, 0xE4, 0xCE, 0x6D, 0x54, 0xB8, 0x0D, 0xEA, 0xC1, - 0xBC, 0x21}; - //the public key - /* unsigned char xA[32] = {0x09, 0xf9, 0xdf, 0x31, 0x1e, 0x54, 0x21, 0xa1, 0x50, 0xdd, 0x7d, 0x16, 0x1e, 0x4b, 0xc5, - 0xc6, 0x72, 0x17, 0x9f, 0xad, 0x18, 0x33, 0xfc, 0x07, 0x6b, 0xb0, 0x8f, 0xf3, 0x56, 0xf3, - 0x50, 0x20}; - unsigned char yA[32] = {0xcc, 0xea, 0x49, 0x0c, 0xe2, 0x67, 0x75, 0xa5, 0x2d, 0xc6, 0xea, 0x71, 0x8c, 0xc1, 0xaa, - 0x60, 0x0a, 0xed, 0x05, 0xfb, 0xf3, 0x5e, 0x08, 0x4a, 0x66, 0x32, 0xf6, 0x07, 0x2d, 0xa9, - 0xad, 0x13};*/ - - unsigned char xA[32], yA[32]; - unsigned char r[32], s[32]; // Signature - - unsigned char IDA[16] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38}; //ASCII code of userA's identification - int IDA_len = 16; - unsigned char ENTLA[2] = {0x00, 0x80}; //the length of userA's identification, presentation in ASCII code - - unsigned char *message = "message digest"; //the message to be signed - int len = strlen(message); //the length of message - unsigned char ZA[SM3_len / 8]; //ZA = Hash(ENTLA || IDA || a || b || Gx || Gy || xA|| yA) - unsigned char Msg[210]; //210 = IDA_len + 2 + SM2_NUMWORD * 6 - - int temp; - - mip = mirsys(10000, 16); - mip->IOBASE = 16; - - temp = SM2_standard_sign_keygeneration(dA, xA, yA); - if (temp) - return temp; - - //ENTLA || IDA || a || b || Gx || Gy || xA || yA - memcpy(Msg, ENTLA, 2); - memcpy(Msg + 2, IDA, IDA_len); - memcpy(Msg + 2 + IDA_len, SM2_a, SM2_NUMWORD); - memcpy(Msg + 2 + IDA_len + SM2_NUMWORD, SM2_b, SM2_NUMWORD); - memcpy(Msg + 2 + IDA_len + SM2_NUMWORD * 2, SM2_Gx, SM2_NUMWORD); - memcpy(Msg + 2 + IDA_len + SM2_NUMWORD * 3, SM2_Gy, SM2_NUMWORD); - memcpy(Msg + 2 + IDA_len + SM2_NUMWORD * 4, xA, SM2_NUMWORD); - memcpy(Msg + 2 + IDA_len + SM2_NUMWORD * 5, yA, SM2_NUMWORD); - SM3_256(Msg, 210, ZA); - - temp = SM2_standard_sign(message, len, ZA, rand, dA, r, s); - if (temp) - return temp; - - temp = SM2_standard_verify(message, len, ZA, xA, yA, r, s); - if (temp) - return temp; - - return 0; -}