]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/ckutils/giantDvt/giantDvt.c
2 * Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "giantIntegers.h"
26 #include "ckutilities.h"
27 #include "feeFunctions.h"
30 #include "ckutilsPlatform.h"
35 #define MAX_SIZE_DEF 32
36 #define LOOP_NOTIFY 100
38 /* quick test to show modg(1,g) broken */
39 #define MODG1_TEST_ENABLE 1
41 static void usage(char **argv
)
43 printf("usage: %s [options]\n", argv
[0]);
44 printf(" Options:\n");
45 printf(" l=loops (default = %d)\n", LOOPS_DEF
);
46 printf(" x=maxBytes (default = %d)\n", MAX_SIZE_DEF
);
53 * ...min <= return <= max
55 static int genRand(int min
, int max
)
58 /* note random() only yields a 31-bit number... */
60 if(max
== min
) /* avoid % 1 ! */
63 return(min
+ (RAND() % (max
-min
+1)));
67 * Fill buffer with random data, random size from 1 to maxSize.
68 * Returns size of random data generated.
70 static unsigned fillData(unsigned maxSize
,
81 size
= genRand(1, maxSize
);
89 ip
= (unsigned *)data
;
90 for(i
=0; i
<intCount
; i
++) {
95 cp
= (unsigned char *)ip
;
96 for(i
=0; i
<residue
; i
++) {
97 *cp
++ = (unsigned char)RAND();
103 * create a giant with random size and data. *Buf is mallocd and
104 * uninitialized and will change here.
106 static giant
genGiant(unsigned maxBytes
, unsigned char *buf
)
108 int size
= fillData(maxBytes
, buf
, 0);
112 g
= giant_with_data(buf
, size
);
114 /* set random sign; giant_with_data() is always positive */
120 /* avoid zero data - too many pitfalls with mod and div */
128 static int testError()
132 printf("Attach via debugger for more info.\n");
133 printf("a to abort, c to continue: ");
135 return (resp
[0] != 'c');
139 static void gabs(giant g
)
147 * Individual tests. API is identical for all tests.
149 * g1, g2 : giants with random data, size, and sign. Tests do not modify
151 * scr1, scr2 : scratch giants, big enough for all conceivable ops. Can
152 * be modified at will.
153 * Return : 0 for sucess, 1 on error.
156 static int compTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
158 gtog(g1
, scr1
); // scr1 := g1
160 if(gcompg(g1
, scr2
)) {
161 printf("gtog/gcompg error\n");
167 static int addSubTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
169 gtog(g1
, scr1
); // scr1 := g1
170 addg(g2
, scr1
); // scr1 := g1 + g2
171 subg(g1
, scr1
); // scr1 := g1 + g2 - g1 =? g2
172 if(gcompg(g2
, scr1
)) {
173 printf("addg/subg error\n");
179 #define LARGEST_MUL 0xffff
181 static int mulTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
183 int randInt
= genRand(1, LARGEST_MUL
);
187 int_to_giant(randInt
, scr1
); // scr1 := randInt
188 gtog(g1
, scr2
); // scr2 := g1
189 mulg(scr1
, scr2
); // scr2 := g1 * randInt
191 /* now do the same thing with multiple adds */
192 int_to_giant(0, scr1
); // scr1 := 0
193 for(i
=0; i
<randInt
; i
++) {
194 addg(g1
, scr1
); // scr1 += g1
195 } // scr1 =? g1 * randInt
196 if(gcompg(scr1
, scr2
)) {
197 printf("g1 : "); printGiantHex(g1
);
198 printf("randInt : 0x%x\n", randInt
);
199 printf("good prod : "); printGiantHex(scr1
);
200 printf("bad prod : "); printGiantHex(scr2
);
201 printf("mulg error\n");
208 static int squareTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
211 mulg(g1
, scr1
); // scr1 := g1 * g1
213 gsquare(scr2
); // scr2 =? g1 * g1
214 if(gcompg(scr1
, scr2
)) {
215 printf("gsquare error\n");
221 static int lshiftTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
223 int maxShift
= (scr1
->capacity
- abs(g1
->sign
) - 1) *
224 GIANT_BITS_PER_DIGIT
;
225 int shiftCnt
= genRand(1, maxShift
);
226 giant scr3
= borrowGiant(scr1
->capacity
);
229 gtog(g1
, scr1
); // scr1 := g1
230 gshiftleft(shiftCnt
, scr1
); // scr1 := (g1 << shiftCnt)
232 gtog(g1
, scr2
); // scr2 := g1
234 int multInt
= (1 << shiftCnt
);
235 int_to_giant(multInt
, scr3
); // scr3 := (1 << shiftCnt)
238 int_to_giant(1, scr3
); // scr3 := 1;
239 gshiftleft(shiftCnt
, scr3
); // scr3 := (1 << shiftCnt)
241 mulg(scr3
, scr2
); // scr2 := g1 * (1 << shiftCnt);
242 if(gcompg(scr1
, scr2
)) {
243 printf("shiftCnt %d 0x%x\n", shiftCnt
, shiftCnt
);
244 printf("g1 : "); printGiantHex(g1
);
245 printf("scr1 : "); printGiantHex(scr1
);
246 printf("scr2 : "); printGiantHex(scr2
);
247 printf("gshiftleft error\n");
254 static int rshiftTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
256 int maxShift
= bitlen(g1
) - 1;
258 giant scr3
= borrowGiant(scr1
->capacity
);
261 /* special case, can't have g1 = 1 */
264 printf("...rshiftTest: tweaking g1 = 1\n");
270 shiftCnt
= genRand(1, maxShift
);
272 gtog(g1
, scr1
); // scr1 := g1
273 gabs(scr1
); // scr1 := |g1|
274 gtog(scr1
, scr2
); // scr2 := |g1|
275 gshiftright(shiftCnt
, scr1
); // scr1 := (|g1| >> shiftCnt)
278 int multInt
= (1 << shiftCnt
);
279 int_to_giant(multInt
, scr3
); // scr3 := (1 << shiftCnt)
282 int_to_giant(1, scr3
); // scr3 := 1;
283 gshiftleft(shiftCnt
, scr3
); // scr3 := (1 << shiftCnt)
285 divg(scr3
, scr2
); // scr2 := g1 / (1 << shiftCnt);
286 if(gcompg(scr1
, scr2
)) {
287 printf("shiftCnt %d 0x%x\n", shiftCnt
, shiftCnt
);
288 printf("g1 : "); printGiantHex(g1
);
289 printf("scr1 : "); printGiantHex(scr1
);
290 printf("scr2 : "); printGiantHex(scr2
);
291 printf("gshiftright error\n");
298 static int divTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
300 gtog(g1
, scr1
); // scr1 := g1
301 mulg(g2
, scr1
); // scr1 := g1 * g2
302 gtog(g2
, scr2
); // scr2 := g2
303 gabs(scr2
); // scr2 := |g2|
304 divg(scr2
, scr1
); // scr1 := (g1 * g2) / |g2|
306 /* weird case - if g2 is negative, this result is -g1! */
308 scr1
->sign
= -scr1
->sign
;
310 if(gcompg(scr1
, g1
)) {
311 printf("g1 : "); printGiantHex(g1
);
312 printf("g2 : "); printGiantHex(g1
);
313 printf("scr1 : "); printGiantHex(scr1
);
314 printf("divTest error\n");
320 #define LARGEST_MOD_MUL 0x40
322 static int modTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
324 int randInt
= genRand(1, LARGEST_MOD_MUL
);
325 giant scr3
= borrowGiant(scr1
->capacity
);
327 giant scr4
= borrowGiant(scr1
->capacity
);
331 int_to_giant(randInt
, scr1
); // scr1 := rand
333 gabs(scr2
); // scr2 := |g1|
335 /* current modg can't deal with g mod 1 ! */
336 if((scr2
->sign
== 1) && (scr2
->n
[0] == 1)) {
337 #if MODG1_TEST_ENABLE
338 /* assume that this is legal... */
340 printf("..modTest: g1 = 1, no tweak\n");
343 printf("..modTest: tweaking g1 = 1\n");
345 #endif MODG1_TEST_ENABLE
347 /* end modg workaround */
350 gabs(scr3
); // scr3 := |g2|
352 /* this will only work if randInt < |g1| */
353 if(gcompg(scr1
, scr2
) >= 0) {
355 printf("..modTest: tweaking rand, > g1 = "); printGiantHex(g1
);
356 printf(" g2 = "); printGiantHex(g2
);
357 printf(" rand = "); printGiantHex(scr1
);
359 modg(scr2
, scr1
); // scr1 := rand mod g1
360 if(gcompg(scr1
, scr2
) >= 0) {
361 printf("simple modg error\n");
366 mulg(scr2
, scr3
); // scr3 := |g1 * g2|
367 addg(scr1
, scr3
); // scr3 := (|g1 * g2|) + rand
369 modg(scr2
, scr3
); // scr3 := scr3 mod |g1| =? rand
370 if(gcompg(scr1
, scr3
)) {
371 printf("g1 : "); printGiantHex(g1
);
372 printf("g2 : "); printGiantHex(g2
);
373 printf("rand : 0x%x\n", randInt
);
374 printf("randG : "); printGiantHex(scr1
);
375 printf("scr4 : "); printGiantHex(scr4
);
376 printf("mod : "); printGiantHex(scr3
);
377 printf("modTest error\n");
387 #if MODG1_TEST_ENABLE
388 /* quickie test to demonstrate failure of modg(1, g). Known failure
390 * modg(1,g) fixed on 13 Apr 1998, so this should now work.
392 static int modg1Test(giant g1
, giant scr1
, giant scr2
)
400 printf("g1 : "); printGiantHex(g1
);
401 printf("g1 mod 1 : "); printGiantHex(scr2
);
406 #endif MODG1_TEST_ENABLE
408 static int mulOnesTest(giant g1
, giant g2
, giant scr1
, giant scr2
)
412 giant gOnes
= borrowGiant(scr1
->capacity
);
414 /* set up a giant with all ones data */
415 gOnes
->sign
= abs(g1
->sign
);
416 for(i
=0; i
<gOnes
->sign
; i
++) {
417 gOnes
->n
[i
] = (giantDigit
)(-1);
420 gtog(gOnes
, scr1
); // scr1 := gOnes
421 mulg(g1
, scr1
); // scr1 := gOnes * g1
426 if(gcompg(scr1
, scr2
)) {
427 printf("good prod : "); printGiantHex(scr1
);
428 printf("bad prod : "); printGiantHex(scr2
);
429 printf("mulOnesTest error\n");
436 int main(int argc
, char **argv
)
440 giant g1
; // init'd randomly
442 giant scr1
; // scratch
447 int loops
= LOOPS_DEF
;
450 unsigned maxSize
= MAX_SIZE_DEF
;
461 for(arg
=1; arg
<argc
; arg
++) {
465 maxSize
= atoi(&argp
[2]);
468 loops
= atoi(&argp
[2]);
471 seed
= atoi(&argp
[2]);
479 buf
= malloc(maxSize
);
484 seed
= (unsigned)tim
;
489 * Scratch giants, big enough for anything
491 scr1
= newGiant(4 * maxSize
* GIANT_BYTES_PER_DIGIT
);
492 scr2
= newGiant(4 * maxSize
* GIANT_BYTES_PER_DIGIT
);
494 printf("Starting giants test: seed %d\n", seed
);
495 for(loop
=0; loop
<loops
; loop
++) {
497 if((loop
% LOOP_NOTIFY
) == 0) {
498 printf("..loop %d\n", loop
);
501 g1
= genGiant(maxSize
, buf
);
502 g2
= genGiant(maxSize
, buf
);
505 if(compTest(g1
, g2
, scr1
, scr2
)) {
508 if(addSubTest(g1
, g2
, scr1
, scr2
)) {
513 if(mulTest(g1
, g2
, scr1
, scr2
)) {
518 if(squareTest(g1
, g2
, scr1
, scr2
)) {
521 if(lshiftTest(g1
, g2
, scr1
, scr2
)) {
524 if(modTest(g1
, g2
, scr1
, scr2
)) {
527 if(rshiftTest(g1
, g2
, scr1
, scr2
)) {
530 /* these all use divide....*/
531 if(divTest(g1
, g2
, scr1
, scr2
)) {
534 #if MODG1_TEST_ENABLE
535 if(modg1Test(g1
, scr1
, scr2
)) {
540 if(mulOnesTest(g1
, g2
, scr1
, scr2
)) {
547 printf("...giantDvt complete\n");