With ECC, we have a base point on the curve (\(G\)) and then create a random value for the private key (\(D\)) and then generate the public key with \(P=D.G\). For the curve types, we have "03" for a Montgomery curve (\(B.y^2 = x^3 + A.x^2 + x \pmod p\)), "01" for a Weierstrass curve (\(y^2 = x^3 + A.x + B \pmod p\)) and "02" for a Twisted Edwards curve (\(A.x^2 + y^2 = 1 + B.x^2.y^2 \pmod p\)).
Generating an ECC key pair in PowerShell |
Method
With ECC, we have a base point on the curve (\(G\)) and then create a random value for the private key (\(D\)) and then generate the public key with \(P=D.G\).
For the curve types, we can have a Montgomery curve:
\(B.y^2 = x^3 + A.x^2 + x \pmod p\)
For a Weierstrass curve:
\(y^2 = x^3 + A.x + B \pmod p\)
For a Twisted Edwards curve:
\(A.x^2 + y^2 = 1 + B.x^2.y^2 \pmod p\)
Coding
First we create a folder named "ecc", and then go into that folder.We can create a Dotnet console project for .NET 7.0 with:
dotnet new console --framework net8.0
This produces a Csproject file of:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
The coding is:
namespace ECC { using System.Security.Cryptography; class Program { static void Main(string[] args) { string curvename="secp256k1"; if (args.Length >0) curvename=args[0]; try { var ecc = ECDsa.Create(System.Security.Cryptography.ECCurve.CreateFromFriendlyName(curvename)); var s = ecc.ExportExplicitParameters(true); var e = ecc.ExportParameters(true); string str1 = "Curve: " + e.Curve.Oid.FriendlyName; str1 = str1 + "\nCurve: " + e.Curve.Oid.Value; str1 = str1 + "\nA=" + BitConverter.ToString(s.Curve.A).Replace("-", string.Empty); str1 = str1 + "\nB=" + BitConverter.ToString(s.Curve.B).Replace("-", string.Empty); str1 = str1 + "\nGx=" + BitConverter.ToString(s.Curve.G.X).Replace("-", string.Empty); str1 = str1 + "\nGy=" + BitConverter.ToString(s.Curve.G.Y).Replace("-", string.Empty); str1 = str1 + "\nP=" + BitConverter.ToString(s.Curve.Prime).Replace("-", string.Empty); str1 = str1 + "\nOrder=" + BitConverter.ToString(s.Curve.Order).Replace("-", string.Empty); str1 = str1 + "\n\nPrivate key:"; str1 = str1 + "\nD=" + BitConverter.ToString(e.D).Replace("-", string.Empty); str1 = str1 + "\n\nPublic key:"; str1 = str1 + "\nQx=" + BitConverter.ToString(e.Q.X).Replace("-", string.Empty); str1 = str1 + "\nQy=" + BitConverter.ToString(e.Q.Y).Replace("-", string.Empty); Console.WriteLine("{0}",str1); } catch (Exception e) { Console.WriteLine("Error: {0}",e.Message); } } } }
A sample run for a secp256k1 key pair:
Curve: secp256k1 Curve: A=0000000000000000000000000000000000000000000000000000000000000000 B=0000000000000000000000000000000000000000000000000000000000000007 Gx=79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy=483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 P=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F Order=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Private key: D=BC0AD7B55C88F287E301D0A5A58464F9EEB533E35A9F2B39D46786D26A212A43 Public key: Qx=3B2918F0850D5AEDABAF94A55E66B7C4E6148AB12663A2A1B0E558C29666E8CB Qy=8D2BBE0687A44EF016B5D610B65F25762FD86B587B3274B1ECE441829BEB0468
A sample run for a NIST P256 key pair:
Curve: nistp256 Curve: A=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC B=5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B Gx=6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296 Gy=4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5 P=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF Order=FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 Private key: D=B9B425D97576D1212E95BBDD0A47C1ECAB2B8A854AC18BBF03389C6B466A1DE7 Public key: Qx=9CAAF0464CC19BE0D7993F32039ED0211B2F9BB35AD3087378AEB0C31BC09941 Qy=A99C4D35CD13ABB298BB3EFDF99647FD85204C2DB57C38F5F67ECAFCB5782639
A sample run for a NIST P521 key pair:
Curve: nistP521 Curve: A=01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC B=0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00 Gx=00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66 Gy=011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650 P=01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF Order=01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409 Private key: D=0155EE9D60F2126AE449CD66AD36D2521251629DA4F93124C9C1C0DAAF2E413B53EC911DDD48D018A091B88EAAB2EE470C4C7FE010D1A8663FAF0BBB1319619EA72B Public key: Qx=011E41735B49B32E96B231584B47B03C584F31F8B3CB772BB34002D4C6C0B99EB843848F6730E63F6D046354065527CFDB4FDA8065490F3C947B9AA3D84862CE3EBF Qy=015272EB818529F5529273D9BF8AE9A89F44F79C2841C59E69E6ED6541DAEAC19AD2F0F4B7828A24ED408F1408F743915C784CAE66A691F681052A9ED1E09DDC991B