ECC Digital Signature

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)
}

猜你喜欢

转载自blog.csdn.net/baidu_25845567/article/details/84110768