Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECC chip] Fixed- and variable-base scalar multiplication #111

Merged
merged 40 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0f60a81
ecc::chip.rs: Add EccScalarFixed, EccScalarFixedShort structs
therealyingtong Jun 12, 2021
64a2b02
ecc::chip.rs: Witness scalar for variable-base scalar mul
therealyingtong Jun 12, 2021
cc9dd20
chip::mul.rs: Implement variable-base scalar mul instruction.
therealyingtong Jun 5, 2021
a263774
chip::witness_scalar_fixed.rs: Implement witness_scalar_fixed instruc…
therealyingtong Jun 5, 2021
ae25310
chip::mul_fixed.rs: Implement fixed-base scalar mul instruction.
therealyingtong Jun 5, 2021
a3ca27b
ecc::tests: Add tests for variable- and fixed-base scalar mul.
therealyingtong Jun 14, 2021
5ae9890
mul::overflow.rs: Overflow check in variable-base scalar mul
therealyingtong Jun 13, 2021
747f71c
constants.rs: Add unit tests for T_P, T_Q constants.
therealyingtong Jun 15, 2021
37074c6
mul_fixed::short: Check that last window is either 0 or 1.
therealyingtong Jun 18, 2021
09b4da1
base_field_elem.rs: Support fixed-base mul using base field element.
therealyingtong Jun 18, 2021
b15343f
Add `OrchardFixedBasesFull::{generator, u}` methods
str4d Jun 16, 2021
e726fee
mul_fixed: Avoid computing fixed constants during proving
str4d Jun 16, 2021
69d6629
chip::mul.rs: Enforce LSB if/else condition
therealyingtong Jun 18, 2021
b363492
ecc::chip.rs: Introduce circuit-wide "constants" fixed column
therealyingtong Jun 19, 2021
4d69dec
mul::incomplete.rs: Constrain first and last y_a values.
therealyingtong Jul 2, 2021
e75c176
mul::incomplete.rs: Make offsets more intuitive
therealyingtong Jul 2, 2021
6ffd867
mul::complete.rs: Constrain negation of (x_p, y_p) in double-and-add.
therealyingtong Jul 2, 2021
3f961ab
mul::process_lsb(): Clean up assignments and boolean-constrain LSB.
therealyingtong Jul 2, 2021
33b66ab
tests::print_ecc_chip(): Print ECC chip.
therealyingtong Jul 2, 2021
67caed5
mul::incomplete: Constrain final iteration correctly
str4d Jul 2, 2021
2536555
mul_fixed: Constrain interpolated window mul to be on curve.
therealyingtong Jul 3, 2021
9fd4d7d
Cleanups and clippy fixes.
therealyingtong Jul 3, 2021
d550e15
mul_fixed_*::tests: Constrain zero outputs in mul_fixed tests.
therealyingtong Jul 3, 2021
2d343af
Update mul_fixed_* APIs to take Layouter instead of Region.
therealyingtong Jul 7, 2021
23f2ed5
gadget::utilities.rs: Add bitrange_subset() helper.
therealyingtong Jul 7, 2021
b690940
chip::mul_fixed.rs: Make q_mul_fixed a selector instead of fixed column.
therealyingtong Jul 7, 2021
72e469e
mul_fixed::base_field_elem.rs: Check canonicity of base field element…
therealyingtong Jul 7, 2021
ae72501
mul_fixed::base_field_elem: Add constraint alpha_2 = 0 => alpha_1 = 0.
therealyingtong Jul 7, 2021
f42d48b
mul_fixed::base_field_elem: Fix two_pow_130 expression.
therealyingtong Jul 8, 2021
d0e34cd
mul_fixed::base_field_elem: Eliminate alpha_0 lookup decomposition.
therealyingtong Jul 8, 2021
96863c9
mul_fixed::*: Use a separate region for complete addition assignment.
therealyingtong Jul 8, 2021
22ec16f
Minor refactors, cleanups, clippy fixes, docfixes.
therealyingtong Jul 8, 2021
e2ea443
mul_fixed::*::tests: Witness expected point and constrain result to b…
therealyingtong Jul 8, 2021
5c38f53
mul::tests: Witness expected point and constrain result to be equal.
therealyingtong Jul 8, 2021
ae4e54d
gadget::utilities: Add test cases for bitrange_subset() helper.
therealyingtong Jul 8, 2021
8a9f821
mul_fixed::base_field_elem: Remove double-enable of base_field_fixed_…
therealyingtong Jul 9, 2021
6c41c72
utilities::range_check: Correct range_check expression
therealyingtong Jul 9, 2021
0ade539
utilities::tests::test_range_check(): Test range_check() helper.
therealyingtong Jul 9, 2021
b696163
mul.rs: Explain ordering of mul::incomplete advice columns.
therealyingtong Jul 14, 2021
425ee6e
Docfixes and minor refactors.
therealyingtong Jul 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rustdoc-args = [ "--html-in-header", "katex-header.html" ]
[dependencies]
aes = "0.6"
arrayvec = "0.7.0"
bigint = "4"
bitvec = "0.22"
blake2b_simd = "0.5"
ff = "0.10"
Expand Down
90 changes: 86 additions & 4 deletions src/circuit/gadget/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use halo2::{
plonk::Error,
};

use crate::circuit::gadget::utilities::CellValue;

pub mod chip;

/// The set of circuit instructions required to use the ECC gadgets.
Expand Down Expand Up @@ -128,6 +130,16 @@ pub trait EccInstructions<C: CurveAffine>: Chip<C::Base> {
scalar: &Self::ScalarFixedShort,
base: &Self::FixedPointsShort,
) -> Result<Self::Point, Error>;

/// Performs fixed-base scalar multiplication using a base field element as the scalar.
/// In the current implementation, this base field element must be output from another
/// instruction.
fn mul_fixed_base_field_elem(
&self,
layouter: &mut impl Layouter<C::Base>,
base_field_elem: CellValue<C::Base>,
base: &Self::FixedPoints,
) -> Result<Self::Point, Error>;
}

/// An element of the given elliptic curve's base field, that is used as a scalar
Expand Down Expand Up @@ -352,6 +364,21 @@ where
})
}

/// Multiplies `self` using a value encoded in a base field element
/// as the scalar.
pub fn mul_base_field_elem(
&self,
mut layouter: impl Layouter<C::Base>,
by: CellValue<C::Base>,
) -> Result<Point<C, EccChip>, Error> {
self.chip
.mul_fixed_base_field_elem(&mut layouter, by, &self.inner)
.map(|inner| Point {
chip: self.chip.clone(),
inner,
})
}

/// Wraps the given fixed base (obtained directly from an instruction) in a gadget.
pub fn from_inner(chip: EccChip, inner: EccChip::FixedPoints) -> Self {
FixedPoint { chip, inner }
Expand Down Expand Up @@ -427,14 +454,17 @@ mod tests {
meta.advice_column(),
];

let constants = [meta.fixed_column(), meta.fixed_column()];
let perm = meta.permutation(
&advices
.iter()
.map(|advice| (*advice).into())
.chain(constants.iter().map(|fixed| (*fixed).into()))
.collect::<Vec<_>>(),
);

EccChip::configure(meta, advices, perm)
let lookup_table = meta.fixed_column();
EccChip::configure(meta, advices, lookup_table, constants, perm)
}

fn synthesize(
Expand All @@ -443,7 +473,11 @@ mod tests {
config: Self::Config,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
let chip = EccChip::construct(config);
let chip = EccChip::construct(config.clone());

// Load 10-bit lookup table. In the Action circuit, this will be
// provided by the Sinsemilla chip.
config.lookup_config.load(&mut layouter)?;

// Generate a random point P
let p_val = pallas::Point::random(rand::rngs::OsRng).to_affine(); // P
Expand Down Expand Up @@ -484,7 +518,7 @@ mod tests {
// Test incomplete addition
{
super::chip::add_incomplete::tests::test_add_incomplete(
chip,
chip.clone(),
layouter.namespace(|| "incomplete addition"),
&zero,
p_val,
Expand All @@ -495,15 +529,63 @@ mod tests {
)?;
}

// Test variable-base scalar multiplication
{
super::chip::mul::tests::test_mul(
chip.clone(),
layouter.namespace(|| "variable-base scalar mul"),
&zero,
&p,
p_val,
)?;
}

// Test full-width fixed-base scalar multiplication
{
super::chip::mul_fixed::full_width::tests::test_mul_fixed(
chip.clone(),
layouter.namespace(|| "full-width fixed-base scalar mul"),
)?;
}

// Test signed short fixed-base scalar multiplication
{
super::chip::mul_fixed::short::tests::test_mul_fixed_short(
chip.clone(),
layouter.namespace(|| "signed short fixed-base scalar mul"),
)?;
}

// Test fixed-base scalar multiplication with a base field element
{
super::chip::mul_fixed::base_field_elem::tests::test_mul_fixed_base_field(
chip,
layouter.namespace(|| "fixed-base scalar mul with base field element"),
)?;
}

Ok(())
}
}

#[test]
fn ecc() {
let k = 6;
let k = 13;
let circuit = MyCircuit {};
let prover = MockProver::run(k, &circuit, vec![]).unwrap();
assert_eq!(prover.verify(), Ok(()))
}

#[cfg(feature = "dev-graph")]
#[test]
fn print_ecc_chip() {
use plotters::prelude::*;

let root = BitMapBackend::new("ecc-chip-layout.png", (1024, 7680)).into_drawing_area();
root.fill(&WHITE).unwrap();
let root = root.titled("Ecc Chip Layout", ("sans-serif", 60)).unwrap();

let circuit = MyCircuit {};
halo2::dev::circuit_layout(&circuit, &root).unwrap();
}
}
Loading