mce_qd: encryption fixed

This commit is contained in:
Mirek Kratochvil 2012-10-11 14:13:04 +02:00
parent 63e3e591b6
commit 5b69b38e09
5 changed files with 42 additions and 36 deletions

View file

@ -395,10 +395,10 @@ public:
int prepare();
uint cipher_size() {
return 0; //TODO
return (1 << T) * block_count;
}
uint plain_size() {
return 0; //TODO
return (1 << T) * (block_count - fld.m);
}
};
@ -406,16 +406,15 @@ class pubkey
{
public:
uint T;
uint k;
std::vector<bvector> qd_sigs;
int encrypt (const bvector&, bvector&, prng&);
uint cipher_size() {
return 0; //TODO
return plain_size() + qd_sigs[0].size();
}
uint plain_size() {
return 0; //TODO
return (1 << T) * qd_sigs.size();
}
};

View file

@ -66,19 +66,19 @@ void bvector::to_poly_cotrace (polynomial&r, gf2m&fld)
{
r.clear();
if (size() % fld.m) return; //impossible
uint s=size()/fld.m;
uint s = size() / fld.m;
r.resize (s, 0);
for (uint i = 0; i < size(); ++i)
if (item (i) ) r[i%s] |= (1 << (i/s) );
if (item (i) ) r[i%s] |= (1 << (i / s) );
}
void bvector::from_poly_cotrace (const polynomial&r, gf2m&fld)
{
clear();
uint s=r.size();
resize (s*fld.m, 0);
uint s = r.size();
resize (s * fld.m, 0);
for (uint i = 0; i < size(); ++i)
item (i) = (r[i%s] >> (i/s) ) & 1;
item (i) = (r[i%s] >> (i / s) ) & 1;
}
/*

View file

@ -37,6 +37,10 @@ void fwht_dyadic_multiply (const bvector& a, const bvector& b, bvector& out)
vector<int> t, A, B;
uint i;
t.resize (a.size() );
A.resize (a.size() );
B.resize (a.size() );
for (i = 0; i < a.size(); ++i) t[i] = a[i];
fwht (t, A);

View file

@ -31,7 +31,7 @@ static uint choose_random (uint limit, prng&rng, std::set<uint>used)
}
int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
uint m, uint T, uint block_count)
uint m, uint T, uint block_discard)
{
priv.fld.create (m);
priv.T = T;
@ -87,6 +87,17 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
//from now on, we fix 'omega' from the paper to zero.
//assemble goppa polynomial.
g.clear();
g.resize (1, 1); //g(x)=1 so we can multiply it
polynomial tmp;
tmp.resize (2, 1); //tmp(x)=x-1
for (uint i = 0; i < t; ++i) {
//tmp(x)=x-z=x-(1/h_i)
tmp[0] = fld.inv (Hsig[i]);
g.mult (tmp, fld);
}
//compute the support, retry if it has two equal elements.
used.clear();
bool consistent = true;
@ -99,24 +110,22 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
consistent = false;
break;
}
if (g.eval (support[i], fld) == 0) {
consistent = false;
break;
}
used.insert (support[i]);
}
if (!consistent) continue; //retry
//assemble goppa polynomial.
g.clear();
g.resize (1, 1); //g(x)=1 so we can multiply it
polynomial tmp;
tmp.resize (2, 1); //tmp(x)=x-1
for (uint i = 0; i < t; ++i) {
//tmp(x)=x-z=x-(1/h_i)
tmp[0] = fld.inv (Hsig[i]);
g.mult (tmp, fld);
}
//now the blocks.
uint block_size = 1 << T,
h_block_count = (fld.n / 2) / block_size;
uint& block_count = priv.block_count;
block_count = h_block_count - block_discard;
//assemble blocks to bl
std::vector<std::vector<uint> > bl, blp;
@ -134,7 +143,6 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
blp.resize (block_count);
//permute individual blocks
priv.block_count = block_count;
priv.block_perms.resize (block_count);
bl.resize (blp.size() );
for (uint i = 0; i < block_count; ++i) {
@ -182,7 +190,6 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
*/
pub.T = T;
pub.k = (block_count - fld.m) * block_size;
pub.qd_sigs.resize (ri.width() / t);
for (uint i = 0; i < ri.width(); i += t)
pub.qd_sigs[i/t] = ri[i];
@ -251,7 +258,6 @@ int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
*/
//some checks
if (in.size() != k) return 1;
if (!qd_sigs.size() ) return 1;
if (qd_sigs[0].size() % t) return 1;
@ -262,11 +268,11 @@ int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
g.resize (t);
r.resize (t);
for (uint i = 0; i < blocks; ++i) {
for (uint i = 0; i < qd_sigs.size(); ++i) {
//plaintext block
for (uint k = 0; k < t; ++k) p[k] = in[k+i*t];
for (uint j = 0; j < qd_sigs.size(); ++j) {
for (uint j = 0; j < blocks; ++j) {
//checksum block
for (uint k = 0; k < t; ++k) g[k] = qd_sigs[i][k+j*t];
@ -278,7 +284,7 @@ int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
//generate t errors
bvector e;
e.resize (k + qd_sigs[0].size(), 0);
e.resize (cipher_size(), 0);
for (uint n = t; n > 0;) {
uint p = rng.random (e.size() );
if (!e[p]) {

View file

@ -24,18 +24,15 @@ int main()
primitiverng r;
r.seed (0);
ccr::mce_oc::privkey priv;
ccr::mce_oc::pubkey pub;
ccr::mce_oc::generate (pub, priv, r, 7, 2, 2);
ccr::mce_qd::privkey priv;
ccr::mce_qd::pubkey pub;
ccr::mce_qd::generate (pub, priv, r, 5, 1, 1);
priv.prepare();
cout << "PUBLIC KEY" << endl;
cout << pub.t << endl;
cout << pub.G;
cout << "cipher size: " << priv.cipher_size() << ' ' << pub.cipher_size() << endl;
cout << "plain size: " << priv.plain_size() << ' ' << pub.plain_size() << endl;
#if 0
/* mce encryption test */
ccr::bvector plain;
plain.resize (pub.plain_size(), 0);
plain[0] = 1;