Skip to main content

midnight_circuits/instructions/
assignments.rs

1// This file is part of MIDNIGHT-ZK.
2// Copyright (C) Midnight Foundation
3// SPDX-License-Identifier: Apache-2.0
4// Licensed under the Apache License, Version 2.0 (the "License");
5// You may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7// http://www.apache.org/licenses/LICENSE-2.0
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//! Assignment instructions interface.
15//!
16//! It provides functions for assigning fixed and secret values into the
17//! circuit.
18//!
19//! This trait is parametrized by the resulting `Assigned` type (a generic of
20//! this trait that implements [InnerValue]). The assignment functions take an
21//! `Assigned::Element` as input and return an `Assigned` value.
22
23use midnight_proofs::{
24    circuit::{Layouter, Value},
25    plonk::Error,
26};
27
28use crate::{types::InnerValue, CircuitField};
29
30/// The set of circuit instructions for assignment operations.
31pub trait AssignmentInstructions<F, Assigned>
32where
33    F: CircuitField,
34    Assigned: InnerValue,
35{
36    /// Assigns an element as a private input to the circuit.
37    ///
38    /// In the following example, `chip` implements [AssignmentInstructions] for
39    /// [AssignedNative](crate::types::AssignedNative).
40    ///
41    /// ```
42    /// # midnight_circuits::run_test_native_gadget!(chip, layouter, {
43    /// // we load a secret variable into the circuit, only the prover may know its value
44    /// let x: AssignedNative<F> = chip.assign(&mut layouter, Value::known(F::ZERO))?;
45    /// # });
46    /// ```
47    ///
48    /// But `chip` can also implement [AssignmentInstructions] for
49    /// [AssignedBit](crate::types::AssignedBit) or
50    /// [AssignedByte](crate::types::AssignedByte) and other types.
51    ///
52    /// ```
53    /// # midnight_circuits::run_test_native_gadget!(chip, layouter, {
54    /// let bit: AssignedBit<F> = chip.assign(&mut layouter, Value::known(true))?;
55    ///
56    /// let byte: AssignedByte<F> = chip.assign(&mut layouter, Value::known(42u8))?;
57    /// # });
58    /// ```
59    fn assign(
60        &self,
61        layouter: &mut impl Layouter<F>,
62        value: Value<Assigned::Element>,
63    ) -> Result<Assigned, Error>;
64
65    /// Assigns a fixed (constant) element.
66    ///
67    /// ```
68    /// # midnight_circuits::run_test_native_gadget!(chip, layouter, {
69    /// // we load a constant into the circuit, everyone knows the value of `k`
70    /// let x: AssignedNative<F> = chip.assign_fixed(&mut layouter, F::ONE)?;
71    ///
72    /// // we can also assign fixed bits or bytes if the chip supports these types
73    /// let bit: AssignedBit<F> = chip.assign_fixed(&mut layouter, false)?;
74    /// let byte: AssignedByte<F> = chip.assign_fixed(&mut layouter, 255u8)?;
75    /// # });
76    /// ```
77    fn assign_fixed(
78        &self,
79        layouter: &mut impl Layouter<F>,
80        constant: Assigned::Element,
81    ) -> Result<Assigned, Error>;
82
83    /// Assigns several elements as private inputs to the circuit.
84    ///
85    /// This is potentially more efficient than calling
86    /// [assign](AssignmentInstructions::assign) multiple times.
87    fn assign_many(
88        &self,
89        layouter: &mut impl Layouter<F>,
90        values: &[Value<Assigned::Element>],
91    ) -> Result<Vec<Assigned>, Error> {
92        values
93            .iter()
94            .map(|v| self.assign(layouter, v.clone()))
95            .collect::<Result<Vec<Assigned>, Error>>()
96    }
97
98    /// Assigns several elements fixed values to the circuit.
99    ///
100    /// This is potentially more efficient than calling
101    /// [assign_fixed](AssignmentInstructions::assign_fixed) multiple times.
102    fn assign_many_fixed(
103        &self,
104        layouter: &mut impl Layouter<F>,
105        values: &[Assigned::Element],
106    ) -> Result<Vec<Assigned>, Error> {
107        values
108            .iter()
109            .map(|v| self.assign_fixed(layouter, v.clone()))
110            .collect::<Result<Vec<Assigned>, Error>>()
111    }
112}