mce/mce_qd: custom error vector support

This commit is contained in:
Mirek Kratochvil 2012-12-16 15:36:29 +01:00
parent bbb8765a62
commit 17d6a55141
3 changed files with 66 additions and 19 deletions

View file

@ -347,6 +347,7 @@ public:
int prepare(); int prepare();
int decrypt (const bvector&, bvector&); int decrypt (const bvector&, bvector&);
int decrypt (const bvector&, bvector&, bvector&);
int sign (const bvector&, bvector&, uint, uint, prng&); int sign (const bvector&, bvector&, uint, uint, prng&);
uint cipher_size() { uint cipher_size() {
@ -361,6 +362,9 @@ public:
uint signature_size() { uint signature_size() {
return plain_size(); return plain_size();
} }
uint error_count() {
return g.degree();
}
sencode* serialize(); sencode* serialize();
bool unserialize (sencode*); bool unserialize (sencode*);
@ -373,6 +377,7 @@ public:
uint t; uint t;
int encrypt (const bvector&, bvector&, prng&); int encrypt (const bvector&, bvector&, prng&);
int encrypt (const bvector&, bvector&, const bvector&);
int verify (const bvector&, const bvector&, uint); int verify (const bvector&, const bvector&, uint);
uint cipher_size() { uint cipher_size() {
@ -387,6 +392,9 @@ public:
uint signature_size() { uint signature_size() {
return plain_size(); return plain_size();
} }
uint error_count() {
return t;
}
sencode* serialize(); sencode* serialize();
bool unserialize (sencode*); bool unserialize (sencode*);
@ -501,6 +509,7 @@ public:
std::vector<uint> support_pos; std::vector<uint> support_pos;
int decrypt (const bvector&, bvector&); int decrypt (const bvector&, bvector&);
int decrypt (const bvector&, bvector&, bvector&);
int prepare(); int prepare();
uint cipher_size() { uint cipher_size() {
@ -509,6 +518,9 @@ public:
uint plain_size() { uint plain_size() {
return (1 << T) * (hperm.size() - fld.m); return (1 << T) * (hperm.size() - fld.m);
} }
uint error_count() {
return 1 << T;
}
sencode* serialize(); sencode* serialize();
bool unserialize (sencode*); bool unserialize (sencode*);
@ -521,6 +533,7 @@ public:
matrix qd_sigs; matrix qd_sigs;
int encrypt (const bvector&, bvector&, prng&); int encrypt (const bvector&, bvector&, prng&);
int encrypt (const bvector&, bvector&, const bvector&);
uint cipher_size() { uint cipher_size() {
return plain_size() + qd_sigs[0].size(); return plain_size() + qd_sigs[0].size();
@ -528,6 +541,9 @@ public:
uint plain_size() { uint plain_size() {
return (1 << T) * qd_sigs.size(); return (1 << T) * qd_sigs.size();
} }
uint error_count() {
return 1 << T;
}
sencode* serialize(); sencode* serialize();
bool unserialize (sencode*); bool unserialize (sencode*);

View file

@ -59,12 +59,8 @@ int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
{ {
uint s = cipher_size(); uint s = cipher_size();
if (t > s) return 1; if (t > s) return 1;
if (in.size() != plain_size() ) return 2;
//make a codeword //create error vector
G.mult_vecT_left (in, out);
//add error vector
bvector e; bvector e;
e.resize (s, 0); e.resize (s, 0);
for (uint n = t; n > 0;) { for (uint n = t; n > 0;) {
@ -74,11 +70,25 @@ int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
--n; --n;
} }
} }
out.add (e); return encrypt (in, out, e);
}
int pubkey::encrypt (const bvector&in, bvector&out, const bvector&errors)
{
if (in.size() != plain_size() ) return 2;
if (errors.size() != cipher_size() ) return 2;
G.mult_vecT_left (in, out);
out.add (errors);
return 0; return 0;
} }
int privkey::decrypt (const bvector&in, bvector&out) int privkey::decrypt (const bvector&in, bvector&out)
{
bvector tmp_errors;
return decrypt (in, out, tmp_errors);
}
int privkey::decrypt (const bvector&in, bvector&out, bvector&errors)
{ {
if (in.size() != cipher_size() ) return 2; if (in.size() != cipher_size() ) return 2;
@ -108,6 +118,7 @@ int privkey::decrypt (const bvector&in, bvector&out)
//shuffle back into systematic order //shuffle back into systematic order
hperm.permute (canonical, not_permuted); hperm.permute (canonical, not_permuted);
hperm.permute (ev, errors);
//get rid of redundancy bits //get rid of redundancy bits
not_permuted.resize (plain_size() ); not_permuted.resize (plain_size() );

View file

@ -334,7 +334,26 @@ int privkey::prepare()
return 0; return 0;
} }
int pubkey::encrypt (const bvector & in, bvector & out, prng & rng) int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
{
uint s = cipher_size(),
t = 1 << T;
if (t > s) return 1;
//create error vector
bvector e;
e.resize (s, 0);
for (uint n = t; n > 0;) {
uint p = rng.random (s);
if (!e[p]) {
e[p] = 1;
--n;
}
}
return encrypt (in, out, e);
}
int pubkey::encrypt (const bvector & in, bvector & out, const bvector&errors)
{ {
uint t = 1 << T; uint t = 1 << T;
bvector p, g, r, cksum; bvector p, g, r, cksum;
@ -348,6 +367,8 @@ int pubkey::encrypt (const bvector & in, bvector & out, prng & rng)
//some checks //some checks
if (!qd_sigs.width() ) return 1; if (!qd_sigs.width() ) return 1;
if (qd_sigs.height() % t) return 1; if (qd_sigs.height() % t) return 1;
if (in.size() != plain_size() ) return 2;
if (errors.size() != cipher_size() ) return 2;
uint blocks = qd_sigs.height() / t; uint blocks = qd_sigs.height() / t;
cksum.resize (qd_sigs.height(), 0); cksum.resize (qd_sigs.height(), 0);
@ -370,26 +391,21 @@ int pubkey::encrypt (const bvector & in, bvector & out, prng & rng)
} }
} }
//generate t errors
bvector e;
e.resize (cipher_size(), 0);
for (uint n = t; n > 0;) {
uint p = rng.random (e.size() );
if (!e[p]) {
e[p] = 1;
--n;
}
}
//compute ciphertext //compute ciphertext
out = in; out = in;
out.insert (out.end(), cksum.begin(), cksum.end() ); out.insert (out.end(), cksum.begin(), cksum.end() );
out.add (e); out.add (errors);
return 0; return 0;
} }
int privkey::decrypt (const bvector & in, bvector & out) int privkey::decrypt (const bvector & in, bvector & out)
{
bvector tmp_errors;
return decrypt (in, out, tmp_errors);
}
int privkey::decrypt (const bvector & in, bvector & out, bvector & errors)
{ {
if (in.size() != cipher_size() ) return 2; if (in.size() != cipher_size() ) return 2;
polynomial synd; polynomial synd;
@ -411,6 +427,8 @@ int privkey::decrypt (const bvector & in, bvector & out)
out = in; out = in;
out.resize (plain_size() ); out.resize (plain_size() );
errors.clear();
errors.resize (cipher_size(), 0);
//flip error positions of out. //flip error positions of out.
for (i = 0; i < ev.size(); ++i) if (ev[i]) { for (i = 0; i < ev.size(); ++i) if (ev[i]) {
uint epos = support_pos[fld.inv (i)]; uint epos = support_pos[fld.inv (i)];
@ -419,6 +437,8 @@ int privkey::decrypt (const bvector & in, bvector & out)
out.clear(); out.clear();
return 1; return 1;
} }
if (epos >= cipher_size() ) return 1;
errors[epos] = 1;
if (epos < plain_size() ) if (epos < plain_size() )
out[epos] = !out[epos]; out[epos] = !out[epos];
} }