Skip to content

Commit 1f48b1d

Browse files
authored
Merge pull request #20 from stefandeml/fix-projection
remove code duplication in alt_bn128 add functions and update docs
2 parents 176f3f4 + 76e6739 commit 1f48b1d

File tree

2 files changed

+36
-117
lines changed

2 files changed

+36
-117
lines changed

libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp

Lines changed: 18 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,9 @@ alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const
156156
// no need to handle points of order 2,4
157157
// (they cannot exist in a prime-order subgroup)
158158

159-
// check for doubling case
160-
161-
// using Jacobian coordinates so:
162-
// (X1:Y1:Z1) = (X2:Y2:Z2)
159+
// using Jacobian coordinates according to
160+
// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
161+
// Note: (X1:Y1:Z1) = (X2:Y2:Z2)
163162
// iff
164163
// X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3
165164
// iff
@@ -177,12 +176,17 @@ alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const
177176
alt_bn128_Fq S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2
178177
alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1
179178

179+
// check for doubling case
180180
if (U1 == U2 && S1 == S2)
181181
{
182182
// dbl case; nothing of above can be reused
183183
return this->dbl();
184184
}
185185

186+
#ifdef PROFILE_OP_COUNTS
187+
this->add_cnt++;
188+
#endif
189+
186190
// rest of add case
187191
alt_bn128_Fq H = U2 - U1; // H = U2-U1
188192
alt_bn128_Fq S2_minus_S1 = S2-S1;
@@ -211,50 +215,7 @@ alt_bn128_G1 alt_bn128_G1::operator-(const alt_bn128_G1 &other) const
211215

212216
alt_bn128_G1 alt_bn128_G1::add(const alt_bn128_G1 &other) const
213217
{
214-
// handle special cases having to do with O
215-
if (this->is_zero())
216-
{
217-
return other;
218-
}
219-
220-
if (other.is_zero())
221-
{
222-
return *this;
223-
}
224-
225-
// no need to handle points of order 2,4
226-
// (they cannot exist in a prime-order subgroup)
227-
228-
// handle double case
229-
if (this->operator==(other))
230-
{
231-
return this->dbl();
232-
}
233-
234-
#ifdef PROFILE_OP_COUNTS
235-
this->add_cnt++;
236-
#endif
237-
// NOTE: does not handle O and pts of order 2,4
238-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
239-
240-
alt_bn128_Fq Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2
241-
alt_bn128_Fq Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2
242-
alt_bn128_Fq U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2
243-
alt_bn128_Fq U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1
244-
alt_bn128_Fq S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2
245-
alt_bn128_Fq S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1
246-
alt_bn128_Fq H = U2 - U1; // H = U2-U1
247-
alt_bn128_Fq S2_minus_S1 = S2-S1;
248-
alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2
249-
alt_bn128_Fq J = H * I; // J = H * I
250-
alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1)
251-
alt_bn128_Fq V = U1 * I; // V = U1 * I
252-
alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V
253-
alt_bn128_Fq S1_J = S1 * J;
254-
alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J
255-
alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H
256-
257-
return alt_bn128_G1(X3, Y3, Z3);
218+
return (*this) + other;
258219
}
259220

260221
alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const
@@ -277,15 +238,13 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const
277238
// no need to handle points of order 2,4
278239
// (they cannot exist in a prime-order subgroup)
279240

280-
// check for doubling case
281-
282-
// using Jacobian coordinates so:
283-
// (X1:Y1:Z1) = (X2:Y2:Z2)
241+
// using Jacobian coordinates according to
242+
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
243+
// Note: (X1:Y1:Z1) = (X2:Y2:Z2)
284244
// iff
285245
// X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3
286246
// iff
287247
// X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3
288-
289248
// we know that Z2 = 1
290249

291250
const alt_bn128_Fq Z1Z1 = (this->Z).squared();
@@ -298,6 +257,7 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const
298257
const alt_bn128_Fq &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2
299258
const alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1
300259

