]>
git.saurik.com Git - apple/security.git/blob - OSX/include/security_cryptkit/CurveParamDocs/tools.c
1 /**************************************************************
5 * Number-theoretical algorithm implementations
8 * 30 Apr 99 REC Modified init_tools type to void.
9 * 3 Apr 98 REC Creation
12 * c. 1998 Perfectly Scientific, Inc.
13 * All Rights Reserved.
16 *************************************************************/
36 #define STACK_COUNT 20
38 /* global variables */
40 int pr
[NUM_PRIMES
]; /* External use allowed. */
41 static giant tmp
[STACK_COUNT
];
46 /**************************************************************
48 * Maintenance functions
50 **************************************************************/
54 init_tools(int shorts
)
58 for(j
= 0; j
< STACK_COUNT
; j
++) {
59 tmp
[j
] = newgiant(shorts
);
61 make_primes(); /* Create table of all primes < 2^16,
62 to be used by other programs as array
76 /**************************************************************
78 * Number-theoretical functions
80 **************************************************************/
86 /* Primality test via small, literal sieve.
87 After init, one should use primeq() instead.
93 return ((p
== 2)?1:0);
109 /* Faster primality test, using preset array pr[] of primes.
110 This test is valid for all unsigned, 32-bit integers odd.
116 if(odd
< 2) return (0);
118 return ((odd
== 2)?1:0);
133 for (k
=0, npr
=1;; k
++)
135 if (prime_literal(3+2*k
))
138 if (npr
>= NUM_PRIMES
)
145 prime_probable(giant p
)
146 /* Invoke Miller-Rabin test of given security depth.
147 For MILLER_RABIN_DEPTH == 8, this is an ironclad primality
148 test for suspected primes p < 3.4 x 10^{14}.
151 giant t1
= popg(), t2
= popg(), t3
= popg();
154 if((p
->n
[0] & 1) == 0) { /* Evenness test. */
157 if(bitlen(p
) < 32) { /* Single-word case. */
159 return(primeq((unsigned int)gtoi(p
)));
162 addg(p
, t1
); /* t1 := p-1. */
166 while(t2
->n
[0] & 1 == 0) {
170 /* Now, p-1 = 2^s * t2. */
171 for(j
= 0; j
< MILLER_RABIN_DEPTH
; j
++) {
173 powermodg(t3
, t2
, p
);
175 if(isone(t3
)) continue;
176 if(gcompg(t3
, t1
) == 0) continue;
177 while((ct
< s
) && (gcompg(t1
, t3
) != 0)) {
178 squareg(t3
); modg(p
, t3
);
184 if(gcompg(t1
, t3
) != 0) goto composite
;
190 prime
: pushg(3); return(1);
194 jacobi_symbol(giant a
, giant n
)
195 /* Standard Jacobi symbol (a/n). Parameter n must be odd, positive. */
197 giant t5
= popg(), t6
= popg(), t7
= popg();
199 gtog(a
, t5
); modg(n
, t5
);
203 while((t5
->n
[0] & 1) == 0) {
205 if((u
==3) || (u
==5)) t
= -t
;
207 gtog(t5
, t7
); gtog(t6
, t5
); gtog(t7
, t6
);
209 if(((t5
->n
[0] & 3) == 3) && ((u
& 3) == 3)) t
= -t
;
221 pseudoq(giant a
, giant p
)
222 /* Query whether a^(p-1) = 1 (mod p). */
225 giant t1
= popg(), t2
= popg();
227 gtog(p
, t1
); itog(1, t2
); subg(t2
, t1
);
229 powermodg(t2
, t1
, p
);
236 pseudointq(int a
, giant p
)
237 /* Query whether a^(p-1) = 1 (mod p). */
250 powFp2(giant a
, giant b
, giant w2
, giant n
, giant p
)
251 /* Perform powering in the field F_p^2:
252 a + b w := (a + b w)^n (mod p), where parameter w2 is a quadratic
253 nonresidue (formally equal to w^2).
256 giant t6
= popg(), t7
= popg(), t8
= popg(), t9
= popg();
264 gtog(a
, t8
); gtog(b
, t9
);
265 for(j
= bitlen(n
)-2; j
>= 0; j
--) {
267 mulg(a
, b
); addg(b
,b
); modg(p
, b
); /* b := 2 a b. */
268 squareg(t6
); modg(p
, t6
);
269 mulg(w2
, t6
); modg(p
, t6
);
270 squareg(a
); addg(t6
, a
); modg(p
, a
); /* a := a^2 + b^2 w2. */
272 gtog(b
, t6
); mulg(t8
, b
); modg(p
, b
);
273 gtog(a
, t7
); mulg(t9
, a
); addg(a
, b
); modg(p
, b
);
274 mulg(t9
, t6
); modg(p
, t6
); mulg(w2
, t6
); modg(p
, t6
);
275 mulg(t8
, a
); addg(t6
, a
); modg(p
, a
);
283 sqrtmod(giant p
, giant x
)
284 /* If Sqrt[x] (mod p) exists, function returns 1, else 0.
285 In either case x is modified, but if 1 is returned,
288 { giant t0
= popg(), t1
= popg(), t2
= popg(), t3
= popg(),
291 modg(p
, x
); /* Justify the argument. */
292 gtog(x
, t0
); /* Store x for eventual validity check on square root. */
293 if((p
->n
[0] & 3) == 3) { /* The case p = 3 (mod 4). */
295 iaddg(1, t1
); gshiftright(2, t1
);
299 /* Next, handle case p = 5 (mod 8). */
300 if((p
->n
[0] & 7) == 5) {
301 gtog(p
, t1
); itog(1, t2
);
302 subg(t2
, t1
); gshiftright(2, t1
);
304 powermodg(t2
, t1
, p
); /* t2 := x^((p-1)/4) % p. */
306 gshiftright(1, t1
); /* t1 := (p+3)/8. */
308 powermodg(x
, t1
, p
); /* x^((p+3)/8) is root. */
311 itog(1, t2
); subg(t2
, t1
); /* t1 := (p-5)/8. */
314 mulg(t0
, x
); addg(x
, x
); modg(p
, x
); /* 2x (4x)^((p-5)/8. */
319 /* Next, handle tougher case: p = 1 (mod 8). */
321 while(1) { /* Find appropriate nonresidue. */
323 squareg(t2
); subg(x
, t2
); modg(p
, t2
);
324 if(jacobi_symbol(t2
, p
) == -1) break;
326 } /* t2 is now w^2 in F_p^2. */
328 gtog(p
, t4
); iaddg(1, t4
); gshiftright(1, t4
);
329 powFp2(t1
, t3
, t2
, t4
, p
);
333 gtog(x
,t1
); squareg(t1
); modg(p
, t1
);
334 if(gcompg(t0
, t1
) == 0) {
336 return(1); /* Success. */
339 return(0); /* No square root. */
344 /* n:= Floor[Sqrt[n]]. */
345 { giant t5
= popg(), t6
= popg();
347 itog(1, t5
); gshiftleft(1 + bitlen(n
)/2, t5
);
351 addg(t5
, t6
); gshiftright(1, t6
);
352 if(gcompg(t6
, t5
) >= 0) break;
360 cornacchia4(giant n
, int d
, giant u
, giant v
)
361 /* Seek representation 4n = u^2 + |d| v^2,
362 for (negative) discriminant d and n > |D|/4.
363 Parameter u := 0 and 0 is returned, if no representation is found;
364 else 1 is returned and u, v properly set.
366 { int r
= n
->n
[0] & 7, sym
;
367 giant t1
= popg(), t2
= popg(), t3
= popg(), t4
= popg();
370 if((n
->n
[0]) & 7 == 1) { /* n = 1 (mod 8). */
371 sym
= jacobi_symbol(t1
,n
);
378 sqrtmod(n
, t2
); /* t2 := Sqrt[d] (mod n). */
379 } else { /* Avoid separate Jacobi/Legendre test. */
381 if(sqrtmod(n
, t2
) == 0) {
387 /* t2 is now a valid square root of d (mod n). */
389 subg(t1
, t3
); /* t3 := t2 - d. */
390 if((t3
->n
[0] & 1) == 1) {
394 gtog(n
, t3
); addg(t3
, t3
); /* t3 := 2n. */
395 gtog(n
, t4
); gshiftleft(2, t4
); sqrtg(t4
); /* t4 = [Sqrt[4 p]]. */
396 while(gcompg(t2
, t4
) > 0) {
402 gtog(n
, t4
); gshiftleft(2, t4
);
403 gtog(t2
, t3
); squareg(t3
);
404 subg(t3
, t4
); /* t4 := 4n - t2^2. */
406 itog(d
, t1
); absg(t1
);
415 sqrtg(t4
); /* t4 := [Sqrt[t4/Abs[d]]]. */
418 if(gcompg(t3
, t1
) != 0) {
430 rep[p_, d_] := Module[{t, x0, a, b, c},
431 If[JacobiSymbol[d,p] != 1, Return[{0,0}]];
433 If[Mod[x0-d,2] == 1, x0 = p-x0];
434 a = 2p; b = x0; c = sqrtint[4 p];
435 While[b > c, {a,b} = {b, Mod[a,b]}];
437 If[Mod[t,Abs[d]] !=0, Return[{0,0}]];
440 If[u^2 != v, Return[{0,0}]];