void transpose(mat_ZZ& X, const mat_ZZ& A) { long n = A.NumRows(); long m = A.NumCols(); long i, j; if (&X == & A) { if (n == m) for (i = 1; i <= n; i++) for (j = i+1; j <= n; j++) swap(X(i, j), X(j, i)); else { mat_ZZ tmp; tmp.SetDims(m, n); for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) tmp(j, i) = A(i, j); X.kill(); X = tmp; } } else { X.SetDims(m, n); for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) X(j, i) = A(i, j); } }
void mul_aux(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B) { long n = A.NumRows(); long l = A.NumCols(); long m = B.NumCols(); if (l != B.NumRows()) Error("matrix mul: dimension mismatch"); X.SetDims(n, m); long i, j, k; ZZ acc, tmp; for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { clear(acc); for(k = 1; k <= l; k++) { mul(tmp, A(i,k), B(k,j)); add(acc, acc, tmp); } X(i,j) = acc; } } }
void gen_svpchallenge(mat_ZZ& B,int n,ZZ seed,int bit=10) { vec_ZZ v; generate_random_HNF(v,n,bit,seed); B.SetDims(n,n); clear(B); B(1,1) = v(1); for (int i=2; i<=n; i++) { B(i,1)=v(i); B(i,i)=1; } }
void mul(mat_ZZ& X, const mat_ZZ& A, long b) { long n = A.NumRows(); long m = A.NumCols(); X.SetDims(n, m); long i, j; for (i = 0; i < n; i++) for (j = 0; j < m; j++) mul(X[i][j], A[i][j], b); }
void ident(mat_ZZ& X, long n) { X.SetDims(n, n); long i, j; for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (i == j) set(X(i, j)); else clear(X(i, j)); }
void negate(mat_ZZ& X, const mat_ZZ& A) { long n = A.NumRows(); long m = A.NumCols(); X.SetDims(n, m); long i, j; for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) negate(X(i,j), A(i,j)); }
void diag(mat_ZZ& X, long n, const ZZ& d_in) { ZZ d = d_in; X.SetDims(n, n); long i, j; for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (i == j) X(i, j) = d; else clear(X(i, j)); }
void gen_randlat(mat_ZZ& basis, ZZ determinant, int dim) { basis.SetDims(dim, dim); ZZ s; s= time(NULL); SetSeed(s); for(int i= 0; i < dim; i++) { basis[i][0]= RandomBnd(determinant); basis[i][i]= 1; } basis[0][0]= determinant; }
void sub(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B) { long n = A.NumRows(); long m = A.NumCols(); if (B.NumRows() != n || B.NumCols() != m) Error("matrix sub: dimension mismatch"); X.SetDims(n, m); long i, j; for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) sub(X(i,j), A(i,j), B(i,j)); }
void HNF(mat_ZZ& W, const mat_ZZ& A_in, const ZZ& D_in) { mat_ZZ A = A_in; long n = A.NumRows(); long m = A.NumCols(); ZZ D = D_in; if (D < 0) negate(D, D); if (n == 0 || m == 0 || D == 0) Error("HNF: bad input"); W.SetDims(m, m); clear(W); long i, j, k; ZZ d, u, v, c1, c2; k = n; for (i = m; i >= 1; i--) { for (j = k-1; j >= 1; j--) { if (A(j, i) != 0) { XGCD(d, u, v, A(k, i), A(j, i)); div(c1, A(k, i), d); div(c2, A(j, i), d); negate(c2, c2); EuclUpdate(A(j), A(k), c1, c2, v, u, D); } } XGCD(d, u, v, A(k, i), D); FixDiag(W(i), u, A(k), D, i); if (W(i, i) == 0) W(i, i) = D; for (j = i+1; j <= m; j++) { div(c1, W(j, i), W(i, i)); ReduceW(W(j), c1, W(i), D, i); } div(D, D, d); k--; } }
NTL_START_IMPL void add(mat_ZZ& X, const mat_ZZ& A, const mat_ZZ& B) { long n = A.NumRows(); long m = A.NumCols(); if (B.NumRows() != n || B.NumCols() != m) LogicError("matrix add: dimension mismatch"); X.SetDims(n, m); long i, j; for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) add(X(i,j), A(i,j), B(i,j)); }
//Ideal lattice challenge problem generator //modified from generate_ideal.cpp in Ideal lattice Challenge web page void gen_idealsvpchallenge(mat_ZZ& B,int index,ZZ seed,vec_ZZ& phivec) { ZZX phi=find_cyclotomic(index); long n=deg(phi); ZZ det=find_determinant(index,10*n,seed); ZZ alpha=find_unity_root(index,det,phi); B.SetDims(n,n); clear(B); B(1,1) = det; for (long i=2; i<=n; i++) { B(i,1)=det-PowerMod(alpha,i-1,det); B(i,i)=1; } phivec.SetLength(n+1); for (int i=0;i<=n;i++) phivec[i] = coeff(phi,i); }
void inv(ZZ& d_out, mat_ZZ& x_out, const mat_ZZ& A, long deterministic) { long n = A.NumRows(); if (A.NumCols() != n) Error("solve: nonsquare matrix"); if (n == 0) { set(d_out); x_out.SetDims(0, 0); return; } zz_pBak zbak; zbak.save(); ZZ_pBak Zbak; Zbak.save(); mat_ZZ x(INIT_SIZE, n, n); ZZ d, d1; ZZ d_prod, x_prod; set(d_prod); set(x_prod); long d_instable = 1; long x_instable = 1; long gp_cnt = 0; long check = 0; mat_ZZ y; long i; long bound = 2+DetBound(A); for (i = 0; ; i++) { if ((check || IsZero(d)) && !d_instable) { if (NumBits(d_prod) > bound) { break; } else if (!deterministic && bound > 1000 && NumBits(d_prod) < 0.25*bound) { ZZ P; long plen = 90 + NumBits(max(bound, NumBits(d))); GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p AA; conv(AA, A); ZZ_p dd; determinant(dd, AA); if (CRT(d, d_prod, rep(dd), P)) d_instable = 1; else break; } } zz_p::FFTInit(i); long p = zz_p::modulus(); mat_zz_p AA; conv(AA, A); if (!check) { mat_zz_p xx; zz_p dd; inv(dd, xx, AA); d_instable = CRT(d, d_prod, rep(dd), p); if (!IsZero(dd)) { mul(xx, xx, dd); x_instable = CRT(x, x_prod, xx); } else x_instable = 1; if (!d_instable && !x_instable) { mul(y, x, A); if (IsDiag(y, n, d)) { d1 = d; check = 1; } } } else { zz_p dd; determinant(dd, AA); d_instable = CRT(d, d_prod, rep(dd), p); } } if (check && d1 != d) { mul(x, x, d); ExactDiv(x, d1); } d_out = d; if (check) x_out = x; zbak.restore(); Zbak.restore(); }