gcrypto

package
v0.0.0-...-506a26f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2024 License: Apache-2.0 Imports: 12 Imported by: 6

Documentation

Overview

Package gcrypto contains cryptographic primitives for the Gordian engine.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidSignature = errors.New("signature could not be verified")
View Source
var ErrUnknownKey = errors.New("unknown key")

Functions

func RegisterEd25519

func RegisterEd25519(reg *Registry)

RegisterEd25519 registers ed25519 with the given Registry. There is no global registry; it is the caller's responsibility to register as needed.

Types

type CommonMessageSignatureProof

type CommonMessageSignatureProof interface {
	// Message is the value being signed in this proof.
	// It is assumed that one proof contains signatures representing one or many public keys,
	// all for the same message.
	//
	// Depending on its configuration, the engine may aggregate
	// different signature proofs, for different messages,
	// into a single, multi-message proof when serializing a block.
	Message() []byte

	// PubKeyHash is an implementation-specific hash across all the candidate keys,
	// to be used as a quick check whether two independent proofs
	// reference the same set of validators.
	//
	// Note, in the future, the algorithm for determining a candidate key hash
	// will probably fall upon a new Scheme definition.
	PubKeyHash() []byte

	// AddSignature adds a signature representing a single key.
	//
	// This should only be called when receiving the local application's signature for a message.
	// Otherwise, use the Merge method to combine incoming proofs with the existing one.
	//
	// If the signature does not match, or if the public key was not one of the candidate keys,
	// an error is returned.
	AddSignature(sig []byte, key PubKey) error

	// Matches reports whether the other proof references the same message and keys
	// as the current proof.
	//
	// Matches does not inspect the signatures present in either proof.
	Matches(other CommonMessageSignatureProof) bool

	// Merge adds the signature information in other to the current proof, without modifying other.
	//
	// The other value is assumed to be untrusted, and the proof should verify
	// every provided signature in other.
	//
	// If other is not the same underlying type, Merge panics.
	Merge(other CommonMessageSignatureProof) SignatureProofMergeResult

	// MergeSparse merges a sparse proof into the current proof.
	// This is intended to be used as part of accepting proofs from peers,
	// where peers will transmit a sparse value.
	MergeSparse(SparseSignatureProof) SignatureProofMergeResult

	// HasSparseKeyID reports whether the full proof already contains a signature
	// matching the given sparse key ID.
	// If the key ID does not properly map into the set of trusted public keys,
	// the "valid" return parameter will be false.
	HasSparseKeyID(keyID []byte) (has, valid bool)

	// Clone returns a copy of the current proof.
	//
	// This is useful when one goroutine owns the writes to a proof,
	// and another goroutine needs a read-only view without mutex contention.
	Clone() CommonMessageSignatureProof

	// Derive is like Clone;
	// it returns a copy of the current proof, but with all signature data cleared.
	//
	// This is occasionally useful when you have a valid proof,
	// but not a proof scheme, and you need to make a complicated operation.
	Derive() CommonMessageSignatureProof

	// SignatureBitSet returns a bit set indicating which of the candidate keys
	// have signatures included in this proof.
	//
	// In the case of a SignatureProof that involves aggregating signatures,
	// the count of set bits may be greater than the number of signatures.
	SignatureBitSet() *bitset.BitSet

	// AsSparse returns a sparse version of the proof,
	// suitable for transmitting over the network.
	AsSparse() SparseSignatureProof
}

CommonMessageSignatureProof manages a mapping of signatures to public keys against a single common message. Constructors for instances of CommonMessageSignatureProof should accept a "candidate public keys" slice as the Signed method returns a bit set indicating the indices of those candidate values whose signatures we have accepted and validated.

This is intended primarily for checking validator signatures, when validators are each signing an identical message.

type CommonMessageSignatureProofScheme

type CommonMessageSignatureProofScheme interface {
	// New creates a new, empty proof.
	New(msg []byte, candidateKeys []PubKey, pubKeyHash string) (CommonMessageSignatureProof, error)

	// IsValidKeyID reports whether the given ID is valid given the set of public keys.
	IsValidKeyID(id []byte, keys []PubKey) bool
}

