#include "giantIntegers.h"
#include "ckutilities.h"
#include "feeFunctions.h"
#include "feeDebug.h"
#include <stdlib.h>
#include "ckutilsPlatform.h"
#include <stdio.h>
#include <time.h>
#define LOOPS_DEF 100
#define MAX_SIZE_DEF 32
#define LOOP_NOTIFY 100
#define MODG1_TEST_ENABLE 1
static void usage(char **argv)
{
printf("usage: %s [options]\n", argv[0]);
printf(" Options:\n");
printf(" l=loops (default = %d)\n", LOOPS_DEF);
printf(" x=maxBytes (default = %d)\n", MAX_SIZE_DEF);
printf(" s=seed\n");
printf(" h(elp)\n");
exit(1);
}
static int genRand(int min, int max)
{
if(max == min)
return(max);
else
return(min + (RAND() % (max-min+1)));
}
static unsigned fillData(unsigned maxSize,
unsigned char *data,
int evenOnly)
{
unsigned *ip;
unsigned intCount;
unsigned residue;
unsigned char *cp;
int i;
unsigned size;
size = genRand(1, maxSize);
if(evenOnly) {
size &= ~1;
if(size == 1) {
size = 2;
}
}
intCount = size >> 2;
ip = (unsigned *)data;
for(i=0; i<intCount; i++) {
*ip++ = RAND();
}
residue = size & 0x3;
cp = (unsigned char *)ip;
for(i=0; i<residue; i++) {
*cp++ = (unsigned char)RAND();
}
return size;
}
static giant genGiant(unsigned maxBytes, unsigned char *buf)
{
int size = fillData(maxBytes, buf, 0);
int i;
giant g;
g = giant_with_data(buf, size);
i = RAND();
if(i & 1) {
g->sign = -g->sign;
}
if(isZero(g)) {
g->sign = 1;
g->n[0] = 0x77;
}
return g;
}
static int testError()
{
char resp[100];
printf("Attach via debugger for more info.\n");
printf("a to abort, c to continue: ");
gets(resp);
return (resp[0] != 'c');
}
static void gabs(giant g)
{
if(g->sign < 0) {
g->sign = -g->sign;
}
}
static int compTest(giant g1, giant g2, giant scr1, giant scr2)
{
gtog(g1, scr1); gtog(scr1, scr2);
if(gcompg(g1, scr2)) {
printf("gtog/gcompg error\n");
return testError();
}
return 0;
}
static int addSubTest(giant g1, giant g2, giant scr1, giant scr2)
{
gtog(g1, scr1); addg(g2, scr1); subg(g1, scr1); if(gcompg(g2, scr1)) {
printf("addg/subg error\n");
return testError();
}
return 0;
}
#define LARGEST_MUL 0xffff
static int mulTest(giant g1, giant g2, giant scr1, giant scr2)
{
int randInt = genRand(1, LARGEST_MUL);
int i;
int rtn = 0;
int_to_giant(randInt, scr1); gtog(g1, scr2); mulg(scr1, scr2);
int_to_giant(0, scr1); for(i=0; i<randInt; i++) {
addg(g1, scr1); } if(gcompg(scr1, scr2)) {
printf("g1 : "); printGiantHex(g1);
printf("randInt : 0x%x\n", randInt);
printf("good prod : "); printGiantHex(scr1);
printf("bad prod : "); printGiantHex(scr2);
printf("mulg error\n");
rtn = testError();
}
return rtn;
}
static int squareTest(giant g1, giant g2, giant scr1, giant scr2)
{
gtog(g1, scr1);
mulg(g1, scr1); gtog(g1, scr2);
gsquare(scr2); if(gcompg(scr1, scr2)) {
printf("gsquare error\n");
return testError();
}
return 0;
}
static int lshiftTest(giant g1, giant g2, giant scr1, giant scr2)
{
int maxShift = (scr1->capacity - abs(g1->sign) - 1) *
GIANT_BITS_PER_DIGIT;
int shiftCnt = genRand(1, maxShift);
giant scr3 = borrowGiant(scr1->capacity);
int rtn = 0;
gtog(g1, scr1); gshiftleft(shiftCnt, scr1);
gtog(g1, scr2); if(shiftCnt <= 30) {
int multInt = (1 << shiftCnt);
int_to_giant(multInt, scr3); }
else {
int_to_giant(1, scr3); gshiftleft(shiftCnt, scr3); }
mulg(scr3, scr2); if(gcompg(scr1, scr2)) {
printf("shiftCnt %d 0x%x\n", shiftCnt, shiftCnt);
printf("g1 : "); printGiantHex(g1);
printf("scr1 : "); printGiantHex(scr1);
printf("scr2 : "); printGiantHex(scr2);
printf("gshiftleft error\n");
rtn = testError();
}
returnGiant(scr3);
return rtn;
}
static int rshiftTest(giant g1, giant g2, giant scr1, giant scr2)
{
int maxShift = bitlen(g1) - 1;
int shiftCnt;
giant scr3 = borrowGiant(scr1->capacity);
int rtn = 0;
if(maxShift == 0) {
#if FEE_DEBUG
printf("...rshiftTest: tweaking g1 = 1\n");
#endif
g1->n[0] = 2;
shiftCnt = 1;
}
else {
shiftCnt = genRand(1, maxShift);
}
gtog(g1, scr1); gabs(scr1); gtog(scr1, scr2); gshiftright(shiftCnt, scr1);
if(shiftCnt <= 30) {
int multInt = (1 << shiftCnt);
int_to_giant(multInt, scr3); }
else {
int_to_giant(1, scr3); gshiftleft(shiftCnt, scr3); }
divg(scr3, scr2); if(gcompg(scr1, scr2)) {
printf("shiftCnt %d 0x%x\n", shiftCnt, shiftCnt);
printf("g1 : "); printGiantHex(g1);
printf("scr1 : "); printGiantHex(scr1);
printf("scr2 : "); printGiantHex(scr2);
printf("gshiftright error\n");
rtn = testError();
}
returnGiant(scr3);
return rtn;
}
static int divTest(giant g1, giant g2, giant scr1, giant scr2)
{
gtog(g1, scr1); mulg(g2, scr1); gtog(g2, scr2); gabs(scr2); divg(scr2, scr1);
if(g2->sign < 0) {
scr1->sign = -scr1->sign;
}
if(gcompg(scr1, g1)) {
printf("g1 : "); printGiantHex(g1);
printf("g2 : "); printGiantHex(g1);
printf("scr1 : "); printGiantHex(scr1);
printf("divTest error\n");
return testError();
}
return 0;
}
#define LARGEST_MOD_MUL 0x40
static int modTest(giant g1, giant g2, giant scr1, giant scr2)
{
int randInt = genRand(1, LARGEST_MOD_MUL);
giant scr3 = borrowGiant(scr1->capacity);
giant scr4 = borrowGiant(scr1->capacity);
int rtn = 0;
int_to_giant(randInt, scr1); gtog(g1, scr2);
gabs(scr2);
if((scr2->sign == 1) && (scr2->n[0] == 1)) {
#if MODG1_TEST_ENABLE
#if FEE_DEBUG
printf("..modTest: g1 = 1, no tweak\n");
#endif
#else
printf("..modTest: tweaking g1 = 1\n");
scr2->n[0] = 0x54;
#endif MODG1_TEST_ENABLE
}
gtog(g2, scr3);
gabs(scr3);
if(gcompg(scr1, scr2) >= 0) {
#if FEE_DEBUG
printf("..modTest: tweaking rand, > g1 = "); printGiantHex(g1);
printf(" g2 = "); printGiantHex(g2);
printf(" rand = "); printGiantHex(scr1);
#endif
modg(scr2, scr1); if(gcompg(scr1, scr2) >= 0) {
printf("simple modg error\n");
return testError();
}
}
mulg(scr2, scr3); addg(scr1, scr3); gtog(scr3, scr4);
modg(scr2, scr3); if(gcompg(scr1, scr3)) {
printf("g1 : "); printGiantHex(g1);
printf("g2 : "); printGiantHex(g2);
printf("rand : 0x%x\n", randInt);
printf("randG : "); printGiantHex(scr1);
printf("scr4 : "); printGiantHex(scr4);
printf("mod : "); printGiantHex(scr3);
printf("modTest error\n");
rtn = testError();
}
returnGiant(scr3);
returnGiant(scr4);
return rtn;
}
#if MODG1_TEST_ENABLE
static int modg1Test(giant g1, giant scr1, giant scr2)
{
scr1->n[0] = 1;
scr1->sign = 1;
gtog(g1, scr2);
modg(scr1, scr2);
if(!isZero(scr2)) {
printf("g1 : "); printGiantHex(g1);
printf("g1 mod 1 : "); printGiantHex(scr2);
return testError();
}
return 0;
}
#endif MODG1_TEST_ENABLE
static int mulOnesTest(giant g1, giant g2, giant scr1, giant scr2)
{
int i;
int rtn = 0;
giant gOnes = borrowGiant(scr1->capacity);
gOnes->sign = abs(g1->sign);
for(i=0; i<gOnes->sign; i++) {
gOnes->n[i] = (giantDigit)(-1);
}
gtog(gOnes, scr1); mulg(g1, scr1);
gtog(g1, scr2);
mulg(gOnes, scr2);
if(gcompg(scr1, scr2)) {
printf("good prod : "); printGiantHex(scr1);
printf("bad prod : "); printGiantHex(scr2);
printf("mulOnesTest error\n");
rtn = testError();
}
return rtn;
}
int main(int argc, char **argv)
{
int arg;
char *argp;
giant g1; giant g2; giant scr1; giant scr2; unsigned char *buf;
int loop;
int loops = LOOPS_DEF;
int seedSpec = 0;
unsigned seed = 0;
unsigned maxSize = MAX_SIZE_DEF;
initCryptKit();
#ifdef macintosh
seedSpec = 1;
seed = 0;
argc = 1;
maxSize = 8;
#endif
for(arg=1; arg<argc; arg++) {
argp = argv[arg];
switch(argp[0]) {
case 'x':
maxSize = atoi(&argp[2]);
break;
case 'l':
loops = atoi(&argp[2]);
break;
case 's':
seed = atoi(&argp[2]);
seedSpec = 1;
break;
case 'h':
default:
usage(argv);
}
}
buf = malloc(maxSize);
if(!seedSpec) {
time_t tim;
time(&tim);
seed = (unsigned)tim;
}
SRAND(seed);
scr1 = newGiant(4 * maxSize * GIANT_BYTES_PER_DIGIT);
scr2 = newGiant(4 * maxSize * GIANT_BYTES_PER_DIGIT);
printf("Starting giants test: seed %d\n", seed);
for(loop=0; loop<loops; loop++) {
if((loop % LOOP_NOTIFY) == 0) {
printf("..loop %d\n", loop);
}
g1 = genGiant(maxSize, buf);
g2 = genGiant(maxSize, buf);
#if 1
if(compTest(g1, g2, scr1, scr2)) {
exit(1);
}
if(addSubTest(g1, g2, scr1, scr2)) {
exit(1);
}
#endif
#if 1
if(mulTest(g1, g2, scr1, scr2)) {
exit(1);
}
#endif
#if 1
if(squareTest(g1, g2, scr1, scr2)) {
exit(1);
}
if(lshiftTest(g1, g2, scr1, scr2)) {
exit(1);
}
if(modTest(g1, g2, scr1, scr2)) {
exit(1);
}
if(rshiftTest(g1, g2, scr1, scr2)) {
exit(1);
}
if(divTest(g1, g2, scr1, scr2)) {
exit(1);
}
#if MODG1_TEST_ENABLE
if(modg1Test(g1, scr1, scr2)) {
exit(1);
}
#endif
#endif 0
if(mulOnesTest(g1, g2, scr1, scr2)) {
exit(1);
}
freeGiant(g1);
freeGiant(g2);
}
printf("...giantDvt complete\n");
return 0;
}