From 8c185c51ad3f37fb41da2b380489886be63b8e15 Mon Sep 17 00:00:00 2001 From: Mirek Kratochvil Date: Sat, 18 May 2013 10:52:57 +0200 Subject: [PATCH] mce_qd: compute check matrix on the fly codecrypt is usually invoked only with one prepare() and decrypt(), so this basically saves several megs of memory and cuts needed computation time in half. --- src/mce_qd.cpp | 35 ++++++++++++++++++----------------- src/mce_qd.h | 8 ++++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/mce_qd.cpp b/src/mce_qd.cpp index 95138ea..ab2e286 100644 --- a/src/mce_qd.cpp +++ b/src/mce_qd.cpp @@ -241,7 +241,7 @@ int privkey::prepare() std::set used; used.clear(); - polynomial g, tmp; + polynomial tmp; g.clear(); g.resize (1, 1); //g(x)=1 tmp.clear(); @@ -294,7 +294,7 @@ int privkey::prepare() // prepare permuted support, from that prepare permuted check matrix // (so that it can be applied directly) uint pos, blk_perm; - std::vector sbl1, sbl2, permuted_support; + std::vector sbl1, sbl2; sbl1.resize (block_size); sbl2.resize (block_size); @@ -318,17 +318,6 @@ int privkey::prepare() permuted_support[j + pos * block_size] = sbl2[j]; } - //prepare Hc - Hc.resize (block_size * block_count); - for (i = 0; i < block_size * block_count; ++i) { - Hc[i].resize (block_size * 2); - Hc[i][0] = fld.inv (g.eval (permuted_support[i], fld) ); - Hc[i][0] = fld.mult (Hc[i][0], Hc[i][0]); - for (j = 1; j < 2 * block_size; ++j) - Hc[i][j] = fld.mult (permuted_support[i], - Hc[i][j - 1]); - } - //convert the permuted support to actual lookup support_pos.clear(); //fld.n in support lookup means that it isn't there (we don't have -1) @@ -419,15 +408,27 @@ int privkey::decrypt (const bvector & in, bvector & out, bvector & errors) { if (in.size() != cipher_size() ) return 2; polynomial synd; - uint i; + uint i, j, tmp; + /* + * compute the syndrome from alternant check matrix + * that is H_alt = Vdm(L) * Diag(g(L_i)^{-2}) + */ + uint h_size = 1 << (T + 1); //= 2*block_size synd.clear(); - for (i = 0; i < cipher_size(); ++i) - if (in[i]) synd.add (Hc[i], fld); + synd.resize (h_size, 0); + for (i = 0; i < cipher_size(); ++i) if (in[i]) { + tmp = fld.inv (g.eval (permuted_support[i], fld) ); + tmp = fld.mult (tmp, tmp); //g(Li)^{-2} + 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); + } + } //decoding polynomial loc; - //compute_alternant_error_locator (synd, fld, g, loc); compute_alternant_error_locator (synd, fld, 1 << T, loc); bvector ev; diff --git a/src/mce_qd.h b/src/mce_qd.h index 5de5c73..ebb4c96 100644 --- a/src/mce_qd.h +++ b/src/mce_qd.h @@ -52,10 +52,10 @@ public: permutation hperm; //block permutation of H block used to get G //derivable stuff - //cols of check matrix of g^2(x) - std::vector Hc; - //pre-permuted positions of support rows - std::vector support_pos; + //pre-permuted positions of support rows and support content + std::vector support_pos, permuted_support; + //generating polynomial + polynomial g; int decrypt (const bvector&, bvector&); int decrypt (const bvector&, bvector&, bvector&);