Documentation
¶
Index ¶
- Variables
- func AggregateG1(points []bn254.G1Affine) (bn254.G1Affine, error)
- func AggregateG2(points []bn254.G2Affine) (bn254.G2Affine, error)
- func ComputePopHash(operator common.Address) [32]byte
- func ComputeVaultWithdrawalID(accountID, blockHash [32]byte, entryIndex uint64, assetURI core.AssetURI, ...) [32]byte
- func DeserializeG1(data []byte) (bn254.G1Affine, error)
- func DeserializeG2(data []byte) (bn254.G2Affine, error)
- func EncodeSignatureForContract(bitmask *big.Int, sigma bn254.G1Affine, apkG2 bn254.G2Affine) ([]byte, error)
- func G1ToCoords(p bn254.G1Affine) [2]*big.Int
- func G2ToCoords(p bn254.G2Affine) [4]*big.Int
- func HashToG1(msgHash [32]byte) (bn254.G1Affine, error)
- func SerializeG1(p bn254.G1Affine) []byte
- func SerializeG2(p bn254.G2Affine) []byte
- func Sign(sk *fr.Element, msgHash [32]byte) (bn254.G1Affine, error)
- func Verify(sigma bn254.G1Affine, pubG2 bn254.G2Affine, msgHash [32]byte) (bool, error)
- func VerifyClusterSignature(data []byte, signature []byte, bitmask [32]byte, k uint16, validators [][]byte) (bool, error)
- type KeyPair
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyAggregation = errors.New("cannot aggregate empty point set")
ErrEmptyAggregation is returned when AggregateG1 or AggregateG2 is called with an empty slice. An empty set of signatures/keys must not produce a valid aggregate — doing so would allow an empty cluster to "sign" any message.
Functions ¶
func AggregateG1 ¶
AggregateG1 sums a slice of G1 points. Returns ErrEmptyAggregation if the input is empty — an empty set of signatures must not produce a valid aggregate.
func AggregateG2 ¶
AggregateG2 sums a slice of G2 points. Returns ErrEmptyAggregation if the input is empty — an empty set of public keys must not produce a valid aggregate.
func ComputePopHash ¶
ComputePopHash computes the proof-of-possession message hash for a given operator address. Matches the Solidity contract: keccak256(abi.encodePacked(msg.sender)).
func ComputeVaultWithdrawalID ¶
func ComputeVaultWithdrawalID(accountID, blockHash [32]byte, entryIndex uint64, assetURI core.AssetURI, amount decimal.Decimal, recipient string, nonce uint64) [32]byte
ComputeVaultWithdrawalID computes the frozen withdrawal ID used at the vault level after a withdrawal entry has been sealed into a block.
WithdrawalID = keccak256(accountId || blockHash || entryIndex || assetURI || amount || recipient || nonce)
Integer fields use fixed-width big-endian encoding. Variable-width fields are length-prefixed to prevent boundary-shift collisions. Amount is the canonical CBOR encoding of the protocol decimal amount; chain base-unit quantization is handled by custody before execution.
func DeserializeG1 ¶
DeserializeG1 reads a G1 point from 64 bytes (X || Y, big-endian). It is an acceptance-path decoder for untrusted input, so it fully validates the point: each coordinate must be a canonical field element (< P), and the point must be on the curve and in the prime-order subgroup. Skipping the subgroup check would admit small-subgroup points that break the signature scheme's security.
func DeserializeG2 ¶
DeserializeG2 reads a G2 point from 128 bytes. Like DeserializeG1 it is an acceptance-path decoder: it rejects non-canonical coordinates (>= P) and points that are off-curve or outside the prime-order subgroup. The off-chain verifier must apply the same membership checks the on-chain precompile does, or a crafted pubkey/signature could pass off-chain acceptance.
func EncodeSignatureForContract ¶
func EncodeSignatureForContract(bitmask *big.Int, sigma bn254.G1Affine, apkG2 bn254.G2Affine) ([]byte, error)
EncodeSignatureForContract ABI-encodes a BLS cluster signature for the Solidity contract. The Solidity contract decodes: abi.decode(signature, (uint256, uint256[2], uint256[4])) where the format is (bitmask, [sigma.X, sigma.Y], [apkG2.X.im, apkG2.X.re, apkG2.Y.im, apkG2.Y.re]).
func G1ToCoords ¶
G1ToCoords extracts the X, Y coordinates of a G1 point as big.Ints.
func G2ToCoords ¶
G2ToCoords extracts the BN254 G2 coordinates in Solidity order: [x_im, x_re, y_im, y_re].
func HashToG1 ¶
HashToG1 hashes a 32-byte message to a BN254 G1 point using try-and-increment. This MUST match the Solidity BLS.hashToG1 exactly.
func SerializeG1 ¶
SerializeG1 serializes a G1 point as 64 bytes (X || Y, big-endian).
func SerializeG2 ¶
SerializeG2 serializes a G2 point as 128 bytes (X.A1 || X.A0 || Y.A1 || Y.A0, big-endian).
func Verify ¶
Verify checks a BLS signature via pairing: e(sigma, G2gen) == e(H(m), pubG2). Equivalently: e(sigma, G2gen) * e(-H(m), pubG2) == 1.
func VerifyClusterSignature ¶
func VerifyClusterSignature(data []byte, signature []byte, bitmask [32]byte, k uint16, validators [][]byte) (bool, error)
VerifyClusterSignature verifies an aggregated BLS threshold signature against the set of validators indicated by the bitmask. The signature is expected in ABI-encoded format: (uint256 bitmask, uint256[2] sigma, uint256[4] apkG2).
k is the DQE-computed signing quorum for this block (block.K). The threshold is floor(2k/3)+1, not floor(2r/3)+1 where r=len(validators) is the shard replication factor — in multi-Slot shards r > k, so a block sealed by exactly k validators must not be rejected for under-signing against r (ISSUE-035 WS-1).
§7 coordination: validators is [][]byte (serialized BN254 G2 pubkeys, exactly 128 bytes each — ADR-008). The on-chain Slasher reconstructs apkG2 from the bitmask by summing those pubkeys; off-chain verification performs the same reconstruction and rejects entries of any other length. k=0 is rejected: every caller must supply the explicit signing quorum (F-CONSENSUS-001).
Types ¶
type KeyPair ¶
KeyPair holds a BLS key pair on BN254.
func GenerateKeyPair ¶
GenerateKeyPair creates a random BLS key pair.
func KeyPairFromSeed ¶
KeyPairFromSeed derives a deterministic key pair from a seed (for tests).
func UnmarshalHexKeyPair ¶
UnmarshalHexKeyPair parses a hex-encoded 32-byte secret scalar and reconstructs the full key pair.
func (*KeyPair) MarshalHex ¶
MarshalHex serializes the secret scalar as a 64-character hex string (pure, in-memory). File persistence belongs to the caller — see `cmd/clearnode` and `client/chain.go` for production I/O.