Skip to main content

midnight_circuits/instructions/
vector.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//! Vector manipulation instructions interface.
15//!
16//! The trait is parameterized by the type `T` of elements contained in the
17//! vector, as well as 2 constants: its maximum size `M` and its chunk alignment
18//! value `A`.
19
20use midnight_proofs::{
21    circuit::{Layouter, Value},
22    plonk::Error,
23};
24
25use crate::{
26    field::AssignedNative,
27    types::AssignedBit,
28    vec::{AssignedVector, Vectorizable},
29    CircuitField,
30};
31
32/// Indicator of the number of filler elements at the beginning and end of an
33/// assigned vector's buffer, as returned by `get_limits`.
34pub type VectorBounds<F> = (AssignedNative<F>, AssignedNative<F>);
35
36/// Instructions for Vector manipulation..
37pub trait VectorInstructions<F, T, const M: usize, const A: usize>
38where
39    F: CircuitField,
40    T: Vectorizable,
41    T::Element: Copy,
42{
43    /// Changes the size of an AssignedVector from M to L.
44    ///
45    /// # Panics
46    ///
47    /// If `L <= M` or `A` does not divide `L`.
48    fn resize<const L: usize>(
49        &self,
50        layouter: &mut impl Layouter<F>,
51        input: AssignedVector<F, T, M, A>,
52    ) -> Result<AssignedVector<F, T, L, A>, Error>;
53
54    /// Assigns vector with a chosen filler value.
55    ///
56    /// # Panics
57    ///
58    /// If |value| > M.
59    fn assign_with_filler(
60        &self,
61        layouter: &mut impl Layouter<F>,
62        value: Value<Vec<T::Element>>,
63        filler: Option<T::Element>,
64    ) -> Result<AssignedVector<F, T, M, A>, Error>;
65
66    /// Trims `n_elems` elements from the beginning of the vector.
67    /// The trimmed elements will not be changed by filler elements,
68    /// they will remain in the buffer but not as part of the effective payload.
69    ///
70    /// # Unsatisfiable Circuit
71    ///
72    /// If the vector length < `n_elems`.
73    fn trim_beginning(
74        &self,
75        layouter: &mut impl Layouter<F>,
76        input: &AssignedVector<F, T, M, A>,
77        n_elems: usize,
78    ) -> Result<AssignedVector<F, T, M, A>, Error>;
79
80    /// Returns a vector of AssignedBits signaling the cells that represent
81    /// padding with a 1, and the ones that represent payload data with a 0.
82    /// Also returns the (start, end) limits of the data in the buffer, since
83    /// they are computed internally.
84    #[allow(clippy::type_complexity)]
85    fn padding_flag(
86        &self,
87        layouter: &mut impl Layouter<F>,
88        input: &AssignedVector<F, T, M, A>,
89    ) -> Result<(Box<[AssignedBit<F>; M]>, VectorBounds<F>), Error>;
90
91    /// Returns the first and last positions of data in the buffer.
92    fn get_limits(
93        &self,
94        layouter: &mut impl Layouter<F>,
95        input: &AssignedVector<F, T, M, A>,
96    ) -> Result<VectorBounds<F>, Error>;
97}