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

📄 ecc.cpp

📁 椭圆曲线密码系统教程和相关源代码,是非常难得的学术资料
💻 CPP
字号:
// --------------------------------------------------------------------
// ECDLP solver using Pohlig-Hellman algorithm to reduce problem
//       size and Pollard's rho algorithm to solve ECDLP over sub
//       -group (+ a routine to brute-force group with small order
//       to avoid pb with order 2...)
//
// 
//   Pollard's rho part is a (very) modified version of 'Miracl/index.c'(DLP)
//   You will be able to find more info reading HoAC or any others
//   good crypto-papers... :) 
//                                   Amenesia//TKM! 
// --------------------------------------------------------------------
// Info: You have to use Miracl to be able to compile it...
// ATM parameters permit to solve the ECDLP used in pDriLl's keygenme #5
// but it's quite easy to modify it in order to solve your own ECDLP
// (is well commented in a bad english :p)
// --------------------------------------------------------------------
                  
#include <stdlib.h>
#include <miracl.h>

#define NPRIMES 10
static miracl *mip;
static big order, rholim;



// --------------------------- Pollard rho ---------------------------

void iterate(epoint* X,epoint* Q,epoint* R,big a,big b)
{ // Random walk...
//       = a(i)     if X in S1
// a(i+1) = a(i) + 1   if X in S2 
//       = 2*a(i)   if X in S3
//
//       = b(i)     if X in S2
// b(i+1) = b(i) + 1   if X in S1 
//       = 2*b(i)   if X in S3
//
//   X(i)   = a(i)*Q + b(i)*R
//   X(i+1) = f(X(i))
//
// BTW: the criteria used by Dimedrol (ecdlp.solver) is quite
//     good (simple and fast to compute) so i take the same :)

  big p = mirvar(0);   
  epoint_get(X,p,p);

  if (remain(p,7)>4)
  { 
    ecurve_add(Q,X);
    incr(a,1,a);
    if (compare(a,order)==0) zero(a);
    mirkill(p);     
    return;
  }
  if (remain(p,7)>2) 
  {   
    ecurve_add(X,X);
    premult(a,2,a);
    if (compare(a,order)>=0) subtract(a,order,a);
    premult(b,2,b);
    if (compare(b,order)>=0) subtract(b,order,b);
    mirkill(p);           
    return;
  }     
  ecurve_add(R,X);
  incr(b,1,b);
  if (compare(b,order)==0) zero(b);
  mirkill(p);   
}



// To avoid endless loops...
void ecdlpbf(epoint* Q,epoint* R,big k)
{
  epoint* T = epoint_init();
  copy(order,k);
  negify(k,k);
  do
  {
    incr(k,1,k);
    ecurve_mult(k,Q,T);     
  } while (!epoint_comp(T,R));
  epoint_free(T);
}


void rho(epoint* Q,epoint* R,big k)
{ // Find ax,ay,bx and by with: ax*Q + bx*R == ay*Q + by*R
// So : (ax-ay)*R = (by-bx)*Q
// ECDLP => k exists such as k*R = Q
// So: (ax-ay) = (by-bx)*k mod order
//   k = (ax-ay)*(by-bx)^1 mod order
// BTW: check if (by-bx) is inversible
//     (order is prime so (by-bx) is 
//     inversible <=> (by-bx) != 0)

  long rr,i;
  big ax,bx,ay,by,m,n;
  epoint* Y = epoint_init();
  epoint* X = epoint_init();
  m=mirvar(0);
  n=mirvar(0);   
  ax=mirvar(0);
  bx=mirvar(0);
  ay=mirvar(0);
  by=mirvar(2);
  
  if (compare(rholim,order)>=0) 
  {
    ecdlpbf(Q,R,k);
  }
  else 
  { 
    do
        {
          rr=1L;   
          bigrand(order,ay);     
          bigrand(order,by);     
          ecurve_mult2(ay,Q,by,R,Y);
          do
          { // Search a collision...
                    epoint_copy(Y,X);
                    copy(ay,ax);
                    copy(by,bx);
                    rr*=2;
                    for (i=1;i<=rr;i++)
                    {
                      iterate(Y,Q,R,ay,by);
                      if (epoint_comp(X,Y)) break;
                    }
          } while (!epoint_comp(X,Y));
        } while (compare(bx,by)==0);

        subtract(ay,ax,m);
        if(size(m)<0){add(m,order,m);}
        subtract(bx,by,n); 
        if(size(m)<0){add(m,order,m);}           
        xgcd(n,order,n,n,n); 
        mad(m,n,n,order,order,k); 

// I don't know why but it seems that
//   -k*A != (-k+ord(A))*A 
// If you are able to explain me why
// feel free to contact me... :)
        
ecurve_mult(k,Q,X);     
if (!epoint_comp(X,R)){ subtract(k,order,k); }                                                                                                                                                                                                                                                                                                                                                     
ecurve_mult(k,Q,X); 
if (!epoint_comp(X,R)){ printf("Error !!!"); } 
  }   
epoint_free(Y);
  epoint_free(X);
  mirkill(by);
  mirkill(ay);
  mirkill(bx);
  mirkill(ax);
}

// --------------------------- End Pollard rho ---------------------------





