diff --git a/.travis.yml b/.travis.yml
index a618262d..29016c5b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -28,7 +28,7 @@ compiler:
- gcc
env:
- - CONFIG_OPTS="no-paillier no-serpent --prefix=/home/travis/dist/" DESTDIR="_install"
+ - CONFIG_OPTS=" --prefix=/home/travis/dist/" DESTDIR="_install"
before_script:
- env
diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info
index d87944c2..b5dc0873 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/sm9/build.info b/crypto/sm9/build.info
index 4d9af353..19bd5822 100644
--- a/crypto/sm9/build.info
+++ b/crypto/sm9/build.info
@@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=sm9_lib.c sm9_err.c sm9_asn1.c sm9_params.c \
- sm9_setup.c sm9_keygen.c sm9_sign.c sm9_enc.c sm9_kap.c
+ sm9_setup.c sm9_keygen.c sm9_sign.c sm9_enc.c sm9_kap.c
diff --git a/engines/sm_standard/sm2/README.md b/engines/sm_standard/sm2/README.md
new file mode 100644
index 00000000..7b2bbab9
--- /dev/null
+++ b/engines/sm_standard/sm2/README.md
@@ -0,0 +1,9 @@
+# About SM standard implementation
+
+This is only a standard implementation of the SM.
+
+In the standard implementation, it uses the **MIRACL** library. **MIRACL** (Multiprecision Integer and Rational Arithmetic Crytographic Library) is a C software library. See also [About the MIRACL Crypto SDK](https://libraries.docs.miracl.com/miracl-user-manual/about).
+
+Also, you can download the source code in the Github. Here is a reference link. [Github MIRACL](https://github.com/miracl/MIRACL).
+
+What's more, when you want test it and compile locally, you need add *-lm* option to solve some math functions problems like *ceil* in the code.
\ No newline at end of file
diff --git a/include/openssl/kdf_standard.h b/engines/sm_standard/sm2/kdf_standard.h
similarity index 100%
rename from include/openssl/kdf_standard.h
rename to engines/sm_standard/sm2/kdf_standard.h
diff --git a/include/openssl/sm2_standard.h b/engines/sm_standard/sm2/sm2_standard.h
similarity index 96%
rename from include/openssl/sm2_standard.h
rename to engines/sm_standard/sm2/sm2_standard.h
index f74793db..3ce7f9b9 100644
--- a/include/openssl/sm2_standard.h
+++ b/engines/sm_standard/sm2/sm2_standard.h
@@ -61,9 +61,9 @@
extern "C" {
#endif
-#include
-#include
-#include
+#include "miracl.h"
+#include "mirdef.h"
+#include "kdf_standard.h"
#define ERR_INFINITY_POINT 0x00000001
#define ERR_NOT_VALID_ELEMENT 0x00000002
@@ -119,7 +119,7 @@ static int Test_PubKey(epoint *pubKey);
int Test_Null(unsigned char array[], int len);
int Test_Zero(big x);
int Test_n(big x);
-int Test_Range(big x);
+static int Test_Range(big x);
static int SM2_standard_init();
static int SM2_standard_keygeneration(big priKey, epoint *pubKey);
int SM2_standard_sign_keygeneration(unsigned char PriKey[], unsigned char Px[], unsigned char Py[]);
@@ -232,6 +232,23 @@ static int Test_PubKey(epoint *pubKey)
}
+/* test if the big x belong to the range[1, n-1] */
+static 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 */
static int SM2_standard_keygeneration(big priKey, epoint *pubKey)
{
diff --git a/crypto/sm2/sm2_standard_enc.c b/engines/sm_standard/sm2/sm2_standard_enc.c
similarity index 98%
rename from crypto/sm2/sm2_standard_enc.c
rename to engines/sm_standard/sm2/sm2_standard_enc.c
index 4cfa82a6..37ffebda 100644
--- a/crypto/sm2/sm2_standard_enc.c
+++ b/engines/sm_standard/sm2/sm2_standard_enc.c
@@ -47,9 +47,9 @@
*/
-#include
-#include
-#include
+#include "miracl.h"
+#include "mirdef.h"
+#include "sm2_standard.h"
/* test if the given array is all zero */
diff --git a/crypto/sm2/sm2_standard_exch.c b/engines/sm_standard/sm2/sm2_standard_exch.c
similarity index 99%
rename from crypto/sm2/sm2_standard_exch.c
rename to engines/sm_standard/sm2/sm2_standard_exch.c
index f9065df7..d3adcc5d 100644
--- a/crypto/sm2/sm2_standard_exch.c
+++ b/engines/sm_standard/sm2/sm2_standard_exch.c
@@ -49,9 +49,9 @@
*/
-#include
-#include
-#include
+#include "mirdef.h"
+#include "miracl.h"
+#include "sm2_standard.h"
/* calculation of w */
diff --git a/crypto/sm2/sm2_standard_sign.c b/engines/sm_standard/sm2/sm2_standard_sign.c
similarity index 96%
rename from crypto/sm2/sm2_standard_sign.c
rename to engines/sm_standard/sm2/sm2_standard_sign.c
index 4b447613..8c9dd134 100644
--- a/crypto/sm2/sm2_standard_sign.c
+++ b/engines/sm_standard/sm2/sm2_standard_sign.c
@@ -48,9 +48,9 @@
*/
-#include
-#include
-#include
+#include "mirdef.h"
+#include "miracl.h"
+#include "sm2_standard.h"
@@ -77,22 +77,6 @@ int Test_n(big x)
}
-/* 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[])
diff --git a/crypto/sm3/sm3_standard.c b/engines/sm_standard/sm3/sm3_standard.c
similarity index 99%
rename from crypto/sm3/sm3_standard.c
rename to engines/sm_standard/sm3/sm3_standard.c
index 0efcfdc0..85dc063e 100644
--- a/crypto/sm3/sm3_standard.c
+++ b/engines/sm_standard/sm3/sm3_standard.c
@@ -1,4 +1,4 @@
-#include "openssl/sm3_standard.h"
+#include "sm3_standard.h"
/****************************************************************
diff --git a/include/openssl/sm3_standard.h b/engines/sm_standard/sm3/sm3_standard.h
similarity index 100%
rename from include/openssl/sm3_standard.h
rename to engines/sm_standard/sm3/sm3_standard.h
diff --git a/engines/sm_standard/sm9/README.md b/engines/sm_standard/sm9/README.md
new file mode 100644
index 00000000..7b2bbab9
--- /dev/null
+++ b/engines/sm_standard/sm9/README.md
@@ -0,0 +1,9 @@
+# About SM standard implementation
+
+This is only a standard implementation of the SM.
+
+In the standard implementation, it uses the **MIRACL** library. **MIRACL** (Multiprecision Integer and Rational Arithmetic Crytographic Library) is a C software library. See also [About the MIRACL Crypto SDK](https://libraries.docs.miracl.com/miracl-user-manual/about).
+
+Also, you can download the source code in the Github. Here is a reference link. [Github MIRACL](https://github.com/miracl/MIRACL).
+
+What's more, when you want test it and compile locally, you need add *-lm* option to solve some math functions problems like *ceil* in the code.
\ No newline at end of file
diff --git a/engines/sm_standard/sm9/kdf_standard.h b/engines/sm_standard/sm9/kdf_standard.h
new file mode 100644
index 00000000..508226fd
--- /dev/null
+++ b/engines/sm_standard/sm9/kdf_standard.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+
+#ifndef HEADER_KDF_STANDARD_H
+#define HEADER_KDF_STANDARD_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SM3_len 256
+#define SM3_T1 0x79CC4519
+#define SM3_T2 0x7A879D8A
+#define SM3_IVA 0x7380166f
+#define SM3_IVB 0x4914b2b9
+#define SM3_IVC 0x172442d7
+#define SM3_IVD 0xda8a0600
+#define SM3_IVE 0xa96f30bc
+#define SM3_IVF 0x163138aa
+#define SM3_IVG 0xe38dee4d
+#define SM3_IVH 0xb0fb0e4e
+
+#define SM2_WORDSIZE 8
+#define SM2_NUMBITS 256
+#define SM2_NUMWORD (SM2_NUMBITS / SM2_WORDSIZE) //32
+
+/* Various logical functions */
+#define SM3_p1(x) (x ^ SM3_rotl32(x, 15) ^ SM3_rotl32(x, 23))
+#define SM3_p0(x) (x ^ SM3_rotl32(x, 9) ^ SM3_rotl32(x, 17))
+#define SM3_ff0(a, b, c) (a ^ b ^ c)
+#define SM3_ff1(a, b, c) ((a & b) | (a & c) | (b & c))
+#define SM3_gg0(e, f, g) (e ^ f ^ g)
+#define SM3_gg1(e, f, g) ((e & f) | ((~e) & g))
+#define SM3_rotl32(x, n) (((x) << n) | ((x) >> (32 - n)))
+#define SM3_rotr32(x, n) (((x) >> n) | ((x) << (32 - n)))
+
+
+typedef struct {
+ unsigned long state[8];
+ unsigned long length;
+ unsigned long curlen;
+ unsigned char buf[64];
+} SM3_STATE;
+
+
+static void BiToW(unsigned long Bi[], unsigned long W[]);
+static void WToW1(unsigned long W[], unsigned long W1[]);
+static void CF(unsigned long W[], unsigned long W1[], unsigned long V[]);
+static void BigEndian(unsigned char src[], unsigned int bytelen, unsigned char des[]);
+static void SM3_init(SM3_STATE *md);
+static void SM3_compress(SM3_STATE *md);
+static void SM3_process(SM3_STATE *md, unsigned char *buf, int len);
+static void SM3_done(SM3_STATE *md, unsigned char hash[]);
+static void SM3_256(unsigned char buf[], int len, unsigned char hash[]);
+static void SM3_kdf(unsigned char Z[], unsigned short zlen, unsigned short klen, unsigned char K[]);
+
+
+/* calculate W from Bi */
+static void BiToW(unsigned long Bi[], unsigned long W[])
+{
+ int i;
+ unsigned long tmp;
+
+ for(i = 0; i <= 15; i++)
+ {
+ W[i] = Bi[i];
+ }
+ for(i = 16;i <= 67; i++)
+ {
+ tmp = W[i - 16] ^ W[i - 9] ^ SM3_rotl32(W[i - 3], 15);
+ W[i] = SM3_p1(tmp) ^ (SM3_rotl32(W[i - 13], 7)) ^ W[i - 6];
+ }
+}
+
+
+/* calculate W1 from W */
+static void WToW1(unsigned long W[], unsigned long W1[])
+{
+ int i;
+ for(i = 0; i <= 63; i++)
+ {
+ W1[i] = W[i] ^ W[i + 4];
+ }
+}
+
+
+/* calculate the CF compress function and update V */
+static void CF(unsigned long W[], unsigned long W1[], unsigned long V[])
+{
+ unsigned long SS1;
+ unsigned long SS2;
+ unsigned long TT1;
+ unsigned long TT2;
+ unsigned long A, B, C, D, E, F, G, H;
+ unsigned long T = SM3_T1;
+ unsigned long FF;
+ unsigned long GG;
+ int j;
+
+ //reg init, set ABCDEFGH = V0
+ A = V[0];
+ B = V[1];
+ C = V[2];
+ D = V[3];
+ E = V[4];
+ F = V[5];
+ G = V[6];
+ H = V[7];
+
+ for (j = 0; j <= 63; j++)
+ {
+ //SS1
+ if (j == 0)
+ {
+ T = SM3_T1;
+ }
+ else if (j == 16)
+ {
+ T = SM3_rotl32(SM3_T2, 16);
+ }
+ else
+ {
+ T = SM3_rotl32(T, 1);
+ }
+ SS1 = SM3_rotl32((SM3_rotl32(A, 12) + E + T), 7);
+
+ //SS2
+ SS2 = SS1 ^ SM3_rotl32(A, 12);
+
+ //TT1
+ if (j <= 15)
+ {
+ FF = SM3_ff0(A, B, C);
+ }
+ else
+ {
+ FF = SM3_ff1(A, B, C);
+ }
+ TT1 = FF + D + SS2 + *W1;
+ W1++;
+
+ //TT2
+ if (j <= 15)
+ {
+ GG = SM3_gg0(E, F, G);
+ }
+ else
+ {
+ GG = SM3_gg1(E, F, G);
+ }
+ TT2 = GG + H + SS1 + *W;
+ W++;
+
+ //D
+ D = C;
+
+ //C
+ C = SM3_rotl32(B, 9);
+
+ //B
+ B = A;
+
+ //A
+ A = TT1;
+
+ //H
+ H = G;
+
+ //G
+ G = SM3_rotl32(F, 19);
+
+ //F
+ F = E;
+
+ //E
+ E = SM3_p0(TT2);
+ }
+
+ //update V
+ V[0] = A ^ V[0];
+ V[1] = B ^ V[1];
+ V[2] = C ^ V[2];
+ V[3] = D ^ V[3];
+ V[4] = E ^ V[4];
+ V[5] = F ^ V[5];
+ V[6] = G ^ V[6];
+ V[7] = H ^ V[7];
+}
+
+
+/* unsigned int endian converse. GM/T 0004-2012 requires to use big-endian.
+ * if CPu uses little-endian, BigEndian function is a necessary
+ * call to change the little-endian format into big-endian format.
+ */
+static void BigEndian(unsigned char src[], unsigned int bytelen, unsigned char des[])
+{
+ unsigned char tmp = 0;
+ unsigned long i = 0;
+ for (i = 0; i < bytelen / 4; i++)
+ {
+ tmp = des[4 * i];
+ des[4 * i] = src[4 * i + 3];
+ src[4 * i + 3] = tmp;
+
+ tmp = des[4 * i + 1];
+ des[4 * i + 1] = src[4 * i + 2];
+ des[4 * i + 2] = tmp;
+ }
+}
+
+
+/* initiate SM3 state */
+static void SM3_init(SM3_STATE *md)
+{
+ md->curlen = md->length = 0;
+ md->state[0] = SM3_IVA;
+ md->state[1] = SM3_IVB;
+ md->state[2] = SM3_IVC;
+ md->state[3] = SM3_IVD;
+ md->state[4] = SM3_IVE;
+ md->state[5] = SM3_IVF;
+ md->state[6] = SM3_IVG;
+ md->state[7] = SM3_IVH;
+}
+
+
+/* compress a single a block of message */
+static void SM3_compress(SM3_STATE *md)
+{
+ unsigned long W[68];
+ unsigned long W1[64];
+
+ //if CPU uses little-endian, BigEndian function is a necessary call
+ BigEndian(md->buf, 64, md->buf);
+ BiToW((unsigned long *)md->buf, W);
+ WToW1(W, W1);
+ CF(W, W1, md->state);
+}
+
+
+/* compress the first(len/64) blocks of message */
+static void SM3_process(SM3_STATE *md, unsigned char *buf, int len)
+{
+ while (len--)
+ {
+ /* copy byte */
+ md->buf[md->curlen] = *buf++;
+ md->curlen++;
+
+ /* is 64 bytes full? */
+ if (md->curlen == 64)
+ {
+ SM3_compress(md);
+ md->length += 512;
+ md->curlen = 0;
+ }
+ }
+}
+
+
+/* compress the rest message that the SM3_process has left behind */
+static void SM3_done(SM3_STATE *md, unsigned char hash[])
+{
+ int i;
+ unsigned char tmp = 0;
+
+ /* increase the bit length of the message */
+ md->length += md->curlen << 3;
+
+ /* append the '1' bit */
+ md->buf[md->curlen] = 0x80;
+ md->curlen++;
+
+ /* if the length is currently above 56 bytes, appends zeros till
+ it reaches 64 bytes, compress the current block, creat a new
+ block by appending zeros and length,and then compress it
+ */
+ if (md->curlen > 56)
+ {
+ for (; md->curlen < 64;)
+ {
+ md->buf[md->curlen] = 0;
+ md->curlen++;
+ }
+ SM3_compress(md);
+ md->curlen = 0;
+ }
+
+ /* if the length is less than 56 bytes, pad upto 56 bytes of zeroes */
+ for (; md->curlen < 56;)
+ {
+ md->buf[md->curlen] = 0;
+ md->curlen++;
+ }
+
+ /* since all messages are under 2^32 bits we mark the top bits zero */
+ for (i = 56; i < 60; i++)
+ {
+ md->buf[i] = 0;
+ }
+
+ /* append length */
+ md->buf[63] = md->length & 0xff;
+ md->buf[62] = (md->length >> 8) & 0xff;
+ md->buf[61] = (md->length >> 16) & 0xff;
+ md->buf[60] = (md->length >> 24) & 0xff;
+
+ SM3_compress(md);
+
+ /* copy output */
+ memcpy(hash, md->state, SM3_len / 8);
+ BigEndian(hash, SM3_len / 8, hash); //if CPU uses little-endian, BigEndian function is a necessary call
+}
+
+
+/* calculate a hash value from a given message */
+static void SM3_256(unsigned char buf[], int len, unsigned char hash[])
+{
+ SM3_STATE md;
+ SM3_init(&md);
+ SM3_process(&md, buf, len);
+ SM3_done(&md, hash);
+}
+
+
+/* key derivation function */
+static void SM3_kdf(unsigned char Z[], unsigned short zlen, unsigned short klen, unsigned char K[])
+{
+ unsigned short i, j, t;
+ unsigned int bitklen;
+ SM3_STATE md;
+ unsigned char Ha[SM2_NUMWORD];
+ unsigned char ct[4] = {0, 0, 0, 1};
+
+ bitklen = klen * 8;
+
+ if (bitklen % SM2_NUMBITS)
+ t = bitklen / SM2_NUMBITS + 1;
+ else
+ t = bitklen / SM2_NUMBITS;
+
+ //s4: K = Ha1 || Ha2 || ...
+ for (i = 1; i < t; i++)
+ {
+ //s2: Hai = Hv(Z || ct)
+ SM3_init(&md);
+ SM3_process(&md, Z, zlen);
+ SM3_process(&md, ct, 4);
+ SM3_done(&md, Ha);
+ memcpy((K + SM2_NUMWORD * (i - 1)), Ha, SM2_NUMWORD);
+
+ if (ct[3] == 0xff)
+ {
+ ct[3] = 0;
+ if (ct[2] == 0xff)
+ {
+ ct[2] = 0;
+ if (ct[1] == 0xff)
+ {
+ ct[1] = 0;
+ ct[0]++;
+ }
+ else
+ ct[1]++;
+ }
+ else
+ ct[2]++;
+ }
+ else
+ ct[3]++;
+ }
+
+ //s3
+ SM3_init(&md);
+ SM3_process(&md, Z, zlen);
+ SM3_process(&md, ct, 4);
+ SM3_done(&md, Ha);
+
+ if(bitklen % SM2_NUMBITS)
+ {
+ i = (SM2_NUMBITS - bitklen + SM2_NUMBITS * (bitklen / SM2_NUMBITS)) / 8;
+ j = (bitklen - SM2_NUMBITS * (bitklen / SM2_NUMBITS)) / 8;
+ memcpy((K + SM2_NUMWORD * (t - 1)), Ha, j);
+ }
+ else
+ {
+ memcpy((K + SM2_NUMWORD * (t - 1)), Ha, SM2_NUMWORD);
+ }
+}
+
+
+#ifdef __cplusplus
+}
+# endif
+#endif
diff --git a/engines/sm_standard/sm9/r-ate.h b/engines/sm_standard/sm9/r-ate.h
new file mode 100644
index 00000000..06c06e18
--- /dev/null
+++ b/engines/sm_standard/sm9/r-ate.h
@@ -0,0 +1,517 @@
+/* ====================================================================
+ * Copyright (c) 2007 - 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.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_R_ATE_H
+#define HEADER_R_ATE_H
+
+
+#include "zzn12_operation.h"
+
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+static zzn2 zzn2_pow(zzn2 x, big k)
+{
+ int i, j, nb, n, nbw, nzs;
+ big zero;
+ zzn2 res, u2, t[16];
+
+ zero = mirvar(0);
+
+ res.a = mirvar(0);
+ res.b = mirvar(0);
+
+ u2.a = mirvar(0);
+ u2.b = mirvar(0);
+
+ if(zzn2_iszero(&x))
+ {
+ zzn2_zero(&res);
+ return res;
+ }
+ if(size(k) == 0)
+ {
+ zzn2_from_int(1, &res);
+ return res;
+ }
+ if(size(k) == 1)
+ return x;
+
+ // Prepare table for windowing
+ zzn2_mul(&x, &x, &u2);
+ t[0].a = mirvar(0);
+ t[0].b = mirvar(0);
+ zzn2_copy(&x, &t[0]);
+ for(i = 1; i < 16; i++)
+ {
+ t[i].a = mirvar(0);
+ t[i].b = mirvar(0);
+ zzn2_mul(&t[i - 1], &u2, &t[i]);
+ }
+
+ // Left to right method - with windows
+ zzn2_copy(&x, &res);
+ nb = logb2(k);
+ if(nb > 1)
+ for(i = nb - 2; i >= 0;)
+ {
+ //Note new parameter of window_size=5. Default to 5, but reduce to 4 (or even 3) to save RAM
+ n = mr_window(k, i, &nbw, &nzs, 5);
+ for(j = 0; j < nbw; j++)
+ zzn2_mul(&res, &res, &res);
+ if(n > 0)
+ zzn2_mul(&res, &t[n / 2], &res);
+ i -= nbw;
+ if(nzs)
+ {
+ for(j = 0; j < nzs; j++)
+ zzn2_mul(&res, &res, &res);
+ i -= nzs;
+ }
+ }
+ return res;
+}
+
+
+static void set_frobenius_constant(zzn2 *X)
+{
+ big p, zero, one, two;
+ p = mirvar(0);
+ zero = mirvar(0);
+ one = mirvar(0);
+ two = mirvar(0);
+
+ convert(0, zero);
+ convert(1, one);
+ convert(2, two);
+
+ mip = get_mip();
+ copy(mip->modulus, p);
+
+ switch(get_mip()->pmod8)
+ {
+ case 5:
+ zzn2_from_bigs(zero, one, X);// = (sqrt(-2)^(p-1)/2
+ break;
+ case 3:
+ // = (1+sqrt(-1))^(p-1)/2
+ zzn2_from_bigs(one, one, X);
+ break;
+ case 7:
+ zzn2_from_bigs(two, one, X);// = (2+sqrt(-1))^(p-1)/2
+ default:
+ break;
+ }
+
+ decr(p, 1, p);
+ subdiv(p, 6, p);
+
+ *X = zzn2_pow(*X, p);
+}
+
+
+static void q_power_frobenius(ecn2 A, zzn2 F)
+{
+ // Fast multiplication of A by q (for Trace-Zero group members only)
+ zzn2 x, y, z, w, r;
+ x.a = mirvar(0);
+ x.b = mirvar(0);
+
+ y.a = mirvar(0);
+ y.b = mirvar(0);
+
+ z.a = mirvar(0);
+ z.b = mirvar(0);
+
+ w.a = mirvar(0);
+ w.b = mirvar(0);
+
+ r.a = mirvar(0);
+ r.b = mirvar(0);
+
+ ecn2_get(&A, &x, &y, &z);
+ zzn2_copy(&F, &r);//r=F
+ if(get_mip()->TWIST == MR_SEXTIC_M)
+ zzn2_inv(&r); // could be precalculated
+ zzn2_mul(&r, &r, &w);//w=r*r
+ zzn2_conj(&x, &x);
+ zzn2_mul(&w, &x, &x);
+ zzn2_conj(&y, &y);
+ zzn2_mul(&w, &r, &w);
+ zzn2_mul(&w, &y, &y);
+ zzn2_conj(&z, &z);
+ ecn2_setxyz(&x, &y, &z, &A);
+}
+
+
+static zzn12 line(ecn2 A, ecn2 *C, ecn2 *B, zzn2 slope, zzn2 extra, BOOL Doubling, big Qx, big Qy)
+{
+ zzn12 res;
+ zzn2 X, Y, Z, Z2, U, QY, CZ;
+ big QX;
+
+ QX = mirvar(0);
+ X.a = mirvar(0);
+ X.b = mirvar(0);
+
+ Y.a = mirvar(0);
+ Y.b = mirvar(0);
+
+ Z.a = mirvar(0);
+ Z.b = mirvar(0);
+
+ Z2.a = mirvar(0);
+ Z2.b = mirvar(0);
+
+ U.a = mirvar(0);
+ U.b = mirvar(0);
+
+ QY.a = mirvar(0);
+ QY.b = mirvar(0);
+
+ CZ.a = mirvar(0);
+ CZ.b = mirvar(0);
+ zzn12_init(&res);
+
+ ecn2_getz(C, &CZ);
+ // Thanks to A. Menezes for pointing out this optimization...
+ if(Doubling)
+ {
+ ecn2_get(&A, &X, &Y, &Z);
+ zzn2_mul(&Z, &Z, &Z2); //Z2=Z*Z
+
+ //X=slope*X-extra
+ zzn2_mul(&slope, &X, &X);
+ zzn2_sub(&X, &extra, &X);
+
+ zzn2_mul(&CZ, &Z2, &U);
+
+ //(-(Z*Z*slope)*Qx);
+ nres(Qx, QX);
+ zzn2_mul(&Z2, &slope, &Y);
+ zzn2_smul(&Y, QX, &Y);
+ zzn2_negate(&Y, &Y);
+
+ if(get_mip()->TWIST == MR_SEXTIC_M)
+ {
+ // "multiplied across" by i to simplify
+ zzn2_from_big(Qy, &QY);
+ zzn2_txx(&QY);
+ zzn2_mul(&U, &QY, &QY);
+ zzn4_from_zzn2s(&QY, &X, &res.a);
+ zzn2_copy(&Y, &(res.c.b));
+ }
+ if(get_mip()->TWIST == MR_SEXTIC_D)
+ {
+ zzn2_smul(&U, Qy, &QY);
+ zzn4_from_zzn2s(&QY, &X, &res.a);
+ zzn2_copy(&Y, &(res.b.b));
+ }
+ }
+ else
+ {
+ //slope*X-Y*Z
+ ecn2_getxy(B, &X, &Y);
+ zzn2_mul(&slope, &X, &X);
+ zzn2_mul(&Y, &CZ, &Y);
+ zzn2_sub(&X, &Y, &X);
+
+ //(-slope*Qx)
+ nres(Qx, QX);
+ zzn2_smul(&slope, QX, &Z);
+ zzn2_negate(&Z, &Z);
+
+ if(get_mip()->TWIST == MR_SEXTIC_M)
+ {
+ zzn2_from_big(Qy, &QY);
+ zzn2_txx(&QY);
+ zzn2_mul(&CZ, &QY, &QY);
+
+ zzn4_from_zzn2s(&QY, &X, &res.a);
+ zzn2_copy(&Z, &(res.c.b));
+ }
+ if(get_mip()->TWIST == MR_SEXTIC_D)
+ {
+ zzn2_smul(&CZ, Qy, &QY);
+ zzn4_from_zzn2s(&QY, &X, &res.a);
+ zzn2_copy(&Z, &(res.b.b));
+ }
+ }
+ return res;
+}
+
+
+static zzn12 g(ecn2 *A, ecn2 *B, big Qx, big Qy)
+{
+ zzn2 lam, extra;
+ BOOL Doubling;
+ ecn2 P;
+ zzn12 res;
+
+ lam.a = mirvar(0);
+ lam.b = mirvar(0);
+
+ extra.a = mirvar(0);
+ extra.b = mirvar(0);
+
+ P.x.a = mirvar(0);
+ P.x.b = mirvar(0);
+
+ P.y.a = mirvar(0);
+ P.y.b = mirvar(0);
+
+ P.z.a = mirvar(0);
+ P.z.b = mirvar(0);
+
+ P.marker = MR_EPOINT_INFINITY;
+
+ zzn12_init(&res);
+ ecn2_copy(A, &P);
+ Doubling = ecn2_add2(B, A, &lam, &extra);
+ if(A->marker == MR_EPOINT_INFINITY)
+ {
+ zzn4_from_int(1, &res.a);
+ res.miller = FALSE;
+ res.unitary = TRUE;
+ }
+ else
+ res = line(P, A, B, lam, extra, Doubling, Qx, Qy);
+ return res;
+}
+
+
+static BOOL fast_pairing(ecn2 P, big Qx, big Qy, big x, zzn2 X, zzn12 *r)
+{
+ int i, nb;
+ big n, zero, negify_x;
+ ecn2 A, KA;
+ zzn12 t0, x0, x1, x2, x3, x4, x5, res;
+
+ zero = mirvar(0);
+ n = mirvar(0);
+ negify_x = mirvar(0);
+
+ A.x.a = mirvar(0);
+ A.x.b = mirvar(0);
+
+ A.y.a = mirvar(0);
+ A.y.b = mirvar(0);
+
+ A.z.a = mirvar(0);
+ A.z.b = mirvar(0);
+ A.marker = MR_EPOINT_INFINITY;
+
+ KA.x.a = mirvar(0);
+ KA.x.b = mirvar(0);
+
+ KA.y.a = mirvar(0);
+ KA.y.b = mirvar(0);
+
+ KA.z.a = mirvar(0);
+ KA.z.b = mirvar(0);
+ KA.marker = MR_EPOINT_INFINITY;
+ zzn12_init(&t0);
+ zzn12_init(&x0);
+ zzn12_init(&x1);
+ zzn12_init(&x2);
+ zzn12_init(&x3);
+ zzn12_init(&x4);
+ zzn12_init(&x5);
+ zzn12_init(&res);
+
+ premult(x, 6, n);
+ incr(n, 2, n);//n=(6*x+2);
+ if(mr_compare(x, zero) < 0) //x<0
+ negify(n, n); //n=-(6*x+2);
+
+ ecn2_copy(&P, &A);
+ nb = logb2(n);
+ zzn4_from_int(1, &res.a);
+ res.unitary = TRUE; //res=1
+ // Short Miller loop
+ res.miller = TRUE;
+
+ for(i = nb - 2; i >= 0; i--)
+ {
+ zzn12_mul(res, res, &res);
+ zzn12_mul(res, g(&A, &A, Qx, Qy), &res);
+ if(mr_testbit(n, i))
+ zzn12_mul(res, g(&A, &P, Qx, Qy), &res);
+ }
+ // Combining ideas due to Longa, Aranha et al. and Naehrig
+ ecn2_copy(&P, &KA);
+ q_power_frobenius(KA, X);
+ if(mr_compare(x, zero) < 0)
+ {
+ ecn2_negate(&A, &A);
+ zzn12_conj(&res, &res);
+ }
+ zzn12_mul(res, g(&A, &KA, Qx, Qy), &res);
+ q_power_frobenius(KA, X);
+ ecn2_negate(&KA, &KA);
+ zzn12_mul(res, g(&A, &KA, Qx, Qy), &res);
+
+ if(zzn4_iszero(&res.a) && zzn4_iszero(&res.b) && zzn4_iszero(&res.c))
+ return FALSE;
+
+ // The final exponentiation
+ zzn12_copy(&res, &t0);//t0=r;
+ zzn12_conj(&res, &res);
+ zzn12_div(res, t0, &res);
+
+ res.miller = FALSE;
+ res.unitary = FALSE;
+
+ zzn12_copy(&res, &t0);//t0=r;
+ zzn12_powq(X, &res);
+ zzn12_powq(X, &res);
+ zzn12_mul(res, t0, &res);// r^[(p^6-1)*(p^2+1)]
+ res.miller = FALSE;
+ res.unitary = TRUE;
+
+ // Newer new idea...
+ // See "On the final exponentiation for calculating pairings on ordinary elliptic curves"
+ // Michael Scott and Naomi Benger and Manuel Charlemagne and Luis J. Dominguez Perez and Ezekiel J. Kachisa
+ zzn12_copy(&res, &t0);
+ zzn12_powq(X, &t0);
+ zzn12_copy(&t0, &x0);
+ zzn12_powq(X, &x0); //x0=t0
+
+ zzn12_mul(res, t0, &x1);
+ zzn12_mul(x0, x1, &x0);// x0*=(res*t0);
+ zzn12_powq(X, &x0);
+
+ x1 = zzn12_inverse(res);// just a conjugation!
+ negify(x, negify_x);
+ x4 = zzn12_pow(res, negify_x);//negify_x=-x x is sparse.
+ zzn12_copy(&x4, &x3);
+ zzn12_powq(X, &x3);
+
+ x2 = zzn12_pow(x4, negify_x);
+ x5 = zzn12_inverse(x2);
+ t0 = zzn12_pow(x2, negify_x);
+
+ zzn12_powq(X, &x2);
+ zzn12_div(x4, x2, &x4);
+
+ zzn12_powq(X, &x2);
+ zzn12_copy(&t0, &res);// res=t0
+ zzn12_powq(X, &res);
+ zzn12_mul(t0, res, &t0);
+
+ zzn12_mul(t0, t0, &t0);
+ zzn12_mul(t0, x4, &t0);
+ zzn12_mul(t0, x5, &t0);//t0*=t0;t0*=x4;t0*=x5;
+
+ zzn12_mul(x3, x5, &res);
+ zzn12_mul(res, t0, &res);//res=x3*x5;res*=t0;
+
+ zzn12_mul(t0, x2, &t0);//t0*=x2;
+
+ zzn12_mul(res, res, &res);
+ zzn12_mul(res, t0, &res);
+ zzn12_mul(res, res, &res);//res*=res; res*=t0;res*=res;
+
+ zzn12_mul(res, x1, &t0);// t0=res*x1;
+ zzn12_mul(res, x0, &res);//res*=x0;
+
+ zzn12_mul(t0, t0, &t0);
+ zzn12_mul(t0, res, &t0);//t0*=t0;t0*=res;
+
+ zzn12_copy(&t0, r);//r= t0;
+
+ return TRUE;
+}
+
+
+static BOOL ecap(ecn2 P, epoint *Q, big x, zzn2 X, zzn12 *r)
+{
+ BOOL Ok;
+ big Qx, Qy;
+ Qx = mirvar(0);
+ Qy = mirvar(0);
+
+ ecn2_norm(&P);
+ epoint_get(Q, Qx, Qy);
+
+ Ok = fast_pairing(P, Qx, Qy, x, X, r);
+
+ if(Ok)
+ return TRUE;
+ return FALSE;
+}
+
+
+static BOOL member(zzn12 r, big x, zzn2 F)
+{
+ zzn12 w;
+ big six;
+ six = mirvar(0);
+ zzn12_init(&w);
+
+ convert(6, six);
+ zzn12_copy(&r, &w);//w=r
+ zzn12_powq(F, &w);
+ r = zzn12_pow(r, x);
+ r = zzn12_pow(r, x);
+ r = zzn12_pow(r, six); // t-1=6x^2
+ if(zzn4_compare(&w.a, &r.a) && zzn4_compare(&w.a, &r.a) && zzn4_compare(&w.a, &r.a))
+ return TRUE;
+ return FALSE;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/engines/sm_standard/sm9/sm4_standard.h b/engines/sm_standard/sm9/sm4_standard.h
new file mode 100644
index 00000000..3f47a337
--- /dev/null
+++ b/engines/sm_standard/sm9/sm4_standard.h
@@ -0,0 +1,188 @@
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_SM4_STANDARD_H
+#define HEADER_SM4_STANDARD_H
+
+
+#include
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+//rotate n bits to the left in a 32bit buffer
+#define SM4_rotl32(buf, n) (((buf) << n) | ((buf) >> (32 - n)))
+
+
+static unsigned int SM4_CK[32] = {0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279};
+unsigned char SM4_Sbox[256] = {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
+ 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
+ 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
+ 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
+ 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
+ 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
+ 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
+ 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
+ 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
+ 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
+ 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
+ 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
+ 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
+ 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
+ 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
+ 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48};
+static unsigned int SM4_FK[4] = {0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC};
+
+
+void SM4_keyschedule(unsigned char MK[], unsigned int rk[])
+{
+ unsigned int tmp, buf, K[36];
+ int i;
+ for(i = 0; i < 4; i++)
+ {
+ K[i] = SM4_FK[i] ^ ((MK[4 * i] << 24) | (MK[4 * i + 1] << 16)
+ | (MK[4 * i + 2] << 8) | (MK[4 * i + 3]));
+ }
+ for(i = 0; i < 32; i++)
+ {
+ tmp = K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ SM4_CK[i];
+
+ //nonlinear operation
+ buf = (SM4_Sbox[(tmp >> 24) & 0xFF]) << 24
+ | (SM4_Sbox[(tmp >> 16) & 0xFF]) << 16
+ | (SM4_Sbox[(tmp >> 8) & 0xFF]) << 8
+ | (SM4_Sbox[tmp & 0xFF]);
+
+ //linear operation
+ K[i + 4] = K[i] ^ ((buf) ^ (SM4_rotl32((buf), 13)) ^ (SM4_rotl32((buf), 23)));
+ rk[i] = K[i + 4];
+ }
+}
+
+
+void SM4_encrypt(unsigned char MK[], unsigned char PlainText[], unsigned char CipherText[])
+{
+ unsigned int rk[32], X[36], tmp, buf;
+ int i, j;
+ SM4_keyschedule(MK, rk);
+ for(j = 0; j < 4; j++)
+ {
+ X[j] = (PlainText[j * 4] << 24) | (PlainText[j * 4 + 1] << 16)
+ | (PlainText[j * 4 + 2] << 8) | (PlainText[j * 4 + 3]);
+ }
+ for(i = 0; i < 32; i++)
+ {
+ tmp = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ rk[i];
+
+ //nonlinear operation
+ buf = (SM4_Sbox[(tmp >> 24) & 0xFF]) << 24
+ | (SM4_Sbox[(tmp >> 16) & 0xFF]) << 16
+ | (SM4_Sbox[(tmp >> 8) & 0xFF]) << 8
+ | (SM4_Sbox[tmp & 0xFF]);
+
+ //linear operation
+ X[i + 4] = X[i] ^ (buf ^ SM4_rotl32((buf), 2) ^ SM4_rotl32((buf), 10)
+ ^ SM4_rotl32((buf), 18) ^ SM4_rotl32((buf), 24));
+ }
+ for(j = 0; j < 4; j++)
+ {
+ CipherText[4 * j] = (X[35 - j] >> 24) & 0xFF;
+ CipherText[4 * j + 1] = (X[35 - j] >> 16) & 0xFF;
+ CipherText[4 * j + 2]= (X[35 - j] >> 8) & 0xFF;
+ CipherText[4 * j + 3] = (X[35 - j]) & 0xFF;
+ }
+}
+
+
+void SM4_decrypt(unsigned char MK[], unsigned char CipherText[], unsigned char PlainText[])
+{
+ unsigned int rk[32], X[36], tmp, buf;
+ int i, j;
+ SM4_keyschedule(MK, rk);
+ for(j = 0; j < 4; j++)
+ {
+ X[j] = (CipherText[j * 4] << 24) | (CipherText[j * 4 + 1] << 16) |
+ (CipherText[j * 4 + 2] << 8) | (CipherText[j * 4 + 3]);
+ }
+ for(i = 0; i < 32; i++)
+ {
+ tmp = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ rk[31 - i];
+ //nonlinear operation
+ buf = (SM4_Sbox[(tmp >> 24) & 0xFF]) << 24
+ | (SM4_Sbox[(tmp >> 16) & 0xFF]) << 16
+ | (SM4_Sbox[(tmp >> 8) & 0xFF]) << 8
+ | (SM4_Sbox[tmp & 0xFF]);
+ //linear operation
+ X[i + 4] = X[i] ^ (buf ^ SM4_rotl32((buf), 2) ^ SM4_rotl32((buf), 10)
+ ^ SM4_rotl32((buf), 18) ^ SM4_rotl32((buf), 24));
+ }
+ for(j = 0; j < 4; j++)
+ {
+ PlainText[4 * j] = (X[35 - j] >> 24) & 0xFF;
+ PlainText[4 * j + 1] = (X[35 - j] >> 16) & 0xFF;
+ PlainText[4 * j + 2] = (X[35 - j] >> 8) & 0xFF;
+ PlainText[4 * j + 3] = (X[35 - j]) & 0xFF;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/engines/sm_standard/sm9/sm9_standard.h b/engines/sm_standard/sm9/sm9_standard.h
new file mode 100644
index 00000000..5b9f3c37
--- /dev/null
+++ b/engines/sm_standard/sm9/sm9_standard.h
@@ -0,0 +1,482 @@
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_SM9_STANDARD_H
+#define HEADER_SM9_STANDARD_H
+
+
+#include
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#include "miracl.h"
+#include "r-ate.h"
+#include "kdf_standard.h"
+
+
+#define BNLEN 32 //BN curve with 256bit is used in SM9 algorithm
+#define SM9_ASK_MEMORY_ERR 0x00000001 //ask for memory fail(申请内存失败)
+#define SM9_MEMBER_ERR 0x00000002 //the order of group G error(群的阶错误)
+#define SM9_MY_ECAP_12A_ERR 0x00000003 //R-ate pairing generated error(R-ate对计算出现错误)
+#define SM9_NOT_VALID_G1 0x00000004 //not valid element of G1
+#define SM9_G1BASEPOINT_SET_ERR 0x00000005 //base point of G1 seted error(G1基点设置错误)
+#define SM9_G2BASEPOINT_SET_ERR 0x00000006 //base point of G2 seted error(G2基点设置错误)
+#define SM9_GEPUB_ERR 0x00000007 //pubkey error(生成公钥错误)
+#define SM9_GEPRI_ERR 0x00000008 //privare key error(生成私钥错误)
+#define SM9_ERR_CMP_S1SB 0x00000009 //S1!=SB
+#define SM9_ERR_CMP_S2SA 0x0000000A //S2!=SA
+#define SM9_ERR_RA 0x0000000B //RA error
+#define SM9_ERR_RB 0x0000000C //RB error
+#define SM9_ERR_SA 0x0000000D //SA error
+#define SM9_ERR_SB 0x0000000E //SB error
+#define SM9_C1_NOT_VALID_G1 0x0000000F //C1不属于群G1
+#define SM9_ENCRYPT_ERR 0x00000010 //加密错误
+#define SM9_ERR_K1_ZERO 0x00000011 //K1 equals 0(K1全0)
+#define SM9_C3_MEMCMP_ERR 0x00000012 //C3对比不一致
+#define SM9_DECRYPT_ERR 0x00000013 //解密错误
+#define SM9_ERR_Encap_C 0x00000014 //cipher error in key encapsulation
+#define SM9_ERR_Encap_K 0x00000015 //key to be encapsulated
+#define SM9_ERR_Decap_K 0x00000016 //key generated by decapsulation
+#define SM9_H_OUTRANGE 0x00000017 //签名H不属于[1,N-1]
+#define SM9_DATA_MEMCMP_ERR 0x00000018 //数据对比不一致
+#define SM9_S_NOT_VALID_G1 0x00000019 //S不属于群G1
+#define SM9_L_error 0x0000001A //参数L错误
+#define SM9_SIGN_ERR 0x0000001B //签名错误
+
+
+static unsigned char SM9_q[32] = {0xB6, 0x40, 0x00, 0x00, 0x02, 0xA3, 0xA6, 0xF1, 0xD6, 0x03, 0xAB, 0x4F, 0xF5, 0x8E, 0xC7, 0x45,
+ 0x21, 0xF2, 0x93, 0x4B, 0x1A, 0x7A, 0xEE, 0xDB, 0xE5, 0x6F, 0x9B, 0x27, 0xE3, 0x51, 0x45, 0x7D};
+static unsigned char SM9_N[32] = {0xB6, 0x40, 0x00, 0x00, 0x02, 0xA3, 0xA6, 0xF1, 0xD6, 0x03, 0xAB, 0x4F, 0xF5, 0x8E, 0xC7, 0x44,
+ 0x49, 0xF2, 0x93, 0x4B, 0x18, 0xEA, 0x8B, 0xEE, 0xE5, 0x6E, 0xE1, 0x9C, 0xD6, 0x9E, 0xCF, 0x25};
+static unsigned char SM9_P1x[32] = {0x93, 0xDE, 0x05, 0x1D, 0x62, 0xBF, 0x71, 0x8F, 0xF5, 0xED, 0x07, 0x04, 0x48, 0x7D, 0x01, 0xD6,
+ 0xE1, 0xE4, 0x08, 0x69, 0x09, 0xDC, 0x32, 0x80, 0xE8, 0xC4, 0xE4, 0x81, 0x7C, 0x66, 0xDD, 0xDD};
+static unsigned char SM9_P1y[32] = {0x21, 0xFE, 0x8D, 0xDA, 0x4F, 0x21, 0xE6, 0x07, 0x63, 0x10, 0x65, 0x12, 0x5C, 0x39, 0x5B, 0xBC,
+ 0x1C, 0x1C, 0x00, 0xCB, 0xFA, 0x60, 0x24, 0x35, 0x0C, 0x46, 0x4C, 0xD7, 0x0A, 0x3E, 0xA6, 0x16};
+static unsigned char SM9_P2[128] = {0x85, 0xAE, 0xF3, 0xD0, 0x78, 0x64, 0x0C, 0x98, 0x59, 0x7B, 0x60, 0x27, 0xB4, 0x41, 0xA0, 0x1F,
+ 0xF1, 0xDD, 0x2C, 0x19, 0x0F, 0x5E, 0x93, 0xC4, 0x54, 0x80, 0x6C, 0x11, 0xD8, 0x80, 0x61, 0x41,
+ 0x37, 0x22, 0x75, 0x52, 0x92, 0x13, 0x0B, 0x08, 0xD2, 0xAA, 0xB9, 0x7F, 0xD3, 0x4E, 0xC1, 0x20,
+ 0xEE, 0x26, 0x59, 0x48, 0xD1, 0x9C, 0x17, 0xAB, 0xF9, 0xB7, 0x21, 0x3B, 0xAF, 0x82, 0xD6, 0x5B,
+ 0x17, 0x50, 0x9B, 0x09, 0x2E, 0x84, 0x5C, 0x12, 0x66, 0xBA, 0x0D, 0x26, 0x2C, 0xBE, 0xE6, 0xED,
+ 0x07, 0x36, 0xA9, 0x6F, 0xA3, 0x47, 0xC8, 0xBD, 0x85, 0x6D, 0xC7, 0x6B, 0x84, 0xEB, 0xEB, 0x96,
+ 0xA7, 0xCF, 0x28, 0xD5, 0x19, 0xBE, 0x3D, 0xA6, 0x5F, 0x31, 0x70, 0x15, 0x3D, 0x27, 0x8F, 0xF2,
+ 0x47, 0xEF, 0xBA, 0x98, 0xA7, 0x1A, 0x08, 0x11, 0x62, 0x15, 0xBB, 0xA5, 0xC9, 0x99, 0xA7, 0xC7};
+static unsigned char SM9_t[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x58, 0xF9, 0x8A};
+static unsigned char SM9_a[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char SM9_b[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05};
+epoint *P1;
+ecn2 P2;
+big N; //order of group, N(t)
+big para_a, para_b, para_t, para_q;
+
+
+static BOOL bytes128_to_ecn2(unsigned char Ppubs[], ecn2 *res);
+static void zzn12_ElementPrint(zzn12 x);
+static void ecn2_Bytes128_Print(ecn2 x);
+static void LinkCharZzn12(unsigned char *message, int len, zzn12 w, unsigned char *Z, int Zlen);
+static int Test_Point(epoint* point);
+void SM4_standard_block_encrypt(unsigned char key[], unsigned char * message, int mlen, unsigned char *cipher, int * cipher_len);
+void SM4_standard_block_decrypt(unsigned char key[], unsigned char *cipher, int len, unsigned char *plain, int *plain_len);
+int SM9_standard_keyex_kdf(unsigned char *IDA, unsigned char *IDB, epoint *RA, epoint *RB, zzn12 g1, zzn12 g2, zzn12 g3, int klen, unsigned char K[]);
+int SM9_standard_keyex_hash(unsigned char hashid[], unsigned char *IDA, unsigned char *IDB, epoint *RA, epoint *RB, zzn12 g1, zzn12 g2, zzn12 g3, unsigned char hash[]);
+static int SM9_standard_h1(unsigned char Z[], int Zlen, big n, big h1);
+int SM9_standard_enc_mac(unsigned char *K, int Klen, unsigned char *M, int Mlen, unsigned char C[]);
+static int SM9_standard_init();
+static int SM9_standard_generateencryptkey(unsigned char hid[], unsigned char *ID, int IDlen, big ke, unsigned char Ppubs[], unsigned char deB[]);
+int SM9_standard_keyex_inita_i(unsigned char hid[], unsigned char *IDB, unsigned char randA[],
+ unsigned char Ppub[], unsigned char deA[], epoint *RA);
+int SM9_standard_keyex_reb_i(unsigned char hid[], unsigned char *IDA, unsigned char *IDB, unsigned char randB[], unsigned char Ppub[], unsigned char deB[], epoint *RA, epoint *RB, unsigned char SB[], zzn12 *g1, zzn12 *g2, zzn12 *g3);
+int SM9_standard_keyex_inita_ii(unsigned char *IDA, unsigned char *IDB, unsigned char randA[], unsigned char Ppub[], unsigned char deA[], epoint *RA, epoint *RB, unsigned char SB[], unsigned char SA[]);
+int SM9_standard_keyex_reb_ii(unsigned char *IDA, unsigned char *IDB, zzn12 g1, zzn12 g2, zzn12 g3, epoint *RA, epoint *RB, unsigned char SA[]);
+int SM9_standard_exch_selfcheck();
+int SM9_standard_enc_selfcheck();
+int SM9_standard_encrypt(unsigned char hid[], unsigned char *IDB, unsigned char *message, int mlen, unsigned char rand[],
+ int EncID, int k1_len, int k2_len, unsigned char Ppub[], unsigned char C[], int *C_len);
+int SM9_standard_decrypt(unsigned char C[], int C_len, unsigned char deB[], unsigned char *IDB, int EncID,
+ int k1_len, int k2_len, unsigned char M[], int * Mlen);
+int SM9_standard_key_encap(unsigned char hid[], unsigned char *IDB, unsigned char rand[], unsigned char Ppub[], unsigned char C[], unsigned char K[], int Klen);
+int SM9_standard_key_decap(unsigned char *IDB, unsigned char deB[], unsigned char C[], int Klen, unsigned char K[]);
+int SM9_standard_encap_selfcheck();
+static int Test_Range(big x);
+int SM9_standard_h2(unsigned char Z[], int Zlen, big n, big h2);
+int SM9_standard_generatesignkey(unsigned char hid[], unsigned char *ID, int IDlen, big ks, unsigned char Ppubs[], unsigned char dsa[]);
+int SM9_standard_sign(unsigned char hid[], unsigned char *IDA, unsigned char *message, int len, unsigned char rand[], unsigned char dsa[], unsigned char Ppub[], unsigned char H[], unsigned char S[]);
+int SM9_standard_verify(unsigned char H[], unsigned char S[], unsigned char hid[], unsigned char *IDA, unsigned char *message, int len, unsigned char Ppub[]);
+int SM9_standard_sv_selfcheck();
+
+
+
+static BOOL bytes128_to_ecn2(unsigned char Ppubs[], ecn2 *res)
+{
+ zzn2 x, y;
+ big a, b;
+ ecn2 r;
+ r.x.a = mirvar(0);
+ r.x.b = mirvar(0);
+
+ r.y.a = mirvar(0);
+ r.y.b = mirvar(0);
+
+ r.z.a = mirvar(0);
+ r.z.b = mirvar(0);
+ r.marker = MR_EPOINT_INFINITY;
+
+ x.a = mirvar(0);
+ x.b = mirvar(0);
+
+ y.a = mirvar(0);
+ y.b = mirvar(0);
+ a = mirvar(0);
+ b = mirvar(0);
+
+ bytes_to_big(BNLEN, Ppubs, b);
+ bytes_to_big(BNLEN, Ppubs + BNLEN, a);
+ zzn2_from_bigs(a, b, &x);
+ bytes_to_big(BNLEN, Ppubs + BNLEN * 2, b);
+ bytes_to_big(BNLEN, Ppubs + BNLEN * 3, a);
+ zzn2_from_bigs(a, b, &y);
+
+ return ecn2_set(&x, &y, res);
+}
+
+
+static void ecn2_Bytes128_Print(ecn2 x)
+{
+ big tmp;
+ tmp = mirvar(0);
+ redc(x.x.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.x.a, tmp);
+ cotnum(tmp, stdout);
+ redc(x.y.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.y.a, tmp);
+ cotnum(tmp, stdout);
+}
+
+
+static void zzn12_ElementPrint(zzn12 x)
+{
+ big tmp;
+ tmp = mirvar(0);
+ redc(x.c.b.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.c.b.a, tmp);
+ cotnum(tmp, stdout);
+ redc(x.c.a.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.c.a.a, tmp);
+ cotnum(tmp,stdout);
+ redc(x.b.b.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.b.b.a, tmp);
+ cotnum(tmp, stdout);
+ redc(x.b.a.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.b.a.a, tmp);
+ cotnum(tmp, stdout);
+ redc(x.a.b.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.a.b.a, tmp);
+ cotnum(tmp, stdout);
+ redc(x.a.a.b, tmp);
+ cotnum(tmp, stdout);
+ redc(x.a.a.a, tmp);
+ cotnum(tmp, stdout);
+}
+
+
+static void LinkCharZzn12(unsigned char *message, int len, zzn12 w, unsigned char *Z, int Zlen)
+{
+ big tmp;
+
+ tmp = mirvar(0);
+
+ memcpy(Z, message, len);
+ redc(w.c.b.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len, 1);
+ redc(w.c.b.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN, 1);
+ redc(w.c.a.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 2, 1);
+ redc(w.c.a.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 3, 1);
+ redc(w.b.b.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 4, 1);
+ redc(w.b.b.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 5, 1);
+ redc(w.b.a.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 6, 1);
+ redc(w.b.a.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 7, 1);
+ redc(w.a.b.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 8, 1);
+ redc(w.a.b.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 9, 1);
+ redc(w.a.a.b, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 10, 1);
+ redc(w.a.a.a, tmp);
+ big_to_bytes(BNLEN, tmp, Z + len + BNLEN * 11, 1);
+}
+
+
+static int Test_Point(epoint* point)
+{
+ big x, y, x_3, tmp;
+ epoint *buf;
+
+ x = mirvar(0);
+ y = mirvar(0);
+ x_3 = mirvar(0);
+ tmp = mirvar(0);
+ buf = epoint_init();
+
+ //test if y^2=x^3+b
+ epoint_get(point, x, y);
+ power(x, 3, para_q, x_3); //x_3=x^3 mod p
+ multiply(x, para_a, x);
+ divide(x, para_q, tmp);
+ add(x_3, x, x); //x=x^3+ax+b
+ add(x, para_b, x);
+ divide(x, para_q, tmp); //x=x^3+ax+b mod p
+ power(y, 2, para_q, y); //y=y^2 mod p
+ if(mr_compare(x, y) != 0)
+ return 1;
+
+ //test infinity
+ ecurve_mult(N, point, buf);
+ if(point_at_infinity(buf) == FALSE)
+ return 1;
+
+ return 0;
+}
+
+
+static int SM9_standard_h1(unsigned char Z[], int Zlen, big n, big h1)
+{
+ int hlen, i, ZHlen;
+ big hh, i256, tmp, n1;
+ unsigned char *ZH = NULL,*ha = NULL;
+
+ hh = mirvar(0);
+ i256 = mirvar(0);
+ tmp = mirvar(0);
+ n1 = mirvar(0);
+ convert(1, i256);
+ ZHlen = Zlen + 1;
+
+ hlen = (int)ceil((5.0 * logb2(n)) / 32.0);
+ decr(n, 1, n1);
+ ZH = (char *)malloc(sizeof(char)*(ZHlen + 1));
+ if(ZH == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(ZH + 1, Z, Zlen);
+ ZH[0] = 0x01;
+ ha = (char *)malloc(sizeof(char)*(hlen + 1));
+ if(ha == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ SM3_kdf(ZH, ZHlen, hlen, ha);
+
+ for(i = hlen - 1; i >= 0; i--)//key[从大到小]
+ {
+ premult(i256, ha[i], tmp);
+ add(hh, tmp, hh);
+ premult(i256, 256, i256);
+ divide(i256, n1, tmp);
+ divide(hh, n1, tmp);
+ }
+ incr(hh, 1, h1);
+ free(ZH);
+ free(ha);
+ return 0;
+}
+
+
+static int SM9_standard_init()
+{
+ big P1_x, P1_y;
+
+ para_q = mirvar(0);
+ N = mirvar(0);
+ P1_x = mirvar(0);
+ P1_y = mirvar(0);
+ para_a = mirvar(0);
+ para_b = mirvar(0);
+ para_t = mirvar(0);
+ X.a = mirvar(0);
+ X.b = mirvar(0);
+ P2.x.a = mirvar(0);
+ P2.x.b = mirvar(0);
+ P2.y.a = mirvar(0);
+ P2.y.b = mirvar(0);
+ P2.z.a = mirvar(0);
+ P2.z.b = mirvar(0);
+ P2.marker = MR_EPOINT_INFINITY;
+
+ P1 = epoint_init();
+ bytes_to_big(BNLEN, SM9_q, para_q);
+ bytes_to_big(BNLEN, SM9_P1x, P1_x);
+ bytes_to_big(BNLEN, SM9_P1y, P1_y);
+ bytes_to_big(BNLEN, SM9_a, para_a);
+ bytes_to_big(BNLEN, SM9_b, para_b);
+ bytes_to_big(BNLEN, SM9_N, N);
+ bytes_to_big(BNLEN, SM9_t, para_t);
+
+ mip->TWIST = MR_SEXTIC_M;
+ ecurve_init(para_a, para_b, para_q, MR_PROJECTIVE); //Initialises GF(q) elliptic curve
+ //MR_PROJECTIVE specifying projective coordinates
+ if(!epoint_set(P1_x, P1_y, 0, P1))
+ return SM9_G1BASEPOINT_SET_ERR;
+
+ if(!(bytes128_to_ecn2(SM9_P2, &P2)))
+ return SM9_G2BASEPOINT_SET_ERR;
+ set_frobenius_constant(&X);
+
+ return 0;
+}
+
+
+static int SM9_standard_generateencryptkey(unsigned char hid[], unsigned char *ID, int IDlen, big ke, unsigned char Ppubs[], unsigned char deB[])
+{
+ big h1, t1, t2, rem, xPpub, yPpub, tmp;
+ unsigned char *Z = NULL;
+ int Zlen = IDlen + 1, buf;
+ ecn2 dEB;
+ epoint *Ppub;
+
+ h1 = mirvar(0);
+ t1 = mirvar(0);
+ t2 = mirvar(0);
+ rem = mirvar(0);
+ tmp = mirvar(0);
+ xPpub = mirvar(0);
+ yPpub = mirvar(0);
+ Ppub = epoint_init();
+ dEB.x.a = mirvar(0);
+ dEB.x.b = mirvar(0);
+ dEB.y.a = mirvar(0);
+ dEB.y.b = mirvar(0);
+ dEB.z.a = mirvar(0);
+ dEB.z.b = mirvar(0);
+ dEB.marker = MR_EPOINT_INFINITY;
+
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ memcpy(Z, ID, IDlen);
+ memcpy(Z + IDlen, hid, 1);
+
+ buf = SM9_standard_h1(Z, Zlen, N, h1);
+ if(buf != 0)
+ return buf;
+ add(h1, ke, t1);//t1=H1(IDA||hid,N)+ks
+ xgcd(t1, N, t1, t1, t1);//t1=t1(-1)
+ multiply(ke, t1, t2);
+ divide(t2, N, rem);//t2=ks*t1(-1)
+
+ //Ppub=[ke]P2
+ ecurve_mult(ke, P1, Ppub);
+
+ //deB=[t2]P2
+ ecn2_copy(&P2, &dEB);
+ ecn2_mul(t2, &dEB);
+
+ printf("\n**************The private key deB = (xdeB, ydeB):*********************\n");
+ ecn2_Bytes128_Print(dEB);
+ printf("\n**********************PublicKey Ppubs=[ke]P1:*************************\n");
+ epoint_get(Ppub, xPpub, yPpub);
+ cotnum(xPpub, stdout);
+ cotnum(yPpub, stdout);
+
+ epoint_get(Ppub, xPpub, yPpub);
+ big_to_bytes(BNLEN, xPpub, Ppubs, 1);
+ big_to_bytes(BNLEN, yPpub, Ppubs + BNLEN, 1);
+
+ redc(dEB.x.b, tmp);
+ big_to_bytes(BNLEN, tmp, deB, 1);
+ redc(dEB.x.a, tmp);
+ big_to_bytes(BNLEN, tmp, deB + BNLEN, 1);
+ redc(dEB.y.b, tmp);
+ big_to_bytes(BNLEN, tmp, deB + BNLEN * 2, 1);
+ redc(dEB.y.a, tmp);
+ big_to_bytes(BNLEN, tmp, deB + BNLEN * 3, 1);
+
+ free(Z);
+ return 0;
+}
+
+
+static int Test_Range(big x)
+{
+ big one, decr_n;
+
+ one = mirvar(0);
+ decr_n = mirvar(0);
+
+ convert(1, one);
+ decr(N, 1, decr_n);
+
+ if((mr_compare(x, one) < 0) | (mr_compare(x, decr_n) > 0))
+ return 1;
+
+ return 0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/engines/sm_standard/sm9/sm9_standard_enc.c b/engines/sm_standard/sm9/sm9_standard_enc.c
new file mode 100644
index 00000000..474fcc49
--- /dev/null
+++ b/engines/sm_standard/sm9/sm9_standard_enc.c
@@ -0,0 +1,477 @@
+/* ====================================================================
+ * Copyright (c) 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 "sm9_standard.h"
+#include "sm4_standard.h"
+#include "miracl.h"
+#include "mirdef.h"
+
+
+void SM4_standard_block_encrypt(unsigned char key[], unsigned char * message, int mlen, unsigned char *cipher, int * cipher_len)
+{
+ unsigned char mess[16];
+ int i, rem = mlen % 16;
+
+ for(i = 0; i < mlen / 16; i++)
+ SM4_encrypt(key, &message[i * 16], &cipher[i * 16]);
+ //encrypt the last block
+ memset(mess, 16 - rem, 16);
+ if(rem)
+ memcpy(mess, &message[i * 16], rem);
+ SM4_encrypt(key, mess, &cipher[i*16]);
+}
+
+
+void SM4_standard_block_decrypt(unsigned char key[], unsigned char *cipher, int len, unsigned char *plain, int *plain_len)
+{
+ int i;
+ for(i = 0; i < len / 16; i++)
+ SM4_decrypt(key, cipher + i * 16, plain + i * 16);
+ *plain_len = len - plain[len - 1];
+}
+
+
+int SM9_standard_enc_mac(unsigned char *K, int Klen, unsigned char *M, int Mlen, unsigned char C[])
+{
+ unsigned char *Z = NULL;
+ int len = Klen + Mlen;
+ Z = (char *)malloc(sizeof(char)*(len + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(Z, M, Mlen);
+ memcpy(Z + Mlen, K, Klen);
+ SM3_256(Z, len, C);
+
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_encrypt(unsigned char hid[], unsigned char *IDB, unsigned char *message, int mlen, unsigned char rand[],
+ int EncID, int k1_len, int k2_len, unsigned char Ppub[], unsigned char C[], int *C_len)
+{
+ big h, x, y, r;
+ zzn12 g, w;
+ epoint *Ppube, *QB, *C1;
+ unsigned char *Z = NULL, *K = NULL, *C2 = NULL, C3[SM3_len / 8];
+ int i = 0, j = 0, Zlen, buf, klen, C2_len;
+
+ //initiate
+ h = mirvar(0);
+ r = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ QB = epoint_init();
+ Ppube = epoint_init();
+ C1 = epoint_init();
+ zzn12_init(&g);
+ zzn12_init(&w);
+
+ bytes_to_big(BNLEN, Ppub, x);
+ bytes_to_big(BNLEN, Ppub + BNLEN, y);
+ epoint_set(x, y, 0, Ppube);
+
+ //Step1:calculate QB=[H1(IDB||hid,N)]P1+Ppube
+ Zlen = strlen(IDB) + 1;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(Z, IDB, strlen(IDB));
+ memcpy(Z + strlen(IDB), hid, 1);
+ buf = SM9_standard_h1(Z, Zlen, N, h);
+ if(buf)
+ return buf;
+ ecurve_mult(h, P1, QB);
+ ecurve_add(Ppube, QB);
+
+ printf("\n*******************QB:=[H1(IDB||hid,N)]P1+Ppube*****************\n");
+ epoint_get(QB, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+
+ //Step2:randnom
+ bytes_to_big(BNLEN, rand, r);
+ printf("\n***********************randnum r:********************************\n");
+ cotnum(r, stdout);
+
+ //Step3:C1=[r]QB
+ ecurve_mult(r, QB, C1);
+ printf("\n*************************:C1=[r]QB*******************************\n");
+ epoint_get(C1, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+ big_to_bytes(BNLEN, x, C, 1);
+ big_to_bytes(BNLEN, y, C + BNLEN, 1);
+
+ //Step4:g = e(P2, Ppub-e)
+ if(!ecap(P2, Ppube, para_t, X, &g))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(g, para_t, X))
+ return SM9_MEMBER_ERR;
+ printf("\n***********************g=e(P2,Ppube):****************************\n");
+ zzn12_ElementPrint(g);
+
+ //Step5:calculate w=g^r
+ w = zzn12_pow(g, r);
+ printf("\n***************************w=g^r:**********************************\n");
+ zzn12_ElementPrint(w);
+
+ free(Z);
+ //Step6:calculate C2
+ if(EncID == 0)
+ {
+ C2_len = mlen;
+ *C_len = BNLEN * 2 + SM3_len / 8 + C2_len;
+
+ //Step:6-1: calculate K=KDF(C1||w||IDB,klen)
+ klen = mlen + k2_len;
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ K = (char *)malloc(sizeof(char)*(klen + 1));
+ C2 = (char *)malloc(sizeof(char)*(mlen + 1));
+ if(Z == NULL || K == NULL || C2 == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12( C, BNLEN * 2, w, Z, (Zlen - strlen(IDB)));
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+ SM3_kdf(Z, Zlen, klen, K);
+ printf("\n*****************K=KDF(C1||w||IDB,klen):***********************\n");
+ for(i = 0; i < klen; i++)
+ printf("%02x", K[i]);
+
+ //Step:6-2: calculate C2=M^K1,and test if K1==0?
+ for(i = 0; i < mlen; i++)
+ {
+ if(K[i] == 0)
+ j = j + 1;
+ C2[i] = message[i] ^ K[i];
+ }
+ if(j == mlen)
+ return SM9_ERR_K1_ZERO;
+ printf("\n************************* C2=M^K1 :***************************\n");
+ for(i = 0; i < C2_len; i++)
+ printf("%02x", C2[i]);
+
+ //Step7:calculate C3=MAC(K2,C2)
+ SM9_standard_enc_mac(K + mlen, k2_len, C2, mlen, C3);
+ printf("\n********************** C3=MAC(K2,C2):*************************\n");
+ for(i = 0; i < 32; i++)
+ printf("%02x", C3[i]);
+
+ memcpy(C + BNLEN * 2, C3, SM3_len / 8);
+ memcpy(C + BNLEN * 2 + SM3_len / 8, C2, C2_len);
+ free(Z);
+ free(K);
+ free(C2);
+ }
+ else
+ {
+ C2_len = (mlen / 16 + 1) * 16;
+ *C_len = BNLEN * 2 + SM3_len / 8 + C2_len;
+
+ //Step:6-1: calculate K=KDF(C1||w||IDB,klen)
+ klen = k1_len + k2_len;
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ K = (char *)malloc(sizeof(char)*(klen + 1));
+ C2 = (char *)malloc(sizeof(char)*(C2_len + 1));
+ if(Z == NULL || K == NULL || C2 == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(C, BNLEN * 2, w, Z, Zlen - strlen(IDB));
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+ SM3_kdf(Z, Zlen, klen, K);
+ printf("\n*****************K=KDF(C1||w||IDB,klen):***********************\n");
+ for(i = 0; i < klen; i++)
+ printf("%02x", K[i]);
+
+ //Step:6-2: calculate C2=Enc(K1,M),and also test if K1==0?
+ for(i = 0; i < k1_len; i++)
+ {
+ if(K[i] == 0)
+ j = j + 1;
+ }
+ if(j == k1_len)
+ return SM9_ERR_K1_ZERO;
+
+ SM4_standard_block_encrypt(K, message, mlen, C2, &C2_len);
+ printf("\n*********************** C2=Enc(K1,M) :*************************\n");
+ for(i = 0; i < C2_len; i++)
+ printf("%02x", C2[i]);
+
+ //Step7:calculate C3=MAC(K2,C2)
+ SM9_standard_enc_mac(K + k1_len, k2_len, C2, C2_len, C3);
+ printf("\n********************** C3=MAC(K2,C2):*************************\n");
+ for(i = 0; i < 32; i++)
+ printf("%02x", C3[i]);
+
+ memcpy(C + BNLEN * 2, C3, SM3_len / 8);
+ memcpy(C + BNLEN * 2 + SM3_len / 8, C2, C2_len);
+ free(Z);
+ free(K);
+ free(C2);
+ }
+ return 0;
+}
+
+
+int SM9_standard_decrypt (unsigned char C[], int C_len, unsigned char deB[], unsigned char *IDB, int EncID,
+ int k1_len, int k2_len, unsigned char M[], int * Mlen)
+{
+ big x, y;
+ epoint *C1;
+ zzn12 w;
+ ecn2 dEB;
+ int mlen, klen, Zlen, i, number = 0;
+ unsigned char *Z = NULL, *K = NULL, *K1 = NULL, u[SM3_len / 8];
+
+ x = mirvar(0);
+ y = mirvar(0);
+ dEB.x.a = mirvar(0);
+ dEB.x.b = mirvar(0);
+ dEB.y.a = mirvar(0);
+ dEB.y.b = mirvar(0);
+ dEB.z.a = mirvar(0);
+ dEB.z.b = mirvar(0);
+ dEB.marker = MR_EPOINT_INFINITY;
+ C1 = epoint_init();
+ zzn12_init(&w);
+
+ bytes_to_big(BNLEN, C, x);
+ bytes_to_big(BNLEN, C + BNLEN, y);
+ bytes128_to_ecn2(deB, &dEB);
+
+ //Step1:get C1,and test if C1 is on G1
+ epoint_set(x, y, 1, C1);
+ if(Test_Point(C1))
+ return SM9_C1_NOT_VALID_G1;
+
+ //Step2:w = e(C1, deB)
+ if(!ecap(dEB, C1, para_t, X, &w))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(w, para_t, X)) return
+ SM9_MEMBER_ERR;
+ printf("\n*********************** w = e(C1, deB):****************************\n");
+ zzn12_ElementPrint(w);
+
+ //Step3:Calculate plaintext
+ mlen = C_len - BNLEN * 2 - SM3_len / 8;
+ if(EncID == 0)
+ {
+ //Step3-1:calculate K=KDF(C1||w||IDB,klen)
+ klen = mlen + k2_len;
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ K = (char *)malloc(sizeof(char)*(klen + 1));
+ if(Z == NULL || K == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(C, BNLEN * 2, w, Z, Zlen - strlen(IDB));
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+ SM3_kdf(Z, Zlen, klen, K);
+ printf("\n*****************K=KDF(C1||w||IDB,klen):***********************\n");
+ for(i = 0; i < klen; i++)
+ printf("%02x", K[i]);
+
+ //Step:3-2: calculate M=C2^K1,and test if K1==0?
+ for(i = 0; i < mlen; i++)
+ {
+ if(K[i] == 0)
+ number += 1;
+ M[i] = C[i + C_len - mlen] ^ K[i];
+ }
+ if(number == mlen)
+ return SM9_ERR_K1_ZERO;
+ *Mlen = mlen;
+
+ //Step4:calculate u=MAC(K2,C2)
+ SM9_standard_enc_mac(K + mlen, k2_len, &C[C_len - mlen], mlen, u);
+ if(memcmp(u, &C[BNLEN * 2], SM3_len / 8))
+ return SM9_C3_MEMCMP_ERR;
+
+ printf("\n****************************** M:******************************\n");
+ for(i = 0; i < mlen; i++)
+ printf("%02x", M[i]);
+ free(Z);
+ free(K);
+ }
+ else
+ {
+ //Step:3-1: calculate K=KDF(C1||w||IDB,klen)
+ klen = k1_len + k2_len;
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ K = (char *)malloc(sizeof(char)*(klen + 1));
+ K1 = (char *)malloc(sizeof(char)*(k1_len + 1));
+ if(Z == NULL || K == NULL || K1 == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(C, BNLEN * 2, w, Z, Zlen - strlen(IDB));
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+ SM3_kdf(Z, Zlen, klen, K);
+ printf("\n*****************K=KDF(C1||w||IDB,klen):***********************\n");
+ for(i = 0; i < klen; i++)
+ printf("%02x", K[i]);
+
+ //Step:3-2: calculate M=dec(K1,C2),and test if K1==0?
+ for(i = 0; i < k1_len; i++)
+ {
+ if(K[i] == 0)
+ number += 1;
+ K1[i] = K[i];
+ }
+ if(number == k1_len)
+ return SM9_ERR_K1_ZERO;
+ SM4_standard_block_decrypt(K1, &C[C_len - mlen], mlen, M, Mlen);
+
+ //Step4:calculate u=MAC(K2,C2)
+ SM9_standard_enc_mac(K + k1_len, k2_len, &C[C_len - mlen], mlen, u);
+ if(memcmp(u, &C[BNLEN * 2], SM3_len / 8))
+ return SM9_C3_MEMCMP_ERR;
+ free(Z);
+ free(K);
+ free(K1);
+ }
+ return 0;
+}
+
+
+int SM9_standard_enc_selfcheck()
+{
+ //the master private key
+ unsigned char KE[32] = {0x00, 0x01, 0xED, 0xEE, 0x37, 0x78, 0xF4, 0x41, 0xF8, 0xDE, 0xA3, 0xD9, 0xFA, 0x0A, 0xCC, 0x4E,
+ 0x07, 0xEE, 0x36, 0xC9, 0x3F, 0x9A, 0x08, 0x61, 0x8A, 0xF4, 0xAD, 0x85, 0xCE, 0xDE, 0x1C, 0x22};
+ unsigned char rand[32] = {0x00, 0x00, 0xAA, 0xC0, 0x54, 0x17, 0x79, 0xC8, 0xFC, 0x45, 0xE3, 0xE2, 0xCB, 0x25, 0xC1, 0x2B,
+ 0x5D, 0x25, 0x76, 0xB2, 0x12, 0x9A, 0xE8, 0xBB, 0x5E, 0xE2, 0xCB, 0xE5, 0xEC, 0x9E, 0x78, 0x5C};
+ //standard datas
+ unsigned char std_Ppub[64] = {0x78, 0x7E, 0xD7, 0xB8, 0xA5, 0x1F, 0x3A, 0xB8, 0x4E, 0x0A, 0x66, 0x00, 0x3F, 0x32, 0xDA, 0x5C,
+ 0x72, 0x0B, 0x17, 0xEC, 0xA7, 0x13, 0x7D, 0x39, 0xAB, 0xC6, 0x6E, 0x3C, 0x80, 0xA8, 0x92, 0xFF,
+ 0x76, 0x9D, 0xE6, 0x17, 0x91, 0xE5, 0xAD, 0xC4, 0xB9, 0xFF, 0x85, 0xA3, 0x13, 0x54, 0x90, 0x0B,
+ 0x20, 0x28, 0x71, 0x27, 0x9A, 0x8C, 0x49, 0xDC, 0x3F, 0x22, 0x0F, 0x64, 0x4C, 0x57, 0xA7, 0xB1};
+ unsigned char std_deB[128] = {0x94, 0x73, 0x6A, 0xCD, 0x2C, 0x8C, 0x87, 0x96, 0xCC, 0x47, 0x85, 0xE9, 0x38, 0x30, 0x1A, 0x13,
+ 0x9A, 0x05, 0x9D, 0x35, 0x37, 0xB6, 0x41, 0x41, 0x40, 0xB2, 0xD3, 0x1E, 0xEC, 0xF4, 0x16, 0x83,
+ 0x11, 0x5B, 0xAE, 0x85, 0xF5, 0xD8, 0xBC, 0x6C, 0x3D, 0xBD, 0x9E, 0x53, 0x42, 0x97, 0x9A, 0xCC,
+ 0xCF, 0x3C, 0x2F, 0x4F, 0x28, 0x42, 0x0B, 0x1C, 0xB4, 0xF8, 0xC0, 0xB5, 0x9A, 0x19, 0xB1, 0x58,
+ 0x7A, 0xA5, 0xE4, 0x75, 0x70, 0xDA, 0x76, 0x00, 0xCD, 0x76, 0x0A, 0x0C, 0xF7, 0xBE, 0xAF, 0x71,
+ 0xC4, 0x47, 0xF3, 0x84, 0x47, 0x53, 0xFE, 0x74, 0xFA, 0x7B, 0xA9, 0x2C, 0xA7, 0xD3, 0xB5, 0x5F,
+ 0x27, 0x53, 0x8A, 0x62, 0xE7, 0xF7, 0xBF, 0xB5, 0x1D, 0xCE, 0x08, 0x70, 0x47, 0x96, 0xD9, 0x4C,
+ 0x9D, 0x56, 0x73, 0x4F, 0x11, 0x9E, 0xA4, 0x47, 0x32, 0xB5, 0x0E, 0x31, 0xCD, 0xEB, 0x75, 0xC1};
+ unsigned char std_C_stream[116] = {0x24, 0x45, 0x47, 0x11, 0x64, 0x49, 0x06, 0x18, 0xE1, 0xEE, 0x20, 0x52, 0x8F, 0xF1, 0xD5, 0x45,
+ 0xB0, 0xF1, 0x4C, 0x8B, 0xCA, 0xA4, 0x45, 0x44, 0xF0, 0x3D, 0xAB, 0x5D, 0xAC, 0x07, 0xD8, 0xFF,
+ 0x42, 0xFF, 0xCA, 0x97, 0xD5, 0x7C, 0xDD, 0xC0, 0x5E, 0xA4, 0x05, 0xF2, 0xE5, 0x86, 0xFE, 0xB3,
+ 0xA6, 0x93, 0x07, 0x15, 0x53, 0x2B, 0x80, 0x00, 0x75, 0x9F, 0x13, 0x05, 0x9E, 0xD5, 0x9A, 0xC0,
+ 0xBA, 0x67, 0x23, 0x87, 0xBC, 0xD6, 0xDE, 0x50, 0x16, 0xA1, 0x58, 0xA5, 0x2B, 0xB2, 0xE7, 0xFC,
+ 0x42, 0x91, 0x97, 0xBC, 0xAB, 0x70, 0xB2, 0x5A, 0xFE, 0xE3, 0x7A, 0x2B, 0x9D, 0xB9, 0xF3, 0x67,
+ 0x1B, 0x5F, 0x5B, 0x0E, 0x95, 0x14, 0x89, 0x68, 0x2F, 0x3E, 0x64, 0xE1, 0x37, 0x8C, 0xDD, 0x5D,
+ 0xA9, 0x51, 0x3B, 0x1C};
+ unsigned char std_C_cipher[128] = {0x24, 0x45, 0x47, 0x11, 0x64, 0x49, 0x06, 0x18, 0xE1, 0xEE, 0x20, 0x52, 0x8F, 0xF1, 0xD5, 0x45,
+ 0xB0, 0xF1, 0x4C, 0x8B, 0xCA, 0xA4, 0x45, 0x44, 0xF0, 0x3D, 0xAB, 0x5D, 0xAC, 0x07, 0xD8, 0xFF,
+ 0x42, 0xFF, 0xCA, 0x97, 0xD5, 0x7C, 0xDD, 0xC0, 0x5E, 0xA4, 0x05, 0xF2, 0xE5, 0x86, 0xFE, 0xB3,
+ 0xA6, 0x93, 0x07, 0x15, 0x53, 0x2B, 0x80, 0x00, 0x75, 0x9F, 0x13, 0x05, 0x9E, 0xD5, 0x9A, 0xC0,
+ 0xFD, 0x3C, 0x98, 0xDD, 0x92, 0xC4, 0x4C, 0x68, 0x33, 0x26, 0x75, 0xA3, 0x70, 0xCC, 0xEE, 0xDE,
+ 0x31, 0xE0, 0xC5, 0xCD, 0x20, 0x9C, 0x25, 0x76, 0x01, 0x14, 0x9D, 0x12, 0xB3, 0x94, 0xA2, 0xBE,
+ 0xE0, 0x5B, 0x6F, 0xAC, 0x6F, 0x11, 0xB9, 0x65, 0x26, 0x8C, 0x99, 0x4F, 0x00, 0xDB, 0xA7, 0xA8,
+ 0xBB, 0x00, 0xFD, 0x60, 0x58, 0x35, 0x46, 0xCB, 0xDF, 0x46, 0x49, 0x25, 0x08, 0x63, 0xF1, 0x0A};
+ unsigned char *std_message = "Chinese IBE standard";
+ unsigned char hid[] = {0x03};
+ unsigned char *IDB = "Bob";
+
+ unsigned char Ppub[64], deB[128];
+ unsigned char message[1000], C[1000];
+ int M_len, C_len;//M_len the length of message //C_len the length of C
+ int k1_len = 16, k2_len = 32;
+ int EncID = 0;//0,stream //1 block
+ int tmp, i;
+ big ke;
+
+ tmp = SM9_standard_init();
+ if(tmp != 0)
+ return tmp;
+
+ ke = mirvar(0);
+ bytes_to_big(32, KE, ke);
+
+ printf("\n*********************** SM9 key Generation ***************************\n");
+ tmp = SM9_standard_generateencryptkey(hid, IDB, strlen(IDB), ke, Ppub, deB);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(Ppub, std_Ppub, 64) != 0)
+ return SM9_GEPUB_ERR;
+ if(memcmp(deB, std_deB, 128) !=0)
+ return SM9_GEPRI_ERR;
+
+ printf("\n*********************** SM9 encrypt algorithm **************************\n");
+ tmp = SM9_standard_encrypt(hid, IDB, std_message, strlen(std_message), rand, EncID, k1_len, k2_len, Ppub, C, &C_len);
+ if(tmp != 0)
+ return tmp;
+ printf("\n******************************Cipher:************************************\n");
+ for(i = 0; i < C_len; i++)
+ printf("%02x", C[i]);
+ if(EncID == 0)
+ tmp = memcmp(C, std_C_stream, C_len);
+ else
+ tmp = memcmp(C, std_C_cipher, C_len);
+ if(tmp)
+ return SM9_ENCRYPT_ERR;
+
+ printf("\n********************** SM9 Decrypt algorithm **************************\n");
+ tmp = SM9_standard_decrypt(std_C_cipher, 128, deB, IDB, 2, k1_len, k2_len, message, &M_len);
+ printf("\n**************************** Message:***********************************\n");
+ for(i = 0; i < M_len; i++)
+ printf("%02x", message[i]);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(message, std_message, M_len) != 0)
+ return SM9_DECRYPT_ERR;
+
+ return 0;
+}
diff --git a/engines/sm_standard/sm9/sm9_standard_encap.c b/engines/sm_standard/sm9/sm9_standard_encap.c
new file mode 100644
index 00000000..a1c8128b
--- /dev/null
+++ b/engines/sm_standard/sm9/sm9_standard_encap.c
@@ -0,0 +1,307 @@
+/* ====================================================================
+ * Copyright (c) 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 "sm9_standard.h"
+#include "miracl.h"
+#include "mirdef.h"
+
+
+int SM9_standard_key_encap(unsigned char hid[], unsigned char *IDB, unsigned char rand[],
+ unsigned char Ppub[], unsigned char C[], unsigned char K[], int Klen)
+{
+ big h, x, y, r;
+ epoint *Ppube, *QB, *Cipher;
+ unsigned char *Z = NULL;
+ int Zlen, buf, i, num = 0;
+ zzn12 g, w;
+
+ //initiate
+ h = mirvar(0);
+ r = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ QB = epoint_init();
+ Ppube = epoint_init();
+ Cipher = epoint_init();
+ zzn12_init(&g);
+ zzn12_init(&w);
+
+ bytes_to_big(BNLEN, Ppub, x);
+ bytes_to_big(BNLEN, Ppub + BNLEN, y);
+ epoint_set(x, y, 0, Ppube);
+
+ //----------Step1:calculate QB=[H1(IDB||hid,N)]P1+Ppube----------
+ Zlen = strlen(IDB) + 1;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(Z, IDB, strlen(IDB));
+ memcpy(Z + strlen(IDB), hid, 1);
+ buf = SM9_standard_h1(Z, Zlen, N, h);
+ free(Z);
+ if(buf)
+ return buf;
+ printf("\n************************ H1(IDB||hid,N) ************************\n");
+ cotnum(h, stdout);
+
+ ecurve_mult(h, P1, QB);
+ ecurve_add(Ppube, QB);
+ printf("\n*******************QB:=[H1(IDB||hid,N)]P1+Ppube*****************\n");
+ epoint_get(QB, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+
+ //-------------------- Step2:randnom -------------------
+ bytes_to_big(BNLEN, rand, r);
+ printf("\n***********************randnum r: ******************************\n");
+ cotnum(r, stdout);
+
+ //----------------Step3:C=[r]QB------------------------
+ ecurve_mult(r, QB, Cipher);
+ epoint_get(Cipher, x, y);
+ printf("\n*********************** C=[r]QB: ******************************\n");
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+ big_to_bytes(BNLEN, x, C, 1);
+ big_to_bytes(BNLEN, y, C + BNLEN, 1);
+
+ //----------------Step4:g=e(Ppube,P2)------------------------
+ if(!ecap(P2, Ppube, para_t, X, &g))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(g, para_t, X))
+ return SM9_MEMBER_ERR;
+
+ printf("\n***********************g=e(Ppube,P2):****************************\n");
+ zzn12_ElementPrint(g);
+
+ //----------------Step5:w=g^r------------------------
+ w = zzn12_pow(g, r);
+ printf("\n************************* w=g^r:*********************************\n");
+ zzn12_ElementPrint(w);
+
+ //----------------Step6:K=KDF(C||w||IDB,klen)------------------------
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ LinkCharZzn12(C, BNLEN * 2, w, Z, BNLEN * 14);
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+
+ SM3_kdf(Z, Zlen, Klen, K);
+ free(Z);
+ //----------------test if K equals 0------------------------
+ printf("\n******************* K=KDF(C||w||IDB,klen):***********************\n");
+ for(i = 0; i < Klen; i++)
+ {
+ if(K[i] == 0)
+ num += 1;
+ printf("%02x", K[i]);
+ }
+ if(num == Klen)
+ return SM9_ERR_K1_ZERO;
+
+ return 0;
+}
+
+
+int SM9_standard_key_decap(unsigned char *IDB, unsigned char deB[], unsigned char C[], int Klen, unsigned char K[])
+{
+ big h, x, y;
+ epoint *Cipher;
+ unsigned char *Z = NULL;
+ int Zlen, i, num = 0;
+ zzn12 w;
+ ecn2 dEB;
+
+ //initiate
+ h = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ Cipher = epoint_init();
+ zzn12_init(&w);
+ dEB.x.a = mirvar(0);
+ dEB.x.b = mirvar(0);
+ dEB.y.a = mirvar(0);
+ dEB.y.b = mirvar(0);
+ dEB.z.a = mirvar(0);
+ dEB.z.b = mirvar(0);
+ dEB.marker = MR_EPOINT_INFINITY;
+
+ bytes_to_big(BNLEN, C, x);
+ bytes_to_big(BNLEN, C + BNLEN, y);
+ epoint_set(x, y, 0, Cipher);
+ bytes128_to_ecn2(deB, &dEB);
+
+ //----------Step1:test if C is on G1-----------------
+ if(Test_Point(Cipher))
+ return SM9_NOT_VALID_G1;
+
+ //----------Step2:calculate w=e(C,deB)-----------------
+ if(!ecap(dEB, Cipher, para_t, X, &w))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(w, para_t, X))
+ return SM9_MEMBER_ERR;
+
+ printf("\n***********************w=e(C,deB):****************************\n");
+ zzn12_ElementPrint(w);
+
+ //----------Step3:K=KDF(C||w'||IDB,klen)------------------------
+ Zlen = strlen(IDB) + BNLEN * 14;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ LinkCharZzn12(C, BNLEN * 2, w, Z, BNLEN * 14);
+ memcpy(Z + BNLEN * 14, IDB, strlen(IDB));
+ SM3_kdf(Z, Zlen, Klen, K);
+
+ //----------------test if K equals 0------------------------
+ printf("\n******************* K=KDF(C||w||IDB,klen):***********************\n");
+ for(i = 0; i < Klen; i++)
+ {
+ if(K[i] == 0)
+ num += 1;
+ printf("%02x", K[i]);
+ }
+ if(num == Klen)
+ return SM9_ERR_K1_ZERO;
+
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_encap_selfcheck()
+{
+ //the master private key
+ unsigned char KE[32] = {0x00, 0x01, 0xED, 0xEE, 0x37, 0x78, 0xF4, 0x41, 0xF8, 0xDE, 0xA3, 0xD9, 0xFA, 0x0A, 0xCC, 0x4E,
+ 0x07, 0xEE, 0x36, 0xC9, 0x3F, 0x9A, 0x08, 0x61, 0x8A, 0xF4, 0xAD, 0x85, 0xCE, 0xDE, 0x1C, 0x22};
+ unsigned char rand[32] = {0x00, 0x00, 0x74, 0x01, 0x5F, 0x84, 0x89, 0xC0, 0x1E, 0xF4, 0x27, 0x04, 0x56, 0xF9, 0xE6, 0x47,
+ 0x5B, 0xFB, 0x60, 0x2B, 0xDE, 0x7F, 0x33, 0xFD, 0x48, 0x2A, 0xB4, 0xE3, 0x68, 0x4A, 0x67, 0x22};
+ //standard datas
+ unsigned char std_Ppub[64] = {0x78, 0x7E, 0xD7, 0xB8, 0xA5, 0x1F, 0x3A, 0xB8, 0x4E, 0x0A, 0x66, 0x00, 0x3F, 0x32, 0xDA, 0x5C,
+ 0x72, 0x0B, 0x17, 0xEC, 0xA7, 0x13, 0x7D, 0x39, 0xAB, 0xC6, 0x6E, 0x3C, 0x80, 0xA8, 0x92, 0xFF,
+ 0x76, 0x9D, 0xE6, 0x17, 0x91, 0xE5, 0xAD, 0xC4, 0xB9, 0xFF, 0x85, 0xA3, 0x13, 0x54, 0x90, 0x0B,
+ 0x20, 0x28, 0x71, 0x27, 0x9A, 0x8C, 0x49, 0xDC, 0x3F, 0x22, 0x0F, 0x64, 0x4C, 0x57, 0xA7, 0xB1};
+ unsigned char std_deB[128] = {0x94, 0x73, 0x6A, 0xCD, 0x2C, 0x8C, 0x87, 0x96, 0xCC, 0x47, 0x85, 0xE9, 0x38, 0x30, 0x1A, 0x13,
+ 0x9A, 0x05, 0x9D, 0x35, 0x37, 0xB6, 0x41, 0x41, 0x40, 0xB2, 0xD3, 0x1E, 0xEC, 0xF4, 0x16, 0x83,
+ 0x11, 0x5B, 0xAE, 0x85, 0xF5, 0xD8, 0xBC, 0x6C, 0x3D, 0xBD, 0x9E, 0x53, 0x42, 0x97, 0x9A, 0xCC,
+ 0xCF, 0x3C, 0x2F, 0x4F, 0x28, 0x42, 0x0B, 0x1C, 0xB4, 0xF8, 0xC0, 0xB5, 0x9A, 0x19, 0xB1, 0x58,
+ 0x7A, 0xA5, 0xE4, 0x75, 0x70, 0xDA, 0x76, 0x00, 0xCD, 0x76, 0x0A, 0x0C, 0xF7, 0xBE, 0xAF, 0x71,
+ 0xC4, 0x47, 0xF3, 0x84, 0x47, 0x53, 0xFE, 0x74, 0xFA, 0x7B, 0xA9, 0x2C, 0xA7, 0xD3, 0xB5, 0x5F,
+ 0x27, 0x53, 0x8A, 0x62, 0xE7, 0xF7, 0xBF, 0xB5, 0x1D, 0xCE, 0x08, 0x70, 0x47, 0x96, 0xD9, 0x4C,
+ 0x9D, 0x56, 0x73, 0x4F, 0x11, 0x9E, 0xA4, 0x47, 0x32, 0xB5, 0x0E, 0x31, 0xCD, 0xEB, 0x75, 0xC1};
+ unsigned char std_K[64] = {0x4F, 0xF5, 0xCF, 0x86, 0xD2, 0xAD, 0x40, 0xC8, 0xF4, 0xBA, 0xC9, 0x8D, 0x76, 0xAB, 0xDB, 0xDE,
+ 0x0C, 0x0E, 0x2F, 0x0A, 0x82, 0x9D, 0x3F, 0x91, 0x1E, 0xF5, 0xB2, 0xBC, 0xE0, 0x69, 0x54, 0x80};
+ unsigned char std_C[64] = {0x1E, 0xDE, 0xE2, 0xC3, 0xF4, 0x65, 0x91, 0x44, 0x91, 0xDE, 0x44, 0xCE, 0xFB, 0x2C, 0xB4, 0x34,
+ 0xAB, 0x02, 0xC3, 0x08, 0xD9, 0xDC, 0x5E, 0x20, 0x67, 0xB4, 0xFE, 0xD5, 0xAA, 0xAC, 0x8A, 0x0F,
+ 0x1C, 0x9B, 0x4C, 0x43, 0x5E, 0xCA, 0x35, 0xAB, 0x83, 0xBB, 0x73, 0x41, 0x74, 0xC0, 0xF7, 0x8F,
+ 0xDE, 0x81, 0xA5, 0x33, 0x74, 0xAF, 0xF3, 0xB3, 0x60, 0x2B, 0xBC, 0x5E, 0x37, 0xBE, 0x9A, 0x4C};
+
+ unsigned char hid[] = {0x03}, *IDB = "Bob";
+ unsigned char Ppub[64], deB[128], C[64], K[32], K_decap[32];
+ big ke;
+ int tmp, i;
+ int Klen = 32;
+
+ mip = mirsys(1000, 16);
+ mip->IOBASE = 16;
+ ke = mirvar(0);
+ bytes_to_big(32, KE, ke);
+
+ tmp = SM9_standard_init();
+ if(tmp != 0)
+ return tmp;
+
+ printf("\n*********************** SM9 key Generation ***************************\n");
+ tmp = SM9_standard_generateencryptkey(hid, IDB, strlen(IDB), ke, Ppub, deB);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(Ppub, std_Ppub, 64) != 0)
+ return SM9_GEPUB_ERR;
+ if(memcmp(deB, std_deB, 128) != 0)
+ return SM9_GEPRI_ERR;
+
+ printf("\n**********************PublicKey Ppubs=[ke]P1:*************************\n");
+ for(i = 0; i < 64; i++)
+ {
+ if(i == 32)
+ printf("\n");
+ printf("%02x", Ppub[i]);
+ }
+ printf("\n**************The private key deB = (xdeB, ydeB):*********************\n");
+ for(i = 0; i < 128; i++)
+ {
+ if(i == 64)
+ printf("\n");
+ printf("%02x", deB[i]);
+ }
+
+ printf("\n///////////////////SM9 Key encapsulation mechanism//////////////////////\n");
+ tmp = SM9_standard_key_encap(hid, IDB, rand, Ppub, C, K, Klen);
+ if(tmp != 0)
+ return tmp;
+
+ if(memcmp(C, std_C, 64) != 0)
+ return SM9_ERR_Encap_C;
+ if(memcmp(K, std_K, Klen) != 0)
+ return SM9_ERR_Encap_K;
+
+ printf("\n///////////////////SM9 Key decapsulation mechanism//////////////////////\n");
+ tmp = SM9_standard_key_decap(IDB, deB, C, Klen, K_decap);
+ if(tmp != 0)
+ return tmp;
+
+ if(memcmp(K_decap, std_K, 32) != 0)
+ return SM9_ERR_Decap_K;
+
+ return 0;
+}
diff --git a/engines/sm_standard/sm9/sm9_standard_exch.c b/engines/sm_standard/sm9/sm9_standard_exch.c
new file mode 100644
index 00000000..be986dfc
--- /dev/null
+++ b/engines/sm_standard/sm9/sm9_standard_exch.c
@@ -0,0 +1,525 @@
+/* ====================================================================
+ * Copyright (c) 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 "sm9_standard.h"
+#include "miracl.h"
+#include "mirdef.h"
+
+
+int SM9_standard_keyex_kdf(unsigned char *IDA, unsigned char *IDB, epoint *RA, epoint *RB, zzn12 g1, zzn12 g2, zzn12 g3, int klen, unsigned char K[])
+{
+ unsigned char *Z = NULL;
+ int Zlen;
+ int IDALen = strlen(IDA), IDBLen = strlen(IDB);
+ big x1, y1, x2, y2;
+
+ x1 = mirvar(0);
+ y1 = mirvar(0);
+ x2 = mirvar(0);
+ y2 = mirvar(0);
+ epoint_get(RA, x1, y1);
+ epoint_get(RB, x2, y2);
+
+ Zlen = IDALen + IDBLen + BNLEN * 40;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ memcpy(Z, IDA, IDALen);
+ memcpy(Z + IDALen, IDB, IDBLen);
+ big_to_bytes(BNLEN, x1, Z + IDALen + IDBLen, 1);
+ big_to_bytes(BNLEN, y1, Z + IDALen + IDBLen + BNLEN, 1);
+ big_to_bytes(BNLEN, x2, Z + IDALen + IDBLen + BNLEN * 2, 1);
+ big_to_bytes(BNLEN, y2, Z + IDALen + IDBLen + BNLEN * 3, 1);
+ LinkCharZzn12(Z, 0, g1, Z + IDALen + IDBLen + BNLEN * 4, BNLEN * 12);
+ LinkCharZzn12(Z, 0, g2, Z + IDALen + IDBLen + BNLEN * 16, BNLEN * 12);
+ LinkCharZzn12(Z, 0, g3, Z + IDALen + IDBLen + BNLEN * 28, BNLEN * 12);
+
+ SM3_kdf(Z, Zlen, klen, K);
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_keyex_hash(unsigned char hashid[], unsigned char *IDA, unsigned char *IDB, epoint *RA, epoint *RB, zzn12 g1, zzn12 g2, zzn12 g3, unsigned char hash[])
+{
+ int Zlen;
+ int IDALen = strlen(IDA), IDBLen = strlen(IDB);
+ unsigned char *Z = NULL;
+ big x1, y1, x2, y2;
+
+ x1 = mirvar(0);
+ y1 = mirvar(0);
+ x2 = mirvar(0);
+ y2 = mirvar(0);
+ epoint_get(RA, x1, y1);
+ epoint_get(RB, x2, y2);
+
+ Zlen = IDALen + IDBLen + BNLEN * 28;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(Z, 0, g2, Z, BNLEN * 12);
+ LinkCharZzn12(Z, 0, g3, Z + BNLEN * 12, BNLEN * 12);
+ memcpy(Z + BNLEN * 24, IDA, IDALen);
+ memcpy(Z + BNLEN * 24 + IDALen, IDB, IDBLen);
+ big_to_bytes(BNLEN, x1, Z + BNLEN * 24 + IDALen + IDBLen, 1);
+ big_to_bytes(BNLEN, y1, Z + BNLEN * 25 + IDALen + IDBLen, 1);
+ big_to_bytes(BNLEN, x2, Z + BNLEN * 26 + IDALen + IDBLen, 1);
+ big_to_bytes(BNLEN, y2, Z + BNLEN * 27 + IDALen + IDBLen, 1);
+
+ SM3_256(Z, Zlen, hash);
+
+ Zlen = 1 + BNLEN * 12 + SM3_len / 8;
+ memcpy(Z, hashid, 1);
+ LinkCharZzn12(Z, 1, g1, Z, 1 + BNLEN * 12);
+ memcpy(Z + 1 + BNLEN * 12, hash, SM3_len / 8);
+
+ SM3_256(Z, Zlen, hash);
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_keyex_inita_i(unsigned char hid[], unsigned char *IDB, unsigned char randA[],
+ unsigned char Ppub[], unsigned char deA[], epoint *RA)
+{
+ big h, x, y, rA;
+ epoint *Ppube, *QB;
+ unsigned char *Z = NULL;
+ int Zlen, buf;
+
+ //initiate
+ h = mirvar(0);
+ rA = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ QB = epoint_init();
+ Ppube = epoint_init();
+
+ bytes_to_big(BNLEN, Ppub, x);
+ bytes_to_big(BNLEN, Ppub + BNLEN, y);
+ epoint_set(x, y, 0, Ppube);
+
+ //----------A1:calculate QB=[H1(IDB||hid,N)]P1+Ppube----------
+ Zlen = strlen(IDB) + 1;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(Z, IDB, strlen(IDB));
+ memcpy(Z + strlen(IDB), hid, 1);
+ buf = SM9_standard_h1(Z, Zlen, N, h);
+ if(buf)
+ return buf;
+ ecurve_mult(h, P1, QB);
+ ecurve_add(Ppube, QB);
+ printf("\n*******************QB:=[H1(IDB||hid,N)]P1+Ppube*****************\n");
+ epoint_get(QB, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+
+ //--------------- Step A2:randnom -------------------
+ bytes_to_big(BNLEN, randA, rA);
+ printf("\n***********************randnum rA:******************************\n");
+ cotnum(rA, stdout);
+
+ //----------------Step A3:RA=[r]QB
+ ecurve_mult(rA, QB, RA);
+
+ free(Z);
+ return 0;
+}
+
+
+
+int SM9_standard_keyex_reb_i(unsigned char hid[], unsigned char *IDA, unsigned char *IDB, unsigned char randB[], unsigned char Ppub[],
+ unsigned char deB[], epoint *RA, epoint *RB, unsigned char SB[], zzn12 *g1, zzn12 *g2, zzn12 *g3)
+{
+ big h, x, y, rB;
+ epoint *Ppube, *QA;
+ unsigned char *Z = NULL, hashid[] = {0x82};
+ unsigned char SKB[16];
+ ecn2 dEB;
+ int Zlen, buf, i;
+
+ //initiate
+ h = mirvar(0);
+ rB = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ QA = epoint_init();
+ Ppube = epoint_init();
+ dEB.x.a = mirvar(0);
+ dEB.x.b = mirvar(0);
+ dEB.y.a = mirvar(0);
+ dEB.y.b = mirvar(0);
+ dEB.z.a = mirvar(0);
+ dEB.z.b = mirvar(0);
+ dEB.marker = MR_EPOINT_INFINITY;
+
+ bytes_to_big(BNLEN, Ppub, x);
+ bytes_to_big(BNLEN, Ppub + BNLEN, y);
+ bytes128_to_ecn2(deB, &dEB);
+ epoint_set(x, y, 0, Ppube);
+
+ //----------B1:calculate QA=[H1(IDA||hid,N)]P1+Ppube----------
+ Zlen = strlen(IDA) + 1;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(Z, IDA, strlen(IDA));
+ memcpy(Z + strlen(IDA), hid, 1);
+
+ buf = SM9_standard_h1(Z, Zlen, N, h);
+ if(buf)
+ return buf;
+ ecurve_mult(h, P1, QA);
+ ecurve_add(Ppube, QA);
+ printf("\n*******************QA:=[H1(IDA||hid,N)]P1+Ppube*****************\n");
+ epoint_get(QA, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+
+ //--------------- Step B2:randnom -------------------
+ bytes_to_big(BNLEN, randB, rB);
+ printf("\n***********************randnum rB:********************************\n");
+ cotnum(rB, stdout);
+
+ //----------------Step B3:RB=[rB]QA------------------
+ ecurve_mult(rB, QA, RB);
+ printf("\n*************************:RB=[rB]QA*******************************\n");
+ epoint_get(RB, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+
+ //test if RA is on G1
+ if(Test_Point(RA))
+ return SM9_NOT_VALID_G1;
+
+ //----------------Step B4:g1=e(deB,RA),g2=(e(P2,Ppube))^rB,g3=g1^rB
+ if(!ecap(dEB, RA, para_t, X, g1))
+ return SM9_MY_ECAP_12A_ERR;
+ if(!ecap(P2, Ppube, para_t, X, g2))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if((!member(*g1, para_t, X)) || (!member(*g2, para_t, X)))
+ return SM9_MEMBER_ERR;
+
+ *g2 = zzn12_pow(*g2, rB);
+ *g3 = zzn12_pow(*g1, rB);
+
+ printf("\n***********************g1=e(RA,deB):****************************\n");
+ zzn12_ElementPrint(*g1);
+ printf("\n*******************g2=(e(P2,Ppub3))^rB:*************************\n");
+ zzn12_ElementPrint(*g2);
+ printf("\n***********************g3=g1^rB:********************************\n");
+ zzn12_ElementPrint(*g3);
+
+ //---------------- B5:SKB=KDF(IDA||IDB||RA||RB||g1||g2||g3,klen)----------
+ buf = SM9_standard_keyex_kdf(IDA, IDB, RA, RB, *g1, *g2, *g3, 16, SKB);
+ if(buf)
+ return buf;
+ printf("\n***********SKB=KDF(IDA||IDB||RA||RB||g1||g2||g3,klen):***********\n");
+ for(i = 0; i < 16; i++)
+ printf("%02x", SKB[i]);
+
+ //---------------- B6(optional):SB=Hash(0x82||g1||Hash(g2||g3||IDA||IDB||RA||RB))----------
+ buf = SM9_standard_keyex_hash(hashid, IDA, IDB, RA, RB, *g1, *g2, *g3, SB);
+ if(buf)
+ return buf;
+ printf("\n********SB=Hash(0x82||g1||Hash(g2||g3||IDA||IDB||RA||RB))********\n");
+ for(i = 0; i < SM3_len / 8; i++)
+ printf("%02x", SB[i]);
+
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_keyex_inita_ii(unsigned char *IDA, unsigned char *IDB, unsigned char randA[], unsigned char Ppub[],
+ unsigned char deA[], epoint *RA, epoint *RB, unsigned char SB[], unsigned char SA[])
+{
+ big h, x, y, rA;
+ epoint *Ppube;
+ unsigned char hashid[] = {0x82};
+ unsigned char S1[SM3_len / 8], SKA[16];
+ zzn12 g1, g2, g3;
+ ecn2 dEA;
+ int buf, i;
+
+ //initiate
+ h = mirvar(0);
+ rA = mirvar(0);
+ x = mirvar(0);
+ y = mirvar(0);
+ Ppube = epoint_init();
+ dEA.x.a = mirvar(0);
+ dEA.x.b = mirvar(0);
+ dEA.y.a = mirvar(0);
+ dEA.y.b = mirvar(0);
+ dEA.z.a = mirvar(0);
+ dEA.z.b = mirvar(0);
+ dEA.marker = MR_EPOINT_INFINITY;
+ zzn12_init(&g1);
+ zzn12_init(&g2);
+ zzn12_init(&g3);
+
+ bytes_to_big(BNLEN, Ppub, x);
+ bytes_to_big(BNLEN, Ppub + BNLEN, y);
+ bytes_to_big(BNLEN, randA, rA);
+ bytes128_to_ecn2(deA, &dEA);
+ epoint_set(x, y, 0, Ppube);
+
+ //test if RB is on G1
+ if(Test_Point(RB))
+ return SM9_NOT_VALID_G1;
+
+ //----------------Step A5:g1=(e(P2,Ppube))^rA,g2=e(deA,RB),g3=g2^rA---------
+ if(!ecap(P2, Ppube, para_t, X, &g1))
+ return SM9_MY_ECAP_12A_ERR;
+ if(!ecap(dEA, RB, para_t, X, &g2))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if((!member(g1, para_t, X)) || (!member(g2, para_t, X)))
+ return SM9_MEMBER_ERR;
+
+ g1 = zzn12_pow(g1, rA);
+ g3 = zzn12_pow(g2, rA);
+ printf("\n***********************g1=e(Ppub,P2):****************************\n");
+ zzn12_ElementPrint(g1);
+ printf("\n*******************g2=(e(RB,deA))^rB:*************************\n");
+ zzn12_ElementPrint(g2);
+ printf("\n***********************g3=g2^rB:********************************\n");
+ zzn12_ElementPrint(g3);
+
+ //------------------ A6:S1=Hash(0x82||g1||Hash(g2||g3||IDA||IDB||RA||RB))----------
+ buf = SM9_standard_keyex_hash(hashid, IDA, IDB, RA, RB, g1, g2, g3, S1);
+ if(buf)
+ return buf;
+ printf("\n*********S1=Hash(0x82||g1||Hash(g2||g3||IDA||IDB||RA||RB))********\n");
+ for(i = 0; i < SM3_len / 8; i++)
+ printf("%02x", S1[i]);
+
+ if(memcmp(S1, SB, SM3_len / 8))
+ return SM9_ERR_CMP_S1SB;
+
+ //---------- A7: SKA=KDF(IDA||IDB||RA||RB||g1||g2||g3,klen)----------
+ buf = SM9_standard_keyex_kdf(IDA, IDB, RA, RB, g1, g2, g3, 16, SKA);
+ if(buf)
+ return buf;
+ printf("\n************SKA=KDF(IDA||IDB||RA||RB||g1||g2||g3,klen)************\n");
+ for(i = 0; i < 16; i++)
+ printf("%02x", SKA[i]);
+
+ //--------- A8(optional):SA=Hash(0x83||g1||Hash(g2||g3||IDA||IDB||RA||RB))----------
+ hashid[0] = (unsigned char)0x83;
+ buf = SM9_standard_keyex_hash(hashid, IDA, IDB, RA, RB, g1, g2, g3, SA);
+ if(buf)
+ return buf;
+ printf("\n*********SA=Hash(0x83||g1||Hash(g2||g3||IDA||IDB||RA||RB))********\n");
+ for(i = 0; i < SM3_len / 8; i++)
+ printf("%02x", SA[i]);
+
+ return 0;
+}
+
+
+int SM9_standard_keyex_reb_ii(unsigned char *IDA, unsigned char *IDB, zzn12 g1, zzn12 g2, zzn12 g3, epoint *RA, epoint *RB, unsigned char SA[])
+{
+ unsigned char hashid[] = {0x83};
+ unsigned char S2[SM3_len / 8];
+ int buf, i;
+
+ //---------------- B8(optional):S2=Hash(0x83||g1||Hash(g2||g3||IDA||IDB||RA||RB))----------
+ buf = SM9_standard_keyex_hash(hashid, IDA, IDB, RA, RB, g1, g2, g3, S2);
+ if(buf)
+ return buf;
+ printf("\n*************** S2=Hash(0x83||g1||Hash(g2||g3||IDA||IDB||RA||RB))****************\n");
+ for(i = 0; i < SM3_len / 8; i++)
+ printf("%02x", S2[i]);
+
+ if(memcmp(S2, SA, SM3_len / 8))
+ return SM9_ERR_CMP_S2SA;
+ return 0;
+}
+
+
+int SM9_standard_exch_selfcheck()
+{
+ //the master private key
+ unsigned char KE[32] = {0x00, 0x02, 0xE6, 0x5B, 0x07, 0x62, 0xD0, 0x42, 0xF5, 0x1F, 0x0D, 0x23, 0x54, 0x2B, 0x13, 0xED,
+ 0x8C, 0xFA, 0x2E, 0x9A, 0x0E, 0x72, 0x06, 0x36, 0x1E, 0x01, 0x3A, 0x28, 0x39, 0x05, 0xE3, 0x1F};
+ unsigned char randA[32] = {0x00, 0x00, 0x58, 0x79, 0xDD, 0x1D, 0x51, 0xE1, 0x75, 0x94, 0x6F, 0x23, 0xB1, 0xB4, 0x1E, 0x93,
+ 0xBA, 0x31, 0xC5, 0x84, 0xAE, 0x59, 0xA4, 0x26, 0xEC, 0x10, 0x46, 0xA4, 0xD0, 0x3B, 0x06, 0xC8};
+ unsigned char randB[32] = {0x00, 0x01, 0x8B, 0x98, 0xC4, 0x4B, 0xEF, 0x9F, 0x85, 0x37, 0xFB, 0x7D, 0x07, 0x1B, 0x2C, 0x92,
+ 0x8B, 0x3B, 0xC6, 0x5B, 0xD3, 0xD6, 0x9E, 0x1E, 0xEE, 0x21, 0x35, 0x64, 0x90, 0x56, 0x34, 0xFE};
+ //standard datas
+ unsigned char std_Ppub[64] = {0x91, 0x74, 0x54, 0x26, 0x68, 0xE8, 0xF1, 0x4A, 0xB2, 0x73, 0xC0, 0x94, 0x5C, 0x36, 0x90, 0xC6,
+ 0x6E, 0x5D, 0xD0, 0x96, 0x78, 0xB8, 0x6F, 0x73, 0x4C, 0x43, 0x50, 0x56, 0x7E, 0xD0, 0x62, 0x83,
+ 0x54, 0xE5, 0x98, 0xC6, 0xBF, 0x74, 0x9A, 0x3D, 0xAC, 0xC9, 0xFF, 0xFE, 0xDD, 0x9D, 0xB6, 0x86,
+ 0x6C, 0x50, 0x45, 0x7C, 0xFC, 0x7A, 0xA2, 0xA4, 0xAD, 0x65, 0xC3, 0x16, 0x8F, 0xF7, 0x42, 0x10};
+ unsigned char std_deA[128] = {0x0F, 0xE8, 0xEA, 0xB3, 0x95, 0x19, 0x9B, 0x56, 0xBF, 0x1D, 0x75, 0xBD, 0x2C, 0xD6, 0x10, 0xB6,
+ 0x42, 0x4F, 0x08, 0xD1, 0x09, 0x29, 0x22, 0xC5, 0x88, 0x2B, 0x52, 0xDC, 0xD6, 0xCA, 0x83, 0x2A,
+ 0x7D, 0xA5, 0x7B, 0xC5, 0x02, 0x41, 0xF9, 0xE5, 0xBF, 0xDD, 0xC0, 0x75, 0xDD, 0x9D, 0x32, 0xC7,
+ 0x77, 0x71, 0x00, 0xD7, 0x36, 0x91, 0x6C, 0xFC, 0x16, 0x5D, 0x8D, 0x36, 0xE0, 0x63, 0x4C, 0xD7,
+ 0x83, 0xA4, 0x57, 0xDA, 0xF5, 0x2C, 0xAD, 0x46, 0x4C, 0x90, 0x3B, 0x26, 0x06, 0x2C, 0xAF, 0x93,
+ 0x7B, 0xB4, 0x0E, 0x37, 0xDA, 0xDE, 0xD9, 0xED, 0xA4, 0x01, 0x05, 0x0E, 0x49, 0xC8, 0xAD, 0x0C,
+ 0x69, 0x70, 0x87, 0x6B, 0x9A, 0xAD, 0x1B, 0x7A, 0x50, 0xBB, 0x48, 0x63, 0xA1, 0x1E, 0x57, 0x4A,
+ 0xF1, 0xFE, 0x3C, 0x59, 0x75, 0x16, 0x1D, 0x73, 0xDE, 0x4C, 0x3A, 0xF6, 0x21, 0xFB, 0x1E, 0xFB};
+ unsigned char std_deB[128] = {0x74, 0xCC, 0xC3, 0xAC, 0x9C, 0x38, 0x3C, 0x60, 0xAF, 0x08, 0x39, 0x72, 0xB9, 0x6D, 0x05, 0xC7,
+ 0x5F, 0x12, 0xC8, 0x90, 0x7D, 0x12, 0x8A, 0x17, 0xAD, 0xAF, 0xBA, 0xB8, 0xC5, 0xA4, 0xAC, 0xF7,
+ 0x01, 0x09, 0x2F, 0xF4, 0xDE, 0x89, 0x36, 0x26, 0x70, 0xC2, 0x17, 0x11, 0xB6, 0xDB, 0xE5, 0x2D,
+ 0xCD, 0x5F, 0x8E, 0x40, 0xC6, 0x65, 0x4B, 0x3D, 0xEC, 0xE5, 0x73, 0xC2, 0xAB, 0x3D, 0x29, 0xB2,
+ 0x44, 0xB0, 0x29, 0x4A, 0xA0, 0x42, 0x90, 0xE1, 0x52, 0x4F, 0xF3, 0xE3, 0xDA, 0x8C, 0xFD, 0x43,
+ 0x2B, 0xB6, 0x4D, 0xE3, 0xA8, 0x04, 0x0B, 0x5B, 0x88, 0xD1, 0xB5, 0xFC, 0x86, 0xA4, 0xEB, 0xC1,
+ 0x8C, 0xFC, 0x48, 0xFB, 0x4F, 0xF3, 0x7F, 0x1E, 0x27, 0x72, 0x74, 0x64, 0xF3, 0xC3, 0x4E, 0x21,
+ 0x53, 0x86, 0x1A, 0xD0, 0x8E, 0x97, 0x2D, 0x16, 0x25, 0xFC, 0x1A, 0x7B, 0xD1, 0x8D, 0x55, 0x39};
+ unsigned char std_RA[64] = {0x7C, 0xBA, 0x5B, 0x19, 0x06, 0x9E, 0xE6, 0x6A, 0xA7, 0x9D, 0x49, 0x04, 0x13, 0xD1, 0x18, 0x46,
+ 0xB9, 0xBA, 0x76, 0xDD, 0x22, 0x56, 0x7F, 0x80, 0x9C, 0xF2, 0x3B, 0x6D, 0x96, 0x4B, 0xB2, 0x65,
+ 0xA9, 0x76, 0x0C, 0x99, 0xCB, 0x6F, 0x70, 0x63, 0x43, 0xFE, 0xD0, 0x56, 0x37, 0x08, 0x58, 0x64,
+ 0x95, 0x8D, 0x6C, 0x90, 0x90, 0x2A, 0xBA, 0x7D, 0x40, 0x5F, 0xBE, 0xDF, 0x7B, 0x78, 0x15, 0x99};
+ unsigned char std_RB[64] = {0x86, 0x1E, 0x91, 0x48, 0x5F, 0xB7, 0x62, 0x3D, 0x27, 0x94, 0xF4, 0x95, 0x03, 0x1A, 0x35, 0x59,
+ 0x8B, 0x49, 0x3B, 0xD4, 0x5B, 0xE3, 0x78, 0x13, 0xAB, 0xC7, 0x10, 0xFC, 0xC1, 0xF3, 0x44, 0x82,
+ 0x32, 0xD9, 0x06, 0xA4, 0x69, 0xEB, 0xC1, 0x21, 0x6A, 0x80, 0x2A, 0x70, 0x52, 0xD5, 0x61, 0x7C,
+ 0xD4, 0x30, 0xFB, 0x56, 0xFB, 0xA7, 0x29, 0xD4, 0x1D, 0x9B, 0xD6, 0x68, 0xE9, 0xEB, 0x96, 0x00};
+ unsigned char std_SA[32] = {0x19, 0x5D, 0x1B, 0x72, 0x56, 0xBA, 0x7E, 0x0E, 0x67, 0xC7, 0x12, 0x02, 0xA2, 0x5F, 0x8C, 0x94,
+ 0xFF, 0x82, 0x41, 0x70, 0x2C, 0x2F, 0x55, 0xD6, 0x13, 0xAE, 0x1C, 0x6B, 0x98, 0x21, 0x51, 0x72};
+ unsigned char std_SB[32] = {0x3B, 0xB4, 0xBC, 0xEE, 0x81, 0x39, 0xC9, 0x60, 0xB4, 0xD6, 0x56, 0x6D, 0xB1, 0xE0, 0xD5, 0xF0,
+ 0xB2, 0x76, 0x76, 0x80, 0xE5, 0xE1, 0xBF, 0x93, 0x41, 0x03, 0xE6, 0xC6, 0x6E, 0x40, 0xFF, 0xEE};
+
+ unsigned char hid[] = {0x02}, *IDA = "Alice", *IDB = "Bob";
+ unsigned char Ppub[64], deA[128], deB[128];
+ unsigned char xy[64], SA[SM3_len / 8], SB[SM3_len / 8];
+ epoint *RA, *RB;
+ big ke, x, y;
+ zzn12 g1, g2, g3;
+ int tmp, i;
+
+ mip = mirsys(1000, 16);
+ mip->IOBASE = 16;
+ x = mirvar(0);
+ y = mirvar(0);
+ ke = mirvar(0);
+ bytes_to_big(32, KE, ke);
+ RA = epoint_init();
+ RB = epoint_init();
+ zzn12_init(&g1);
+ zzn12_init(&g2);
+ zzn12_init(&g3);
+
+ tmp = SM9_standard_init();
+ if(tmp != 0)
+ return tmp;
+
+ printf("\n*********************** SM9 key Generation ***************************\n");
+ tmp = SM9_standard_generateencryptkey(hid, IDA, strlen(IDA), ke, Ppub, deA);
+ if(tmp != 0)
+ return tmp;
+ tmp = SM9_standard_generateencryptkey(hid, IDB, strlen(IDB), ke, Ppub, deB);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(Ppub, std_Ppub, 64) != 0)
+ return SM9_GEPUB_ERR;
+ if(memcmp(deA, std_deA, 128) != 0)
+ return SM9_GEPRI_ERR;
+ if(memcmp(deB, std_deB, 128) != 0)
+ return SM9_GEPRI_ERR;
+
+ printf("\n**********************PublicKey Ppubs=[ke]P1:*************************\n");
+ for(i = 0; i < 64; i++)
+ printf("%02x", Ppub[i]);
+ printf("\n**************The private key deA = (xdeA, ydeA):*********************\n");
+ for(i = 0; i < 128; i++)
+ printf("%02x", deA[i]);
+ printf("\n**************The private key deB = (xdeB, ydeB):*********************\n");
+ for(i = 0; i < 128; i++)
+ printf("%02x", deB[i]);
+
+ printf("\n//////////////////// SM9 Key exchange A1-A4://////////////////////////\n");
+ tmp = SM9_standard_keyex_inita_i(hid, IDB, randA, Ppub, deA, RA);
+ if(tmp != 0)
+ return tmp;
+ printf("\n ////////////////////////////:RA=[r]QB //////////////////////////////\n");
+ epoint_get(RA, x, y);
+ cotnum(x, stdout);
+ cotnum(y, stdout);
+ big_to_bytes(BNLEN, x, xy, 1);
+ big_to_bytes(BNLEN, y, xy + BNLEN, 1);
+ if(memcmp(xy, std_RA, BNLEN * 2) != 0)
+ return SM9_ERR_RA;
+
+ printf("\n//////////////////////// SM9 Key exchange B1-B7:///////////////////////\n");
+ tmp = SM9_standard_keyex_reb_i(hid, IDA, IDB, randB, Ppub, deB, RA, RB, SB, &g1, &g2, &g3);
+ if(tmp != 0)
+ return tmp;
+ epoint_get(RB, x, y);
+ big_to_bytes(BNLEN, x, xy, 1);
+ big_to_bytes(BNLEN, y, xy + BNLEN, 1);
+
+ if(memcmp(xy, std_RB, BNLEN * 2) != 0)
+ return SM9_ERR_RB;
+ if(memcmp(SB, std_SB, SM3_len / 8) != 0)
+ return SM9_ERR_SB;
+
+ printf("\n//////////////////////// SM9 Key exchange A5-A8:///////////////////////\n");
+ tmp = SM9_standard_keyex_inita_ii(IDA, IDB, randA, Ppub, deA, RA, RB, SB, SA);
+ if(tmp!=0)
+ return tmp;
+ if(memcmp(SA, std_SA, SM3_len / 8) != 0)
+ return SM9_ERR_SA;
+
+ printf("\n//////////////////////// SM9 Key exchange B8:///////////////////////\n");
+ tmp = SM9_standard_keyex_reb_ii(IDA, IDB, g1, g2, g3, RA, RB, SA);
+ if(tmp != 0)
+ return tmp;
+
+ return 0;
+}
diff --git a/engines/sm_standard/sm9/sm9_standard_sv.c b/engines/sm_standard/sm9/sm9_standard_sv.c
new file mode 100644
index 00000000..f27fc534
--- /dev/null
+++ b/engines/sm_standard/sm9/sm9_standard_sv.c
@@ -0,0 +1,446 @@
+/* ====================================================================
+ * Copyright (c) 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 "sm9_standard.h"
+#include "miracl.h"
+#include "mirdef.h"
+#include
+
+
+int SM9_standard_h2(unsigned char Z[], int Zlen, big n, big h2)
+{
+ int hlen, ZHlen, i;
+ big hh, i256, tmp, n1;
+ unsigned char *ZH = NULL, *ha = NULL;
+
+ hh = mirvar(0);
+ i256 = mirvar(0);
+ tmp = mirvar(0);
+ n1 = mirvar(0);
+ convert(1, i256);
+ ZHlen = Zlen + 1;
+
+ hlen = (int)ceil((5.0 * logb2(n)) / 32.0);
+ decr(n, 1, n1);
+ ZH = (char *)malloc(sizeof(char)*(ZHlen + 1));
+ if(ZH == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ memcpy(ZH + 1, Z, Zlen);
+ ZH[0] = 0x02;
+ ha = (char *)malloc(sizeof(char)*(hlen + 1));
+ if(ha == NULL)
+ return SM9_ASK_MEMORY_ERR;
+ SM3_kdf(ZH, ZHlen, hlen, ha);
+
+ for(i = hlen - 1; i >= 0; i--)//key[从大到小]
+ {
+ premult(i256, ha[i], tmp);
+ add(hh, tmp, hh);
+ premult(i256, 256, i256);
+ divide(i256, n1, tmp);
+ divide(hh, n1, tmp);
+ }
+ incr(hh, 1, h2);
+ free(ZH);
+ free(ha);
+ return 0;
+}
+
+
+
+int SM9_standard_generatesignkey(unsigned char hid[], unsigned char *ID, int IDlen, big ks, unsigned char Ppubs[], unsigned char dsa[])
+{
+ big h1, t1, t2, rem, xdSA, ydSA, tmp;
+ unsigned char *Z = NULL;
+ int Zlen = IDlen + 1, buf;
+ ecn2 Ppub;
+ epoint *dSA;
+
+ h1 = mirvar(0);
+ t1 = mirvar(0);
+ t2 = mirvar(0);
+ rem = mirvar(0);
+ tmp = mirvar(0);
+ xdSA = mirvar(0);
+ ydSA = mirvar(0);
+ dSA = epoint_init();
+ Ppub.x.a = mirvar(0);
+ Ppub.x.b = mirvar(0);
+ Ppub.y.a = mirvar(0);
+ Ppub.y.b = mirvar(0);
+ Ppub.z.a = mirvar(0);
+ Ppub.z.b = mirvar(0);
+ Ppub.marker = MR_EPOINT_INFINITY;
+
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ memcpy(Z, ID, IDlen);
+ memcpy(Z + IDlen, hid, 1);
+
+ buf = SM9_standard_h1(Z, Zlen, N, h1);
+ if(buf != 0)
+ return buf;
+ add(h1, ks, t1);//t1=H1(IDA||hid,N)+ks
+ xgcd(t1, N, t1, t1, t1);//t1=t1(-1)
+ multiply(ks, t1, t2);
+ divide(t2, N, rem);//t2=ks*t1(-1)
+
+ //dSA=[t2]P1
+ ecurve_mult(t2, P1, dSA);
+
+ //Ppub=[ks]P2
+ ecn2_copy(&P2, &Ppub);
+ ecn2_mul(ks, &Ppub);
+
+ printf("\n*********************The signed key = (xdA, ydA):*********************\n");
+ epoint_get(dSA, xdSA, ydSA);
+ cotnum(xdSA, stdout);
+ cotnum(ydSA, stdout);
+ printf("\n**********************PublicKey Ppubs=[ks]P2:*************************\n");
+ ecn2_Bytes128_Print(Ppub);
+
+ epoint_get(dSA, xdSA, ydSA);
+ big_to_bytes(BNLEN, xdSA, dsa, 1);
+ big_to_bytes(BNLEN, ydSA, dsa + BNLEN, 1);
+
+ redc(Ppub.x.b, tmp);
+ big_to_bytes(BNLEN, tmp, Ppubs, 1);
+ redc(Ppub.x.a, tmp);
+ big_to_bytes(BNLEN, tmp, Ppubs + BNLEN, 1);
+ redc(Ppub.y.b, tmp);
+ big_to_bytes(BNLEN, tmp, Ppubs + BNLEN * 2, 1);
+ redc(Ppub.y.a, tmp);
+ big_to_bytes(BNLEN, tmp, Ppubs + BNLEN * 3, 1);
+
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_sign(unsigned char hid[], unsigned char *IDA, unsigned char *message, int len, unsigned char rand[], unsigned char dsa[], unsigned char Ppub[], unsigned char H[], unsigned char S[])
+{
+ big h1, r, h, l, xdSA, ydSA;
+ big xS, yS, tmp, zero;
+ zzn12 g, w;
+ epoint *s, *dSA;
+ ecn2 Ppubs;
+ int Zlen, buf;
+ unsigned char *Z = NULL;
+
+ //initiate
+ h1 = mirvar(0);
+ r = mirvar(0);
+ h = mirvar(0);
+ l = mirvar(0);
+ tmp = mirvar(0);
+ zero = mirvar(0);
+ xS = mirvar(0);
+ yS = mirvar(0);
+ xdSA = mirvar(0);
+ ydSA = mirvar(0);
+ s = epoint_init();
+ dSA = epoint_init();
+ Ppubs.x.a = mirvar(0);
+ Ppubs.x.b = mirvar(0);
+ Ppubs.y.a = mirvar(0);
+ Ppubs.y.b = mirvar(0);
+ Ppubs.z.a = mirvar(0);
+ Ppubs.z.b = mirvar(0);
+ Ppubs.marker = MR_EPOINT_INFINITY;
+ zzn12_init(&g);
+ zzn12_init(&w);
+
+ bytes_to_big(BNLEN, rand, r);
+ bytes_to_big(BNLEN, dsa, xdSA);
+ bytes_to_big(BNLEN, dsa + BNLEN, ydSA);
+ epoint_set(xdSA, ydSA, 0, dSA);
+ bytes128_to_ecn2(Ppub, &Ppubs);
+
+ //Step1:g = e(P1, Ppub-s)
+ if(!ecap(Ppubs, P1, para_t, X, &g))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(g, para_t, X))
+ return SM9_MEMBER_ERR;
+
+ printf("\n***********************g=e(P1,Ppubs):****************************\n");
+ zzn12_ElementPrint(g);
+
+ //Step2:calculate w=g(r)
+ printf("\n***********************randnum r:********************************\n");
+ cotnum(r, stdout);
+ w = zzn12_pow(g, r);
+ printf("\n***************************w=gr:**********************************\n");
+ zzn12_ElementPrint(w);
+
+ //Step3:calculate h=H2(M||w,N)
+ Zlen = len + 32 * 12;
+ Z = (char *)malloc(sizeof(char)*(Zlen + 1));
+ if(Z == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(message, len, w, Z, Zlen);
+ buf = SM9_standard_h2(Z, Zlen, N, h);
+ if(buf != 0)
+ return buf;
+ printf("\n****************************h:*************************************\n");
+ cotnum(h, stdout);
+
+ //Step4:l=(r-h)mod N
+ subtract(r, h, l);
+ divide(l, N, tmp);
+ while(mr_compare(l, zero) < 0)
+ add(l, N, l);
+ if(mr_compare(l, zero) == 0)
+ return SM9_L_error;
+ printf("\n**************************l=(r-h)mod N:****************************\n");
+ cotnum(l, stdout);
+
+ //Step5:S=[l]dSA=(xS,yS)
+ ecurve_mult(l, dSA, s);
+ epoint_get(s, xS, yS);
+ printf("\n**************************S=[l]dSA=(xS,yS):*************************\n");
+ cotnum(xS, stdout);
+ cotnum(yS, stdout);
+
+ big_to_bytes(32, h, H, 1);
+ big_to_bytes(32, xS, S, 1);
+ big_to_bytes(32, yS, S + 32, 1);
+
+ free(Z);
+ return 0;
+}
+
+
+int SM9_standard_verify(unsigned char H[], unsigned char S[], unsigned char hid[], unsigned char *IDA, unsigned char *message, int len, unsigned char Ppub[])
+{
+ big h, xS, yS, h1, h2;
+ epoint *S1;
+ zzn12 g, t, u, w;
+ ecn2 P, Ppubs;
+ int Zlen1, Zlen2, buf;
+ unsigned char * Z1 = NULL, *Z2 = NULL;
+
+ h = mirvar(0);
+ h1 = mirvar(0);
+ h2 = mirvar(0);
+ xS = mirvar(0);
+ yS = mirvar(0);
+ P.x.a = mirvar(0);
+ P.x.b = mirvar(0);
+ P.y.a = mirvar(0);
+ P.y.b = mirvar(0);
+ P.z.a = mirvar(0);
+ P.z.b = mirvar(0);
+ P.marker = MR_EPOINT_INFINITY;
+ Ppubs.x.a = mirvar(0);
+ Ppubs.x.b = mirvar(0);
+ Ppubs.y.a = mirvar(0);
+ Ppubs.y.b = mirvar(0);
+ Ppubs.z.a = mirvar(0);
+ Ppubs.z.b = mirvar(0);
+ Ppubs.marker = MR_EPOINT_INFINITY;
+ S1 = epoint_init();
+ zzn12_init(&g);
+ zzn12_init(&t);
+ zzn12_init(&u);
+ zzn12_init(&w);
+
+ bytes_to_big(BNLEN, H, h);
+ bytes_to_big(BNLEN, S, xS);
+ bytes_to_big(BNLEN, S + BNLEN, yS);
+ bytes128_to_ecn2(Ppub, &Ppubs);
+
+ //Step 1:test if h in the rangge [1,N-1]
+ if(Test_Range(h))
+ return SM9_H_OUTRANGE;
+
+ //Step 2:test if S is on G1
+ epoint_set(xS, yS, 0, S1);
+ if(Test_Point(S1))
+ return SM9_S_NOT_VALID_G1;
+
+ //Step3:g = e(P1, Ppub-s)
+ if(!ecap(Ppubs, P1, para_t, X, &g))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(g, para_t, X))
+ return SM9_MEMBER_ERR;
+
+ printf("\n***********************g=e(P1,Ppubs):****************************\n");
+ zzn12_ElementPrint(g);
+
+ //Step4:calculate t=g(h)
+ t = zzn12_pow(g, h);
+ printf("\n***************************w=gh:**********************************\n");
+ zzn12_ElementPrint(t);
+
+ //Step5:calculate h1=H1(IDA||hid,N)
+ Zlen1 = strlen(IDA) + 1;
+ Z1 = (char *)malloc(sizeof(char)*(Zlen1 + 1));
+ if(Z1 == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ memcpy(Z1, IDA, strlen(IDA));
+ memcpy(Z1 + strlen(IDA), hid, 1);
+ buf = SM9_standard_h1(Z1, Zlen1, N, h1);
+ if(buf != 0)
+ return buf;
+ printf("\n****************************h1:**********************************\n");
+ cotnum(h1, stdout);
+
+ //Step6:P=[h1]P2+Ppubs
+ ecn2_copy(&P2, &P);
+ ecn2_mul(h1, &P);
+ ecn2_add(&Ppubs, &P);
+
+ //Step7:u=e(S1,P)
+ if(!ecap(P, S1, para_t, X, &u))
+ return SM9_MY_ECAP_12A_ERR;
+ //test if a ZZn12 element is of order q
+ if(!member(u, para_t, X))
+ return SM9_MEMBER_ERR;
+ printf("\n************************** u=e(S1,P):*****************************\n");
+ zzn12_ElementPrint(u);
+
+ //Step8:w=u*t
+ zzn12_mul(u, t, &w);
+ printf("\n************************* w=u*t: **********************************\n");
+ zzn12_ElementPrint(w);
+
+ //Step9:h2=H2(M||w,N)
+ Zlen2 = len + 32 * 12;
+ Z2 = (char *)malloc(sizeof(char)*(Zlen2 + 1));
+ if(Z2 == NULL)
+ return SM9_ASK_MEMORY_ERR;
+
+ LinkCharZzn12(message, len, w, Z2, Zlen2);
+ buf = SM9_standard_h2(Z2, Zlen2, N, h2);
+ if(buf != 0)
+ return buf;
+ printf("\n**************************** h2:***********************************\n");
+ cotnum(h2, stdout);
+
+ free(Z1);
+ free(Z2);
+ if(mr_compare(h2, h) != 0)
+ return SM9_DATA_MEMCMP_ERR;
+
+ return 0;
+}
+
+
+int SM9_standard_sv_selfcheck()
+{
+ //the master private key
+ unsigned char dA[32] = {0x00, 0x01, 0x30, 0xE7, 0x84, 0x59, 0xD7, 0x85, 0x45, 0xCB, 0x54, 0xC5, 0x87, 0xE0, 0x2C, 0xF4,
+ 0x80, 0xCE, 0x0B, 0x66, 0x34, 0x0F, 0x31, 0x9F, 0x34, 0x8A, 0x1D, 0x5B, 0x1F, 0x2D, 0xC5, 0xF4};
+ unsigned char rand[32] = {0x00, 0x03, 0x3C, 0x86, 0x16, 0xB0, 0x67, 0x04, 0x81, 0x32, 0x03, 0xDF, 0xD0, 0x09, 0x65, 0x02,
+ 0x2E, 0xD1, 0x59, 0x75, 0xC6, 0x62, 0x33, 0x7A, 0xED, 0x64, 0x88, 0x35, 0xDC, 0x4B, 0x1C, 0xBE};
+
+ unsigned char h[32], S[64];// Signature
+ unsigned char Ppub[128], dSA[64];
+
+ unsigned char std_h[32] = {0x82, 0x3C, 0x4B, 0x21, 0xE4, 0xBD, 0x2D, 0xFE, 0x1E, 0xD9, 0x2C, 0x60, 0x66, 0x53, 0xE9, 0x96,
+ 0x66, 0x85, 0x63, 0x15, 0x2F, 0xC3, 0x3F, 0x55, 0xD7, 0xBF, 0xBB, 0x9B, 0xD9, 0x70, 0x5A, 0xDB};
+ unsigned char std_S[64] = {0x73, 0xBF, 0x96, 0x92, 0x3C, 0xE5, 0x8B, 0x6A, 0xD0, 0xE1, 0x3E, 0x96, 0x43, 0xA4, 0x06, 0xD8,
+ 0xEB, 0x98, 0x41, 0x7C, 0x50, 0xEF, 0x1B, 0x29, 0xCE, 0xF9, 0xAD, 0xB4, 0x8B, 0x6D, 0x59, 0x8C,
+ 0x85, 0x67, 0x12, 0xF1, 0xC2, 0xE0, 0x96, 0x8A, 0xB7, 0x76, 0x9F, 0x42, 0xA9, 0x95, 0x86, 0xAE,
+ 0xD1, 0x39, 0xD5, 0xB8, 0xB3, 0xE1, 0x58, 0x91, 0x82, 0x7C, 0xC2, 0xAC, 0xED, 0x9B, 0xAA, 0x05};
+ unsigned char std_Ppub[128] = {0x9F, 0x64, 0x08, 0x0B, 0x30, 0x84, 0xF7, 0x33, 0xE4, 0x8A, 0xFF, 0x4B, 0x41, 0xB5, 0x65, 0x01,
+ 0x1C, 0xE0, 0x71, 0x1C, 0x5E, 0x39, 0x2C, 0xFB, 0x0A, 0xB1, 0xB6, 0x79, 0x1B, 0x94, 0xC4, 0x08,
+ 0x29, 0xDB, 0xA1, 0x16, 0x15, 0x2D, 0x1F, 0x78, 0x6C, 0xE8, 0x43, 0xED, 0x24, 0xA3, 0xB5, 0x73,
+ 0x41, 0x4D, 0x21, 0x77, 0x38, 0x6A, 0x92, 0xDD, 0x8F, 0x14, 0xD6, 0x56, 0x96, 0xEA, 0x5E, 0x32,
+ 0x69, 0x85, 0x09, 0x38, 0xAB, 0xEA, 0x01, 0x12, 0xB5, 0x73, 0x29, 0xF4, 0x47, 0xE3, 0xA0, 0xCB,
+ 0xAD, 0x3E, 0x2F, 0xDB, 0x1A, 0x77, 0xF3, 0x35, 0xE8, 0x9E, 0x14, 0x08, 0xD0, 0xEF, 0x1C, 0x25,
+ 0x41, 0xE0, 0x0A, 0x53, 0xDD, 0xA5, 0x32, 0xDA, 0x1A, 0x7C, 0xE0, 0x27, 0xB7, 0xA4, 0x6F, 0x74,
+ 0x10, 0x06, 0xE8,0x5F,0x5C,0xDF,0xF0,0x73,0x0E,0x75,0xC0,0x5F,0xB4,0xE3,0x21, 0x6D};
+ unsigned char std_dSA[64] = {0xA5, 0x70, 0x2F, 0x05, 0xCF, 0x13, 0x15, 0x30, 0x5E, 0x2D, 0x6E, 0xB6, 0x4B, 0x0D, 0xEB, 0x92,
+ 0x3D, 0xB1, 0xA0, 0xBC, 0xF0, 0xCA, 0xFF, 0x90, 0x52, 0x3A, 0xC8, 0x75, 0x4A, 0xA6, 0x98, 0x20,
+ 0x78, 0x55, 0x9A, 0x84, 0x44, 0x11, 0xF9, 0x82, 0x5C, 0x10, 0x9F, 0x5E, 0xE3, 0xF5, 0x2D, 0x72,
+ 0x0D, 0xD0, 0x17, 0x85, 0x39, 0x2A, 0x72, 0x7B, 0xB1, 0x55, 0x69, 0x52, 0xB2, 0xB0, 0x13, 0xD3};
+
+ unsigned char hid[] = {0x01};
+ unsigned char *IDA = "Alice";
+ unsigned char *message = "Chinese IBS standard";//the message to be signed
+ int mlen = strlen(message), tmp;//the length of message
+ big ks;
+
+ tmp = SM9_standard_init();
+
+ if(tmp != 0)
+ return tmp;
+ ks = mirvar(0);
+
+ bytes_to_big(32, dA, ks);
+
+ printf("\n*********************** SM9 key Generation ***************************\n");
+ tmp = SM9_standard_generatesignkey(hid, IDA, strlen(IDA), ks, Ppub, dSA);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(Ppub, std_Ppub, 128) != 0)
+ return SM9_GEPUB_ERR;
+ if(memcmp(dSA, std_dSA, 64) != 0)
+ return SM9_GEPRI_ERR;
+
+ printf("\n********************** SM9 signature algorithm***************************\n");
+ tmp = SM9_standard_sign(hid, IDA, message, mlen, rand, dSA, Ppub, h, S);
+ if(tmp != 0)
+ return tmp;
+ if(memcmp(h, std_h, 32) != 0)
+ return SM9_SIGN_ERR;
+ if(memcmp(S, std_S, 64) != 0)
+ return SM9_SIGN_ERR;
+ printf("\n******************* SM9 verification algorithm *************************\n");
+ tmp = SM9_standard_verify(h, S, hid, IDA, message, mlen, Ppub);
+ if(tmp != 0)
+ return tmp;
+
+ return 0;
+}
diff --git a/engines/sm_standard/sm9/zzn12_operation.h b/engines/sm_standard/sm9/zzn12_operation.h
new file mode 100644
index 00000000..3f535113
--- /dev/null
+++ b/engines/sm_standard/sm9/zzn12_operation.h
@@ -0,0 +1,462 @@
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ */
+
+#ifndef HEADER_ZZN12_OPERATION_H
+#define HEADER_ZZN12_OPERATION_H
+
+
+#include "miracl.h"
+
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+miracl* mip;
+zzn2 X; //Frobniues constant
+typedef struct
+{
+ zzn4 a, b, c;
+ BOOL unitary; // "unitary property means that fast squaring can be used, and inversions are just conjugates
+ BOOL miller; // "miller" property means that arithmetic on this instance can ignore multiplications
+ // or divisions by constants - as instance will eventually be raised to (p-1).
+} zzn12;
+
+
+static void zzn12_init(zzn12 *x)
+{
+ x->a.a.a = mirvar(0);
+ x->a.a.b = mirvar(0);
+
+ x->a.b.a = mirvar(0);
+ x->a.b.b = mirvar(0);
+
+ x->a.unitary = FALSE;
+
+
+ x->b.a.a = mirvar(0);
+ x->b.a.b = mirvar(0);
+
+ x->b.b.a = mirvar(0);
+ x->b.b.b = mirvar(0);
+
+ x->b.unitary = FALSE;
+
+
+ x->c.a.a = mirvar(0);
+ x->c.a.b = mirvar(0);
+
+ x->c.b.a = mirvar(0);
+ x->c.b.b = mirvar(0);
+
+ x->c.unitary = FALSE;
+
+
+ x->miller = FALSE;
+ x->unitary = FALSE;
+}
+
+
+static void zzn12_copy(zzn12 *x, zzn12 *y)
+{
+ zzn4_copy(&x->a, &y->a);
+ zzn4_copy(&x->b, &y->b);
+ zzn4_copy(&x->c, &y->c);
+
+ y->miller = x->miller;
+ y->unitary = x->unitary;
+}
+
+
+static void zzn12_mul(zzn12 x, zzn12 y, zzn12 *z)
+{
+ // Karatsuba
+ zzn4 Z0, Z1, Z2, Z3, T0, T1;
+ BOOL zero_c, zero_b;
+
+ Z0.a.a = mirvar(0);
+ Z0.a.b = mirvar(0);
+
+ Z0.b.a = mirvar(0);
+ Z0.b.b = mirvar(0);
+
+ Z0.unitary = FALSE;
+
+
+ Z1.a.a = mirvar(0);
+ Z1.a.b = mirvar(0);
+
+ Z1.b.a = mirvar(0);
+ Z1.b.b = mirvar(0);
+
+ Z1.unitary = FALSE;
+
+
+ Z2.a.a = mirvar(0);
+ Z2.a.b = mirvar(0);
+
+ Z2.b.a = mirvar(0);
+ Z2.b.b = mirvar(0);
+
+ Z2.unitary = FALSE;
+
+
+ Z3.a.a = mirvar(0);
+ Z3.a.b = mirvar(0);
+
+ Z3.b.a = mirvar(0);
+ Z3.b.b = mirvar(0);
+
+ Z3.unitary = FALSE;
+
+
+ T0.a.a = mirvar(0);
+ T0.a.b = mirvar(0);
+
+ T0.b.a = mirvar(0);
+ T0.b.b = mirvar(0);
+
+ T0.unitary = FALSE;
+
+
+ T1.a.a = mirvar(0);
+ T1.a.b = mirvar(0);
+
+ T1.b.a = mirvar(0);
+ T1.b.b = mirvar(0);
+
+ T1.unitary = FALSE;
+
+
+ zzn12_copy(&x, z);
+ if(zzn4_compare(&x.a, &y.a) && zzn4_compare(&x.a, &y.a) && zzn4_compare(&x.a, &y.a))
+ {
+ if(x.unitary == TRUE)
+ {
+ zzn4_copy(&x.a, &Z0);
+ zzn4_mul(&x.a, &x.a, &z->a);
+ zzn4_copy(&z->a, &Z3);
+ zzn4_add(&z->a, &z->a, &z->a);
+ zzn4_add(&z->a, &Z3, &z->a);
+ zzn4_conj(&Z0, &Z0);
+ zzn4_add(&Z0, &Z0, &Z0);
+ zzn4_sub(&z->a, &Z0, &z->a);
+ zzn4_copy(&x.c, &Z1);
+ zzn4_mul(&Z1, &Z1, &Z1);
+ zzn4_tx(&Z1);
+ zzn4_copy(&Z1, &Z3);
+ zzn4_add(&Z1, &Z1, &Z1);
+ zzn4_add(&Z1, &Z3, &Z1);
+ zzn4_copy(&x.b, &Z2);
+ zzn4_mul(&Z2, &Z2, &Z2);
+ zzn4_copy(&Z2, &Z3);
+ zzn4_add(&Z2, &Z2, &Z2);
+ zzn4_add(&Z2, &Z3, &Z2);
+ zzn4_conj(&x.b, &z->b);
+ zzn4_add(&z->b, &z->b, &z->b);
+ zzn4_conj(&x.c, &z->c);
+ zzn4_add(&z->c, &z->c, &z->c);
+ zzn4_negate(&z->c, &z->c);
+ zzn4_add(&z->b, &Z1, &z->b);
+ zzn4_add(&z->c, &Z2, &z->c);
+ }
+ else
+ {
+ if(!x.miller)
+ { // Chung-Hasan SQR2
+ zzn4_copy(&x.a, &Z0);
+ zzn4_mul(&Z0, &Z0, &Z0);
+ zzn4_mul(&x.b, &x.c, &Z1);
+ zzn4_add(&Z1, &Z1, &Z1);
+ zzn4_copy(&x.c, &Z2);
+ zzn4_mul(&Z2, &Z2, &Z2);
+ zzn4_mul(&x.a, &x.b, &Z3);
+ zzn4_add(&Z3, &Z3, &Z3);
+ zzn4_add(&x.a, &x.b, &z->c);
+ zzn4_add(&z->c, &x.c, &z->c);
+ zzn4_mul(&z->c, &z->c, &z->c);
+ zzn4_tx(&Z1);
+ zzn4_add(&Z0, &Z1, &z->a);
+ zzn4_tx(&Z2);
+ zzn4_add(&Z3, &Z2, &z->b);
+ zzn4_add(&Z0, &Z1, &T0);
+ zzn4_add(&T0, &Z2, &T0);
+ zzn4_add(&T0, &Z3, &T0);
+ zzn4_sub(&z->c, &T0, &z->c);
+ }
+ else
+ { // Chung-Hasan SQR3 - actually calculate 2x^2 !
+ // Slightly dangerous - but works as will be raised to p^{k/2}-1
+ // which wipes out the 2.
+ zzn4_copy(&x.a, &Z0);
+ zzn4_mul(&Z0, &Z0, &Z0); // a0^2 = S0
+ zzn4_copy(&x.c, &Z2);
+ zzn4_mul(&Z2, &x.b, &Z2);
+ zzn4_add(&Z2, &Z2, &Z2); // 2a1.a2 = S3
+ zzn4_copy(&x.c, &Z3);
+ zzn4_mul(&Z3, &Z3, &Z3); // a2^2 = S4
+ zzn4_add(&x.c, &x.a, &z->c); // a0+a2
+ zzn4_copy(&x.b, &Z1);
+ zzn4_add(&Z1, &z->c, &Z1);
+ zzn4_mul(&Z1, &Z1, &Z1); // (a0+a1+a2)^2 =S1
+ zzn4_sub(&z->c, &x.b, &z->c);
+ zzn4_mul(&z->c, &z->c, &z->c); // (a0-a1+a2)^2 =S2
+ zzn4_add(&Z2, &Z2, &Z2);
+ zzn4_add(&Z0, &Z0, &Z0);
+ zzn4_add(&Z3, &Z3, &Z3);
+ zzn4_sub(&Z1, &z->c, &T0);
+ zzn4_sub(&T0, &Z2, &T0);
+ zzn4_sub(&Z1, &Z0, &T1);
+ zzn4_sub(&T1, &Z3, &T1);
+ zzn4_add(&z->c, &T1, &z->c);
+ zzn4_tx(&Z3);
+ zzn4_add(&T0, &Z3, &z->b);
+ zzn4_tx(&Z2);
+ zzn4_add(&Z0, &Z2, &z->a);
+ }
+ }
+ }
+ else
+ {
+ // Karatsuba
+ zero_b = zzn4_iszero(&y.b);
+ zero_c = zzn4_iszero(&y.c);
+
+ zzn4_mul(&x.a, &y.a, &Z0); //9
+ if(!zero_b)
+ zzn4_mul(&x.b, &y.b, &Z2); //+6
+
+ zzn4_add(&x.a, &x.b, &T0);
+ zzn4_add(&y.a, &y.b, &T1);
+ zzn4_mul(&T0, &T1, &Z1); //+9
+ zzn4_sub(&Z1, &Z0, &Z1);
+ if(!zero_b)
+ zzn4_sub(&Z1, &Z2, &Z1);
+
+ zzn4_add(&x.b, &x.c, &T0);
+ zzn4_add(&y.b, &y.c, &T1);
+ zzn4_mul(&T0, &T1, &Z3);//+6
+ if(!zero_b)
+ zzn4_sub(&Z3, &Z2, &Z3);
+
+ zzn4_add(&x.a, &x.c, &T0);
+ zzn4_add(&y.a, &y.c, &T1);
+ zzn4_mul(&T0, &T1, &T0);//+9=39 for "special case"
+ if(!zero_b)
+ zzn4_add(&Z2, &T0, &Z2);
+ else
+ zzn4_copy(&T0, &Z2);
+
+ zzn4_sub(&Z2, &Z0, &Z2);
+ zzn4_copy(&Z1, &z->b);
+ if(!zero_c)
+ {
+ // exploit special form of BN curve line function
+ zzn4_mul(&x.c, &y.c, &T0);
+ zzn4_sub(&Z2, &T0, &Z2);
+ zzn4_sub(&Z3, &T0, &Z3);
+ zzn4_tx(&T0);
+ zzn4_add(&z->b, &T0, &z->b);
+ }
+
+ zzn4_tx(&Z3);
+ zzn4_add(&Z0, &Z3, &z->a);
+ zzn4_copy(&Z2, &z->c);
+ if(!y.unitary)
+ z->unitary = FALSE;
+ }
+}
+
+
+static void zzn12_conj(zzn12 *x, zzn12 *y)
+{
+ zzn4_conj(&x->a, &y->a);
+ zzn4_conj(&x->b, &y->b);
+ zzn4_negate(&y->b, &y->b);
+ zzn4_conj(&x->c, &y->c);
+ y->miller = x->miller;
+ y->unitary = x->unitary;
+}
+
+
+static zzn12 zzn12_inverse(zzn12 w)
+{
+ zzn4 tmp1, tmp2;
+ zzn12 res;
+
+ tmp1.a.a = mirvar(0);
+ tmp1.a.b = mirvar(0);
+
+ tmp1.b.a = mirvar(0);
+ tmp1.b.b = mirvar(0);
+
+ tmp1.unitary = FALSE;
+
+
+ tmp2.a.a = mirvar(0);
+ tmp2.a.b = mirvar(0);
+
+ tmp2.b.a = mirvar(0);
+ tmp2.b.b = mirvar(0);
+
+ tmp2.unitary = FALSE;
+
+
+ zzn12_init(&res);
+
+ if(w.unitary)
+ {
+ zzn12_conj(&w, &res);
+ return res;
+ }
+ //res.a=w.a*w.a-tx(w.b*w.c);
+ zzn4_mul(&w.a, &w.a, &res.a);
+ zzn4_mul(&w.b, &w.c, &res.b);
+ zzn4_tx(&res.b);
+ zzn4_sub(&res.a, &res.b, &res.a);
+
+ //res.b=tx(w.c*w.c)-w.a*w.b;
+ zzn4_mul(&w.c, &w.c, &res.c);
+ zzn4_tx(&res.c);
+ zzn4_mul(&w.a, &w.b, &res.b);
+ zzn4_sub(&res.c, &res.b, &res.b);
+
+ //res.c=w.b*w.b-w.a*w.c;
+ zzn4_mul(&w.b, &w.b, &res.c);
+ zzn4_mul(&w.a, &w.c, &tmp1);
+ zzn4_sub(&res.c, &tmp1, &res.c);
+
+ //tmp1=tx(w.b*res.c)+w.a*res.a+tx(w.c*res.b);
+ zzn4_mul(&w.b, &res.c, &tmp1);
+ zzn4_tx(&tmp1);
+ zzn4_mul(&w.a, &res.a, &tmp2);
+ zzn4_add(&tmp1, &tmp2, &tmp1);
+ zzn4_mul(&w.c, &res.b, &tmp2);
+ zzn4_tx(&tmp2);
+ zzn4_add(&tmp1, &tmp2, &tmp1);
+
+ zzn4_inv(&tmp1);
+ zzn4_mul(&res.a, &tmp1, &res.a);
+ zzn4_mul(&res.b, &tmp1, &res.b);
+ zzn4_mul(&res.c, &tmp1, &res.c);
+ return res;
+}
+
+
+static void zzn12_powq(zzn2 F, zzn12 *y)
+{
+ zzn2 X2, X3;
+ X2.a = mirvar(0);
+ X2.b = mirvar(0);
+
+ X3.a = mirvar(0);
+ X3.b = mirvar(0);
+ zzn2_mul(&F, &F, &X2);
+ zzn2_mul(&X2, &F, &X3);
+
+ zzn4_powq(&X3, &y->a);
+ zzn4_powq(&X3, &y->b);
+ zzn4_powq(&X3, &y->c);
+ zzn4_smul(&y->b, &X, &y->b);
+ zzn4_smul(&y->c, &X2, &y->c);
+}
+
+
+static void zzn12_div(zzn12 x, zzn12 y, zzn12 *z)
+{
+ y=zzn12_inverse(y);
+ zzn12_mul(x, y, z);
+}
+
+
+static zzn12 zzn12_pow(zzn12 x, big k)
+{
+ big zero, tmp, tmp1;
+ int nb, i;
+ BOOL invert_it;
+ zzn12 res;
+
+ zero = mirvar(0);
+ tmp = mirvar(0);
+ tmp1 = mirvar(0);
+
+ zzn12_init(&res);
+ copy(k, tmp1);
+ invert_it = FALSE;
+
+ if(mr_compare(tmp1, zero) == 0)
+ {
+ tmp = get_mip()->one;
+ zzn4_from_big(tmp, &res.a);
+ return res;
+ }
+ if(mr_compare(tmp1, zero) < 0)
+ {
+ negify(tmp1, tmp1);
+ invert_it = TRUE;
+ }
+ nb = logb2(k);
+ zzn12_copy(&x, &res);
+ if(nb > 1)
+ for(i = nb - 2; i >= 0; i--)
+ {
+ zzn12_mul(res, res, &res);
+ if(mr_testbit(k, i))
+ zzn12_mul(res, x, &res);
+ }
+ if(invert_it)
+ res = zzn12_inverse(res);
+ return res;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/openssl/miracl.h b/engines/vendor_defns/miracl.h
similarity index 100%
rename from include/openssl/miracl.h
rename to engines/vendor_defns/miracl.h
diff --git a/include/openssl/mirdef.h b/engines/vendor_defns/mirdef.h
similarity index 100%
rename from include/openssl/mirdef.h
rename to engines/vendor_defns/mirdef.h