From 6753a3d051517889afdfb7e7497ad36596270f0d Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 29 Aug 2018 18:56:33 -0600 Subject: [PATCH] Add documentation and script for deriving the Jubjub curve --- README.md | 12 ++++++++---- doc/derive/README.md | 1 - doc/derive/derive.sage | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) delete mode 100644 doc/derive/README.md create mode 100644 doc/derive/derive.sage diff --git a/README.md b/README.md index cc63471..67b2700 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # jubjub [![Crates.io](https://img.shields.io/crates/v/jubjub.svg)](https://crates.io/crates/jubjub) # -This is an implementation of the **Jubjub** elliptic curve group and its associated fields. +This is a pure Rust implementation of the Jubjub elliptic curve group and its associated fields. * **This implementation has not been reviewed or audited. Use at your own risk.** * This implementation targets Rust `1.28` or later. @@ -9,7 +9,9 @@ This is an implementation of the **Jubjub** elliptic curve group and its associa ## [Documentation](https://docs.rs/jubjub) -Jubjub is the twisted Edwards curve `-x^2 + y^2 = 1 + d.x^2.y^2` of rational points over `GF(q)` with a subgroup of prime order `r` and cofactor `8`. +## Curve Description + +Jubjub is the [twisted Edwards curve](https://en.wikipedia.org/wiki/Twisted_Edwards_curve) `-x^2 + y^2 = 1 + d.x^2.y^2` of rational points over `GF(q)` with a subgroup of prime order `r` and cofactor `8`. ``` q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 @@ -17,9 +19,11 @@ r = 0x0e7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7 d = -(10240/10241) ``` -`GF(q)` is the scalar field of the BLS12-381 elliptic curve group. Jubjub is birationally equivalent to a Montgomery curve `y^2 = x^3 + Ax^2 + x` over the same field with `A = 40962`. `A` is the smallest integer such that `(A - 2) / 4` is a small integer, `A^2 - 4` is nonsquare in `GF(q)`, and the Montgomery curve and its quadratic twist have small cofactors `8` and `4`, respectively. +The choice of `GF(q)` is made to be the scalar field of the BLS12-381 elliptic curve group. -Please see [./doc/evidence/](./doc/evidence/) for supporting evidence that Jubjub meets the [SafeCurves](https://safecurves.cr.yp.to/index.html) criteria. The tool in [./doc/derive/](./doc/derive/) will derive the curve parameters via the above criteria. +Jubjub is birationally equivalent to a [Montgomery curve](https://en.wikipedia.org/wiki/Montgomery_curve) `y^2 = x^3 + Ax^2 + x` over the same field with `A = 40962`. This value of `A` is the smallest integer such that `(A - 2) / 4` is a small integer, `A^2 - 4` is nonsquare in `GF(q)`, and the Montgomery curve and its quadratic twist have small cofactors `8` and `4`, respectively. This is identical to the relationship between Curve25519 and ed25519. + +Please see [./doc/evidence/](./doc/evidence/) for supporting evidence that Jubjub meets the [SafeCurves](https://safecurves.cr.yp.to/index.html) criteria. The tool in [./doc/derive/](./doc/derive/) will derive the curve parameters via the above criteria to demonstrate rigidity. ## License diff --git a/doc/derive/README.md b/doc/derive/README.md deleted file mode 100644 index 1333ed7..0000000 --- a/doc/derive/README.md +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/doc/derive/derive.sage b/doc/derive/derive.sage new file mode 100644 index 0000000..c0c5310 --- /dev/null +++ b/doc/derive/derive.sage @@ -0,0 +1,32 @@ +q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 +Fq = GF(q) + +# We wish to find a Montgomery curve with B = 1 and A the smallest such +# that (A - 2) / 4 is a small integer. +def get_A(n): + return (n * 4) + 2 + +# A = 2 is invalid (singular curve), so we start at i = 1 (A = 6) +i = 1 + +while True: + A = Fq(get_A(i)) + i = i + 1 + + # We also want that A^2 - 4 is nonsquare. + if ((A^2) - 4).is_square(): + continue + + ec = EllipticCurve(Fq, [0, A, 0, 1, 0]) + o = ec.order() + + if (o % 8 == 0): + o = o // 8 + if is_prime(o): + twist = ec.quadratic_twist() + otwist = twist.order() + if (otwist % 4 == 0): + otwist = otwist // 4 + if is_prime(otwist): + print "A = %s" % A + exit(0)