Documentation
¶
Overview ¶
Package sign provides blockchain-agnostic cryptographic signing interfaces.
This package defines core interfaces for digital signatures that can be implemented by various blockchain ecosystems while maintaining a consistent API for signing operations.
The primary interfaces are:
- Signer: Core interface for cryptographic signing operations
- PublicKey: Interface for public key operations
- Address: Interface for blockchain addresses
- AddressRecoverer: Optional interface for signature-based address recovery
Security Design ¶
This package follows security best practices by:
- Never exposing private key material through interfaces
- Providing only necessary operations (signing and public key access)
- Supporting hardware security modules (HSM) and key management services (KMS)
- Preventing accidental private key leakage in logs or debugging
Usage
// Create a new Ethereum signer from a hex-encoded private key
signer, err := sign.NewEthereumSigner(privateKeyHex)
if err != nil {
log.Fatal(err)
}
// Sign a message (provide hash, not raw message)
message := []byte("hello world")
hash := ethcrypto.Keccak256Hash(message)
signature, err := signer.Sign(hash.Bytes())
if err != nil {
log.Fatal(err)
}
// Get the address
address := signer.PublicKey().Address()
fmt.Println("Address:", address.String())
Package sign provides mock implementations for testing signature operations.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Address ¶
type Address interface {
fmt.Stringer // All addresses must have a string representation.
// Equals returns true if this address equals the other address.
Equals(other Address) bool
}
Address is an interface for a blockchain-specific address.
func RecoverAddressFromHash ¶
RecoverAddressFromHash recovers an address from a signature using a pre-computed hash.
Example ¶
ExampleRecoverAddressFromHash demonstrates Ethereum-specific address recovery.
package main
import (
"fmt"
"log"
"github.com/erc7824/nitrolite/clearnode/pkg/sign"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
)
func main() {
// Example message for standard recovery
message := []byte("hello world")
// Create a signature using our signer
pkHex := "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
signer, err := sign.NewEthereumSigner(pkHex)
if err != nil {
log.Fatal(err)
}
hash := ethcrypto.Keccak256Hash(message)
signature, err := signer.Sign(hash.Bytes())
if err != nil {
log.Fatal(err)
}
// Call the function directly from the `sign` package for hash recovery
recoveredAddr, err := sign.RecoverAddressFromHash(hash.Bytes(), signature)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
// Verify it matches the signer's address
signerAddr := signer.PublicKey().Address()
fmt.Printf("Addresses match: %t\n", recoveredAddr.Equals(signerAddr))
}
Output: Addresses match: true
type AddressRecoverer ¶
type AddressRecoverer interface {
RecoverAddress(message []byte, signature Signature) (Address, error)
}
AddressRecoverer is an interface for recovering addresses from signatures.
func NewAddressRecoverer ¶
func NewAddressRecoverer(sigType Type) (AddressRecoverer, error)
NewAddressRecoverer creates an appropriate AddressRecoverer based on the signature algorithm.
func NewAddressRecovererFromSignature ¶
func NewAddressRecovererFromSignature(signature Signature) (AddressRecoverer, error)
NewAddressRecovererFromSignature creates an AddressRecoverer based on signature algorithm detection.
type EthereumAddress ¶
EthereumAddress implements the Address interface for Ethereum.
func NewEthereumAddress ¶
func NewEthereumAddress(addr common.Address) EthereumAddress
NewEthereumAddress creates a new Ethereum address from a common.Address.
func NewEthereumAddressFromHex ¶
func NewEthereumAddressFromHex(hexAddr string) EthereumAddress
NewEthereumAddressFromHex creates a new Ethereum address from a hex string.
func (EthereumAddress) Equals ¶
func (a EthereumAddress) Equals(other Address) bool
Equals returns true if this address equals the other address.
func (EthereumAddress) String ¶
func (a EthereumAddress) String() string
type EthereumAddressRecoverer ¶
type EthereumAddressRecoverer struct{}
EthereumAddressRecoverer implements the AddressRecoverer interface for Ethereum.
Example ¶
ExampleEthereumAddressRecoverer demonstrates using the generic AddressRecoverer interface.
package main
import (
"fmt"
"log"
"github.com/erc7824/nitrolite/clearnode/pkg/sign"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
)
func main() {
message := []byte("hello world")
// Create a signer
pkHex := "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
signer, err := sign.NewEthereumSigner(pkHex)
if err != nil {
log.Fatal(err)
}
// Sign the message (note: Ethereum signers expect a hash)
hash := ethcrypto.Keccak256Hash(message)
signature, err := signer.Sign(hash.Bytes())
if err != nil {
log.Fatal(err)
}
// Use the dedicated AddressRecoverer implementation
var recoverer sign.AddressRecoverer = &sign.EthereumAddressRecoverer{}
// The recoverer implementation will hash the raw message internally
recoveredAddr, err := recoverer.RecoverAddress(message, signature)
if err != nil {
log.Fatal(err)
}
signerAddr := signer.PublicKey().Address()
fmt.Printf("Generic recovery works: %t\n", recoveredAddr.Equals(signerAddr))
}
Output: Generic recovery works: true
func (*EthereumAddressRecoverer) RecoverAddress ¶
func (r *EthereumAddressRecoverer) RecoverAddress(message []byte, signature Signature) (Address, error)
RecoverAddress implements the AddressRecoverer interface.
type EthereumPublicKey ¶
EthereumPublicKey implements the PublicKey interface for Ethereum.
func NewEthereumPublicKey ¶
func NewEthereumPublicKey(pub *ecdsa.PublicKey) EthereumPublicKey
NewEthereumPublicKey creates a new Ethereum public key from an ECDSA public key.
func NewEthereumPublicKeyFromBytes ¶
func NewEthereumPublicKeyFromBytes(pubBytes []byte) (EthereumPublicKey, error)
NewEthereumPublicKeyFromBytes creates a new Ethereum public key from raw bytes.
func (EthereumPublicKey) Address ¶
func (p EthereumPublicKey) Address() Address
func (EthereumPublicKey) Bytes ¶
func (p EthereumPublicKey) Bytes() []byte
type EthereumSigner ¶
type EthereumSigner struct {
// contains filtered or unexported fields
}
EthereumSigner is the Ethereum implementation of the Signer interface.
func (*EthereumSigner) PublicKey ¶
func (s *EthereumSigner) PublicKey() PublicKey
type MockAddress ¶ added in v0.4.0
type MockAddress struct {
// contains filtered or unexported fields
}
MockAddress is a mock implementation of the Address interface for testing. It uses a simple string ID as the address representation.
func NewMockAddress ¶ added in v0.4.0
func NewMockAddress(id string) *MockAddress
NewMockAddress creates a new MockAddress with the given ID.
func (*MockAddress) Equals ¶ added in v0.4.0
func (m *MockAddress) Equals(other Address) bool
Equals compares this address with another by comparing their string representations.
func (*MockAddress) String ¶ added in v0.4.0
func (m *MockAddress) String() string
String returns the ID as the string representation of the address.
type MockPublicKey ¶ added in v0.4.0
type MockPublicKey struct {
// contains filtered or unexported fields
}
MockPublicKey is a mock implementation of the PublicKey interface for testing. It stores an ID string that is used as both the key data and address.
func NewMockPublicKey ¶ added in v0.4.0
func NewMockPublicKey(id string) *MockPublicKey
NewMockPublicKey creates a new MockPublicKey with the given ID.
func (*MockPublicKey) Address ¶ added in v0.4.0
func (m *MockPublicKey) Address() Address
Address returns a mock address based on the public key's ID.
func (*MockPublicKey) Bytes ¶ added in v0.4.0
func (m *MockPublicKey) Bytes() []byte
Bytes returns the ID as a byte slice.
type MockSigner ¶ added in v0.4.0
type MockSigner struct {
// contains filtered or unexported fields
}
MockSigner is a mock implementation of the Signer interface for testing purposes. It generates predictable signatures by appending a suffix to the data.
func NewMockSigner ¶ added in v0.4.0
func NewMockSigner(id string) *MockSigner
NewMockSigner creates a new MockSigner with the given ID. The ID is used to create the underlying mock public key.
func (*MockSigner) PublicKey ¶ added in v0.4.0
func (m *MockSigner) PublicKey() PublicKey
PublicKey returns the mock public key associated with this signer.
type Signature ¶
type Signature []byte
Signature is a generic byte slice representing a cryptographic signature.
func (Signature) MarshalJSON ¶
MarshalJSON implements the json.Marshaler interface, encoding the signature as a hex string.
func (Signature) String ¶
String implements the fmt.Stringer interface
Example ¶
ExampleSignature_String demonstrates the String method of Signature.
package main
import (
"fmt"
"github.com/erc7824/nitrolite/clearnode/pkg/sign"
)
func main() {
sig := sign.Signature([]byte{0x01, 0x02, 0x03, 0x04})
fmt.Println(sig.String())
}
Output: 0x01020304
func (Signature) Type ¶
Type returns the signature type for this signature based on its length and structure.
func (*Signature) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unmarshaler interface.
type Signer ¶
type Signer interface {
PublicKey() PublicKey // Public key associated with this signer.
Sign(data []byte) (Signature, error) // Sign generates a signature for the given data.
}
Signer is an interface for a blockchain-agnostic signer.
func NewEthereumSigner ¶
NewEthereumSigner creates a new Ethereum signer from a hex-encoded private key.
Example ¶
ExampleNewEthereumSigner demonstrates creating an Ethereum signer and signing a message.
package main
import (
"fmt"
"log"
"github.com/erc7824/nitrolite/clearnode/pkg/sign"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
)
func main() {
pkHex := "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" // Example private key
// Create a new Ethereum signer. It returns the generic sign.Signer interface.
signer, err := sign.NewEthereumSigner(pkHex)
if err != nil {
log.Fatal(err)
}
// You can now use the signer for generic operations.
fmt.Println("Address:", signer.PublicKey().Address())
message := []byte("hello world")
hash := ethcrypto.Keccak256Hash(message)
signature, err := signer.Sign(hash.Bytes())
if err != nil {
log.Fatal(err)
}
fmt.Println("Signature length:", len(signature))
}
Output: Address: 0x1Be31A94361a391bBaFB2a4CCd704F57dc04d4bb Signature length: 65