Scalar multiplication on secp521r1 using Crypto++

后端 未结 1 1843
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-23 07:30

I am writing the following code for scalar multiplication in elliptic curve in c++. The code runs when i don\'t initialize the value of the point. But when i do, it gives me the

相关标签:
1条回答
  • 2021-01-23 07:51

    ERROR: CryptoPP::ECP::GetField(...) returned nullptr.

    For Crypto++ you need to load a curve. Based on the code you posted it does not look like that has been done. Loading the curve loads the domain parameters for the curve. In the case of a curve over a prime field the domain parameters are {a,b,p,G,n,h}, where a and b are coefficients, p modulus, G is the basepoint with order N, n is the order and h is the cofactor. You can see them in eccrypto.cpp.

    For secp521r1 the easiest way to do it is probably along the lines of the following. secp256r1 was used to make the output smaller, but you should use secp521r1 instead.

    #include "integer.h"
    #include "eccrypto.h"
    #include "osrng.h"
    #include "oids.h"
    
    #include <iostream>
    #include <iomanip>
    
    int main(int argc, char* argv[])
    {
        using namespace CryptoPP;
        typedef DL_GroupParameters_EC<ECP> GroupParameters;
        typedef DL_GroupParameters_EC<ECP>::Element Element;
    
        AutoSeededRandomPool prng;    
        GroupParameters group;
        group.Initialize(ASN1::secp256r1());
    
        // private key
        Integer x(prng, Integer::One(), group.GetMaxExponent());
    
        std::cout << "Private exponent:" << std::endl;
        std::cout << "  " << std::hex << x << std::endl;
    
        // public key
        Element y = group.ExponentiateBase(x);
    
        std::cout << "Public element:" << std::endl;
        std::cout << "  " << std::hex << y.x << std::endl;
        std::cout << "  " << std::hex << y.y << std::endl;
    
        // element addition
        Element u = group.GetCurve().Add(y, ECP::Point(2,3));
    
        std::cout << "Add:" << std::endl;
        std::cout << "  " << std::hex << u.x << std::endl;
        std::cout << "  " << std::hex << u.y << std::endl;
    
        // scalar multiplication
        Element v = group.GetCurve().ScalarMultiply(u, Integer::Two());
    
        std::cout << "Mult:" << std::endl;
        std::cout << "  " << std::hex << v.x << std::endl;
        std::cout << "  " << std::hex << v.y << std::endl;
    
        return 0;
    }
    

    Compile the code with g++ test.cxx ./libcryptopp.a -o test.exe.

    Running the code produces:

    $ ./test.exe
    Private exponent:
      b48e35e8d60918f815857503b034681bc59db689dee0ffc35a140e365bb056dch
    Public element:
      bb9c8daaace9712f368bc98cf004a4594a14f9c330e2db141906ec67f05ab8d8h
      e37e5e161aae15f54f20d67b665311717305932a1479427fe063d84c5be82a1dh
    Add:
      f5055cd23f23f5721d8a5f6f87bd61206e972a97c19478200cb0b1f24af398ach
      107a532732098c4d051efc7f54d9bda78020a6e68f95e01a33700bab56a91f9ah
    Mult:
      46628d3e4f43da4fd001c652682d33f608c34ce3cf6c13f45b9bd014cbb83ed4h
      3b58f98bd0d70196036b77f6fcca6fe206bdf3beda4b2b604d5cb8ae0327a57ch
    

    The DL_GroupParameters_EC<ECP> group looks unusual because you are into lower-level base interfaces. I think that's where you want to be based on your sample code.

    In general the hierarchy of objects with respect to the EC gear is/are shown below. It uses both an "is a" or "has a" relationships. For example, a Signer and Decryptor each "has a" Private Key. A Private Key "is a" GroupParameters.

    Encryptor
      +- Public key
           +- Group parameters
                +- Curve
                     +- Field
    
    Decryptor
      +- Private key
           +- Group parameters
                +- Curve
                     +- Field
    
    Verifier
      +- Public key
           +- Group parameters
                +- Curve
                     +- Field
    
    Signer
      +- Private key
           +- Group parameters
                +- Curve
                     +- Field
    

    For example, the Signer is the protocol, and implements everything you need in a single package. Below the Signer is the Private Key, and it performs the multiplication and exponentiation. Below the Private Key is the field and the curve. And so on until you get to the coefficients and modulus.

    With that said, you usually want to use one of the higher level objects. Most folks use Encryptors, Decryptors, Public Keys and Private Keys. Most folks don't need to go below, like into objects like GroupParameters or Curves.


    You might also be interested in the Crypto++ Manual and Elliptic Curve Cryptography in the Crypto++ wiki.

    0 讨论(0)
提交回复
热议问题