Example #1
0
static long ZZ_remove(struct ZZ &dest, const struct ZZ &src, const struct ZZ &f)
{
    // Based on the code for mpz_remove
    ZZ fpow[40];            // inexaustible...until year 2020 or so
    ZZ x, rem;
    long pwr;
    int p;

    if (compare(f, 1) <= 0 && compare(f, -1) >= 0)
        Error("Division by zero");

    if (compare(src, 0) == 0)
    {
        if (src != dest)
           dest = src;
        return 0;
    }

    if (compare(f, 2) == 0)
    {
        dest = src;
        return MakeOdd(dest);
    }

    /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0).  It is an
     upper bound of the result we're seeking.  We could also shift down the
     operands so that they become odd, to make intermediate values smaller.  */

    pwr = 0;
    fpow[0] = ZZ(f);
    dest = src;
    rem = ZZ();
    x = ZZ();

    /* Divide by f, f^2, ..., f^(2^k) until we get a remainder for f^(2^k).  */
    for (p = 0;;p++)
    {
        DivRem(x, rem, dest, fpow[p]);
        if (compare(rem, 0) != 0)
            break;
        fpow[p+1] = ZZ();
        NTL::mul(fpow[p+1], fpow[p], fpow[p]);
        dest = x;
    }

    pwr = (1 << p) - 1;

    /* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give a
       zero remainder.  */
    while (--p >= 0)
    {
        DivRem(x, rem, dest, fpow[p]);
        if (compare(rem, 0) == 0)
        {
            pwr += 1 << p;
            dest = x;
        }
    }
    return pwr;
}
Example #2
0
// trial division primitive
void TrialDivision(vec_pair_ZZ_long& factors, ZZ& q, const ZZ& n, long bnd) {
  factors.SetLength(0);

  if (&q!=&n) q=n;
  if (bnd==0) {
    bnd=10000;  // should probably be higher
  }

  PrimeSeq s;
  ZZ d;
  for (long p=s.next(); (p>0 && p<=bnd); p=s.next()) {
    if (DivRem(d,q,p)==0) {
      long e=1;
      q=d;
      while (DivRem(d,q,p)==0) {
	++e;
	q=d;
      }
      addFactor(factors,to_ZZ(p),e);
      if (IsOne(q))
	return;
    }
    if (d<=p) {
      // q must be prime
      addFactor(factors,q);
      set(q);
      return;
    }
  }
}
Example #3
0
bool BPMiniGame_JewelFlip::GemMatches(BPMiniGame_JewelFlip_Jewel* gem1, BPMiniGame_JewelFlip_Jewel* gem2) {
	int type = gem1->GemType;
	int position = Gems.IndexOf(gem2);
	
	int Row;
	int Col = DivRem(position, 7, Row);
	
	// try searching horizontally
	if (Col > 0) {
		// gem to the left
		if (AutoSubstituteGem(position - 7, gem1, gem2)->GemType == type) return true;
	}
	
	if (Col < 5) {
		// one to the right
		if (AutoSubstituteGem(position + 7, gem1, gem2)->GemType == type) return true;
	}
	
	// try searching vertically
	if (Row > 0) {
		// gem above
		if (AutoSubstituteGem(position - 1, gem1, gem2)->GemType == type) return true;
	}
	
	if (Row < 6) {
		// gem below
		if (AutoSubstituteGem(position + 1, gem1, gem2)->GemType == type) return true;
	}
	
	return false;
}
Example #4
0
void YASHE::roundMultiply(NTL::ZZ_pX& output,
                          const NTL::ZZ_pX& a,
                          const NTL::ZZ_pX& b) {

  // maximum is q^2 * (maxDegree + 1)
  NTL::ZZ_pPush push((cModulus * cModulus)/pModulus);


  NTL::ZZ_pX product;
  NTL::MulMod(product, a, b, bigCycloMod);

  output.SetLength(maxDegree + 1);
  NTL::ZZ quotient, remainder;

  for (long i = 0; i <= maxDegree; i++) {
    DivRem(quotient, remainder, pModulus * rep(product[i]), cModulus);

    // Rounding using remainder
    if (remainder * 2 > cModulus) {
      quotient += 1;
    }

    output[i] = NTL::conv<NTL::ZZ_p>(quotient);
  }
}
Example #5
0
void YASHE::roundMultiply(NTL::ZZ_pX& output,
                          const NTL::ZZ_pXMultiplier& a,
                          const NTL::ZZ_pXMultiplier& b) {
  // maximum is q^2 * (maxDegree + 1)
  NTL::ZZ_pPush push((cModulus * cModulus)/pModulus);

  long n = bigCycloMod.n;
  NTL::ZZ_pX product, P1(NTL::INIT_SIZE, n), P2(NTL::INIT_SIZE, n);
  NTL::FFTRep R1(NTL::INIT_SIZE, bigCycloMod.l), R2(NTL::INIT_SIZE, bigCycloMod.l);

  ToFFTRep(R1, a.val(), bigCycloMod.l);
  mul(R2, R1, b.B1);
  FromFFTRep(P1, R2, n-1, 2*n-3);

  mul(R1, a.B2, b.B2);
  ToFFTRep(R2, P1, bigCycloMod.k);
  mul(R2, R2, bigCycloMod.FRep);
  sub(R1, R1, R2);

  FromFFTRep(product, R1, 0, n-1);

  output.SetLength(maxDegree + 1);
  NTL::ZZ quotient, remainder;

  for (long i = 0; i <= maxDegree; i++) {
    DivRem(quotient, remainder, pModulus * rep(product[i]), cModulus);

    // Rounding using remainder
    if (remainder * 2 > cModulus) {
      quotient += 1;
    }

    output[i] = NTL::conv<NTL::ZZ_p>(quotient);
  }
}
Example #6
0
void div(RR& z, const RR& a, const RR& b)
{
   if (IsZero(b))
      Error("RR: division by zero");

   if (IsZero(a)) {
      clear(z);
      return;
   }

   long la = NumBits(a.x);
   long lb = NumBits(b.x);

   long neg = (sign(a) != sign(b));

   long k = RR::prec - la + lb + 1;
   if (k < 0) k = 0;

   static RR t;
   static ZZ A, B, R;

   abs(A, a.x);
   LeftShift(A, A, k);

   abs(B, b.x);
   DivRem(t.x, R, A, B);

   t.e = a.e - b.e - k;

   normalize(z, t, !IsZero(R));

   if (neg)
      negate(z.x, z.x);
}
long divide(const zz_pX& a, const zz_pX& b)
{
   if (IsZero(b)) return IsZero(a);
   zz_pX lq, r;
   DivRem(lq, r, a, b);
   if (!IsZero(r)) return 0;
   return 1;
}
void XGCD(zz_pX& d, zz_pX& s, zz_pX& t, const zz_pX& a, const zz_pX& b)
{
   zz_p w;

   if (IsZero(a) && IsZero(b)) {
      clear(d);
      set(s);
      clear(t);
      return;
   }

   zz_pX U, V, Q;

   U = a;
   V = b;

   long flag = 0;

   if (deg(U) == deg(V)) {
      DivRem(Q, U, U, V);
      swap(U, V);
      flag = 1;
   }
   else if (deg(U) < deg(V)) {
      swap(U, V);
      flag = 2;
   }

   zz_pXMatrix M;

   XHalfGCD(M, U, V, deg(U)+1);

   d = U;

   if (flag == 0) {
      s = M(0,0); 
      t = M(0,1);
   }
   else if (flag == 1) {
      s = M(0,1);
      mul(t, Q, M(0,1));
      sub(t, M(0,0), t);
   }
   else {  /* flag == 2 */
      s = M(0,1);
      t = M(0,0);
   }

   // normalize

   inv(w, LeadCoeff(d));
   mul(d, d, w);
   mul(s, s, w);
   mul(t, t, w);
}
Example #9
0
NTL_START_IMPL


