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

📄 gf2x1.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 4 页
字号:
      ShiftAdd(qq, qbuf, a_len);   }   q = qq;}staticvoid TrinomReduce(GF2X& x, const GF2X& a, long n, long k){   long wn = n / NTL_BITS_PER_LONG;   long bn = n - wn*NTL_BITS_PER_LONG;   long wdiff = (n-k)/NTL_BITS_PER_LONG;   long bdiff = (n-k) - wdiff*NTL_BITS_PER_LONG;   long m = a.xrep.length()-1;   if (wn > m) {      x = a;      return;   }   GF2XRegister(r);   r = a;   _ntl_ulong *p = r.xrep.elts();   _ntl_ulong *pp;   _ntl_ulong w;   if (bn == 0) {      if (bdiff == 0) {         // bn == 0 && bdiff == 0         while (m >= wn) {            w = p[m];            p[m-wdiff] ^= w;            p[m-wn] ^= w;            m--;         }      }      else {         // bn == 0 && bdiff != 0         while (m >= wn) {            w = p[m];            pp = &p[m-wdiff];            *pp ^= (w >> bdiff);            *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bdiff));            p[m-wn] ^= w;            m--;         }      }   }   else {      if (bdiff == 0) {         // bn != 0 && bdiff == 0         while (m > wn) {            w = p[m];            p[m-wdiff] ^= w;            pp = &p[m-wn];            *pp ^= (w >> bn);            *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bn));            m--;         }         w = (p[m] >> bn) << bn;;         p[m-wdiff] ^= w;         p[0] ^= (w >> bn);         p[m] &= ((1UL<<bn)-1UL);       }      else {         // bn != 0 && bdiff != 0         while (m > wn) {            w = p[m];            pp = &p[m-wdiff];            *pp ^= (w >> bdiff);;            *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bdiff));            pp = &p[m-wn];            *pp ^= (w >> bn);            *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bn));            m--;         }         w = (p[m] >> bn) << bn;;         p[m-wdiff] ^= (w >> bdiff);         if (m-wdiff-1 >= 0) p[m-wdiff-1] ^= (w << (NTL_BITS_PER_LONG-bdiff));         p[0] ^= (w >> bn);         p[m] &= ((1UL<<bn)-1UL);       }   }   if (bn == 0)      wn--;   while (wn >= 0 && p[wn] == 0)      wn--;   r.xrep.QuickSetLength(wn+1);   x = r;}staticvoid PentReduce(GF2X& x, const GF2X& a, long n, long k3, long k2, long k1){   long wn = n / NTL_BITS_PER_LONG;   long bn = n - wn*NTL_BITS_PER_LONG;   long m = a.xrep.length()-1;   if (wn > m) {      x = a;      return;   }   long wdiff1 = (n-k1)/NTL_BITS_PER_LONG;   long bdiff1 = (n-k1) - wdiff1*NTL_BITS_PER_LONG;   long wdiff2 = (n-k2)/NTL_BITS_PER_LONG;   long bdiff2 = (n-k2) - wdiff2*NTL_BITS_PER_LONG;   long wdiff3 = (n-k3)/NTL_BITS_PER_LONG;   long bdiff3 = (n-k3) - wdiff3*NTL_BITS_PER_LONG;   static GF2X r;   r = a;   _ntl_ulong *p = r.xrep.elts();   _ntl_ulong *pp;   _ntl_ulong w;   while (m > wn) {      w = p[m];      if (bn == 0)          p[m-wn] ^= w;      else {         pp = &p[m-wn];         *pp ^= (w >> bn);         *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bn));      }      if (bdiff1 == 0)          p[m-wdiff1] ^= w;      else {         pp = &p[m-wdiff1];         *pp ^= (w >> bdiff1);         *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bdiff1));      }      if (bdiff2 == 0)          p[m-wdiff2] ^= w;      else {         pp = &p[m-wdiff2];         *pp ^= (w >> bdiff2);         *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bdiff2));      }      if (bdiff3 == 0)          p[m-wdiff3] ^= w;      else {         pp = &p[m-wdiff3];         *pp ^= (w >> bdiff3);         *(pp-1) ^= (w << (NTL_BITS_PER_LONG-bdiff3));      }      m--;   }   w = (p[m] >> bn) << bn;   p[0] ^= (w >> bn);    if (bdiff1 == 0)      p[m-wdiff1] ^= w;   else {      p[m-wdiff1] ^= (w >> bdiff1);      if (m-wdiff1-1 >= 0) p[m-wdiff1-1] ^= (w << (NTL_BITS_PER_LONG-bdiff1));   }   if (bdiff2 == 0)      p[m-wdiff2] ^= w;   else {      p[m-wdiff2] ^= (w >> bdiff2);      if (m-wdiff2-1 >= 0) p[m-wdiff2-1] ^= (w << (NTL_BITS_PER_LONG-bdiff2));   }   if (bdiff3 == 0)      p[m-wdiff3] ^= w;   else {      p[m-wdiff3] ^= (w >> bdiff3);      if (m-wdiff3-1 >= 0) p[m-wdiff3-1] ^= (w << (NTL_BITS_PER_LONG-bdiff3));   }   if (bn != 0)      p[m] &= ((1UL<<bn)-1UL);      if (bn == 0)      wn--;   while (wn >= 0 && p[wn] == 0)      wn--;   r.xrep.QuickSetLength(wn+1);   x = r;}staticvoid RightShiftAdd(GF2X& c, const GF2X& a, long n){   if (n < 0) {      Error("RightShiftAdd: negative shamt");   }   if (n == 0) {      add(c, c, a);      return;   }   long sa = a.xrep.length();   long wn = n/NTL_BITS_PER_LONG;   long bn = n - wn*NTL_BITS_PER_LONG;   if (wn >= sa) {      return;   }   long sc = c.xrep.length();   long i;   if (sa-wn > sc)      c.xrep.SetLength(sa-wn);   _ntl_ulong *cp = c.xrep.elts();   const _ntl_ulong *ap = a.xrep.elts();   for (i = sc; i < sa-wn; i++)      cp[i] = 0;   if (bn == 0) {      for (i = 0; i < sa-wn; i++)         cp[i] ^= ap[i+wn];   }   else {      for (i = 0; i < sa-wn-1; i++)         cp[i] ^= (ap[i+wn] >> bn) | (ap[i+wn+1] << (NTL_BITS_PER_LONG - bn));      cp[sa-wn-1] ^= ap[sa-1] >> bn;   }   c.normalize();}staticvoid TriDiv21(GF2X& q, const GF2X& a, long n, long k){   GF2XRegister(P1);   RightShift(P1, a, n);   if (k != 1)       RightShiftAdd(P1, P1, n-k);   q = P1;}static void TriDivRem21(GF2X& q, GF2X& r, const GF2X& a, long n, long k){   GF2XRegister(Q);   TriDiv21(Q, a, n, k);   TrinomReduce(r, a, n, k);   q = Q;}staticvoid PentDiv21(GF2X& q, const GF2X& a, long n, long k3, long k2, long k1){   if (deg(a) < n) {      clear(q);      return;   }   GF2XRegister(P1);   GF2XRegister(P2);   RightShift(P1, a, n);      RightShift(P2, P1, n-k3);   RightShiftAdd(P2, P1, n-k2);   if (k1 != 1) {      RightShiftAdd(P2, P1, n-k1);   }   add(P2, P2, P1);   q = P2;}static void PentDivRem21(GF2X& q, GF2X& r, const GF2X& a, long n,                   long k3, long k2, long k1){   GF2XRegister(Q);   PentDiv21(Q, a, n, k3, k2, k1);   PentReduce(r, a, n, k3, k2, k1);   q = Q;}staticvoid TriDivRemX1(GF2X& q, GF2X& r, const GF2X& aa, long n, long k){   GF2XRegister(buf);   GF2XRegister(tmp);   GF2XRegister(a);   GF2XRegister(qq);   GF2XRegister(qbuf);   clear(buf);   a = aa;   clear(qq);   long a_len = deg(a) + 1;   while (a_len > 0) {      long old_buf_len = deg(buf) + 1;      long amt = min(2*n-1-old_buf_len, a_len);      LeftShift(buf, buf, amt);      RightShift(tmp, a, a_len-amt);      add(buf, buf, tmp);      trunc(a, a, a_len-amt);      TriDivRem21(qbuf, buf, buf, n, k);      a_len -= amt;      ShiftAdd(qq, qbuf, a_len);   }   r = buf;   q = qq;}staticvoid TriDivX1(GF2X& q, const GF2X& aa, long n, long k){   GF2XRegister(buf);   GF2XRegister(tmp);   GF2XRegister(a);   GF2XRegister(qq);   GF2XRegister(qbuf);      clear(buf);   a = aa;   clear(qq);   long a_len = deg(a) + 1;   while (a_len > 0) {      long old_buf_len = deg(buf) + 1;      long amt = min(2*n-1-old_buf_len, a_len);      LeftShift(buf, buf, amt);      RightShift(tmp, a, a_len-amt);      add(buf, buf, tmp);      trunc(a, a, a_len-amt);      TriDivRem21(qbuf, buf, buf, n, k);      a_len -= amt;      ShiftAdd(qq, qbuf, a_len);   }   q = qq;}staticvoid PentDivRemX1(GF2X& q, GF2X& r, const GF2X& aa, long n,                   long k3, long k2, long k1){   GF2XRegister(buf);   GF2XRegister(tmp);   GF2XRegister(a);   GF2XRegister(qq);   GF2XRegister(qbuf);   clear(buf);   a = aa;   clear(qq);   long a_len = deg(a) + 1;   while (a_len > 0) {      long old_buf_len = deg(buf) + 1;      long amt = min(2*n-1-old_buf_len, a_len);      LeftShift(buf, buf, amt);      RightShift(tmp, a, a_len-amt);      add(buf, buf, tmp);      trunc(a, a, a_len-amt);      PentDivRem21(qbuf, buf, buf, n, k3, k2, k1);      a_len -= amt;      ShiftAdd(qq, qbuf, a_len);   }   r = buf;   q = qq;}staticvoid PentDivX1(GF2X& q, const GF2X& aa, long n, long k3, long k2, long k1){   GF2XRegister(buf);   GF2XRegister(tmp);   GF2XRegister(a);   GF2XRegister(qq);   GF2XRegister(qbuf);      clear(buf);   a = aa;   clear(qq);   long a_len = deg(a) + 1;   while (a_len > 0) {      long old_buf_len = deg(buf) + 1;      long amt = min(2*n-1-old_buf_len, a_len);      LeftShift(buf, buf, amt);      RightShift(tmp, a, a_len-amt);      add(buf, buf, tmp);      trunc(a, a, a_len-amt);      PentDivRem21(qbuf, buf, buf, n, k3, k2, k1);      a_len -= amt;      ShiftAdd(qq, qbuf, a_len);   }   q = qq;}void rem(GF2X& r, const GF2X& a, const GF2XModulus& F){   long n = F.n;   if (n < 0) Error("rem: uninitialized modulus");   if (F.method == GF2X_MOD_TRI) {      TrinomReduce(r, a, n, F.k3);      return;   }   if (F.method == GF2X_MOD_PENT) {      PentReduce(r, a, n, F.k3, F.k2, F.k1);      return;   }   long da = deg(a);   if (da < n) {      r = a;   }   else if (F.method == GF2X_MOD_MUL) {      if (da <= 2*(n-1))          UseMulRem21(r, a, F);      else         UseMulRemX1(r, a, F);   }   else if (F.method == GF2X_MOD_SPECIAL) {      long sa = a.xrep.length();      long posa = da - NTL_BITS_PER_LONG*(sa-1);         _ntl_ulong *ap;      if (&r == &a)         ap = r.xrep.elts();      else {         GF2X_rembuf = a.xrep;         ap = GF2X_rembuf.elts();      }         _ntl_ulong *atop = &ap[sa-1];      _ntl_ulong *stab_top;         long i;         while (da >= n) {         if (atop[0] & (1UL << posa)) {            stab_top = &F.stab1[posa << 1];            i = F.stab_cnt[posa];            atop[i] ^= stab_top[0];            atop[i+1] ^= stab_top[1];         }            da--;         posa--;         if (posa < 0) {            posa = NTL_BITS_PER_LONG-1;            atop--;         }      }         long sn = F.size;      r.xrep.SetLength(sn);      if (&r != &a) {         _ntl_ulong *rp = r.xrep.elts();         for (i = 0; i < sn; i++)            rp[i] = ap[i];      }      r.xrep[sn-1] &= F.msk;      r.normalize();   }   else {      long sa = a.xrep.length();      long posa = da - NTL_BITS_PER_LONG*(sa-1);            _ntl_ulong *ap;      if (&r == &a)         ap = r.xrep.elts();      else {         GF2X_rembuf = a.xrep;         ap = GF2X_rembuf.elts();      }         _ntl_ulong *atop = &ap[sa-1];      _ntl_ulong *stab_top;         long i;         while (da >= n) {         if (atop[0] & (1UL << posa)) {            stab_top = F.stab_ptr[posa];            for (i = F.stab_cnt[posa]; i <= 0; i++)               atop[i] ^= stab_top[i];         }            da--;         posa--;         if (posa < 0) {            posa = NTL_BITS_PER_LONG-1;            atop--;         }      }         long sn = F.size;      r.xrep.SetLength(sn);      if (&r != &a) {         _ntl_ulong *rp = r.xrep.elts();         for (i = 0; i < sn; i++)            rp[i] = ap[i];      }      r.normalize();   }}void DivRem(GF2X& q, GF2X& r, const GF2X& a, const GF2XModulus& F){   long da = deg(a);   long n = F.n;   if (n < 0) Error("DivRem: uninitialized modulus");   if (da < n) {      r = a;      clear(q);   }   else if (F.method == GF2X_MOD_TRI) {      if (da <= 2*(n-1))          TriDivRem21(q, r, a, F.n, F.k3);      else         TriDivRemX1(q, r, a, F.n, F.k3);   }   else if (F.method == GF2X_MOD_PENT) {      if (da <= 2*(n-1))          PentDivRem21(q, r, a, F.n, F.k3, F.k2, F.k1);      else         PentDivRemX1(q, r, a, F.n, F.k3, F.k2, F.k1);   }   else if (F.method == GF2X_MOD_MUL) {      if (da <= 2*(n-1))          UseMulDivRem21(q, r, a, F);      else         UseMulDivRemX1(q, r, a, F);   }   else if (F.method == GF2X_MOD_SPECIAL) {      long sa = a.xrep.length();      long posa = da - NTL_BITS_PER_LONG*(sa-1);         long dq = da - n;      long sq = dq/NTL_BITS_PER_LONG + 1;      long posq = dq - NTL_BITS_PER_LONG*(sq-1);         _ntl_ulong *ap;      if (&r == &a)         ap = r.xrep.elts();      else {         GF2X_rembuf = a.xrep;         ap = GF2X_rembuf.elts();      }         _ntl_ulong *atop = &ap[sa-1];      _ntl_ulong *stab_top;      long i;      q.xrep.SetLength(sq);      _ntl_ulong *qp = q.xrep.elts();      for (i = 0; i < sq; i++)         qp[i] = 0;      _ntl_ulong *qtop = &qp[sq-1];         while (da >= n) {         if (atop[0] & (1UL << posa)) {            qtop[0] |= (1UL << posq);            stab_top = &F.stab1[posa << 1];            i = F.stab_cnt[posa];            atop[i] ^= stab_top[0];            atop[i+1] ^= stab_top[1];         }            da--;         posa--;         if (posa < 0) {            posa = NTL_BITS_PER_LONG-1;            atop--;         }         posq--;         if (posq < 0) {            posq = NTL_BITS_PER_LONG-1;            qtop--;         }      }         long sn = F.size;      r.xrep.SetLength(sn);      if (&r != &a) {         _ntl_ulong *rp = r.xrep.elts();         for (i = 0; i < sn; i++)            rp[i] = ap[i];      }      r.xrep[sn-1] &= F.msk;      r.normalize();   }   else {      long sa = a.xrep.length();      long posa = da - NTL_BITS_PER_LONG*(sa-1);         long dq = da - n;      long sq = dq/NTL_BITS_PER_LONG + 1;      long posq = dq - NTL_BITS_PER_LONG*(sq-1);         _ntl_ulong *ap;      if (&r == &a)         ap = r.xrep.elts();      else {         GF2X_rembuf = a.xrep;         ap = GF2X_rembuf.elts();      }         _ntl_ulong *atop = &ap[sa-1];      _ntl_ulong *stab_top;         long i;      q.xrep.SetLength(sq);      _ntl_ulong *qp = q.xrep.elts();      for (i = 0; i < sq; i++)         qp[i] = 0;      _ntl_ulong *qtop = &qp[sq-1];         while (da >= n) {         if (atop[0] & (1UL << posa)) {            qtop[0] |= (1UL << posq);            stab_top = F.stab_ptr[posa];            for (i = F.stab_cnt[posa]; i <= 0; i++)               atop[i] ^= stab_top[i];         }            da--;         posa--;         if (posa < 0) {            posa = NTL_BITS_PER_LONG-1;            atop--;         }         posq--;         if (posq < 0) {            posq = NTL_BITS_PER_LONG-1;            qtop--;         }      }         long sn = F.size;      r.xrep.SetLength(sn);      if (&r != &a) {         _ntl_ulong *rp = r.xrep.elts();         for (i = 0; i < sn; i++)            rp[i] = ap[i];      }      r.normalize();   }}void div(GF2X& q, const GF2X& a, const GF2XModulus& F){   long da = deg(a);   long n = F.n;   if (n < 0) Error("div: uninitialized modulus");   if (da < n) {      clear(q);   }   else if (F.method == GF2X_MOD_TRI) {      if (da <= 2*(n-1))          TriDiv21(q, a, F.n, F.k3);      else         TriDivX1(q, a, F.n, F.k3);   }   else if (F.method == GF2X_MOD_PENT) {      if (da <= 2*(n-1))          PentDiv21(q, a, F.n, F.k3, F.k2, F.k1);      else         PentDivX1(q, a, F.n, F.k3, F.k2, F.k1);   }   else if (F.method == GF2X_MOD_MUL) {      if (da <= 2*(n-1))          UseMulDiv21(q, a, F);      else         UseMulDivX1(q, a, F);   }   else if (F.method == GF2X_MOD_SPECIAL) {      long sa = a.xrep.length();      long posa = da - NTL_BITS_PER_LONG*(sa-1);         long dq = da - n;      long sq = dq/NTL_BITS_PER_LONG + 1;      long posq = dq - NTL_BITS_PER_LONG*(sq-1);         _ntl_ulong *ap;      GF2X_rembuf = a.xrep;      ap = GF2X_rembuf.elts();

⌨️ 快捷键说明

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