Files
indra/pkg/crypto/key/sig/signature.go

50 lines
1.7 KiB
Go

// Package sig provides functions to Sign hashes of messages, generating a
// standard compact 65 byte Signature and recover the 33 byte pub.Key embedded
// in it. This is used as a MAC for Indra packets to associate messages with
// Indra peers' sessions.
package sig
import (
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
"github.com/indra-labs/indra"
"github.com/indra-labs/indra/pkg/crypto/key/prv"
"github.com/indra-labs/indra/pkg/crypto/key/pub"
"github.com/indra-labs/indra/pkg/crypto/sha256"
log2 "github.com/indra-labs/indra/pkg/proc/log"
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
)
// Len is the length of the signatures used in Indra, compact keys that can have
// the public key extracted from them, thus eliminating the need to separately
// specify it in messages.
const Len = 65
// Bytes is an ECDSA BIP62 formatted compact signature which allows the recovery
// of the public key from the signature. This allows messages to avoid adding
// extra bytes to also specify the public key of the signer.
type Bytes [Len]byte
// Sign produces an ECDSA BIP62 compact signature.
func Sign(prv *prv.Key, hash sha256.Hash) (sig Bytes, e error) {
copy(sig[:],
ecdsa.SignCompact((*secp256k1.PrivateKey)(prv), hash[:], true))
return
}
// Recover the public key corresponding to the signing private key used to
// create a signature on the hash of a message.
func (sig Bytes) Recover(hash sha256.Hash) (p *pub.Key, e error) {
var pk *secp256k1.PublicKey
// We are only using compressed keys, so we can ignore the compressed
// bool.
if pk, _, e = ecdsa.RecoverCompact(sig[:], hash[:]); !check(e) {
p = (*pub.Key)(pk)
}
return
}