int main()
{
  mip =mirsys(100,0);
  unsigned char mod_str[10];
  int i,j;
  int pw[NPRIMES];   
  big pf[NPRIMES],logmod[NPRIMES];
  for (i=0;i<NPRIMES;i++) 
  {
    pf[i]=mirvar(0);
    logmod[i]=mirvar(0);
  }   
  
  big_chinese bc;   
  
  big k=mirvar(0);
  big p=mirvar(0);
  big a=mirvar(0);
  big b=mirvar(0);
  big p1=mirvar(0);     
  big xA=mirvar(0);
  big xB=mirvar(0);

  epoint* A = epoint_init();   
  epoint* At = epoint_init(); 
  epoint* B = epoint_init(); 
  epoint* Q= epoint_init(); 
  epoint* R= epoint_init(); 
  epoint* Rj= epoint_init(); 

  big c=mirvar(0);   
  big N=mirvar(0);
  order=mirvar(0);
  rholim=mirvar(2);
  irand(41563436);   
  
  mip->IOBASE=16; 
  // --------------------- Elliptic Curve Definition --------------------- 
  printf("In progress...\n");
                  
  cinstr(a,"1");   
  cinstr(b,"0");   
  cinstr(p,"ACC00CF0775153B19E037CE879D332BB");   
    
  cinstr(xA,"18650A0922FC3EC0B778347B20EE6619"); 
  cinstr(xB,"0D85FA1C5BC8982485ACD9FA9B1BEBEC");     
  

  ecurve_init(a,b,p,MR_AFFINE);
  epoint_set(xA,xA,0,A);
  epoint_set(xB,xB,1,B);


  // --------------------- Order factors ---------------------   
  mip->IOBASE=16;
  cinstr(p1,"566006783BA8A9D8CF01BE743CE9995E");                 
  cinstr(pf[0],"2"); pw[0]=1;
  cinstr(pf[1],"3"); pw[1]=1;
  cinstr(pf[2],"7"); pw[2]=1;
  cinstr(pf[3],"D"); pw[3]=2;     
  cinstr(pf[4],"7F"); pw[4]=1;
  cinstr(pf[5],"D3"); pw[5]=1;
  cinstr(pf[6],"1DF75"); pw[6]=1;
  cinstr(pf[7],"5978F"); pw[7]=1;
  cinstr(pf[8],"1F374C47"); pw[8]=1;   
  cinstr(pf[9],"5F73FD8D3"); pw[9]=1;   
            
  
  // --------------------- Pohlig Hellman --------------------- 
  // If ord(A) = p1^e1 * p2^e2 * ... * pn^en there is a group 
  // isomorphism such:   f : <A> -> Cp1^e1 * ... * Cpn^en 
  // where Cpi^ei are subgroup of <A> of order pi^ei.
  //
  // The projection of f to Cpi^ei is given by:
  //       fi : <A> -> Fpi^ei
  //           R -> (N/pi^ei)*R
  //   Moreover fi is a group homomorphism so because of linearity
  //   ("lin閍rit? en francais mais j'ai quelques doutes sur son
  //   equivalent en anglais): B = k*A so fi(B) = fi(k*A) = k*fi(A)
  //   but we are in Cpi^ei so k is determined modulo (pi^ei). 
  //
  //   Using CRT we will find p mod (p1^e1* ... * pn^en)...
  //   If you are really interested in PH algo you sould read more :)

  for (i=0;i<NPRIMES;i++)
  {       
    // ui = 0
    zero(logmod[i]); 
    // Q = (n/pi)*A               
    copy(p1,N);     
    divide(N,pf[i],N);
    ecurve_mult(N,A,Q);
    // R(0) = B
    epoint_copy(B,Rj);
                
    // For j=0 to (e-1)
    for (j=0;j<pw[i];j++)
    {           
          // R = (n/pi^(j+1))*Rj         
          ecurve_mult(N,Rj,R);
          // Solve R = kj*Q   
          copy(pf[i],order);                                                 
          rho(Q,R,k); 
          // c = kj*pi^j     
          powltr(j,pf[i],p1,c);
          power(pf[i],j,p1,c);                     
          multiply(k,c,c);
          // Rj+1 = Rj - kj*pi^j*A
          ecurve_mult(c,A,At);
          ecurve_sub(At,Rj);           
          // ui = ui + kj*pi^j       
          add(logmod[i],c,logmod[i]);
          // N = (n/pi^(j+2))           
          divide(N,pf[i],N);                   
    }
    power(pf[i],pw[i],p1,pf[i]); 
    // Interface
    cotstr(pf[i],mod_str);           
    printf("# Solved over C(%s)\n#> ",mod_str); 
    cotnum(logmod[i],stdout);     
  }           
  
  // --------- Chinese remainder thereom ---------     
  crt_init(&bc,NPRIMES,pf);
  crt(&bc,logmod,k);   
  crt_end(&bc);

  // -------------------- User-friendly Interface :) -------------------- 
      
  ecurve_mult(k,A,Q);         
  if (epoint_comp(Q,B))
  {
    printf("\nDiscrete logarithm: "); 
    cotnum(k,stdout); 
  }
  else
  { 
    printf("Wrong solution !? :x");
  }           
  getch();


  // -----------------------------------------------------------------
  epoint_free(A);
  epoint_free(At);   
  epoint_free(B); 
  epoint_free(Q);
  epoint_free(R); 
  epoint_free(Rj);
  
  for (i=0;i<NPRIMES;i++) 
  {
    mirkill(pf[i]);
    mirkill(logmod[i]);
  }     
  mirkill(k);
  mirkill(p);
  mirkill(a);
  mirkill(b);
  mirkill(p1);     
  mirkill(xA);
  mirkill(xB);
  mirkill(c);
  mirkill(N);
  mirexit(); 
  return(0); 
}

⌨️ 快捷键说明

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