Skip to content

Commit 219b83a

Browse files
Added cofactors to non-edwardian curve interfaces (#50)
* Added cofactors to non-edwardian curve interfaces * Added mnt sage script * Added more sage and fixed mnt4 g2 cofactor
1 parent 3a0ae81 commit 219b83a

25 files changed

+382
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Implementation of altbn128
2+
3+
## Run the sage script to generate the curve parameters
4+
5+
1. Make sure that you have [SageMath](https://www.sagemath.org/) installed
6+
7+
2. Run:
8+
```bash
9+
sage alt_bn128.sage
10+
```
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env sage -python
2+
3+
from sage.all import *
4+
import sys
5+
sys.path.append("../")
6+
import params_generator
7+
8+
# Prime order of the subgroup we work in
9+
def r(x):
10+
return 36*(x**4) + 36*(x**3) + 18*(x**2) + 6*x + 1
11+
12+
# Prime used to generate the base finite field
13+
def q(x):
14+
return 36*(x**4) + 36*(x**3) + 24*(x**2) + 6*x + 1
15+
16+
# Compute G2 cofactor
17+
# See: Proposition 1, Section 3.3: https://eprint.iacr.org/2015/247.pdf
18+
def g2_h(x):
19+
return 36*x^4+ 36*x^3+ 30*x^2+ 6*x + 1
20+
21+
# Computes the order of G1, the safe subgroup of E/Fq
22+
def g1_order(curve_order):
23+
decomposition = factor(curve_order)
24+
# Factor returns the prime decomposition and orders prime
25+
# factors from smaller to biggest
26+
biggest_factor = decomposition[-1]
27+
assert(biggest_factor[1] == 1)
28+
return biggest_factor[0]
29+
30+
def main():
31+
print("Generating parameters for alt_bn128")
32+
# Curve parameter
33+
param = 0x44e992b44a6909f1
34+
35+
prime_r = r(param)
36+
assert(prime_r == 21888242871839275222246405745257275088548364400416034343698204186575808495617)
37+
38+
prime_q = q(param)
39+
assert(prime_q == 21888242871839275222246405745257275088696311157297823662689037894645226208583)
40+
if (mod(prime_q, 6) != 1):
41+
raise BaseException("Unexpected: q should be = 1 (mod 6). See: https://eprint.iacr.org/2007/390.pdf")
42+
43+
# Scalar field
44+
print('prime_r = {}'.format(prime_r))
45+
#params_generator.generate_libff_Fp_model_params(prime_r)
46+
Fr = GF(prime_r)
47+
48+
# Base field
49+
print('prime_q = {}'.format(prime_q))
50+
#params_generator.generate_libff_Fp_model_params(prime_q)
51+
Fq = GF(prime_q)
52+
53+
# E/Fq
54+
curve = EllipticCurve(Fq, [0, 3])
55+
curve_order = curve.order()
56+
57+
# Cofactors
58+
h1 = curve_order // g1_order(curve_order)
59+
# G1 cofactor should be 1
60+
assert(h1 == 1)
61+
print('h1 = {}'.format(h1))
62+
h2 = g2_h(param)
63+
print('h2 = {}'.format(h2))
64+
65+
if __name__ == '__main__':
66+
main()

libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ std::vector<size_t> alt_bn128_G1::fixed_base_exp_window_table;
1919
alt_bn128_G1 alt_bn128_G1::G1_zero = {};
2020
alt_bn128_G1 alt_bn128_G1::G1_one = {};
2121
bool alt_bn128_G1::initialized = false;
22+
bigint<alt_bn128_G1::h_limbs> alt_bn128_G1::h;
2223

2324
alt_bn128_G1::alt_bn128_G1()
2425
{
@@ -319,6 +320,12 @@ alt_bn128_G1 alt_bn128_G1::dbl() const
319320
return alt_bn128_G1(X3, Y3, Z3);
320321
}
321322

323+
alt_bn128_G1 alt_bn128_G1::mul_by_cofactor() const
324+
{
325+
// Cofactor = 1
326+
return *this;
327+
}
328+
322329
bool alt_bn128_G1::is_well_formed() const
323330
{
324331
if (this->is_zero())

libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class alt_bn128_G1 {
3333
typedef alt_bn128_Fq base_field;
3434
typedef alt_bn128_Fr scalar_field;
3535

36+
// Cofactor
37+
static const mp_size_t h_bitcount = 1;
38+
static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS;
39+
static bigint<h_limbs> h;
40+
3641
alt_bn128_Fq X, Y, Z;
3742

3843
// using Jacobian coordinates
@@ -58,6 +63,7 @@ class alt_bn128_G1 {
5863
alt_bn128_G1 add(const alt_bn128_G1 &other) const;
5964
alt_bn128_G1 mixed_add(const alt_bn128_G1 &other) const;
6065
alt_bn128_G1 dbl() const;
66+
alt_bn128_G1 mul_by_cofactor() const;
6167

6268
bool is_well_formed() const;
6369

libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ std::vector<size_t> alt_bn128_G2::fixed_base_exp_window_table;
1919
alt_bn128_G2 alt_bn128_G2::G2_zero = {};
2020
alt_bn128_G2 alt_bn128_G2::G2_one = {};
2121
bool alt_bn128_G2::initialized = false;
22+
bigint<alt_bn128_G2::h_limbs> alt_bn128_G2::h;
2223

2324
alt_bn128_G2::alt_bn128_G2()
2425
{
@@ -336,6 +337,11 @@ alt_bn128_G2 alt_bn128_G2::mul_by_q() const
336337
(this->Z).Frobenius_map(1));
337338
}
338339

340+
alt_bn128_G2 alt_bn128_G2::mul_by_cofactor() const
341+
{
342+
return alt_bn128_G2::h * (*this);
343+
}
344+
339345
bool alt_bn128_G2::is_well_formed() const
340346
{
341347
if (this->is_zero())

libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class alt_bn128_G2 {
3434
typedef alt_bn128_Fq2 twist_field;
3535
typedef alt_bn128_Fr scalar_field;
3636

37+
// Cofactor
38+
static const mp_size_t h_bitcount = 256;
39+
static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS;
40+
static bigint<h_limbs> h;
41+
3742
alt_bn128_Fq2 X, Y, Z;
3843

3944
// using Jacobian coordinates
@@ -62,6 +67,7 @@ class alt_bn128_G2 {
6267
alt_bn128_G2 mixed_add(const alt_bn128_G2 &other) const;
6368
alt_bn128_G2 dbl() const;
6469
alt_bn128_G2 mul_by_q() const;
70+
alt_bn128_G2 mul_by_cofactor() const;
6571

6672
bool is_well_formed() const;
6773

libff/algebra/curves/alt_bn128/alt_bn128_init.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ void init_alt_bn128_params()
150150
alt_bn128_Fq::one());
151151
alt_bn128_G1::initialized = true;
152152

153+
// Cofactor
154+
alt_bn128_G1::h = bigint<alt_bn128_G1::h_limbs>("1");
155+
153156
alt_bn128_G1::wnaf_window_table.resize(0);
154157
alt_bn128_G1::wnaf_window_table.push_back(11);
155158
alt_bn128_G1::wnaf_window_table.push_back(24);
@@ -215,6 +218,14 @@ void init_alt_bn128_params()
215218
alt_bn128_Fq2::one());
216219
alt_bn128_G2::initialized = true;
217220

221+
// Cofactor
222+
// [Sage excerpt]
223+
// See: https://eprint.iacr.org/2015/247.pdf
224+
// u = 4965661367192848881
225+
// h2 = (36 * u^4) + (36 * u^3) + (30 * u^2) + 6*u + 1; h2
226+
// # 21888242871839275222246405745257275088844257914179612981679871602714643921549
227+
alt_bn128_G2::h = bigint<alt_bn128_G2::h_limbs>("21888242871839275222246405745257275088844257914179612981679871602714643921549");
228+
218229
alt_bn128_G2::wnaf_window_table.resize(0);
219230
alt_bn128_G2::wnaf_window_table.push_back(5);
220231
alt_bn128_G2::wnaf_window_table.push_back(15);

libff/algebra/curves/bn128/bn128_g1.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::vector<size_t> bn128_G1::fixed_base_exp_window_table;
2020
bn128_G1 bn128_G1::G1_zero = {};
2121
bn128_G1 bn128_G1::G1_one = {};
2222
bool bn128_G1::initialized = false;
23+
bigint<bn128_G1::h_limbs> bn128_G1::h;
2324

2425
bn::Fp bn128_G1::sqrt(const bn::Fp &el)
2526
{
@@ -337,6 +338,12 @@ bn128_G1 bn128_G1::dbl() const
337338
return result;
338339
}
339340

341+
bn128_G1 bn128_G1::mul_by_cofactor() const
342+
{
343+
// Cofactor = 1
344+
return (*this);
345+
}
346+
340347
bn128_G1 bn128_G1::zero()
341348
{
342349
return G1_zero;

libff/algebra/curves/bn128/bn128_g1.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ class bn128_G1 {
3737
typedef bn128_Fq base_field;
3838
typedef bn128_Fr scalar_field;
3939

40+
// Cofactor
41+
static const mp_size_t h_bitcount = 1;
42+
static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS;
43+
static bigint<h_limbs> h;
44+
4045
bn::Fp X, Y, Z;
4146
void fill_coord(bn::Fp coord[3]) const { coord[0] = this->X; coord[1] = this->Y; coord[2] = this->Z; return; };
4247

@@ -62,6 +67,7 @@ class bn128_G1 {
6267
bn128_G1 add(const bn128_G1 &other) const;
6368
bn128_G1 mixed_add(const bn128_G1 &other) const;
6469
bn128_G1 dbl() const;
70+
bn128_G1 mul_by_cofactor() const;
6571

6672
bool is_well_formed() const;
6773

libff/algebra/curves/bn128/bn128_g2.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::vector<size_t> bn128_G2::fixed_base_exp_window_table;
2020
bn128_G2 bn128_G2::G2_zero = {};
2121
bn128_G2 bn128_G2::G2_one = {};
2222
bool bn128_G2::initialized = false;
23+
bigint<bn128_G2::h_limbs> bn128_G2::h;
2324

2425
bn::Fp2 bn128_G2::sqrt(const bn::Fp2 &el)
2526
{
@@ -337,6 +338,11 @@ bn128_G2 bn128_G2::dbl() const
337338
return result;
338339
}
339340

341+
bn128_G2 bn128_G2::mul_by_cofactor() const
342+
{
343+
return bn128_G2::h * (*this);
344+
}
345+
340346
bool bn128_G2::is_well_formed() const
341347
{
342348
if (this->is_zero())

0 commit comments

Comments
 (0)