circuit: Remove `Copy` impl from `CellValue`

We will be replacing it with `halo2::circuit::AssignedCell`, which does
not impl `Copy`.
This commit is contained in:
Jack Grigg 2021-12-01 12:51:33 +00:00
parent 55567f31ed
commit 50b4600a1a
18 changed files with 105 additions and 94 deletions

View File

@ -405,7 +405,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
leaf_pos: self.pos,
path,
};
let leaf = *cm_old.extract_p().inner();
let leaf = cm_old.extract_p().inner().clone();
merkle_inputs.calculate_root(layouter.namespace(|| "MerkleCRH"), leaf)?
};
@ -454,7 +454,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
let (commitment, _) = {
let value_commit_v = ValueCommitV::get();
let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v);
value_commit_v.mul(layouter.namespace(|| "[v_net] ValueCommitV"), v_net)?
value_commit_v.mul(layouter.namespace(|| "[v_net] ValueCommitV"), v_net.clone())?
};
// blind = [rcv] ValueCommitR
@ -481,7 +481,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
let nf_old = {
// hash_old = poseidon_hash(nk, rho_old)
let hash_old = {
let poseidon_message = [nk, rho_old];
let poseidon_message = [nk.clone(), rho_old.clone()];
let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, _, 3, 2>::init(
config.poseidon_chip(),
layouter.namespace(|| "Poseidon init"),
@ -581,7 +581,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
config.sinsemilla_chip_1(),
ecc_chip.clone(),
layouter.namespace(|| "CommitIvk"),
*ak.extract_p().inner(),
ak.extract_p().inner().clone(),
nk,
rivk,
)?
@ -619,7 +619,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
config.ecc_chip(),
g_d_old.inner(),
pk_d_old.inner(),
v_old,
v_old.clone(),
rho_old,
psi_old,
rcm_old,
@ -675,8 +675,8 @@ impl plonk::Circuit<pallas::Base> for Circuit {
config.ecc_chip(),
g_d_new.inner(),
pk_d_new.inner(),
v_new,
*nf_old.inner(),
v_new.clone(),
nf_old.inner().clone(),
psi_new,
rcm_new,
)?;
@ -694,7 +694,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|mut region| {
copy(&mut region, || "v_old", config.advices[0], 0, &v_old)?;
copy(&mut region, || "v_new", config.advices[1], 0, &v_new)?;
let (magnitude, sign) = v_net;
let (magnitude, sign) = v_net.clone();
copy(
&mut region,
|| "v_net magnitude",

View File

@ -26,7 +26,7 @@ pub(super) mod witness_point;
/// A curve point represented in affine (x, y) coordinates, or the
/// identity represented as (0, 0).
/// Each coordinate is assigned to a cell.
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct EccPoint {
/// x-coordinate
x: CellValue<pallas::Base>,
@ -62,12 +62,12 @@ impl EccPoint {
/// The cell containing the affine short-Weierstrass x-coordinate,
/// or 0 for the zero point.
pub fn x(&self) -> CellValue<pallas::Base> {
self.x
self.x.clone()
}
/// The cell containing the affine short-Weierstrass y-coordinate,
/// or 0 for the zero point.
pub fn y(&self) -> CellValue<pallas::Base> {
self.y
self.y.clone()
}
#[cfg(test)]
@ -78,7 +78,7 @@ impl EccPoint {
/// A non-identity point represented in affine (x, y) coordinates.
/// Each coordinate is assigned to a cell.
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct NonIdentityEccPoint {
/// x-coordinate
x: CellValue<pallas::Base>,
@ -110,11 +110,11 @@ impl NonIdentityEccPoint {
}
/// The cell containing the affine short-Weierstrass x-coordinate.
pub fn x(&self) -> CellValue<pallas::Base> {
self.x
self.x.clone()
}
/// The cell containing the affine short-Weierstrass y-coordinate.
pub fn y(&self) -> CellValue<pallas::Base> {
self.y
self.y.clone()
}
}
@ -298,7 +298,7 @@ struct EccBaseFieldElemFixed {
impl EccBaseFieldElemFixed {
fn base_field_elem(&self) -> CellValue<pallas::Base> {
self.base_field_elem
self.base_field_elem.clone()
}
}
@ -396,7 +396,7 @@ impl EccInstructions<pallas::Affine> for EccChip {
let config = self.config().mul;
config.assign(
layouter.namespace(|| "variable-base scalar mul"),
*scalar,
scalar.clone(),
base,
)
}

View File

@ -175,7 +175,7 @@ impl Config {
let offset = 0;
// Case `base` into an `EccPoint` for later use.
let base_point: EccPoint = (*base).into();
let base_point: EccPoint = base.clone().into();
// Decompose `k = alpha + t_q` bitwise (big-endian bit order).
let bits = decompose_for_scalar_mul(alpha.value());
@ -211,7 +211,7 @@ impl Config {
offset,
base,
bits_incomplete_hi,
(X(acc.x), Y(acc.y), z_init),
(X(acc.x), Y(acc.y), z_init.clone()),
)?;
// Double-and-add (incomplete addition) for the `lo` half of the scalar decomposition
@ -221,7 +221,7 @@ impl Config {
offset,
base,
bits_incomplete_lo,
(x_a, y_a, *z),
(x_a, y_a, z.clone()),
)?;
// Move from incomplete addition to complete addition.
@ -245,7 +245,7 @@ impl Config {
&base_point,
x_a,
y_a,
*z,
z.clone(),
)?
};
@ -253,8 +253,8 @@ impl Config {
let offset = offset + COMPLETE_RANGE.len() * 2;
// Process the least significant bit
let z_1 = zs_complete.last().unwrap();
let (result, z_0) = self.process_lsb(&mut region, offset, base, acc, *z_1, lsb)?;
let z_1 = zs_complete.last().unwrap().clone();
let (result, z_0) = self.process_lsb(&mut region, offset, base, acc, z_1, lsb)?;
#[cfg(test)]
// Check that the correct multiple is obtained.
@ -292,8 +292,11 @@ impl Config {
},
)?;
self.overflow_config
.overflow_check(layouter.namespace(|| "overflow check"), alpha, &zs)?;
self.overflow_config.overflow_check(
layouter.namespace(|| "overflow check"),
alpha.clone(),
&zs,
)?;
Ok((result, alpha))
}
@ -416,7 +419,7 @@ impl<F: FieldExt> Deref for X<F> {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
// `y`-coordinate of the accumulator.
struct Y<F: FieldExt>(CellValue<F>);
impl<F: FieldExt> Deref for Y<F> {
@ -427,7 +430,7 @@ impl<F: FieldExt> Deref for Y<F> {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
// Cumulative sum `z` used to decompose the scalar.
struct Z<F: FieldExt>(CellValue<F>);
impl<F: FieldExt> Deref for Z<F> {

View File

@ -106,7 +106,7 @@ impl Config {
}
// Use x_a, y_a output from incomplete addition
let mut acc = EccPoint { x: *x_a, y: *y_a };
let mut acc = EccPoint { x: x_a.0, y: y_a.0 };
// Copy running sum `z` from incomplete addition
let mut z = {
@ -148,7 +148,7 @@ impl Config {
)?;
Z(CellValue::new(z_cell, z_val))
};
zs.push(z);
zs.push(z.clone());
// Assign `y_p` for complete addition.
let y_p = {
@ -176,7 +176,10 @@ impl Config {
};
// U = P if the bit is set; U = -P is the bit is not set.
let U = EccPoint { x: base.x, y: y_p };
let U = EccPoint {
x: base.x.clone(),
y: y_p,
};
// Acc + U
let tmp_acc = self

View File

@ -251,7 +251,7 @@ impl<const NUM_BITS: usize> Config<NUM_BITS> {
|| z_val.ok_or(Error::Synthesis),
)?;
z = CellValue::new(z_cell, z_val);
zs.push(Z(z));
zs.push(Z(z.clone()));
// Assign `x_p`, `y_p`
region.assign_advice(

View File

@ -107,7 +107,7 @@ impl Config {
// In the overflow check gate, we check that s is properly derived
// from alpha and k_254.
let s = {
let k_254 = *zs[254];
let k_254 = zs[254].clone();
let s_val = alpha
.value()
.zip(k_254.value())
@ -130,7 +130,7 @@ impl Config {
// Subtract the first 130 low bits of s = alpha + k_254 ⋅ 2^130
// using thirteen 10-bit lookups, s_{0..=129}
let s_minus_lo_130 =
self.s_minus_lo_130(layouter.namespace(|| "decompose s_{0..=129}"), s)?;
self.s_minus_lo_130(layouter.namespace(|| "decompose s_{0..=129}"), s.clone())?;
layouter.assign_region(
|| "overflow check",
@ -223,6 +223,6 @@ impl Config {
false,
)?;
// (s - (2^0 s_0 + 2^1 s_1 + ... + 2^129 s_129)) / 2^130
Ok(zs[zs.len() - 1])
Ok(zs[zs.len() - 1].clone())
}
}

View File

@ -173,13 +173,13 @@ impl Config {
let running_sum = self.super_config.running_sum_config.copy_decompose(
&mut region,
offset,
scalar,
scalar.clone(),
true,
constants::L_ORCHARD_BASE,
constants::NUM_WINDOWS,
)?;
EccBaseFieldElemFixed {
base_field_elem: running_sum[0],
base_field_elem: running_sum[0].clone(),
running_sum: (*running_sum).as_slice().try_into().unwrap(),
}
};
@ -203,8 +203,8 @@ impl Config {
|| "Base-field elem fixed-base mul (complete addition)",
|mut region| {
self.super_config.add_config.assign_region(
&mul_b.into(),
&acc.into(),
&mul_b.clone().into(),
&acc.clone().into(),
0,
&mut region,
)
@ -249,9 +249,9 @@ impl Config {
// => z_13_alpha_0_prime = 0
//
let (alpha, running_sum) = (scalar.base_field_elem, &scalar.running_sum);
let z_43_alpha = running_sum[43];
let z_44_alpha = running_sum[44];
let z_84_alpha = running_sum[84];
let z_43_alpha = running_sum[43].clone();
let z_44_alpha = running_sum[44].clone();
let z_84_alpha = running_sum[84].clone();
// α_0 = α - z_84_alpha * 2^252
let alpha_0 = alpha
@ -275,9 +275,9 @@ impl Config {
13,
false,
)?;
let alpha_0_prime = zs[0];
let alpha_0_prime = zs[0].clone();
(alpha_0_prime, zs[13])
(alpha_0_prime, zs[13].clone())
};
layouter.assign_region(

View File

@ -149,8 +149,8 @@ impl Config {
|| "Full-width fixed-base mul (last window, complete addition)",
|mut region| {
self.super_config.add_config.assign_region(
&mul_b.into(),
&acc.into(),
&mul_b.clone().into(),
&acc.clone().into(),
0,
&mut region,
)

View File

@ -82,7 +82,7 @@ impl Config {
let running_sum = self.super_config.running_sum_config.copy_decompose(
region,
offset,
magnitude,
magnitude.clone(),
true,
L_VALUE,
NUM_WINDOWS_SHORT,
@ -107,7 +107,7 @@ impl Config {
let offset = 0;
// Decompose the scalar
let scalar = self.decompose(&mut region, offset, magnitude_sign)?;
let scalar = self.decompose(&mut region, offset, magnitude_sign.clone())?;
let (acc, mul_b) = self.super_config.assign_region_inner::<NUM_WINDOWS_SHORT>(
&mut region,
@ -128,8 +128,8 @@ impl Config {
let offset = 0;
// Add to the cumulative sum to get `[magnitude]B`.
let magnitude_mul = self.super_config.add_config.assign_region(
&mul_b.into(),
&acc.into(),
&mul_b.clone().into(),
&acc.clone().into(),
offset,
&mut region,
)?;
@ -149,7 +149,7 @@ impl Config {
// Copy last window to `u` column.
// (Although the last window is not a `u` value; we are copying it into the `u`
// column because there is an available cell there.)
let z_21 = scalar.running_sum[21];
let z_21 = scalar.running_sum[21].clone();
copy(
&mut region,
|| "last_window",

View File

@ -32,7 +32,7 @@ pub trait SinsemillaInstructions<C: CurveAffine, const K: usize, const MAX_WORDS
///
/// For example, in the case `K = 10`, `NUM_BITS = 255`, we can fit
/// up to `N = 25` words in a single base field element.
type MessagePiece: Copy + Clone + Debug;
type MessagePiece: Clone + Debug;
/// A cumulative sum `z` is used to decompose a Sinsemilla message. It
/// produces intermediate values for each word in the message, such
@ -170,7 +170,7 @@ where
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
{
fn inner(&self) -> SinsemillaChip::MessagePiece {
self.inner
self.inner.clone()
}
}

View File

@ -337,8 +337,8 @@ impl CommitIvkConfig {
domain.short_commit(layouter.namespace(|| "Hash ak||nk"), message, rivk)?
};
let z13_a = zs[0][13];
let z13_c = zs[2][13];
let z13_a = zs[0][13].clone();
let z13_c = zs[2][13].clone();
let (a_prime, z13_a_prime) = self.ak_canonicity(
layouter.namespace(|| "ak canonicity"),
@ -347,7 +347,7 @@ impl CommitIvkConfig {
let (b2_c_prime, z14_b2_c_prime) = self.nk_canonicity(
layouter.namespace(|| "nk canonicity"),
b_2,
b_2.clone(),
c.inner().cell_value(),
)?;
@ -406,10 +406,10 @@ impl CommitIvkConfig {
13,
false,
)?;
let a_prime = zs[0];
let a_prime = zs[0].clone();
assert_eq!(zs.len(), 14); // [z_0, z_1, ..., z13_a]
Ok((a_prime, zs[13]))
Ok((a_prime, zs[13].clone()))
}
#[allow(clippy::type_complexity)]
@ -443,10 +443,10 @@ impl CommitIvkConfig {
14,
false,
)?;
let b2_c_prime = zs[0];
let b2_c_prime = zs[0].clone();
assert_eq!(zs.len(), 15); // [z_0, z_1, ..., z14]
Ok((b2_c_prime, zs[14]))
Ok((b2_c_prime, zs[14].clone()))
}
// Assign cells for the canonicity gate.

View File

@ -257,10 +257,10 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
let (point, zs) = self.hash_to_point(
layouter.namespace(|| format!("hash at l = {}", l)),
Q,
vec![a, b, c].into(),
vec![a.clone(), b.clone(), c.clone()].into(),
)?;
let z1_a = zs[0][1];
let z1_b = zs[1][1];
let z1_a = zs[0][1].clone();
let z1_b = zs[1][1].clone();
// Check that the pieces have been decomposed properly.
/*

View File

@ -32,7 +32,7 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize, const MAX_WORDS: usize> std::
///
/// The piece must fit within a base field element, which means its length
/// cannot exceed the base field's `NUM_BITS`.
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct MessagePiece<F: FieldExt, const K: usize> {
cell_value: CellValue<F>,
/// The number of K-bit words in this message piece.
@ -62,6 +62,6 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> MessagePiece<F, K> {
}
pub fn cell_value(&self) -> CellValue<F> {
self.cell_value
self.cell_value.clone()
}
}

View File

@ -738,13 +738,13 @@ impl NoteCommitConfig {
)?
};
let z13_a = zs[0][13];
let z13_c = zs[2][13];
let z1_d = zs[3][1];
let z13_f = zs[5][13];
let z1_g = zs[6][1];
let g_2 = z1_g;
let z13_g = zs[6][13];
let z13_a = zs[0][13].clone();
let z13_c = zs[2][13].clone();
let z1_d = zs[3][1].clone();
let z13_f = zs[5][13].clone();
let z1_g = zs[6][1].clone();
let g_2 = z1_g.clone();
let z13_g = zs[6][13].clone();
let (a_prime, z13_a_prime) = self.canon_bitshift_130(
layouter.namespace(|| "x(g_d) canonicity"),
@ -753,18 +753,18 @@ impl NoteCommitConfig {
let (b3_c_prime, z14_b3_c_prime) = self.pkd_x_canonicity(
layouter.namespace(|| "x(pk_d) canonicity"),
b_3,
b_3.clone(),
c.inner().cell_value(),
)?;
let (e1_f_prime, z14_e1_f_prime) = self.rho_canonicity(
layouter.namespace(|| "rho canonicity"),
e_1,
e_1.clone(),
f.inner().cell_value(),
)?;
let (g1_g2_prime, z13_g1_g2_prime) =
self.psi_canonicity(layouter.namespace(|| "psi canonicity"), g_1, g_2)?;
self.psi_canonicity(layouter.namespace(|| "psi canonicity"), g_1.clone(), g_2)?;
let gate_cells = GateCells {
a: a.inner().cell_value(),
@ -841,10 +841,10 @@ impl NoteCommitConfig {
13,
false,
)?;
let a_prime = zs[0];
let a_prime = zs[0].clone();
assert_eq!(zs.len(), 14); // [z_0, z_1, ..., z_13]
Ok((a_prime, zs[13]))
Ok((a_prime, zs[13].clone()))
}
// Check canonicity of `x(pk_d)` encoding
@ -880,10 +880,10 @@ impl NoteCommitConfig {
14,
false,
)?;
let b3_c_prime = zs[0];
let b3_c_prime = zs[0].clone();
assert_eq!(zs.len(), 15); // [z_0, z_1, ..., z_13, z_14]
Ok((b3_c_prime, zs[14]))
Ok((b3_c_prime, zs[14].clone()))
}
#[allow(clippy::type_complexity)]
@ -920,10 +920,10 @@ impl NoteCommitConfig {
14,
false,
)?;
let e1_f_prime = zs[0];
let e1_f_prime = zs[0].clone();
assert_eq!(zs.len(), 15); // [z_0, z_1, ..., z_13, z_14]
Ok((e1_f_prime, zs[14]))
Ok((e1_f_prime, zs[14].clone()))
}
// Check canonicity of `psi` encoding
@ -957,10 +957,10 @@ impl NoteCommitConfig {
13,
false,
)?;
let g1_g2_prime = zs[0];
let g1_g2_prime = zs[0].clone();
assert_eq!(zs.len(), 14); // [z_0, z_1, ..., z_13]
Ok((g1_g2_prime, zs[13]))
Ok((g1_g2_prime, zs[13].clone()))
}
// Check canonicity of y-coordinate given its LSB as a value.
@ -1010,13 +1010,15 @@ impl NoteCommitConfig {
25,
true,
)?;
(zs[0], zs[1], zs[13])
(zs[0].clone(), zs[1].clone(), zs[13].clone())
};
// Decompose j_prime = j + 2^130 - t_P using 13 ten-bit lookups.
// We can reuse the canon_bitshift_130 logic here.
let (j_prime, z13_j_prime) =
self.canon_bitshift_130(layouter.namespace(|| "j_prime = j + 2^130 - t_P"), j)?;
let (j_prime, z13_j_prime) = self.canon_bitshift_130(
layouter.namespace(|| "j_prime = j + 2^130 - t_P"),
j.clone(),
)?;
/*

View File

@ -13,14 +13,14 @@ pub(crate) mod decompose_running_sum;
pub(crate) mod lookup_range_check;
/// A variable representing a field element.
#[derive(Copy, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct CellValue<F: FieldExt> {
cell: Cell,
value: Option<F>,
}
/// Trait for a variable in the circuit.
pub trait Var<F: FieldExt>: Copy + Clone + std::fmt::Debug {
pub trait Var<F: FieldExt>: Clone + std::fmt::Debug {
/// Construct a new variable.
fn new(cell: Cell, value: Option<F>) -> Self;

View File

@ -252,8 +252,11 @@ mod tests {
// Load the pair and the swap flag into the circuit.
let a = chip.load_private(layouter.namespace(|| "a"), config.a, self.a)?;
// Return the swapped pair.
let swapped_pair =
chip.swap(layouter.namespace(|| "swap"), (a, self.b), self.swap)?;
let swapped_pair = chip.swap(
layouter.namespace(|| "swap"),
(a.clone(), self.b),
self.swap,
)?;
if let Some(swap) = self.swap {
if swap {

View File

@ -179,7 +179,7 @@ impl<F: FieldExt + PrimeFieldBits, const WINDOW_NUM_BITS: usize>
};
// Initialize empty vector to store running sum values [z_0, ..., z_W].
let mut zs: Vec<CellValue<F>> = vec![z_0];
let mut zs: Vec<CellValue<F>> = vec![z_0.clone()];
let mut z = z_0;
// Assign running sum `z_{i+1}` = (z_i - k_i) / (2^K) for i = 0..=n-1.
@ -205,7 +205,7 @@ impl<F: FieldExt + PrimeFieldBits, const WINDOW_NUM_BITS: usize>
// Update `z`.
z = z_next;
zs.push(z);
zs.push(z.clone());
}
assert_eq!(zs.len(), num_windows + 1);
@ -284,7 +284,7 @@ mod tests {
WORD_NUM_BITS,
NUM_WINDOWS,
)?;
let alpha = zs[0];
let alpha = zs[0].clone();
let offset = offset + NUM_WINDOWS + 1;

View File

@ -223,7 +223,7 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
}
};
let mut zs = vec![element];
let mut zs = vec![element.clone()];
// Assign cumulative sum such that
// z_i = 2^{K}⋅z_{i + 1} + a_i
@ -256,7 +256,7 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
CellValue::new(z_cell, z_val)
};
zs.push(z);
zs.push(z.clone());
}
if strict {
@ -316,7 +316,7 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
CellValue::new(cell, element)
};
self.short_range_check(&mut region, element, num_bits)?;
self.short_range_check(&mut region, element.clone(), num_bits)?;
Ok(element)
},