static void ExactDiv(ZZ& qq, const ZZ& a, const ZZ& b)
{
   static ZZ q, r;

   DivRem(q, r, a, b);
   if (!IsZero(r)) {
      Error("ExactDiv: nonzero remainder");
   }
   qq = q;
}
Example #10
0
void YASHE::roundDecrypt(NTL::ZZ& output,
                         const NTL::ZZ_pX& a,
                         const NTL::ZZ_pX& b) {
  NTL::ZZ_pX product = MulMod(a, b, cycloMod);

  NTL::ZZ quotient, remainder;

  DivRem(output, remainder, pModulus * rep(product[0]), cModulus);

    // Rounding using remainder
  if (remainder * 2 > cModulus) {
    output += 1;
  }
}
Example #11
0
void YASHE::radixDecomp(std::vector<NTL::ZZ> & output,
                        const NTL::ZZ & input) {

  output.resize(decompSize);
  NTL::ZZ remainder;
  NTL::ZZ quotient, numerator;
  numerator = input;

  for (long i = 0; i < decompSize; i++) {
    DivRem(quotient, remainder, numerator, radix);
    output[i] = remainder;
    numerator = quotient;
  }
}
Example #12
0
static void BalDiv(ZZ& q, const ZZ& a, const ZZ& d)

//  rounds a/d to nearest integer, breaking ties
//    by rounding towards zero.  Assumes d > 0.

