Skip to content

Commit 4bf6202

Browse files
Modify ECC gadget to work with chip refactor
1 parent b5de8e6 commit 4bf6202

File tree

2 files changed

+153
-55
lines changed

2 files changed

+153
-55
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ subtle = "2.3"
3232

3333
[dependencies.halo2]
3434
git = "https://github.com/zcash/halo2.git"
35-
rev = "6acacf1aca12f34fc311aa59056e40adc0e6d8bd"
35+
rev = "cae6f6af725cf1f5bc94e126a0b41e9ac602a302"
3636

3737
[dependencies.pasta_curves]
3838
git = "https://github.com/zcash/pasta_curves.git"

src/circuit/gadget/ecc.rs

+152-54
Original file line numberDiff line numberDiff line change
@@ -12,129 +12,227 @@ use halo2::{
1212
pub trait FixedPoints<C: CurveAffine>: Clone + fmt::Debug {}
1313

1414
/// The set of circuit instructions required to use the ECC gadgets.
15-
pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
16-
/// Variable representing an element of the elliptic curve's scalar field.
17-
type Scalar: Clone + fmt::Debug;
15+
pub trait EccInstructions<C: CurveAffine>: Chip<C::Base> {
16+
/// Variable representing a full-width element of the elliptic curve's scalar field, to be used for fixed-base scalar mul.
17+
type ScalarFixed: Clone + fmt::Debug;
18+
/// Variable representing a signed short element of the elliptic curve's scalar field, to be used for fixed-base scalar mul.
19+
type ScalarFixedShort: Clone + fmt::Debug;
1820
/// Variable representing an elliptic curve point.
1921
type Point: Clone + fmt::Debug;
22+
/// Variable representing the x-coordinate of an elliptic curve point.
23+
type X: Clone + fmt::Debug;
2024
/// Variable representing the set of fixed bases in the circuit.
2125
type FixedPoints: FixedPoints<C>;
2226
/// Variable representing a fixed elliptic curve point (constant in the circuit).
2327
type FixedPoint: Clone + fmt::Debug;
2428

25-
/// Witnesses the given scalar as a private input to the circuit.
26-
fn witness_scalar(
27-
layouter: &mut impl Layouter<Self>,
29+
/// Witnesses the given full-width scalar as a private input to the circuit for fixed-based scalar mul.
30+
fn witness_scalar_fixed(
31+
&self,
32+
layouter: &mut impl Layouter<C::Base>,
33+
value: Option<C::Scalar>,
34+
) -> Result<Self::ScalarFixed, Error>;
35+
36+
/// Witnesses the given signed short scalar as a private input to the circuit for fixed-based scalar mul.
37+
fn witness_scalar_fixed_short(
38+
&self,
39+
layouter: &mut impl Layouter<C::Base>,
2840
value: Option<C::Scalar>,
29-
) -> Result<Self::Scalar, Error>;
41+
) -> Result<Self::ScalarFixedShort, Error>;
3042

3143
/// Witnesses the given point as a private input to the circuit.
3244
fn witness_point(
33-
layouter: &mut impl Layouter<Self>,
45+
&self,
46+
layouter: &mut impl Layouter<C::Base>,
3447
value: Option<C>,
3548
) -> Result<Self::Point, Error>;
3649

50+
/// Extracts the x-coordinate of a point.
51+
fn extract_p(point: &Self::Point) -> &Self::X;
52+
3753
/// Gets a fixed point into the circuit.
38-
fn get_fixed(
39-
layouter: &mut impl Layouter<Self>,
40-
fixed_points: Self::FixedPoints,
41-
) -> Result<Self::FixedPoint, Error>;
54+
fn get_fixed(&self, fixed_points: Self::FixedPoints) -> Result<Self::FixedPoint, Error>;
4255

4356
/// Performs point addition, returning `a + b`.
4457
fn add(
45-
layouter: &mut impl Layouter<Self>,
58+
&self,
59+
layouter: &mut impl Layouter<C::Base>,
4660
a: &Self::Point,
4761
b: &Self::Point,
4862
) -> Result<Self::Point, Error>;
4963

50-
/// Performs point doubling, returning `[2] a`.
51-
fn double(layouter: &mut impl Layouter<Self>, a: &Self::Point) -> Result<Self::Point, Error>;
64+
/// Performs complete point addition, returning `a + b`.
65+
fn add_complete(
66+
&self,
67+
layouter: &mut impl Layouter<C::Base>,
68+
a: &Self::Point,
69+
b: &Self::Point,
70+
) -> Result<Self::Point, Error>;
5271

5372
/// Performs variable-base scalar multiplication, returning `[scalar] base`.
5473
fn mul(
55-
layouter: &mut impl Layouter<Self>,
56-
scalar: &Self::Scalar,
74+
&self,
75+
layouter: &mut impl Layouter<C::Base>,
76+
scalar: C::Scalar,
5777
base: &Self::Point,
5878
) -> Result<Self::Point, Error>;
5979

60-
/// Performs fixed-base scalar multiplication, returning `[scalar] base`.
80+
/// Performs fixed-base scalar multiplication using a full-width scalar, returning `[scalar] base`.
6181
fn mul_fixed(
62-
layouter: &mut impl Layouter<Self>,
63-
scalar: &Self::Scalar,
82+
&self,
83+
layouter: &mut impl Layouter<C::Base>,
84+
scalar: &Self::ScalarFixed,
85+
base: &Self::FixedPoint,
86+
) -> Result<Self::Point, Error>;
87+
88+
/// Performs fixed-base scalar multiplication using a short signed scalar, returning `[scalar] base`.
89+
fn mul_fixed_short(
90+
&self,
91+
layouter: &mut impl Layouter<C::Base>,
92+
scalar: &Self::ScalarFixedShort,
6493
base: &Self::FixedPoint,
6594
) -> Result<Self::Point, Error>;
6695
}
6796

68-
/// An element of the given elliptic curve's scalar field.
97+
/// A full-width element of the given elliptic curve's scalar field, to be used for fixed-base scalar mul.
6998
#[derive(Debug)]
70-
pub struct Scalar<C: CurveAffine, EccChip: EccInstructions<C>> {
71-
inner: EccChip::Scalar,
99+
pub struct ScalarFixed<C: CurveAffine, EccChip: EccInstructions<C> + Clone> {
100+
chip: EccChip,
101+
inner: EccChip::ScalarFixed,
72102
}
73103

74-
impl<C: CurveAffine, EccChip: EccInstructions<C>> Scalar<C, EccChip> {
75-
/// Constructs a new point with the given value.
104+
impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone> ScalarFixed<C, EccChip> {
105+
/// Constructs a new ScalarFixed with the given value.
106+
pub fn new(
107+
chip: EccChip,
108+
mut layouter: impl Layouter<C::Base>,
109+
value: Option<C::Scalar>,
110+
) -> Result<Self, Error> {
111+
chip.witness_scalar_fixed(&mut layouter, value)
112+
.map(|inner| ScalarFixed {
113+
chip: chip.clone(),
114+
inner,
115+
})
116+
}
117+
}
118+
119+
/// A signed short element of the given elliptic curve's scalar field, to be used for fixed-base scalar mul.
120+
#[derive(Debug)]
121+
pub struct ScalarFixedShort<C: CurveAffine, EccChip: EccInstructions<C> + Clone> {
122+
chip: EccChip,
123+
inner: EccChip::ScalarFixedShort,
124+
}
125+
126+
impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone> ScalarFixedShort<C, EccChip> {
127+
/// Constructs a new ScalarFixedShort with the given value.
76128
pub fn new(
77-
mut layouter: impl Layouter<EccChip>,
129+
chip: EccChip,
130+
mut layouter: impl Layouter<C::Base>,
78131
value: Option<C::Scalar>,
79132
) -> Result<Self, Error> {
80-
EccChip::witness_scalar(&mut layouter, value).map(|inner| Scalar { inner })
133+
chip.witness_scalar_fixed_short(&mut layouter, value)
134+
.map(|inner| ScalarFixedShort {
135+
chip: chip.clone(),
136+
inner,
137+
})
81138
}
82139
}
83140

84141
/// An elliptic curve point over the given curve.
85142
#[derive(Debug)]
86-
pub struct Point<C: CurveAffine, EccChip: EccInstructions<C>> {
143+
pub struct Point<C: CurveAffine, EccChip: EccInstructions<C> + Clone> {
144+
chip: EccChip,
87145
inner: EccChip::Point,
88146
}
89147

90-
impl<C: CurveAffine, EccChip: EccInstructions<C>> Point<C, EccChip> {
148+
impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone> Point<C, EccChip> {
91149
/// Constructs a new point with the given value.
92-
pub fn new(mut layouter: impl Layouter<EccChip>, value: Option<C>) -> Result<Self, Error> {
93-
EccChip::witness_point(&mut layouter, value).map(|inner| Point { inner })
150+
pub fn new(
151+
&self,
152+
mut layouter: impl Layouter<C::Base>,
153+
value: Option<C>,
154+
) -> Result<Self, Error> {
155+
self.chip
156+
.witness_point(&mut layouter, value)
157+
.map(|inner| Point {
158+
chip: self.chip.clone(),
159+
inner,
160+
})
94161
}
95162

96-
/// Returns `self + other`.
97-
pub fn add(&self, mut layouter: impl Layouter<EccChip>, other: &Self) -> Result<Self, Error> {
98-
EccChip::add(&mut layouter, &self.inner, &other.inner).map(|inner| Point { inner })
163+
/// Extracts the x-coordinate of a point.
164+
pub fn extract_p(&self) -> X<C, EccChip> {
165+
X::from_inner(self.chip.clone(), EccChip::extract_p(&self.inner).clone())
99166
}
100167

101-
/// Returns `[2] self`.
102-
pub fn double(&self, mut layouter: impl Layouter<EccChip>) -> Result<Self, Error> {
103-
EccChip::double(&mut layouter, &self.inner).map(|inner| Point { inner })
168+
/// Wraps the given point (obtained directly from an instruction) in a gadget.
169+
pub fn from_inner(chip: EccChip, inner: EccChip::Point) -> Self {
170+
Point { chip, inner }
171+
}
172+
173+
/// Returns `self + other`.
174+
pub fn add(&self, mut layouter: impl Layouter<C::Base>, other: &Self) -> Result<Self, Error> {
175+
self.chip
176+
.add(&mut layouter, &self.inner, &other.inner)
177+
.map(|inner| Point {
178+
chip: self.chip.clone(),
179+
inner,
180+
})
104181
}
105182

106183
/// Returns `[by] self`.
107-
pub fn mul(
108-
&self,
109-
mut layouter: impl Layouter<EccChip>,
110-
by: &Scalar<C, EccChip>,
111-
) -> Result<Self, Error> {
112-
EccChip::mul(&mut layouter, &by.inner, &self.inner).map(|inner| Point { inner })
184+
pub fn mul(&self, mut layouter: impl Layouter<C::Base>, by: C::Scalar) -> Result<Self, Error> {
185+
self.chip
186+
.mul(&mut layouter, by, &self.inner)
187+
.map(|inner| Point {
188+
chip: self.chip.clone(),
189+
inner,
190+
})
191+
}
192+
}
193+
194+
/// The x-coordinate of an elliptic curve point over the given curve.
195+
#[derive(Debug)]
196+
pub struct X<C: CurveAffine, EccChip: EccInstructions<C> + Clone> {
197+
chip: EccChip,
198+
inner: EccChip::X,
199+
}
200+
201+
impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone> X<C, EccChip> {
202+
/// Wraps the given x-coordinate (obtained directly from an instruction) in a gadget.
203+
pub fn from_inner(chip: EccChip, inner: EccChip::X) -> Self {
204+
X { chip, inner }
113205
}
114206
}
115207

116208
/// A constant elliptic curve point over the given curve, for which scalar multiplication
117209
/// is more efficient.
118-
#[derive(Debug)]
119-
pub struct FixedPoint<C: CurveAffine, EccChip: EccInstructions<C>> {
210+
#[derive(Clone, Debug)]
211+
pub struct FixedPoint<C: CurveAffine, EccChip: EccInstructions<C> + Clone> {
212+
chip: EccChip,
120213
inner: EccChip::FixedPoint,
121214
}
122215

123-
impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPoint<C, EccChip> {
216+
impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone> FixedPoint<C, EccChip> {
124217
/// Gets a reference to the specified fixed point in the circuit.
125-
pub fn get(
126-
mut layouter: impl Layouter<EccChip>,
127-
point: EccChip::FixedPoints,
128-
) -> Result<Self, Error> {
129-
EccChip::get_fixed(&mut layouter, point).map(|inner| FixedPoint { inner })
218+
pub fn get(chip: EccChip, point: EccChip::FixedPoints) -> Result<Self, Error> {
219+
chip.get_fixed(point).map(|inner| FixedPoint {
220+
chip: chip.clone(),
221+
inner,
222+
})
130223
}
131224

132225
/// Returns `[by] self`.
133226
pub fn mul(
134227
&self,
135-
mut layouter: impl Layouter<EccChip>,
136-
by: &Scalar<C, EccChip>,
228+
mut layouter: impl Layouter<C::Base>,
229+
by: &ScalarFixed<C, EccChip>,
137230
) -> Result<Point<C, EccChip>, Error> {
138-
EccChip::mul_fixed(&mut layouter, &by.inner, &self.inner).map(|inner| Point { inner })
231+
self.chip
232+
.mul_fixed(&mut layouter, &by.inner, &self.inner)
233+
.map(|inner| Point {
234+
chip: self.chip.clone(),
235+
inner,
236+
})
139237
}
140238
}

0 commit comments

Comments
 (0)