algos_enc: f-o decryption
This commit is contained in:
parent
0f2db0b62c
commit
7a48eff37a
|
@ -78,7 +78,8 @@ int algo_mceqd256::create_keypair (sencode**pub, sencode**priv, prng&rng)
|
||||||
*
|
*
|
||||||
* Note that:
|
* Note that:
|
||||||
* - the last block is _always present_
|
* - the last block is _always present_
|
||||||
* (even if there's no message bytes in it.)
|
* (even if there are no message bytes in it, there still must be the zero
|
||||||
|
* 1byte number that is telling us.)
|
||||||
* - stuff in bytes is always thought about as big-endian
|
* - stuff in bytes is always thought about as big-endian
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -161,11 +162,11 @@ static bool message_unpad (const std::vector<byte>&in, bvector&out)
|
||||||
#include "arcfour.h"
|
#include "arcfour.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic F-O encryption function. Note that ranksize must be equal to
|
* Generic F-O functions. Note that ranksize must be equal to
|
||||||
*
|
*
|
||||||
* floor(log(comb(ciphersize,errorcount))/log(2))
|
* floor(log(comb(ciphersize,errorcount))/log(2))
|
||||||
*
|
*
|
||||||
* otherwise it probably fails miserably.
|
* otherwise it probably fails. miserably.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template < class pubkey_type,
|
template < class pubkey_type,
|
||||||
|
@ -207,7 +208,8 @@ static int fo_encrypt (const bvector&plain, bvector&cipher,
|
||||||
//prepare the error vector
|
//prepare the error vector
|
||||||
bvector ev_rank;
|
bvector ev_rank;
|
||||||
ev_rank.resize (ranksize);
|
ev_rank.resize (ranksize);
|
||||||
for (i = 0; i < ranksize; ++i) ev_rank[i] = 1 & (H[ (i >> 3) % H.size()] >> (i & 0x7) );
|
for (i = 0; i < ranksize; ++i)
|
||||||
|
ev_rank[i] = 1 & (H[ (i >> 3) % H.size()] >> (i & 0x7) );
|
||||||
|
|
||||||
bvector ev;
|
bvector ev;
|
||||||
ev_rank.colex_unrank (ev, ciphersize, errorcount);
|
ev_rank.colex_unrank (ev, ciphersize, errorcount);
|
||||||
|
@ -250,7 +252,6 @@ template < class privkey_type,
|
||||||
static int fo_decrypt (const bvector&cipher, bvector&plain,
|
static int fo_decrypt (const bvector&cipher, bvector&plain,
|
||||||
sencode* privkey)
|
sencode* privkey)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
//load the key
|
//load the key
|
||||||
|
@ -262,14 +263,67 @@ static int fo_decrypt (const bvector&cipher, bvector&plain,
|
||||||
if (Priv.cipher_size() != ciphersize) return 1;
|
if (Priv.cipher_size() != ciphersize) return 1;
|
||||||
if (Priv.error_count() != errorcount) return 1;
|
if (Priv.error_count() != errorcount) return 1;
|
||||||
|
|
||||||
//TODO
|
//get the McE part
|
||||||
//split the message into McE and Arcfour parts
|
if (cipher.size() < ciphersize) return 2;
|
||||||
//decrypt the symmetric key
|
bvector mce_cipher, mce_plain, ev;
|
||||||
//decrypt the message part
|
mce_cipher.insert (mce_cipher.end(),
|
||||||
//check the hash
|
cipher.begin(),
|
||||||
//unpad the message
|
cipher.begin() + ciphersize);
|
||||||
|
|
||||||
return -1;
|
//decrypt the symmetric key
|
||||||
|
if (Priv.decrypt (mce_cipher, mce_plain, ev) ) return 2;
|
||||||
|
|
||||||
|
//convert stuff to byte vectors
|
||||||
|
std::vector<byte> K, M;
|
||||||
|
K.resize (plainsize >> 3, 0);
|
||||||
|
for (i = 0; i < plainsize; ++i)
|
||||||
|
if (mce_plain[i]) K[i >> 3] |= 1 << (i & 0x7);
|
||||||
|
|
||||||
|
uint msize = cipher.size() - ciphersize;
|
||||||
|
if (msize & 0x7) return 2;
|
||||||
|
M.resize (msize >> 3, 0);
|
||||||
|
for (i = 0; i < msize; ++i)
|
||||||
|
if (cipher[ciphersize + i]) M[i >> 3] |= 1 << (i & 0x7);
|
||||||
|
|
||||||
|
//prepare arcfour
|
||||||
|
arcfour<byte> arc;
|
||||||
|
arc.init (8);
|
||||||
|
//stuff in the whole key
|
||||||
|
for (i = 0; i < (K.size() >> 8); ++i) {
|
||||||
|
std::vector<byte> subkey (K.begin() + (i << 8),
|
||||||
|
min (K.end(),
|
||||||
|
K.begin() + ( (i + 1) << 8) ) );
|
||||||
|
arc.load_key (subkey);
|
||||||
|
}
|
||||||
|
arc.discard (256);
|
||||||
|
//decrypt the message part
|
||||||
|
for (i = 0; i < M.size(); ++i) M[i] = M[i] ^ arc.gen();
|
||||||
|
|
||||||
|
//compute the hash of K+M
|
||||||
|
std::vector<byte>H, M2;
|
||||||
|
M2 = M;
|
||||||
|
M2.insert (M2.end(), K.begin(), K.end() );
|
||||||
|
hash_type hf;
|
||||||
|
H = hf (M2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare the error vector (again. Avoiding colex ranking which is
|
||||||
|
* little less deterministic than it could be (produces varying amounts
|
||||||
|
* of whitespace)
|
||||||
|
*/
|
||||||
|
bvector ev_rank, ev2;
|
||||||
|
ev_rank.resize (ranksize);
|
||||||
|
for (i = 0; i < ranksize; ++i)
|
||||||
|
ev_rank[i] = 1 & (H[ (i >> 3) % H.size()] >> (i & 0x7) );
|
||||||
|
ev_rank.colex_unrank (ev2, ciphersize, errorcount);
|
||||||
|
|
||||||
|
//now it should match, otherwise someone mangled the message.
|
||||||
|
if (ev != ev2) return 3;
|
||||||
|
|
||||||
|
//if the message seems okay, unpad and return it.
|
||||||
|
if (!message_unpad (M, plain) ) return 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -315,7 +369,7 @@ int algo_mceqd256::decrypt (const bvector&cipher, bvector&plain,
|
||||||
return fo_decrypt
|
return fo_decrypt
|
||||||
< mce_qd::privkey,
|
< mce_qd::privkey,
|
||||||
4096, 8192, 256,
|
4096, 8192, 256,
|
||||||
sha256hash,
|
sha512hash,
|
||||||
1638 >
|
1638 >
|
||||||
(cipher, plain, privkey);
|
(cipher, plain, privkey);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue