mce_qd: code generator working
This commit is contained in:
parent
30f873c86b
commit
ec81c53463
|
@ -116,6 +116,9 @@ public:
|
||||||
void generate_random_with_inversion (uint, matrix&, prng&);
|
void generate_random_with_inversion (uint, matrix&, prng&);
|
||||||
bool create_goppa_generator (matrix&, permutation&, prng&);
|
bool create_goppa_generator (matrix&, permutation&, prng&);
|
||||||
bool create_goppa_generator (matrix&, const permutation&);
|
bool create_goppa_generator (matrix&, const permutation&);
|
||||||
|
|
||||||
|
bool create_goppa_generator_dyadic (matrix&, uint&, prng&);
|
||||||
|
bool create_goppa_generator_dyadic (matrix&, uint);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -131,7 +134,7 @@ public:
|
||||||
|
|
||||||
void generate_random (uint n, prng&);
|
void generate_random (uint n, prng&);
|
||||||
|
|
||||||
template<class V> void permute (const V&a, V&r) const {
|
template<class A, class R> void permute (const A&a, R&r) const {
|
||||||
r.resize (a.size() );
|
r.resize (a.size() );
|
||||||
for (uint i = 0; i < size(); ++i) r[item (i) ] = a[i];
|
for (uint i = 0; i < size(); ++i) r[item (i) ] = a[i];
|
||||||
}
|
}
|
||||||
|
@ -139,8 +142,8 @@ public:
|
||||||
void permute_rows (const matrix&, matrix&) const;
|
void permute_rows (const matrix&, matrix&) const;
|
||||||
|
|
||||||
//work-alike for dyadic permutations.
|
//work-alike for dyadic permutations.
|
||||||
template<class V> static bool permute_dyadic
|
template<class A, class R> static bool permute_dyadic
|
||||||
(uint sig, const V&a, V&r) {
|
(uint sig, const A&a, R&r) {
|
||||||
|
|
||||||
//check if the thing has size 2^n
|
//check if the thing has size 2^n
|
||||||
uint s = a.size();
|
uint s = a.size();
|
||||||
|
@ -365,7 +368,8 @@ int generate (pubkey&, privkey&, prng&, uint m, uint t);
|
||||||
*
|
*
|
||||||
* Good security, extremely good speed with extremely reduced key size.
|
* Good security, extremely good speed with extremely reduced key size.
|
||||||
* Recommended for encryption, but needs some plaintext conversion -- either
|
* Recommended for encryption, but needs some plaintext conversion -- either
|
||||||
* Fujisaki-Okamoto or Kobara-Imai are known to work good.
|
* Fujisaki-Okamoto or Kobara-Imai are known to work good. Without the
|
||||||
|
* conversion, the encryption itself is extremely weak.
|
||||||
*/
|
*/
|
||||||
namespace mce_qd
|
namespace mce_qd
|
||||||
{
|
{
|
||||||
|
@ -375,9 +379,9 @@ public:
|
||||||
std::vector<uint> essence;
|
std::vector<uint> essence;
|
||||||
gf2m fld; //we fix q=2^fld.m=fld.n, n=q/2
|
gf2m fld; //we fix q=2^fld.m=fld.n, n=q/2
|
||||||
uint T; //the QD's t parameter is 2^T.
|
uint T; //the QD's t parameter is 2^T.
|
||||||
uint hperm; //dyadic permutation of H to G
|
|
||||||
permutation block_perm; //order of blocks
|
permutation block_perm; //order of blocks
|
||||||
uint block_count; //blocks >= block_count are shortened-out
|
uint block_count; //blocks >= block_count are shortened-out
|
||||||
|
permutation hperm; //block permutation of H block used to get G
|
||||||
std::vector<uint> block_perms; //dyadic permutations of blocks
|
std::vector<uint> block_perms; //dyadic permutations of blocks
|
||||||
|
|
||||||
//derivable stuff
|
//derivable stuff
|
||||||
|
@ -400,7 +404,7 @@ class pubkey
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint T;
|
uint T;
|
||||||
matrix M;
|
std::vector<bvector> qd_sigs;
|
||||||
|
|
||||||
int encrypt (const bvector&, bvector&, prng&);
|
int encrypt (const bvector&, bvector&, prng&);
|
||||||
|
|
||||||
|
|
|
@ -128,19 +128,63 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
|
||||||
Hsig.begin() + (i + 1) * block_size);
|
Hsig.begin() + (i + 1) * block_size);
|
||||||
|
|
||||||
//permute them
|
//permute them
|
||||||
permutation bp;
|
priv.block_perm.generate_random (h_block_count, rng);
|
||||||
bp.generate_random (h_block_count, rng);
|
priv.block_perm.permute (bl, blp);
|
||||||
bp.permute (bl, blp);
|
|
||||||
|
|
||||||
//discard blocks
|
//discard blocks
|
||||||
blp.resize (block_count);
|
blp.resize (block_count);
|
||||||
|
|
||||||
//TODO permute individual blocks
|
//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) {
|
||||||
|
priv.block_perms[i] = rng.random (block_size);
|
||||||
|
permutation::permute_dyadic (priv.block_perms[i],
|
||||||
|
blp[i], bl[i]);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO co-trace to binary H^
|
//co-trace blocks to binary H^, retry creating G using hperm.
|
||||||
//TODO systematic H
|
matrix Hc;
|
||||||
//TODO systematic G
|
polynomial col;
|
||||||
//TODO signature of G
|
Hc.resize (block_count * block_size);
|
||||||
|
|
||||||
|
matrix r, ri, l;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
priv.hperm.generate_random (block_count, rng);
|
||||||
|
|
||||||
|
for (uint i = 0; i < block_count; ++i)
|
||||||
|
for (uint j = 0; j < block_size; ++j) {
|
||||||
|
permutation::permute_dyadic
|
||||||
|
(j, bl[priv.hperm[i]], col);
|
||||||
|
Hc[i*block_size + j].from_poly_cotrace
|
||||||
|
(col, fld);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try computing the redundancy block of G
|
||||||
|
*
|
||||||
|
* Since H*G^T = [L | R] * [I | X] = L + R*X = 0
|
||||||
|
* we have the solution: X = R^1 * L
|
||||||
|
*/
|
||||||
|
|
||||||
|
Hc.get_right_square (r);
|
||||||
|
if (!r.compute_inversion (ri) )
|
||||||
|
continue; //retry with other hperm
|
||||||
|
Hc.strip_right_square (l);
|
||||||
|
ri.mult (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redundancy-checking part of G is now (transposed) in ri.
|
||||||
|
* Get QD signatures by getting every t'th row (transposed).
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub.T = T;
|
||||||
|
pub.qd_sigs.resize (ri.width() / t);
|
||||||
|
for (uint i = 0; i < ri.width(); i += t)
|
||||||
|
pub.qd_sigs[i/t] = ri[i];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -148,17 +192,20 @@ int mce_qd::generate (pubkey&pub, privkey&priv, prng&rng,
|
||||||
|
|
||||||
int privkey::prepare()
|
int privkey::prepare()
|
||||||
{
|
{
|
||||||
|
//TODO compute H signature from essence
|
||||||
|
//TODO compute goppa code support
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
|
int pubkey::encrypt (const bvector& in, bvector&out, prng&rng)
|
||||||
{
|
{
|
||||||
|
//TODO FWHT
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int privkey::decrypt (const bvector&in, bvector&out)
|
int privkey::decrypt (const bvector&in, bvector&out)
|
||||||
{
|
{
|
||||||
|
//TODO decoding
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue