📄 p1363.c
字号:
P1363_API BOOL AES_CBC_IV0_ENCRYPT(octet *k,octet *m,FILE *ifp,octet *c,FILE *ofp)
{ /* AES CBC encryption, with Null IV */
/* Input is from either an octet string m, or from a file plain,
output is to an octet string c, or a file cipher */
aes a;
int i,j,ipt,opt,ch;
char buff[16];
BOOL fin;
int padlen;
if (m!=NULL && ifp!=NULL) return FALSE;
if (c!=NULL)
{
if (ofp!=NULL) return FALSE;
OCTET_CLEAR(c);
}
if (!aes_init(&a,MR_CBC,k->len,k->val,NULL)) return FALSE;
ipt=opt=0;
fin=FALSE;
forever
{
for (i=0;i<16;i++)
{
if (m!=NULL)
{
if (ipt<m->len) buff[i]=m->val[ipt++];
else {fin=TRUE; break;}
}
if (ifp!=NULL)
{
if ((ch=fgetc(ifp))!=EOF) buff[i]=ch;
else {fin=TRUE; break;}
}
}
if (fin) break;
aes_encrypt(&a,buff);
for (i=0;i<16;i++)
{
if (c!=NULL) if (opt<c->max) c->val[opt++]=buff[i];
if (ofp!=NULL) fputc(buff[i],ofp);
}
}
/* last block, filled up to i-th index */
padlen=16-i;
for (j=i;j<16;j++) buff[j]=padlen;
aes_encrypt(&a,buff);
for (i=0;i<16;i++)
{
if (c!=NULL) if (opt<c->max) c->val[opt++]=buff[i];
if (ofp!=NULL) fputc(buff[i],ofp);
}
aes_end(&a);
if (c!=NULL) c->len=opt;
return TRUE;
}
/*** DL primitives - support functions ***/
/* Destroy the DL Domain structure */
P1363_API void DL_DOMAIN_KILL(dl_domain *DOM)
{
OCTET_KILL(&DOM->Q);
OCTET_KILL(&DOM->R);
OCTET_KILL(&DOM->G);
OCTET_KILL(&DOM->K);
OCTET_KILL(&DOM->IK);
if (DOM->PC.store!=0)
brick_end(&DOM->PC);
DOM->words=DOM->fsize=0; DOM->H=DOM->rbits=0;
}
/* Initialise the DL domain structure
* It is assumed that the DL domain details are obtained from a file
* or from an array of strings
* multi-precision numbers are read in in Hex
* A suitable file can be generated offline by the MIRACL example program
* dssetup.c
* Set precompute=TRUE if a precomputed table is to be used to
* speed up the calculation g^x mod p
* Returns recommended number of bytes for use with octet strings */
P1363_API int DL_DOMAIN_INIT(dl_domain *DOM,char *fname,char **params,BOOL precompute)
{ /* get domain details from specified file, OR from an array of strings *
* If input from a file, params=NULL, if input from strings, fname=NULL *
* returns filed size in bytes */
FILE *fp;
BOOL fileinput=TRUE;
miracl *mr_mip;
big q,r,g,k;
int bits,rbits,bytes,rbytes,err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(4)];
memset(mem,0,MR_BIG_RESERVE(4));
#endif
if (fname==NULL && params==NULL) return MR_P1363_DOMAIN_NOT_FOUND;
if (fname==NULL) fileinput=FALSE;
if (fileinput)
{
fp=fopen(fname,"rt");
if (fp==NULL) return MR_P1363_DOMAIN_NOT_FOUND;
fscanf(fp,"%d\n",&bits);
}
else
sscanf(params[0],"%d\n",&bits);
DOM->words=MR_ROUNDUP(bits,MIRACL);
mr_mip=mirsys(MR_ROUNDUP(bits,4),16);
if (mr_mip==NULL)
{
if (fileinput) fclose(fp);
return MR_P1363_OUT_OF_MEMORY;
}
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 4);
if (mem==NULL)
{
if (fileinput) fclose(fp);
res=MR_P1363_OUT_OF_MEMORY;
}
#endif
mr_mip->ERCON=TRUE;
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
r=mirvar_mem(_MIPP_ mem,1);
g=mirvar_mem(_MIPP_ mem,2);
k=mirvar_mem(_MIPP_ mem,3);
bytes=MR_ROUNDUP(bits,8);
if (fileinput)
{
innum(_MIPP_ q,fp);
innum(_MIPP_ r,fp);
innum(_MIPP_ g,fp);
fclose(fp);
}
else
{
instr(_MIPP_ q,params[1]);
instr(_MIPP_ r,params[2]);
instr(_MIPP_ g,params[3]);
}
rbits=logb2(_MIPP_ r); /* r is usually much smaller than q */
rbytes=MR_ROUNDUP(rbits,8);
OCTET_INIT(&DOM->Q,bytes);
OCTET_INIT(&DOM->R,rbytes);
OCTET_INIT(&DOM->G,bytes);
OCTET_INIT(&DOM->K,bytes);
OCTET_INIT(&DOM->IK,rbytes);
DOM->H=(1+rbits)/2;
DOM->fsize=bytes;
DOM->rbits=rbits;
decr(_MIPP_ q,1,k);
divide(_MIPP_ k,r,k); /* k=(q-1)/r */
convert_big_octet(_MIPP_ q,&DOM->Q);
convert_big_octet(_MIPP_ r,&DOM->R);
convert_big_octet(_MIPP_ g,&DOM->G);
convert_big_octet(_MIPP_ k,&DOM->K);
xgcd(_MIPP_ k,r,k,k,k);
convert_big_octet(_MIPP_ k,&DOM->IK);
DOM->PC.store=0;
if (precompute) brick_init(_MIPP_ &DOM->PC,g,q,logb2(_MIPP_ r));
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,4);
#else
memset(mem,0,MR_BIG_RESERVE(4));
#endif
err=mr_mip->ERNUM;
mirexit(_MIPPO_ );
if (err==MR_ERR_OUT_OF_MEMORY) return MR_P1363_OUT_OF_MEMORY;
if (err==MR_ERR_DIV_BY_ZERO) return MR_P1363_DIV_BY_ZERO;
if (err!=0) return -(1000+err);
if (res<0) return res;
else return bytes;
}
/* validate DL domain details - good idea if you got them from
* some-one else! */
P1363_API int DL_DOMAIN_VALIDATE(BOOL (*idle)(void),dl_domain *DOM)
{ /* do domain checks - IEEE P1363 A16.2 */
miracl *mr_mip=mirsys(DOM->words,0);
big q,r,g,t;
int err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(4)];
memset(mem,0,MR_BIG_RESERVE(4));
#endif
if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
mr_mip->ERCON=TRUE;
mr_mip->NTRY=50;
set_user_function(_MIPP_ idle);
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 4);
if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;
#endif
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
r=mirvar_mem(_MIPP_ mem,1);
g=mirvar_mem(_MIPP_ mem,2);
t=mirvar_mem(_MIPP_ mem,3);
OS2FEP(_MIPP_ &DOM->Q,q);
OS2FEP(_MIPP_ &DOM->R,r);
OS2FEP(_MIPP_ &DOM->G,g);
if (size(g)<2 || size(q)<=2 || size(r)<=2) res=MR_P1363_DOMAIN_ERROR;
if (compare(g,q)>=0) res=MR_P1363_DOMAIN_ERROR;
}
if (res==0)
{
gprime(_MIPP_ 10000);
if (!isprime(_MIPP_ q)) res=MR_P1363_DOMAIN_ERROR;
}
if (res==0)
{
if (!isprime(_MIPP_ r)) res=MR_P1363_DOMAIN_ERROR;
}
if (res==0)
{ /* is g of order r? */
powmod(_MIPP_ g,r,q,t);
if (size(t)!=1) res=MR_P1363_DOMAIN_ERROR;
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,4);
#else
memset(mem,0,MR_BIG_RESERVE(4));
#endif
err=mr_mip->ERNUM;
mirexit(_MIPPO_ );
if (err==MR_ERR_OUT_OF_MEMORY) return MR_P1363_OUT_OF_MEMORY;
if (err==MR_ERR_DIV_BY_ZERO) return MR_P1363_DIV_BY_ZERO;
if (err!=0) return -(1000+err);
return res;
}
/* Calculate a public/private DL key pair. W=g^S mod p
* where S is the private key and W the public key
* If RNG is NULL then the private key is provided externally in S
* otherwise it is generated randomly internally
*/
P1363_API int DL_KEY_PAIR_GENERATE(BOOL (*idle)(void),dl_domain *DOM,csprng *RNG, octet *S,octet *W)
{
miracl *mr_mip=mirsys(DOM->words,0);
big q,r,g,s,w;
int err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(5)];
memset(mem,0,MR_BIG_RESERVE(5));
#endif
if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
mr_mip->ERCON=TRUE;
set_user_function(_MIPP_ idle);
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 5);
if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;
#endif
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
r=mirvar_mem(_MIPP_ mem,1);
g=mirvar_mem(_MIPP_ mem,2);
s=mirvar_mem(_MIPP_ mem,3);
w=mirvar_mem(_MIPP_ mem,4);
OS2FEP(_MIPP_ &DOM->Q,q);
OS2FEP(_MIPP_ &DOM->R,r);
OS2FEP(_MIPP_ &DOM->G,g);
if (RNG!=NULL)
{
strong_bigrand(_MIPP_ RNG,r,s);
}
else
{
OS2FEP(_MIPP_ S,s);
divide(_MIPP_ s,r,r);
}
if (DOM->PC.store==0)
powmod(_MIPP_ g,s,q,w);
else
pow_brick(_MIPP_ &DOM->PC,s,w);
if (RNG!=NULL) convert_big_octet(_MIPP_ s,S);
FE2OSP(_MIPP_ w,DOM->fsize,W);
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,5);
#else
memset(mem,0,MR_BIG_RESERVE(5));
#endif
err=mr_mip->ERNUM;
mirexit(_MIPPO_ );
if (err==MR_ERR_OUT_OF_MEMORY) return MR_P1363_OUT_OF_MEMORY;
if (err==MR_ERR_DIV_BY_ZERO) return MR_P1363_DIV_BY_ZERO;
if (err!=0) return -(1000+err);
return res;
}
/* validate a DL public key. Set full=TRUE for fuller,
* but more time-consuming test */
P1363_API int DL_PUBLIC_KEY_VALIDATE(BOOL (*idle)(void),dl_domain *DOM,BOOL full,octet *W)
{
miracl *mr_mip=mirsys(DOM->words,0);
big q,r,w,t;
int err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(4)];
memset(mem,0,MR_BIG_RESERVE(4));
#endif
if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
mr_mip->ERCON=TRUE;
set_user_function(_MIPP_ idle);
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 4);
if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;
#endif
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
r=mirvar_mem(_MIPP_ mem,1);
w=mirvar_mem(_MIPP_ mem,2);
t=mirvar_mem(_MIPP_ mem,3);
OS2FEP(_MIPP_ &DOM->Q,q);
OS2FEP(_MIPP_ &DOM->R,r);
OS2FEP(_MIPP_ W,w);
if (size(w)<2 || compare(w,q)>=0) res=MR_P1363_INVALID_PUBLIC_KEY;
}
if (res==0 && full)
{
powmod(_MIPP_ w,r,q,t);
if (size(t)!=1) res=MR_P1363_INVALID_PUBLIC_KEY;
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,4);
#else
memset(mem,0,MR_BIG_RESERVE(4));
#endif
err=mr_mip->ERNUM;
mirexit(_MIPPO_ );
if (err==MR_ERR_OUT_OF_MEMORY) return MR_P1363_OUT_OF_MEMORY;
if (err==MR_ERR_DIV_BY_ZERO) return MR_P1363_DIV_BY_ZERO;
if (err!=0) return -(1000+err);
return res;
}
/*** P1363 DL primitives ***/
/* See P1363 documentation for specification */
P1363_API int DLSVDP_DH(BOOL (*idle)(void),dl_domain *DOM,octet *S,octet *WD,octet *Z)
{
miracl *mr_mip=mirsys(DOM->words,0);
big q,s,wd,z;
int err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(4)];
memset(mem,0,MR_BIG_RESERVE(4));
#endif
if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
mr_mip->ERCON=TRUE;
set_user_function(_MIPP_ idle);
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 4);
if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;
#endif
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
s=mirvar_mem(_MIPP_ mem,1);
wd=mirvar_mem(_MIPP_ mem,2);
z=mirvar_mem(_MIPP_ mem,3);
OS2FEP(_MIPP_ &DOM->Q,q);
OS2FEP(_MIPP_ S,s);
OS2FEP(_MIPP_ WD,wd);
powmod(_MIPP_ wd,s,q,z);
FE2OSP(_MIPP_ z,DOM->fsize,Z);
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,4);
#else
memset(mem,0,MR_BIG_RESERVE(4));
#endif
err=mr_mip->ERNUM;
mirexit(_MIPPO_ );
if (err==MR_ERR_OUT_OF_MEMORY) return MR_P1363_OUT_OF_MEMORY;
if (err==MR_ERR_DIV_BY_ZERO) return MR_P1363_DIV_BY_ZERO;
if (err!=0) return -(1000+err);
return res;
}
P1363_API int DLSVDP_DHC(BOOL (*idle)(void),dl_domain *DOM,octet *S,octet *WD,BOOL compatible,octet *Z)
{
miracl *mr_mip=mirsys(DOM->words,0);
big q,r,k,ik,s,wd,t,z;
int sz;
int err,res=0;
#ifndef MR_STATIC
char *mem;
#else
char mem[MR_BIG_RESERVE(8)];
memset(mem,0,MR_BIG_RESERVE(8));
#endif
if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
mr_mip->ERCON=TRUE;
set_user_function(_MIPP_ idle);
#ifndef MR_STATIC
mem=memalloc(_MIPP_ 8);
if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;
#endif
if (res==0)
{
q=mirvar_mem(_MIPP_ mem,0);
r=mirvar_mem(_MIPP_ mem,1);
k=mirvar_mem(_MIPP_ mem,2);
ik=mirvar_mem(_MIPP_ mem,3);
s=mirvar_mem(_MIPP_ mem,4);
wd=mirvar_mem(_MIPP_ mem,5);
z=mirvar_mem(_MIPP_ mem,6);
t=mirvar_mem(_MIPP_ mem,7);
OS2FEP(_MIPP_ &DOM->Q,q);
OS2FEP(_MIPP_ &DOM->R,r);
OS2FEP(_MIPP_ &DOM->K,k);
OS2FEP(_MIPP_ S,s);
OS2FEP(_MIPP_ WD,wd);
if (compatible)
{
OS2FEP(_MIPP_ &DOM->IK,ik);
mad(_MIPP_ ik,s,ik,r,r,t); /* t=s/k mod r */
}
else copy(s,t);
multiply(_MIPP_ t,k,t); /* kt */
powmod(_MIPP_ wd,t,q,z);
sz=size(z);
if (sz==0 || sz==1) res=MR_P1363_INVALID_PUBLIC_KEY;
else FE2OSP(_MIPP_ z,DOM->fsize,Z);
}
#ifndef MR_STATIC
memkill(_MIPP_ mem,8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -