curve25519 base point multiplication using Crypto++

0

When we multiply the basepoint of curve25519 with a scalar number, an exception is thrown.

Integer gx(group.GetSubgroupGenerator().x);

Integer gy(group.GetSubgroupGenerator().y);

ECP::Point g(gx, gy);

ECP::Point P(group.GetCurve().ScalarMultiply(g, 3));

Exception thrown at 0x005B4412 in CryptoExample.exe: 0xC0000005: Access violation reading location 0x00000000.

How can we take generator, other than basepoint in this curve?

c++
cryptography
crypto++
elliptic-curve
curve-25519
asked on Stack Overflow Aug 6, 2019 by Security Geek • edited Aug 6, 2019 by jww

1 Answer

1
Integer gx(group.GetSubgroupGenerator().x);

Integer gy(group.GetSubgroupGenerator().y);

ECP::Point g(gx, gy);

ECP::Point P(group.GetCurve().ScalarMultiply(g, 3));

group.GetCurve() is likely returning NULL because no curve has been set. But the curve25519 gear is probably not going to function correctly using the standard way of doing things (like shown at Scalar multiplication on secp521r1 using Crypto++). In fact, if you run the following code:

GroupParameters group;
group.Initialize(ASN1::X25519());

Then the code will result in an exception because the domain parameters are missing in eccrypto.h and eccrypto.cpp:

$ ./test.exe
terminate called after throwing an instance of 'CryptoPP::UnknownOID'
  what():  BER decode error: unknown object identifier

The curve25519 gear is special in Crypto++. Rather than using the library's underlying Integer class and typical field operations through GroupParameters object, it uses a constant time implementation from Andrew Moon called Donna. The library then wraps Moon's Donna code and provides most expected operation using Crypto++ objects like PK_Signer and PK_Verifier.

However, "... and provides most expected operation" stops precisely at the lower-level objects like DL_GroupParameters_EC, which is the interface you are trying to use.

You might also want to take a look at the functions available in donna.h:

int curve25519_mult (byte publicKey[32], const byte secretKey[32])
    Generate a public key. More...

int curve25519_mult (byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
    Generate a shared key. More...

Those are the scalar multiplications you are looking for. The first curve25519_mult uses a basepoint of 9. The second curve25519_mult allows you to specify an arbitrary basepoint.

donna.h should be a private header, but we had to expose it because of the missing curve operations. However, Donna is still missing functions for Add and Double, though they could probably be exported if needed.

And also see x25519 and ed25519 on the Crypto++ wiki; and Scalar multiplication on secp521r1 using Crypto++ on Stack Overflow.


The x25519 and ed25519 wiki pages actually discuss your problem:

The Crypto++ library uses Andrew Moon's constant time ed25519-donna. The curve25519 gear appears to be like most other comparable public key objects in the Crypto++ library but it is mostly a facade. The Crypto++ classes are just wrappers around Moon's code that present some of the expected interface for callers. A side effect of the integration is, there is no general Point, Curve, or GroupParameters so you can't perform arbitrary calculations with curve25519.


The reason curve25519 is special is, we needed to provide the gear, but wanted to avoid a lot of changes required to properly support it. The library supports short Weierstrass curves well, but has nearly no support for Edwards and Twisted Edward curves.

Eventually curve25519 will be properly added to the library.

answered on Stack Overflow Aug 6, 2019 by jww • edited Aug 6, 2019 by jww

User contributions licensed under CC BY-SA 3.0