]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cryptkit/ckutils/atomTime/atomTime.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cryptkit / ckutils / atomTime / atomTime.c
diff --git a/Security/libsecurity_cryptkit/ckutils/atomTime/atomTime.c b/Security/libsecurity_cryptkit/ckutils/atomTime/atomTime.c
new file mode 100644 (file)
index 0000000..d4eec12
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * atomTime.c - measure performance of mulg, gsquare, feemod, 
+ * gshift{left,right}, elliptic, ellMulProj
+ */
+#include "ckconfig.h"
+#include "ckutilsPlatform.h"
+#include "CryptKitSA.h"
+#include "ckutilities.h"               /* needs private headers */
+#include "curveParams.h"               /* ditto */
+#include "falloc.h"                            /* ditto */
+#include "elliptic.h"
+#include "ellipticProj.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+/* default loops for "fast" and "slow" ops respecitively */
+#define LOOPS_DEF_FAST 10000
+#define LOOPS_DEF_SLOW 100
+
+#define NUM_BORROW     100
+
+/* individual enables - normally all on, disable to zero in on one test */
+#define MULG_ENABLE        1
+#define GSQUARE_ENABLE     1
+#define FEEMOD_ENABLE      1
+#define BORROW_ENABLE      1
+#define        SHIFT_ENABLE        1
+#define BINVAUX_ENABLE     1
+#define MAKE_RECIP_ENABLE   1
+#define MODGRECIP_ENABLE    1
+#define KEYGEN_ENABLE      1
+#define ELLIPTIC_ENABLE            1
+#define ELL_SIMPLE_ENABLE   1
+
+static void usage(char **argv)
+{
+       printf("Usage: %s [l=loops_fast] [L=loops_slow] [q(uick)] [D=depth]\n", argv[0]);
+       exit(1);
+}
+
+/*
+ * Fill numGiants with random data of length bits. 
+ */
+static void genRandGiants(giant *giants, 
+       unsigned numGiants,
+       unsigned bits,
+       feeRand rand)
+{
+       int i;
+       giant g;
+       unsigned char *rdata;
+       unsigned bytes = (bits + 7) / 8;
+       giantDigit mask = 0;
+       unsigned giantMsd = 0;  // index of MSD
+       unsigned log2BitsPerDigit;
+       unsigned bitsPerDigit;
+       
+       /* just to satisfy compiler - make sure it's always called */
+       if(giants == NULL) {
+           return;
+       }
+       
+       log2BitsPerDigit = GIANT_LOG2_BITS_PER_DIGIT;
+       bitsPerDigit = GIANT_BITS_PER_DIGIT;
+
+       if((bits & 7) != 0) {
+               /* 
+                * deserializeGiant() has a resolution of one byte. We
+                * need more resolution - that is, we'll be creating
+                * giants a little larger than we need, and we'll mask off 
+                * some bits in the giants' m.s. digit.
+                * This assumes that data fills the giantDigits such 
+                * that if bytes mod GIANT_BYTES_PER_DIGIT != 0, the
+                * empty byte(s) in the MSD are in the m.s. byte(s).
+                */
+               giantMsd = bits >> log2BitsPerDigit;
+               mask = (1 << (bits & (bitsPerDigit - 1))) - 1;
+       }
+       rdata = fmalloc(bytes);
+       for(i=0; i<numGiants; i++) {
+               g = giants[i];
+               feeRandBytes(rand, rdata, bytes);
+               deserializeGiant(rdata, g, bytes);
+               if(mask != 0) {
+                       int j;
+                       
+                       g->n[giantMsd] &= mask;
+                       
+                       /*
+                        * We've zeroed out some bits; we might have to 
+                        * adjust the sign of the giant as well. Note that
+                        * deserializeGiant always yields positive 
+                        * giants....
+                        */
+                       for(j=(g->sign - 1); j!=0; j--) {       
+                           if(g->n[j] == 0) {
+                               (g->sign)--;
+                           }
+                           else {
+                               break;
+                           }
+                       }
+               }
+       }
+       ffree(rdata);
+       return;
+}
+
+#if    CRYPTKIT_ELL_PROJ_ENABLE
+/*
+ * Assumes the presence of numEllPoints items in *points, and that the
+ * x coordinate in each point is init'd to a random giant. Uses the x
+ * coords as seeds to make normalized points of the entire *points array.
+ */
+static void makePoints(pointProjStruct *points, 
+       unsigned numEllPoints,
+       curveParams *cp)
+{
+       int i;
+       giant seed = newGiant(cp->maxDigits);
+       
+       for(i=0; i<numEllPoints; i++) {
+               gtog(points[i].x, seed);
+               findPointProj(&points[i], seed, cp);
+       }
+       freeGiant(seed);
+}
+
+#endif /* CRYPTKIT_ELL_PROJ_ENABLE */
+
+int main(int argc, char **argv)
+{
+       int             arg;
+       char            *argp;
+       unsigned        loopsFast = LOOPS_DEF_FAST;
+       unsigned        loopsSlow = LOOPS_DEF_SLOW;
+       unsigned        maxLoops;
+       unsigned        depth;
+       feeRand         rand;
+       giant           *giants;
+       unsigned        seed;
+       int             i;
+       int             j;
+       PLAT_TIME       startTime;
+       PLAT_TIME       endTime;
+       double          elapsed;
+       unsigned        numGiants;
+       #if CRYPTKIT_ELL_PROJ_ENABLE
+       unsigned        numEllGiants;           // for elliptic ops
+       unsigned        numEllPoints;           // for elliptic ops
+       #endif  
+       curveParams     *cp;
+       unsigned        quick = 0;
+       unsigned        minDepth = 0;
+       unsigned        maxDepth = FEE_DEPTH_MAX;
+       unsigned        basePrimeLen;
+       int             *shiftCnt;
+       char            *curveType;
+       #if CRYPTKIT_ELL_PROJ_ENABLE
+       pointProjStruct *points;
+       #endif
+       giant           z = NULL;
+       giant           modGiant = NULL;
+       giant           recip = NULL;
+       feePubKey       *keyArray = NULL;
+       giant           gborrow[NUM_BORROW];
+       
+       /* just to satisfy compiler - make sure it's always called */
+       genRandGiants(NULL, 0, 0, 0);
+
+       for(arg=1; arg<argc; arg++) {
+               argp = argv[arg];
+               switch(argp[0]) {
+                   case 'l':
+                       loopsFast = atoi(&argp[2]);
+                       break;
+                   case 'L':
+                       loopsSlow = atoi(&argp[2]);
+                       break;
+                   case 'q':
+                       quick = 1;
+                       break;
+                   case 'D':
+                       minDepth = maxDepth = atoi(&argp[2]);
+                       break;
+                   default:
+                       usage(argv);
+                       break;
+               }
+       }
+       
+       /*
+        * Common random generator
+        */
+       time((unsigned long *)&seed);
+       rand = feeRandAllocWithSeed(seed);
+
+       maxLoops = loopsFast;
+       if(loopsSlow > maxLoops) {
+           maxLoops = loopsSlow;
+       }
+       
+       /*
+        * Alloc array of giants big enough for squaring at the largest
+        * key size, enough of them for 'loops' mulgs
+        */
+       cp = curveParamsForDepth(FEE_DEPTH_LARGEST);
+       numGiants = maxLoops * 2;                       // 2 giants per loop
+       if(loopsSlow > (maxLoops / 4)) {
+           /* findPointProj needs 4 giants per loop */
+           numGiants *= 4;
+       }
+       #if CRYPTKIT_ELL_PROJ_ENABLE
+       numEllGiants = loopsSlow * 2;
+       numEllPoints = loopsSlow * 2;
+       #endif
+       giants = fmalloc(numGiants * sizeof(giant));
+       if(giants == NULL) {
+               printf("malloc failure\n");
+               exit(1);
+       }
+       for(i=0; i<numGiants; i++) {
+               giants[i] = newGiant(cp->maxDigits);
+               if(giants[i] == NULL) {
+                       printf("malloc failure\n");
+                       exit(1);
+               }
+       }
+       freeCurveParams(cp);
+       
+       #if CRYPTKIT_ELL_PROJ_ENABLE
+       /*
+        * Projective points - two per ellLoop. The giants come from 
+        * giants[]. We reserve an extra giant per point.
+        * We're assuming that numEllPoints < (4 * numGiants).
+        */
+       points = fmalloc(numEllPoints * sizeof(pointProjStruct));
+       if(points == NULL) {
+               printf("malloc failure\n");
+               exit(1);
+       }
+       j=0;
+       for(i=0; i<numEllPoints; i++) {
+               points[i].x = giants[j++];
+               points[i].y = giants[j++];
+               points[i].z = giants[j++];
+               j++;                            // skip a giant
+       }
+       #endif
+       
+       /* feePubKey array */
+       keyArray = fmalloc(sizeof(feePubKey) * loopsSlow);
+       if(keyArray == NULL) {
+               printf("malloc failure\n");
+               exit(1);
+       }
+       
+       /*
+        * Alloc an array of shiftCnt ints
+        */
+       shiftCnt = fmalloc(maxLoops * sizeof(int));
+       if(shiftCnt == NULL) {
+               printf("malloc failure\n");
+               exit(1);
+       }
+       
+       for(depth=minDepth; depth<=maxDepth; depth++) {
+       
+               if(quick) {
+                   if((depth != FEE_DEPTH_127M) &&
+                      (depth != FEE_DEPTH_161W)) {
+                       continue;
+                   }
+               }
+               
+               /*
+                * Get curve params for this depth
+                */
+               cp = curveParamsForDepth(depth);
+               if(cp == NULL) {
+                       printf("malloc failure\n");
+                       exit(1);
+               }
+               switch(cp->curveType) {
+                   case FCT_Montgomery:
+                       curveType = "FCT_Montgomery";
+                       break;
+                   case FCT_Weierstrass:
+                       curveType = "FCT_Weierstrass";
+                       break;
+                   case FCT_General:
+                       curveType = "FCT_General";
+                       break;
+                   default:
+                       printf("***Unknown curveType!\n");
+                       exit(1);
+               }
+               
+               switch(cp->primeType) {
+                   case FPT_General:
+                       printf("depth=%d; FPT_General, %s; keysize=%d;\n", 
+                               depth, curveType, bitlen(cp->basePrime));
+                       break;
+                   case FPT_Mersenne:
+                       printf("depth=%d; FPT_Mersenne, %s; q=%d\n",
+                               depth, curveType, cp->q);
+                       break;
+                   default:
+                       printf("depth=%d; FPT_FEE, %s; q=%d k=%d\n",
+                               depth, curveType, cp->q, cp->k);
+                       break;
+               }
+               basePrimeLen = bitlen(cp->basePrime);
+               
+               /*
+                * mulg test
+                * bitlen(giant) <= bitlen(basePrime);
+                * giants[n+1] *= giants[n]
+                */
+               #if     MULG_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<numGiants; i+=2) {
+                       mulg(giants[i], giants[i+1]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   mulg:             %12.2f ns per op\n", 
+                       elapsed / (numGiants / 2));
+               #endif  /* MULG_ENABLE */
+               
+               /*
+                * gsquare test
+                * bitlen(giant) <= bitlen(basePrime);
+                * gsquare(giants[n])
+                */
+               #if     GSQUARE_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsFast; i++) {
+                       gsquare(giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   gsquare:          %12.2f ns per op\n", elapsed / loopsFast);
+               #endif  /* GSQUARE_ENABLE */
+               
+               /*
+                * feemod test
+                * bitlen(giant) <= ((2 * bitlen(basePrime) - 2);
+                * feemod(giants[n])
+                */
+               #if     FEEMOD_ENABLE
+               genRandGiants(giants, numGiants, (basePrimeLen * 2) - 2, 
+                       rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsFast; i++) {
+                       feemod(cp, giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   feemod:           %12.2f ns per op\n", elapsed / loopsFast);
+               #endif  /* FEEMOD_ENABLE */
+               
+               
+               /*
+                * borrowGiant test
+                */
+               #if     BORROW_ENABLE
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsFast; i++) {
+                   for(j=0; j<NUM_BORROW; j++) {
+                       gborrow[j] = borrowGiant(cp->maxDigits);
+                   }
+                   for(j=0; j<NUM_BORROW; j++) {
+                       returnGiant(gborrow[j]);
+                   }
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   borrow/return:    %12.2f ns per op\n", 
+                       elapsed / (loopsFast * NUM_BORROW));            
+               #endif  /* BORROW_ENABLE */
+               
+               /*
+                * shiftright test
+                * bitlen(giant) <= bitlen(basePrime)
+                * 0 <= shiftCnt <= bitlen(basePrime)
+                * gshiftright(giants[i])
+                */
+               #if     SHIFT_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               for(i=0; i<loopsFast; i++) {
+                       shiftCnt[i] = feeRandNextNum(rand) % basePrimeLen;
+               }
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsFast; i++) {
+                       gshiftright(shiftCnt[i], giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   gshiftright:      %12.2f ns per op\n", elapsed / loopsFast);
+                
+               /*
+                * shiftleft test
+                * bitlen(giant) <= bitlen(basePrime)
+                * 1 <= shiftCnt <= bitlen(basePrime)
+                * gshiftleft(giants[i]
+                */
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsFast; i++) {
+                       gshiftright(shiftCnt[i], giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   gshiftleft:       %12.2f ns per op\n", elapsed / loopsFast);
+               #endif  /* SHIFT_ENABLE */
+               
+               /*
+                * binvaux test
+                * bitlen(giant) <= bitlen(basePrime);
+                * binvaux(basePrime, giants[n+1])
+                */
+               #if     BINVAUX_ENABLE
+               genRandGiants(giants, loopsSlow, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       binvaux(cp->basePrime, giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   binvaux:          %12.2f us per op\n", 
+                       elapsed / loopsSlow);
+               #endif  /* BINVAUX_ENABLE */
+               
+               /*
+                * make_recip test
+                * bitlen(giant) <= bitlen(basePrime);
+                * make_recip(giants[n], giants[n+1]
+                */
+               #if     MAKE_RECIP_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow*2; i+=2) {
+                       make_recip(giants[i], giants[i+1]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   make_recip:       %12.2f us per op\n", 
+                       elapsed / loopsSlow);
+               #endif  /* MAKE_RECIP_ENABLE */
+               
+               /*
+                * modg_via_recip test
+                * bitlen(giant) <= ((2 * bitlen(basePrime) - 2);
+                * bitlen(modGiant) <= bitlen(basePrime)
+                * calc recip of modGiant
+                * modg_via_recip(giants[i])
+                */
+               #if     MODGRECIP_ENABLE
+               genRandGiants(giants, numGiants, (basePrimeLen * 2) - 2, 
+                       rand);
+               modGiant = borrowGiant(cp->maxDigits);
+               recip = borrowGiant(cp->maxDigits);
+               genRandGiants(&modGiant, 1, basePrimeLen, rand);
+               make_recip(modGiant, recip);
+               
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       modg_via_recip(modGiant, recip, giants[i]);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   modg_via_recip:   %12.2f ns per op\n", 
+                       elapsed / loopsSlow);
+               returnGiant(modGiant);
+               modGiant = NULL;
+               returnGiant(recip);
+               recip = NULL;
+               #endif  /* MODGRECIP_ENABLE */
+               
+               /*
+                * key generate test
+                * keyArray[n] = feePubKeyAlloc(); 
+                * feePubKeyInitFromPrivData(keyArray[n] );
+                */
+               #if KEYGEN_ENABLE
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       keyArray[i] = feePubKeyAlloc(); 
+                       if(keyArray[i] == NULL) {
+                               printf("malloc failure\n");
+                               exit(1);
+                       }
+                       /* fixme how about some better seed data */
+                       feePubKeyInitFromPrivDataDepth(keyArray[i],
+                               (unsigned char *)"somePrivData",
+                               12,
+                               depth,
+                               1);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   keygen:           %12.2f us per op\n",       
+                       elapsed / loopsSlow);
+               for(i=0; i<loopsSlow; i++) {
+                       feePubKeyFree(keyArray[i]);
+               }
+               #endif  /* KEYGEN_ENABLE*/
+               
+               /*
+                * elliptic test
+                * bitlen(giant) <= bitlen(basePrime);
+                * {giants[n], 1} *=  giants[n+1]   (elliptic mult)
+                */
+               #if ELLIPTIC_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               z = borrowGiant(cp->maxDigits);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i+=2) {
+                       /* superoptimized int_to_giant(1) */
+                       z->n[0] = 1;
+                       z->sign = 1;
+                       elliptic(giants[i], z, giants[i+1], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   elliptic:         %12.2f us per op\n", 
+                       elapsed / (loopsSlow / 2));
+               #endif  /* ELLIPTIC_ENABLE*/
+               
+               /*
+                * elliptic_simple test
+                * bitlen(giant) <= bitlen(basePrime);
+                * giants[n] *= giants[n+1] (elliptic mult)
+                */
+               #if ELL_SIMPLE_ENABLE
+               genRandGiants(giants, numGiants, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow*2; i+=2) {
+                       elliptic_simple(giants[i], giants[i+1], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   elliptic_simple:  %12.2f us per op\n", 
+                       elapsed / loopsSlow);
+               #endif  /* ELL_SIMPLE_ENABLE */
+               
+               if(cp->curveType != FCT_Weierstrass) {
+                       goto loopEnd;
+               }
+               
+               #if CRYPTKIT_ELL_PROJ_ENABLE
+               /*
+                * ellMulProj test
+                * bitlen(giant) <= bitlen(basePrime);
+                * point[n+1] = point[n] * giants[4n+3] 
+                * 
+                * note we're cooking up way more giants than we have to;
+                * we really only need the x's and k's. But what the heck.
+                */
+               genRandGiants(giants, 4 * numEllPoints, basePrimeLen, rand);
+               makePoints(points, numEllPoints, cp);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i+=2) {
+                       ellMulProj(&points[i], &points[i+1], 
+                               giants[4*i+3], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   ellMulProj:       %12.2f us per op\n", 
+                       elapsed / (loopsSlow / 2));
+       
+               /*
+                * ellMulProjSimple test
+                * bitlen(giant) <= bitlen(basePrime);
+                * point[n] *= giants[4n+3] (projective elliptic mult)
+                */
+               genRandGiants(giants, 4 * numEllPoints, basePrimeLen, rand);
+               makePoints(points, numEllPoints, cp);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       ellMulProjSimple(&points[i], giants[4*i+3], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   ellMulProjSimple: %12.2f us per op\n", 
+                       elapsed / loopsSlow);
+       
+               /*
+                * ellAddProj test
+                * bitlen(giant) <= bitlen(basePrime);
+                * point[n] += point[n+1] (projective elliptic add)
+                */
+               genRandGiants(giants, 4 * numEllPoints, basePrimeLen, rand);
+               makePoints(points, numEllPoints, cp);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i+=2) {
+                       ellAddProj(&points[i], &points[i+1], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   ellAddProj:       %12.2f ns per op\n",
+                       elapsed / loopsSlow);
+       
+               /*
+                * ellDoubleProj test
+                * bitlen(giant) <= bitlen(basePrime);
+                * ellDoubleProj(point[n])
+                */
+               genRandGiants(giants, 4 * numEllPoints, basePrimeLen, rand);
+               makePoints(points, numEllPoints, cp);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       ellDoubleProj(&points[i], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_NS(startTime, endTime);
+               printf("   ellDoubleProj:    %12.2f ns per op\n", 
+                       elapsed / loopsSlow);
+       
+               /*
+                * findPointProj test
+                * bitlen(giant) <= bitlen(basePrime);
+                * findPointProj(point[n], giants[4n+3])
+                */
+               genRandGiants(giants, 4 * loopsSlow, basePrimeLen, rand);
+               PLAT_GET_TIME(startTime);
+               for(i=0; i<loopsSlow; i++) {
+                       findPointProj(&points[i], giants[4*i + 3], cp);
+               }
+               PLAT_GET_TIME(endTime);
+               elapsed = PLAT_GET_US(startTime, endTime);
+               printf("   findPointProj:    %12.2f us per op\n", 
+                       elapsed / loopsSlow);
+                       
+               #endif  /* CRYPTKIT_ELL_PROJ_ENABLE */
+
+loopEnd:
+               freeCurveParams(cp);
+       }
+       
+       feeRandFree(rand);
+       for(i=0; i<numGiants; i++) {
+               freeGiant(giants[i]);
+       }
+       ffree(giants);
+       if(z) {
+           freeGiant(z);
+       }
+       if(recip) {
+           freeGiant(recip);
+       }
+       if(modGiant) {
+           freeGiant(modGiant);
+       }
+       return 0;
+}