]>
git.saurik.com Git - apple/security.git/blob - libsecurity_cryptkit/ckutils/giantDvt/giantDvt.c
1 /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
3 * giantDvt.c - DVT of NSGiantInteger primitives.
7 * 09 Apr 98 Doug Mitchell at Apple
11 #include "giantIntegers.h"
12 #include "ckutilities.h"
13 #include "feeFunctions.h"
16 #include "ckutilsPlatform.h"
21 #define MAX_SIZE_DEF 32
22 #define LOOP_NOTIFY 100
24 /* quick test to show modg(1,g) broken */
25 #define MODG1_TEST_ENABLE 1
27 static void usage(char **argv
)
29 printf("usage: %s [options]\n", argv
[0]);
30 printf(" Options:\n");
31 printf(" l=loops (default = %d)\n", LOOPS_DEF
);
32 printf(" x=maxBytes (default = %d)\n", MAX_SIZE_DEF
);
39 * ...min <= return <= max
41 static int genRand(int min
, int max
)
44 /* note random() only yields a 31-bit number... */
46 if(max
== min
) /* avoid % 1 ! */
49 return(min
+ (RAND() % (max
-min
+1)));
53 * Fill buffer with random data, random size from 1 to maxSize.
54 * Returns size of random data generated.
56 static unsigned fillData(unsigned maxSize
,
67 size
= genRand(1, maxSize
);
75 ip
= (unsigned *)data
;
76 for(i
=0; i
<intCount
; i
++) {
81 cp
= (unsigned char *)ip
;
82 for(i
=0; i
<residue
; i
++) {
83 *cp
++ = (unsigned char)RAND();
89 * create a giant with random size and data. *Buf is mallocd and
90 * uninitialized and will change here.
92 static giant
genGiant(unsigned maxBytes
, unsigned char *buf
)
94 int size
= fillData(maxBytes
, buf
, 0);
98 g
= giant_with_data(buf
, size
);
100 /* set random sign; giant_with_data() is always positive */
106 /* avoid zero data - too many pitfalls with mod and div */
114 static int testError()
118 printf("Attach via debugger for more info.\n");
119 printf("a to abort, c to continue: ");
121 return (resp
[0] != 'c');
125 static void gabs(giant g
)
133 * Individual tests. API is identical for all tests.
135 * g1, g2 : giants with random data, size, and sign. Tests do not modify
137 * scr1, scr2 : scratch giants, big enough for all conceivable ops. Can
138 * be modified at will.
139 * Return : 0 for sucess, 1 on error.
142 static int compTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
144 gtog(g1
, scr1
); // scr1 := g1
146 if(gcompg(g1
, scr2
)) {
147 printf("gtog/gcompg error\n");
153 static int addSubTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
155 gtog(g1
, scr1
); // scr1 := g1
156 addg(g2
, scr1
); // scr1 := g1 + g2
157 subg(g1
, scr1
); // scr1 := g1 + g2 - g1 =? g2
158 if(gcompg(g2
, scr1
)) {
159 printf("addg/subg error\n");
165 #define LARGEST_MUL 0xffff
167 static int mulTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
169 int randInt
= genRand(1, LARGEST_MUL
);
173 int_to_giant(randInt
, scr1
); // scr1 := randInt
174 gtog(g1
, scr2
); // scr2 := g1
175 mulg(scr1
, scr2
); // scr2 := g1 * randInt
177 /* now do the same thing with multiple adds */
178 int_to_giant(0, scr1
); // scr1 := 0
179 for(i
=0; i
<randInt
; i
++) {
180 addg(g1
, scr1
); // scr1 += g1
181 } // scr1 =? g1 * randInt
182 if(gcompg(scr1
, scr2
)) {
183 printf("g1 : "); printGiantHex(g1
);
184 printf("randInt : 0x%x\n", randInt
);
185 printf("good prod : "); printGiantHex(scr1
);
186 printf("bad prod : "); printGiantHex(scr2
);
187 printf("mulg error\n");
194 static int squareTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
197 mulg(g1
, scr1
); // scr1 := g1 * g1
199 gsquare(scr2
); // scr2 =? g1 * g1
200 if(gcompg(scr1
, scr2
)) {
201 printf("gsquare error\n");
207 static int lshiftTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
209 int maxShift
= (scr1
->capacity
- abs(g1
->sign
) - 1) *
210 GIANT_BITS_PER_DIGIT
;
211 int shiftCnt
= genRand(1, maxShift
);
212 giant scr3
= borrowGiant(scr1
->capacity
);
215 gtog(g1
, scr1
); // scr1 := g1
216 gshiftleft(shiftCnt
, scr1
); // scr1 := (g1 << shiftCnt)
218 gtog(g1
, scr2
); // scr2 := g1
220 int multInt
= (1 << shiftCnt
);
221 int_to_giant(multInt
, scr3
); // scr3 := (1 << shiftCnt)
224 int_to_giant(1, scr3
); // scr3 := 1;
225 gshiftleft(shiftCnt
, scr3
); // scr3 := (1 << shiftCnt)
227 mulg(scr3
, scr2
); // scr2 := g1 * (1 << shiftCnt);
228 if(gcompg(scr1
, scr2
)) {
229 printf("shiftCnt %d 0x%x\n", shiftCnt
, shiftCnt
);
230 printf("g1 : "); printGiantHex(g1
);
231 printf("scr1 : "); printGiantHex(scr1
);
232 printf("scr2 : "); printGiantHex(scr2
);
233 printf("gshiftleft error\n");
240 static int rshiftTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
242 int maxShift
= bitlen(g1
) - 1;
244 giant scr3
= borrowGiant(scr1
->capacity
);
247 /* special case, can't have g1 = 1 */
250 printf("...rshiftTest: tweaking g1 = 1\n");
256 shiftCnt
= genRand(1, maxShift
);
258 gtog(g1
, scr1
); // scr1 := g1
259 gabs(scr1
); // scr1 := |g1|
260 gtog(scr1
, scr2
); // scr2 := |g1|
261 gshiftright(shiftCnt
, scr1
); // scr1 := (|g1| >> shiftCnt)
264 int multInt
= (1 << shiftCnt
);
265 int_to_giant(multInt
, scr3
); // scr3 := (1 << shiftCnt)
268 int_to_giant(1, scr3
); // scr3 := 1;
269 gshiftleft(shiftCnt
, scr3
); // scr3 := (1 << shiftCnt)
271 divg(scr3
, scr2
); // scr2 := g1 / (1 << shiftCnt);
272 if(gcompg(scr1
, scr2
)) {
273 printf("shiftCnt %d 0x%x\n", shiftCnt
, shiftCnt
);
274 printf("g1 : "); printGiantHex(g1
);
275 printf("scr1 : "); printGiantHex(scr1
);
276 printf("scr2 : "); printGiantHex(scr2
);
277 printf("gshiftright error\n");
284 static int divTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
286 gtog(g1
, scr1
); // scr1 := g1
287 mulg(g2
, scr1
); // scr1 := g1 * g2
288 gtog(g2
, scr2
); // scr2 := g2
289 gabs(scr2
); // scr2 := |g2|
290 divg(scr2
, scr1
); // scr1 := (g1 * g2) / |g2|
292 /* weird case - if g2 is negative, this result is -g1! */
294 scr1
->sign
= -scr1
->sign
;
296 if(gcompg(scr1
, g1
)) {
297 printf("g1 : "); printGiantHex(g1
);
298 printf("g2 : "); printGiantHex(g1
);
299 printf("scr1 : "); printGiantHex(scr1
);
300 printf("divTest error\n");
306 #define LARGEST_MOD_MUL 0x40
308 static int modTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
310 int randInt
= genRand(1, LARGEST_MOD_MUL
);
311 giant scr3
= borrowGiant(scr1
->capacity
);
313 giant scr4
= borrowGiant(scr1
->capacity
);
317 int_to_giant(randInt
, scr1
); // scr1 := rand
319 gabs(scr2
); // scr2 := |g1|
321 /* current modg can't deal with g mod 1 ! */
322 if((scr2
->sign
== 1) && (scr2
->n
[0] == 1)) {
323 #if MODG1_TEST_ENABLE
324 /* assume that this is legal... */
326 printf("..modTest: g1 = 1, no tweak\n");
329 printf("..modTest: tweaking g1 = 1\n");
331 #endif MODG1_TEST_ENABLE
333 /* end modg workaround */
336 gabs(scr3
); // scr3 := |g2|
338 /* this will only work if randInt < |g1| */
339 if(gcompg(scr1
, scr2
) >= 0) {
341 printf("..modTest: tweaking rand, > g1 = "); printGiantHex(g1
);
342 printf(" g2 = "); printGiantHex(g2
);
343 printf(" rand = "); printGiantHex(scr1
);
345 modg(scr2
, scr1
); // scr1 := rand mod g1
346 if(gcompg(scr1
, scr2
) >= 0) {
347 printf("simple modg error\n");
352 mulg(scr2
, scr3
); // scr3 := |g1 * g2|
353 addg(scr1
, scr3
); // scr3 := (|g1 * g2|) + rand
355 modg(scr2
, scr3
); // scr3 := scr3 mod |g1| =? rand
356 if(gcompg(scr1
, scr3
)) {
357 printf("g1 : "); printGiantHex(g1
);
358 printf("g2 : "); printGiantHex(g2
);
359 printf("rand : 0x%x\n", randInt
);
360 printf("randG : "); printGiantHex(scr1
);
361 printf("scr4 : "); printGiantHex(scr4
);
362 printf("mod : "); printGiantHex(scr3
);
363 printf("modTest error\n");
373 #if MODG1_TEST_ENABLE
374 /* quickie test to demonstrate failure of modg(1, g). Known failure
376 * modg(1,g) fixed on 13 Apr 1998, so this should now work.
378 static int modg1Test(giant g1
, giant scr1
, giant scr2
)
386 printf("g1 : "); printGiantHex(g1
);
387 printf("g1 mod 1 : "); printGiantHex(scr2
);
392 #endif MODG1_TEST_ENABLE
394 static int mulOnesTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
398 giant gOnes
= borrowGiant(scr1
->capacity
);
400 /* set up a giant with all ones data */
401 gOnes
->sign
= abs(g1
->sign
);
402 for(i
=0; i
<gOnes
->sign
; i
++) {
403 gOnes
->n
[i
] = (giantDigit
)(-1);
406 gtog(gOnes
, scr1
); // scr1 := gOnes
407 mulg(g1
, scr1
); // scr1 := gOnes * g1
412 if(gcompg(scr1
, scr2
)) {
413 printf("good prod : "); printGiantHex(scr1
);
414 printf("bad prod : "); printGiantHex(scr2
);
415 printf("mulOnesTest error\n");
422 int main(int argc
, char **argv
)
426 giant g1
; // init'd randomly
428 giant scr1
; // scratch
433 int loops
= LOOPS_DEF
;
436 unsigned maxSize
= MAX_SIZE_DEF
;
447 for(arg
=1; arg
<argc
; arg
++) {
451 maxSize
= atoi(&argp
[2]);
454 loops
= atoi(&argp
[2]);
457 seed
= atoi(&argp
[2]);
465 buf
= malloc(maxSize
);
470 seed
= (unsigned)tim
;
475 * Scratch giants, big enough for anything
477 scr1
= newGiant(4 * maxSize
* GIANT_BYTES_PER_DIGIT
);
478 scr2
= newGiant(4 * maxSize
* GIANT_BYTES_PER_DIGIT
);
480 printf("Starting giants test: seed %d\n", seed
);
481 for(loop
=0; loop
<loops
; loop
++) {
483 if((loop
% LOOP_NOTIFY
) == 0) {
484 printf("..loop %d\n", loop
);
487 g1
= genGiant(maxSize
, buf
);
488 g2
= genGiant(maxSize
, buf
);
491 if(compTest(g1
, g2
, scr1
, scr2
)) {
494 if(addSubTest(g1
, g2
, scr1
, scr2
)) {
499 if(mulTest(g1
, g2
, scr1
, scr2
)) {
504 if(squareTest(g1
, g2
, scr1
, scr2
)) {
507 if(lshiftTest(g1
, g2
, scr1
, scr2
)) {
510 if(modTest(g1
, g2
, scr1
, scr2
)) {
513 if(rshiftTest(g1
, g2
, scr1
, scr2
)) {
516 /* these all use divide....*/
517 if(divTest(g1
, g2
, scr1
, scr2
)) {
520 #if MODG1_TEST_ENABLE
521 if(modg1Test(g1
, scr1
, scr2
)) {
526 if(mulOnesTest(g1
, g2
, scr1
, scr2
)) {
533 printf("...giantDvt complete\n");