Example #1
0
static void ZZ_pX_InvMod_newton_unram(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ_pXModulus &F, const struct ZZ_pContext &cpn, const struct ZZ_pContext &cp)
{
    //int j;
    cp.restore();
    ZZ_pX *amodp = new ZZ_pX();
    ZZ_pX *xmodp = new ZZ_pX();
    ZZ_pX *fmodp = new ZZ_pX();
    ZZ_pX_conv_modulus(*amodp, a, cp);
    ZZ_pX_conv_modulus(*fmodp, F.val(), cp);
    InvMod(*xmodp, *amodp, *fmodp);
    //cout << "xmodp: " << *xmodp << "\namodp: " << *amodp << "\nfmodp: " << *fmodp << "\n";
    cpn.restore();
    ZZ_pX *minusa = new ZZ_pX();
    ZZ_pX *xn = new ZZ_pX();
    ZZ_pX_conv_modulus(*xn, *xmodp, cpn);
    NTL::negate(*minusa, a);
    while (1 > 0)
    {
        // x_n = 2*x_{n-1} - a*x_{n-1}^2 = (2 - a*x_{n-1})*x_{n-1}
        MulMod(x, *minusa, *xn, F);
        SetCoeff(x, 0, ConstTerm(x) + 2);
        MulMod(x, x, *xn, F);
        if (x == *xn)
            break;
        *xn = x;
        //cout << "x: " << x << "\nxn: " << *xn << "\n";
        //cin >> j;
    }
    delete amodp;
    delete xmodp;
    delete fmodp;
    delete minusa;
    delete xn;
}
Example #2
0
// The function compOrder(orders, classes,flag,m) computes the order of elements
// of the quotient group, relative to current equivalent classes. If flag==1
// then also check if the order is the same as in (Z/mZ)^* and store the order
// with negative sign if not.
static void 
compOrder(vector<long>& orders, vector<long>& classes, bool flag, long m)
{
  orders[0] = 0;
  orders[1] = 1;
  for (long i=2; i<m; i++) {
    if (classes[i] <= 1) { // ignore i not in Z_m^* and order-0 elements
      orders[i] = (classes[i]==1)? 1 : 0;
      continue;
    }

    // If not comparing order with (Z/mZ)^*, only compute the order of pivots

    if (!flag && classes[i]<i){          // not a pivot
      orders[i] = orders[classes[i]];
      continue;
    }

    // For an element i>1, the order is at least 2
    long j = MulMod(i, i, m);
    long ord = 2;
    while (classes[j] != 1) {
      j = MulMod(j, i, m); // next element in <i>
      ord++;    // count how many steps until we reach 1
    }

    // When we get here we have classes[j]==1, so if j!=1 it means that the
    // order of i in the quotient group is smaller than its order in the
    // entire group Z_m^*. If the flag is set then we store orders[i] = -ord.
    
    if (flag && j != 1) ord = -ord; // order in Z_m^* is larger than ord
    orders[i] = ord;
  }
}
Example #3
0
static
void conjClasses(vector<unsigned long>& classes, unsigned long g, unsigned long m)
{
    for (unsigned long i=0; i<m; i++) {
        if (classes[i]==0) continue; // i \notin (Z/mZ)^*

        if (classes[i]<i) { // i is not a pivot, updated its pivot
            classes[i] = classes[classes[i]];
            continue;
        }

        // If i is a pivot, update other pivots to point to it
        unsigned long ii = i;
        unsigned long gg = g;
        unsigned long jj = MulMod(ii, gg, m);
        while (classes[jj] != i) {
            classes[classes[jj]]= i; // Merge the equivalence classes of j and i

            // Note: if classes[j]!=j then classes[j] will be updated later,
            //       when we get to i=j and use the code for "i not pivot".

            jj = MulMod(jj, g, m);
        }
    }
}
void PaillierParty::secretShare() {
    ZZ beta = getRandomInNStar(m_n);

    std::vector<ZZ> coefficients;

    coefficients.push_back(MulMod(beta,m_m,m_n*m_m));

    for (uint32_t i=1; i < m_numOfParties; i++) {
        coefficients.push_back(getRandomInNStar(m_n*m_m));
    }

    ZZ_p::init(m_n*m_m);
    ZZ_pX polynomial;
    for (uint32_t i=0; i < m_numOfParties; i++) {
        SetCoeff(polynomial, i, conv<ZZ_p>(coefficients[i]));
    }

    for (auto &party : m_parties) {
        ZZ result = rep(eval(polynomial,ZZ_p(party.first)));
        sendZZTo(result,party.second);
    }

    ZZ_p s_i = eval(polynomial,ZZ_p(m_partyId));
    for (auto &party : m_parties) {
        ZZ value;
        receiveZZFrom(value,party.second);
        ZZ_p coefficient = conv<ZZ_p>(value);
        s_i = s_i + coefficient;
    }

    m_share = rep(s_i);

    m_pubKey = MulMod(MulMod(m_a,beta,m_n),m_m,m_n);
}
Example #5
0
// Sets the prime defining the field for the curve and stores certain values
void Icart::setPrime(ZZ* p)
{
    //ZZ_p::init(*p);
    // Icart hash function uses 1/3 root, which is equivalent to (2p-1)/3
    exp = MulMod( SubMod( MulMod(ZZ(2), *p, *p), ZZ(1), *p), InvMod(ZZ(3),*p), *p);
    // Store inverse values to be used later
    ts = inv(ZZ_p(27));
    th = inv(ZZ_p(3));
}
Example #6
0
/*
 * Must guarantee c+c DO NOT OVERFLOW!!!(both a, b, c are INTEGERS)
 * $a or $b may be negative, however $c must be positive
 */
template<class T> T PowMod( T a, T b, T c) {
   	T r=Mod((T)1,c);
   	a=Mod(a,c);
	while(b != 0) {
		if(b & 1) r=MulMod(r, a, c);
		a = MulMod( a, a, c);
		b >>= 1;
	}
	return r;
}
Example #7
0
void Shares::addShares(map<string, ZZ> newShares){
    for(auto i : newShares){
        ZZ tmp = MulMod(i.second, shares[i.first], groupModulus);
        shares[i.first] = tmp;
    }
    nbrShares++;
}
Example #8
0
void InnerProduct(zz_p& x, const vec_zz_p& a, const vec_zz_p& b,
                  long offset)
{
   if (offset < 0) LogicError("InnerProduct: negative offset");
   if (NTL_OVERFLOW(offset, 1, 0)) ResourceError("InnerProduct: offset too big");

   long n = min(a.length(), b.length()+offset);
   long i;

   long accum, t;
   long p = zz_p::modulus();
   mulmod_t pinv = zz_p::ModulusInverse();


   const zz_p *ap = a.elts();
   const zz_p *bp = b.elts();

   accum = 0;
   for (i = offset; i < n; i++) {
      t = MulMod(rep(ap[i]), rep(bp[i-offset]), p, pinv);
      accum = AddMod(accum, t, p);
   }

   x.LoopHole() = accum;
}
Example #9
0
// Apply F(X)->F(X^k) followed by re-liearization. The automorphism is possibly
// evaluated via a sequence of steps, to ensure that we can re-linearize the
// result of every step.
void Ctxt::smartAutomorph(long k) 
{
  FHE_TIMER_START;
  // Special case: if *this is empty then do nothing
  if (this->isEmpty()) return;

  long m = context.zMStar.getM();

  k = mcMod(k, m);

  // Sanity check: verify that k \in Zm*
  assert (context.zMStar.inZmStar(k));

  long keyID=getKeyID();
  if (!inCanonicalForm(keyID)) {     // Re-linearize the input, if needed
    reLinearize(keyID);
    assert (inCanonicalForm(keyID)); // ensure that re-linearization succeeded
  }
  assert (pubKey.isReachable(k,keyID)); // reachable from 1

  while (k != 1) {
    const KeySwitch& matrix = pubKey.getNextKSWmatrix(k,keyID);
    long amt = matrix.fromKey.getPowerOfX();

    automorph(amt);
    reLinearize(keyID);

    k = MulMod(k, InvMod(amt,m), m);
  }
  FHE_TIMER_STOP;
}
void build(zz_pXArgument& A, const zz_pX& h, const zz_pXModulus& F, long m)
{
   if (m <= 0 || deg(h) >= F.n) Error("build: bad args");

   if (m > F.n) m = F.n;

   long i;

   if (zz_pXArgBound > 0) {
      double sz = 1;
      sz = sz*F.n;
      sz = sz+6;
      sz = sz*(sizeof (long));
      sz = sz/1024;
      m = min(m, long(zz_pXArgBound/sz));
      m = max(m, 1);
   }

   zz_pXMultiplier M;

   build(M, h, F);

   A.H.SetLength(m+1);

   set(A.H[0]);
   A.H[1] = h;
   for (i = 2; i <= m; i++) 
      MulMod(A.H[i], A.H[i-1], M, F);
}
Example #11
0
YASHE YASHE::readFromFile(std::string filename) {
  YASHE output;
  std::ifstream ifs(filename);
  boost::archive::text_iarchive ia(ifs);
  ia >> output;
  NTL::ZZ_p::init(output.cModulus);
  output.cycloMod = NTL::ZZ_pXModulus(NTL::conv<NTL::ZZ_pX>(output.cycloModX));
  {
    NTL::ZZ_pPush push(output.bigModulus); // switch to multiplication modulus
    // make another modulus for fast multiplication
    output.bigCycloMod = NTL::ZZ_pXModulus(NTL::conv<NTL::ZZ_pX>(output.cycloModX));
  }
  {
    NTL::ZZ_pPush push(output.bigPModulus); // switch to plain text modulus
    // Factor the cyclotomic polynomial modulo t
    // for batch encryption
    NTL::ZZ_pXModulus pModulusX;
    NTL::build(pModulusX, NTL::conv<NTL::ZZ_pX>(output.cycloModX));

    output.crtElements.resize(output.factors.size());
    NTL::ZZ_pX fInv, fInvInv;
    for (long i = 0; i < output.factors.size(); i++) {
      div(fInv, NTL::conv<NTL::ZZ_pX>(output.cycloModX), output.factors[i]);
      rem(fInvInv, fInv, output.factors[i]);
      InvMod(fInvInv, fInvInv, output.factors[i]);
      output.crtElements[i] = MulMod(fInv, fInvInv, pModulusX);
    }
  }
  return output;
}
void MinPolyMod(zz_pX& hh, const zz_pX& g, const zz_pXModulus& F, long m)
{
   zz_pX h, h1;
   long n = F.n;
   if (m < 1 || m > n) Error("MinPoly: bad args");

   /* probabilistically compute min-poly */

   ProbMinPolyMod(h, g, F, m);
   if (deg(h) == m) { hh = h; return; }
   CompMod(h1, h, g, F);
   if (IsZero(h1)) { hh = h; return; }

   /* not completely successful...must iterate */

   long i;

   zz_pX h2, h3;
   zz_pXMultiplier H1;
   vec_zz_p R(INIT_SIZE, n);

   for (;;) {
      R.SetLength(n);
      for (i = 0; i < n; i++) random(R[i]);
      build(H1, h1, F);
      UpdateMap(R, R, H1, F);
      DoMinPolyMod(h2, g, F, m-deg(h), R);

      mul(h, h, h2);
      if (deg(h) == m) { hh = h; return; }
      CompMod(h3, h2, g, F);
      MulMod(h1, h3, H1, F);
      if (IsZero(h1)) { hh = h; return; }
   }
}
Example #13
0
static
void BuildMatrix(vec_GF2XVec& M, long n, const GF2EX& g, const GF2EXModulus& F,
                 long verbose)
{
   long i, j, m;
   GF2EX h;


   M.SetLength(n);
   for (i = 0; i < n; i++)
      M[i].SetSize(n, 2*GF2E::WordLength());

   set(h);
   for (j = 0; j < n; j++) {
      if (verbose && j % 10 == 0) cerr << "+";

      m = deg(h);
      for (i = 0; i < n; i++) {
         if (i <= m)
            M[i][j] = rep(h.rep[i]);
         else
            clear(M[i][j]);
      }

      if (j < n-1)
         MulMod(h, h, g, F);
   }

   for (i = 0; i < n; i++)
      add(M[i][i], M[i][i], 1);

}
Example #14
0
// Compute the mapping between linear array and a hypercube corresponding
/// to a single generator tree
void ComputeOneGenMapping(Permut& genMap, const OneGeneratorTree& T)
{
  Vec<long> dims(INIT_SIZE, T.getNleaves());
  Vec<long> coefs(INIT_SIZE,T.getNleaves());
  for (long i=T.getNleaves()-1, leaf=T.lastLeaf(); i>=0;
                                i--, leaf=T.prevLeaf(leaf)) {
    dims[i] = T[leaf].getData().size;
    coefs[i] = T[leaf].getData().e;
  }

  // A representation of an integer with digits from dims
  Vec<long> rep(INIT_SIZE, T.getNleaves());
  for (long i=0; i<rep.length(); i++) rep[i]=0; // initialize to zero

  // initialize to all zero
  long sz = T[0].getData().size;
  genMap.SetLength(sz);
  for (long i=0; i<sz; i++) genMap[i]=0;

  // compute the permutation
  for (long i=1; i<sz; i++) {
    addOne(rep, dims); // representation of i in base dims
    for (long j=0; j<coefs.length(); j++) {
      long tmp = MulMod(rep[j], coefs[j], sz);
      genMap[i] = AddMod(genMap[i], tmp, sz);
    }
  }
}
void build(ZZ_pXArgument& A, const ZZ_pX& h, const ZZ_pXModulus& F, long m)
{
   if (m <= 0 || deg(h) >= F.n) LogicError("build: bad args");

   if (m > F.n) m = F.n;

   long i;

   if (ZZ_pXArgBound > 0) {
      double sz = ZZ_p::storage();
      sz = sz*F.n;
      sz = sz + NTL_VECTOR_HEADER_SIZE + sizeof(vec_ZZ_p);
      sz = sz/1024;
      m = min(m, long(ZZ_pXArgBound/sz));
      m = max(m, 1);
   }

   ZZ_pXMultiplier M;

   build(M, h, F);

   A.H.SetLength(m+1);

   set(A.H[0]);
   A.H[1] = h;
   for (i = 2; i <= m; i++) 
      MulMod(A.H[i], A.H[i-1], M, F);
}
void CompMod(ZZ_pX& x, const ZZ_pX& g, const ZZ_pXArgument& A, 
             const ZZ_pXModulus& F)
{
   if (deg(g) <= 0) {
      x = g;
      return;
   }


   ZZ_pX s, t;
   ZZVec scratch(F.n, ZZ_p::ExtendedModulusSize());

   long m = A.H.length() - 1;
   long l = ((g.rep.length()+m-1)/m) - 1;

   ZZ_pXMultiplier M;
   build(M, A.H[m], F);

   InnerProduct(t, g.rep, l*m, l*m + m - 1, A.H, F.n, scratch);
   for (long i = l-1; i >= 0; i--) {
      InnerProduct(s, g.rep, i*m, i*m + m - 1, A.H, F.n, scratch);
      MulMod(t, t, M, F);
      add(t, t, s);
   }

   x = t;
}
void CompMod(zz_pX& x, const zz_pX& g, const zz_pXArgument& A, 
             const zz_pXModulus& F)
{
   if (deg(g) <= 0) {
      x = g;
      return;
   }


   zz_pX s, t;
   vec_zz_p scratch(INIT_SIZE, F.n);

   long m = A.H.length() - 1;
   long l = ((g.rep.length()+m-1)/m) - 1;

   zz_pXMultiplier M;
   build(M, A.H[m], F);

   InnerProduct(t, g.rep, l*m, l*m + m - 1, A.H, F.n, scratch);
   for (long i = l-1; i >= 0; i--) {
      InnerProduct(s, g.rep, i*m, i*m + m - 1, A.H, F.n, scratch);
      MulMod(t, t, M, F);
      add(t, t, s);
   }

   x = t;
}
Example #18
0
long CRT(vec_ZZ& gg, ZZ& a, const vec_zz_p& G)
{
   long n = gg.length();
   if (G.length() != n) Error("CRT: vector length mismatch");

   long p = zz_p::modulus();

   ZZ new_a;
   mul(new_a, a, p);

   long a_inv;
   a_inv = rem(a, p);
   a_inv = InvMod(a_inv, p);

   long p1;
   p1 = p >> 1;

   ZZ a1;
   RightShift(a1, a, 1);

   long p_odd = (p & 1);

   long modified = 0;

   long h;

   ZZ g;
   long i;
   for (i = 0; i < n; i++) {
      if (!CRTInRange(gg[i], a)) {
         modified = 1;
         rem(g, gg[i], a);
         if (g > a1) sub(g, g, a);
      }
      else
         g = gg[i];

      h = rem(g, p);
      h = SubMod(rep(G[i]), h, p);
      h = MulMod(h, a_inv, p);
      if (h > p1)
         h = h - p;

      if (h != 0) {
         modified = 1;

         if (!p_odd && g > 0 && (h == p1))
            MulSubFrom(g, a, h);
         else
            MulAddTo(g, a, h);
      }

      gg[i] = g;
   }

   a = new_a;

   return modified;
}
Example #19
0
NTL_START_IMPL


long IterIrredTest(const GF2X& f)
{
   long df = deg(f);

   if (df <= 0) return 0;
   if (df == 1) return 1;

   GF2XModulus F;

   build(F, f);
   
   GF2X h;
   SetX(h);
   SqrMod(h, h, F);

   long i, d, limit, limit_sqr;
   GF2X g, X, t, prod;


   SetX(X);

   i = 0;
   g = h;
   d = 1;
   limit = 2;
   limit_sqr = limit*limit;

   set(prod);

   while (2*d <= df) {
      add(t, g, X);
      MulMod(prod, prod, t, F);
      i++;
      if (i == limit_sqr) {
         GCD(t, f, prod);
         if (!IsOne(t)) return 0;

         set(prod);
         limit++;
         limit_sqr = limit*limit;
         i = 0;
      }

      d = d + 1;
      if (2*d <= deg(f)) {
         SqrMod(g, g, F);
      }
   }

   if (i > 0) {
      GCD(t, f, prod);
      if (!IsOne(t)) return 0;
   }

   return 1;
}
Example #20
0
NTL::ZZ_pX YASHE::keyGen() {
  /**
   * The secret key is computed as
   *
   *      f' <- X_key
   *      f = (t*f' + 1) mod q
   *      secretKey = f
   * 
   * Secret keys are randomly generated until
   * an invertible key f^-1 is found
   */
  NTL::ZZ_pX secretKey, secretKeyInv;
  long inverseStatus;
  do {
    secretKey = pModulus * randomKeyPoly() + 1;
    inverseStatus = InvModStatus(secretKeyInv, secretKey, cycloMod);
  } while (inverseStatus == 1);

  /**
   * The public key is computed by
   *
   *      g <- X_key
   *      h = (t*g*f^-1) mod q
   *      publicKey = h
   */
  publicKey = MulMod(randomKeyPoly(), secretKeyInv, cycloMod);
  publicKey *= pModulus;

  /** 
   * The evaluation key is computed by
   *
   *        e, s <- X_err
   *        gamma = (powersOfRadix(f) + e + h*s) mod q
   *        evaluationKey = gamma
   */
  std::vector<NTL::ZZ_pX> evalKey;
  powersOfRadix(evalKey, secretKey);
  evalKeyMult.resize(decompSize);
  for (long i = 0; i < decompSize; i++) {
    evalKey[i] += randomErrPoly();
    evalKey[i] += MulMod(publicKey, randomErrPoly(), cycloMod);
    NTL::build(evalKeyMult[i], evalKey[i], cycloMod);
  }

  return secretKey;
}
Example #21
0
void mul_aux(vec_zz_p& x, const mat_zz_p& A, const vec_zz_p& b)
{
   long n = A.NumRows();
   long l = A.NumCols();

   if (l != b.length())
      LogicError("matrix mul: dimension mismatch");

   x.SetLength(n);
   zz_p* xp = x.elts();

   long p = zz_p::modulus();
   mulmod_t pinv = zz_p::ModulusInverse();

   long i, k;
   long acc, tmp;

   const zz_p* bp = b.elts();

   if (n <= 1) {

      for (i = 0; i < n; i++) {
	 acc = 0;
	 const zz_p* ap = A[i].elts();

	 for (k = 0; k < l; k++) {
            tmp = MulMod(rep(ap[k]), rep(bp[k]), p, pinv);
            acc = AddMod(acc, tmp, p);
	 }

	 xp[i].LoopHole() = acc;
      }

   }
   else {

      Vec<mulmod_precon_t>::Watcher watch_precon_vec(precon_vec);
      precon_vec.SetLength(l);
      mulmod_precon_t *bpinv = precon_vec.elts();

      for (k = 0; k < l; k++)
         bpinv[k] = PrepMulModPrecon(rep(bp[k]), p, pinv);

      for (i = 0; i < n; i++) {
	 acc = 0;
	 const zz_p* ap = A[i].elts();

	 for (k = 0; k < l; k++) {
            tmp = MulModPrecon(rep(ap[k]), rep(bp[k]), p, bpinv[k]);
            acc = AddMod(acc, tmp, p);
	 }

	 xp[i].LoopHole() = acc;
      } 
   }
}
Example #22
0
long FHEPubKey::Encrypt(Ctxt &ctxt, const ZZX& ptxt, long ptxtSpace) const
{
    FHE_TIMER_START;
    assert(this == &ctxt.pubKey);

    if (ptxtSpace != pubEncrKey.ptxtSpace) { // plaintext-space mistamtch
        ptxtSpace = GCD(ptxtSpace, pubEncrKey.ptxtSpace);
        if (ptxtSpace <= 1) Error("Plaintext-space mismatch on encryption");
    }

    // choose a random small scalar r and a small random error vector e,
    // then set ctxt = r*pubEncrKey + ptstSpace*e + (ptxt,0)
    DoubleCRT e(context, context.ctxtPrimes);
    DoubleCRT r(context, context.ctxtPrimes);
    r.sampleSmall();

    // generate a random encryption of zero from the public encryption key
    ctxt = pubEncrKey;  // already an encryption of zero, just not a random one
    for (size_t i=0; i<ctxt.parts.size(); i++) {  // add noise to all the parts
        ctxt.parts[i] *= r;

        e.sampleGaussian();
        e *= ptxtSpace;
        ctxt.parts[i] += e;
    }

    // add in the plaintext
    // FIXME: This relies on the first part to be with respect to 1
    if (ptxtSpace==2) ctxt.parts[0] += ptxt;

    else { // The general case of ptxtSpace>2: for a ciphertext
        // relative to modulus Q, we add ptxt * Q mod ptxtSpace.
        long QmodP = rem(context.productOfPrimes(ctxt.primeSet), ptxtSpace);
        ctxt.parts[0] += MulMod(ptxt,QmodP,ptxtSpace); // MulMod from module NumbTh
    }
    // FIXME: the above relies on the first part, ctxt[0], to have handle to 1

    // fill in the other ciphertext data members
    ctxt.ptxtSpace = ptxtSpace;

    // We have <skey,ctxt>= r*<skey,pkey> +p*(e0+e1*s) +m, where VAR(<skey,pkey>)
    // is recorded in pubEncrKey.noiseVar, VAR(ei)=sigma^2*phi(m), VAR(s) is
    // determined by the secret-key Hamming weight (skHwt), and VAR(r)=phi(m)/2.
    // Hence the total expected size squared is bounded by
    //     E(X^2) <= pubEncrKey.noiseVar*phi(m)/2
    //               + p^2*sigma^2*phi(m)*(skHwt+1) + p^2

    long hwt = skHwts[0];
    xdouble phim = to_xdouble(context.zMStar.getPhiM());
    xdouble sigma2 = context.stdev * context.stdev;
    xdouble p2 = to_xdouble(ptxtSpace) * to_xdouble(ptxtSpace);
    ctxt.noiseVar = pubEncrKey.noiseVar*phim/2 + p2*sigma2*phim*(hwt+1) + p2;

    FHE_TIMER_STOP;
    return ptxtSpace;
}
Example #23
0
void InitFFTPrimeInfo(FFTPrimeInfo& info, long q, long w, long bigtab)
{
   double qinv = 1/((double) q);

   long mr = CalcMaxRoot(q);

   info.q = q;
   info.qinv = qinv;
   info.zz_p_context = 0;


   info.RootTable.SetLength(mr+1);
   info.RootInvTable.SetLength(mr+1);
   info.TwoInvTable.SetLength(mr+1);
   info.TwoInvPreconTable.SetLength(mr+1);

   long *rt = &info.RootTable[0];
   long *rit = &info.RootInvTable[0];
   long *tit = &info.TwoInvTable[0];
   mulmod_precon_t *tipt = &info.TwoInvPreconTable[0];

   long j;
   long t;

   rt[mr] = w;
   for (j = mr-1; j >= 0; j--)
      rt[j] = MulMod(rt[j+1], rt[j+1], q);

   rit[mr] = InvMod(w, q);
   for (j = mr-1; j >= 0; j--)
      rit[j] = MulMod(rit[j+1], rit[j+1], q);

   t = InvMod(2, q);
   tit[0] = 1;
   for (j = 1; j <= mr; j++)
      tit[j] = MulMod(tit[j-1], t, q);

   for (j = 0; j <= mr; j++)
      tipt[j] = PrepMulModPrecon(tit[j], q, qinv);

   info.bigtab = bigtab;
}
Example #24
0
ZZ PaillierParty::decrypt(const std::map<uint32_t,ZZ> &partialCiphers,
                          const std::vector<ZZ> &pubKeys) {
    ZZ sum(0);
    for (auto &pubKey : pubKeys) {
        sum = AddMod(sum,pubKey,m_n);
    }

    ZZ phi = MulMod(m_a,sum,m_n);

    ZZ prod(1);
    for (auto &partialCipher: partialCiphers) {
        uint32_t partyId = partialCipher.first;
        prod = MulMod(prod,PowerMod(partialCipher.second, 2*m_lagrangeBasis[partyId],m_field),m_field);
    }

    ZZ LResult = L_function(prod);

    ZZ combinedShare = InvMod(MulMod(4*m_delta*m_delta,phi,m_n),m_n);
    return MulMod(LResult, combinedShare, m_n);
}
Example #25
0
unsigned long PAlgebra::exponentiate(const vector<unsigned long>& exps,
                                     bool onlySameOrd) const
{
    unsigned long t = 1;
    unsigned long n = min(exps.size(),gens.size());
    for (unsigned long i=0; i<n; i++) {
        if (onlySameOrd && !SameOrd(i)) continue;
        unsigned long g = PowerMod(gens[i] ,exps[i], m);
        t = MulMod(t, g, m);
    }
    return t;
}
Example #26
0
static
void ProcessTable(GF2X& f, vec_pair_GF2X_long& factors, 
                  const GF2XModulus& F, long limit, const vec_GF2X& tbl,
                  long d, long verbose)

{
   if (limit == 0) return;

   if (verbose) cerr << "+";

   GF2X t1;

   if (limit == 1) {
      GCD(t1, f, tbl[0]);
      if (deg(t1) > 0) {
         AddFactor(factors, t1, d, verbose);
         div(f, f, t1);
      }

      return;
   }

   long i;

   t1 = tbl[0];
   for (i = 1; i < limit; i++)
      MulMod(t1, t1, tbl[i], F);

   GCD(t1, f, t1);

   if (deg(t1) == 0) return;

   div(f, f, t1);

   GF2X t2;

   i = 0;
   d = d - limit + 1;

   while (2*d <= deg(t1)) {
      GCD(t2, tbl[i], t1); 
      if (deg(t2) > 0) {
         AddFactor(factors, t2, d, verbose);
         div(t1, t1, t2);
      }

      i++;
      d++;
   }

   if (deg(t1) > 0)
      AddFactor(factors, t1, deg(t1), verbose);
}
Example #27
0
/**
 * A message is a polynomial of degree <= d modulo t.
 * The encryption is calculated as follows:
 * 
 *   c = (floor(q/t) * (m mod t) + e + publicKey*s) mod q
 *
 * With s, e <- X_err
 */
YASHE_CT YASHE::encrypt(long message) {
  
  NTL::ZZ_pX output;
  output.SetLength(maxDegree + 1);

  output[0] = NTL::ZZ_p(message % pModulus);

  output *= modulusRatio;
  output += randomErrPoly();
  output += MulMod(randomErrPoly(), publicKey, cycloMod);

  return YASHE_CT(output, this);
}
Example #28
0
// return multiplicative order of p modulo m, or 0 if GCD(p, m) != 1
long multOrd(long p, long m)
{
  if (GCD(p, m) != 1) return 0;

  p = p % m;
  long ord = 1;
  long val = p; 
  while (val != 1) {
    ord++;
    val = MulMod(val, p, m);
  }
  return ord;
}
Example #29
0
long simplePolyEval(const ZZX& poly, DynamicPtxtPowers& babyStep, long mod)
{
  assert (deg(poly)<=(long)babyStep.size());// ensure that we have enough powers

  long ret = rem(ConstTerm(poly), mod);
  for (long i=0; i<deg(poly); i++) {
    long coeff = rem(poly[i+1], mod); // f_{i+1}
    long tmp = babyStep[i];           // X^{i+1}
    tmp = MulMod(tmp, coeff, mod);    // f_{i+1} X^{i+1}
    ret = AddMod(ret, tmp, mod);
  }
  return ret;
}
Example #30
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;
  }
}