Elliptic Curve Digital Signature Algorithm (ECDSA) is used within Bitcoin and Ethereum. In this case we will generate a private key and a public key point \((x,y)\). This create a signature value of the \((r,s)\). You should be able to enter base 10 or base 16 (hex) integer values for the public key point \((x,y)\) and the signature \((r,s)\).
ECDSA Creation and Verification |
Outline
The code is:
package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" "os" "strings" "github.com/dustinxie/ecc" ) func getCurve(s string) elliptic.Curve { if strings.Contains(s, "224") { return (elliptic.P224()) } else if strings.Contains(s, "384") { return (elliptic.P384()) } else if strings.Contains(s, "521") { return (elliptic.P521()) } return (ecc.P256k1()) } func main() { msg := "Hello 123" curveType := "" argCount := len(os.Args[1:]) if argCount > 0 { msg = os.Args[1] } if argCount > 1 { curveType = os.Args[2] } pubkeyCurve := getCurve(curveType) m := []byte(msg) digest := sha256.Sum256(m) privatekey, _ := ecdsa.GenerateKey(pubkeyCurve, rand.Reader) pubkey := privatekey.PublicKey r, s, _ := ecdsa.Sign(rand.Reader, privatekey, digest[:]) fmt.Printf("=== Message ===\n") fmt.Printf("Msg=%s\nHash=%x\n", msg, digest) fmt.Printf("\n=== Private key ===\n") fmt.Printf("Private key=%x\n", privatekey.D) fmt.Printf("Curve=%s\n", privatekey.Curve.Params().Name) fmt.Printf("\n=== Public key (X,Y) ===\n") fmt.Printf("X=%s Y=%s\n", pubkey.X, pubkey.Y) fmt.Printf(" Hex: X=%x Y=%x\n", pubkey.X.Bytes(), pubkey.Y.Bytes()) fmt.Printf("\n=== Signature (R,S) ===\n") fmt.Printf("R=%s S=%s\n", r, s) fmt.Printf(" Hex: R=%x S=%x\n", r, s) rtn := ecdsa.Verify(&pubkey, digest[:], r, s) if rtn { fmt.Printf("Signature verifies") } else { fmt.Printf("Signature does not verify") } }
A sample run:
=== Message === Msg=Hello 123 Hash=859e38d581e214dc7c8c871c425642913363a829065cf4acddd120ed5391b04b === Private key === Private key=efb07b041bf74cd139b4a99e1d71916db022b1d173995aed448bca5c1c1376dd Curve=P-256k1 === Public key (X,Y) === X=53933337350786642369966928329583701535925667250778372628720393885319300631175 Y=87107639962879319180644070197561583762690151615530346856552126558590659712083 Hex: X=773d2fea494fd6f6a1dc09b36adb5a4416c2e68a432f44859de5c1d0d8e7ca87 Y=c0952d5338c62dcb8e807cba9f2c7e72b90bb459e5b70ca605c96769202bd453 === Signature (R,S) === R=34016846122089221079433596705365984318972352339990175584597250806941821561344 S=6421257385918753353051248667214791710962127181984336059449472167128213367128 Hex: R=4b34da44a1627b7cd097720c12eb24af0922d133c0ce57485d40a89beaadea00 S=e324d89e8f3b5ef35d9abdb129e2e35180b2a83ca33f7a272e116e7950a2958 Signature verifies