mirror of https://github.com/status-im/go-waku.git
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
|
package discovery
|
||
|
|
||
|
import (
|
||
|
"crypto/ecdsa"
|
||
|
"crypto/subtle"
|
||
|
"encoding/asn1"
|
||
|
"errors"
|
||
|
"math/big"
|
||
|
|
||
|
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||
|
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
|
||
|
"github.com/minio/sha256-simd"
|
||
|
)
|
||
|
|
||
|
// Taken from: https://github.com/libp2p/go-libp2p-core/blob/094b0d3f8ba2934339cb35e1a875b11ab6d08839/crypto/ecdsa.go as
|
||
|
// they don't provide a way to set the key
|
||
|
var ErrNilSig = errors.New("sig is nil")
|
||
|
|
||
|
// ECDSASig holds the r and s values of an ECDSA signature
|
||
|
type ECDSASig struct {
|
||
|
R, S *big.Int
|
||
|
}
|
||
|
|
||
|
// ECDSAPublicKey is an implementation of an ECDSA public key
|
||
|
type ECDSAPublicKey struct {
|
||
|
pub *ecdsa.PublicKey
|
||
|
}
|
||
|
|
||
|
// Type returns the key type
|
||
|
func (ePub *ECDSAPublicKey) Type() pb.KeyType {
|
||
|
return pb.KeyType_Secp256k1
|
||
|
}
|
||
|
|
||
|
// Raw returns x509 bytes from a public key
|
||
|
func (ePub *ECDSAPublicKey) Raw() ([]byte, error) {
|
||
|
return ethcrypto.CompressPubkey(ePub.pub), nil
|
||
|
}
|
||
|
|
||
|
// Bytes returns the public key as protobuf bytes
|
||
|
func (ePub *ECDSAPublicKey) Bytes() ([]byte, error) {
|
||
|
return crypto.MarshalPublicKey(ePub)
|
||
|
}
|
||
|
|
||
|
// Equals compares to public keys
|
||
|
func (ePub *ECDSAPublicKey) Equals(o crypto.Key) bool {
|
||
|
return basicEquals(ePub, o)
|
||
|
}
|
||
|
|
||
|
// Verify compares data to a signature
|
||
|
func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (bool, error) {
|
||
|
sig := new(ECDSASig)
|
||
|
if _, err := asn1.Unmarshal(sigBytes, sig); err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
if sig == nil {
|
||
|
return false, ErrNilSig
|
||
|
}
|
||
|
|
||
|
hash := sha256.Sum256(data)
|
||
|
|
||
|
return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil
|
||
|
}
|
||
|
|
||
|
func basicEquals(k1, k2 crypto.Key) bool {
|
||
|
if k1.Type() != k2.Type() {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
a, err := k1.Raw()
|
||
|
if err != nil {
|
||
|
return false
|
||
|
}
|
||
|
b, err := k2.Raw()
|
||
|
if err != nil {
|
||
|
return false
|
||
|
}
|
||
|
return subtle.ConstantTimeCompare(a, b) == 1
|
||
|
}
|