Skip to content

Commit 2486ae1

Browse files
committed
simplify splitting code
1 parent f1c3332 commit 2486ae1

File tree

10 files changed

+438
-516
lines changed

10 files changed

+438
-516
lines changed

src/elliptic/projective_point.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<Fq: FqTrait> Point<Fq> {
5151
}
5252

5353
/// Returns the X and Z coordinates of the projective point
54-
pub fn to_point_x(self) -> PointX<Fq> {
54+
pub fn to_pointx(self) -> PointX<Fq> {
5555
PointX::new(&self.X, &self.Z)
5656
}
5757

src/elliptic/torsion_basis.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::point::PointX;
55
use fp2::fq::Fq as FqTrait;
66

77
impl<Fq: FqTrait> Curve<Fq> {
8-
/// TODO:
8+
/// Given xP and xQ as (X : Z) points, compute the point x(P ± Q) (sign is unknown).
99
fn projective_difference(self, P: &PointX<Fq>, Q: &PointX<Fq>) -> PointX<Fq> {
1010
let mut t0 = P.X * Q.X;
1111
let mut t1 = P.Z * Q.Z;
@@ -24,12 +24,10 @@ impl<Fq: FqTrait> Curve<Fq> {
2424
bxz += t0; // bzz = (PX * QX + PZ * QZ) * (PX * QZ + PZ * QX) + 2 * A * PX * QZ * PZ * QX
2525

2626
// We now normalise the result by \bar{(PZ * QZ)}^2
27-
// TODO: I can remove a square here, right?
2827
t0 = P.Z.conjugate();
29-
t0.set_square();
3028
t1 = Q.Z.conjugate();
31-
t1.set_square();
3229
t0 *= t1;
30+
t0.set_square();
3331
bxx *= t0;
3432
bxz *= t0;
3533
bzz *= t0;
@@ -148,8 +146,8 @@ impl<Fq: FqTrait> Curve<Fq> {
148146
xPQ = self.xmul(&xPQ, cofactor, cofactor_bitsize);
149147

150148
// We clear the 2^(f - e) order with repeated doubling.
151-
xP = self.xmul_2e(&xP, e_diff);
152-
xPQ = self.xmul_2e(&xPQ, e_diff);
149+
xP = self.xdouble_iter(&xP, e_diff);
150+
xPQ = self.xdouble_iter(&xPQ, e_diff);
153151

154152
// Compute the difference point to get the basis x(P), x(Q) and x(P-Q)
155153
let xQ = self.projective_difference(&xP, &xPQ);
@@ -211,8 +209,8 @@ impl<Fq: FqTrait> Curve<Fq> {
211209
xPQ = self.xmul(&xPQ, cofactor, cofactor_bitsize);
212210

213211
// We clear the 2^(f - e) order with repeated doubling.
214-
xP = self.xmul_2e(&xP, e_diff);
215-
xPQ = self.xmul_2e(&xPQ, e_diff);
212+
xP = self.xdouble_iter(&xP, e_diff);
213+
xPQ = self.xdouble_iter(&xPQ, e_diff);
216214

217215
// Compute the difference point to get the basis x(P), x(Q) and x(P-Q)
218216
let xQ = self.projective_difference(&xP, &xPQ);

src/elliptic/x_only_arithmetic.rs

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,6 @@ impl<Fq: FqTrait> Curve<Fq> {
3434
*Z *= V1;
3535
}
3636

37-
/// x-only doubling, set `R` to the value of \[2\]P
38-
#[inline]
39-
fn set_xdouble(self, xR: &mut PointX<Fq>) {
40-
self.xdbl(&mut xR.X, &mut xR.Z);
41-
}
42-
43-
/// Return the value [2]P
44-
#[inline]
45-
fn xdouble(self, xP: &PointX<Fq>) -> PointX<Fq> {
46-
let mut xR = *xP;
47-
self.set_xdouble(&mut xR);
48-
xR
49-
}
50-
51-
/// Return the value [2^n]P
52-
#[inline]
53-
fn xdouble_iter(self, xP: &PointX<Fq>, n: usize) -> PointX<Fq> {
54-
let mut xR = *xP;
55-
for _ in 0..n {
56-
self.set_xdouble(&mut xR);
57-
}
58-
xR
59-
}
60-
6137
/// x-only differential formula Note: order of arguments:
6238
/// (XPQ : ZPQ), (XP : ZP), (XQ : ZQ) For PQ = P - Q
6339
/// Sets Q = P + Q in place
@@ -97,7 +73,7 @@ impl<Fq: FqTrait> Curve<Fq> {
9773
*ZQ = *XPQ * (V1 - V2).square();
9874
}
9975

100-
/// P3 <- n*P, X-only variant.
76+
/// P3 <- n*P, x-only variant.
10177
/// Integer n is encoded as unsigned little-endian, with length
10278
/// nbitlen bits. Bits beyond that length are ignored.
10379
pub fn xmul_into(self, P3: &mut PointX<Fq>, P: &PointX<Fq>, n: &[u8], nbitlen: usize) {
@@ -153,7 +129,7 @@ impl<Fq: FqTrait> Curve<Fq> {
153129
P3.Z.set_cond(&Fq::ONE, spec);
154130
}
155131

156-
/// Return n*P as a new point (X-only variant).
132+
/// Return n*P as a new point (x-only variant).
157133
/// Integer n is encoded as unsigned little-endian, with length
158134
/// nbitlen bits. Bits beyond that length are ignored.
159135
pub fn xmul(self, P: &PointX<Fq>, n: &[u8], nbitlen: usize) -> PointX<Fq> {
@@ -162,8 +138,27 @@ impl<Fq: FqTrait> Curve<Fq> {
162138
P3
163139
}
164140

165-
/// P3 <- (2^e)*P (X-only variant)
166-
fn xmul_2e_into(self, P3: &mut PointX<Fq>, P: &PointX<Fq>, e: usize) {
141+
/// P3 <- [2]*P (x-only variant)
142+
fn xdouble_into(self, P3: &mut PointX<Fq>, P: &PointX<Fq>) {
143+
let mut V1 = (P.X + P.Z).square();
144+
let V2 = (P.X - P.Z).square();
145+
P3.X = V1 * V2;
146+
V1 -= V2;
147+
P3.Z = V1;
148+
P3.Z *= self.A24;
149+
P3.Z += V2;
150+
P3.Z *= V1;
151+
}
152+
153+
/// Return [2]*P (x-only variant).
154+
pub fn xdouble(self, P: &PointX<Fq>) -> PointX<Fq> {
155+
let mut Q = PointX::INFINITY;
156+
self.xdouble_into(&mut Q, P);
157+
Q
158+
}
159+
160+
/// P3 <- (2^e)*P (x-only variant)
161+
fn xdouble_iter_into(self, P3: &mut PointX<Fq>, P: &PointX<Fq>, e: usize) {
167162
let mut X = P.X;
168163
let mut Z = P.Z;
169164
for _ in 0..e {
@@ -181,17 +176,17 @@ impl<Fq: FqTrait> Curve<Fq> {
181176
}
182177

183178
/// Return (2^e)*P (x-only variant).
184-
pub fn xmul_2e(self, P: &PointX<Fq>, e: usize) -> PointX<Fq> {
179+
pub fn xdouble_iter(self, P: &PointX<Fq>, e: usize) -> PointX<Fq> {
185180
let mut Q = PointX::INFINITY;
186-
self.xmul_2e_into(&mut Q, P, e);
181+
self.xdouble_iter_into(&mut Q, P, e);
187182
Q
188183
}
189184

190185
/// Return (2^e)*R for R in [P, Q, P - Q] (x-only variant).
191-
pub fn basis_xmul_2e(self, B: &BasisX<Fq>, e: usize) -> BasisX<Fq> {
192-
let P = self.xmul_2e(&B.P, e);
193-
let Q = self.xmul_2e(&B.Q, e);
194-
let PQ = self.xmul_2e(&B.PQ, e);
186+
pub fn basis_double_iter(self, B: &BasisX<Fq>, e: usize) -> BasisX<Fq> {
187+
let P = self.xdouble_iter(&B.P, e);
188+
let Q = self.xdouble_iter(&B.Q, e);
189+
let PQ = self.xdouble_iter(&B.PQ, e);
195190
BasisX::from_points(&P, &Q, &PQ)
196191
}
197192

@@ -230,7 +225,7 @@ impl<Fq: FqTrait> Curve<Fq> {
230225
*ZQ = ZPQ;
231226
}
232227

233-
/// Return P + n*Q, X-only variant given the x-only basis x(P), x(Q) and x(P - Q).
228+
/// Return P + n*Q, x-only variant given the x-only basis x(P), x(Q) and x(P - Q).
234229
/// Integer `n` is encoded as unsigned little-endian, with length `nbitlen` bits.
235230
/// Bits beyond that length are ignored.
236231
pub fn three_point_ladder(self, B: &BasisX<Fq>, n: &[u8], nbitlen: usize) -> PointX<Fq> {
@@ -308,7 +303,7 @@ impl<Fq: FqTrait> Curve<Fq> {
308303
((s0 & 1) as usize, (s1 & 1) as usize, r)
309304
}
310305

311-
/// Return [a]P + [b]*Q, X-only variant given the x-only basis x(P), x(Q) and x(P - Q).
306+
/// Return [a]P + [b]*Q, x-only variant given the x-only basis x(P), x(Q) and x(P - Q).
312307
/// The integers `a` and `b` are encoded as unsigned little-endian.
313308
pub fn ladder_biscalar(
314309
self,

src/protocols/sqisign.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl<Fq: FqTrait> Sqisign<Fq> {
227227
let mut chl_kernel =
228228
pk.curve
229229
.three_point_ladder(&pk_basis, sig.chl_scalar, self.security_bits);
230-
chl_kernel = pk.curve.xmul_2e(&chl_kernel, sig.backtracking);
230+
chl_kernel = pk.curve.xdouble_iter(&chl_kernel, sig.backtracking);
231231

232232
// Compute the isogeny chain, a failure u32 is returned for the case of
233233
// bad input.
@@ -333,8 +333,9 @@ impl<Fq: FqTrait> Sqisign<Fq> {
333333
// Double the bases to get points of the correct even order.
334334
aux_basis = sig
335335
.aux_curve
336-
.basis_xmul_2e(&aux_basis, self.f - e_rsp_prime - 2);
337-
chl_basis = E_chl.basis_xmul_2e(&chl_basis, self.f - e_rsp_prime - sig.two_resp_length - 2);
336+
.basis_double_iter(&aux_basis, self.f - e_rsp_prime - 2);
337+
chl_basis =
338+
E_chl.basis_double_iter(&chl_basis, self.f - e_rsp_prime - sig.two_resp_length - 2);
338339

339340
// Apply the change of basis dictated by the matrix aij contained in the signature.
340341
chl_basis = Self::apply_change_of_basis(&E_chl, &chl_basis, &sig.aij, chl_order);
@@ -355,9 +356,9 @@ impl<Fq: FqTrait> Sqisign<Fq> {
355356
// depending on aij values
356357
let mut basis_img = B.to_array();
357358
let kernel = if sig.aij[0][0] & 1 == 0 && sig.aij[2][0] & 1 == 0 {
358-
E.xmul_2e(&B.Q, e_rsp_prime + 2)
359+
E.xdouble_iter(&B.Q, e_rsp_prime + 2)
359360
} else {
360-
E.xmul_2e(&B.P, e_rsp_prime + 2)
361+
E.xdouble_iter(&B.P, e_rsp_prime + 2)
361362
};
362363

363364
// Compute the two isogeny and push the challenge basis through

src/theta/theta_chain.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use fp2::fq::Fq as FqTrait;
22

33
use super::elliptic_product::{EllipticProduct, ProductPoint};
4-
use super::theta_gluing::gluing_isogeny;
54
use super::theta_isogeny::{two_isogeny, two_isogeny_to_product};
65
use super::theta_point::ThetaPoint;
76
use super::theta_splitting::{split_to_product, splitting_isomorphism};
@@ -47,7 +46,7 @@ impl<Fq: FqTrait> EllipticProduct<Fq> {
4746

4847
// Compute Gluing isogeny
4948
let (mut domain, mut kernel_pts) =
50-
gluing_isogeny(&self, &P1P2_8, &Q1Q2_8, &kernel_couple_pts);
49+
self.gluing_isogeny(&P1P2_8, &Q1Q2_8, &kernel_couple_pts);
5150

5251
// Do all remaining steps
5352
let mut Tp1: ThetaPoint<Fq>;
@@ -146,8 +145,7 @@ impl<Fq: FqTrait> EllipticProduct<Fq> {
146145

147146
// Compute the Gluing isogeny and push through stategy_points to get a new
148147
// vector of ThetaPoints of the same length.
149-
let (mut domain, mut strategy_pts) = gluing_isogeny(
150-
&self,
148+
let (mut domain, mut strategy_pts) = self.gluing_isogeny(
151149
&product_strategy_pts[2 * k],
152150
&product_strategy_pts[2 * k + 1],
153151
&product_strategy_pts,

0 commit comments

Comments
 (0)