| 269 | static Integer |
| 270 | old_kdf(const byte *seed, int seedlen, Integer limit) { |
| 271 | // hash the seed into a private exponent (a number), looping to make sure |
| 272 | // it doesn't exceed the group order. This implements a Tiger-based KDF |
| 273 | Tiger t; |
| 274 | byte privexpbytes[24] = {0}; |
| 275 | Integer privexponentm1; |
| 276 | |
| 277 | t.Update(reinterpret_cast<const byte*>(TAG_AND_SALT), TAG_AND_SALT_len); |
| 278 | t.Update(reinterpret_cast<const byte*>(seed), seedlen); |
| 279 | t.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE); |
| 280 | privexponentm1.Decode(privexpbytes, sizeof(privexpbytes)); |
| 281 | while (privexponentm1 >= limit) { |
| 282 | Tiger t2; |
| 283 | t2.Update(reinterpret_cast<const byte*>(TAG_AND_SALT), TAG_AND_SALT_len); |
| 284 | std::cerr << "WHEE " << sizeof(privexpbytes) << "\n";std::cerr.flush(); |
| 285 | t2.Update(privexpbytes, sizeof(privexpbytes)); |
| 286 | t2.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE); |
| 287 | privexponentm1.Decode(privexpbytes, sizeof(privexpbytes)); |
| 288 | } |
| 289 | return privexponentm1; |
| 290 | } |
| 291 | |
| 292 | static Integer |
| 293 | kdf(const byte *seed, int seedlen, Integer limit) { |
| 294 | // hash the seed into a private exponent (a number), looping to make sure |
| 295 | // it doesn't exceed the group order. This implements HKDF with |
| 296 | // SHA2-512d-truncated-to-256 as the extractor, and SHA2-256d as the |
| 297 | // expander. |
| 298 | return Integer(5); |
| 299 | |
| 300 | // david-sarah suggests: |
| 301 | // start with a seed that is 256 bits long |
| 302 | // compute seed % groupsize |
| 303 | //http://www.cryptopp.com/docs/ref/class_integer.html |
| 304 | //Integer(RandomNumberGenerator &rng, size_t bitcount) |
| 305 | //then operator %= |
| 306 | |
| 307 | } |
| 308 | |
| 309 | // for testing, we expose this. It hashes a seed and returns the (integer) |
| 310 | // private exponent. |
| 311 | PyObject * |
| 312 | _ecdsa_test_kdf(PyObject* self, PyObject* args, PyObject* kwdict) { |
| 313 | static const char *kwlist[] = { "seed", "limit", NULL }; |
| 314 | const byte* seed; |
| 315 | unsigned int limit_arg = 0; |
| 316 | Integer limit; |
| 317 | int seedlen; |
| 318 | if (!PyArg_ParseTupleAndKeywords(args, kwdict, "t#|I:_test_kdf__", |
| 319 | const_cast<char**>(kwlist), |
| 320 | &seed, &seedlen, &limit_arg)) { |
| 321 | return NULL; |
| 322 | } |
| 323 | if (limit_arg != 0) { |
| 324 | limit = Integer(limit_arg); // assume Integer() has an int-taking constructor |
| 325 | } else { |
| 326 | DL_GroupParameters_EC<ECP> params(ASN1::secp192r1()); |
| 327 | params.SetPointCompression(true); |
| 328 | limit = params.GetGroupOrder() - 1; |
| 329 | } |
| 330 | |
| 331 | Integer privexponentm1 = kdf(seed, seedlen, limit); |
| 332 | |
| 333 | // now encode the exponent as a python string, and return to the caller |
| 334 | byte privexpbytes[24]; |
| 335 | assert(privexponentm1.MinEncodedSize() <= 24); |
| 336 | privexponentm1.Encode(privexpbytes, sizeof(privexpbytes)); |
| 337 | PyObject *result; |
| 338 | result = PyString_FromStringAndSize((const char *)privexpbytes, |
| 339 | sizeof(privexpbytes)); |
| 340 | return result; |
| 341 | } |
| 342 | |
| 343 | |
| 344 | |
292 | | Tiger t; |
293 | | |
294 | | t.Update(reinterpret_cast<const byte*>(TAG_AND_SALT), TAG_AND_SALT_len); |
295 | | t.Update(reinterpret_cast<const byte*>(seed), seedlen); |
296 | | t.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE); |
297 | | privexponentm1.Decode(privexpbytes, sizeof(privexpbytes)); |
298 | | |
299 | | while (privexponentm1 >= grouporderm1) { |
300 | | Tiger t2; |
301 | | t2.Update(reinterpret_cast<const byte*>(TAG_AND_SALT), TAG_AND_SALT_len); |
302 | | std::cerr << "WHEE " << sizeof(privexpbytes) << "\n";std::cerr.flush(); |
303 | | t2.Update(privexpbytes, sizeof(privexpbytes)); |
304 | | t2.TruncatedFinal(privexpbytes, Tiger::DIGESTSIZE); |
305 | | privexponentm1.Decode(privexpbytes, sizeof(privexpbytes)); |
306 | | } |
| 368 | privexponentm1 = kdf(seed, seedlen, grouporderm1); |