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

View file

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

View file

@ -335,6 +335,25 @@ int privkey::prepare()
}
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;
bvector p, g, r, cksum;
@ -348,6 +367,8 @@ int pubkey::encrypt (const bvector & in, bvector & out, prng & rng)
//some checks
if (!qd_sigs.width() ) 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;
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
out = in;
out.insert (out.end(), cksum.begin(), cksum.end() );
out.add (e);
out.add (errors);
return 0;
}
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;
polynomial synd;
@ -411,6 +427,8 @@ int privkey::decrypt (const bvector & in, bvector & out)
out = in;
out.resize (plain_size() );
errors.clear();
errors.resize (cipher_size(), 0);
//flip error positions of out.
for (i = 0; i < ev.size(); ++i) if (ev[i]) {
uint epos = support_pos[fld.inv (i)];
@ -419,6 +437,8 @@ int privkey::decrypt (const bvector & in, bvector & out)
out.clear();
return 1;
}
if (epos >= cipher_size() ) return 1;
errors[epos] = 1;
if (epos < plain_size() )
out[epos] = !out[epos];
}