⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p1363.c

📁 大数运算库miracl。有了miracl这样的函数库
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* 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 to the specified base (normally 16)
 * 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,int base,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;
    char *mem;
    if (fname==NULL && params==NULL) return MR_P1363_DOMAIN_NOT_FOUND;
    if (fname==NULL) fileinput=FALSE;

    if (fileinput)
    {
        fp=fopen(fname,"r");
        if (fp==NULL) return MR_P1363_DOMAIN_NOT_FOUND;
        fscanf(fp,"%d\n",&bits);
    }
    else
        sscanf(params[0],"%d\n",&bits); 

    DOM->words=24+(bits/MIRACL);
        
    mr_mip=mirsys(DOM->words,0);
    if (mr_mip==NULL) 
    {
        if (fileinput) fclose(fp);
        return MR_P1363_OUT_OF_MEMORY;
    }

    mem=memalloc(_MIPP_ 4);
    if (mem==NULL)
    {
        if (fileinput) fclose(fp);
        res=MR_P1363_OUT_OF_MEMORY;
    }

    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);

        if (base<2 || base>60) base=10;
        mr_mip->IOBASE=base;

        bytes=bits/8;
        if (bits%8!=0) bytes++;

        if (fileinput)
        {
            cinnum(_MIPP_ q,fp);
            cinnum(_MIPP_ r,fp);
            cinnum(_MIPP_ g,fp);
            
            fclose(fp);
        }
        else
        {
            cinstr(_MIPP_ q,params[1]);
            cinstr(_MIPP_ r,params[2]);
            cinstr(_MIPP_ g,params[3]);
        } 
         
        rbits=logb2(_MIPP_ r);       /* r is usually much smaller than q */
        if (rbits%8==0) rbytes=rbits/8;
        else            rbytes=(rbits/8)+1;
        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));
    }

    memkill(_MIPP_ mem,4);

    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;
    char *mem;
    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;

    mr_mip->ERCON=TRUE;
    mr_mip->NTRY=50;
    set_user_function(_MIPP_ idle);

    mem=memalloc(_MIPP_ 4);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    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;
    }

    memkill(_MIPP_ mem,4);
    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;
    char *mem;

    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
    mr_mip->ERCON=TRUE;
    set_user_function(_MIPP_ idle);
    mem=memalloc(_MIPP_ 5);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    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);
    }
    memkill(_MIPP_ mem,5);

    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;
    char *mem;
    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
    mr_mip->ERCON=TRUE;
    set_user_function(_MIPP_ idle);

    mem=memalloc(_MIPP_ 4);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    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;
    }   

    memkill(_MIPP_ mem,4);

    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;
    char *mem;
    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
    mr_mip->ERCON=TRUE;
    set_user_function(_MIPP_ idle);

    mem=memalloc(_MIPP_ 4);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    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);
    }

    memkill(_MIPP_ mem,4);
    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;
    char *mem;
    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
    mr_mip->ERCON=TRUE;
    set_user_function(_MIPP_ idle);

    mem=memalloc(_MIPP_ 8);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    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);
    }
    memkill(_MIPP_ mem,8);

    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_MQV(BOOL (*idle)(void),dl_domain *DOM,octet *S,octet *U,octet *V,octet *WD,octet *VD,octet *Z)
{
    miracl *mr_mip=mirsys(DOM->words,0);
    int h;
    int err,res=0;
    big q,r,s,u,v,wd,vd,e,t,td,z;
    char *mem;
    if (mr_mip==NULL) return MR_P1363_OUT_OF_MEMORY;
    mr_mip->ERCON=TRUE;
    set_user_function(_MIPP_ idle);

    mem=memalloc(_MIPP_ 11);
    if (mem==NULL) res=MR_P1363_OUT_OF_MEMORY;

    if (res==0)
    {
        q=mirvar_mem(_MIPP_ mem, 0);
        r=mirvar_mem(_MIPP_ mem, 1);
        s=mirvar_mem(_MIPP_ mem, 2);
        u=mirvar_mem(_MIPP_ mem, 3);
        v=mirvar_mem(_MIPP_ mem, 4);
        wd=mirvar_mem(_MIPP_ mem, 5);
        vd=mirvar_mem(_MIPP_ mem, 6);
        e=mirvar_mem(_MIPP_ mem, 7);
        t=mirvar_mem(_MIPP_ mem, 8);
        td=mirvar_mem(_MIPP_ mem, 9);
        z=mirvar_mem(_MIPP_ mem, 10);

        OS2FEP(_MIPP_ &DOM->Q,q);
        OS2FEP(_MIPP_ &DOM->R,r);
        OS2FEP(_MIPP_ S,s);
        OS2FEP(_MIPP_ U,u);
        OS2FEP(_MIPP_ V,v);
        OS2FEP(_MIPP_ WD,wd);
        OS2FEP(_MIPP_ VD,vd);

        h=DOM->H;
        expint(_MIPP_ 2,h,z);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -