fmtseq: remove internal rc4 usage, use chacha20

Result is incompatible with previous version. Those just shouldn't be
used anymore.
This commit is contained in:
Mirek Kratochvil 2014-04-05 14:04:08 +02:00
parent 37d9c9a98e
commit c5cf430ab5
5 changed files with 66 additions and 65 deletions

View file

@ -82,7 +82,8 @@ static void msg_pad (const bvector&in, std::vector<byte>&out, size_t minsize)
* actual signature stuff.
*/
template <int h, int l, int hs, class message_hash, class tree_hash>
template < int h, int l, int hs,
class message_hash, class tree_hash, class generator >
static int fmtseq_generic_sign (const bvector&msg,
bvector&sig,
sencode**privkey,
@ -110,7 +111,8 @@ static int fmtseq_generic_sign (const bvector&msg,
//make a signature
tree_hash hf;
if (Priv.sign (hash, sig, hf) ) return 3;
generator g;
if (Priv.sign (hash, sig, hf, g) ) return 3;
//if it went okay, refresh the privkey
sencode* new_pk = Priv.serialize();
@ -154,15 +156,16 @@ static int fmtseq_generic_verify (const bvector&sig,
return 0;
}
template<class treehash, int hs, int h, int l>
template<class treehash, class generator, int hs, int h, int l>
static int fmtseq_create_keypair (sencode**pub, sencode**priv, prng&rng)
{
fmtseq::pubkey Pub;
fmtseq::privkey Priv;
treehash hf;
generator g;
if (fmtseq::generate (Pub, Priv, rng, hf, hs, h, l) )
if (fmtseq::generate (Pub, Priv, rng, hf, g, hs, h, l) )
return 1;
*pub = Pub.serialize();
@ -175,6 +178,8 @@ static int fmtseq_create_keypair (sencode**pub, sencode**priv, prng&rng)
* actual instantiations
*/
#include "chacha.h"
#if HAVE_CRYPTOPP==1
#include "sha_hash.h"
@ -188,7 +193,7 @@ int algo_fmtseq128::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 256, sha256hash, rmd128hash>
<4, 4, 256, sha256hash, rmd128hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -208,7 +213,7 @@ int algo_fmtseq192::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 384, sha384hash, tiger192hash>
<4, 4, 384, sha384hash, tiger192hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -228,7 +233,7 @@ int algo_fmtseq256::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 512, sha512hash, sha256hash>
<4, 4, 512, sha512hash, sha256hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -243,19 +248,19 @@ int algo_fmtseq256::verify (const bvector&sig,
int algo_fmtseq128::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<rmd128hash, 256, 4, 4>
return fmtseq_create_keypair<rmd128hash, chacha20, 256, 4, 4>
(pub, priv, rng);
}
int algo_fmtseq192::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<tiger192hash, 384, 4, 4>
return fmtseq_create_keypair<tiger192hash, chacha20, 384, 4, 4>
(pub, priv, rng);
}
int algo_fmtseq256::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<sha256hash, 512, 4, 4>
return fmtseq_create_keypair<sha256hash, chacha20, 512, 4, 4>
(pub, priv, rng);
}
@ -273,7 +278,7 @@ int algo_fmtseq128h20::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 256, sha256hash, rmd128hash>
<4, 5, 256, sha256hash, rmd128hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -293,7 +298,7 @@ int algo_fmtseq192h20::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 384, sha384hash, tiger192hash>
<4, 5, 384, sha384hash, tiger192hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -313,7 +318,7 @@ int algo_fmtseq256h20::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 512, sha512hash, sha256hash>
<4, 5, 512, sha512hash, sha256hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -328,19 +333,19 @@ int algo_fmtseq256h20::verify (const bvector&sig,
int algo_fmtseq128h20::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<rmd128hash, 256, 4, 5>
return fmtseq_create_keypair<rmd128hash, chacha20, 256, 4, 5>
(pub, priv, rng);
}
int algo_fmtseq192h20::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<tiger192hash, 384, 4, 5>
return fmtseq_create_keypair<tiger192hash, chacha20, 384, 4, 5>
(pub, priv, rng);
}
int algo_fmtseq256h20::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<sha256hash, 512, 4, 5>
return fmtseq_create_keypair<sha256hash, chacha20, 512, 4, 5>
(pub, priv, rng);
}
@ -359,7 +364,7 @@ int algo_fmtseq128cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 256, cube256hash, cube128hash>
<4, 4, 256, cube256hash, cube128hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -379,7 +384,7 @@ int algo_fmtseq192cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 384, cube384hash, cube192hash>
<4, 4, 384, cube384hash, cube192hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -399,7 +404,7 @@ int algo_fmtseq256cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 4, 512, cube512hash, cube256hash>
<4, 4, 512, cube512hash, cube256hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -414,19 +419,19 @@ int algo_fmtseq256cube::verify (const bvector&sig,
int algo_fmtseq128cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube128hash, 256, 4, 4>
return fmtseq_create_keypair<cube128hash, chacha20, 256, 4, 4>
(pub, priv, rng);
}
int algo_fmtseq192cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube192hash, 384, 4, 4>
return fmtseq_create_keypair<cube192hash, chacha20, 384, 4, 4>
(pub, priv, rng);
}
int algo_fmtseq256cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube256hash, 512, 4, 4>
return fmtseq_create_keypair<cube256hash, chacha20, 512, 4, 4>
(pub, priv, rng);
}
@ -441,7 +446,7 @@ int algo_fmtseq128h20cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 256, cube256hash, cube128hash>
<4, 5, 256, cube256hash, cube128hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -461,7 +466,7 @@ int algo_fmtseq192h20cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 384, cube384hash, cube192hash>
<4, 5, 384, cube384hash, cube192hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -481,7 +486,7 @@ int algo_fmtseq256h20cube::sign (const bvector&msg,
prng&rng)
{
return fmtseq_generic_sign
<4, 5, 512, cube512hash, cube256hash>
<4, 5, 512, cube512hash, cube256hash, chacha20>
(msg, sig, privkey, dirty, rng);
}
@ -496,18 +501,18 @@ int algo_fmtseq256h20cube::verify (const bvector&sig,
int algo_fmtseq128h20cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube128hash, 256, 4, 5>
return fmtseq_create_keypair<cube128hash, chacha20, 256, 4, 5>
(pub, priv, rng);
}
int algo_fmtseq192h20cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube192hash, 384, 4, 5>
return fmtseq_create_keypair<cube192hash, chacha20, 384, 4, 5>
(pub, priv, rng);
}
int algo_fmtseq256h20cube::create_keypair (sencode**pub, sencode**priv, prng&rng)
{
return fmtseq_create_keypair<cube256hash, 512, 4, 5>
return fmtseq_create_keypair<cube256hash, chacha20, 512, 4, 5>
(pub, priv, rng);
}

