1
0
mirror of https://github.com/biergaizi/codecrypt synced 2024-06-25 16:28:15 +00:00

bvector: use faster to/from string/byte conversion

This commit is contained in:
Mirek Kratochvil 2015-11-07 23:17:09 +01:00
parent bbca109f8b
commit a7ffdbdee0
6 changed files with 85 additions and 71 deletions

@ -519,7 +519,7 @@ int action_decrypt (bool armor, const std::string&symmetric,
return 1;
}
if (!plaintext.to_string (data)) {
if (!plaintext.to_string_check (data)) {
err ("error: malformed data");
return 1;
}
@ -862,7 +862,8 @@ int action_verify (bool armor, const std::string&detach,
sencode_destroy (M);
std::string tmp;
if (!msg.message.to_string (tmp) || tmp != MSG_CLEARTEXT) {
if (!msg.message.to_string_check (tmp)
|| tmp != MSG_CLEARTEXT) {
err ("error: malformed cleartext signature");
return 1;
}
@ -913,7 +914,8 @@ int action_verify (bool armor, const std::string&detach,
sencode_destroy (M);
std::string tmp;
if (!msg.message.to_string (tmp) || tmp != MSG_DETACHED) {
if (!msg.message.to_string_check (tmp)
|| tmp != MSG_DETACHED) {
err ("error: malformed detached signature");
return 1;
}
@ -1210,7 +1212,7 @@ int action_decrypt_verify (bool armor, bool yes,
return 1;
}
if (!bv.to_string (data)) {
if (!bv.to_string_check (data)) {
err ("error: malformed data");
return 1;
}

@ -133,20 +133,15 @@ static void msg_pad_length (const std::vector<byte>& msg,
static void message_pad (const bvector&in, std::vector<byte>&out,
prng&rng, hash_func&pad_hash)
{
out.clear();
in.to_bytes (out);
//make space for the bit stage
if (in.size() == 0) out.resize (1, 0);
else out.resize ( ( (in.size() - 1) >> 3) + 2, 0);
//copy message bits
uint i;
for (i = 0; i < in.size(); ++i)
if (in[i]) out[i >> 3] |= 1 << (i & 0x7);
out.resize (out.size() + 1, 0);
//pad with random bits to whole byte
unsigned char rtmp = rng.random (256);
for (; i & 0x7; ++i)
uint i;
for (i = in.size(); i & 0x7; ++i)
if (rtmp >> (i & 0x7))
out[i >> 3] |= 1 << (i & 0x7);
@ -214,10 +209,7 @@ static bool message_unpad (std::vector<byte> in, bvector&out,
//convert to bvector
uint msg_size = ( (in_end - (bit_overflow ? 2 : 1)) << 3)
+ bit_overflow;
out.clear();
out.resize (msg_size);
for (uint i = 0; i < msg_size; ++i)
out[i] = 1 & (in[i >> 3] >> (i & 0x7));
out.from_bytes (in, msg_size);
return true;
}
@ -275,7 +267,7 @@ static int fo_encrypt (const bvector&plain, bvector&cipher,
hash_type hf;
H = hf (M2);
//prepare the error vector
//prepare the error vector (rotate the hash so we don't need ultralong hash functions)
bvector ev_rank;
ev_rank.resize (ranksize);
for (i = 0; i < ranksize; ++i)
@ -286,8 +278,8 @@ static int fo_encrypt (const bvector&plain, bvector&cipher,
//prepare plaintext
bvector mce_plain;
mce_plain.resize (plainsize);
for (i = 0; i < plainsize; ++i) mce_plain[i] = 1 & (K[i >> 3] >> (i & 0x7));
mce_plain.from_bytes (K);
mce_plain.resize (plainsize, 0); //pad with 0's to exact size
//run McEliece
if (Pub.encrypt (mce_plain, cipher, ev)) return 5;
@ -301,11 +293,10 @@ static int fo_encrypt (const bvector&plain, bvector&cipher,
//encrypt
for (i = 0; i < M.size(); ++i) M[i] = M[i] ^ sc.gen();
//append the message part to the ciphertext
cipher.resize (ciphersize + (M.size() << 3));
for (i = 0; i < (M.size() << 3); ++i)
cipher[ciphersize + i] = 1 & (M[i >> 3] >> (i & 0x7));
//append the message part to the key block.
bvector Mb;
Mb.from_bytes (M);
cipher.append (Mb);
return 0;
}
@ -375,13 +366,14 @@ static int fo_decrypt (const bvector&cipher, bvector&plain,
//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);
M.resize (msize >> 3, 0);
for (i = 0; i < msize; ++i)
if (cipher[ciphersize + i]) M[i >> 3] |= 1 << (i & 0x7);
bvector Kb;
mce_plain.get_block (0, plainsize, Kb);
Kb.to_bytes (K);
bvector Mb;
cipher.get_block (ciphersize, msize, Mb);
Mb.to_bytes (M);
//prepare symmetric cipher
scipher sc;
@ -403,7 +395,7 @@ static int fo_decrypt (const bvector&cipher, bvector&plain,
bvector ev_rank;
ev.colex_rank (ev_rank);
ev_rank.resize (ranksize, 0);
for (i = 0; i < ranksize; ++i)
for (i = 0; i < ranksize; ++i) //cyclic hash repetition again
if (ev_rank[i] != (1 & (H[ (i >> 3) % H.size()]
>> (i & 0x7))))
return 7;

@ -57,16 +57,12 @@
typedef chacha20 padding_generator;
static void msg_pad (const bvector&in, std::vector<byte>&out, size_t minsize)
static void msg_pad (const bvector&in, std::vector<byte>&out, size_t tgt_size)
{
uint i;
out.clear();
out.resize ( ( (in.size() - 1) >> 3) + 1, 0);
for (i = 0; i < in.size(); ++i)
if (in[i]) out[i >> 3] |= 1 << (i & 0x7);
if (out.size() >= minsize) return;
in.to_bytes (out);
if (out.size() >= tgt_size) return;
padding_generator g;
g.init ();
@ -74,8 +70,8 @@ static void msg_pad (const bvector&in, std::vector<byte>&out, size_t minsize)
g.load_key_vector (out);
i = out.size();
out.resize (minsize);
for (; i < minsize; ++i) out[i] = g.gen();
out.resize (tgt_size);
for (; i < tgt_size; ++i) out[i] = g.gen();
}
/*
@ -106,8 +102,7 @@ static int fmtseq_generic_sign (const bvector&msg,
//convert to bvector
bvector hash;
hash.resize (hs, 0);
for (uint i = 0; i < hs; ++i) hash[i] = 1 & (H[i >> 3] >> (i & 0x7));
hash.from_bytes (H);
//make a signature
tree_hash hf;
@ -145,8 +140,7 @@ static int fmtseq_generic_verify (const bvector&sig,
//convert to bvector
bvector hash;
hash.resize (hs, 0);
for (uint i = 0; i < hs; ++i) hash[i] = 1 & (H[i >> 3] >> (i & 0x7));
hash.from_bytes (H);
//check the signature
tree_hash hf;

@ -199,6 +199,7 @@ void bvector::get_block (size_t offset, size_t bs, bvector&out) const
uint bvector::and_hamming_weight (const bvector&a) const
{
/* sizes must match */
uint r = 0;
size_t s = _data.size();
if (s > a._data.size()) s = a._data.size();
@ -222,26 +223,48 @@ void bvector::from_poly_cotrace (const polynomial&r, gf2m&fld)
item (i) = (r[i % s] >> (i / s)) & 1;
}
bool bvector::to_string (std::string& out) const
void bvector::to_bytes (std::vector<byte>& out) const
{
if (size() & 0x7) return false;
out.resize ( (size() + 7) >> 3, 0);
out.clear();
out.resize (size() >> 3, 0);
for (size_t i = 0; i < size(); ++i)
if (item (i)) out[i >> 3] |= (1 << (i & 0x7));
return true;
for (size_t i = 0; i < size(); i += 8)
out[i >> 3] = (_data[i >> 6]
>> ( ( (i >> 3) & 7) << 3)) & 0xff;
}
void bvector::from_string (const std::string&in)
void bvector::to_string (std::string& out) const
{
clear();
resize (in.length() << 3);
out.resize ( (size() + 7) >> 3, '\0');
for (size_t i = 0; i < size(); ++i)
item (i) = (in[i >> 3] >> (i & 0x7)) & 1;
for (size_t i = 0; i < size(); i += 8)
out[i >> 3] = (_data[i >> 6]
>> ( ( (i >> 3) & 7) << 3)) & 0xff;
}
void bvector::from_string (const std::string&in, size_t bits)
{
if (bits) resize (bits);
else resize (in.length() << 3);
fill_zeros();
for (size_t i = 0; i < size(); i += 8)
_data[i >> 6] |=
( (uint64_t) (unsigned char) in[i >> 3])
<< ( ( (i >> 3) & 7) << 3);
fix_padding();
}
void bvector::from_bytes (const std::vector<byte>&in, size_t bits)
{
if (bits) resize (bits);
else resize (in.size() << 3);
fill_zeros();
for (size_t i = 0; i < size(); i += 8)
_data[i >> 6] |=
( (uint64_t) (unsigned char) in[i >> 3])
<< ( ( (i >> 3) & 7) << 3);
fix_padding();
}
/*

@ -197,8 +197,17 @@ public:
void colex_rank (bvector&) const;
bool colex_unrank (bvector&, uint n, uint k) const;
bool to_string (std::string&) const;
void from_string (const std::string&);
void to_string (std::string&) const;
void to_bytes (std::vector<byte>&) const;
bool to_string_check (std::string&s) const {
if (size() & 7) return false;
to_string (s);
return true;
}
void from_string (const std::string&, size_t bits = 0);
void from_bytes (const std::vector<byte>&, size_t bits = 0);
sencode* serialize();
bool unserialize (sencode*);

@ -62,14 +62,10 @@ static bool unserialize_uint_vector (std::vector<uint>*v, sencode*s)
sencode* bvector::serialize()
{
uint ss = (size() + 7) / 8;
std::string bytes;
bytes.resize (ss, '\0');
//the padding of each vector is zero, we can stuff the bytes right in. Just make it sure here:
fix_padding();
for (size_t i = 0; i < size(); i += 8)
bytes[i >> 3] = (_data[i >> 6] >> ( ( (i >> 3) & 7) << 3)) & 0xff;
to_string (bytes);
sencode_list*l = new sencode_list;
l->items.push_back (new sencode_int (size()));
@ -85,19 +81,17 @@ bool bvector::unserialize (sencode* s)
sencode_int*CAST_INT (l->items[0], size);
sencode_bytes*CAST_BYTES (l->items[1], bytes);
if (bytes->b.size() != ( (size->i + 7) / 8)) return false;
clear();
resize (size->i, 0);
for (i = 0; i < _size; i += 8)
_data[i >> 6] |= ( (uint64_t) (unsigned char) bytes->b[i >> 3]) << ( ( (i >> 3) & 7) << 3);
/*
* the important part. verify that padding is always zero, because
* sencode serialization must be bijective
*/
for (i = _size; i < 8 * bytes->b.size(); ++i)
for (i = size->i; i < 8 * bytes->b.size(); ++i)
if ( (bytes->b[i / 8] >> (i % 8)) & 1)
return false;
from_string (bytes->b, size->i);
return true;
}