]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/CurveParamDocs/fmodule.c
   1 /************************************************************** 
   8  *              13 Apr 98   REC - creation 
  10  *      c. 1998 Perfectly Scientific, Inc. 
  11  *      All Rights Reserved. 
  14  *************************************************************/ 
  33 #define NUM_PRIMES 6542 /* PrimePi[2^16]. */ 
  36 #define MERSENNE_MOD (-1) 
  37 #define D 100  /* A decimation parameter for stage-2 ECM factoring. */ 
  39 /* compiler options */ 
  42 #pragma warning( disable : 4127 4706 ) /* disable conditional is constant warning */ 
  46 /* global variables */ 
  48 extern int pr
[NUM_PRIMES
];  /* Primes array from tools.c. */ 
  50 unsigned short factors
[NUM_PRIMES
], exponents
[NUM_PRIMES
]; 
  51 int             modmode 
= GENERAL_MOD
; 
  53 static giant t1 
= NULL
, t2 
= NULL
, t3 
= NULL
, t4 
= NULL
; 
  54 static giant An 
= NULL
, Ad 
= NULL
; 
  55 static point_mont pt1
, pt2
; 
  59 static int verbosity 
= 0; 
  61 /************************************************************** 
  65  **************************************************************/ 
  68 init_fmodule(int shorts
) { 
  70         pb
[0] = NULL
;  /* To guarantee proper ECM initialization. */ 
  71         t1 
= newgiant(shorts
); 
  72         t2 
= newgiant(shorts
); 
  73         t3 
= newgiant(shorts
); 
  74         t4 
= newgiant(shorts
); 
  75         An 
= newgiant(shorts
); 
  76     Ad 
= newgiant(shorts
); 
  77         pt1 
= new_point_mont(shorts
); 
  78         pt2 
= new_point_mont(shorts
); 
  83 /* Call verbose(1) for output during factoring processes,  
  84    call verbose(0) to silence all that. 
  98 set_mod_mode(int mode
)  
  99 /* Call this with mode := 1, 0, -1, for Fermat-mod, general mod, and Mersenne mod,  
 100    respectively; the point being that the special cases of 
 101    Fermat- and Mersenne-mod are much faster than 
 102    general mod.  If all mods will be with respect to a number-to-be-factored, 
 103    of the form N = 2^m + 1, use Fermat mod; while if N = 2^m-1, use Mersenne mod. 
 118                         mersennemod(bitlen(N
), t
); 
 121                         fermatmod(bitlen(N
)-1, t
); 
 136         return(&exponents
[0]); 
 140 sieve(giant N
, int sievelim
) 
 141 /* Returns number of N's prime factors < min(sievelim, 2^16), 
 142    with N reduced accordingly by said factors. 
 143    The n-th entry of factors[] becomes the n-th prime 
 144    factor of N, with corresponding exponent 
 145    becoming the n-th element of exponents[].  
 147 {       int j
, pcount
, rem
; 
 152                 for (j
=0; j 
< NUM_PRIMES
; j
++) 
 155                         if(pri 
> sievelim
) break; 
 158                                 rem 
= idivg(pri
, t1
); 
 164                         if(exponents
[pcount
] > 0) { 
 165                                 factors
[pcount
] = pr
[j
]; 
 167                                 exponents
[pcount
] = 0; 
 174 pollard_rho(giant N
, giant fact
, int steps
, int abort
) 
 175 /* Perform Pollard-rho x:= 3; loop(x:= x^2 + 2), a total of steps times. 
 176    Parameter fact will be a nontrivial factor found, in which case 
 177    N is also modified as: N := N/fact. 
 178    The function returns 0 if no nontrivial factor found, else returns 1. 
 179    The abort parameter, when set, causes the factorer to exit on the 
 180    first nontrivial factor found (the requisite GCD is checked 
 181    every 1000 steps).  If abort := 0, the full number 
 182    of steps are always performed, then one solitary GCD is taken, 
 191         for(j
=0; j 
< steps
; j
++) { 
 192                 squareg(t1
); iaddg(2, t1
); special_modg(N
, t1
); 
 193                 squareg(t2
); iaddg(2, t2
); special_modg(N
, t2
); 
 194                 squareg(t2
); iaddg(2, t2
); special_modg(N
, t2
); 
 195                 gtog(t2
, t3
); subg(t1
,t3
); mulg(t3
, fact
); special_modg(N
, fact
); 
 196                 if(((j 
% 1000 == 999) && abort
) || (j 
== steps
-1)) { 
 200                                 found 
= (gcompg(N
, fact
) == 0) ? 0 : 1; 
 205     if(verbosity
) { printf("\n"); fflush(stdout
); } 
 215 pollard_pminus1(giant N
, giant fact
, int lim
, int abort
) 
 216 /* Perform Pollard-(p-1); where we test 
 220    where P is an accumulation of primes <= min(lim, 2^16),  
 221    to appropriate powers. 
 222    Parameter fact will be a nontrivial factor found, in which case 
 223    N is also modified as: N := N/fact. 
 224    The function returns 0 if no nontrivial factor found, else returns 1. 
 225    The abort parameter, when set, causes the factorer to exit on the 
 226    first nontrivial factor found (the requisite GCD is checked 
 227    every 100 steps).  If abort := 0, the full number 
 228    of steps are always performed, then one solitary GCD is taken, 
 231 {  int cnt
, j
, k
, pri
, found 
= 0; 
 234    for (j
=0; j
< NUM_PRIMES
; j
++) 
 237                         if((pri 
> lim
) || (j 
== NUM_PRIMES
-1) || (abort 
&& (j 
% 100 == 99))) { 
 245                                         found 
= (gcompg(N
, t1
) == 0) ? 0 : 1; 
 250                         if(pri 
< 19) { cnt 
= 20-pri
;  /* Smaller primes get higher powers. */ 
 251                         } else if(pri 
< 100) { 
 254                         for (k
=0; k
< cnt
; k
++) 
 256                                 powermod(fact
, pri
, N
); 
 259     if(verbosity
) { printf("\n"); fflush(stdout
); } 
 270 ecm(giant N
, giant fact
, int S
, unsigned int B
, unsigned int C
) 
 271 /* Perform elliptic curve method (ECM), with: 
 272    Brent seed parameter = S 
 276                 returns 1 if nontrivial factor is found in stage 1 of ECM; 
 277                 returns 2 if nontrivial factor is found in stage 2 of ECM; 
 279    In the positive return, parameter fact is the factor and N := N/fact. 
 281 {       unsigned int pri
, q
; 
 282         int j
, cnt
, count
, k
; 
 285                 printf("Finding curve and point, B = %u, C = %u, seed = %d...", B
, C
, S
); 
 288         find_curve_point_brent(pt1
, S
, An
, Ad
, N
); 
 291                 printf("Commencing stage 1 of ECM...\n"); 
 295         q 
= pr
[NUM_PRIMES
-1]; 
 302                         if(primeq(q
)) pri 
= q
;  
 305                 if(verbosity
) if((++count
) % 100 == 0) dot(); 
 307                 if(pri 
< 19) { cnt 
= 20-pri
;  
 308                         } else if(pri 
< 100) { 
 311                 for(k 
= 0; k 
< cnt
; k
++)         
 312                         ell_mul_int_brent(pt1
, pri
, An
, Ad
, N
);  
 319                         ell_mul_int_brent(pt1
, k
, An
, Ad
, N
); 
 321                                         ell_mul_int_brent(pt1
, k
, An
, Ad
, N
); 
 327     if(verbosity
) { printf("\n"); fflush(stdout
); } 
 329 /* Next, test stage-1 attempt. */        
 332     if((!isone(fact
)) && (gcompg(N
, fact
) != 0)) { 
 336         if(B 
>= C
) {  /* No stage 2 planned. */ 
 341 /* Commence second stage of ECM. */ 
 344                 printf("Commencing stage 2 of ECM...\n"); 
 348                 for(k
=0; k 
< D
+2; k
++) { 
 349                                 pb
[k
] = new_point_mont(curshorts
); 
 350                                 xzb
[k
] = newgiant(curshorts
); 
 355         ptop_mont(pt1
, pb
[0]); 
 356         ell_mul_int_brent(pb
[0], k
*D
+1 , An
, Ad
, N
); 
 357         ptop_mont(pt1
, pb
[D
+1]); 
 358         ell_mul_int_brent(pb
[D
+1], (k
+2)*D
+1 , An
, Ad
, N
); 
 360         for (j
=1; j 
<= D
; j
++) 
 362                 ptop_mont(pt1
, pb
[j
]); 
 363                 ell_mul_int_brent(pb
[j
], 2*j 
, An
, Ad
, N
); 
 364                 gtog(pb
[j
]->z
, xzb
[j
]); 
 365                 mulg(pb
[j
]->x
, xzb
[j
]); 
 366                 special_modg(N
, xzb
[j
]); 
 371                 if(verbosity
) if((++count
) % 10 == 0) dot(); 
 372                 gtog(pb
[0]->z
, xzb
[0]); 
 373                 mulg(pb
[0]->x
, xzb
[0]); 
 374                 special_modg(N
, xzb
[0]); 
 375                 mulg(pb
[0]->z
, fact
); 
 376                 special_modg(N
, fact
); /* Accumulate. */ 
 377                 for (j 
= 1; j 
< D
; j
++) { 
 378                                 if (!primeq(k
*D
+1+2*j
)) continue; 
 379 /* Next, accumulate (xa - xb)(za + zb) - xa za + xb zb. */ 
 390                                 special_modg(N
, fact
); 
 395                 ptop_mont(pb
[D
+1], pt2
); 
 396                 ell_odd_brent(pb
[D
], pb
[D
+1], pb
[0], N
); 
 397                 ptop_mont(pt2
, pb
[0]); 
 399     if(verbosity
) { printf("\n"); fflush(stdout
); } 
 402     if((!isone(fact
)) && (gcompg(N
, fact
) != 0)) { 
 404                 return(2);  /* Return value of 2 for stage-2 success! */