View file

@ -33,7 +33,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ128-SHA256-RIPEMD128";
return "FMTSEQ128C-SHA256-RIPEMD128";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -55,7 +55,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ192-SHA384-TIGER192";
return "FMTSEQ192C-SHA384-TIGER192";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -77,7 +77,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ256-SHA512-SHA256";
return "FMTSEQ256C-SHA512-SHA256";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -99,7 +99,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ128H20-SHA256-RIPEMD128";
return "FMTSEQ128H20C-SHA256-RIPEMD128";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -121,7 +121,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ192H20-SHA384-TIGER192";
return "FMTSEQ192H20C-SHA384-TIGER192";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -143,7 +143,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ256H20-SHA512-SHA256";
return "FMTSEQ256H20C-SHA512-SHA256";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -169,7 +169,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ128-CUBE256-CUBE128";
return "FMTSEQ128C-CUBE256-CUBE128";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -191,7 +191,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ192-CUBE384-CUBE192";
return "FMTSEQ192C-CUBE384-CUBE192";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -213,7 +213,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ256-CUBE512-CUBE256";
return "FMTSEQ256C-CUBE512-CUBE256";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -235,7 +235,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ128H20-CUBE256-CUBE128";
return "FMTSEQ128H20C-CUBE256-CUBE128";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -257,7 +257,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ192H20-CUBE384-CUBE192";
return "FMTSEQ192H20C-CUBE384-CUBE192";
}
virtual int sign (const bvector&msg, bvector&sig,
@ -279,7 +279,7 @@ public:
}
std::string get_alg_id() {
return "FMTSEQ256H20-CUBE512-CUBE256";
return "FMTSEQ256H20C-CUBE512-CUBE256";
}
virtual int sign (const bvector&msg, bvector&sig,

View file

@ -40,9 +40,7 @@ public:
}
void clear() {
I = J = 0;
mask = 0;
S.clear();
init();
}
void load_key (const inttype*begin, const inttype*end) {

View file

@ -17,32 +17,25 @@
*/
#include "fmtseq.h"
#include "arcfour.h"
using namespace fmtseq;
typedef arcfour<byte, 8, 0> privgen;
void prepare_keygen (privgen& kg, const std::vector<byte>&SK, uint idx)
void prepare_keygen (streamcipher& kg, const std::vector<byte>&SK, uint idx)
{
kg.clear();
kg.init ();
kg.init();
kg.load_key_vector (SK);
std::vector<byte>tmp;
tmp.reserve (16);
while (idx) {
tmp.push_back (idx & 0xff);
idx >>= 8;
}
tmp.resize (16, 0); //prevent chaining to other numbers
kg.load_key_vector (tmp);
kg.discard (4096);
//discarding is done manually here,
//for the purpose of double key loading.
}
static void add_zero_checksum (bvector& v)
{
uint s = v.size();
if (!s) return;
@ -136,10 +129,9 @@ static bool check_privkey (privkey&priv, hash_func&hf)
return true;
}
static void update_privkey (privkey&priv, hash_func&hf)
static void update_privkey (privkey&priv, hash_func&hf, streamcipher&generator)
{
uint i, j;
privgen generator;
std::vector<byte> x, Y;
uint commitments = fmtseq_commitments (priv.hs);
@ -170,6 +162,8 @@ static void update_privkey (privkey&priv, hash_func&hf)
* whole algorithm is kindof complex. Omitted for simplicity.
*/
x.resize (hf.size() );
uint d_leaves, d_startpos, d_h;
for (i = 0; i < priv.desired.size(); ++i) {
d_h = (i + 1) * priv.h;
@ -184,7 +178,7 @@ static void update_privkey (privkey&priv, hash_func&hf)
prepare_keygen (generator, priv.SK, leafid);
Y.clear();
for (j = 0; j < commitments; ++j) {
generator.gen (hf.size(), x);
generator.gen (hf.size(), & (x[0]) );
x = hf (x);
Y.insert (Y.end(), x.begin(), x.end() );
}
@ -265,7 +259,7 @@ static void update_privkey (privkey&priv, hash_func&hf)
*/
int fmtseq::generate (pubkey&pub, privkey&priv,
prng&rng, hash_func&hf,
prng&rng, hash_func&hf, streamcipher&generator,
uint hs, uint h, uint l)
{
uint i, j;
@ -293,8 +287,8 @@ int fmtseq::generate (pubkey&pub, privkey&priv,
uint commitments = fmtseq_commitments (hs);
privgen generator;
std::vector<byte> x, Y;
x.resize (hf.size() );
alloc_exist (priv);
@ -304,7 +298,7 @@ int fmtseq::generate (pubkey&pub, privkey&priv,
Y.reserve (commitments * hf.size() );
prepare_keygen (generator, priv.SK, i);
for (j = 0; j < commitments; ++j) {
generator.gen (hf.size(), x);
generator.gen (hf.size(), & (x[0]) );
x = hf (x);
Y.insert (Y.end(), x.begin(), x.end() );
}
@ -365,7 +359,8 @@ int fmtseq::generate (pubkey&pub, privkey&priv,
#include "iohelpers.h"
int privkey::sign (const bvector& hash, bvector& sig, hash_func& hf)
int privkey::sign (const bvector& hash, bvector& sig, hash_func& hf,
streamcipher&generator)
{
if (hash.size() != hash_size() ) return 2;
if (!sigs_remaining() ) {
@ -386,13 +381,14 @@ int privkey::sign (const bvector& hash, bvector& sig, hash_func& hf)
std::vector<byte> Sig, t;
uint i;
t.resize (hf.size() );
Sig.reserve (hf.size() * (commitments + h * l) );
//first, compute the commitments and push them to the signature
privgen generator;
prepare_keygen (generator, SK, sigs_used);
for (i = 0; i < commitments; ++i) {
//generate x_i
generator.gen (hf.size(), t);
generator.gen (hf.size(), & (t[0]) );
//if it's 0, publish y_i, else publish x_i
if (!M2[i]) t = hf (t);
@ -432,7 +428,7 @@ int privkey::sign (const bvector& hash, bvector& sig, hash_func& hf)
}
//move to the next signature and update the cache
update_privkey (*this, hf);
update_privkey (*this, hf, generator);
//start moaning at around 1% of remaining signatures
if (!sigs_remaining() )

View file

@ -26,6 +26,7 @@
#include "sencode.h"
#include "hash.h"
#include "prng.h"
#include "sc.h"
/*
* FMTseq - Merkle signatures with fractal tree traversal, using original
@ -70,7 +71,7 @@ public:
std::vector<std::vector<tree_stk_item> > desired_stack;
std::vector<uint> desired_progress;
int sign (const bvector&, bvector&, hash_func&);
int sign (const bvector&, bvector&, hash_func&, streamcipher&);
uint sigs_remaining() {
return (1 << (h * l) ) - sigs_used;
@ -109,7 +110,8 @@ public:
bool unserialize (sencode*);
};
int generate (pubkey&, privkey&, prng&, hash_func&, uint hs, uint h, uint l);
int generate (pubkey&, privkey&, prng&, hash_func&, streamcipher&,
uint hs, uint h, uint l);
}
#endif