CommonMessageSignatureProofScheme indicates how to create CommonMessageSignatureProof instances.

It also contains methods that have no relation to a particular proof instance.

var SimpleCommonMessageSignatureProofScheme CommonMessageSignatureProofScheme = LiteralCommonMessageSignatureProofScheme(
	NewSimpleCommonMessageSignatureProof,
	isValidSimpleCommonSignatureKeyID,
)

SimpleCommonMessageSignatureProofScheme is the scheme for a SimpleCommonMessageSignatureProof.

func LiteralCommonMessageSignatureProofScheme

func LiteralCommonMessageSignatureProofScheme[P CommonMessageSignatureProof](
	newFn func([]byte, []PubKey, string) (P, error),
	isValidKeyIDFn func([]byte, []PubKey) bool,
) CommonMessageSignatureProofScheme

LiteralCommonMessageSignatureProofScheme returns a CommonMessageSignatureProofScheme from a literal function with a strongly typed return values.

This allows signature proof authors to follow the more common pattern of returning the concrete types in their constructor functions, without writing extra boilerplate to produce a corresponding scheme.

type Ed25519PubKey

type Ed25519PubKey ed25519.PublicKey

func (Ed25519PubKey) Equal

func (e Ed25519PubKey) Equal(other PubKey) bool

func (Ed25519PubKey) PubKeyBytes

func (e Ed25519PubKey) PubKeyBytes() []byte

func (Ed25519PubKey) TypeName

func (e Ed25519PubKey) TypeName() string

func (Ed25519PubKey) Verify

func (e Ed25519PubKey) Verify(msg, sig []byte) bool

type Ed25519Signer

type Ed25519Signer struct {
	// contains filtered or unexported fields
}

func NewEd25519Signer

func NewEd25519Signer(priv ed25519.PrivateKey) Ed25519Signer

func (Ed25519Signer) PubKey

func (s Ed25519Signer) PubKey() PubKey

func (Ed25519Signer) Sign

func (s Ed25519Signer) Sign(_ context.Context, input []byte) ([]byte, error)

type NewPubKeyFunc

type NewPubKeyFunc func([]byte) (PubKey, error)

type PubKey

type PubKey interface {
	// The raw bytes constituting the public key.
	// Implementers are free to return the same underlying slice on every call,
	// and callers must not modify the slice;
	// callers may also assume the slice will never be modified.
	PubKeyBytes() []byte

	// Equal reports whether the other key is of the same type
	// and has the same public key bytes.
	Equal(other PubKey) bool

	// Verify reports whether the signature is authentic,
	// for the given message against this public key.
	Verify(msg, sig []byte) bool

	// The internal name of this key's type.
	// This must be a valid ASCII string of length 8 bytes or fewer,
	// and it must be an identical string for every instance of this type.
	TypeName() string
}

PubKey is the interface for an instance of a public key.

func NewEd25519PubKey

func NewEd25519PubKey(b []byte) (PubKey, error)

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is a runtime-defined registry to manage encoding and decoding a predetermined set of public key types.

func (*Registry) Decode

func (r *Registry) Decode(typeName string, b []byte) (PubKey, error)

Decode returns a new PubKey from the given type and public key bytes. It returns an error if the typeName was not previously registered, or if the registered NewPubKeyFunc itself returns an error.

Callers must assume that the returned public key retains a reference to b, and therefore b must not be modified after calling Decode.

func (*Registry) Marshal

func (r *Registry) Marshal(pubKey PubKey) []byte

func (*Registry) Register

func (r *Registry) Register(name string, inst PubKey, newFn NewPubKeyFunc)

func (*Registry) Unmarshal

func (r *Registry) Unmarshal(b []byte) (PubKey, error)

Unmarshal returns a new public key based on b, which should be the result of a previous call to *Registry.Marshal.

