⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gf2x1.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 4 页
字号:
   long i;   for (i = 0; i < wmin; i++)      xp[i] = ap[i];   if (wa < wx) {      for (i = wa; i < wx; i++)         xp[i] = 0;   }   else {      long p = n % NTL_BITS_PER_LONG;      if (p != 0)         xp[wx-1] &= (1UL << p) - 1UL;   }}void add(GF2X& c, const GF2X& a, long b){   c = a;   if (b & 1) {      long n = c.xrep.length();      if (n == 0)          set(c);      else {         c.xrep[0] ^= 1;         if (n == 1 && !c.xrep[0]) c.xrep.SetLength(0);      }   }}void add(GF2X& c, const GF2X& a, GF2 b){   add(c, a, rep(b));}void MulTrunc(GF2X& c, const GF2X& a, const GF2X& b, long n){   GF2XRegister(t);   mul(t, a, b);   trunc(c, t, n);}void SqrTrunc(GF2X& c, const GF2X& a, long n){   GF2XRegister(t);   sqr(t, a);   trunc(c, t, n);}long divide(GF2X& q, const GF2X& a, const GF2X& b){   if (IsZero(b)) {      if (IsZero(a)) {         clear(q);         return 1;      }      else         return 0;   }   GF2XRegister(lq);   GF2XRegister(r);   DivRem(lq, r, a, b);   if (!IsZero(r)) return 0;   q = lq;   return 1;}long divide(const GF2X& a, const GF2X& b){   if (IsZero(b)) return IsZero(a);   GF2XRegister(r);   rem(r, a, b);   if (!IsZero(r)) return 0;   return 1;}/*** modular composition routines and data structures ***/void InnerProduct(GF2X& x, const GF2X& v, long dv, long low, long high,                    const vec_GF2X& H, long n, WordVector& t){   long i, j;   _ntl_ulong *tp = t.elts();   for (i = 0; i < n; i++)      tp[i] = 0;   long w_low = low/NTL_BITS_PER_LONG;   long b_low = low - w_low*NTL_BITS_PER_LONG;      const _ntl_ulong *vp = &v.xrep[w_low];   _ntl_ulong msk = 1UL << b_low;   _ntl_ulong vv = *vp;   high = min(high, dv);   i = low;   for (;;) {      if (vv & msk) {         const WordVector& h = H[i-low].xrep;         long m = h.length();         const _ntl_ulong *hp = h.elts();         for (j = 0; j < m; j++)            tp[j] ^= hp[j];      }      i++;      if (i > high) break;      msk = msk << 1;      if (!msk) {         msk = 1UL;         vp++;         vv = *vp;      }   }   x.xrep = t;   x.normalize();}void CompMod(GF2X& x, const GF2X& g, const GF2XArgument& A, const GF2XModulus& F){   long dg = deg(g);   if (dg <= 0) {      x = g;      return;   }   GF2X s, t;   WordVector scratch(INIT_SIZE, F.size);   long m = A.H.length() - 1;   long l = (((dg+1)+m-1)/m) - 1;   InnerProduct(t, g, dg, l*m, l*m + m - 1, A.H, F.size, scratch);   for (long i = l-1; i >= 0; i--) {      InnerProduct(s, g, dg, i*m, i*m + m - 1, A.H, F.size, scratch);      MulMod(t, t, A.H[m], F);      add(t, t, s);   }   x = t;}void build(GF2XArgument& A, const GF2X& h, const GF2XModulus& F, long m){   if (m <= 0 || deg(h) >= F.n) Error("build GF2XArgument: bad args");   if (m > F.n) m = F.n;   long i;   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], h, F);}void CompMod(GF2X& x, const GF2X& g, const GF2X& h, const GF2XModulus& F)   // x = g(h) mod f{   long m = SqrRoot(deg(g)+1);   if (m == 0) {      clear(x);      return;   }   GF2XArgument A;   build(A, h, F, m);   CompMod(x, g, A, F);}void Comp2Mod(GF2X& x1, GF2X& x2, const GF2X& g1, const GF2X& g2,              const GF2X& h, const GF2XModulus& F){   long m = SqrRoot(deg(g1) + deg(g2) + 2);   if (m == 0) {      clear(x1);      clear(x2);      return;   }   GF2XArgument A;   build(A, h, F, m);   GF2X xx1, xx2;   CompMod(xx1, g1, A, F);   CompMod(xx2, g2, A, F);   x1 = xx1;   x2 = xx2;}void Comp3Mod(GF2X& x1, GF2X& x2, GF2X& x3,               const GF2X& g1, const GF2X& g2, const GF2X& g3,              const GF2X& h, const GF2XModulus& F){   long m = SqrRoot(deg(g1) + deg(g2) + deg(g3) + 3);   if (m == 0) {      clear(x1);      clear(x2);      clear(x3);      return;   }   GF2XArgument A;   build(A, h, F, m);   GF2X xx1, xx2, xx3;   CompMod(xx1, g1, A, F);   CompMod(xx2, g2, A, F);   CompMod(xx3, g3, A, F);   x1 = xx1;   x2 = xx2;   x3 = xx3;}void build(GF2XTransMultiplier& B, const GF2X& b, const GF2XModulus& F){   long db = deg(b);   if (db >= F.n) Error("build TransMultiplier: bad args");   GF2X t;   LeftShift(t, b, F.n-1);   div(t, t, F);   // we optimize for low degree b   long d;   d = deg(t);   if (d < 0)      B.shamt_fbi = 0;   else      B.shamt_fbi = F.n-2 - d;    CopyReverse(B.fbi, t, d);   if (F.method != GF2X_MOD_TRI && F.method != GF2X_MOD_PENT) {         // The following code optimizes the case when       // f = X^n + low degree poly         trunc(t, F.f, F.n);      d = deg(t);      if (d < 0)         B.shamt = 0;      else         B.shamt = d;      CopyReverse(B.f0, t, d);   }   if (db < 0)      B.shamt_b = 0;   else      B.shamt_b = db;   CopyReverse(B.b, b, db);}void TransMulMod(GF2X& x, const GF2X& a, const GF2XTransMultiplier& B,               const GF2XModulus& F){   if (deg(a) >= F.n) Error("TransMulMod: bad args");   GF2XRegister(t1);   GF2XRegister(t2);   GF2XRegister(t3);   mul(t1, a, B.b);   RightShift(t1, t1, B.shamt_b);   if (F.method == GF2X_MOD_TRI) {      RightShift(t2, a, F.k3);      add(t2, t2, a);   }   else if (F.method == GF2X_MOD_PENT) {      RightShift(t2, a, F.k3);      RightShift(t3, a, F.k2);      add(t2, t2, t3);      RightShift(t3, a, F.k1);      add(t2, t2, t3);      add(t2, t2, a);   }   else {      mul(t2, a, B.f0);      RightShift(t2, t2, B.shamt);   }   trunc(t2, t2, F.n-1);   mul(t2, t2, B.fbi);   if (B.shamt_fbi > 0) LeftShift(t2, t2, B.shamt_fbi);   trunc(t2, t2, F.n-1);   MulByX(t2, t2);   add(x, t1, t2);}void UpdateMap(vec_GF2& x, const vec_GF2& a, const GF2XTransMultiplier& B,       const GF2XModulus& F){   GF2XRegister(xx);   GF2XRegister(aa);   conv(aa, a);   TransMulMod(xx, aa, B, F);   conv(x, xx);}   void ProjectPowers(GF2X& x, const GF2X& a, long k, const GF2XArgument& H,                   const GF2XModulus& F){   long n = F.n;   if (deg(a) >= n || k < 0 || k >= (1L << (NTL_BITS_PER_LONG-4)))       Error("ProjectPowers: bad args");   long m = H.H.length()-1;   long l = (k+m-1)/m - 1;   GF2XTransMultiplier M;   build(M, H.H[m], F);   GF2X s;   s = a;   x.SetMaxLength(k);   clear(x);   long i;   for (i = 0; i <= l; i++) {      long m1 = min(m, k-i*m);      for (long j = 0; j < m1; j++)         SetCoeff(x, i*m+j, InnerProduct(H.H[j].xrep, s.xrep));      if (i < l)         TransMulMod(s, s, M, F);   }}void ProjectPowers(vec_GF2& x, const vec_GF2& a, long k,                    const GF2XArgument& H, const GF2XModulus& F){   GF2X xx;   ProjectPowers(xx, to_GF2X(a), k, H, F);   VectorCopy(x, xx, k);}void ProjectPowers(GF2X& x, const GF2X& a, long k, const GF2X& h,                    const GF2XModulus& F){   if (deg(a) >= F.n || k < 0) Error("ProjectPowers: bad args");   if (k == 0) {      clear(x);      return;   }   long m = SqrRoot(k);   GF2XArgument H;   build(H, h, F, m);   ProjectPowers(x, a, k, H, F);}void ProjectPowers(vec_GF2& x, const vec_GF2& a, long k, const GF2X& H,                   const GF2XModulus& F){   GF2X xx;   ProjectPowers(xx, to_GF2X(a), k, H, F);   VectorCopy(x, xx, k);}void MinPolyInternal(GF2X& h, const GF2X& x, long m){   GF2X a, b, r, s;   GF2X a_in, b_in;   if (IsZero(x)) {      set(h);      return;   }   clear(a_in);   SetCoeff(a_in, 2*m);   CopyReverse(b_in, x, 2*m-1);         a.xrep.SetMaxLength(a_in.xrep.length()+1);   b.xrep.SetMaxLength(b_in.xrep.length()+1);   long max_sz = max(a_in.xrep.length(), b_in.xrep.length());   r.xrep.SetLength(max_sz+1);   s.xrep.SetLength(max_sz+1);   _ntl_ulong *rp = r.xrep.elts();   _ntl_ulong *sp = s.xrep.elts();   long i;   for (i = 0; i <= max_sz; i++) {      rp[i] = sp[i] = 0;   }   sp[0] = 1;   long sr = 0;   long ss = 1;   a = a_in;   b = b_in;   _ntl_ulong *ap = a.xrep.elts();   _ntl_ulong *bp = b.xrep.elts();   long da = deg(a);   long wa = da/NTL_BITS_PER_LONG;   long ba = da - wa*NTL_BITS_PER_LONG;   long db = deg(b);   long wb = db/NTL_BITS_PER_LONG;   long bb = db - wb*NTL_BITS_PER_LONG;   long parity = 0;   for (;;) {      if (da < db) {         swap(ap, bp);         swap(da, db);         swap(wa, wb);         swap(ba, bb);         parity = 1 - parity;         swap(rp, sp);         swap(sr, ss);      }      // da >= db      if (db < m) break;      ShiftAdd(ap, bp, wb+1, da-db);      ShiftAdd(rp, sp, ss, da-db);      long t = ss + (da-db+NTL_BITS_PER_LONG-1)/NTL_BITS_PER_LONG;      if (t > sr) {         while (t > 0 && rp[t-1] == 0) t--;          sr = t;      }      _ntl_ulong msk = 1UL << ba;      _ntl_ulong aa = ap[wa];      while ((aa & msk) == 0) {         da--;         msk = msk >> 1;         ba--;         if (!msk) {            wa--;            ba = NTL_BITS_PER_LONG-1;            msk = 1UL << (NTL_BITS_PER_LONG-1);            if (wa < 0) break;            aa = ap[wa];         }      }   }   a.normalize();   b.normalize();   r.normalize();   s.normalize();   if (!parity) {      h = s;   }   else {      h = r;   }}void DoMinPolyMod(GF2X& h, const GF2X& g, const GF2XModulus& F, long m,                const GF2X& R){   GF2X x;   ProjectPowers(x, R, 2*m, g, F);   MinPolyInternal(h, x, m);}void MinPolySeq(GF2X& h, const vec_GF2& a, long m){   if (m < 0 || m >= (1L << (NTL_BITS_PER_LONG-4))) Error("MinPoly: bad args");   if (a.length() < 2*m) Error("MinPoly: sequence too short");   GF2X x;   x.xrep = a.rep;   x.normalize();   MinPolyInternal(h, x, m);}void ProbMinPolyMod(GF2X& h, const GF2X& g, const GF2XModulus& F, long m){   long n = F.n;   if (m < 1 || m > n) Error("ProbMinPoly: bad args");   GF2X R;   random(R, n);   DoMinPolyMod(h, g, F, m, R);}void ProbMinPolyMod(GF2X& h, const GF2X& g, const GF2XModulus& F){   ProbMinPolyMod(h, g, F, F.n);}void MinPolyMod(GF2X& hh, const GF2X& g, const GF2XModulus& F, long m){   GF2X 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 */   GF2X h2, h3;   GF2X R;   GF2XTransMultiplier H1;      for (;;) {      random(R, n);      build(H1, h1, F);      TransMulMod(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; }   }}void IrredPolyMod(GF2X& h, const GF2X& g, const GF2XModulus& F, long m){   if (m < 1 || m > F.n) Error("IrredPoly: bad args");   GF2X R;   set(R);   DoMinPolyMod(h, g, F, m, R);}void IrredPolyMod(GF2X& h, const GF2X& g, const GF2XModulus& F){   IrredPolyMod(h, g, F, F.n);}void MinPolyMod(GF2X& hh, const GF2X& g, const GF2XModulus& F){   MinPolyMod(hh, g, F, F.n);}void MulByXMod(GF2X& c, const GF2X& a, const GF2XModulus& F){   long da = deg(a);   long df = deg(F);   if (da >= df) Error("MulByXMod: bad args");    MulByX(c, a);   if (da >= 0 && da == df-1)      add(c, c, F);}staticvoid MulByXModAux(GF2X& c, const GF2X& a, const GF2X& f){   long da = deg(a);   long df = deg(f);   if (da >= df) Error("MulByXMod: bad args");    MulByX(c, a);   if (da >= 0 && da == df-1)      add(c, c, f);}void MulByXMod(GF2X& h, const GF2X& a, const GF2X& f){   if (&h == &f) {      GF2X hh;      MulByXModAux(hh, a, f);      h = hh;   }   else      MulByXModAux(h, a, f);}void power(GF2X& x, const GF2X& a, long e){   if (e < 0) {      Error("power: negative exponent");   }   if (e == 0) {      x = 1;      return;   }   if (a == 0 || a == 1) {      x = a;      return;   }   long da = deg(a);   if (da > (NTL_MAX_LONG-1)/e)      Error("overflow in power");   GF2X res;   res.SetMaxLength(da*e + 1);   res = 1;      long k = NumBits(e);   long i;   for (i = k - 1; i >= 0; i--) {      sqr(res, res);      if (bit(e, i))         mul(res, res, a);   }   x = res;}staticvoid FastTraceVec(vec_GF2& S, const GF2XModulus& f){   long n = deg(f);   if (n <= 0) Error("TraceVec: bad args");   GF2X x = reverse(-LeftShift(reverse(diff(reverse(f)), n-1), n-1)/f, n-1);   VectorCopy(S, x, n);   S.put(0, to_GF2(n));}staticvoid PlainTraceVec(vec_GF2& S, const GF2X& f){   long n = deg(f);   if (n <= 0)       Error("TraceVec: bad args");   if (n == 0) {      S.SetLength(0);      return;   }   GF2X x = reverse(-LeftShift(reverse(diff(reverse(f)), n-1), n-1)/f, n-1);   VectorCopy(S, x, n);    S.put(0, to_GF2(n));}void TraceVec(vec_GF2& S, const GF2X& f){   PlainTraceVec(S, f);}staticvoid ComputeTraceVec(const GF2XModulus& F){   vec_GF2& S = *((vec_GF2 *) &F.tracevec);   if (S.length() > 0)      return;   if (F.method == GF2X_MOD_PLAIN) {      PlainTraceVec(S, F.f);   }   else {      FastTraceVec(S, F);   }}void TraceMod(GF2& x, const GF2X& a, const GF2XModulus& F){   long n = F.n;   if (deg(a) >= n)      Error("trace: bad args");   if (F.tracevec.length() == 0)       ComputeTraceVec(F);   project(x, F.tracevec, a);}void TraceMod(GF2& x, const GF2X& a, const GF2X& f){   if (deg(a) >= deg(f) || deg(f) <= 0)      Error("trace: bad args");   project(x, TraceVec(f), a);}NTL_END_IMPL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -