mce: signatures and verification
This commit is contained in:
parent
3758f23f44
commit
d573d1cfe7
|
@ -200,7 +200,7 @@ public:
|
||||||
uint t;
|
uint t;
|
||||||
|
|
||||||
int encrypt (const bvector&, bvector&, prng&);
|
int encrypt (const bvector&, bvector&, prng&);
|
||||||
int verify (const bvector&, const bvector&, uint, uint);
|
int verify (const bvector&, const bvector&, uint);
|
||||||
|
|
||||||
uint cipher_size() {
|
uint cipher_size() {
|
||||||
return G.width();
|
return G.width();
|
||||||
|
@ -224,7 +224,7 @@ public:
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
int decrypt (const bvector&, bvector&);
|
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
|
class pubkey
|
||||||
|
@ -234,7 +234,7 @@ public:
|
||||||
uint t;
|
uint t;
|
||||||
|
|
||||||
int encrypt (const bvector&, bvector&, prng&);
|
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&);
|
int generate (pubkey&, privkey&, prng&);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
#include "decoding.h"
|
#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)
|
std::vector<polynomial>& sqInv, bvector&ev)
|
||||||
|
|
||||||
{
|
{
|
||||||
ev.clear();
|
ev.clear();
|
||||||
ev.resize (fld.n, 0);
|
ev.resize (fld.n, 0);
|
||||||
if (syndrome.zero() ) return;
|
if (syndrome.zero() ) return true;
|
||||||
|
|
||||||
polynomial v;
|
polynomial v;
|
||||||
syndrome.to_poly (v, fld);
|
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.
|
a.make_monic (fld); //now it is the error locator.
|
||||||
|
|
||||||
for (uint i = 0; i < fld.n; ++i) {
|
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"
|
#include "codecrypt.h"
|
||||||
|
|
||||||
using namespace ccr;
|
using namespace ccr;
|
||||||
void syndrome_decode (bvector&syndrome,
|
bool syndrome_decode (bvector&syndrome,
|
||||||
gf2m&fld,
|
gf2m&fld,
|
||||||
polynomial& gp,
|
polynomial& gp,
|
||||||
std::vector<polynomial>& sqInv,
|
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
|
//decode
|
||||||
bvector ev;
|
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
|
// check the error vector, it should have exactly t == deg (g) errors
|
||||||
if ( (int) ev.hamming_weight() != g.degree() )
|
if ( (int) ev.hamming_weight() != g.degree() )
|
||||||
|
@ -106,14 +108,62 @@ int privkey::prepare ()
|
||||||
return 0;
|
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)
|
||||||
{
|
{
|
||||||
|
bvector tmp;
|
||||||
return -1; //TODO
|
//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
|
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
|
return -1; //TODO
|
||||||
|
|
Loading…
Reference in a new issue