Search code examples
c++crypto++

ECDSA using SecByteBlock key pairs


I have implemented ECDH, and both private and public are of type SecByteBlock, now I am trying to implement ECDSA with SHA256 using these keys.

Assuming that pubA and privA are already generated and there are SecByteBlock instances, how can I use them in ECDSA?

Thank you in advance!

OID CURVE = secp256r1();
AutoSeededX917RNG<AES> rng;

// Elliptic Curve Diffie-Hellman
ECDH < ECP >::Domain dhA( CURVE );

SecByteBlock privA(dhA.PrivateKeyLength()), pubA(dhA.PublicKeyLength());
dhA.GenerateKeyPair(rng, privA, pubA);

// Elliptic Curve Digital Signature Algorithm
ECDSA<ECP, SHA256>::PrivateKey privateKey;
DL_GroupParameters_EC<ECP> params(ASN1::secp256k1());

privateKey.Initialize(rng, params);        

// Generating private key
ECIES<ECP>::PrivateKey privateKey;
privateKey.Initialize(rng, ASN1::secp160r1());

// Generating matching public key
ECIES<ECP>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);

ECDSA<ECP>::Signer signer(privateKey);

ECDSA<ECP>::Verifier verifier(publicKey);

Solution

  • I don't think this is a good idea. You should use the ECDSA class to create the keys. However, here it is.

    #include "cryptlib.h"
    #include "eccrypto.h"
    #include "secblock.h"
    #include "filters.h"
    #include "integer.h"
    #include "osrng.h"
    #include "files.h"
    #include "oids.h"
    #include "sha.h"
    
    #include <iostream>
    #include <stdexcept>
    
    int main(int argc, char* argv[])
    {
        using namespace CryptoPP;
    
        try
        {
            const OID CURVE = ASN1::secp256r1();
            AutoSeededRandomPool prng;
    
            ECDH <ECP>::Domain dh(CURVE);
    
            SecByteBlock privA(dh.PrivateKeyLength()), pubA(dh.PublicKeyLength());
            dh.GenerateKeyPair(prng, privA, pubA);
    
            const Integer x(privA.begin(), privA.size());
    
            ECDSA<ECP, SHA256>::PrivateKey privateKey;
            privateKey.Initialize(CURVE, x);
    
            bool valid = privateKey.Validate(prng, 3);
            if (valid == false)
                throw std::runtime_error("Private key is not valid ECDSA key");
    
            std::cout << "Private key is valid ECDSA key" << std::endl;
        }
        catch (const std::runtime_error& ex)
        {
            std::cerr << ex.what() << std::endl;
            std::exit(1);
        }
    
        return 0;
    }
    

    And:

    cryptopp$ g++ test.cxx ./libcryptopp.a -o test.exe
    cryptopp$ ./test.exe
    Private key is valid ECDSA key
    

    More information is at Elliptic Curve Digital Signature Algorithm on the Crypto++ wiki.