void Montgomery_multiplication(long b, long n,
                               verylong zm, verylong zx,
                               verylong zy, verylong *zA)
{
  long i, n1 = n + 1, u, mp, *a, *m, *x, *y;
  verylong za = 0, zb = 0, zc = 0, zd = 0, zs = 0;

  a = calloc(n1, sizeof(long));
  m = calloc(n1, sizeof(long));
  x = calloc(n1, sizeof(long));
  y = calloc(n1, sizeof(long));
  if (a == 0 || m == 0 || x == 0 || y == 0) {
    printf("*error*\ncan't get memory from Montgomery");
    printf(" multiplication");
    exit(1);
  }
  zintoz(b, &zb);
  zinvmod(zm, zb, &za);
  znegate(&za);
  mp = zsmod(za, b);
  radix_representation(b, n1, m, zm);
  radix_representation(b, n1, x, zx);
  radix_representation(b, n1, y, zy);
  zzero(zA);
  for (i = 0; i < n; i++) {
    radix_representation(b, n1, a, *zA);
    u = ((a[0] + x[i] * y[0]) * mp) % b;
    zsmul(zy, x[i], &za);
    zsmul(zm, u, &zc);
    zadd(*zA, za, &zs);
    zadd(zs, zc, &zd);
    zsdiv(zd, b, zA);
  }
  if (zcompare(*zA, zm) >= 0) {
    zsub(*zA, zm, &za);
    zcopy(za, zA);
  }
  free(a);
  free(m);
  free(x);
  free(y);
  zfree(&za);
  zfree(&zb);
  zfree(&zc);
  zfree(&zd);
  zfree(&zs);
}
Beispiel #2
0
int BabyStepGiantStep(verylong zalpha, verylong zbeta,
                      verylong zn, verylong zp, verylong *zx)
/* given a generator alpha of a cyclic group G of
   order n and an element beta compute the discrete
   logarithm x returns 0 if not enough memory
   for the problem 1 otherwise */
{
  long i, j, m;
  static verylong za = 0, zd = 0, zg = 0, zm = 0;
  struct Element *element, temp;

  zsqrt(zn, &za, &zd);
  zsadd(za, 1l, &zm);
  m = ztoint(zm);
  element = (struct Element *) malloc(m * sizeof(struct Element));
  if (element == 0) return 0;
  zone(&zd);
  /* construct table */
  for (i = 0; i < m; i++) {
    element[i].index = i;
    element[i].alpha_index = 0;
    zcopy(zd, &element[i].alpha_index);
    zmul(zd, zalpha, &za);
    zmod(za, zp, &zd);
  }
  /* sort on second values */
  for (i = 0; i < m - 1; i++) {
    for (j = i + 1; j < m; j++) {
      if (zcompare(element[i].alpha_index, element[j].alpha_index) > 0) {
        temp = element[i];
        element[i] = element[j];
        element[j] = temp;
      }
    }
  }
  zinvmod(zalpha, zp, &za);
  zexp(za, zm, &zg);
  zmod(zg, zp, &zd);
  zcopy(zbeta, &zg);
  for (i = 0; i < m; i++) {
    printf("%d ", element[i].index);
    zwriteln(element[i].alpha_index);
  }
  for (i = 0; i < m; i++) {
    j = Find(m, zg, element);
    if (j != - 1) {
      zsmul(zm, i, &za);
      zsadd(za, j, zx);
      for (j = 0; j < m; j++)
        zfree(&element[j].alpha_index);
      free(element);
      return 1;
    }
    zmul(zg, zd, &za);
    zmod(za, zp, &zg);
  }
  return 0;
}
Beispiel #3
0
/* Matrix multiplication C = A * B */
extern void amMul(ArrayMatrix C, ArrayMatrix A, ArrayMatrix B)
{
	mwSignedIndex np, nrow, ncol, nelem;

	/* Number of elements */
	nelem = intmax(A.nelem, B.nelem);

	/* Check if any of the arguments are a scalar */
	if (amIsScalar(A)) {
		/* Call scalar multiplication with A and B interchanged */
		nrow = B.nrow;
		ncol = B.ncol;
		if (A.complex || B.complex) {
			/* Complex multiplication */
			zsmul(C.data, B.data, A.data, B.nelem > 1, A.nelem > 1, nrow, ncol, nelem);
		} else {
			/* Real multiplication */
			dsmul(C.data, B.data, A.data, B.nelem > 1, A.nelem > 1, nrow, ncol, nelem);
		}
	} else if (amIsScalar(B)) {
		nrow = A.nrow;
		ncol = A.ncol;
		if (A.complex || B.complex) {
			/* Complex multiplication */
			zsmul(C.data, A.data, B.data, A.nelem > 1, B.nelem > 1, nrow, ncol, nelem);
		} else {
			/* Real multiplication */
			dsmul(C.data, A.data, B.data, A.nelem > 1, B.nelem > 1, nrow, ncol, nelem);
		}
	} else {
		nrow = A.nrow;
		ncol = B.ncol;
		np = A.ncol;
		if (A.complex || B.complex) {
			/* Complex multiplication */
			zgemul(C.data, A.data, B.data, A.nelem > 1, B.nelem > 1, np, nrow, ncol, nelem);
		} else {
			/* Real multiplication */
			dgemul(C.data, A.data, B.data, A.nelem > 1, B.nelem > 1, np, nrow, ncol, nelem);
		}
	}

}
Beispiel #4
0
void zai(verylong za0, verylong zn, verylong zx0, verylong *za1)
{
  long x = zsmod(zx0, 3l);
  static verylong za = 0;

  if (x == 1)
    zcopy(za0, za1);
  else if (x == 0) {
    zsmul(za0, 2l, &za);
    zmod(za, zn, za1);
  }
  else {
    zsadd(za0, 1l, &za);
    zmod(za, zn, za1);
  }
}
Beispiel #5
0
void zbi(verylong zb0, verylong zn, verylong zx0, verylong *zb1)
{
  long x = zsmod(zx0, 3l);
  static verylong zb = 0;

  if (x == 1) {
    zsadd(zb0, 1l, &zb);
    zmod(zb, zn, zb1);
  }
  else if (x == 0) {
    zsmul(zb0, 2l, &zb);
    zmod(zb, zn, zb1);
  }
  else
    zcopy(zb0, zb1);
}