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("Bit size=%d\n", privatekey.Curve.Params().BitSize) fmt.Printf("Base point (G) =(%d, %d)\n", privatekey.Curve.Params().Gx, privatekey.Curve.Params().Gy) fmt.Printf("Prime=%d, Order=%d", privatekey.Curve.Params().P, privatekey.Curve.Params().N) 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(\n"Signature verifies") } else { fmt.Printf("\nSignature does not verify") } }
A sample run:
=== Message === Msg=Hello 123 Hash=859e38d581e214dc7c8c871c425642913363a829065cf4acddd120ed5391b04b === Private key === Private key=b3645f2efea9a96d28cbeb5bf8a5304a3dc96b2a42bee21c0b3aaa88f595df2d Curve=P-256k1 Bit size=256 Base point (G) =(55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424) Prime=115792089237316195423570985008687907853269984665640564039457584007908834671663, Order=115792089237316195423570985008687907852837564279074904382605163141518161494337 === Public key (X,Y) === X=77007236596272499552697218405908714888874625059778411542685725622785792316534 Y=20745252821220973789342590850065442758134973002375340605949893038975196614597 Hex: X=aa408d244da8a2ea673213ef63536ea96486ce0412a5294c9cdf0959cc689476 Y=2ddd65a19ed17f361b0381a72713f740b63d4fdca059427c389239da39004fc5 === Signature (R,S) === R=33027995512220841690000083421269061534408622570666620793995266029032826750381 S=44867240085578618664628913670877492263668786345184239470907981535519639811276 Hex: R=49052ed8fcf1903f530bda10ea9b578b6bb77487ea6b22b5558fc68524e045ad S=6331f53ce5e1a64e4043712631aeeb3f5c0ed753140a0fd76a8c5367e69b34cc Signature verifies