Go has several standard elliptic curve methods integrated. These generate the parameters of \(P\) (the order of curve as is a prime number), \(N\) (the order of the base point), B (the value in \(y^2 = x^3 + B\)), \(G_x\) (the x co-ordinate of the base point), \(G_y\) (the y co-ordinate of the base point). In the following we will generate a random value (\(n\) - the private key), and the generate a public key point (\(P\)), and where \(P = n G\). \(G\) is the base point on the elliptic curve:
ECC with Go |
Coding
package main import ( "crypto/elliptic" "crypto/rand" "fmt" "flag" "strconv" "encoding/hex" ) func GenerateRandomBytes(n int) ([]byte, error) { b := make([]byte, n) _, err := rand.Read(b) // Note that err == nil only if we read len(b) bytes. if err != nil { return nil, err } return b, nil } func main() { c := elliptic.P256() flag.Parse() args := flag.Args() i,_:=strconv.Atoi(args[0]) if ( i==1) { c = elliptic.P224() } else if (i==2) { c = elliptic.P256() } else if (i==3) { c = elliptic.P384() } else if (i==4) { c = elliptic.P521() } params := c.Params() fmt.Printf("Type=%s\n\nP=%d\nN=%d\nB=%d\nGx=%d\nGy=%d\n\n",params.Name,params.P,params.N,params.B,params.Gx,params.Gy) r,_ := GenerateRandomBytes(32) p1x,p1y := c.ScalarMult(params.Gx,params.Gy,r) fmt.Printf("\nPrivate key (n):\t%s\n",hex.EncodeToString(r)) fmt.Printf("\nPublic key point\nPx=%d\nPy=%d",p1x,p1y) fmt.Printf("\nIs on curve: %t",c.IsOnCurve(p1x,p1y)) r1,_ := GenerateRandomBytes(32) p2x,p2y := c.ScalarMult(params.Gx,params.Gy,r1) // We could also use p2x,p2y := c.ScalarBaseMult(r) p3x,p3y := c.Add(p1x,p1y,p2x,p2y) fmt.Printf("\n=======\n\nAnother point:\nPx=%d\nPy=%d",p2x,p2y) fmt.Printf("\n\nPoints added\nPx=%d\nPy=%d",p3x,p3y) fmt.Printf("\nIs on curve: %t",c.IsOnCurve(p3x,p3y)) p4x,p4y := c.Double(p1x,p1y) fmt.Printf("\n\n======\nPublic key point doubled\nPx=%d\nPy=%d",p4x,p4y) fmt.Printf("\nIs on curve: %t",c.IsOnCurve(p4x,p4y))
A sample run is:
Type=P-224 P=26959946667150639794667015087019630673557916260026308143510066298881 N=26959946667150639794667015087019625940457807714424391721682722368061 B=18958286285566608000408668544493926415504680968679321075787234672564 Gx=19277929113566293071110308034699488026831934219452440156649784352033 Gy=19926808758034470970197974370888749184205991990603949537637343198772 Private key (n): f690908776af7a11c498e34f82f60ec3b6d0ed83aa90db59df895df4b2f179c8 Public key point Px=9925349165106137410166943921072763299660450481809944831245424675094 Py=9065617640778934052293915087167395592139117022243384874230567871038 Is on curve: true ======= Another point: Px=23136018329224908623445669959286947327823236885272806592799495678837 Py=17169971633869479024781240443056816123567131727587156456101817886424 Points added Px=23368788923337954618515240098202069770818791587102693334605541502805 Py=17957086314294810054460827367853910159464781480234161081925385866633 Is on curve: true ====== Public key point doubled Px=16909016828479539946399520929338565834816997574361289384369948267675 Py=26514066051462865483239367165061892434193801508197944511924300362823 Is on curve: true
Presentation