Skip to content

Commit

Permalink
merged with upstream to fix checks
Browse files Browse the repository at this point in the history
  • Loading branch information
kitounliu committed Feb 2, 2024
2 parents b717aa7 + 1fe10a7 commit 7631e5b
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 79 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ members = [
"halo2wrong",
"ecc",
"ecdsa",
"transcript"
"transcript",
]
resolver = "2"
2 changes: 1 addition & 1 deletion halo2wrong/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
num-bigint = { version = "0.4", features = ["rand"] }
num-integer = "0.1"
num-traits = "0.2"
halo2 = { package = "halo2_proofs", git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2023_04_20" }
halo2 = { package = "halo2_proofs", git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v0.3.0" }

[dev-dependencies]
rand = "0.8"
Expand Down
2 changes: 1 addition & 1 deletion halo2wrong/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn mock_prover_verify<F: FromUniformBytes<64> + Ord, C: Circuit<F>>(
let prover = MockProver::run(dimension.k(), circuit, instance)
.unwrap_or_else(|err| panic!("{:#?}", err));
assert_eq!(
prover.verify_at_rows_par(dimension.advice_range(), dimension.advice_range()),
prover.verify_at_rows(dimension.advice_range(), dimension.advice_range()),
Ok(())
)
}
Expand Down
50 changes: 46 additions & 4 deletions integer/src/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use crate::instructions::{IntegerInstructions, Range};
use crate::rns::{Common, Integer, Rns};
use halo2::halo2curves::ff::PrimeField;
use halo2::plonk::Error;
use maingate::{halo2, AssignedCondition, AssignedValue, MainGateInstructions, RegionCtx};
use maingate::halo2::circuit::Value;
use maingate::{
halo2, AssignedCondition, AssignedValue, CombinationOptionCommon, MainGateInstructions,
RangeInstructions, RegionCtx, Term,
};
use maingate::{MainGate, MainGateConfig};
use maingate::{RangeChip, RangeConfig};

Expand Down Expand Up @@ -516,7 +520,45 @@ impl<W: PrimeField, N: PrimeField, const NUMBER_OF_LIMBS: usize, const BIT_LEN_L
a: &AssignedInteger<W, N, NUMBER_OF_LIMBS, BIT_LEN_LIMB>,
) -> Result<AssignedCondition<N>, Error> {
self.assert_in_field(ctx, a)?;
self.main_gate().sign(ctx, a.limb(0))

// Assignes new value equals to `1` if least significant bit of `a` is `1` or assigns
// `0` if lsb of `a` is `0`.
let w: Value<(N, N)> = a.limb(0).value().map(|value| {
use maingate::{big_to_fe, fe_to_big};
use num_bigint::BigUint;
use num_traits::{One, Zero};
let value = &fe_to_big(*value);
let half = big_to_fe(value / 2usize);
let sign = ((value & BigUint::one() != BigUint::zero()) as u64).into();
(sign, half)
});

let sign = self.main_gate.assign_bit(ctx, w.map(|w| w.0))?;

let half_a = self
.main_gate
.apply(
ctx,
[
Term::Unassigned(w.map(|w| w.1), N::from(2)),
Term::Assigned(&sign, N::ONE),
Term::Assigned(a.limb(0), -N::ONE),
],
N::ZERO,
CombinationOptionCommon::OneLinerAdd.into(),
)?
.swap_remove(0);

// Enforce half_a in [0, (LIMB_MAX_VAL / 2) )
let assigned = self.range_chip.decompose(
ctx,
half_a.value_field().evaluate(),
Self::sublimb_bit_len(),
BIT_LEN_LIMB - 1,
)?;
self.main_gate.assert_equal(ctx, &assigned.0, &half_a)?;

Ok(sign)
}
}

Expand Down Expand Up @@ -600,12 +642,12 @@ mod tests {
pub(crate) fn rand_in_remainder_range(
&self,
) -> Integer<W, N, NUMBER_OF_LIMBS, BIT_LEN_LIMB> {
let el = OsRng.gen_biguint(self.rns.max_remainder.bits() as u64);
let el = OsRng.gen_biguint(self.rns.max_remainder.bits());
Integer::from_big(el, Rc::clone(&self.rns))
}

pub(crate) fn rand_in_operand_range(&self) -> Integer<W, N, NUMBER_OF_LIMBS, BIT_LEN_LIMB> {
let el = OsRng.gen_biguint(self.rns.max_operand.bits() as u64);
let el = OsRng.gen_biguint(self.rns.max_operand.bits());
Integer::from_big(el, Rc::clone(&self.rns))
}

Expand Down
9 changes: 6 additions & 3 deletions integer/src/rns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<W: PrimeField, N: PrimeField, const NUMBER_OF_LIMBS: usize, const BIT_LEN_L
/// when values when working with `big_uint`.
fn calculate_base_aux() -> [big_uint; NUMBER_OF_LIMBS] {
let two = N::from(2);
let r = &fe_to_big(two.pow(&[BIT_LEN_LIMB as u64, 0, 0, 0]));
let r = &fe_to_big(two.pow([BIT_LEN_LIMB as u64]));
let wrong_modulus = modulus::<W>();
let wrong_modulus: Vec<N> = decompose_big(wrong_modulus, NUMBER_OF_LIMBS, BIT_LEN_LIMB);

Expand Down Expand Up @@ -536,14 +536,14 @@ impl<W: PrimeField, N: PrimeField, const NUMBER_OF_LIMBS: usize, const BIT_LEN_L

// Right shifts field element by `u * BIT_LEN_LIMB` bits
let right_shifters = (0..NUMBER_OF_LIMBS)
.map(|i| two_inv.pow(&[(i * BIT_LEN_LIMB) as u64, 0, 0, 0]))
.map(|i| two_inv.pow([(i * BIT_LEN_LIMB) as u64]))
.collect::<Vec<N>>()
.try_into()
.unwrap();

// Left shifts field element by `u * BIT_LEN_LIMB` bits
let left_shifters = (0..NUMBER_OF_LIMBS)
.map(|i| two.pow(&[(i * BIT_LEN_LIMB) as u64, 0, 0, 0]))
.map(|i| two.pow([(i * BIT_LEN_LIMB) as u64]))
.collect::<Vec<N>>()
.try_into()
.unwrap();
Expand Down Expand Up @@ -618,12 +618,15 @@ impl<W: PrimeField, N: PrimeField, const NUMBER_OF_LIMBS: usize, const BIT_LEN_L
self.max_most_significant_operand_limb.bits() as usize % self.bit_len_lookup;
let max_most_significant_reduced_limb_size =
self.max_most_significant_reduced_limb.bits() as usize % self.bit_len_lookup;
// For sign function
let sign_aux = self.bit_len_lookup - 1;
vec![
self.mul_v_bit_len % self.bit_len_lookup,
self.red_v_bit_len % self.bit_len_lookup,
max_most_significant_mul_quotient_limb_size,
max_most_significant_operand_limb_size,
max_most_significant_reduced_limb_size,
sign_aux,
]
}
}
Expand Down
81 changes: 30 additions & 51 deletions maingate/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
};
use halo2wrong::{
curves::ff::PrimeField,
utils::{big_to_fe, decompose, fe_to_big, power_of_two},
utils::{decompose, power_of_two},
RegionCtx,
};
use std::iter;
Expand Down Expand Up @@ -330,33 +330,36 @@ pub trait MainGateInstructions<F: PrimeField, const WIDTH: usize>: Chip<F> {
.swap_remove(2))
}

/// Assigns new value equal to `1` if `c1 ^ c0 = 1`,
/// equal to `0` if `c1 ^ c0 = 0`
// `new_assigned_value + 2 * c1 * c2 - c1 - c2 = 0`.
/// Returns c0 ^ c1.
/// Enforcing `result + 2 * c1 * c2 - c1 - c2 = 0`.
fn xor(
&self,
ctx: &mut RegionCtx<'_, F>,
c1: &AssignedCondition<F>,
c2: &AssignedCondition<F>,
) -> Result<AssignedCondition<F>, Error> {
// Find the new witness
let c = c1
let result = c1
.value()
.zip(c2.value())
.map(|(c1, c2)| *c1 + *c2 - (F::ONE + F::ONE) * *c1 * *c2);

Ok(self
// The original constraint: `result + 2 * c1 * c2 - c1 - c2 = 0`.
// requires scaling the multiplication by 2, but in this implementation
// it is easier to scale other terms by 1/2.
let result = self
.apply(
ctx,
[
Term::assigned_to_sub(c1),
Term::assigned_to_sub(c2),
Term::unassigned_to_add(c),
Term::Assigned(c1, -F::TWO_INV),
Term::Assigned(c2, -F::TWO_INV),
Term::Unassigned(result, F::TWO_INV),
],
F::ZERO,
CombinationOptionCommon::OneLinerMul.into(),
)?
.swap_remove(2))
.swap_remove(2);
Ok(result)
}

/// Assigns new value that is logic inverse of the given assigned value.
Expand Down Expand Up @@ -885,14 +888,22 @@ pub trait MainGateInstructions<F: PrimeField, const WIDTH: usize>: Chip<F> {
ctx: &mut RegionCtx<'_, F>,
a: &AssignedCondition<F>,
b: &AssignedCondition<F>,
) -> Result<(), Error> {
self.apply(
ctx,
[Term::assigned_to_mul(a), Term::assigned_to_mul(b)],
F::ZERO,
CombinationOptionCommon::OneLinerMul.into(),
)?;
Ok(())
) -> Result<AssignedCondition<F>, Error> {
// result + ab - 1 =0
let result = a.value().zip(b.value()).map(|(a, b)| F::ONE - *a * b);
let result = self
.apply(
ctx,
[
Term::assigned_to_mul(a),
Term::assigned_to_mul(b),
Term::unassigned_to_add(result),
],
-F::ONE,
CombinationOptionCommon::OneLinerMul.into(),
)?
.swap_remove(2);
Ok(result)
}

/// Assigns a new witness `r` as:
Expand Down Expand Up @@ -962,38 +973,6 @@ pub trait MainGateInstructions<F: PrimeField, const WIDTH: usize>: Chip<F> {
cond: &AssignedCondition<F>,
) -> Result<AssignedValue<F>, Error>;

/// Assignes new value equals to `1` if first bit of `a` is `1` or assigns
/// `0` if first bit of `a` is `0`
fn sign(
&self,
ctx: &mut RegionCtx<'_, F>,
a: &AssignedValue<F>,
) -> Result<AssignedCondition<F>, Error> {
let w: Value<(F, F)> = a.value().map(|value| {
use num_bigint::BigUint;
use num_traits::{One, Zero};
let value = &fe_to_big(*value);
let half = big_to_fe(value / 2usize);
let sign = ((value & BigUint::one() != BigUint::zero()) as u64).into();
(sign, half)
});

let sign = self.assign_bit(ctx, w.map(|w| w.0))?;

self.apply(
ctx,
[
Term::Unassigned(w.map(|w| w.1), F::from(2)),
Term::Assigned(&sign, F::ONE),
Term::Assigned(a, -F::ONE),
],
F::ZERO,
CombinationOptionCommon::OneLinerAdd.into(),
)?;

Ok(sign)
}

/// Assigns array values of bit values which is equal to decomposition of
/// given assigned value
fn to_bits(
Expand Down Expand Up @@ -1021,7 +1000,7 @@ pub trait MainGateInstructions<F: PrimeField, const WIDTH: usize>: Chip<F> {

let terms = bits
.iter()
.zip(bases.into_iter())
.zip(bases)
.map(|(bit, base)| Term::Assigned(bit, base))
.collect::<Vec<_>>();
let result = self.compose(ctx, &terms, F::ZERO)?;
Expand Down
45 changes: 32 additions & 13 deletions maingate/src/main_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1524,11 +1524,11 @@ mod tests {
}

#[derive(Default)]
struct TestCircuitSign<F: PrimeField> {
struct TestCircuitLogicOps<F: PrimeField> {
_marker: PhantomData<F>,
}

impl<F: PrimeField> Circuit<F> for TestCircuitSign<F> {
impl<F: PrimeField> Circuit<F> for TestCircuitLogicOps<F> {
type Config = TestCircuitConfig;
type FloorPlanner = SimpleFloorPlanner;
#[cfg(feature = "circuit-params")]
Expand Down Expand Up @@ -1559,15 +1559,32 @@ mod tests {
let offset = 0;
let ctx = &mut RegionCtx::new(region, offset);

let a = F::from(20u64);
let assigned = main_gate.assign_value(ctx, Value::known(a))?;
let assigned_sign = main_gate.sign(ctx, &assigned)?;
main_gate.assert_zero(ctx, &assigned_sign)?;
let zero = &main_gate.assign_constant(ctx, F::ZERO)?;
let one = &main_gate.assign_constant(ctx, F::ONE)?;

let xor_io = [
[zero, zero, zero],
[zero, one, one],
[one, zero, one],
[one, one, zero],
];

let nand_io = [
[zero, zero, one],
[zero, one, one],
[one, zero, one],
[one, one, zero],
];

for io in xor_io.iter() {
let out_xor = main_gate.xor(ctx, io[0], io[1])?;
main_gate.assert_equal(ctx, &out_xor, io[2])?;
}

let a = F::from(21u64);
let assigned = main_gate.assign_value(ctx, Value::known(a))?;
let assigned_sign = main_gate.sign(ctx, &assigned)?;
main_gate.assert_one(ctx, &assigned_sign)?;
for io in nand_io.iter() {
let out_nand = main_gate.nand(ctx, io[0], io[1])?;
main_gate.assert_equal(ctx, &out_nand, io[2])?;
}

Ok(())
},
Expand All @@ -1578,16 +1595,18 @@ mod tests {
}

#[test]
fn test_main_gate_sign() {
const K: u32 = 10;
let circuit = TestCircuitSign::<Fp> {
fn test_logic_ops() {
const K: u32 = 8;

let circuit = TestCircuitLogicOps::<Fp> {
_marker: PhantomData::<Fp>,
};
let public_inputs = vec![vec![]];
let prover = match MockProver::run(K, &circuit, public_inputs) {
Ok(prover) => prover,
Err(e) => panic!("{:#?}", e),
};

assert_eq!(prover.verify(), Ok(()));
}
}
4 changes: 2 additions & 2 deletions maingate/src/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl<F: PrimeField> RangeChip<F> {
base_len += 1;
}
let bases = (0..base_len)
.map(|i| F::from(2).pow(&[(bit_len * i) as u64, 0, 0, 0]))
.map(|i| F::from(2).pow([(bit_len * i) as u64]))
.collect();
Some((bit_len, bases))
}
Expand Down Expand Up @@ -526,7 +526,7 @@ mod tests {
let mut inputs: Vec<_> = (2..20)
.map(|number_of_limbs| {
let bit_len = LIMB_BIT_LEN * number_of_limbs + OVERFLOW_BIT_LEN;
let value = Fp::from(2).pow(&[bit_len as u64, 0, 0, 0]) - Fp::one();
let value = Fp::from(2).pow([bit_len as u64]) - Fp::one();
Input {
value: Value::known(value),
limb_bit_len: LIMB_BIT_LEN,
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.63.0
1.74.0
2 changes: 1 addition & 1 deletion transcript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"

[dependencies]
ecc = { path = "../ecc", default-features = false }
poseidon = { git = "https://github.com/privacy-scaling-explorations/poseidon.git", tag = "v2023_04_20" }
poseidon = { git = "https://github.com/privacy-scaling-explorations/poseidon.git", tag = "v2024_01_31" }
subtle = { version = "2.3", default-features = false }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion transcript/src/transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ mod tests {
ctx,
&self.spec,
ecc_chip.clone(),
LimbRepresentation::default(),
LimbRepresentation,
)?;

for e in self.inputs.as_ref().transpose_vec(self.n) {
Expand Down

0 comments on commit 7631e5b

Please sign in to comment.