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. * 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, static int fmtseq_generic_sign (const bvector&msg,
bvector&sig, bvector&sig,
sencode**privkey, sencode**privkey,
@ -110,7 +111,8 @@ static int fmtseq_generic_sign (const bvector&msg,
//make a signature //make a signature
tree_hash hf; 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 //if it went okay, refresh the privkey
sencode* new_pk = Priv.serialize(); sencode* new_pk = Priv.serialize();
@ -154,15 +156,16 @@ static int fmtseq_generic_verify (const bvector&sig,
return 0; 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) static int fmtseq_create_keypair (sencode**pub, sencode**priv, prng&rng)
{ {
fmtseq::pubkey Pub; fmtseq::pubkey Pub;
fmtseq::privkey Priv; fmtseq::privkey Priv;
treehash hf; 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; return 1;
*pub = Pub.serialize(); *pub = Pub.serialize();
@ -175,6 +178,8 @@ static int fmtseq_create_keypair (sencode**pub, sencode**priv, prng&rng)
* actual instantiations * actual instantiations
*/ */
#include "chacha.h"
#if HAVE_CRYPTOPP==1 #if HAVE_CRYPTOPP==1
#include "sha_hash.h" #include "sha_hash.h"
@ -188,7 +193,7 @@ int algo_fmtseq128::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 256, sha256hash, rmd128hash> <4, 4, 256, sha256hash, rmd128hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -208,7 +213,7 @@ int algo_fmtseq192::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 384, sha384hash, tiger192hash> <4, 4, 384, sha384hash, tiger192hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -228,7 +233,7 @@ int algo_fmtseq256::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 512, sha512hash, sha256hash> <4, 4, 512, sha512hash, sha256hash, chacha20>
(msg, sig, privkey, dirty, rng); (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) 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); (pub, priv, rng);
} }
int algo_fmtseq192::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
int algo_fmtseq256::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
@ -273,7 +278,7 @@ int algo_fmtseq128h20::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 256, sha256hash, rmd128hash> <4, 5, 256, sha256hash, rmd128hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -293,7 +298,7 @@ int algo_fmtseq192h20::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 384, sha384hash, tiger192hash> <4, 5, 384, sha384hash, tiger192hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -313,7 +318,7 @@ int algo_fmtseq256h20::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 512, sha512hash, sha256hash> <4, 5, 512, sha512hash, sha256hash, chacha20>
(msg, sig, privkey, dirty, rng); (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) 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); (pub, priv, rng);
} }
int algo_fmtseq192h20::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
int algo_fmtseq256h20::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
@ -359,7 +364,7 @@ int algo_fmtseq128cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 256, cube256hash, cube128hash> <4, 4, 256, cube256hash, cube128hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -379,7 +384,7 @@ int algo_fmtseq192cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 384, cube384hash, cube192hash> <4, 4, 384, cube384hash, cube192hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -399,7 +404,7 @@ int algo_fmtseq256cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 4, 512, cube512hash, cube256hash> <4, 4, 512, cube512hash, cube256hash, chacha20>
(msg, sig, privkey, dirty, rng); (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) 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); (pub, priv, rng);
} }
int algo_fmtseq192cube::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
int algo_fmtseq256cube::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
@ -441,7 +446,7 @@ int algo_fmtseq128h20cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 256, cube256hash, cube128hash> <4, 5, 256, cube256hash, cube128hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -461,7 +466,7 @@ int algo_fmtseq192h20cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 384, cube384hash, cube192hash> <4, 5, 384, cube384hash, cube192hash, chacha20>
(msg, sig, privkey, dirty, rng); (msg, sig, privkey, dirty, rng);
} }
@ -481,7 +486,7 @@ int algo_fmtseq256h20cube::sign (const bvector&msg,
prng&rng) prng&rng)
{ {
return fmtseq_generic_sign return fmtseq_generic_sign
<4, 5, 512, cube512hash, cube256hash> <4, 5, 512, cube512hash, cube256hash, chacha20>
(msg, sig, privkey, dirty, rng); (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) 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); (pub, priv, rng);
} }
int algo_fmtseq192h20cube::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }
int algo_fmtseq256h20cube::create_keypair (sencode**pub, sencode**priv, prng&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); (pub, priv, rng);
} }

View file

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

View file

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

View file

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

View file

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