{
   static ZZ r;
   DivRem(q, r, a, d);


   add(r, r, r);

   long cmp = compare(r, d);
   if (cmp > 0 || (cmp == 0 && q < 0))
      add(q, q, 1);
}
void ResHalfGCD(zz_pX& U, zz_pX& V, vec_zz_p& cvec, vec_long& dvec)
{
   long d_red = (deg(U)+1)/2;

   if (IsZero(V) || deg(V) <= deg(U) - d_red) {
      return;
   }

   long du = deg(U);


   long d1 = (d_red + 1)/2;
   if (d1 < 1) d1 = 1;
   if (d1 >= d_red) d1 = d_red - 1;

   zz_pXMatrix M1;

   ResHalfGCD(M1, U, V, d1, cvec, dvec);
   mul(U, V, M1);

   long d2 = deg(V) - du + d_red;

   if (IsZero(V) || d2 <= 0) {
      return;
   }

   M1(0,0).kill();
   M1(0,1).kill();
   M1(1,0).kill();
   M1(1,1).kill();


   zz_pX Q;

   append(cvec, LeadCoeff(V));
   append(dvec, dvec[dvec.length()-1]-deg(U)+deg(V));
   DivRem(Q, U, U, V);
   swap(U, V);

   ResHalfGCD(M1, U, V, d2, cvec, dvec);

   mul(U, V, M1); 
}
Example #14
0
xdouble PowerOf10(const ZZ& e)
{
   static NTL_CHEAP_THREAD_LOCAL long init = 0;
   static NTL_CHEAP_THREAD_LOCAL long k = 0;

   NTL_TLS_LOCAL(xdouble, v10k);

   if (!init) {
      k = ComputeMax10Power();
      RRPush push;
      RR::SetPrecision(NTL_DOUBLE_PRECISION);
      v10k = to_xdouble(power(to_RR(10), k)); 
      init = 1;
   }

   ZZ e1;
   long neg;

   if (e < 0) {
      e1 = -e;
      neg = 1;
   }
   else {
      e1 = e;
      neg = 0;
   }

   long r;
   ZZ q;

   r = DivRem(q, e1, k);

   RRPush push;
   RR::SetPrecision(NTL_DOUBLE_PRECISION);
   xdouble x1 = to_xdouble(power(to_RR(10), r));

   xdouble x2 = power(v10k, q);
   xdouble x3 = x1*x2;

   if (neg) x3 = 1/x3;

   return x3;
}
Example #15
0
void YASHE::roundDecryptVec(NTL::ZZ_pX& output,
                            const NTL::ZZ_pX& a,
                            const NTL::ZZ_pX& b) {
  NTL::ZZ_pX product = MulMod(a, b, cycloMod);

  output.SetLength(maxDegree + 1);
  NTL::ZZ quotient, remainder;

  for (long i = 0; i <= maxDegree; i++) {

    DivRem(quotient, remainder, pModulus * rep(product[i]), cModulus);

    // Rounding using remainder
    if (remainder * 2 > cModulus) {
      quotient += 1;
    }

    output[i] = NTL::conv<NTL::ZZ_p>(quotient);
  }
}
void HalfGCD(zz_pX& U, zz_pX& V)
{
   long d_red = (deg(U)+1)/2;

   if (IsZero(V) || deg(V) <= deg(U) - d_red) {
      return;
   }

   long du = deg(U);


   long d1 = (d_red + 1)/2;
   if (d1 < 1) d1 = 1;
   if (d1 >= d_red) d1 = d_red - 1;

   zz_pXMatrix M1;

   HalfGCD(M1, U, V, d1);
   mul(U, V, M1);

   long d2 = deg(V) - du + d_red;

   if (IsZero(V) || d2 <= 0) {
      return;
   }

   M1(0,0).kill();
   M1(0,1).kill();
   M1(1,0).kill();
   M1(1,1).kill();


   zz_pX Q;

   DivRem(Q, U, U, V);
   swap(U, V);

   HalfGCD(M1, U, V, d2);

   mul(U, V, M1); 
}
NTL_START_IMPL



long divide(zz_pX& q, const zz_pX& a, const zz_pX& b)
{
   if (IsZero(b)) {
      if (IsZero(a)) {
         clear(q);
         return 1;
      }
      else
         return 0;
   }

   zz_pX lq, r;
   DivRem(lq, r, a, b);
   if (!IsZero(r)) return 0;
   q = lq;
   return 1;
}
Example #18
0
void myCRT::ComputeFactors(int f_degree, int f_size){
	factors.SetLength(f_size);
	int s = 1<<f_degree;
	ZZ_pX list[s];
	for(int i=0; i<s; i++)
		list[i] = to_ZZ_pX(num2ZZX(i+s));

	int j=0;
	ZZ_pX t1 = modulus;
	ZZ_pX comp, remin, quo;
	SetCoeff(comp, 0, 0);
	for(int i=0; i<s; i++){
		DivRem(quo, remin, t1, list[i]);
		if(remin == comp){
			t1 = quo;
			factors[j] = list[i];
			j++;
		}
	}
	size = factors.length();
}
Example #19
0
// The recursive procedure in the Paterson-Stockmeyer
// polynomial-evaluation algorithm from SIAM J. on Computing, 1973.
// This procedure assumes that poly is monic, deg(poly)=k*(2t-1)+delta
// with t=2^e, and that babyStep contains >= k+delta powers
static void
PatersonStockmeyer(Ctxt& ret, const ZZX& poly, long k, long t, long delta,
		   DynamicCtxtPowers& babyStep, DynamicCtxtPowers& giantStep)
{
  if (deg(poly)<=babyStep.size()) { // Edge condition, use simple eval
    simplePolyEval(ret, poly, babyStep);
    return;
  }
  ZZX r = trunc(poly, k*t);      // degree <= k*2^e-1
  ZZX q = RightShift(poly, k*t); // degree == k(2^e-1) +delta

  const ZZ p = to_ZZ(babyStep[0].getPtxtSpace());
  const ZZ& coef = coeff(r,deg(q));
  SetCoeff(r, deg(q), coef-1);  // r' = r - X^{deg(q)}

  ZZX c,s;
  DivRem(c,s,r,q); // r' = c*q + s
  // deg(s)<deg(q), and if c!= 0 then deg(c)<k-delta

  assert(deg(s)<deg(q));
  assert(IsZero(c) || deg(c)<k-delta);
  SetCoeff(s,deg(q)); // s' = s + X^{deg(q)}, deg(s)==deg(q)

  // reduce the coefficients modulo p
  for (long i=0; i<=deg(c); i++) rem(c[i],c[i], p);
  c.normalize();
  for (long i=0; i<=deg(s); i++) rem(s[i],s[i], p);
  s.normalize();

  // Evaluate recursively poly = (c+X^{kt})*q + s'
  PatersonStockmeyer(ret, q, k, t/2, delta, babyStep, giantStep);

  Ctxt tmp(ret.getPubKey(), ret.getPtxtSpace());
  simplePolyEval(tmp, c, babyStep);
  tmp += giantStep.getPower(t);
  ret.multiplyBy(tmp);

  PatersonStockmeyer(tmp, s, k, t/2, delta, babyStep, giantStep);
  ret += tmp;
}
Example #20
0
void div(RR& z, const RR& a, const RR& b)
{
   if (IsZero(b))
      ArithmeticError("RR: division by zero");

   if (IsZero(a)) {
      clear(z);
      return;
   }

   long la = NumBits(a.x);
   long lb = NumBits(b.x);

   long neg = (sign(a) != sign(b));

   long k = RR::prec - la + lb + 1;
   if (k < 0) k = 0;

   NTL_TLS_LOCAL(RR, t);
   NTL_ZZRegister(A);
   NTL_ZZRegister(B);
   NTL_ZZRegister(R);

   abs(A, a.x);
   LeftShift(A, A, k);

   abs(B, b.x);
   DivRem(t.x, R, A, B);

   t.e = a.e - b.e - k;

   normalize(z, t, !IsZero(R));

   if (neg)
      negate(z.x, z.x);
}
Example #21
0
int BPMiniGame_JewelFlip::RemoveGem(BPMiniGame_JewelFlip_Jewel* gem) {
	// remove this gem, then remove any others that touch it
	if (gem->Removed) return 0; // this has been removed already!
	
	gem->Removed = true;
	if (SelectedGem == gem) SelectedGem = NULL;
	
	int position = Gems.IndexOf(gem);
	
	int Row;
	int Col = DivRem(position, 7, Row);
	
	int num_removed = 1; // we've removed ourselves
	
	// remove the one above
	if (Row > 0) {
		if (Gems[position - 1]->GemType == gem->GemType) num_removed += RemoveGem(Gems[position - 1]);
	}
	
	// remove the one below
	if (Row < 6) {
		if (Gems[position + 1]->GemType == gem->GemType) num_removed += RemoveGem(Gems[position + 1]);
	}
	
	// remove the one to the left
	if (Col > 0) {
		if (Gems[position - 7]->GemType == gem->GemType) num_removed += RemoveGem(Gems[position - 7]);
	}
	
	// remove the one to the right
	if (Col < 5) {
		if (Gems[position + 7]->GemType == gem->GemType) num_removed += RemoveGem(Gems[position + 7]);
	}
	
	return num_removed;
}
Example #22
0
void ZZ_p::DoInstall()
{
   SmartPtr<ZZ_pTmpSpaceT> tmps = 0;

   do { // NOTE: thread safe lazy init 
      Lazy<ZZ_pFFTInfoT>::Builder builder(ZZ_pInfo->FFTInfo);
      if (!builder()) break;

      UniquePtr<ZZ_pFFTInfoT> FFTInfo;
      FFTInfo.make();

      ZZ B, M, M1, M2, M3;
      long n, i;
      long q, t;
      mulmod_t qinv;

      sqr(B, ZZ_pInfo->p);

      LeftShift(B, B, NTL_FFTMaxRoot+NTL_FFTFudge);

      // FIXME: the following is quadratic time...would
      // be nice to get a faster solution...
      // One could estimate the # of primes by summing logs,
      // then multiply using a tree-based multiply, then 
      // adjust up or down...

      // Assuming IEEE floating point, the worst case estimate
      // for error guarantees a correct answer +/- 1 for
      // numprimes up to 2^25...for sure we won't be
      // using that many primes...we can certainly put in 
      // a sanity check, though. 

      // If I want a more accuaruate summation (with using Kahan,
      // which has some portability issues), I could represent 
      // numbers as x = a + f, where a is integer and f is the fractional
      // part.  Summing in this representation introduces an *absolute*
      // error of 2 epsilon n, which is just as good as Kahan 
      // for this application.

      // same strategy could also be used in the ZZX HomMul routine,
      // if we ever want to make that subquadratic

      set(M);
      n = 0;
      while (M <= B) {
         UseFFTPrime(n);
         q = GetFFTPrime(n);
         n++;
         mul(M, M, q);
      }

      FFTInfo->NumPrimes = n;
      FFTInfo->MaxRoot = CalcMaxRoot(q);


      double fn = double(n);

      if (8.0*fn*(fn+48) > NTL_FDOUBLE_PRECISION)
         ResourceError("modulus too big");


      if (8.0*fn*(fn+48) <= NTL_FDOUBLE_PRECISION/double(NTL_SP_BOUND))
         FFTInfo->QuickCRT = true;
      else
         FFTInfo->QuickCRT = false;
      
      // FIXME: some of this stuff does not need to be initialized
      // at all if FFTInfo->crt_struct.special()

      FFTInfo->x.SetLength(n);
      FFTInfo->u.SetLength(n);
      FFTInfo->uqinv.SetLength(n);

      FFTInfo->rem_struct.init(n, ZZ_pInfo->p, GetFFTPrime);

      FFTInfo->crt_struct.init(n, ZZ_pInfo->p, GetFFTPrime);

      if (!FFTInfo->crt_struct.special()) {
         ZZ qq, rr;

         DivRem(qq, rr, M, ZZ_pInfo->p);

         NegateMod(FFTInfo->MinusMModP, rr, ZZ_pInfo->p);

         for (i = 0; i < n; i++) {
            q = GetFFTPrime(i);
            qinv = GetFFTPrimeInv(i);

            long tt = rem(qq, q);

            mul(M2, ZZ_pInfo->p, tt);
            add(M2, M2, rr); 
            div(M2, M2, q);  // = (M/q) rem p
            

            div(M1, M, q);
            t = rem(M1, q);
            t = InvMod(t, q);

            mul(M3, M2, t);
            rem(M3, M3, ZZ_pInfo->p);

            FFTInfo->crt_struct.insert(i, M3);


            FFTInfo->x[i] = ((double) t)/((double) q);
            FFTInfo->u[i] = t;
            FFTInfo->uqinv[i] = PrepMulModPrecon(FFTInfo->u[i], q, qinv);
         }
      }

      tmps = MakeSmart<ZZ_pTmpSpaceT>();
      tmps->crt_tmp_vec.fetch(FFTInfo->crt_struct);
      tmps->rem_tmp_vec.fetch(FFTInfo->rem_struct);

      builder.move(FFTInfo);
   } while (0);

   if (!tmps) {
      const ZZ_pFFTInfoT *FFTInfo = ZZ_pInfo->FFTInfo.get();
      tmps = MakeSmart<ZZ_pTmpSpaceT>();
      tmps->crt_tmp_vec.fetch(FFTInfo->crt_struct);
      tmps->rem_tmp_vec.fetch(FFTInfo->rem_struct);
   }

   ZZ_pTmpSpace = tmps;
}
Example #23
0
// This procedure assumes that poly is monic, deg(poly)=k*(2t-1)+delta
// with t=2^e, and that babyStep contains k+delta powers
static long 
PatersonStockmeyer(const ZZX& poly, long k, long t, long delta,
		   DynamicPtxtPowers& babyStep, DynamicPtxtPowers& giantStep,
		   long mod, long& recursiveDepth)
{
  if (verbose) cerr << "PatersonStockmeyer("<<poly<<"), k="<<k<<", t="<<t<<endl;

  if (deg(poly)<=babyStep.size()) { // Edge condition, use simple eval
    long ret = simplePolyEval(poly, babyStep, mod);
    recursiveDepth = babyStep.getDepth(deg(poly));
    return ret;
  }
  long subDepth1=0, subDepth2=0;
  long ret, tmp;

  ZZX r = trunc(poly, k*t);      // degree <= k*2^e-1
  ZZX q = RightShift(poly, k*t); // degree == k(2^e-1) +delta

  if (verbose) cerr << "  r ="<<r<< ", q="<<q;

  const ZZ& coef = coeff(r,deg(q));
  SetCoeff(r, deg(q), coef-1);  // r' = r - X^{deg(q)}

  if (verbose) cerr << ", r'="<<r;

  ZZX c,s;
  DivRem(c,s,r,q); // r' = c*q + s
  // deg(s)<deg(q), and if c!= 0 then deg(c)<k-delta

  if (verbose) cerr << ", c="<<c<< ", s ="<<s<<endl;

  assert(deg(s)<deg(q));
  assert(IsZero(c) || deg(c)<k-delta);
  SetCoeff(s,deg(q)); // s' = s + X^{deg(q)}, deg(s)==deg(q)

  // reduce the coefficients modulo mod
  for (long i=0; i<=deg(c); i++) rem(c[i],c[i], to_ZZ(mod));
  c.normalize();
  for (long i=0; i<=deg(s); i++) rem(s[i],s[i], to_ZZ(mod));
  s.normalize();

  if (verbose) cerr << " {t==n+1} recursing on "<<s<<" + (X^"<<t*k<<"+"<<c<<")*"<<q<<endl;

  // Evaluate recursively poly = (c+X^{kt})*q + s'
  tmp = simplePolyEval(c, babyStep, mod);
  tmp = AddMod(tmp, giantStep.getPower(t), mod);
  subDepth1 = max(babyStep.getDepth(deg(c)), giantStep.getDepth(t));

  ret = PatersonStockmeyer(q, k, t/2, delta,
			   babyStep, giantStep, mod, subDepth2);

  if (verbose) {
    cerr << "  PatersonStockmeyer("<<q<<") returns "<<ret
	 << ", depth="<<subDepth2<<endl;
    if (ret != polyEvalMod(q,babyStep[0], mod)) {
      cerr << "  **1st recursive call failed, q="<<q<<endl;
      exit(0);
    }
  }
  ret = MulMod(ret, tmp, mod);
  nMults++;
  subDepth1 = max(subDepth1, subDepth2)+1;

  tmp = PatersonStockmeyer(s, k, t/2, delta,
			   babyStep, giantStep, mod, subDepth2);
  if (verbose) {
    cerr << "  PatersonStockmeyer("<<s<<") returns "<<tmp
	 << ", depth="<<subDepth2<<endl;
    if (tmp != polyEvalMod(s,babyStep[0], mod)) {
      cerr << "  **2nd recursive call failed, s="<<s<<endl;
      exit(0);
    }
  }
  ret = AddMod(ret,tmp,mod);
  recursiveDepth = max(subDepth1, subDepth2);
  return ret;
}
Example #24
0
void ZZ_pInfoT::init()
{
   ZZ B, M, M1, M2, M3;
   long n, i;
   long q, t;

   initialized = 1;

   sqr(B, p);

   LeftShift(B, B, NTL_FFTMaxRoot+NTL_FFTFudge);

   set(M);
   n = 0;
   while (M <= B) {
      UseFFTPrime(n);
      q = FFTPrime[n];
      n++;
      mul(M, M, q);
   }

   NumPrimes = n;
   MaxRoot = CalcMaxRoot(q);


   double fn = double(n);

   if (8.0*fn*(fn+32) > NTL_FDOUBLE_PRECISION)
      Error("modulus too big");


   if (8.0*fn*(fn+32) > NTL_FDOUBLE_PRECISION/double(NTL_SP_BOUND))
      QuickCRT = 0;
   else
      QuickCRT = 1;


   if (!(x = (double *) NTL_MALLOC(n, sizeof(double), 0)))
      Error("out of space");

   if (!(u = (long *) NTL_MALLOC(n,  sizeof(long), 0)))
      Error("out of space");

   ZZ_p_rem_struct_init(&rem_struct, n, p, FFTPrime);

   ZZ_p_crt_struct_init(&crt_struct, n, p, FFTPrime);

   if (ZZ_p_crt_struct_special(crt_struct)) return;

   ZZ qq, rr;

   DivRem(qq, rr, M, p);

   NegateMod(MinusMModP, rr, p);

   for (i = 0; i < n; i++) {
      q = FFTPrime[i];

      long tt = rem(qq, q);

      mul(M2, p, tt);
      add(M2, M2, rr); 
      div(M2, M2, q);  // = (M/q) rem p
      

      div(M1, M, q);
      t = rem(M1, q);
      t = InvMod(t, q);

      mul(M3, M2, t);
      rem(M3, M3, p);

      ZZ_p_crt_struct_insert(crt_struct, i, M3);


      x[i] = ((double) t)/((double) q);
      u[i] = t;
   }
}
Example #25
0
ostream& operator<<(ostream& s, const xdouble& a)
{
   if (a == 0) {
      s << "0";
      return s;
   }

   RRPush push;
   long temp_p = long(log(fabs(log(fabs(a))) + 1.0)/log(2.0)) + 10; 
   RR::SetPrecision(temp_p);

   RR ln2, ln10, log_2_10;
   ComputeLn2(ln2);
   ComputeLn10(ln10);
   log_2_10 = ln10/ln2;
   ZZ log_10_a = to_ZZ(
  (to_RR(a.e)*to_RR(2*NTL_XD_HBOUND_LOG) + log(fabs(a.x))/log(2.0))/log_2_10);


   xdouble b;
   long neg;

   if (a < 0) {
      b = -a;
      neg = 1;
   }
   else {
      b = a;
      neg = 0;
   }

   ZZ k = xdouble::OutputPrecision() - log_10_a;

   xdouble c, d;

   c = PowerOf10(to_ZZ(xdouble::OutputPrecision()));
   d = PowerOf10(log_10_a);

   b = b / d;
   b = b * c;

   while (b < c) {
      b = b * 10.0;
      k++;
   }

   while (b >= c) {
      b = b / 10.0;
      k--;
   }

   b = b + 0.5;
   k = -k;

   ZZ B;
   conv(B, b);

   long bp_len = xdouble::OutputPrecision()+10;

   UniqueArray<char> bp_store;
   bp_store.SetLength(bp_len);
   char *bp = bp_store.get();

   long len, i;

   len = 0;
   do {
      if (len >= bp_len) LogicError("xdouble output: buffer overflow");
      bp[len] = IntValToChar(DivRem(B, B, 10));
      len++;
   } while (B > 0);

   for (i = 0; i < len/2; i++) {
      char tmp;
      tmp = bp[i];
      bp[i] = bp[len-1-i];
      bp[len-1-i] = tmp;
   }

   i = len-1;
   while (bp[i] == '0') i--;

   k += (len-1-i);
   len = i+1;

   bp[len] = '\0';

   if (k > 3 || k < -len - 3) {
      // use scientific notation

      if (neg) s << "-";
      s << "0." << bp << "e" << (k + len);
   }
   else {
      long kk = to_long(k);

      if (kk >= 0) {
         if (neg) s << "-";
         s << bp;
         for (i = 0; i < kk; i++) 
            s << "0";
      }
      else if (kk <= -len) {
         if (neg) s << "-";
         s << "0.";
         for (i = 0; i < -len-kk; i++)
            s << "0";
         s << bp;
      }
      else {
         if (neg) s << "-";
         for (i = 0; i < len+kk; i++)
            s << bp[i];
   
         s << ".";
   
         for (i = len+kk; i < len; i++)
            s << bp[i];
      }
   }

   return s;
}
Example #26
0
bitstring Extractor::extract(bitstring w, bitstring x) {
//	cout <<"Extractor :: w.size = "<< w.size() <<" n size"<< n<<endl;
//	cout <<"Extractor :: x.size = "<< x.size() <<" d size"<< d<<endl;
    /*if (w.size() < (size_t)n) {
    	throw invalid_argument("W has wrong size");
    }*/
    /*if (x.size() != (size_t)d) {
    	//cout << "(extractor.cpp:215) TO_REMOVE:X has wrong size (Extractor) x="<< x.size() << "d="<< (size_t)d <<"\n" ;
    	throw invalid_argument("X has wrong size (Extractor) ");
    }*/


    // X to poly

    ZZ_pE xpoly;

    PolyFromBstr(xpoly,x,0);



    // W
    ZZ_pEX wpoly;
    ZZ_pE wpp[32];

    for(int i=0; i<32; i++) {
        PolyFromBstr(wpp[i],w,32*i);
        ZZ_pEX temp(i,wpp[i]);
        wpoly += temp;
    }

    // geracao dos 4 f

    ZZ_pEX lixo;
    ZZ_pEX f1, f2, f4, f8;

    f1 = wpoly;
    DivRem(lixo, f1, f1, mod3232);
    f2 = f1 * f1;
    DivRem(lixo, f2, f2, mod3232);
    f4 = f2 * f2;
    DivRem(lixo, f4, f4, mod3232);
    f8 = f4 * f4;
    DivRem(lixo, f8, f8, mod3232);


    // f(y)

    ZZ_pE res0,res1,res2,res3;

    res0 = coeff(f1,0);
    res1 = coeff(f2,0);
    res2 = coeff(f4,0);
    res3 = coeff(f8,0);

    ZZ_pE aux = xpoly;

    for(int i=1; i<32; i++) {

        res0 += aux * coeff(f1,i);
        res1 += aux * coeff(f2,i);
        res2 += aux * coeff(f4,i);
        res3 += aux * coeff(f8,i);

        aux *= xpoly;
    }


    //cout << "RES: " << res0 << "(res0) " << res1 << "(res1) " << res2 << "(res2) " << res2 << "(res2) " << "\n";

    bitstring result(128);


    ZZ_p one;
    one=1;

    for(int i = 0; i<32; i++) {
        if(coeff(rep(res0),i) == one) result.set(i);
        if(coeff(rep(res1),i) == one) result.set(i+32);
        if(coeff(rep(res2),i) == one) result.set(i+64);
        if(coeff(rep(res3),i) == one) result.set(i+96);
    }

    /*cout << "Result: ";
    result.print();
    cout << "\n";*/


    // retornar algo de tamanho 32, porque senao da erro de tamanho errado na entrada do extractor.. provavelmente devido a realimentacao
    //bitstring bla = x;
    //cout <<"bitstring output result = "<< result.to_string()<< endl;
    return result;
}
void HalfGCD(zz_pXMatrix& M_out, const zz_pX& U, const zz_pX& V, long d_red)
{
   if (IsZero(V) || deg(V) <= deg(U) - d_red) {
      set(M_out(0,0));   clear(M_out(0,1));
      clear(M_out(1,0)); set(M_out(1,1));
 
      return;
   }


   long n = deg(U) - 2*d_red + 2;
   if (n < 0) n = 0;

   zz_pX U1, V1;

   RightShift(U1, U, n);
   RightShift(V1, V, n);

   if (d_red <= NTL_zz_pX_HalfGCD_CROSSOVER) {
      IterHalfGCD(M_out, U1, V1, d_red);
      return;
   }

   long d1 = (d_red + 1)/2;
   if (d1 < 1) d1 = 1;
   if (d1 >= d_red) d1 = d_red - 1;

   zz_pXMatrix M1;

   HalfGCD(M1, U1, V1, d1);
   mul(U1, V1, M1);

   long d2 = deg(V1) - deg(U) + n + d_red;

   if (IsZero(V1) || d2 <= 0) {
      M_out = M1;
      return;
   }


   zz_pX Q;
   zz_pXMatrix M2;

   DivRem(Q, U1, U1, V1);
   swap(U1, V1);

   HalfGCD(M2, U1, V1, d2);

   zz_pX t(INIT_SIZE, deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,0));
   sub(t, M1(0,0), t);
   swap(M1(0,0), M1(1,0));
   swap(M1(1,0), t);

   t.kill();

   t.SetMaxLength(deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,1));
   sub(t, M1(0,1), t);
   swap(M1(0,1), M1(1,1));
   swap(M1(1,1), t);

   t.kill();

   mul(M_out, M2, M1); 
}
void XHalfGCD(zz_pXMatrix& M_out, zz_pX& U, zz_pX& V, long d_red)
{
   if (IsZero(V) || deg(V) <= deg(U) - d_red) {
      set(M_out(0,0));   clear(M_out(0,1));
      clear(M_out(1,0)); set(M_out(1,1));
 
      return;
   }

   long du = deg(U);

   if (d_red <= NTL_zz_pX_HalfGCD_CROSSOVER) {
      IterHalfGCD(M_out, U, V, d_red);
      return;
   }

   long d1 = (d_red + 1)/2;
   if (d1 < 1) d1 = 1;
   if (d1 >= d_red) d1 = d_red - 1;

   zz_pXMatrix M1;

   HalfGCD(M1, U, V, d1);
   mul(U, V, M1);

   long d2 = deg(V) - du + d_red;

   if (IsZero(V) || d2 <= 0) {
      M_out = M1;
      return;
   }


   zz_pX Q;
   zz_pXMatrix M2;

   DivRem(Q, U, U, V);
   swap(U, V);

   XHalfGCD(M2, U, V, d2);

   zz_pX t(INIT_SIZE, deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,0));
   sub(t, M1(0,0), t);
   swap(M1(0,0), M1(1,0));
   swap(M1(1,0), t);

   t.kill();

   t.SetMaxLength(deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,1));
   sub(t, M1(0,1), t);
   swap(M1(0,1), M1(1,1));
   swap(M1(1,1), t);

   t.kill();

   mul(M_out, M2, M1); 
}
Example #29
0
static CYTHON_INLINE void ZZX_quo_rem(struct ZZX* x, struct ZZX* other, struct ZZX** r, struct ZZX** q)
{
    struct ZZX *qq = new ZZX(), *rr = new ZZX();
    DivRem(*qq, *rr, *x, *other);
    *r = rr; *q = qq;
}
void ResHalfGCD(ZZ_pXMatrix& M_out, const ZZ_pX& U, const ZZ_pX& V, long d_red,
                vec_ZZ_p& cvec, vec_long& dvec)
{
   if (IsZero(V) || deg(V) <= deg(U) - d_red) {
      set(M_out(0,0));   clear(M_out(0,1));
      clear(M_out(1,0)); set(M_out(1,1));
 
      return;
   }


   long n = deg(U) - 2*d_red + 2;
   if (n < 0) n = 0;

   ZZ_pX U1, V1;

   RightShift(U1, U, n);
   RightShift(V1, V, n);

   if (d_red <= NTL_ZZ_pX_HalfGCD_CROSSOVER) { 
      ResIterHalfGCD(M_out, U1, V1, d_red, cvec, dvec);
      return;
   }

   long d1 = (d_red + 1)/2;
   if (d1 < 1) d1 = 1;
   if (d1 >= d_red) d1 = d_red - 1;

   ZZ_pXMatrix M1;

   ResHalfGCD(M1, U1, V1, d1, cvec, dvec);
   mul(U1, V1, M1);

   long d2 = deg(V1) - deg(U) + n + d_red;

   if (IsZero(V1) || d2 <= 0) {
      M_out = M1;
      return;
   }


   ZZ_pX Q;
   ZZ_pXMatrix M2;

   append(cvec, LeadCoeff(V1));
   append(dvec, dvec[dvec.length()-1]-deg(U1)+deg(V1));
   DivRem(Q, U1, U1, V1);
   swap(U1, V1);

   ResHalfGCD(M2, U1, V1, d2, cvec, dvec);

   ZZ_pX t(INIT_SIZE, deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,0));
   sub(t, M1(0,0), t);
   swap(M1(0,0), M1(1,0));
   swap(M1(1,0), t);

   t.kill();

   t.SetMaxLength(deg(M1(1,1))+deg(Q)+1);

   mul(t, Q, M1(1,1));
   sub(t, M1(0,1), t);
   swap(M1(0,1), M1(1,1));
   swap(M1(1,1), t);

   t.kill();

   mul(M_out, M2, M1); 
}