[tahoe-dev] [pycryptopp] #2: deterministic generation of private key from small seed
pycryptopp
trac at allmydata.org
Mon Mar 2 21:19:23 PST 2009
#2: deterministic generation of private key from small seed
------------------------+---------------------------------------------------
Reporter: zooko | Owner: zooko
Type: enhancement | Status: new
Priority: major | Version: 0.4.0
Keywords: | Launchpad_bug:
------------------------+---------------------------------------------------
Changes (by zooko):
* cc: tahoe-dev@… (added)
Comment:
I posted to the cryptopp-users mailing list asking for feedback about my
current approach:
http://groups.google.com/group/cryptopp-users/msg/01a2620f684a70bd
-------
I am about to implement "deterministic generation of private key from
small seed" [1] for Tahoe, so I need to come up with a function that takes
an input of 96 bits and produces a 192-bit ECDSA private key. I'm going
to have to support this functon forever (approximately) for backwards-
compatibility reasons. I would really like the next release of Tahoe to
be compatible with older Crypto++ versions. Also I would really like for
this function to be as simple and clear as possible so that I can easily
explain to other people how to implement it compatibly.
My current code to do this is below (and I've earlier posted it to this
list: [2]), but I'm not entirely satisfied with it because it seems rather
ad-hoc. One of my earlier notes on this subject to this list, [2], says
that I experimented with using X917RNG with a customization of Salsa20 to
pretend that it has a block size of 32.
So, I ask everyone, what is the simplest efficient way to take a secret
96-bit input, and produce an output between [1, n) such that
a) if you know the 96-bit secret and use this algorithm, you always get
the same output, and
b) if you don't know the 96-bit secret, you can't learn anything about the
output
Unless I, or someone, can think of a problem with this way to do it, or
can propose a better way to do it, then I guess I'm going to proceed with
this and then I'll be committed to maintaining it for a while.
Regards,
Zooko
[1] http://allmydata.org/trac/pycryptopp/ticket/2 # deterministic
generation of private key from small seed
[2] http://groups.google.com/group/cryptopp-
users/browse_thread/thread/f30427601a5884f6
[3] http://groups.google.com/group/cryptopp-users/msg/c1041e508c8d8705
------- begin appended code
static const char* TAG_AND_SALT = "102:pycryptopp v0.5.3 key derivation
algorithm using Tiger hash to generate ECDSA 192-bit secret exponents," \
"16:H1yGNvUONoc0FD1d,";
static const size_t TAG_AND_SALT_len = 127;
static int
SigningKey___init__(PyObject* self, PyObject* args, PyObject* kwdict) {
static const char *kwlist[] = { "seed", NULL };
const char* seed;
int seedlen;
if (!PyArg_ParseTupleAndKeywords(args, kwdict,
"t#:SigningKey___init__", const_cast<char**>(kwlist), &seed, &seedlen)) {
return -1;
}
if (seedlen != 12) {
PyErr_Format(ecdsa_error, "Precondition violation: seed is
required to be of length 12, but it was %d", seedlen);
return -1;
}
OID curve;
Integer grouporderm1;
byte privexpbytes[24] = {0};
Integer privexponentm1;
privexponentm1.Decode(privexpbytes, sizeof(privexpbytes)); assert
(priveexponentm1 == 0); // just checking..
curve = ASN1::secp192r1();
grouporderm1 = DL_GroupParameters_EC<ECP>(curve).GetGroupOrder() - 1;
Tiger t;
t.Update(reinterpret_cast<const byte*>(TAG_AND_SALT),
TAG_AND_SALT_len);
t.Update(reinterpret_cast<const byte*>(seed), seedlen);
t.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE);
privexponentm1.Decode(privexpbytes, sizeof(privexpbytes));
while (privexponentm1 >= grouporderm1) {
Tiger t2;
t2.Update(reinterpret_cast<const byte*>(TAG_AND_SALT),
TAG_AND_SALT_len);
t2.Update(privexpbytes, sizeof(privexpbytes));
t2.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE);
privexponentm1.Decode(privexpbytes, sizeof(privexpbytes));
}
SigningKey* mself = reinterpret_cast<SigningKey*>(self);
mself->k.AccessKey().Initialize(curve, privexponentm1+1);
return 0;
}
--
Ticket URL: <http://allmydata.org/trac/pycryptopp/ticket/2#comment:4>
pycryptopp <http://allmydata.org/trac/pycryptopp>
Python bindings for the Crypto++ library
More information about the tahoe-dev
mailing list