ECDSA for Multiple Curves and Different Hashing Methods with PowerShell[ECDSA Home][Home]
With ECDSA (Elliptic Curve Digital Signature) we use an elliptic curve to produce a digital signature. Overall, we take a hash of a message, and then create a signature using a private key. The public key can then be used to verify the signature. In this case we will use a range of curves, such as 192-bit, 256-bit, 384-bit and 521-bit curves, and create with a range of hashing methods (such as MD5, SHA-1 and SHA-256).
|
Method
Overall, Microsoft has been a little sluggish in getting into elliptic curve cryptography (ECC), but now .NET and Powershell support it. In fact, Powershell is now supported on Linux, Mac OSX and Windows. Overall, we can run the pwsh command to run a Powershell script.
So, let’s see if we can create a signature that is used by Bitcoin and Ethereum: ECDSA (Elliptic Curve Digital Signature Algorithm). With ECDSA we use an elliptic curve to produce a digital signature. Overall, we take a hash of a message and then create a signature using a private key. The public key can then be used to verify the signature.
In this case, we will use a range of curves, such as 192-bit, 256-bit, 384-bit and 521-bit curves, and create with a range of hashing methods (such as MD5, SHA-1 and SHA-256). Common curve types include Brainpool, secp, and NIST. To set up a NIST P-256 curve, we create with:
$ecc = [System.Security.Cryptography.ECDsa]::Create([System.Security.Cryptography.ECCurve]::CreateFromFriendlyName(("nistp256")))
We can then export the keys with:
$e=$ecc.ExportParameters($true)
To select an SHA-1 hashing method for a word of “hello”:
$hash1=[System.Security.Cryptography.HashAlgorithm]::Create("sha1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes("hello"))
The signature is then created with:
$ecdsa = [System.Security.Cryptography.ECDsa]::Create($e); $ecdsa_sig=$ecdsa.SignHash($hash1);
To verify, we need to provide the hash of the message and the signature:
$rtn=$ecdsa.VerifyHash($hash1,$ecdsa_sig); if ($rtn) { "`nSuccess verification of signature" } else { "`nNot successful verification of signature" }
Coding
The coding is:
$word=$Args[0] $hashmethod=$Args[1] $curvename=$Args[2] # "nistP256", "nistP512", "Input word: "+$word "Hash method: "+$hashmethod $ecc = [System.Security.Cryptography.ECDsa]::Create([System.Security.Cryptography.ECCurve]::CreateFromFriendlyName(($curvename))) $e=$ecc.ExportParameters($true) "Curve: "+$e.Curve.Oid.FriendlyName "Curve: "+$e.Curve.Oid.Value "== Private key ==" "D= "+[System.Convert]::ToHexString($e.D) "`nPublic key" "Qx= "+[System.Convert]::ToHexString($e.Q.X) "Qy= "+[System.Convert]::ToHexString($e.Q.Y) $hash1=[System.Security.Cryptography.HashAlgorithm]::Create($hashmethod).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($word)) $ecdsa = [System.Security.Cryptography.ECDsa]::Create($e); $ecdsa_sig=$ecdsa.SignHash($hash1); "`nECDSA (Hex): "+[System.Convert]::ToHexString($ecdsa_sig) "`nECDSA (Base64): "+[System.Convert]::ToBase64String($ecdsa_sig) $rtn=$ecdsa.VerifyHash($hash1,$ecdsa_sig); if ($rtn) { "`nSuccess verification of signature" } else { "`nNot successful verification of signature" }
and a sample test for secp256k1:
Input word: qwerty Hash method: sha512 Curve: secp256k1 Curve: == Private key == D= 9801D3FDA8F7CAB2EABEA2CA2E600A9B62B63E06499BDEAC06185922BE69C992 Public key Qx= 40642AED903917008FE4565A94AD543841C465DD4937620FAED46358C31EE3D6 Qy= 16F2CFDA89DBDDC7F2EA58F242BF605E34FD96AB3C1FFE9EA5597C3C1574811C ECDSA (Hex): 18B1AB2B9C434EEBC6E18A65DF27062D4581AD9984D391C64E34D57C33FFA7DE056B0C08100091118E018B736F84DEEC8328C553AFCECA8FEA0BC75F9422DE83 ECDSA (Base64): GLGrK5xDTuvG4Ypl3ycGLUWBrZmE05HGTjTVfDP/p94FawwIEACREY4Bi3NvhN7sgyjFU6/Oyo/qC8dflCLegw== Success verification of signature
and for NIST-P521:
Input word: qwerty Hash method: sha512 Curve: nistP521 Curve: 1.3.132.0.35 == Private key == D= 0105F60DE583AB0B2A73039299A7DF3FE1EF3F87DFCB47197AD9399BCB1A729C91DBA06B1584648B54E8A21B1A3680358158C668CBDA6E5ABE97ADDAB4C7519CA183 Public key Qx= 013FD703BC148AA2A611E248AB8BB6EE0CFA020015B03420B77C35F6EB35618DD3484C3A0832F03E0B9FB765455B801F0FB34BFD25C228F6B3515CA6C9FA651384D8 Qy= 0055B999F2D60EBDECF90E415B9D0291C79447612066366034BC426CAC3BA3A146EC45F9B514DCA833BBB194B123B9137EAF033AFFF0BD9FD5DE361A5470730456C4 ECDSA (Hex): 000DA7DDBA8C3C6B106C57B2E5F1328AC729F06C90660BA617DF29C57E0AA36B4B3911CF5D7A4D51DB3B9AE488232890C1E570968517E5E652F979C71034E86449EF018D1677DE8ABF2424D8F1ACB64C00129862517987AF40E8A76E5DD9D61B3382F04EA20313A615365E9613CC717FFB6ACBB09885F261A3F1C592D602B7442619009F ECDSA (Base64): AA2n3bqMPGsQbFey5fEyiscp8GyQZgumF98pxX4Ko2tLORHPXXpNUds7muSIIyiQweVwloUX5eZS+XnHEDToZEnvAY0Wd96KvyQk2PGstkwAEphiUXmHr0Dop25d2dYbM4LwTqIDE6YVNl6WE8xxf/tqy7CYhfJho/HFktYCt0QmGQCf Success verification of signature