📄 lll_rr.c
字号:
#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 + -