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 (sig *Signature) Bytes() []byte { b := sig.R.Bytes() b = append(b, sig.S.Bytes()...) return b } func SignatureFromBytes(b []byte) (*Signature, error) { if len(b) != 64 { return nil, errors.New("Invalid signature") } rBytes := b[:32] sBytes := b[32:] r := new(big.Int).SetBytes(rBytes) s := new(big.Int).SetBytes(sBytes) sig := &Signature{ R: r, S: s, } return sig, nil } type Signature struct { R *big.Int S *big.Int } func Sign(privK *ecdsa.PrivateKey, m []byte) (*Signature, 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 nil, err } sig := &Signature{ R: r, S: s, } return sig, nil } func VerifySignature(pubK *ecdsa.PublicKey, m []byte, sig Signature) bool { hashMsg := HashBytes(m) verified := ecdsa.Verify(pubK, hashMsg[:], sig.R, sig.S) return verified }