mce: signatures and verification
This commit is contained in:
parent
3758f23f44
commit
d573d1cfe7
|
@ -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&);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
62
lib/mce.cpp
62
lib/mce.cpp
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue