Skip to main content

Hint

Trait Hint 

Source
pub trait Hint:
    Send
    + Sync
    + 'static {
    const NAME: &'static str;

    // Required methods
    fn shape(&self, dimensions: &[usize]) -> (usize, usize);
    fn execute(
        &self,
        dimensions: &[usize],
        inputs: &[Word],
        outputs: &mut [Word],
    );
}
Expand description

Hint handler trait for extensible operations.

Each implementor declares a globally unique name, and the registry keys on the hash of that name alone.

Every gate using the same hint type therefore shares one handler entry.

A hint’s fields are not part of its identity. Only the first value registered under a name is kept; later values are dropped. Gates that differ only in those fields fold together under deduplication. Parameterize a hint through its dimensions, never through its fields.

§The dimensions parameter

Both shape and execute take a dimensions: &[usize] slice. This is hint-defined parameterization for a single gate — the values the caller passes when invoking the hint via CircuitBuilder::call_hint. The same slice is then handed back to execute at witness-generation time.

dimensions controls input/output arity: shape(dimensions) -> (n_in, n_out) tells the builder how many wires the gate consumes and produces, and execute is later called with inputs.len() == n_in and outputs.len() == n_out. A hint whose arity is fixed (e.g. always 4 inputs / 6 outputs) takes an empty slice and ignores it. A hint that is parameterized over, say, big-integer limb counts takes those counts as dimensions.

Two arity modes illustrate the contract:

  • A parameterized hint reads limb counts from dimensions and derives its arity from them.
  • A fixed-arity hint ignores dimensions (an empty slice) and returns a constant shape.

Required Associated Constants§

Source

const NAME: &'static str

Globally unique name for this hint, which the registry hashes into its key.

Required Methods§

Source

fn shape(&self, dimensions: &[usize]) -> (usize, usize)

Compute the gate’s input/output arity as a function of dimensions.

Called once when the gate is emitted by call_hint to allocate output wires. The returned (n_in, n_out) is the contract for the matching execute call: the builder will provide n_in input wires and expect n_out outputs.

Implementations must be a pure function of dimensions and must agree with execute on the same dimensions.

Source

fn execute(&self, dimensions: &[usize], inputs: &[Word], outputs: &mut [Word])

Compute the hint’s outputs from its inputs at witness-generation time.

Receives the same dimensions slice that was passed to shape when the gate was emitted. inputs.len() == n_in and outputs.len() == n_out where (n_in, n_out) == self.shape(dimensions). Implementations write all n_out output slots — including zero-padding when the natural result has fewer significant words.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§