package crypto
import (
"crypto/sha256"
"fmt"
"io"
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
"github.com/libp2p/go-libp2p/core/internal/catch"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
)
type Secp256k1PrivateKey secp256k1 .PrivateKey
type Secp256k1PublicKey secp256k1 .PublicKey
func GenerateSecp256k1Key (_ io .Reader ) (PrivKey , PubKey , error ) {
privk , err := secp256k1 .GeneratePrivateKey ()
if err != nil {
return nil , nil , err
}
k := (*Secp256k1PrivateKey )(privk )
return k , k .GetPublic (), nil
}
func UnmarshalSecp256k1PrivateKey (data []byte ) (k PrivKey , err error ) {
if len (data ) != secp256k1 .PrivKeyBytesLen {
return nil , fmt .Errorf ("expected secp256k1 data size to be %d" , secp256k1 .PrivKeyBytesLen )
}
defer func () { catch .HandlePanic (recover (), &err , "secp256k1 private-key unmarshal" ) }()
privk := secp256k1 .PrivKeyFromBytes (data )
return (*Secp256k1PrivateKey )(privk ), nil
}
func UnmarshalSecp256k1PublicKey (data []byte ) (_k PubKey , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "secp256k1 public-key unmarshal" ) }()
k , err := secp256k1 .ParsePubKey (data )
if err != nil {
return nil , err
}
return (*Secp256k1PublicKey )(k ), nil
}
func (k *Secp256k1PrivateKey ) Type () pb .KeyType {
return pb .KeyType_Secp256k1
}
func (k *Secp256k1PrivateKey ) Raw () ([]byte , error ) {
return (*secp256k1 .PrivateKey )(k ).Serialize (), nil
}
func (k *Secp256k1PrivateKey ) Equals (o Key ) bool {
sk , ok := o .(*Secp256k1PrivateKey )
if !ok {
return basicEquals (k , o )
}
return k .GetPublic ().Equals (sk .GetPublic ())
}
func (k *Secp256k1PrivateKey ) Sign (data []byte ) (_sig []byte , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "secp256k1 signing" ) }()
key := (*secp256k1 .PrivateKey )(k )
hash := sha256 .Sum256 (data )
sig := ecdsa .Sign (key , hash [:])
return sig .Serialize (), nil
}
func (k *Secp256k1PrivateKey ) GetPublic () PubKey {
return (*Secp256k1PublicKey )((*secp256k1 .PrivateKey )(k ).PubKey ())
}
func (k *Secp256k1PublicKey ) Type () pb .KeyType {
return pb .KeyType_Secp256k1
}
func (k *Secp256k1PublicKey ) Raw () (res []byte , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "secp256k1 public key marshaling" ) }()
return (*secp256k1 .PublicKey )(k ).SerializeCompressed (), nil
}
func (k *Secp256k1PublicKey ) Equals (o Key ) bool {
sk , ok := o .(*Secp256k1PublicKey )
if !ok {
return basicEquals (k , o )
}
return (*secp256k1 .PublicKey )(k ).IsEqual ((*secp256k1 .PublicKey )(sk ))
}
func (k *Secp256k1PublicKey ) Verify (data []byte , sigStr []byte ) (success bool , err error ) {
defer func () {
catch .HandlePanic (recover (), &err , "secp256k1 signature verification" )
if err != nil {
success = false
}
}()
sig , err := ecdsa .ParseDERSignature (sigStr )
if err != nil {
return false , err
}
hash := sha256 .Sum256 (data )
return sig .Verify (hash [:], (*secp256k1 .PublicKey )(k )), nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .