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

📄 lll_rr.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <NTL/LLL.h>#include <NTL/fileio.h>#include <NTL/new.h>NTL_START_IMPLstatic void RowTransform(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1)// x = x - y*MU{   static ZZ T, MU;   long k;   long n = A.length();   long i;   MU = MU1;   if (MU == 1) {      for (i = 1; i <= n; i++)         sub(A(i), A(i), B(i));      return;   }   if (MU == -1) {      for (i = 1; i <= n; i++)         add(A(i), A(i), B(i));      return;   }   if (MU == 0) return;   if (NumTwos(MU) >= NTL_ZZ_NBITS)       k = MakeOdd(MU);   else      k = 0;   if (MU.WideSinglePrecision()) {      long mu1;      conv(mu1, MU);      for (i = 1; i <= n; i++) {         mul(T, B(i), mu1);         if (k > 0) LeftShift(T, T, k);         sub(A(i), A(i), T);      }   }   else {      for (i = 1; i <= n; i++) {         mul(T, B(i), MU);         if (k > 0) LeftShift(T, T, k);         sub(A(i), A(i), T);      }   }}static void RowTransform2(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1)// x = x + y*MU{   static ZZ T, MU;   long k;   long n = A.length();   long i;   MU = MU1;   if (MU == 1) {      for (i = 1; i <= n; i++)         add(A(i), A(i), B(i));      return;   }   if (MU == -1) {      for (i = 1; i <= n; i++)         sub(A(i), A(i), B(i));      return;   }   if (MU == 0) return;   if (NumTwos(MU) >= NTL_ZZ_NBITS)       k = MakeOdd(MU);   else      k = 0;   if (MU.WideSinglePrecision()) {      long mu1;      conv(mu1, MU);      for (i = 1; i <= n; i++) {         mul(T, B(i), mu1);         if (k > 0) LeftShift(T, T, k);         add(A(i), A(i), T);      }   }   else {      for (i = 1; i <= n; i++) {         mul(T, B(i), MU);         if (k > 0) LeftShift(T, T, k);         add(A(i), A(i), T);      }   }}void ComputeGS(const mat_ZZ& B, mat_RR& B1,                mat_RR& mu, vec_RR& b,                vec_RR& c, long k, const RR& bound, long st,                vec_RR& buf, const RR& bound2){   long i, j;   RR s, t, t1;   ZZ T1;   if (st < k) {      for (i = 1; i < st; i++)         mul(buf(i), mu(k,i), c(i));   }   for (j = st; j <= k-1; j++) {      InnerProduct(s, B1(k), B1(j));      sqr(t1, s);      mul(t1, t1, bound);      mul(t, b(k), b(j));      if (t >= bound2 && t >= t1) {         InnerProduct(T1, B(k), B(j));         conv(s, T1);      }      clear(t1);      for (i = 1; i <= j-1; i++) {         mul(t, mu(j, i), buf(i));         add(t1, t1, t);      }      sub(t, s, t1);      buf(j) = t;      div(mu(k, j), t, c(j));   }   clear(s);   for (j = 1; j <= k-1; j++) {      mul(t, mu(k, j), buf(j));      add(s, s, t);   }   sub(c(k), b(k), s);}static RR red_fudge;static long log_red = 0;static void init_red_fudge(){   log_red = long(0.50*RR::precision());   power2(red_fudge, -log_red);}static void inc_red_fudge(){   mul(red_fudge, red_fudge, 2);   log_red--;   cerr << "LLL_RR: warning--relaxing reduction (" << log_red << ")\n";   if (log_red < 4)      Error("LLL_RR: can not continue...sorry");}static long verbose = 0;static unsigned long NumSwaps = 0;static double StartTime = 0;static double LastTime = 0;static void LLLStatus(long max_k, double t, long m, const mat_ZZ& B){   cerr << "---- LLL_RR status ----\n";   cerr << "elapsed time: ";   PrintTime(cerr, t-StartTime);   cerr << ", stage: " << max_k;   cerr << ", rank: " << m;   cerr << ", swaps: " << NumSwaps << "\n";   ZZ t1;   long i;   double prodlen = 0;   for (i = 1; i <= m; i++) {      InnerProduct(t1, B(i), B(i));      if (!IsZero(t1))         prodlen += log(t1);   }   cerr << "log of prod of lengths: " << prodlen/(2.0*log(2.0)) << "\n";   if (LLLDumpFile) {      cerr << "dumping to " << LLLDumpFile << "...";      ofstream f;      OpenWrite(f, LLLDumpFile);            f << "[";      for (i = 1; i <= m; i++) {         f << B(i) << "\n";      }      f << "]\n";      f.close();      cerr << "\n";   }   LastTime = t;   }staticlong ll_LLL_RR(mat_ZZ& B, mat_ZZ* U, const RR& delta, long deep,            LLLCheckFct check, mat_RR& B1, mat_RR& mu,            vec_RR& b, vec_RR& c, long m, long init_k, long &quit){   long n = B.NumCols();   long i, j, k, Fc1;   ZZ MU;   RR mu1, t1, t2, cc;   ZZ T1;   RR bound;      // we tolerate a 15% loss of precision in computing      // inner products in ComputeGS.   power2(bound, 2*long(0.15*RR::precision()));   RR bound2;   power2(bound2, 2*RR::precision());   quit = 0;   k = init_k;   vec_long st_mem;   st_mem.SetLength(m+2);   long *st = st_mem.elts();   for (i = 1; i < k; i++)      st[i] = i;   for (i = k; i <= m+1; i++)      st[i] = 1;   vec_RR buf;   buf.SetLength(m);   long rst;   long counter;   long trigger_index;   long small_trigger;   long cnt;   RR half;   conv(half,  0.5);   RR half_plus_fudge;   add(half_plus_fudge, half, red_fudge);   long max_k = 0;   double tt;   while (k <= m) {      if (k > max_k) {         max_k = k;      }      if (verbose) {         tt = GetTime();         if (tt > LastTime + LLLStatusInterval)            LLLStatus(max_k, tt, m, B);      }      if (st[k] == k)         rst = 1;      else         rst = k;      if (st[k] < st[k+1]) st[k+1] = st[k];      ComputeGS(B, B1, mu, b, c, k, bound, st[k], buf, bound2);      st[k] = k;      counter = 0;      trigger_index = k;      small_trigger = 0;      cnt = 0;      do {         // size reduction         counter++;         if (counter > 10000) {            cerr << "LLL_XD: warning--possible infinite loop\n";            counter = 0;         }         Fc1 = 0;         for (j = rst-1; j >= 1; j--) {            abs(t1, mu(k,j));            if (t1 > half_plus_fudge) {               if (!Fc1) {                  if (j > trigger_index ||                      (j == trigger_index && small_trigger)) {                     cnt++;                     if (cnt > 10) {                        inc_red_fudge();                        add(half_plus_fudge, half, red_fudge);                        cnt = 0;                     }                  }                  trigger_index = j;                  small_trigger = (t1 < 4);               }               Fc1 = 1;                  mu1 = mu(k,j);               if (sign(mu1) >= 0) {                  sub(mu1, mu1, half);                  ceil(mu1, mu1);               }               else {                  add(mu1, mu1, half);                  floor(mu1, mu1);               }               if (mu1 == 1) {                  for (i = 1; i <= j-1; i++)                     sub(mu(k,i), mu(k,i), mu(j,i));               }               else if (mu1 == -1) {                  for (i = 1; i <= j-1; i++)                     add(mu(k,i), mu(k,i), mu(j,i));               }               else {                  for (i = 1; i <= j-1; i++) {                     mul(t2, mu1, mu(j,i));                     sub(mu(k,i), mu(k,i), t2);                  }               }                  conv(MU, mu1);               sub(mu(k,j), mu(k,j), mu1);                  RowTransform(B(k), B(j), MU);               if (U) RowTransform((*U)(k), (*U)(j), MU);            }         }         if (Fc1) {            for (i = 1; i <= n; i++)               conv(B1(k, i), B(k, i));               InnerProduct(b(k), B1(k), B1(k));            ComputeGS(B, B1, mu, b, c, k, bound, 1, buf, bound2);         }      } while (Fc1);      if (check && (*check)(B(k)))          quit = 1;      if (IsZero(b(k))) {         for (i = k; i < m; i++) {            // swap i, i+1            swap(B(i), B(i+1));            swap(B1(i), B1(i+1));            swap(b(i), b(i+1));            if (U) swap((*U)(i), (*U)(i+1));         }         for (i = k; i <= m+1; i++) st[i] = 1;         m--;         if (quit) break;         continue;      }      if (quit) break;      if (deep > 0) {         // deep insertions            cc = b(k);         long l = 1;         while (l <= k-1) {             mul(t1, delta, c(l));            if (t1 > cc) break;            sqr(t1, mu(k,l));            mul(t1, t1, c(l));            sub(cc, cc, t1);            l++;         }            if (l <= k-1 && (l <= deep || k-l <= deep)) {            // deep insertion at position l               for (i = k; i > l; i--) {               // swap rows i, i-1               swap(B(i), B(i-1));               swap(B1(i), B1(i-1));               swap(mu(i), mu(i-1));               swap(b(i), b(i-1));               if (U) swap((*U)(i), (*U)(i-1));            }               k = l;            continue;         }      } // end deep insertions      // test LLL reduction condition      if (k <= 1) {         k++;      }      else {         sqr(t1, mu(k,k-1));         mul(t1, t1, c(k-1));         add(t1, t1, c(k));         mul(t2, delta, c(k-1));         if (t2 > t1) {            // swap rows k, k-1            swap(B(k), B(k-1));            swap(B1(k), B1(k-1));            swap(mu(k), mu(k-1));            swap(b(k), b(k-1));            if (U) swap((*U)(k), (*U)(k-1));               k--;            NumSwaps++;         }         else {            k++;         }      }   }   if (verbose) {      LLLStatus(m+1, GetTime(), m, B);   }   return m;}staticlong LLL_RR(mat_ZZ& B, mat_ZZ* U, const RR& delta, long deep,            LLLCheckFct check){   long m = B.NumRows();   long n = B.NumCols();   long i, j;   long new_m, dep, quit;   RR s;   ZZ MU;   RR mu1;   RR t1;   ZZ T1;   init_red_fudge();   if (U) ident(*U, m);   mat_RR B1;  // approximates B   B1.SetDims(m, n);   mat_RR mu;   mu.SetDims(m, m);   vec_RR c;  // squared lengths of Gramm-Schmidt basis vectors   c.SetLength(m);   vec_RR b; // squared lengths of basis vectors   b.SetLength(m);   for (i = 1; i <=m; i++)      for (j = 1; j <= n; j++)          conv(B1(i, j), B(i, j));            for (i = 1; i <= m; i++) {      InnerProduct(b(i), B1(i), B1(i));   }   new_m = ll_LLL_RR(B, U, delta, deep, check, B1, mu, b, c, m, 1, quit);   dep = m - new_m;   m = new_m;   if (dep > 0) {      // for consistency, we move all of the zero rows to the front      for (i = 0; i < m; i++) {         swap(B(m+dep-i), B(m-i));         if (U) swap((*U)(m+dep-i), (*U)(m-i));      }   }   return m;}         long LLL_RR(mat_ZZ& B, double delta, long deep,             LLLCheckFct check, long verb){   verbose = verb;   NumSwaps = 0;   if (verbose) {      StartTime = GetTime();      LastTime = StartTime;   }   if (delta < 0.50 || delta >= 1) Error("LLL_RR: bad delta");   if (deep < 0) Error("LLL_RR: bad deep");   RR Delta;   conv(Delta, delta);   return LLL_RR(B, 0, Delta, deep, check);}long LLL_RR(mat_ZZ& B, mat_ZZ& U, double delta, long deep,            LLLCheckFct check, long verb){   verbose = verb;   NumSwaps = 0;   if (verbose) {      StartTime = GetTime();      LastTime = StartTime;   }   if (delta < 0.50 || delta >= 1) Error("LLL_RR: bad delta");   if (deep < 0) Error("LLL_RR: bad deep");   RR Delta;   conv(Delta, delta);   return LLL_RR(B, &U, Delta, deep, check);}static vec_RR BKZConstant;staticvoid ComputeBKZConstant(long beta, long p){   RR c_PI;   ComputePi(c_PI);   RR LogPI = log(c_PI);   BKZConstant.SetLength(beta-1);   vec_RR Log;   Log.SetLength(beta);   long i, j, k;   RR x, y;   for (j = 1; j <= beta; j++)      Log(j) = log(to_RR(j));   for (i = 1; i <= beta-1; i++) {      // First, we compute x = gamma(i/2)^{2/i}      k = i/2;      if ((i & 1) == 0) { // i even         x = 0;         for (j = 1; j <= k; j++)            x += Log(j);                   x = exp(x/k);      }      else { // i odd         x = 0;         for (j = k + 2; j <= 2*k + 2; j++)            x += Log(j);         x += 0.5*LogPI - 2*(k+1)*Log(2);         x = exp(2*x/i);      }      // Second, we compute y = 2^{2*p/i}      y = exp(-(2*p/to_RR(i))*Log(2));      BKZConstant(i) = x*y/c_PI;   }}static vec_RR BKZThresh;static void ComputeBKZThresh(RR *c, long beta){   BKZThresh.SetLength(beta-1);   long i;   RR x;   RR t1;   x = 0;   for (i = 1; i <= beta-1; i++) {      log(t1, c[i-1]);      add(x, x, t1);      div(t1, x, i);      exp(t1, t1);      mul(BKZThresh(i), t1, BKZConstant(i));   }}static 

⌨️ 快捷键说明

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