galoisd/README.md
Galois daemon (galoisd) is a gRPC service providing consensus proof generation for CometBLS block headers. It requires another service, such as an IBC relayer, to send block data for zkp generation.
The circuits developed under this service are tailored for the light client. Various implementations are partial and may not be sound if reused in a different context. We do not recommend reusing part of the circuits independently.
Call galoisd --help to see an up-to-date overview of functions. The CLI is self-documenting.
nix developnix run .#galoisd -- --helpWarning
galoisd is not designed to be a public service. Proving is a computationally intensive process. Incorrectly configuring the service can lead to denial-of-service attacks.
For production deployments, use the docker image provided in our package registry.
docker pull ghcr.io/unionlabs/galoisd:<VERSION>
nix run github:unionlabs/union/<COMMIT_OR_VERSION>#galoisd -- --help
Galoisd exposes gRPC endpoints to generate and verify CometBLS zero-knowledge proofs.
The CometBLS circuit is generic over $2^n$ validators. It is built to verify (non-)adjacent transitions between blocks. We decided to implements the circuit on top of Gnark. Galois includes the following gadgets that are not yet available in Gnark:
BN254 emulated $G_2$ arithmetic for hashing to curve.Follows RFC-6962 - Merkle Hash Trees where the hash function is BN254-MiMC.
The circuit is generic over the size of the embedded tree, which is fixed by the parent circuit that contains it. As a result, when computing the root, the caller must provide the current size of the tree, with any padding data intentionally discarded.
The BLS circuit provides facilities to aggregate and verify signatures.
WARNING: When registering a public key (specifically a validator in this case), it is essential to provide a proof of possession to prevent rogue key attacks. The aggregation component of the circuit assumes that every public key being aggregated has been verified with a proof of possession prior to the proving process.
The light client circuits enable the verification of non-adjacent CometBLS blocks, analogous to Tendermint's existing non-adjacent verification functionality.
The prover must provide both trusted and untrusted validator sets, where a minimum of 1/3 of the trusted validators and 2/3 of the untrusted validators must have signed the block header. If fewer than 1/3 of the trusted validators have attested the block, it is up to the caller to supply a valid checkpoint block (typically achieved through bisection) to satisfy the constraint.
The sole public input is a SHA-256 hash of all inputs to be verified:
let public_input = sha256(
header.chain_id,
header.height,
header.time.seconds,
header.time.nanoseconds,
header.validators_hash,
header.next_validators_hash,
header.app_hash,
trusted_validators_hash
) & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
Where header represents the new block header to verify and trusted_validators_hash is the next_validators_hash of the previously verified header. Furthermore, we truncate the most significant byte to fit the BN254 scalar field.
In the circuit, we proceed as follows:
trusted_validators_hash have signed (recalculate and verify the validators hash,
aggregate public keys and verify signature).header.validators_hash have signed (recalculate and verify the validators hash,
aggregate public keys and verify signature).Note that both signatures verified in-circuit must be computed by the caller.
The circuit is currently designed for a maximum of 128 validators.
The gRPC service facilitate interactions with Galois.
Proving require the client to submit a ProveRequest to the Prove endpoint.
The result will contains both a Gnark-compatible and EVM-compatible proofs.
sequenceDiagram
Client->>Galois: ProveRequest
Galois->>Client: ProveResponse
Verifying is done through the Verify endpoint, by submitting a VerifyRequest.
The result is a boolean value telling whether or not the proof is valid.
Note that the provided as input is expected to be a Gnark-compatible proof and not the EVM variant.
sequenceDiagram
Client->>Galois: VerifyRequest
Galois->>Client: VerifyResponse