mce/mce_qd: custom error vector support
This commit is contained in:
parent
bbb8765a62
commit
17d6a55141
|
@ -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*);
|
||||||
|
|
23
lib/mce.cpp
23
lib/mce.cpp
|
@ -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() );
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue