bls

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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

func AggregateG1(points []bn254.G1Affine) (bn254.G1Affine, error)

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

func AggregateG2(points []bn254.G2Affine) (bn254.G2Affine, error)

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

func ComputePopHash(operator common.Address) [32]byte

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

func DeserializeG1(data []byte) (bn254.G1Affine, error)

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

func DeserializeG2(data []byte) (bn254.G2Affine, error)

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

func G1ToCoords(p bn254.G1Affine) [2]*big.Int

G1ToCoords extracts the X, Y coordinates of a G1 point as big.Ints.

func G2ToCoords

func G2ToCoords(p bn254.G2Affine) [4]*big.Int

G2ToCoords extracts the BN254 G2 coordinates in Solidity order: [x_im, x_re, y_im, y_re].

func HashToG1

func HashToG1(msgHash [32]byte) (bn254.G1Affine, error)

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

func SerializeG1(p bn254.G1Affine) []byte

SerializeG1 serializes a G1 point as 64 bytes (X || Y, big-endian).

func SerializeG2

func SerializeG2(p bn254.G2Affine) []byte

SerializeG2 serializes a G2 point as 128 bytes (X.A1 || X.A0 || Y.A1 || Y.A0, big-endian).

func Sign

func Sign(sk *fr.Element, msgHash [32]byte) (bn254.G1Affine, error)

Sign produces a BLS signature: sigma = sk * HashToG1(msgHash).

func Verify

func Verify(sigma bn254.G1Affine, pubG2 bn254.G2Affine, msgHash [32]byte) (bool, error)

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

type KeyPair struct {
	Secret   fr.Element
	PublicG1 bn254.G1Affine
	PublicG2 bn254.G2Affine
}

KeyPair holds a BLS key pair on BN254.

func GenerateKeyPair

func GenerateKeyPair() (*KeyPair, error)

GenerateKeyPair creates a random BLS key pair.

func KeyPairFromSeed

func KeyPairFromSeed(seed []byte) *KeyPair

KeyPairFromSeed derives a deterministic key pair from a seed (for tests).

func UnmarshalHexKeyPair

func UnmarshalHexKeyPair(hexStr string) (*KeyPair, error)

UnmarshalHexKeyPair parses a hex-encoded 32-byte secret scalar and reconstructs the full key pair.

func (*KeyPair) MarshalHex

func (kp *KeyPair) MarshalHex() string

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.

Jump to

Keyboard shortcuts

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