2021SC@SDUSC Application and practice of software engineering in school of software, Shandong University
1. mrebrick.c structure
The overall structure of mrebrick.c is as follows, which mainly implements ebrick_init(), ebrick_end(),mul_brick() is a few important functions in the miracl open source library. This blog is to read the functions of this function.
2. Source code
BOOL ebrick_init(_MIPD_ ebrick *B,big x,big y,big a,big b,big n,int window,int nb) { /* Uses Montgomery arithmetic internally * * (x,y) is the fixed base * * a,b and n are parameters and modulus of the curve * * window is the window size in bits and * * nb is the maximum number of bits in the multiplier */ int i,j,k,t,bp,len,bptr,is; epoint **table; epoint *w; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (nb<2 || window<1 || window>nb || mr_mip->ERNUM) return FALSE; t=MR_ROUNDUP(nb,window); if (t<2) return FALSE; MR_IN(115) #ifndef MR_ALWAYS_BINARY if (mr_mip->base != mr_mip->base2) { mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); MR_OUT return FALSE; } #endif B->window=window; B->max=nb; table=(epoint **)mr_alloc(_MIPP_ (1<<window),sizeof(epoint *)); if (table==NULL) { mr_berror(_MIPP_ MR_ERR_OUT_OF_MEMORY); MR_OUT return FALSE; } B->a=mirvar(_MIPP_ 0); B->b=mirvar(_MIPP_ 0); B->n=mirvar(_MIPP_ 0); copy(a,B->a); copy(b,B->b); copy(n,B->n); ecurve_init(_MIPP_ a,b,n,MR_BEST); w=epoint_init(_MIPPO_ ); epoint_set(_MIPP_ x,y,0,w); table[0]=epoint_init(_MIPPO_ ); table[1]=epoint_init(_MIPPO_ ); epoint_copy(w,table[1]); for (j=0;j<t;j++) ecurve_double(_MIPP_ w); k=1; for (i=2;i<(1<<window);i++) { table[i]=epoint_init(_MIPPO_ ); if (i==(1<<k)) { k++; epoint_norm(_MIPP_ w); epoint_copy(w,table[i]); for (j=0;j<t;j++) ecurve_double(_MIPP_ w); continue; } bp=1; for (j=0;j<k;j++) { if (i&bp) { is=1<<j; ecurve_add(_MIPP_ table[is],table[i]); } bp<<=1; } epoint_norm(_MIPP_ table[i]); } epoint_free(w); /* create the table */ len=n->len; bptr=0; B->table=(mr_small *)mr_alloc(_MIPP_ 2*len*(1<<window),sizeof(mr_small)); for (i=0;i<(1<<window);i++) { for (j=0;j<len;j++) { B->table[bptr++]=table[i]->X->w[j]; } for (j=0;j<len;j++) { B->table[bptr++]=table[i]->Y->w[j]; } epoint_free(table[i]); } mr_free(table); MR_OUT return TRUE; } void ebrick_end(ebrick *B) { mirkill(B->n); mirkill(B->b); mirkill(B->a); mr_free(B->table); }
ebrick_ The main function of init () method is to initialize the GF (p) elliptic curve multiplication and pre calculated Comb method instance.. The internal memory is allocated to 20000 elliptic curve points, and these large numbers will be calculated and stored in advance* B is the ebrick structure pointer to be initialized. Other input data is to improve various attributes of * B. This method uses Montgomery algorithm to initialize * B inside the function. The input data a, B and N determine a curve function y2 = (x3 + ax + b) mod n, X and y are combined into a two-dimensional coordinate point (x,y) on the curve. Window determines the window size in bits and. For larger input data, windows needs more space to store data, and the input data nb limits the maximum bits to be used in the index.
void ebrick_init(ebrick *B,const mr_small* rom,big a,big b,big n,int window,int nb) { B->table=rom; B->a=a; /* just pass a pointer */ B->b=b; B->n=n; B->window=window; /* 2^4=16 stored values */ B->max=nb; }
ebrick_ The init () method is also overloaded in another form. This method only roughly replaces various attributes required by * B with input data, rather than using Montgomery algorithm to initialize * B.
void ebrick_end(ebrick *B) { mirkill(B->n); mirkill(B->b); mirkill(B->a); mr_free(B->table); }
brick_ The main function of the end () method is to release the memory space occupied by the brick structure pointer * B. First, call the mirkill() method. By zeroing the large numbers B - > N, B - > b and B - > A and freeing their memory, you can safely kill the large number. Call Mr again_ The free () method frees the memory space dynamically allocated to B - > table by the calloc() method.
void ebrick_init(ebrick *B,const mr_small* rom,big a,big b,big n,int window,int nb) { B->table=rom; B->a=a; /* just pass a pointer */ B->b=b; B->n=n; B->window=window; /* 2^4=16 stored values */ B->max=nb; } #endif int mul_brick(_MIPD_ ebrick *B,big e,big x,big y) { int i,j,t,d,len,maxsize,promptr; epoint *w,*z; #ifdef MR_STATIC char mem[MR_ECP_RESERVE(2)]; #else char *mem; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (size(e)<0) mr_berror(_MIPP_ MR_ERR_NEG_POWER); t=MR_ROUNDUP(B->max,B->window); MR_IN(116) #ifndef MR_ALWAYS_BINARY if (mr_mip->base != mr_mip->base2) { mr_berror(_MIPP_ MR_ERR_NOT_SUPPORTED); MR_OUT return 0; } #endif if (logb2(_MIPP_ e) > B->max) { mr_berror(_MIPP_ MR_ERR_EXP_TOO_BIG); MR_OUT return 0; } ecurve_init(_MIPP_ B->a,B->b,B->n,MR_BEST); #ifdef MR_STATIC memset(mem,0,MR_ECP_RESERVE(2)); #else mem=(char *)ecp_memalloc(_MIPP_ 2); #endif w=epoint_init_mem(_MIPP_ mem,0); z=epoint_init_mem(_MIPP_ mem,1); len=B->n->len; maxsize=2*(1<<B->window)*len; j=recode(_MIPP_ e,t,B->window,t-1); if (j>0) { promptr=2*j*len; init_point_from_rom(w,len,B->table,maxsize,&promptr); } for (i=t-2;i>=0;i--) { j=recode(_MIPP_ e,t,B->window,i); ecurve_double(_MIPP_ w); if (j>0) { promptr=2*j*len; init_point_from_rom(z,len,B->table,maxsize,&promptr); ecurve_add(_MIPP_ z,w); } } d=epoint_get(_MIPP_ w,x,y); #ifndef MR_STATIC ecp_memkill(_MIPP_ mem,2); #else memset(mem,0,MR_ECP_RESERVE(2)); #endif MR_OUT return d; }
mul_ The main function of the brick () method is to multiply GF (P) elliptic curves using the pre calculated values stored in the ebrick structure. First call ecurve_init method initializes the internal parameters of the currently active GF (P) elliptic curve: y2 = (x3 + Ax + B) mod p, and then call ECP_ The memalloc method preserves 2 spaces at the elliptic curve point and then calls epoint_. init_ The MEM method initializes the memory of the two elliptic curve points from the pre allocated font field array mem. After that, call init_. point_ from_ The ROM method initializes elliptical curve points W from ROM memory. Next, the recode method is called recursively, encoding the index for the Comb method, and then calling ecurve_. The double method multiplies the w on the active curve by twice, and calls init_ point_ from_ The ROM method initializes the elliptic curve point z from ROM memory, and then calls ecurve_ The add method adds W and Z on the active curve to W. After the end of the loop, call epoint_. The get method obtains the coordinates on the w (x,y), and finally calls ecp_. The memkill method is deleted and set to zero previously by ECP_ Two memory space elliptical curve points allocated by memalloc.