Beispiel #1
0
static F2(jtcfrz){A z;B b=0,p;I j,n;Z c,d,*t,*u,*v;
 RZ(w=rsort(w)); 
 n=AN(w); u=ZAV(w); 
 GATV(z,CMPX,1+n,1,0); v=ZAV(z); *v=c=*ZAV(a); p=!c.im;
 for(j=0;j<n;++j){
  d=znegate(u[j]); t=j+v; *(1+t)=*t; 
  DO(j, *t=zplus(*(t-1),ztymes(d,*t)); --t;); 
  *v=ztymes(d,*v);
  if(p&&d.im)if(b=!b)c=u[j]; else if(p=ZCJ(c,u[j])){t=v; DO(2+j, t++->im=0.0;);}
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 #3
0
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;
}