260+
// check for doubling case
301261
if (U1 == U2 && S1 == S2)
302262
{
303263
// dbl case; nothing of above can be reused
@@ -307,11 +267,9 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const
307267
#ifdef PROFILE_OP_COUNTS
308268
this->add_cnt++;
309269
#endif
310-
311-
// NOTE: does not handle O and pts of order 2,4
312-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
270+
313271
alt_bn128_Fq H = U2-(this->X); // H = U2-X1
314-
alt_bn128_Fq HH = H.squared() ; // HH = H&2
272+
alt_bn128_Fq HH = H.squared() ; // HH = H^2
315273
alt_bn128_Fq I = HH+HH; // I = 4*HH
316274
I = I + I;
317275
alt_bn128_Fq J = H*I; // J = H*I
@@ -340,9 +298,9 @@ alt_bn128_G1 alt_bn128_G1::dbl() const
340298
// no need to handle points of order 2,4
341299
// (they cannot exist in a prime-order subgroup)
342300

343-
// NOTE: does not handle O and pts of order 2,4
344-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
345-
301+
// using Jacobian coordinates according to
302+
// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
303+
346304
alt_bn128_Fq A = (this->X).squared(); // A = X1^2
347305
alt_bn128_Fq B = (this->Y).squared(); // B = Y1^2
348306
alt_bn128_Fq C = B.squared(); // C = B^2

libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp

Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,9 @@ alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const
166166
// no need to handle points of order 2,4
167167
// (they cannot exist in a prime-order subgroup)
168168

169-
// check for doubling case
170-
171-
// using Jacobian coordinates so:
172-
// (X1:Y1:Z1) = (X2:Y2:Z2)
169+
// using Jacobian coordinates according to
170+
// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
171+
// Note: (X1:Y1:Z1) = (X2:Y2:Z2)
173172
// iff
174173
// X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3
175174
// iff
@@ -187,12 +186,17 @@ alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const
187186
alt_bn128_Fq2 S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2
188187
alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1
189188

189+
// check for doubling case
190190
if (U1 == U2 && S1 == S2)
191191
{
192192
// dbl case; nothing of above can be reused
193193
return this->dbl();
194194
}
195195

196+
#ifdef PROFILE_OP_COUNTS
197+
this->add_cnt++;
198+
#endif
199+
196200
// rest of add case
197201
alt_bn128_Fq2 H = U2 - U1; // H = U2-U1
198202
alt_bn128_Fq2 S2_minus_S1 = S2-S1;
@@ -221,50 +225,7 @@ alt_bn128_G2 alt_bn128_G2::operator-(const alt_bn128_G2 &other) const
221225

222226
alt_bn128_G2 alt_bn128_G2::add(const alt_bn128_G2 &other) const
223227
{
224-
// handle special cases having to do with O
225-
if (this->is_zero())
226-
{
227-
return other;
228-
}
229-
230-
if (other.is_zero())
231-
{
232-
return *this;
233-
}
234-
235-
// no need to handle points of order 2,4
236-
// (they cannot exist in a prime-order subgroup)
237-
238-
// handle double case
239-
if (this->operator==(other))
240-
{
241-
return this->dbl();
242-
}
243-
244-
#ifdef PROFILE_OP_COUNTS
245-
this->add_cnt++;
246-
#endif
247-
// NOTE: does not handle O and pts of order 2,4
248-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2
249-
250-
alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2
251-
alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2
252-
alt_bn128_Fq2 U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2
253-
alt_bn128_Fq2 U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1
254-
alt_bn128_Fq2 S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2
255-
alt_bn128_Fq2 S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1
256-
alt_bn128_Fq2 H = U2 - U1; // H = U2-U1
257-
alt_bn128_Fq2 S2_minus_S1 = S2-S1;
258-
alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2
259-
alt_bn128_Fq2 J = H * I; // J = H * I
260-
alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1)
261-
alt_bn128_Fq2 V = U1 * I; // V = U1 * I
262-
alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V
263-
alt_bn128_Fq2 S1_J = S1 * J;
264-
alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J
265-
alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H
266-
267-
return alt_bn128_G2(X3, Y3, Z3);
228+
return (*this) + other;
268229
}
269230

270231
alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const
@@ -287,15 +248,13 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const
287248
// no need to handle points of order 2,4
288249
// (they cannot exist in a prime-order subgroup)
289250

290-
// check for doubling case
291-
292-
// using Jacobian coordinates so:
293-
// (X1:Y1:Z1) = (X2:Y2:Z2)
251+
// using Jacobian coordinates according to
252+
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
253+
// Note: (X1:Y1:Z1) = (X2:Y2:Z2)
294254
// iff
295255
// X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3
296256
// iff
297257
// X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3
298-
299258
// we know that Z2 = 1
300259

301260
const alt_bn128_Fq2 Z1Z1 = (this->Z).squared();
@@ -308,6 +267,7 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const
308267
const alt_bn128_Fq2 &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2
309268
const alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1
310269

270+
// check for doubling case
311271
if (U1 == U2 && S1 == S2)
312272
{
313273
// dbl case; nothing of above can be reused
@@ -318,10 +278,8 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const
318278
this->add_cnt++;
319279
#endif
320280

321-
// NOTE: does not handle O and pts of order 2,4
322-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
323281
alt_bn128_Fq2 H = U2-(this->X); // H = U2-X1
324-
alt_bn128_Fq2 HH = H.squared() ; // HH = H&2
282+
alt_bn128_Fq2 HH = H.squared() ; // HH = H^2
325283
alt_bn128_Fq2 I = HH+HH; // I = 4*HH
326284
I = I + I;
327285
alt_bn128_Fq2 J = H*I; // J = H*I
@@ -348,8 +306,11 @@ alt_bn128_G2 alt_bn128_G2::dbl() const
348306
}
349307

350308
// NOTE: does not handle O and pts of order 2,4
351-
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#doubling-dbl-2007-bl
309+
// (they cannot exist in a prime-order subgroup)
352310

311+
// using Jacobian coordinates according to
312+
// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
313+
353314
alt_bn128_Fq2 A = (this->X).squared(); // A = X1^2
354315
alt_bn128_Fq2 B = (this->Y).squared(); // B = Y1^2
355316
alt_bn128_Fq2 C = B.squared(); // C = B^2

0 commit comments

Comments
 (0)