little refactor of decoding

This commit is contained in:
Mirek Kratochvil 2012-06-03 23:28:18 +02:00
parent c13fb3c414
commit d0810664d7
4 changed files with 48 additions and 22 deletions

View file

@ -1,14 +1,15 @@
#include "decoding.h"
bool syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
std::vector<polynomial>& sqInv, bvector&ev,
bool check_failure)
void compute_error_locator (bvector&syndrome, gf2m&fld, polynomial& goppa,
std::vector<polynomial>& sqInv, polynomial&out)
{
ev.clear();
ev.resize (fld.n, 0);
if (syndrome.zero() ) return true;
if (syndrome.zero() ) {
//ensure no roots
out.resize (1);
out[0] = 1;
return;
}
polynomial v;
syndrome.to_poly (v, fld);
@ -28,20 +29,26 @@ bool syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
a.add (b, fld); //new a = a^2 + x b^2
a.make_monic (fld); //now it is the error locator.
out = a;
}
bool evaluate_error_locator_dumb (polynomial&a, bvector&ev, gf2m&fld)
{
ev.clear();
ev.resize (fld.n, 0);
for (uint i = 0; i < fld.n; ++i) {
if (a.eval (i, fld) == 0) {
ev[i] = 1;
if (!check_failure) continue;
//check if the error locator splits over GF(2^m).
//We simplify it to the assumption that all roots are
//also roots of linear factors.
//divide the polynomial by (found) linear factor
polynomial t, q, r;
t.resize (2, 0);
t[0] = i;
t[1] = 1;
a.divmod (t, q, r, fld);
//if it doesn't divide, die.
if (r.degree() >= 0) {
ev.clear();
return false;
@ -50,7 +57,8 @@ bool syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
}
}
if (check_failure && a.degree() > 0) {
//also if there's something left, die.
if (a.degree() > 0) {
ev.clear();
return false;
}

View file

@ -5,11 +5,14 @@
#include "codecrypt.h"
using namespace ccr;
bool syndrome_decode (bvector&syndrome,
void compute_error_locator (bvector&syndrome,
gf2m&fld,
polynomial& gp,
polynomial&goppa,
std::vector<polynomial>& sqInv,
bvector&ev,
bool check_failure = true);
polynomial&loc);
bool evaluate_error_locator_dumb (polynomial&el, bvector&ev, gf2m&fld);
bool evaluate_error_locator_trace (polynomial&el, bvector&ev, gf2m&fld);
#endif

View file

@ -79,13 +79,18 @@ int privkey::decrypt (const bvector&in, bvector&out)
h.mult_vec_right (canonical, syndrome);
//decode
polynomial loc;
compute_error_locator (syndrome, fld, g, sqInv, loc);
bvector ev;
if (!syndrome_decode (syndrome, fld, g, sqInv, ev) )
if (!evaluate_error_locator_dumb (loc, ev, fld) )
return 1; //if decoding somehow failed, fail as well.
// check the error vector, it should have exactly t == deg (g) errors
if ( (int) ev.hamming_weight() != g.degree() )
return 1;
//TODO cryptoanalysis suggests omitting this check for preventing
//bit-flipping attack
//correct the errors
canonical.add (ev);
@ -115,6 +120,7 @@ int privkey::sign (const bvector&in, bvector&out, uint delta, uint attempts, prn
bvector p, e, synd, synd_orig, e2;
std::vector<uint> epos;
permutation hpermInv;
polynomial loc;
s = hash_size();
@ -143,7 +149,9 @@ int privkey::sign (const bvector&in, bvector&out, uint delta, uint attempts, prn
synd.add (h[epos[i]]);
}
if (syndrome_decode (synd, fld, g, sqInv, e2, true) ) {
compute_error_locator (synd, fld, g, sqInv, loc);
if (evaluate_error_locator_dumb (loc, e2, fld) ) {
//create the decodable message
p.add (e);

View file

@ -58,8 +58,11 @@ int privkey::decrypt (const bvector&in, bvector&out)
bvector unsc; //unscrambled
Sinv.mult_vec_right (in, unsc);
polynomial loc;
compute_error_locator (unsc, fld, g, sqInv, loc);
bvector ev;
if (!syndrome_decode (unsc, fld, g, sqInv, ev) )
if (!evaluate_error_locator_dumb (loc, ev, fld) )
return 1;
if ( (int) ev.hamming_weight() != g.degree() )
@ -75,6 +78,8 @@ int privkey::sign (const bvector&in, bvector&out, uint delta, uint attempts, prn
bvector synd_unsc, synd, e;
polynomial loc;
s = hash_size();
if (in.size() != s) return 2;
@ -88,7 +93,9 @@ int privkey::sign (const bvector&in, bvector&out, uint delta, uint attempts, prn
Sinv.mult_vec_right (synd, synd_unsc);
if (syndrome_decode (synd_unsc, fld, g, sqInv, e, true) ) {
compute_error_locator (synd_unsc, fld, g, sqInv, loc);
if (evaluate_error_locator_dumb (loc, e, fld) ) {
Pinv.permute (e, out);
return 0;