The Greatness of C#, PowerShell and .NET

You may disagree with me, but I think the C# and the .NET framework provide the best programming environment. Why? Well, there are many…

The Greatness of C#, PowerShell and .NET

You may disagree with me, but I think the C# and the .NET framework provide the best programming environment. Why? Well, there are many reasons, but one of the best is that it provides a common framework for programming environment — no matter if it is Web, scripted or console-based. For this, we have a unified platform, and where PowerShell and C# can share the same classes. So, let me show you how to convert from PowerShell to C#, and show how easy this conversion is.

ECC and Powershell

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 a Weierstrass curve, we have:

y²=x³+A.x+B (mod p)

For this, we can generate a key pair and then display it with PowerShell [here]:

$curvename=$Args[0]
$ecc = [System.Security.Cryptography.ECDsa]::Create([System.Security.Cryptography.ECCurve]::CreateFromFriendlyName(($curvename)))
$s=$ecc.ExportExplicitParameters($true)
$e=$ecc.ExportParameters($true)
"Curve: "+$e.Curve.Oid.FriendlyName
"Curve: "+$e.Curve.Oid.Value

"A="+[System.Convert]::ToHexString($s.Curve.A)
"B="+[System.Convert]::ToHexString($s.Curve.B)
"Gx="+[System.Convert]::ToHexString($s.Curve.G.X)
"Gy="+[System.Convert]::ToHexString($s.Curve.G.Y)
"P="+[System.Convert]::ToHexString($s.Curve.Prime)
"Order="+[System.Convert]::ToHexString($s.Curve.Order)
"`n== Private key =="
"D= "+[System.Convert]::ToHexString($e.D)
"`nPublic key"
"Qx= "+[System.Convert]::ToHexString($e.Q.X)
"Qy= "+[System.Convert]::ToHexString($e.Q.Y)

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= 3457C26D32D8FFA31FCACC8B0E763893456FD602F1281366DC25577D2B95E2DE

Public key
Qx= DAA2664FA4FD50D27E9A44973FF4E8E884A0D63A2147FDAC1D51173AA4507E01
Qy= 7B0DF15E25FDA3C304C9DC75519EF306F2AA121E4FA81C02E5F35EFCCD23D507

This curve is used for Bitcoin and Ethereum, and we have is then y²=x³+7 (mod p), and where D is the private key, and Qx, Qy is the public key.

ECC and Powershell

So let’s carefully recode, and where:

$curvename=$Args[0]
$ecc = [System.Security.Cryptography.ECDsa]::Create([System.Security.Cryptography.ECCurve]::CreateFromFriendlyName(($curvename)))
$s=$ecc.ExportExplicitParameters($true)
$e=$ecc.ExportParameters($true)

becomes:

  ECDsa ecc = System.Security.Cryptography.ECDsa.Create(System.Security.Cryptography.ECCurve.CreateFromFriendlyName(curvename));
ECParameters s = ecc.ExportExplicitParameters(true);
ECParameters e = ecc.ExportParameters(true);

and where we have used the same classes. We can then continue to translate from PowerShell to C# with:

public string ecc(string curvename) {


ECDsa ecc = System.Security.Cryptography.ECDsa.Create(System.Security.Cryptography.ECCurve.CreateFromFriendlyName(curvename));
ECParameters s = ecc.ExportExplicitParameters(true);
ECParameters 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);


return (str1);
}

A sample run for a secp256k1 key pair [here]:

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

And where we can see that A, B, Gx, Gy, P and the Order are all the same.

Conclusions

And there you go, it is as simple as that. Basically it is simple to convert from PowerShell to C#, and vice-versa.