void Garner(long t, verylong *zm, verylong *zv, verylong *zx) /* solution of the Chinese remaider theorem */ { long i, j; verylong za = 0, zb = 0, zu = 0, zC[CRT_SIZE]; for (i = 0; i < CRT_SIZE; i++) zC[i] = 0; for (i = 1; i < t; i++) { zone(&zC[i]); for (j = 0; j <= i - 1; j++) { zinvmod(zm[j], zm[i], &zu); zmulmod(zu, zC[i], zm[i], &za); zcopy(za, &zC[i]); } } zcopy(zv[0], &zu); zcopy(zu, zx); for (i = 1; i < t; i++) { zsub(zv[i], *zx, &za); zmulmod(za, zC[i], zm[i], &zu); zone(&za); for (j = 0; j <= i - 1; j++) { zmul(za, zm[j], &zb); zcopy(zb, &za); } zmul(za, zu, &zb); zadd(*zx, zb, &za); zcopy(za, zx); } zfree(&za); zfree(&zb); zfree(&zu); for (i = 0; i < CRT_SIZE; i++) zfree(&zC[i]); }
void Montgomery_exponentiation(char *e, long b, long l, long t, verylong zR, verylong zm, verylong zx, verylong *zA) { long i; verylong za = 0, zb = 0, zxp = 0; zmulmod(zR, zR, zm, &zb); Montgomery_multiplication(b, l, zm, zx, zb, &zxp); zmod(zR, zm, zA); for (i = t; i >= 0; i--) { Montgomery_multiplication(b, l, zm, *zA, *zA, &za); zcopy(za, zA); if (e[i] == 1) { Montgomery_multiplication(b, l, zm , *zA, zxp, &za); zcopy(za, zA); } #ifdef DEBUG zwriteln(*zA); #endif } zone(&zxp); Montgomery_multiplication(b, l, zm, *zA, zxp, &za); zcopy(za, zA); zfree(&za); zfree(&zb); zfree(&zxp); }
void RSA_exponentiation(verylong zx, verylong zd, verylong zp, verylong zq, verylong *zM) { verylong zdp = 0, zdq = 0, zp1 = 0, zq1 = 0; verylong zm[2], zv[2]; zsadd(zp, - 1l, &zp1); zsadd(zq, - 1l, &zq1); zmod(zd, zp1, &zdp); zmod(zd, zq1, &zdq); zm[0] = zm[1] = zv[0] = zv[1] = 0; zcopy(zp, &zm[0]); zcopy(zq, &zm[1]); zexpmod(zx, zdp, zp, &zv[0]); zexpmod(zx, zdq, zq, &zv[1]); Garner(2l, zm, zv, zM); zfree(&zdp); zfree(&zdq); zfree(&zp1); zfree(&zq1); zfree(&zm[0]); zfree(&zm[1]); zfree(&zv[0]); zfree(&zv[1]); }
void srk_exp(long exp, long k, verylong zg, verylong *zA) { long f[32], i, j, l, t; verylong za = 0, *zg1; l = pow(2, k); zg1 = calloc(l, sizeof(verylong)); assert(zg1 != 0); k_ary_string_replacement(exp, k, f, &t); zcopy(zg, &zg1[1]); for (i = 2; i <= k; i++) { j = pow(2, i - 1) - 1; l = pow(2, i) - 1; zsq(zg1[j], &za); zmul(za, zg, &zg1[l]); } zone(zA); for (i = t - 1; i >= 0; i--) { zsq(*zA, &za); zcopy(za, zA); j = f[i]; if (j != 0) { zmul(*zA, zg1[j], &za); zcopy(za, zA); } } free(zg1); zfree(&za); }
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; }
void radix_representation(long b, long n, long *a, verylong za) { long i = 0; verylong zb = 0, zq = 0, zr = 0, zx = 0; zintoz(b, &zb); zcopy(za, &zx); do { zdiv(zx, zb, &zq, &zr); a[i++] = ztoint(zr); zcopy(zq, &zx); } while (zscompare(zq, 0l) != 0); while (i < n) a[i++] = 0; zfree(&zb); zfree(&zq); zfree(&zr); zfree(&zx); }
int Miller_Rabin(long t, verylong zn) { int value = 1; long i, j, s = 0; verylong za = 0, zb = 0, zn1 = 0, zr = 0, zy = 0; if (zodd(zn)) { if (zscompare(zn, 3l) > 0) { zsadd(zn, - 1l, &zn1); zcopy(zn1, &zr); while (!zodd(zr)) { s++; zrshift(zr, 1l, &za); zcopy(za, &zr); } for (i = 1; value && i <= t; i++) { do zrandomb(zn1, &za); while (zscompare(za, 2l) < 0); zexpmod(za, zr, zn, &zy); if (zscompare(zy, 1l) != 0 && zcompare(zy, zn1) != 0) { j = 1; while (value && j <= s - 1 && zcompare(zy, zn1) != 0) { zmulmod(zy, zy, zn, &zb); zcopy(zb, &zy); if (zscompare(zy, 1l) == 0) value = 0; j++; } if (value && zcompare(zy, zn1) != 0) value = 0; } } } else value = 1; } else value = zscompare(zn, 2l) == 0; zfree(&za); zfree(&zb); zfree(&zn1); zfree(&zr); zfree(&zy); return value; }
/* t_astruct subtype that implements copy. */ static int z1copy(i_ctx_t *i_ctx_p) { os_ptr op = osp; int code = zcopy(i_ctx_p); if (code >= 0) return code; if (!r_has_type(op, t_astruct)) return code; return zcopy_gstate(i_ctx_p); }
void RED(long k, long l, long n, verylong *zd, verylong **zb, verylong **zh, verylong **zl) { long i; verylong zq = 0, zr = 0, zs = 0, zt = 0; zlshift(zl[k][l], 1l, &zr); zcopy(zr, &zs); zabs(&zs); if (zcompare(zs, zd[l]) > 0) { zadd(zr, zd[l], &zs); zlshift(zd[l], 1l, &zr); zdiv(zs, zr, &zq, &zt); for (i = 1; i <= n; i++) { zmul(zq, zh[i][l], &zr); zsub(zh[i][k], zr, &zs); zcopy(zs, &zh[i][k]); zmul(zq, zb[l][i], &zr); zsub(zb[k][i], zr, &zs); zcopy(zs, &zb[k][i]); } zmul(zq, zd[l], &zr); zsub(zl[k][l], zr, &zs); zcopy(zs, &zl[k][l]); for (i = 1; i <= l - 1; i++) { zmul(zq, zl[l][i], &zr); zsub(zl[k][i], zr, &zs); zcopy(zs, &zl[k][i]); } } zfree(&zq); zfree(&zr); zfree(&zs); zfree(&zt); }
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); }
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); } }
void scalar(long n, verylong *za, verylong *zb, verylong *zs) { /* *s = inner_product(a, b) */ long i; verylong zt = 0, zu = 0; zzero(zs); for (i = 1; i <= n; i++) { zmul(za[i], zb[i], &zt); zadd(zt, *zs, &zu); zcopy(zu, zs); } zfree(&zt); zfree(&zu); }
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); }
void SWAP(long k, long k1, long kmax, long n, verylong *zd, verylong **zb, verylong **zh, verylong **zl) { long i, j; verylong zB = 0, zm = 0, zr = 0, zs = 0, zt = 0; verylong zu = 0; for (i = 1; i <= n; i++) { zcopy(zh[i][k], &zt); zcopy(zh[i][k1], &zh[i][k]); zcopy(zt, &zh[i][k1]); } for (j = 1; j <= n; j++) { zcopy(zb[k][j], &zt); zcopy(zb[k1][j], &zb[k][j]); zcopy(zt, &zb[k1][j]); } if (k > 2) { for (j = 1; j <= k - 2; j++) { zcopy(zl[k][j], &zt); zcopy(zl[k1][j], &zl[k][j]); zcopy(zt, &zl[k1][j]); } } zcopy(zl[k][k1], &zm); zmul(zd[k - 2], zd[k], &zr); zsq(zm, &zs); zadd(zr, zs, &zt); zdiv(zt, zd[k1], &zB, &zr); for (i = k + 1; i <= kmax; i++) { zcopy(zl[i][k], &zt); zmul(zd[k], zl[i][k1], &zr); zmul(zm, zt, &zs); zsub(zr, zs, &zu); zdiv(zu, zd[k1], &zl[i][k], &zr); zmul(zB, zt, &zr); zmul(zm, zl[i][k], &zs); zadd(zr, zs, &zu); zdiv(zu, zd[k], &zl[i][k1], &zr); } zcopy(zB, &zd[k1]); zfree(&zB); zfree(&zm); zfree(&zr); zfree(&zs); zfree(&zt); zfree(&zu); }
int simultaneous_diophantine(double delta, long n, verylong zQ, verylong *zP, verylong *zp, verylong *zq) { double P, Q, l; int equal, found; long i, j, n1 = n + 1; verylong zd = 0, zl = 0, zr = 0, zs = 0, zt = 0; verylong **zA = allocate_very_matrix(1, n1, 1, n1); verylong **zh = allocate_very_matrix(1, n1, 1, n1); Q = zdoub(zQ); zintoz(pow(Q, delta), &zl); l = 1.0 / zdoub(zl); zmul(zl, zQ, &zd); for (i = 1; i <= n; i++) zcopy(zd, &zA[i][i]); znegate(&zl); for (i = 1; i <= n; i++) zmul(zl, zq[i], &zA[n1][i]); zone(&zA[n1][n1]); int_LLL(n1, zA, zh); found = 0; for (j = 1; !found && j <= n1; j++) { zcopy(zA[j][n1], zP); if (zcompare(*zP, zQ) != 0) { for (i = 1; i <= n; i++) { zdiv(zA[j][i], zl, &zr, &zs); zmul(*zP, zq[i], &zt); zadd(zr, zt, &zs); zdiv(zs, zQ, &zp[i], &zr); } P = zdoub(*zP); #ifdef DEBUG if (n <= 16) { printf("p = "); zwrite(*zP); printf(" p[i] "); for (i = 1; i <= n; i++) { zwrite(zp[i]); printf(" "); } printf("\n"); } #endif if (zcompare(*zP, 0) != 0) { equal = 1; for (i = 1; equal && i <= n; i++) equal = fabs(P * zdoub(zq[i]) / Q - zdoub(zp[i])) <= l; } else equal = 0; found = equal; } } free_very_matrix(zA, 1, n1, 1, n1); free_very_matrix(zh, 1, n1, 1, n1); zfree(&zd); zfree(&zl); zfree(&zr); zfree(&zs); zfree(&zt); return found; }
void PROVABLE_PRIME(long k, verylong *zn) { double c, r, s; int success; long B, m, n, p, sqrtn; verylong zI = 0, zR = 0, za = 0, zb = 0, zc = 0; verylong zd = 0, zk = 0, zl = 0, zq = 0, zu = 0; if (k <= 20) { do { n = OddRandom(k); sqrtn = sqrt(n); zpstart2(); do p = zpnext(); while (n % p != 0 && p < sqrtn); } while (p < sqrtn); zintoz(n, zn); } else { c = 0.1; m = 20; B = c * k * k; if (k > 2 * m) do { s = rand() / (double) RAND_MAX; r = pow(2.0, s - 1.0); } while (k - r * k <= m); else r = 0.5; PROVABLE_PRIME(r * k + 1, &zq); zone(&za); zlshift(za, k - 1, &zk); zcopy(zq, &za); zlshift(za, 1l, &zl); zdiv(zk, zl, &zI, &za); zsadd(zI, 1l, &zl); zlshift(zI, 1l, &zu); success = 0; while (!success) { do zrandomb(zu, &zR); while (zcompare(zR, zl) < 0); zmul(zR, zq, &za); zlshift(za, 1l, &zb); zsadd(zb, 1l, zn); zcopy(zR, &za); zlshift(za, 1l, &zR); zpstart2(); p = zpnext(); while (zsmod(*zn, p) != 0 && p < B) p = zpnext(); if (p >= B) { zcopy(*zn, &zc); zsadd(zc, - 2l, &zb); do zrandomb(*zn, &za); while (zscompare(za, 2l) < 0 || zcompare(za, zb) > 0); zsadd(*zn, - 1l, &zc); zexpmod(za, zc, *zn, &zb); if (zscompare(zb, 1l) == 0) { zexpmod(za, zR, *zn, &zb); zcopy(zb, &zd); zsadd(zd, - 1l, &zb); zgcd(zb, *zn, &zd); success = zscompare(zd, 1l) == 0; } } } } zfree(&zI); zfree(&zR); zfree(&za); zfree(&zb); zfree(&zc); zfree(&zd); zfree(&zk); zfree(&zl); zfree(&zq); zfree(&zu); }
void int_LLL(long n, verylong **zb, verylong **zh) { double x, y; long i, j, k = 2, k1, kmax = 1, l; verylong zr = 0, zs = 0, zt = 0, zu = 0; verylong *zB = allocate_very_vector(1, n); verylong *zd = allocate_very_vector(0, n); verylong **zl = allocate_very_matrix(1, n, 1, n); zone(&zd[0]); scalar(n, zb[1], zb[1], &zd[1]); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) zzero(&zh[i][j]); zone(&zh[i][i]); } #ifdef DEBUG if (n <= 17) { printf("the basis to be reduced is:\n"); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { zwrite(zb[i][j]); printf(" "); } printf("\n"); } } #endif L2: if (k <= kmax) goto L3; kmax = k; for (j = 1; j <= k; j++) { scalar(n, zb[k], zb[j], &zu); for (i = 1; i <= j - 1; i++) { zmul(zd[i], zu, &zr); zmul(zl[k][i], zl[j][i], &zs); zsub(zr, zs, &zt); zdiv(zt, zd[i - 1], &zu, &zr); } if (j < k) zcopy(zu, &zl[k][j]); else if (j == k) { zcopy(zu, &zd[k]); if (zscompare(zd[k], 0l) == 0) system_error("Failure in int_LLL."); } } L3: k1 = k - 1; RED(k, k1, n, zd, zb, zh, zl); zmul(zd[k], zd[k - 2], &zr); zsq(zd[k1], &zs); zsq(zl[k][k1], &zt); x = zdoub(zr); y = 3.0 * zdoub(zs) / 4.0 - zdoub(zt); if (x < y) { SWAP(k, k1, kmax, n, zd, zb, zh, zl); k = max(2, k1); goto L3; } for (l = k - 2; l >= 1; l--) RED(k, l, n, zd, zb, zh, zl); if (++k <= n) goto L2; #ifdef DEBUG if (n <= 17) { printf("the LLL-reduced basis is:\n"); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { zwrite(zb[i][j]); printf(" "); } printf("\n"); } } #endif free_very_matrix(zl, 1, n, 1, n); free_very_vector(zB, 1, n); free_very_vector(zd, 0, n); zfree(&zr); zfree(&zs); zfree(&zt); zfree(&zu); }
int PollardRho(verylong zalpha, verylong zbeta, verylong zn, verylong zp, verylong *zx) { long i = 2, j; static verylong za0 = 0, za1 = 0, za2 = 0, za3 = 0; static verylong zb0 = 0, zb1 = 0, zb2 = 0, zb3 = 0; static verylong zx0 = 0, zx1 = 0, zx2 = 0, zx3 = 0; static verylong zr = 0, zri = 0; zone(&zx0); zzero(&za0); zzero(&zb0); zfi(zalpha, zbeta, zp, zx0, &zx1); zai(za0, zn, zx0, &za1); zbi(zb0, zn, zx0, &zb1); zfi(zalpha, zbeta, zp, zx1, &zx2); zai(za1, zn, zx1, &za2); zbi(zb1, zn, zx1, &zb2); zcopy(za1, &za0); zcopy(zb1, &zb0); zcopy(zx1, &zx0); for (;;) { zfi(zalpha, zbeta, zp, zx0, &zx1); zai(za0, zn, zx0, &za1); zbi(zb0, zn, zx0, &zb1); zcopy(za1, &za2); zcopy(zb1, &zb2); zcopy(zx1, &zx2); i++; for (j = 0; j < i; j++) { zfi(zalpha, zbeta, zp, zx2, &zx3); zai(za2, zn, zx2, &za3); zbi(zb2, zn, zx2, &zb3); zcopy(za3, &za2); zcopy(zb3, &zb2); zcopy(zx3, &zx2); } if (zcompare(zx1, zx3) == 0) { zsubmod(zb1, zb3, zn, &zr); if (zscompare(zr, 0) == 0) return 0; zinvmod(zr, zn, &zri); zsub(za3, za1, &za0); zmulmod(za0, zri, zn, zx); return 1; } zcopy(za1, &za0); zcopy(zb1, &zb0); zcopy(zx1, &zx0); } }
void zbinary_ext_gcd(verylong zx, verylong zy, verylong *za, verylong *zb, verylong *zv) /* returns a * x + b * y = v, v = gcd(x, y) */ { verylong zA = 0, zB = 0, zC = 0, zD = 0; verylong zX = 0, zY = 0, zc = 0, zg = 0; verylong zu = 0; zone(&zg); zcopy(zx, &zX); zcopy(zy, &zY); while (!zodd(zX) && !zodd(zY)) { zrshift(zX, 1l, &zc); zcopy(zc, &zX); zrshift(zY, 1l, &zc); zcopy(zc, &zY); zlshift(zg, 1l, &zc); zcopy(zc, &zg); } zcopy(zX, &zu); zcopy(zY, zv); zone(&zA); zzero(&zB); zzero(&zC); zone(&zD); do { while (!zodd(zu)) { zrshift(zu, 1l, &zc); zcopy(zc, &zu); if (!zodd(zA) && !zodd(zB)) { zrshift(zA, 1l, &zc); zcopy(zc, &zA); zrshift(zB, 1l, &zc); zcopy(zc, &zB); } else { zadd(zA, zY, &zc); zrshift(zc, 1l, &zA); zsub(zB, zX, &zc); zrshift(zc, 1l, &zB); } } while (!zodd(*zv)) { zrshift(*zv, 1l, &zc); zcopy(zc, zv); if (!zodd(zC) && !zodd(zD)) { zrshift(zC, 1l, &zc); zcopy(zc, &zC); zrshift(zD, 1l, &zc); zcopy(zc, &zD); } else { zadd(zC, zY, &zc); zrshift(zc, 1l, &zC); zsub(zD, zX, &zc); zrshift(zc, 1l, &zD); } } if (zcompare(zu, *zv) >= 0) { zsub(zu, *zv, &zc); zcopy(zc, &zu); zsub(zA, zC, &zc); zcopy(zc, &zA); zsub(zB, zD, &zc); zcopy(zc, &zB); } else { zsub(*zv, zu, &zc); zcopy(zc, zv); zsub(zC, zA, &zc); zcopy(zc, &zC); zsub(zD, zB, &zc); zcopy(zc, &zD); } #ifdef DEBUG zwrite(zu); printf(" "); zwrite(*zv); printf(" "); zwrite(zA); printf(" "); zwrite(zB); printf(" "); zwrite(zC); printf(" "); zwriteln(zD); #endif } while (zscompare(zu, 0l) != 0); zcopy(zC, za); zcopy(zD, zb); zmul(zg, *zv, &zc); zcopy(zc, zv); zfree(&zA); zfree(&zB); zfree(&zC); zfree(&zD); zfree(&zX); zfree(&zY); zfree(&zc); zfree(&zg); zfree(&zu); }