diff --git a/src/gf2m.h b/src/gf2m.h
index 5406aa6..c4a0b62 100644
--- a/src/gf2m.h
+++ b/src/gf2m.h
@@ -82,6 +82,24 @@ public:
 
 	sencode* serialize();
 	bool unserialize (sencode*);
+
+	//optimized part of creating alternant check matrix
+	template<class iter>
+	inline void add_mults (uint base, uint step, iter begin, iter end) {
+		if (begin == end || base == 0) return;
+
+		*begin = add (*begin, base);
+		++begin;
+
+		if (begin == end || step == 0) return;
+
+		uint lb = log[base], ls = log[step];
+
+		for (; begin != end; ++begin) {
+			lb = (lb + ls) % (n - 1);
+			*begin = add (*begin, antilog[lb]);
+		}
+	}
 };
 
 #endif
diff --git a/src/mce_qd.cpp b/src/mce_qd.cpp
index 0fa56d1..4a1b1f1 100644
--- a/src/mce_qd.cpp
+++ b/src/mce_qd.cpp
@@ -413,11 +413,8 @@ int privkey::decrypt (const bvector & in, bvector & out, bvector & errors)
 	for (i = 0; i < cipher_size(); ++i) if (in[i]) {
 			tmp = fld.inv_square //g(Li)^{-2}
 			      (g.eval (permuted_support[i], fld) );
-			synd[0] = fld.add (synd[0], tmp);
-			for (j = 1; j < h_size; ++j) {
-				tmp = fld.mult (tmp, permuted_support[i]);
-				synd[j] = fld.add (synd[j], tmp);
-			}
+			fld.add_mults (tmp, permuted_support[i],
+			               synd.begin(), synd.end() );
 		}
 
 	//decoding