发新话题
打印

[转载]椭圆曲线对数问题解决算法C语言源代码

[转载]椭圆曲线对数问题解决算法C语言源代码

文章作者:Amenesia
复制内容到剪贴板
代码:
// --------------------------------------------------------------------
// 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&#39;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&#39;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);  
}

TOP

发新话题