Callers should assume that the newly returned PubKey will retain a reference to b; therefore the slice must not be modified after calling Unmarshal.

type SignatureProofMergeResult

type SignatureProofMergeResult struct {
	// Whether every signature in the "other" proof was valid.
	AllValidSignatures bool

	// Whether merging resulted in signatures we did not yet have.
	IncreasedSignatures bool

	// Was the "other" proof a strict superset of the current proof?
	WasStrictSuperset bool
}

SignatureProofMergeResult includes three important details that determine whether meaningful new information was learned from two signature proofs, and whether the message for the "other" proof should be propagated further or if the current/merged proof should be sent in its place.

If AllValidSignatures was false, then the other message should not be propagated.

IncreasedSignatures indicates whether the other proof had any signatures missing from the current proof. This does not indicate whether the current proof had any signatures missing from other.

func (SignatureProofMergeResult) Combine

Combine returns a new SignatureProofMergeResult, the result of combining r and other. This is helpful for methods that combine multiple proofs, such as a prevote merge that must handle both active and nil prevotes.

type Signer

type Signer interface {
	// PubKey returns the gcrypto public key.
	PubKey() PubKey

	// Sign returns the signature for a given input.
	// It accepts a context in case the signing happens remotely.
	Sign(ctx context.Context, input []byte) (signature []byte, err error)
}

Signer produces cryptographic signatures against an input.

type SimpleCommonMessageSignatureProof

type SimpleCommonMessageSignatureProof struct {
	// contains filtered or unexported fields
}

SimpleCommonMessageSignatureProof is the simplest signature proof, which only tracks pairs of signatures and public keys.

func NewSimpleCommonMessageSignatureProof

func NewSimpleCommonMessageSignatureProof(msg []byte, candidateKeys []PubKey, pubKeyHash string) (SimpleCommonMessageSignatureProof, error)

func (SimpleCommonMessageSignatureProof) AddSignature

func (p SimpleCommonMessageSignatureProof) AddSignature(sig []byte, key PubKey) error

func (SimpleCommonMessageSignatureProof) AsSparse

func (SimpleCommonMessageSignatureProof) Clone

func (SimpleCommonMessageSignatureProof) Derive

func (SimpleCommonMessageSignatureProof) HasSparseKeyID

func (p SimpleCommonMessageSignatureProof) HasSparseKeyID(keyID []byte) (has, valid bool)

func (SimpleCommonMessageSignatureProof) Matches

func (SimpleCommonMessageSignatureProof) Merge

func (SimpleCommonMessageSignatureProof) MergeSparse

func (SimpleCommonMessageSignatureProof) Message

func (SimpleCommonMessageSignatureProof) PubKeyHash

func (p SimpleCommonMessageSignatureProof) PubKeyHash() []byte

func (SimpleCommonMessageSignatureProof) SignatureBitSet

func (p SimpleCommonMessageSignatureProof) SignatureBitSet() *bitset.BitSet

type SparseSignature

type SparseSignature struct {
	// The Key ID is an opaque value, specific to the full proof,
	// indicating which key or keys are represented by the given signature.
	KeyID []byte

	// The bytes of the signature.
	Sig []byte
}

SparseSignature is part of a SparseSignatureProof, representing one or many original signatures, depending on whether the non-sparse proof aggregates signatures.

type SparseSignatureProof

type SparseSignatureProof struct {
	// The PubKeyHash of the original proof.
	PubKeyHash string

	// The signatures for this proof,
	// along with implementation-specific key IDs.
	Signatures []SparseSignature
}

SparseSignatureProof is a minimal representation of a single signature proof.

This format is suitable for network transmission, as it does not encode the entire proof state, but it suffices for the remote end with fuller knowledge to use MergeSparse to increase signature proof awareness.

NOTE: this may be renamed in the future if multiple-message signature proofs need a different sparse representation.

Directories

Path Synopsis
Code generated by go generate; DO NOT EDIT.
Code generated by go generate; DO NOT EDIT.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL