Example #1
0
/**
 * muGSO
 * \brief on input B returnes a lower-triangular matrix mu such that B = mu*Q,
 *        with <b_i^*, b_i^*> / ||b_i^*|| = 1 on the main diagonal,
 *        Q - matrix with orthonormal rows.
 *
 * @params B the basis
 */
matrix<double> muGSO(matrix<long> const &B_std) {
	Mat<ZZ> B = to_ntl<ZZ>(B_std);
	Mat<RR> B_star;
	Mat<RR> muGSO;
	muGSO.SetDims(B.NumRows(), B.NumCols());
	B_star.SetDims(B.NumRows(), B.NumCols());
	if (B.NumRows() > 0) {
		for (long i = 0; i < B.NumRows(); ++i) {
			B_star[i] = conv<Vec<RR>>(B[i]);
			for (long j = 0; j < i; ++j) {
				RR num; num = 0;
				RR denom; denom = 0;

				InnerProduct(num, B_star[j], conv<Vec<RR>>(B[i]));
				InnerProduct(denom, B_star[j], B_star[j]);

				muGSO[i][j] = num / denom;
				B_star[i] = B_star[i] - muGSO[i][j] * B_star[j];
			}
			// InnerProduct(muGSO[i][i], B_star[i], B_star[i]);
			muGSO[i][i] = 1;
		}
	}
	return to_stl<double>(muGSO);
}
Example #2
0
Mat<ZZ> CreateLPerp(Mat<ZZ> const &A, int n, int m, long q, double sigma) {
	Mat<ZZ> LPerp;
	LPerp.SetDims(2 * n + m, n + m);

	Mat<ZZ> qI;
	diag(qI, n + m, conv<ZZ>(q));

	ZZ factor = (2 * conv<ZZ>(sigma));

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n + m; j++) {
			if (j < m)
				LPerp[i][j] = -A[i][j] % q;
			if (j - i == m)
				LPerp[i][j] = factor;
		}
	}

	for (int i = n; i < 2 * n + m; i++) {
		for (int j = 0; j < n + m; j++)
			if (j < m)
				LPerp[i][j] = qI[i - n][j];
			else
				LPerp[i][j] = factor * qI[i - n][j];
	}

	return LPerp;
}
Example #3
0
static
void RawConvertTranspose(Mat<zz_p>& X, const Mat<MatPrime_residue_t>& A)
{
   long n = A.NumRows();
   long m = A.NumCols();

   X.SetDims(m, n);
   for (long i = 0; i < n; i++) {
      const MatPrime_residue_t *Ai = A[i].elts();
      for (long j = 0; j < m; j++)
         X[j][i] = Ai[j];
   }
} 
Example #4
0
static
void mul_aux(Mat<zz_pE>& X, const Mat<zz_pE>& A, const Mat<zz_pE>& B)  
{  
   long n = A.NumRows();  
   long l = A.NumCols();  
   long m = B.NumCols();  
  
   if (l != B.NumRows())  
      LogicError("matrix mul: dimension mismatch");  
  
   X.SetDims(n, m);  


   zz_pContext zz_p_context;
   zz_p_context.save();
   zz_pEContext zz_pE_context;
   zz_pE_context.save();
   double sz = zz_pE_SizeInWords();

   bool seq = (double(n)*double(l)*double(m)*sz*sz < PAR_THRESH);

   NTL_GEXEC_RANGE(seq, m, first, last)
   NTL_IMPORT(n)
   NTL_IMPORT(l)
   NTL_IMPORT(m)

   zz_p_context.restore();
   zz_pE_context.restore();

   long i, j, k;  
   zz_pX acc, tmp;  

   Vec<zz_pE> B_col;
   B_col.SetLength(l);

   for (j = first; j < last; j++) {
      for (k = 0; k < l; k++) B_col[k] = B[k][j];

      for (i = 0; i < n; i++) {
         clear(acc);
         for (k = 0; k < l; k++) {
            mul(tmp, rep(A[i][k]), rep(B_col[k]));
            add(acc, acc, tmp);
         }
         conv(X[i][j], acc);
      }
   }

   NTL_GEXEC_RANGE_END
}  
Example #5
0
static
void RawConvert(Mat<MatPrime_residue_t>& X, const Mat<zz_p>& A)
{
   long n = A.NumRows();
   long m = A.NumCols();

   X.SetDims(n, m);
   for (long i = 0; i < n; i++) {
      const zz_p *Ai = A[i].elts();
      MatPrime_residue_t *Xi = X[i].elts();
      for (long j = 0; j < m; j++)
         Xi[j] = rep(Ai[j]);
   }
} 
Example #6
0
Mat<ZZ> PadMatrix(Mat<ZZ> A, long q, int m, int n) {
	Mat<ZZ> res;
	Mat<ZZ> qI;
	res.SetDims(m + n, m);

	A = transpose(A);

	for (int i = 0; i < n; i++) {
		res[i] = A[i];
	}

	diag(qI, conv<long>(m), conv<ZZ>(q));

	for (int i = n; i < m + n; i++) {
		for (int j = 0; j < m; j++) {
			res[i][j] = qI[i - n][j];
		}
	}
	return res;
}
Example #7
0
Mat<ZZ> Kernel(Mat<ZZ> U, long r, long q) {
	Mat<ZZ> ker;
	long m = U.NumCols();
	// ker.SetDims(m-r, m); //without q-ary part
	ker.SetDims(2 * m - r, m);
	for (int i = 0; i < m - r; i++)
		for (int j = 0; j < m; j++)
			ker[i][j] = U[i][j] % q;

	Mat<ZZ> qI;
	diag(qI, conv<long>(m), conv<ZZ>(q));

	for (int i = m - r; i < 2 * m - r; i++) {
		for (int j = 0; j < m; j++) {
			ker[i][j] = qI[i - m + r][j];
		}
	}

	return ker;
}
Example #8
0
int main()
{
	int iA[MS][MS] = {	{5,2,1},
						{3,0,-4},
						{2,1,6}};

	Mat<ZZ> A;
	long i, j;
	ZZ d;

	A.SetDims( MS, MS );

	for (i = 0; i < MS; i++)
		for (j = 0; j < MS; j++)
			A[i][j] = iA[i][j];

	cout << A << endl;

	long deterministic=0;
	d = determinant(A, deterministic);

	cout << d << endl;

}
Example #9
0
/**
 * GenerateSamples
 * \brief generates the requested number of samples and returns them in matrix
 *        form
 *
 * @param n length of each sample vector
 * @param q modulus
 * @param m number of samples
 * @param sigma for discrete gaussian
 * @param tailfactor for discrete gaussian
 * @param number_of_rects used in sampling algorithm (trade off speed/memory)
 * @param precision used in sampling algorithm
 */
tuple<Mat<ZZ>, Vec<ZZ>, Vec<ZZ>>
GenerateSamples(int n, long q, int m, double sigma, int tailfactor,
				int number_of_rects, int precision, int flag_binary,
				int flag_trinary, int flag_binary_secret, int flag_binary_lwe,
				int flag_binary_sis) {
	Mat<ZZ> A;
	Vec<ZZ> t;
	Vec<ZZ> s;
	Vec<ZZ> e;
	Vec<ZZ> As; // solution vector -EK

	Vec<ZZ> u; // to test BinaryA
	Vec<ZZ> C1; // to test BinaryA
	Mat<ZZ> Abin;

	u.SetLength(m);
	C1.SetLength(n);
	Abin.SetDims(n, m);

	A.SetDims(m, n); // m rows x n cols
	t.SetLength(m);
	As.SetLength(m);
	// generate LWE secret s
	if (flag_binary_secret) {
		s = RandomVec(n, 2);
	} else {
		s = RandomVec(n, q);
	}

	// generate error vector e
	if (flag_binary) {
		random_device rd;
		uniform_int_distribution<int> dist(0, 1);
		e.SetLength(m);
		for (ZZ *it = e.begin(); it != e.end(); ++it) {
			*it = ZZ(dist(rd));
		}
		// a uniform, trinary error (from {-1, 0, 1}) is used
		// in "Efficient Identity-Based Encryption over NTRU Lattices"
		// by Ducas, Lyubashevsky and Prest
	} else if (flag_trinary) {
		random_device rd;
		uniform_int_distribution<int> dist(-1, 1);
		e.SetLength(m);
		for (ZZ *it = e.begin(); it != e.end(); ++it) {
			*it = ZZ(dist(rd));
		}
	} else {
		Ziggurat sampler(number_of_rects, sigma, tailfactor, precision);
		e.SetLength(m);
		for (ZZ *it = e.begin(); it != e.end(); ++it) {
			*it = sampler.sample();
		}
	}

	// generate LWE samples
	if (flag_binary_sis) {
		//-------For Binary-SIS---------
		u = RandomVec(m, 2);

		for (int i = 0; i < n; i++) {
			Abin[i] = RandomVec(m, 2);
			InnerProduct(C1[i], Abin[i], u);
			C1[i] = C1[i] % q;
		}
		return make_tuple(A, t, As);
	} else if (flag_binary_lwe) {
		//-------For Binary-LWE---------
		for (int i = 0; i < m; ++i) {
			A[i] = RandomVec(n, 2);
			InnerProduct(t[i], A[i], s);
			As[i] = t[i] % q;
			t[i] += e[i];
			t[i] = t[i] % q;
		}
		return make_tuple(A, t, As);
	} else {
		for (int i = 0; i < m; ++i) {
			A[i] = RandomVec(n, q);
			InnerProduct(t[i], A[i], s);
			As[i] = t[i] % q;
			t[i] += e[i];
			t[i] = t[i] % q;
		}
		return make_tuple(A, t, As);
	}
}
Example #10
0
void inv(zz_pE& d, Mat<zz_pE>& X, const Mat<zz_pE>& A)
{
   long n = A.NumRows();

   if (A.NumCols() != n)
      LogicError("inv: nonsquare matrix");

   if (n == 0) {
      set(d);
      X.SetDims(0, 0);
      return;
   }

   const zz_pXModulus& G = zz_pE::modulus();

   zz_pX t1, t2;
   zz_pX pivot;
   zz_pX pivot_inv;

   Vec< Vec<zz_pX> > M;
   // scratch space

   M.SetLength(n);
   for (long i = 0; i < n; i++) {
      M[i].SetLength(n);
      for (long j = 0; j < n; j++) {
         M[i][j].SetMaxLength(2*deg(G)-1);
         M[i][j] = rep(A[i][j]);
      }
   }

   zz_pX det;
   det = 1;


   Vec<long> P;
   P.SetLength(n);
   for (long k = 0; k < n; k++) P[k] = k;
   // records swap operations
   

   zz_pContext zz_p_context;
   zz_p_context.save();
   double sz = zz_pE_SizeInWords();

   bool seq = double(n)*double(n)*sz*sz < PAR_THRESH;

   bool pivoting = false;

   for (long k = 0; k < n; k++) {

      long pos = -1;

      for (long i = k; i < n; i++) {
         rem(pivot, M[i][k], G);
         if (pivot != 0) {
            InvMod(pivot_inv, pivot, G);
            pos = i;
            break;
         }
      }

      if (pos != -1) {
         if (k != pos) {
            swap(M[pos], M[k]);
            negate(det, det); 
            P[k] = pos;
            pivoting = true;
         }

         MulMod(det, det, pivot, G);

         {
            // multiply row k by pivot_inv
            zz_pX *y = &M[k][0];
            for (long j = 0; j < n; j++) {
               rem(t2, y[j], G);
               MulMod(y[j], t2, pivot_inv, G);
            }
            y[k] = pivot_inv;
         }


         NTL_GEXEC_RANGE(seq, n, first, last)  
         NTL_IMPORT(n)
         NTL_IMPORT(k)

         zz_p_context.restore();

         zz_pX *y = &M[k][0]; 
         zz_pX t1, t2;

         for (long i = first; i < last; i++) {
            if (i == k) continue; // skip row k

            zz_pX *x = &M[i][0]; 
            rem(t1, x[k], G);
            negate(t1, t1); 
            x[k] = 0;
            if (t1 == 0) continue;

            // add t1 * row k to row i
            for (long j = 0; j < n; j++) {
               mul(t2, y[j], t1);
               add(x[j], x[j], t2);
            }
         }
         NTL_GEXEC_RANGE_END
      }
      else {
         clear(d);
         return;
      }
   }