acir::circuit::opcodes

Enum Opcode

Source
pub enum Opcode<F: AcirField> {
    AssertZero(Expression<F>),
    BlackBoxFuncCall(BlackBoxFuncCall<F>),
    MemoryOp {
        block_id: BlockId,
        op: MemOp<F>,
    },
    MemoryInit {
        block_id: BlockId,
        init: Vec<Witness>,
        block_type: BlockType,
    },
    BrilligCall {
        id: BrilligFunctionId,
        inputs: Vec<BrilligInputs<F>>,
        outputs: Vec<BrilligOutputs>,
        predicate: Option<Expression<F>>,
    },
    Call {
        id: AcirFunctionId,
        inputs: Vec<Witness>,
        outputs: Vec<Witness>,
        predicate: Option<Expression<F>>,
    },
}
Expand description

Defines an operation within an ACIR circuit

Expects a type parameter F which implements AcirField.

Variants§

§

AssertZero(Expression<F>)

An AssertZero opcode adds the constraint that P(w) = 0, where w=(w_1,..w_n) is a tuple of n witnesses, and P is a multi-variate polynomial of total degree at most 2.

The coefficients {q_M}_{i,j}, q_i,q_c of the polynomial are known values which define the opcode.

A general expression of assert-zero opcode is the following:

\sum_{i,j} {q_M}_{i,j}w_iw_j + \sum_i q_iw_i +q_c = 0

An assert-zero opcode can be used to:

  • express a constraint on witnesses; for instance to express that a witness w is a boolean, you can add the opcode: w*w-w=0
  • or, to compute the value of an arithmetic operation of some inputs.

For instance, to multiply two witnesses x and y, you would use the opcode z-x*y=0, which would constrain z to be x*y.

The solver expects that at most one witness is not known when executing the opcode.

§

BlackBoxFuncCall(BlackBoxFuncCall<F>)

Calls to “gadgets” which rely on backends implementing support for specialized constraints.

Often used for exposing more efficient implementations of SNARK-unfriendly computations.

All black box function inputs are specified as FunctionInput, and they have one or several witnesses as output.

Some more advanced computations assume that the proving system has an ‘embedded curve’. It is a curve that cycles with the main curve of the proving system, i.e the scalar field of the embedded curve is the base field of the main one, and vice-versa. e.g. Aztec’s Barretenberg uses BN254 as the main curve and Grumpkin as the embedded curve.

§

MemoryOp

Atomic operation on a block of memory

ACIR is able to address any array of witnesses. Each array is assigned an id (BlockId) and needs to be initialized with the Opcode::MemoryInit opcode. Then it is possible to read and write from/to an array by providing the index and the value we read/write as arithmetic expressions. Note that ACIR arrays all have a known fixed length (given in the Opcode::MemoryInit opcode below)

Fields

§block_id: BlockId

Identifier of the array

§op: MemOp<F>

Describe the memory operation to perform

§

MemoryInit

Initialize an ACIR array from a vector of witnesses.

There must be only one MemoryInit per block_id, and MemoryOp opcodes must come after the MemoryInit.

Fields

§block_id: BlockId

Identifier of the array

§init: Vec<Witness>

Vector of witnesses specifying the initial value of the array

§block_type: BlockType

Specify what type of memory we should initialize

§

BrilligCall

Calls to unconstrained functions. Unconstrained functions are constructed with Brillig.

Fields

§id: BrilligFunctionId

Id for the function being called. It is the responsibility of the executor to fetch the appropriate Brillig bytecode from this id.

§inputs: Vec<BrilligInputs<F>>

Inputs to the function call

§outputs: Vec<BrilligOutputs>

Outputs to the function call

§predicate: Option<Expression<F>>

Predicate of the Brillig execution - when the predicate evaluates to 0, execution is skipped. When the predicate evaluates to 1 or is None, execution proceeds.

§

Call

Calls to functions represented as a separate circuit. A call opcode allows us to build a call stack when executing the outer-most circuit.

Fields

§id: AcirFunctionId

Id for the function being called. It is the responsibility of the executor to fetch the appropriate circuit from this id.

§inputs: Vec<Witness>

Inputs to the function call

§outputs: Vec<Witness>

Outputs of the function call

§predicate: Option<Expression<F>>

Predicate of the circuit execution - when the predicate evaluates to 0, execution is skipped. When the predicate evaluates to 1 or is None, execution proceeds.

Trait Implementations§

Source§

impl<F: Clone + AcirField> Clone for Opcode<F>

Source§

fn clone(&self) -> Opcode<F>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<F: AcirField> Debug for Opcode<F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, F> Deserialize<'de> for Opcode<F>
where F: Deserialize<'de> + AcirField,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<F: AcirField> Display for Opcode<F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<F: Hash + AcirField> Hash for Opcode<F>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<F: PartialEq + AcirField> PartialEq for Opcode<F>

Source§

fn eq(&self, other: &Opcode<F>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<F> Serialize for Opcode<F>
where F: Serialize + AcirField,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<F: Eq + AcirField> Eq for Opcode<F>

Source§

impl<F: AcirField> StructuralPartialEq for Opcode<F>

Auto Trait Implementations§

§

impl<F> Freeze for Opcode<F>
where F: Freeze,

§

impl<F> RefUnwindSafe for Opcode<F>
where F: RefUnwindSafe,

§

impl<F> Send for Opcode<F>
where F: Send,

§

impl<F> Sync for Opcode<F>
where F: Sync,

§

impl<F> Unpin for Opcode<F>
where F: Unpin,

§

impl<F> UnwindSafe for Opcode<F>
where F: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,