package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"os"
"encoding/pem"
"crypto/sha256"
"math/big"
"fmt"
)
func ECCGenKey(privatePath string,publicPath string) error {
privateKey,err:=ecdsa.GenerateKey(elliptic.P521(),rand.Reader)
if err!=nil {
return err
}
privateStream,err:=x509.MarshalECPrivateKey(privateKey)
if err!=nil {
return err
}
privateFile,err:=os.Create(privatePath)
if err!=nil {
return err
}
defer privateFile.Close()
err=pem.Encode(privateFile,&pem.Block{
Type:"ecdsa private key",
Bytes:privateStream,
})
if err!=nil {
return err
}
publicKey:=privateKey.PublicKey
publicStream,err:=x509.MarshalPKIXPublicKey(&publicKey)
if err!=nil {
return err
}
publicFile,err:=os.Create(publicPath)
if err!=nil {
return err
}
defer publicFile.Close()
err=pem.Encode(publicFile,&pem.Block{
Type:"ecdsa public key",
Bytes:publicStream,
})
if err!=nil {
return err
}
return nil
}
func Sign(src []byte,privatePath string) ([]byte,[]byte,error) {
privateFile,err:=os.Open(privatePath)
if err!=nil {
return nil,nil,err
}
defer privateFile.Close()
fileinfo,err:=os.Stat(privatePath)
if err!=nil {
return nil,nil,err
}
m:=make([]byte,fileinfo.Size())
privateFile.Read(m)
block,_:=pem.Decode(m)
privateKey,err:=x509.ParseECPrivateKey(block.Bytes)
if err!=nil {
return nil,nil,err
}
h:=sha256.Sum256(src)
s,r,err:=ecdsa.Sign(rand.Reader,privateKey,h[:])
sb,err:=s.MarshalText()
if err!=nil {
return nil,nil,err
}
rb,err:=r.MarshalText()
if err!=nil {
return nil,nil,err
}
return sb,rb,nil
}
func Verify(src []byte,publicPath string,sb []byte,rb []byte) (bool,error) {
publicFile,err:=os.Open(publicPath)
if err!=nil {
return false, err
}
defer publicFile.Close()
fileinfo,err:=os.Stat(publicPath)
if err!=nil {
return false, err
}
m:=make([]byte,fileinfo.Size())
publicFile.Read(m)
block,_:=pem.Decode(m)
publicKey,err:=x509.ParsePKIXPublicKey(block.Bytes)
if err!=nil {
return false, err
}
var s,r big.Int
err=s.UnmarshalText(sb)
if err!=nil {
return false, err
}
err=r.UnmarshalText(rb)
if err!=nil {
return false, err
}
/*xb:=publicKey.(*ecdsa.PublicKey).X.Bytes()
yb:=publicKey.(*ecdsa.PublicKey).Y.Bytes()
b:=append(xb,yb...)
var x,y big.Int
n:=len(b)
x.SetBytes(b[:n/2])
y.SetBytes(b[n/2:])
rawPublicKey:=ecdsa.PublicKey{elliptic.P521(),&x,&y}*/
h:=sha256.Sum256(src)
return ecdsa.Verify(publicKey.(*ecdsa.PublicKey),h[:],&s,&r),nil
//return ecdsa.Verify(&rawPublicKey,h[:],&s,&r),nil
}
func main() {
privatePath:="private181122.pem"
publicPath:="public181122.pem"
err:=ECCGenKey(privatePath,publicPath)
if err!=nil {
fmt.Print(err)
return
}
s,r,err:=Sign([]byte("waist-length hair"),privatePath)
if err!=nil {
fmt.Print(err)
return
}
x,err:=Verify([]byte("waist-length hair"),publicPath,s,r)
if err!=nil {
fmt.Print(err)
return
}
fmt.Print(x)
y,err:=Verify([]byte("central parting waist-length hair"),publicPath,s,r)
if err!=nil {
fmt.Print(err)
return
}
fmt.Print(y)
}