It appears that .NET Core supports creation of custom curves in ECC.
I've tried to define the Curve25519, as shown below:
public class Curves
{
// TODO: check the key gen rand.
public static ECCurve Curve25519
{
get
{
return new ECCurve()
{
CurveType = ECCurve.ECCurveType.PrimeMontgomery,
B = new byte[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
A = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,109,6},
G = new ECPoint()
{
X = new byte[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9},
Y = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }},
Prime = new byte[] { 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 237 },
Order = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8},
Cofactor = new byte[] { 1 } // fix later
};
}
}
However, when I try to define it
var ecc2 = ECDsa.Create(Curves.Curve25519);
I get a null pointer exception.
Does anyone see any obvious error, or is there still not much support for explicit curves in .NET Core?
Curve25519 is an elliptic curve in Montgomery form with base field Fp and p = 2255–19 . In [1], Bernstein explains its design implementation, which is claimed to be highly secure and efficient.
X25519 is an elliptic curve Diffie-Hellman key exchange using Curve25519. It allows two parties to jointly agree on a shared secret using an insecure channel.
Errors are being raised because Curve25519 is designed for ECDH key exchange calculations, specifically X25519. Details of this usage is at this SO question.
ECDSA should be used over twisted Edwards version of Curve25519, namely Ed25519. This curve can be defined and used in .Net Core as below.
ECCurve ecCurve = new ECCurve() // Ed25519, 32 bytes, 256 bit
{
CurveType = ECCurve.ECCurveType.PrimeTwistedEdwards,
A = new byte[] { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec }, // GF(-1)
B = new byte[] { 0x52, 0x03, 0x6C, 0xEE, 0x2B, 0x6F, 0xFE, 0x73, 0x8C, 0xC7, 0x40, 0x79, 0x77, 0x79, 0xE8, 0x98,
0x00, 0x70, 0x0A, 0x4D, 0x41, 0x41, 0xD8, 0xAB, 0x75, 0xEB, 0x4D, 0xCA, 0x13, 0x59, 0x78, 0xA3 },
G = new ECPoint()
{
X = new byte[] { 0x21, 0x69, 0x36, 0xD3, 0xCD, 0x6E, 0x53, 0xFE, 0xC0, 0xA4, 0xE2, 0x31, 0xFD, 0xD6, 0xDC, 0x5C,
0x69, 0x2C, 0xC7, 0x60, 0x95, 0x25, 0xA7, 0xB2, 0xC9, 0x56, 0x2D, 0x60, 0x8F, 0x25, 0xD5, 0x1A },
Y = new byte[] { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58 }
},
Prime = new byte[] { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed },
Order = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed },
Cofactor = new byte[] { 8 }
};
Parameter A is -1, above representation is -1 in Galois Field of 2^255-19. This can be calculated by evaluating below code at SageMathCell.
gf=GF(2^255-19)
print (hex(gf(-1)))
But, documentation says explicit curves are not supported on below Windows 10 and macOS, and my tries show they throw exceptions on Linux. So, if platforms other than Windows 10 or inter-platform operability is needed, libraries like NSec or libsodium-core should be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With