|
|
package core
import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "encoding/hex" "errors" "math/big" )
// Address is the type data for addresses
type Address [32]byte
func (addr Address) String() string { return hex.EncodeToString(addr[:]) }
func NewKey() (*ecdsa.PrivateKey, error) { curve := elliptic.P256()
privatekey := new(ecdsa.PrivateKey) privatekey, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { return nil, err }
return privatekey, err }
func PackPubK(pubK *ecdsa.PublicKey) []byte { return elliptic.Marshal(pubK.Curve, pubK.X, pubK.Y) } func UnpackPubK(b []byte) *ecdsa.PublicKey { x, y := elliptic.Unmarshal(elliptic.P256(), b) return &ecdsa.PublicKey{ Curve: elliptic.P256(), X: x, Y: y, } }
func AddressFromPrivK(privK *ecdsa.PrivateKey) Address { h := HashBytes(PackPubK(&privK.PublicKey)) return Address(h) }
func PackSignature(r, s *big.Int) []byte { sig := r.Bytes() sig = append(sig, s.Bytes()...) return sig }
func UnpackSignature(sig []byte) (*big.Int, *big.Int, error) { if len(sig) != 64 { return nil, nil, errors.New("Invalid signature") } rBytes := sig[:32] sBytes := sig[32:]
r := new(big.Int).SetBytes(rBytes) s := new(big.Int).SetBytes(sBytes)
return r, s, nil }
func Sign(privK *ecdsa.PrivateKey, m []byte) ([]byte, error) { r := big.NewInt(0) s := big.NewInt(0)
hashMsg := HashBytes(m)
r, s, err := ecdsa.Sign(rand.Reader, privK, hashMsg[:]) if err != nil { return []byte{}, err }
sig := PackSignature(r, s)
return sig, nil
}
func VerifySignature(pubK *ecdsa.PublicKey, m []byte, sig []byte) bool { hashMsg := HashBytes(m)
r, s, err := UnpackSignature(sig) if err != nil { return false }
verified := ecdsa.Verify(pubK, hashMsg[:], r, s) return verified }
|