简体   繁体   中英

Scalar multiplication on secp521r1 using Crypto++

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 nullptr error.

I have tried the below code:

ECP r1;
ECPPoint basepoint = ECPPoint(2,3);
ECPPoint point;
ECPPoint s1= ecp.ScalarMultiply(basepoint, x1);

Error:

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM