Ticket #2: kdf.diff

File kdf.diff, 7.2 KB (added by warner, at 2011-01-06T22:52:37Z)

half-finished patch to extract Tiger-based KDF into separate function for testing

  • pycryptopp/_pycryptoppmodule.cpp

    diff -rN -u old-pycryptopp-ecdsa/pycryptopp/_pycryptoppmodule.cpp new-pycryptopp-ecdsa/pycryptopp/_pycryptoppmodule.cpp
    old new  
    11
    22#include <Python.h>
    33
    4 //#include "publickey/ecdsamodule.hpp"
     4#include "publickey/ecdsamodule.hpp"
    55#include "publickey/rsamodule.hpp"
    66#include "hash/sha256module.hpp"
    77#include "cipher/aesmodule.hpp"
     
    1010"_pycryptopp -- Python wrappers for a few algorithms from Crypto++\n\
    1111\n\
    1212from pycryptopp import publickey\n\
    13 #from pycryptopp.publickey import ecdsa\n\
     13from pycryptopp.publickey import ecdsa\n\
    1414from pycryptopp.publickey import rsa\n\
    1515from pycryptopp import cipher\n\
    1616from pycryptopp.cipher import aes\n\
     
    2121    {"rsa_generate", reinterpret_cast<PyCFunction>(rsa_generate), METH_KEYWORDS, const_cast<char*>(rsa_generate__doc__)},
    2222    {"rsa_create_verifying_key_from_string", reinterpret_cast<PyCFunction>(rsa_create_verifying_key_from_string), METH_KEYWORDS, const_cast<char*>(rsa_create_verifying_key_from_string__doc__)},
    2323    {"rsa_create_signing_key_from_string", reinterpret_cast<PyCFunction>(rsa_create_signing_key_from_string), METH_KEYWORDS, const_cast<char*>(rsa_create_signing_key_from_string__doc__)},
     24    {"ecdsa__test_kdf",  reinterpret_cast<PyCFunction>(_ecdsa_test_kdf), METH_KEYWORDS, NULL},
    2425    {NULL, NULL, 0, NULL}  /* sentinel */
    2526};
    2627
     
    3536    if (!module)
    3637      return;
    3738
    38     //init_ecdsa(module);
     39    init_ecdsa(module);
    3940    init_rsa(module);
    4041    init_sha256(module);
    4142    init_aes(module);
  • pycryptopp/publickey/ecdsamodule.cpp

    diff -rN -u old-pycryptopp-ecdsa/pycryptopp/publickey/ecdsamodule.cpp new-pycryptopp-ecdsa/pycryptopp/publickey/ecdsamodule.cpp
    old new  
    266266*
    267267*/
    268268
     269static Integer
     270old_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
     292static Integer
     293kdf(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.
     311PyObject *
     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
    269345static int
    270346SigningKey___init__(PyObject* self, PyObject* args, PyObject* kwdict) {
    271347    static const char *kwlist[] = { "seed", NULL };
    272     const char* seed;
     348    const byte* seed;
    273349    Py_ssize_t seedlen;
    274350    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "t#:SigningKey___init__", const_cast<char**>(kwlist), &seed, &seedlen)) {
    275351        return -1;
     
    289365    DL_GroupParameters_EC<ECP> params(ASN1::secp192r1());
    290366    params.SetPointCompression(true);
    291367    grouporderm1 = params.GetGroupOrder() - 1;
    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);
    307369
    308370    SigningKey* mself = reinterpret_cast<SigningKey*>(self);
    309371
  • pycryptopp/publickey/ecdsamodule.hpp

    diff -rN -u old-pycryptopp-ecdsa/pycryptopp/publickey/ecdsamodule.hpp new-pycryptopp-ecdsa/pycryptopp/publickey/ecdsamodule.hpp
    old new  
    11#ifndef __INCL_ECDSAMODULE_HPP
    22#define __INCL_ECDSAMODULE_HPP
    33
     4PyObject *
     5_ecdsa_test_kdf(PyObject* self, PyObject* args, PyObject* kwdict);
     6
    47void
    58init_ecdsa(PyObject* module);
    69
  • setup.py

    diff -rN -u old-pycryptopp-ecdsa/setup.py new-pycryptopp-ecdsa/setup.py
    old new  
    2424# ECDSA isn't yet supported, but it can be turned on by testing purposes.  But
    2525# you'll have to comment-in some lines in the C++ code to make it work.  Also
    2626# comment-in the unit tests.
    27 ECDSA=False
    28 # ECDSA=True
     27#ECDSA=False
     28ECDSA=True
    2929
    3030DEBUG=False
    3131if "--debug" in sys.argv: