mce: signatures and verification

This commit is contained in:
Mirek Kratochvil 2012-05-22 15:41:56 +02:00
parent 3758f23f44
commit d573d1cfe7
5 changed files with 82 additions and 14 deletions

View file

@ -200,7 +200,7 @@ public:
uint t;
int encrypt (const bvector&, bvector&, prng&);
int verify (const bvector&, const bvector&, uint, uint);
int verify (const bvector&, const bvector&, uint);
uint cipher_size() {
return G.width();
@ -224,7 +224,7 @@ public:
// TODO
int decrypt (const bvector&, bvector&);
int sign (const bvector&hash, bvector&sig, uint, uint, prng&);
int sign (const bvector&, bvector&, uint, uint, prng&);
};
class pubkey
@ -234,7 +234,7 @@ public:
uint t;
int encrypt (const bvector&, bvector&, prng&);
int verify (const bvector&sig, const bvector&hash, uint, uint);
int verify (const bvector&, const bvector&, uint);
};
int generate (pubkey&, privkey&, prng&);

View file

@ -1,13 +1,13 @@
#include "decoding.h"
void syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
bool syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
std::vector<polynomial>& sqInv, bvector&ev)
{
ev.clear();
ev.resize (fld.n, 0);
if (syndrome.zero() ) return;
if (syndrome.zero() ) return true;
polynomial v;
syndrome.to_poly (v, fld);
@ -29,6 +29,24 @@ void syndrome_decode (bvector&syndrome, gf2m&fld, polynomial& goppa,
a.make_monic (fld); //now it is the error locator.
for (uint i = 0; i < fld.n; ++i) {
if (a.eval (i, fld) == 0) ev[i] = 1;
if (a.eval (i, fld) == 0) {
ev[i] = 1;
//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.
polynomial t, q, r;
t.resize (2, 0);
t[0] = i;
t[1] = 1;
a.divmod (t, q, r, fld);
if (r.degree() >= 0) {
ev.clear();
return false;
}
a = q;
}
}
return true;
}

View file

@ -5,7 +5,7 @@
#include "codecrypt.h"
using namespace ccr;
void syndrome_decode (bvector&syndrome,
bool syndrome_decode (bvector&syndrome,
gf2m&fld,
polynomial& gp,
std::vector<polynomial>& sqInv,

View file

@ -78,7 +78,9 @@ int privkey::decrypt (const bvector&in, bvector&out)
//decode
bvector ev;
syndrome_decode (syndrome, fld, g, sqInv, ev);
if (!syndrome_decode (syndrome, fld, g, sqInv, ev) ) {
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() )
@ -106,14 +108,62 @@ int privkey::prepare ()
return 0;
}
int privkey::sign (const bvector&in, bvector&out, uint delta, uint h, prng&rng)
int privkey::sign (const bvector&in, bvector&out, uint delta, uint attempts, prng&rng)
{
uint i, t, s;
bvector p, e, synd, synd2, e2;
std::vector<uint> epos;
permutation hpermInv;
return -1; //TODO
s = cipher_size();
//TODO check sizes of everything!
//first, prepare the codeword to canonical form for decoding
Pinv.permute (in, e2);
hperm.compute_inversion (hpermInv);
hpermInv.permute (e2, p);
//prepare extra error vector
e.resize (s, 0);
epos.resize (delta);
h.mult_vec_right (p, synd);
for (t = 0; t < attempts; ++t) {
for (i = 0; i < s; ++i) {
epos[i] = rng.random (s);
/* we don't care about (unlikely) error bit collisions
(they actually don't harm anything) */
e[epos[i]] = 1;
}
//abuse linearity of p+e; it is usually faster.
h.mult_vec_right (e, synd2);
synd2.add (synd);
if (syndrome_decode (synd2, fld, g, sqInv, e2) ) {
//decoding success!
p.add (e); //add original errors
hperm.permute (p, e2); //back to systematic (e2~=tmp)
Sinv.mult_vecT_left (e2, out); //get a signature
return 0; //OK lol
}
//if this round failed, we try a new error pattern.
for (i = 0; i < s; ++i) //clear the errors for the next cycle
e[epos[i]] = 0;
}
return 1; //couldn't decode
}
int pubkey::verify (const bvector&in, const bvector&hash, uint delta, uint h)
int pubkey::verify (const bvector&in, const bvector&hash, uint delta)
{
return -1; //TODO
bvector tmp;
//TODO check sizes!
G.mult_vecT_left (in, tmp);
tmp.add (hash);
if (tmp.hamming_weight() > (t + delta) ) return 1; //not a signature
return 0; //sig OK
}

View file

@ -28,7 +28,7 @@ int privkey::sign (const bvector&in, bvector&out, uint delta, uint h, prng&rng)
return -1; //TODO
}
int pubkey::verify (const bvector&in, const bvector&hash, uint delta, uint h)
int pubkey::verify (const bvector&in, const bvector&hash, uint delta)
{
return -1; //TODO