Beispiel #1
0
void zHex2Dec(z *u, z *v)
{
	//convert u[] in hex to v[] in decimal by repeatedly dividing
	//u by 1e9 = 0x3b9aca00
	//the remainder of the ith division is the ith decimal digit.
	//when the quotient = 0, stop

	z a,b;
	fp_digit r = 0;
	int su = abs(u->size);
	int approx_words = (int)((double)su * 1.5);	
	//because decimal takes more room than hex to store

	zInit(&a);
	zInit(&b);

	if (v->alloc < approx_words)
		zGrow(v,approx_words);
	zClear(v);

	if (a.alloc < approx_words)
	{
		zGrow(&a,approx_words);
		zClear(&a);
	}

	if (b.alloc < approx_words)
	{
		zGrow(&b,approx_words);
		zClear(&b);
	}
	
	zCopy(u,&a);
	v->size = 1;
	do
	{
		r = zShortDiv(&a,MAX_DEC_WORD,&b);
		v->val[v->size - 1] = r;
		v->size++;
		zCopy(&b,&a);
	} while (zCompare(&a,&zZero) != 0);
	v->size--;

	if (u->size < 0)
		v->size *= -1;

	zFree(&a);
	zFree(&b);
	return;
}
Beispiel #2
0
void monty_init(z *n)
{
	//for a input modulus n, initialize constants for 
	//montogomery representation
	//this assumes that n is relatively prime to 2, i.e. is odd.
	z g, b, q, r;

	//global montyconst structure
	zInit(&montyconst.nhat);
	zInit(&montyconst.r);
	zInit(&montyconst.rhat);
	zInit(&montyconst.one);

	
	if (abs(n->size) <= 16) 
	{
		fp_montgomery_setup(n,&montyconst.nhat.val[0]);
		fp_montgomery_calc_normalization(&montyconst.r,n);
		montyconst.one.val[0] = 1;
		montyconst.one.size = 1;
		to_monty(&montyconst.one,n);
		TFM_MONTY = 1;
		return;
	}
	else
		TFM_MONTY = 0;

	zInit(&g);
	zInit(&b);
	zInit(&q);
	zInit(&r);

	b.val[1]=1; b.size=2;

	//find r = b^t > N, where b = 2 ^32
	if (montyconst.r.alloc < n->size + 1)
		zGrow(&montyconst.r,n->size + 1);

	zClear(&montyconst.r);
	montyconst.r.size = n->size + 1;
	montyconst.r.val[montyconst.r.size - 1] = 1;

	//find nhat = -n^-1 mod b
	//nhat = -(n^-1 mod b) mod b = b - n^-1 mod b
	//since b is 2^32, this can be simplified, and made faster.
	xGCD(n,&b,&montyconst.nhat,&montyconst.rhat,&g);
	zSub(&b,&montyconst.nhat,&q);
	zCopy(&q,&montyconst.nhat);

	zCopy(&zOne,&montyconst.one);
	to_monty(&montyconst.one,n);

	zFree(&g);
	zFree(&b);
	zFree(&q);
	zFree(&r);
	return;
}
Beispiel #3
0
void zCopy(z *src, z *dest)
{
	//physically copy the digits of u into the digits of v
	int su = abs(src->size);
	
	if (src == dest)
		return;

	if (dest->alloc < su)
		zGrow(dest,su);

	memcpy(dest->val,src->val,su * sizeof(fp_digit));
	dest->size = src->size;
	dest->type = src->type;
	return;
}
Beispiel #4
0
void zDec2Hex(z *u, z *v)
{
	//convert u[] in dec to v[] in hex by multiplying the ith digit by (1e9)*i
	//and adding to the previous digits

	z a,b,vv;
	int i,su = abs(u->size);

	zInit(&a);
	zInit(&b);
	zInit(&vv);

	if (v->alloc < su)
		zGrow(v,su);

	if (a.alloc < su)
	{
		zGrow(&a,su);
		zClear(&a);
	}

	if (b.alloc < su)
	{
		zGrow(&b,su);
		zClear(&b);
	}

	if (vv.alloc < su)
	{
		zGrow(&vv,su);
		zClear(&vv);
	}
	vv.size = su;

	//a holds the value of (1e9)*i
	a.size = 1;
	a.val[0] = 1;
	for (i=0;i<su;i++)
	{
		zShortMul(&a,u->val[i],&b);
		zAdd(&vv,&b,&vv);
		zShortMul(&a,MAX_DEC_WORD,&a);
	}

	//v may have unused high order limbs
	for (i=su-1;i>=0;i--)
	{
		if (vv.val[i] != 0)
			break;
	}
	vv.size = i+1;

	if (u->size < 0)
		vv.size *= -1;

	if (vv.size == 0)
		vv.size = 1;

	zCopy(&vv,v);

	zFree(&vv);
	zFree(&a);
	zFree(&b);
	return;
}
Beispiel #5
0
void zREDC(z *T, z *n)
{
	/* from handbook of applied cryptography, ch. 14
	INPUT: integers m = (mn-1 . . .m1m0)b with gcd(m; b) = 1, R = b^n,m' = -m^-1 mod
	b, and T = (t2n-1 . . . t1t0)b <mR.
	OUTPUT: TR^-1 mod m, the reduction of T mod m in montgomery representation...
	1. A=T . (Notation: A = (a2n-1 . . . a1a0)b.)
	2. For i from 0 to (n - 1) do the following:
	2.1 ui=ai*m' mod b.
	2.2 A=A + ui*m*b^i.
	3. A=A/b^n.
	4. If A > m then A=A-m.
	5. Return(A).
	*/
	int i,j,ix,su;
	fp_digit nhat = montyconst.nhat.val[0], ui,k;
	z mtmp3;

	if (TFM_MONTY == 1)
	{
		fp_montgomery_reduce(T,n,montyconst.nhat.val[0]);
		return;
	}
	
	//printf("shouldn't get to here\n");
	zInit(&mtmp3);

	if (mtmp3.alloc < n->size * 2)
		zGrow(&mtmp3,n->size * 2);

	//T needs to have allocated montyconst.n.size + T.size
	if (T->alloc < n->size + T->size)
		zGrow(T,n->size + T->size + 1);
	
	for (i=0;i<n->size;i++)
	{
		//the mod b happens automatically because only the 
		//lower 32 bits of the product is returned.
		ui = T->val[i] * nhat;						//ui = a1*nhat mod b 	
		//zShortMul(&montyconst.n,ui,&mtmp3);			//t1 = ui * n
		
		//short mul
		k=0;
		su = n->size;
		for (ix=0;ix<su;++ix)
			spMulAdd(n->val[ix],ui,0,k,&mtmp3.val[ix],&k);

		//if still have a carry, add a digit to w
		if (k)
		{
			mtmp3.val[su]=k;
			su++;
		}
		
		//check for significant digits.  only necessary if v or u = 0?
		for (ix = su - 1;ix>=0;--ix)
		{
			if (mtmp3.val[ix] != 0)
				break;
		}
		mtmp3.size = ix+1;
		

		for (j=mtmp3.size - 1;j>=0;j--)				//t1 *= b^i 
			mtmp3.val[j+i] = mtmp3.val[j];
		mtmp3.size += i;
		zAdd(T,&mtmp3,T);								//A += t1
	}

	for (j=0; j<T->size; j++)						//A /= b^n
		T->val[j] = T->val[j+n->size];
	T->size -= n->size;

	if (zCompare(T,n) > 0)				//if A > n, A = A-n
		zSub(T,n,T);

	if (T->size == 0)
		zCopy(n,T);

	zFree(&mtmp3);

	return;	
}
void fp_mul_comba(z *A, z *B, z *C)
{
   int       ix, iy, iz, tx, ty, pa, sA, sB;
   fp_digit  c0, c1, c2, *tmpx, *tmpy;
   z    *dst;
   z loc;

   COMBA_START;
   COMBA_CLEAR;
   
   /* get size of output and trim */
   sA = abs(A->size);
   sB = abs(B->size);
   pa = sA + sB;

   if (A == C || B == C) {
	   zInit(&loc);
      //dst = &atmp1;
	   dst = &loc;
   } else {
      dst = C;
   }

	if (dst->alloc < pa)
		zGrow(dst,pa + LIMB_BLKSZ);
	zClear(dst);

   for (ix = 0; ix < pa; ix++) {
      /* get offsets into the two bignums */
      ty = MIN(ix, sB-1);
      tx = ix - ty;

      /* setup temp aliases */
      tmpx = A->val + tx;
      tmpy = B->val + ty;

      /* this is the number of times the loop will iterrate, essentially its 
         while (tx++ < a->used && ty-- >= 0) { ... }
       */
      iy = MIN(sA-tx, ty+1);

      /* execute loop */
      COMBA_FORWARD;
      for (iz = 0; iz < iy; ++iz) {
		  MULADD(*tmpx++, *tmpy--);
      }

      /* store term */
      COMBA_STORE(dst->val[ix]);
  }
  COMBA_FINI;

  dst->size = pa;
  if ((A->size * B->size) < 0)
	  dst->size *= -1;

  fp_clamp(dst);
  if (dst != C) {
	zCopy(dst, C);
	zFree(&loc);
  }
}
void fp_sqr_comba(z *A, z *B)
{
  int       pa, ix, iz, sA;
  fp_digit  c0, c1, c2;
  z    *dst;
  z loc;
#ifdef TFM_ISO
  uint64   tt;
#endif    

  /* get size of output and trim */
  sA = abs(A->size);
   pa = sA + sA;

  /* number of output digits to produce */
  COMBA_START;
  CLEAR_CARRY;

  if (A == B) {
     //zClear(&atmp1);
	  zInit(&loc);
     //dst = &atmp1;
	  dst = &loc;
  } else {
     zClear(B);
     dst = B;
  }

	if (dst->alloc < pa)
	{
		zGrow(dst,pa + LIMB_BLKSZ);
	}
	zClear(dst);
	
  for (ix = 0; ix < pa; ix++) { 
      int      tx, ty, iy;
      fp_digit *tmpy, *tmpx;

      /* get offsets into the two bignums */
      ty = MIN(sA-1, ix);
      tx = ix - ty;

      /* setup temp aliases */
      tmpx = A->val + tx;
      tmpy = A->val + ty;

      /* this is the number of times the loop will iterrate,
         while (tx++ < a->used && ty-- >= 0) { ... }
       */
      iy = MIN(sA-tx, ty+1);

      /* now for squaring tx can never equal ty 
       * we halve the distance since they approach 
       * at a rate of 2x and we have to round because 
       * odd cases need to be executed
       */
      iy = MIN(iy, (ty-tx+1)>>1);

      /* forward carries */
      CARRY_FORWARD;

      /* execute loop */
      for (iz = 0; iz < iy; iz++) {
		  SQRADD2(*tmpx++, *tmpy--);
      }

      /* even columns have the square term in them */
      if ((ix&1) == 0) {
		  SQRADD(A->val[ix>>1],A->val[ix>>1]);
      }

      /* store it */
      COMBA_STORE(dst->val[ix]);
  }