From 51f9823c91f91e62d6bac552aa0644a3696918f1 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 14:12:58 -0700 Subject: [PATCH 01/21] Create a new docs/ subtree and move assets into it --- Makefile | 4 ++-- .../assets/dalek-logo-clear.png | Bin dalek-logo.png => docs/assets/dalek-logo.png | Bin dalek-logo.svg => docs/assets/dalek-logo.svg | 0 .../assets/rustdoc-include-katex-header.html | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename dalek-logo-clear.png => docs/assets/dalek-logo-clear.png (100%) rename dalek-logo.png => docs/assets/dalek-logo.png (100%) rename dalek-logo.svg => docs/assets/dalek-logo.svg (100%) rename rustdoc-include-katex-header.html => docs/assets/rustdoc-include-katex-header.html (100%) diff --git a/Makefile b/Makefile index eabe38a..8b376cb 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ FEATURES := nightly yolocrypto doc: - cargo rustdoc --features "$(FEATURES)" -- --html-in-header rustdoc-include-katex-header.html + cargo rustdoc --features "$(FEATURES)" -- --html-in-header docs/assets/rustdoc-include-katex-header.html doc-internal: - cargo rustdoc --features "$(FEATURES)" -- --html-in-header rustdoc-include-katex-header.html --document-private-items + cargo rustdoc --features "$(FEATURES)" -- --html-in-header docs/assets/rustdoc-include-katex-header.html --document-private-items diff --git a/dalek-logo-clear.png b/docs/assets/dalek-logo-clear.png similarity index 100% rename from dalek-logo-clear.png rename to docs/assets/dalek-logo-clear.png diff --git a/dalek-logo.png b/docs/assets/dalek-logo.png similarity index 100% rename from dalek-logo.png rename to docs/assets/dalek-logo.png diff --git a/dalek-logo.svg b/docs/assets/dalek-logo.svg similarity index 100% rename from dalek-logo.svg rename to docs/assets/dalek-logo.svg diff --git a/rustdoc-include-katex-header.html b/docs/assets/rustdoc-include-katex-header.html similarity index 100% rename from rustdoc-include-katex-header.html rename to docs/assets/rustdoc-include-katex-header.html From ef0dae241aa0bb5cc008ede85568184640720bf9 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 14:24:06 -0700 Subject: [PATCH 02/21] Add an explanatory note that's built on stable When building on stable, the README.md is not included in the documentation, leaving a bare entry. This adds a warning stub, pointing people to use nightly rust. --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 0a8a1a3..6699118 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,9 @@ #![cfg_attr(feature = "nightly", doc(include = "../README.md"))] #![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")] +//! Note that docs will only build on nightly Rust until +//! [RFC 1990 stabilizes](https://github.com/rust-lang/rust/issues/44732). + //------------------------------------------------------------------------ // External dependencies: //------------------------------------------------------------------------ From c841998b07d8739978a2e0ec2b3cc8afff52642d Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 14:43:19 -0700 Subject: [PATCH 03/21] Extract Ristretto notes into a markdown file --- docs/ristretto-notes.md | 318 ++++++++++++++++++++++++++++++++++++++ src/ristretto.rs | 331 ++-------------------------------------- 2 files changed, 329 insertions(+), 320 deletions(-) create mode 100644 docs/ristretto-notes.md diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md new file mode 100644 index 0000000..190a227 --- /dev/null +++ b/docs/ristretto-notes.md @@ -0,0 +1,318 @@ +Below are some notes on Ristretto, which are *NOT* a full writeup and which may have errors. + +# Notes on Ristretto + +## The Jacobi Quartic + +The Jacobi quartic is parameterized by \\(e, A\\), and is of the +form $$ \mathcal J\_{e,A} : t\^2 = es\^4 + 2As\^2 + 1, $$ with +identity point \\((0,1)\\). For more details on the Jacobi quartic, +see the [Decaf paper](https://eprint.iacr.org/2015/673.pdf) or +[_Jacobi Quartic Curves +Revisited_](https://eprint.iacr.org/2009/312.pdf) by Hisil, Wong, +Carter, and Dawson). + +When \\(e = a\^2\\), \\(\mathcal J\_{e,A}\\) has full +\\(2\\)-torsion (i.e., \\(\mathcal J[2] \cong \mathbb Z /2 \times +\mathbb Z/2\\)), and +we can write the \\(\mathcal J[2]\\)-coset of a point \\(P = +(s,t)\\) as +$$ +P + \mathcal J[2] = \left\\{ + (s,t), + (-s,-t), + (1/as, -t/as\^2), + (-1/as, t/as\^2) \right\\}. +$$ +Notice that replacing \\(a\\) by \\(-a\\) just swaps the last two +points, so this set does not depend on the choice of \\(a\\). In +what follows we require \\(a = \pm 1\\). + +## Encoding \\(\mathcal J / \mathcal J[2]\\) + +To encode points on \\(\mathcal J\\) modulo \\(\mathcal J[2]\\), +we need to choose a canonical representative of the above coset. +To do this, it's sufficient to make two independent sign choices: +the Decaf paper suggests choosing \\((s,t)\\) with \\(s\\) +non-negative and finite, and \\(t/s\\) non-negative or infinite. + +The encoding is then the (canonical byte encoding of the) +\\(s\\)-value of the canonical representative. + +## The Edwards Curve + +Our primary internal model for Curve25519 points are the [_Extended +Twisted Edwards Coordinates_](https://eprint.iacr.org/2008/522.pdf) +of Hisil, Wong, Carter, and Dawson. +These correspond to the affine model + +$$\mathcal E\_{a,d} : ax\^2 + y\^2 = 1 + dx\^2y\^2.$$ + +In projective coordinates, we represent a point as \\((X:Y:Z:T)\\) +with $$XY = ZT, \quad aX\^2 + Y\^2 = Z\^2 + dT\^2.$$ (For more +details on this model, see the documentation for the `edwards` +module). The case \\(a = 1\\) is the _untwisted_ case; we only +consider \\(a = \pm 1\\), and in particular we focus on the twisted +Edwards form of Curve25519, which has \\(a = -1, d = +-121665/121666\\). When not otherwise specified, we write +\\(\mathcal E\\) for \\(\mathcal E\_{-1, -121665/121666}\\). + +When both \\(d\\) and \\(ad\\) are nonsquare (which forces \\(a\\) +to be square), the curve is *complete*. In this case the +four-torsion subgroup is cyclic, and we +can write it explicitly as +$$ +\mathcal E\_{a,d}[4] = \\{ (0,1),\; (1/\sqrt a, 0),\; (0, -1),\; (-1/\sqrt{a}, 0)\\}. +$$ +These are the only points with \\(xy = 0\\); the points with \\( y +\neq 0 \\) are \\(2\\)-torsion. The \\(\mathcal +E\_{a,d}[4]\\)-coset of \\(P = (x,y)\\) is then +$$ +P + \mathcal E\_{a,d}[4] = \\{ (x,y),\; (y/\sqrt a, -x\sqrt a),\; (-x, -y),\; (-y/\sqrt a, x\sqrt a)\\}. +$$ +Notice that if \\(xy \neq 0 \\), then exactly two of +these points have \\( xy \\) non-negative, and they differ by the +\\(2\\)-torsion point \\( (0,-1) \\). This means that we can select +a representative modulo \\(\mathcal +E\_{a,d}[2] \\) by requiring \\(xy\\) nonnegative and \\(y \neq +0\\), and we can ensure this condition by conditionally adding a +\\(4\\)-torsion point if \\(xy\\) is negative or \\(y = 0\\). + +This procedure gives a canonical lift from \\(\mathcal E / \mathcal +E[4]\\) to \\(\mathcal E / \mathcal E[2]\\). Since it involves a +conditional rotation, we refer to it as *torquing* the point. + +The structure of the Curve25519 group is \\( \mathcal E(\mathbb +F\_p) \cong \mathbb Z / 8 \times \mathbb Z / \ell\\), where \\( \ell += 2\^{252} + \cdots \\) is a large prime. Because \\(\mathcal E[8] +\cong \mathbb Z / 8\\), we have \\(\[2\](\mathcal E[8]) = \mathcal +E[4]\\), \\(\mathcal E[4] \cong \mathbb Z / 4 +\\) and \\( \mathcal E[2] \cong \mathbb Z / 2\\). In particular +this tells us that the group +$$ +\frac{\[2\](\mathcal E)}{\mathcal E[4]} +$$ +is well-defined and has prime order \\( (8\ell / 2) / 4 = \ell \\). +This is the group we will construct using Ristretto. + +## The Isogeny + +For \\(a = \pm 1\\), we have a \\(2\\)-isogeny +$$ +\theta\_{a,d} : \mathcal J\_{a\^2, -a(a+d)/(a-d)} \longrightarrow \mathcal E\_{a,d} +$$ +(or simply \\(\theta\\)) defined by +$$ +\theta\_{a,d} : (s,t) \mapsto \left( \frac{1}{\sqrt{ad-1}} \cdot \frac{2s}{t},\quad \frac{1+as\^2}{1-as\^2} \right). +$$ + +XXX Its dual is ... ? + +The kernel of the isogeny is \\( \{(0, \pm 1)\} \\). +The image of the isogeny is \\(\[2\](\mathcal E)\\). To see this, +first note that because \\( \theta \circ \hat{\theta} = [2] \\), we +know that \\( \[2\](\mathcal E) \subseteq \theta(\mathcal J)\\); then, to see that +\\(\theta(\mathcal J)\\) is exactly \\(\[2\](\mathcal E)\\), +recall that isogenous elliptic curves over a finite field have the +same number of points (exercise 5.4 of Silverman), so that +$$ +\\# \theta(\mathcal J) = \frac {\\# \mathcal J} {\\# \ker \theta} += \frac {\\# \mathcal E}{2} = \\# \[2\](\mathcal E). +$$ + +To determine the image \\(\theta(\mathcal J[2])\\) of the +\\(2\\)-torsion, we consider the image of the coset \\(\theta((s,t) ++ \mathcal J[2])\\). Let \\((x,y) = \theta(s,t)\\); then +\\(\theta(-s,-t) = (x,y)\\) and \\(\theta(1/as, -t/as\^2) = (-x, +-y)\\), so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). + +The Decaf paper recalls that, for a group \\( G \\) with normal +subgroup \\(G' \leq G\\), a group homomorphism \\( \phi : G +\rightarrow H \\) induces a homomorphism +$$ +\bar{\phi} : \frac G {G'} \longrightarrow \frac {\phi(G)}{\phi(G')} \leq \frac {H} {\phi(G')}, +$$ +and that the induced homomorphism \\(\bar{\phi}\\) is injective if +\\( \ker \phi \leq G' \\). In our context, the kernel of +\\(\theta\\) is \\( \\{(0, \pm 1)\\} \leq \mathcal J[2] \\), +so \\(\theta\\) gives an isomorphism +$$ +\frac {\mathcal J} {\mathcal J[2]} +\cong +\frac {\theta(\mathcal J)} {\theta(\mathcal J[2])} +\cong +\frac {\[2\](\mathcal E)} {\mathcal E[2]}. +$$ + +We can use the isomorphism to transfer the encoding of \\(\mathcal +J / \mathcal J[2] \\) defined above to \\(\[2\](\mathcal E)/\mathcal +E[2]\\), by encoding the Edwards point \\((x,y)\\) using the Jacobi +quartic encoding of \\(\theta\^{-1}(x,y)\\). + +Since \\(\\# (\[2\](\mathcal E) / \mathcal E[2]) = (\\#\mathcal +E)/4\\), if \\(\mathcal E\\) has cofactor \\(4\\), we're done. +Otherwise, if \\(\mathcal E\\) has cofactor \\(8\\), as in the +Curve25519 case, we use the torquing procedure to lift \\(\mathcal E +/ \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\), and then +apply the encoding for \\( \[2\](\mathcal E) / \mathcal E[2] \\). + +## The Ristretto Encoding + +We can write the above encoding/decoding procedure concretely (in affine +coordinates) as follows: + +### Encoding + +On input \\( (x,y) \in \[2\](\mathcal E)\\), a representative for a +coset in \\( \[2\](\mathcal E) / \mathcal E[4] \\): + +1. Check if \\( xy \\) is negative or \\( x = 0 \\); if so, torque + the point by setting \\( (x,y) \gets (x,y) + P_4 \\), where + \\(P_4\\) is a \\(4\\)-torsion point. + +2. Check if \\(x\\) is negative or \\( y = -1 \\); if so, set + \\( (x,y) \gets (x,y) + (0,-1) = (-x, -y) \\). + +3. Compute $$ s = +\sqrt {(-a) \frac {1 - y} {1 + y} }, $$ choosing + the positive square root. + +The output is then the (canonical) byte-encoding of \\(s\\). + +If \\(\mathcal E\\) has cofactor \\(4\\), we skip the first step, +since our input already represents a coset in +\\( \[2\](\mathcal E) / \mathcal E[2] \\). + +To see that this corresponds to the encoding procedure above, notice +that the first step lifts from \\( \mathcal E / \mathcal E[4] \\) to +\\(\mathcal E / \mathcal E[2]\\). To understand steps 2 and 3, +notice that the \\(y\\)-coordinate of \\(\theta(s,t)\\) is +$$ +y = \frac {1 + as\^2}{1 - as\^2}, +$$ +so that the \\(s\\)-coordinate of \\(\theta\^{-1}(x,y)\\) has +$$ +s\^2 = (-a)\frac {1-y}{1+y}. +$$ +Since +$$ +x = \frac 1 {\sqrt {ad - 1}} \frac {2s} {t}, +$$ +we also have +$$ +\frac s t = x \frac {\sqrt {ad-1}} 2, +$$ +so that the sign of \\(s/t\\) is determined by the sign of \\(x\\). + +Recall that to choose a canonical representative of \\( (s,t) + +\mathcal J[2] \\), it's sufficient to make two sign choices: the +sign of \\(s\\) and the sign of \\(s/t\\). Step 2 determines the +sign of \\(s/t\\), while step 3 computes \\(s\\) and determines its +sign (by choosing the positive square root). Finally, the check +that \\(y \neq -1\\) prevents division-by-zero when encoding the +identity; it falls out of the optimized formulas below. + +### Decoding + +On input `s_bytes`, decoding proceeds as follows: + +1. Decode `s_bytes` to \\(s\\); reject if `s_bytes` is not the + canonical encoding of \\(s\\). + +2. Check whether \\(s\\) is negative; if so, reject. + +3. Compute +$$ +y \gets \frac {1 + as\^2}{1 - as\^2}. +$$ + +4. Compute +$$ +x \gets +\sqrt{ \frac{4s\^2} {ad(1+as\^2)\^2 - (1-as\^2)\^2}}, +$$ +choosing the positive square root, or reject if the square root does +not exist. + +5. Check whether \\(xy\\) is negative or \\(y = 0\\); if so, reject. + +## Encoding in Extended Coordinates + +The formulas above are given in affine coordinates, but the usual +internal representation is extended twisted Edwards coordinates \\( +(X:Y:Z:T) \\) with \\( x = X/Z \\), \\(y = Y/Z\\), \\(xy = T/Z \\). +Selecting the distinguished representative of the coset +requires the affine coordinates \\( (x,y) \\), and computing \\( s +\\) requires an inverse square root. +As inversions are expensive, we'd like to be able to do this +whole computation with only one inverse square root, by batching +together the inversion and the inverse square root. + +However, it is not obvious how to do this, since the inverse square +root computation depends on the affine coordinates (which select the +distinguished representative). + +In what follows we consider only the case +\\(a = -1\\); a similar argument applies to the case \\( a = 1\\). + +Since \\(y = Y/Z\\), in extended coordinates the formula for \\(s\\) becomes +$$ +s = \sqrt{ \frac{ 1 - Y/Z}{1+Y/Z}} = \sqrt{\frac{Z - Y}{Z+Y}} += \frac {Z - Y} {\sqrt{Z\^2 - Y\^2}}. +$$ + +Here \\( (X:Y:Z:T) \\) are the coordinates of the distinguished +representative of the coset. +Write \\( (X\_0 : Y\_0 : Z\_0 : T\_0) \\) +for the coordinates of the initial representative. Then the +torquing procedure in step 1 replaces \\( (X\_0 : Y\_0 : Z\_0 : +T\_0) \\) by \\( (iY\_0 : iX\_0 : Z\_0 : -T\_0) \\). This means we +want to obtain either +$$ +\frac {1} { \sqrt{Z\_0\^2 - Y\_0\^2}} +\quad \text{or} \quad +\frac {1} { \sqrt{Z\_0\^2 + X\_0\^2}}. +$$ + +We can relate these using the identity +$$ +(a-d)X\^2Y\^2 = (Z\^2 - aX\^2)(Z\^2 - Y\^2), +$$ +which is valid for all curve points. To see this, recall from the curve equation that +$$ +-dX\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2, +$$ +so that +$$ +(a-d)X\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2 + aX\^2Y\^2 = (Z\^2 - Y\^2)(Z\^2 + X\^2). +$$ + +The encoding procedure is as follows: + +1. \\(u\_1 \gets (Z\_0 + Y\_0)(Z\_0 - Y\_0) = Z\_0\^2 - Y\_0\^2 \\) +2. \\(u\_2 \gets X\_0 Y\_0 \\) +3. \\(I \gets \mathrm{invsqrt}(u\_1 u\_2\^2) = 1/\sqrt{X\_0\^2 Y\_0\^2 (Z\_0\^2 - Y\_0\^2)} \\) +4. \\(D\_1 \gets u\_1 I = \sqrt{(Z\_0\^2 - Y\_0\^2)/(X\_0\^2 Y\_0\^2)} \\) +5. \\(D\_2 \gets u\_2 I = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) +6. \\(Z\_{inv} \gets D\_1 D\_2 T\_0 = (u\_1 u\_2)/(u\_1 u\_2\^2) T\_0 = T\_0 / X\_0 Y\_0 = 1/Z\_0 \\) +7. If \\( T\_0 Z\_{inv} = x\_0 y\_0 \\) is negative: + 1. \\( X \gets iY\_0 \\) + 2. \\( Y \gets iX\_0 \\) + 3. \\( D \gets D\_1 / \sqrt{a-d} = 1/\sqrt{Z\_0\^2 + X\_0\^2} \\) +8. Otherwise: + 1. \\( X \gets X\_0 \\) + 2. \\( Y \gets Y\_0 \\) + 3. \\( D \gets D\_2 = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) +9. If \\( X Z\_{inv} = x \\) is negative, set \\( Y \gets - Y\\) +10. Compute \\( s \gets (Z - Y) D = (Z - Y) / \sqrt{Z\^2 - Y\^2} \\) and return. + +## Decoding to Extended Coordinates + +## Equality Testing + +## Elligator + +## The Double-Ristretto Encoding + +It's possible to do batch encoding of \\( [2]P \\) using the dual +isogeny \\(\hat{\theta}\\). Defer this for now. + +## ??? diff --git a/src/ristretto.rs b/src/ristretto.rs index f2fcce0..452299a 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -142,327 +142,18 @@ //! [ristretto_notes]: //! https://doc-internal.dalek.rs/curve25519_dalek/ristretto/notes/index.html + +// Conditionally include the Ristretto notes if: +// - we're on nightly (so we can include docs at all) +// - we're in stage 2 of the build. +// The latter point prevents a really silly and annoying problem, +// where the location of ".." is different depending on whether we're +// building the crate for real, or whether we're in build.rs +// generating the lookup tables (in which case we're relative to the +// location of build.rs, not lib.rs, so the markdown file appears +// missing). +#[cfg_attr(all(feature = "nightly", feature="precomputed_tables"), doc(include = "../docs/ristretto-notes.md"))] mod notes { - -//! Below are some notes on Ristretto, which are *NOT* a full writeup and which may have errors. -//! -//! # Notes on Ristretto -//! -//! ## The Jacobi Quartic -//! -//! The Jacobi quartic is parameterized by \\(e, A\\), and is of the -//! form $$ \mathcal J\_{e,A} : t\^2 = es\^4 + 2As\^2 + 1, $$ with -//! identity point \\((0,1)\\). For more details on the Jacobi quartic, -//! see the [Decaf paper](https://eprint.iacr.org/2015/673.pdf) or -//! [_Jacobi Quartic Curves -//! Revisited_](https://eprint.iacr.org/2009/312.pdf) by Hisil, Wong, -//! Carter, and Dawson). -//! -//! When \\(e = a\^2\\), \\(\mathcal J\_{e,A}\\) has full -//! \\(2\\)-torsion (i.e., \\(\mathcal J[2] \cong \mathbb Z /2 \times -//! \mathbb Z/2\\)), and -//! we can write the \\(\mathcal J[2]\\)-coset of a point \\(P = -//! (s,t)\\) as -//! $$ -//! P + \mathcal J[2] = \left\\{ -//! (s,t), -//! (-s,-t), -//! (1/as, -t/as\^2), -//! (-1/as, t/as\^2) \right\\}. -//! $$ -//! Notice that replacing \\(a\\) by \\(-a\\) just swaps the last two -//! points, so this set does not depend on the choice of \\(a\\). In -//! what follows we require \\(a = \pm 1\\). -//! -//! ## Encoding \\(\mathcal J / \mathcal J[2]\\) -//! -//! To encode points on \\(\mathcal J\\) modulo \\(\mathcal J[2]\\), -//! we need to choose a canonical representative of the above coset. -//! To do this, it's sufficient to make two independent sign choices: -//! the Decaf paper suggests choosing \\((s,t)\\) with \\(s\\) -//! non-negative and finite, and \\(t/s\\) non-negative or infinite. -//! -//! The encoding is then the (canonical byte encoding of the) -//! \\(s\\)-value of the canonical representative. -//! -//! ## The Edwards Curve -//! -//! Our primary internal model for Curve25519 points are the [_Extended -//! Twisted Edwards Coordinates_](https://eprint.iacr.org/2008/522.pdf) -//! of Hisil, Wong, Carter, and Dawson. -//! These correspond to the affine model -//! -//! $$\mathcal E\_{a,d} : ax\^2 + y\^2 = 1 + dx\^2y\^2.$$ -//! -//! In projective coordinates, we represent a point as \\((X:Y:Z:T)\\) -//! with $$XY = ZT, \quad aX\^2 + Y\^2 = Z\^2 + dT\^2.$$ (For more -//! details on this model, see the documentation for the `edwards` -//! module). The case \\(a = 1\\) is the _untwisted_ case; we only -//! consider \\(a = \pm 1\\), and in particular we focus on the twisted -//! Edwards form of Curve25519, which has \\(a = -1, d = -//! -121665/121666\\). When not otherwise specified, we write -//! \\(\mathcal E\\) for \\(\mathcal E\_{-1, -121665/121666}\\). -//! -//! When both \\(d\\) and \\(ad\\) are nonsquare (which forces \\(a\\) -//! to be square), the curve is *complete*. In this case the -//! four-torsion subgroup is cyclic, and we -//! can write it explicitly as -//! $$ -//! \mathcal E\_{a,d}[4] = \\{ (0,1),\; (1/\sqrt a, 0),\; (0, -1),\; (-1/\sqrt{a}, 0)\\}. -//! $$ -//! These are the only points with \\(xy = 0\\); the points with \\( y -//! \neq 0 \\) are \\(2\\)-torsion. The \\(\mathcal -//! E\_{a,d}[4]\\)-coset of \\(P = (x,y)\\) is then -//! $$ -//! P + \mathcal E\_{a,d}[4] = \\{ (x,y),\; (y/\sqrt a, -x\sqrt a),\; (-x, -y),\; (-y/\sqrt a, x\sqrt a)\\}. -//! $$ -//! Notice that if \\(xy \neq 0 \\), then exactly two of -//! these points have \\( xy \\) non-negative, and they differ by the -//! \\(2\\)-torsion point \\( (0,-1) \\). This means that we can select -//! a representative modulo \\(\mathcal -//! E\_{a,d}[2] \\) by requiring \\(xy\\) nonnegative and \\(y \neq -//! 0\\), and we can ensure this condition by conditionally adding a -//! \\(4\\)-torsion point if \\(xy\\) is negative or \\(y = 0\\). -//! -//! This procedure gives a canonical lift from \\(\mathcal E / \mathcal -//! E[4]\\) to \\(\mathcal E / \mathcal E[2]\\). Since it involves a -//! conditional rotation, we refer to it as *torquing* the point. -//! -//! The structure of the Curve25519 group is \\( \mathcal E(\mathbb -//! F\_p) \cong \mathbb Z / 8 \times \mathbb Z / \ell\\), where \\( \ell -//! = 2\^{252} + \cdots \\) is a large prime. Because \\(\mathcal E[8] -//! \cong \mathbb Z / 8\\), we have \\(\[2\](\mathcal E[8]) = \mathcal -//! E[4]\\), \\(\mathcal E[4] \cong \mathbb Z / 4 -//! \\) and \\( \mathcal E[2] \cong \mathbb Z / 2\\). In particular -//! this tells us that the group -//! $$ -//! \frac{\[2\](\mathcal E)}{\mathcal E[4]} -//! $$ -//! is well-defined and has prime order \\( (8\ell / 2) / 4 = \ell \\). -//! This is the group we will construct using Ristretto. -//! -//! ## The Isogeny -//! -//! For \\(a = \pm 1\\), we have a \\(2\\)-isogeny -//! $$ -//! \theta\_{a,d} : \mathcal J\_{a\^2, -a(a+d)/(a-d)} \longrightarrow \mathcal E\_{a,d} -//! $$ -//! (or simply \\(\theta\\)) defined by -//! $$ -//! \theta\_{a,d} : (s,t) \mapsto \left( \frac{1}{\sqrt{ad-1}} \cdot \frac{2s}{t},\quad \frac{1+as\^2}{1-as\^2} \right). -//! $$ -//! -//! XXX Its dual is ... ? -//! -//! The kernel of the isogeny is \\( \{(0, \pm 1)\} \\). -//! The image of the isogeny is \\(\[2\](\mathcal E)\\). To see this, -//! first note that because \\( \theta \circ \hat{\theta} = [2] \\), we -//! know that \\( \[2\](\mathcal E) \subseteq \theta(\mathcal J)\\); then, to see that -//! \\(\theta(\mathcal J)\\) is exactly \\(\[2\](\mathcal E)\\), -//! recall that isogenous elliptic curves over a finite field have the -//! same number of points (exercise 5.4 of Silverman), so that -//! $$ -//! \\# \theta(\mathcal J) = \frac {\\# \mathcal J} {\\# \ker \theta} -//! = \frac {\\# \mathcal E}{2} = \\# \[2\](\mathcal E). -//! $$ -//! -//! To determine the image \\(\theta(\mathcal J[2])\\) of the -//! \\(2\\)-torsion, we consider the image of the coset \\(\theta((s,t) -//! + \mathcal J[2])\\). Let \\((x,y) = \theta(s,t)\\); then -//! \\(\theta(-s,-t) = (x,y)\\) and \\(\theta(1/as, -t/as\^2) = (-x, -//! -y)\\), so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). -//! -//! The Decaf paper recalls that, for a group \\( G \\) with normal -//! subgroup \\(G' \leq G\\), a group homomorphism \\( \phi : G -//! \rightarrow H \\) induces a homomorphism -//! $$ -//! \bar{\phi} : \frac G {G'} \longrightarrow \frac {\phi(G)}{\phi(G')} \leq \frac {H} {\phi(G')}, -//! $$ -//! and that the induced homomorphism \\(\bar{\phi}\\) is injective if -//! \\( \ker \phi \leq G' \\). In our context, the kernel of -//! \\(\theta\\) is \\( \\{(0, \pm 1)\\} \leq \mathcal J[2] \\), -//! so \\(\theta\\) gives an isomorphism -//! $$ -//! \frac {\mathcal J} {\mathcal J[2]} -//! \cong -//! \frac {\theta(\mathcal J)} {\theta(\mathcal J[2])} -//! \cong -//! \frac {\[2\](\mathcal E)} {\mathcal E[2]}. -//! $$ -//! -//! We can use the isomorphism to transfer the encoding of \\(\mathcal -//! J / \mathcal J[2] \\) defined above to \\(\[2\](\mathcal E)/\mathcal -//! E[2]\\), by encoding the Edwards point \\((x,y)\\) using the Jacobi -//! quartic encoding of \\(\theta\^{-1}(x,y)\\). -//! -//! Since \\(\\# (\[2\](\mathcal E) / \mathcal E[2]) = (\\#\mathcal -//! E)/4\\), if \\(\mathcal E\\) has cofactor \\(4\\), we're done. -//! Otherwise, if \\(\mathcal E\\) has cofactor \\(8\\), as in the -//! Curve25519 case, we use the torquing procedure to lift \\(\mathcal E -//! / \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\), and then -//! apply the encoding for \\( \[2\](\mathcal E) / \mathcal E[2] \\). -//! -//! ## The Ristretto Encoding -//! -//! We can write the above encoding/decoding procedure concretely (in affine -//! coordinates) as follows: -//! -//! ### Encoding -//! -//! On input \\( (x,y) \in \[2\](\mathcal E)\\), a representative for a -//! coset in \\( \[2\](\mathcal E) / \mathcal E[4] \\): -//! -//! 1. Check if \\( xy \\) is negative or \\( x = 0 \\); if so, torque -//! the point by setting \\( (x,y) \gets (x,y) + P_4 \\), where -//! \\(P_4\\) is a \\(4\\)-torsion point. -//! -//! 2. Check if \\(x\\) is negative or \\( y = -1 \\); if so, set -//! \\( (x,y) \gets (x,y) + (0,-1) = (-x, -y) \\). -//! -//! 3. Compute $$ s = +\sqrt {(-a) \frac {1 - y} {1 + y} }, $$ choosing -//! the positive square root. -//! -//! The output is then the (canonical) byte-encoding of \\(s\\). -//! -//! If \\(\mathcal E\\) has cofactor \\(4\\), we skip the first step, -//! since our input already represents a coset in -//! \\( \[2\](\mathcal E) / \mathcal E[2] \\). -//! -//! To see that this corresponds to the encoding procedure above, notice -//! that the first step lifts from \\( \mathcal E / \mathcal E[4] \\) to -//! \\(\mathcal E / \mathcal E[2]\\). To understand steps 2 and 3, -//! notice that the \\(y\\)-coordinate of \\(\theta(s,t)\\) is -//! $$ -//! y = \frac {1 + as\^2}{1 - as\^2}, -//! $$ -//! so that the \\(s\\)-coordinate of \\(\theta\^{-1}(x,y)\\) has -//! $$ -//! s\^2 = (-a)\frac {1-y}{1+y}. -//! $$ -//! Since -//! $$ -//! x = \frac 1 {\sqrt {ad - 1}} \frac {2s} {t}, -//! $$ -//! we also have -//! $$ -//! \frac s t = x \frac {\sqrt {ad-1}} 2, -//! $$ -//! so that the sign of \\(s/t\\) is determined by the sign of \\(x\\). -//! -//! Recall that to choose a canonical representative of \\( (s,t) + -//! \mathcal J[2] \\), it's sufficient to make two sign choices: the -//! sign of \\(s\\) and the sign of \\(s/t\\). Step 2 determines the -//! sign of \\(s/t\\), while step 3 computes \\(s\\) and determines its -//! sign (by choosing the positive square root). Finally, the check -//! that \\(y \neq -1\\) prevents division-by-zero when encoding the -//! identity; it falls out of the optimized formulas below. -//! -//! ### Decoding -//! -//! On input `s_bytes`, decoding proceeds as follows: -//! -//! 1. Decode `s_bytes` to \\(s\\); reject if `s_bytes` is not the -//! canonical encoding of \\(s\\). -//! -//! 2. Check whether \\(s\\) is negative; if so, reject. -//! -//! 3. Compute -//! $$ -//! y \gets \frac {1 + as\^2}{1 - as\^2}. -//! $$ -//! -//! 4. Compute -//! $$ -//! x \gets +\sqrt{ \frac{4s\^2} {ad(1+as\^2)\^2 - (1-as\^2)\^2}}, -//! $$ -//! choosing the positive square root, or reject if the square root does -//! not exist. -//! -//! 5. Check whether \\(xy\\) is negative or \\(y = 0\\); if so, reject. -//! -//! ## Encoding in Extended Coordinates -//! -//! The formulas above are given in affine coordinates, but the usual -//! internal representation is extended twisted Edwards coordinates \\( -//! (X:Y:Z:T) \\) with \\( x = X/Z \\), \\(y = Y/Z\\), \\(xy = T/Z \\). -//! Selecting the distinguished representative of the coset -//! requires the affine coordinates \\( (x,y) \\), and computing \\( s -//! \\) requires an inverse square root. -//! As inversions are expensive, we'd like to be able to do this -//! whole computation with only one inverse square root, by batching -//! together the inversion and the inverse square root. -//! -//! However, it is not obvious how to do this, since the inverse square -//! root computation depends on the affine coordinates (which select the -//! distinguished representative). -//! -//! In what follows we consider only the case -//! \\(a = -1\\); a similar argument applies to the case \\( a = 1\\). -//! -//! Since \\(y = Y/Z\\), in extended coordinates the formula for \\(s\\) becomes -//! $$ -//! s = \sqrt{ \frac{ 1 - Y/Z}{1+Y/Z}} = \sqrt{\frac{Z - Y}{Z+Y}} -//! = \frac {Z - Y} {\sqrt{Z\^2 - Y\^2}}. -//! $$ -//! -//! Here \\( (X:Y:Z:T) \\) are the coordinates of the distinguished -//! representative of the coset. -//! Write \\( (X\_0 : Y\_0 : Z\_0 : T\_0) \\) -//! for the coordinates of the initial representative. Then the -//! torquing procedure in step 1 replaces \\( (X\_0 : Y\_0 : Z\_0 : -//! T\_0) \\) by \\( (iY\_0 : iX\_0 : Z\_0 : -T\_0) \\). This means we -//! want to obtain either -//! $$ -//! \frac {1} { \sqrt{Z\_0\^2 - Y\_0\^2}} -//! \quad \text{or} \quad -//! \frac {1} { \sqrt{Z\_0\^2 + X\_0\^2}}. -//! $$ -//! -//! We can relate these using the identity -//! $$ -//! (a-d)X\^2Y\^2 = (Z\^2 - aX\^2)(Z\^2 - Y\^2), -//! $$ -//! which is valid for all curve points. To see this, recall from the curve equation that -//! $$ -//! -dX\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2, -//! $$ -//! so that -//! $$ -//! (a-d)X\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2 + aX\^2Y\^2 = (Z\^2 - Y\^2)(Z\^2 + X\^2). -//! $$ -//! -//! The encoding procedure is as follows: -//! -//! 1. \\(u\_1 \gets (Z\_0 + Y\_0)(Z\_0 - Y\_0) = Z\_0\^2 - Y\_0\^2 \\) -//! 2. \\(u\_2 \gets X\_0 Y\_0 \\) -//! 3. \\(I \gets \mathrm{invsqrt}(u\_1 u\_2\^2) = 1/\sqrt{X\_0\^2 Y\_0\^2 (Z\_0\^2 - Y\_0\^2)} \\) -//! 4. \\(D\_1 \gets u\_1 I = \sqrt{(Z\_0\^2 - Y\_0\^2)/(X\_0\^2 Y\_0\^2)} \\) -//! 5. \\(D\_2 \gets u\_2 I = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) -//! 6. \\(Z\_{inv} \gets D\_1 D\_2 T\_0 = (u\_1 u\_2)/(u\_1 u\_2\^2) T\_0 = T\_0 / X\_0 Y\_0 = 1/Z\_0 \\) -//! 7. If \\( T\_0 Z\_{inv} = x\_0 y\_0 \\) is negative: -//! 1. \\( X \gets iY\_0 \\) -//! 2. \\( Y \gets iX\_0 \\) -//! 3. \\( D \gets D\_1 / \sqrt{a-d} = 1/\sqrt{Z\_0\^2 + X\_0\^2} \\) -//! 8. Otherwise: -//! 1. \\( X \gets X\_0 \\) -//! 2. \\( Y \gets Y\_0 \\) -//! 3. \\( D \gets D\_2 = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) -//! 9. If \\( X Z\_{inv} = x \\) is negative, set \\( Y \gets - Y\\) -//! 10. Compute \\( s \gets (Z - Y) D = (Z - Y) / \sqrt{Z\^2 - Y\^2} \\) and return. -//! -//! ## Decoding to Extended Coordinates -//! -//! ## Equality Testing -//! -//! ## Elligator -//! -//! ## The Double-Ristretto Encoding -//! -//! It's possible to do batch encoding of \\( [2]P \\) using the dual -//! isogeny \\(\hat{\theta}\\). Defer this for now. -//! -//! ## ??? - } use core::fmt::Debug; From 35e1b07e728bea8234cd44ffc5c911d5af81c10e Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 14:58:02 -0700 Subject: [PATCH 04/21] Clarify abstraction layers in Ristretto intro --- src/ristretto.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ristretto.rs b/src/ristretto.rs index 452299a..aac5e67 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -23,7 +23,7 @@ //! Eliminating cofactors through point //! compression_](https://eprint.iacr.org/2015/673.pdf), notes that while //! most cryptographic systems require a group of prime order, most -//! concrete implementations using elliptic curve groups fall short -- +//! concrete implementations using elliptic curve groups fall short – //! they either provide a group of prime order, but with incomplete or //! variable-time addition formulae (for instance, most Weierstrass //! models), or else they provide a fast and safe implementation of a @@ -31,15 +31,19 @@ //! small cofactor \\(h\\) (for instance, Edwards curves, which have //! cofactor at least \\(4\\)). //! -//! This abstraction mismatch requires ad-hoc protocol modifications to -//! ensure security; these modifications require careful analysis and -//! are a recurring source of [vulnerabilities][cryptonote] and [design +//! This abstraction mismatch is commonly “handled” by pushing the +//! complexity upwards, adding ad-hoc protocol modifications. But +//! these modifications require careful analysis and are a recurring +//! source of unexpected [vulnerabilities][cryptonote] and [design //! complications][ed25519_hkd]. //! -//! Instead, Ristretto uses a quotient group to implement a prime-order -//! group using a non-prime-order curve. More details are described in -//! the *Implementation* section below. Ristretto points are provided -//! in `curve25519-dalek` by the `RistrettoPoint` struct. +//! Instead, Ristretto uses a quotient group to implement a +//! prime-order group using a non-prime-order curve. This provides +//! the correct abstraction for cryptographic systems, while retaining +//! the speed and safety benefits of an Edwards curve. More details +//! are described in the *Implementation* section below. Ristretto +//! points are provided in `curve25519-dalek` by the `RistrettoPoint` +//! struct. //! //! ## Encoding and Decoding //! From 46048e451bfed9c542b43d5051bdf98d9e82aef8 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 15:03:19 -0700 Subject: [PATCH 05/21] Clarify wording on canonical scalars --- src/ristretto.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ristretto.rs b/src/ristretto.rs index aac5e67..4f4a703 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -69,8 +69,10 @@ //! ## Scalars //! //! Scalars are represented by the `Scalar` struct. Each scalar has a -//! canonical representative mod the group order; see -//! `Scalar::from_canonical_bytes()` and `Scalar::is_canonical()`. +//! canonical representative mod the group order. To attempt to load +//! a supposedly-canonical scalar, use +//! `Scalar::from_canonical_bytes()`. To check whether a +//! representative is canonical, use `Scalar::is_canonical()`. //! //! ## Scalar Multiplication //! From c99bd62b255636a91eccd08cbb94237cf363c55d Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 15:10:04 -0700 Subject: [PATCH 06/21] Add example to RistrettoBasepointTable --- src/ristretto.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ristretto.rs b/src/ristretto.rs index 4f4a703..6cd7301 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -832,6 +832,16 @@ pub fn multiscalar_mul(scalars: I, points: J) -> RistrettoPoint /// A precomputed table of multiples of a basepoint, used to accelerate /// scalar multiplication. +/// +/// A precomputed table of multiples of the Ristretto basepoint is +/// available in the `constants` module: +/// ``` +/// use curve25519_dalek::constants; +/// use curve25519_dalek::scalar::Scalar; +/// +/// let a = Scalar::from_u64(87329482); +/// let P = &a * &constants::RISTRETTO_BASEPOINT_TABLE; +/// ``` #[derive(Clone)] pub struct RistrettoBasepointTable(pub(crate) EdwardsBasepointTable); From ff787c2f12ba227f896acdd3fb66a6cdb70fd35e Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 15:38:16 -0700 Subject: [PATCH 07/21] Clarify Ristretto / Decaf relation in user docs --- src/ristretto.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/ristretto.rs b/src/ristretto.rs index 6cd7301..d30a3a2 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -19,7 +19,9 @@ //! # The Ristretto Group //! //! Ristretto is a modification of Mike Hamburg's Decaf scheme to work -//! with Curve25519. The introduction of the Decaf paper, [_Decaf: +//! with cofactor-\\(8\\) curves, such as Curve25519. +//! +//! The introduction of the Decaf paper, [_Decaf: //! Eliminating cofactors through point //! compression_](https://eprint.iacr.org/2015/673.pdf), notes that while //! most cryptographic systems require a group of prime order, most @@ -34,13 +36,21 @@ //! This abstraction mismatch is commonly “handled” by pushing the //! complexity upwards, adding ad-hoc protocol modifications. But //! these modifications require careful analysis and are a recurring -//! source of unexpected [vulnerabilities][cryptonote] and [design +//! source of [vulnerabilities][cryptonote] and [design //! complications][ed25519_hkd]. //! -//! Instead, Ristretto uses a quotient group to implement a +//! Instead, Decaf (and Ristretto) use a quotient group to implement a //! prime-order group using a non-prime-order curve. This provides //! the correct abstraction for cryptographic systems, while retaining -//! the speed and safety benefits of an Edwards curve. More details +//! the speed and safety benefits of an Edwards curve. +//! +//! Decaf is named “after the procedure which divides the effect of +//! coffee by \\(4\\)”. However, Curve25519 has a cofactor of +//! \\(8\\). To eliminate its cofactor, Ristretto restricts further; +//! this [additional restriction][ristretto_coffee] gives the +//! _Ristretto_ encoding. +//! +//! More details //! are described in the *Implementation* section below. Ristretto //! points are provided in `curve25519-dalek` by the `RistrettoPoint` //! struct. @@ -121,19 +131,10 @@ //! a coset is accepted). //! //! Internally, each coset is represented by a curve point; two points -//! may represent the same coset in the same way that two points with -//! different \\(X,Y,Z\\) coordinates may represent the same point. The -//! group operations are carried out using the fast, safe Edwards -//! formulas. -//! -//! The Decaf paper suggests implementing the compression and -//! decompression routines using an isogeny from a Jacobi quartic; for -//! curves of cofactor \\(4\\), this eliminates the cofactor, and -//! explains the name: Decaf is named "after the procedure which divides -//! the effect of coffee by \\(4\\)". However, Curve25519 has a -//! cofactor of \\(8\\). To eliminate its cofactor, we tweak Decaf to -//! restrict further. This [additional restriction][ristretto_coffee] -//! gives the _Ristretto_ encoding. +//! \\( P, Q \\) may represent the same coset in the same way that two +//! points with different \\(X,Y,Z\\) coordinates may represent the +//! same point. The group operations are carried out with no overhead +//! using Edwards formulas. //! //! Notes on the details of the encoding can be found in the //! [`ristretto::notes`][ristretto_notes] submodule of the internal `curve25519-dalek` From c2d409788ab1c08f815eab8b6913f98c423f9b2d Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 27 Mar 2018 17:18:28 -0700 Subject: [PATCH 08/21] Add links, tweak intro --- docs/ristretto-notes.md | 46 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 190a227..7c80c25 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -1,15 +1,25 @@ -Below are some notes on Ristretto, which are *NOT* a full writeup and which may have errors. +Below are some notes on Ristretto, which are not an authoritative +writeup and which may have errors. See also the [Decaf +paper][decaf_paper], the [libdecaf +implementation][ristretto_libdecaf], and the [Sage +script][ristretto_sage]. -# Notes on Ristretto +Decaf constructs a prime-order group from a cofactor-\\(4\\) Edwards +curve by defining an encoding of a related Jacobi quartic, then +transporting the encoding from the Jacobi quartic to the Edwards curve +by means of an isogeny. Ristretto uses a different Jacobi quartic and +a different isogeny, but is otherwise similar. + +These notes only describe Ristretto, and focus on the cofactor-\\(8\\) +case. ## The Jacobi Quartic -The Jacobi quartic is parameterized by \\(e, A\\), and is of the +The Jacobi quartic curve is parameterized by \\(e, A\\), and is of the form $$ \mathcal J\_{e,A} : t\^2 = es\^4 + 2As\^2 + 1, $$ with identity point \\((0,1)\\). For more details on the Jacobi quartic, -see the [Decaf paper](https://eprint.iacr.org/2015/673.pdf) or -[_Jacobi Quartic Curves -Revisited_](https://eprint.iacr.org/2009/312.pdf) by Hisil, Wong, +see the [Decaf paper][decaf_paper] or +[_Jacobi Quartic Curves Revisited_][hwcd_jacobi] by Hisil, Wong, Carter, and Dawson). When \\(e = a\^2\\), \\(\mathcal J\_{e,A}\\) has full @@ -19,10 +29,13 @@ we can write the \\(\mathcal J[2]\\)-coset of a point \\(P = (s,t)\\) as $$ P + \mathcal J[2] = \left\\{ - (s,t), - (-s,-t), - (1/as, -t/as\^2), - (-1/as, t/as\^2) \right\\}. + +(s,t), +(-s,-t), +(1/as, -t/as\^2), +(-1/as, t/as\^2) + +\right\\}. $$ Notice that replacing \\(a\\) by \\(-a\\) just swaps the last two points, so this set does not depend on the choice of \\(a\\). In @@ -42,9 +55,8 @@ The encoding is then the (canonical byte encoding of the) ## The Edwards Curve Our primary internal model for Curve25519 points are the [_Extended -Twisted Edwards Coordinates_](https://eprint.iacr.org/2008/522.pdf) -of Hisil, Wong, Carter, and Dawson. -These correspond to the affine model +Twisted Edwards Coordinates_][hwcd_edwards] of Hisil, Wong, Carter, +and Dawson. These correspond to the affine model $$\mathcal E\_{a,d} : ax\^2 + y\^2 = 1 + dx\^2y\^2.$$ @@ -316,3 +328,11 @@ It's possible to do batch encoding of \\( [2]P \\) using the dual isogeny \\(\hat{\theta}\\). Defer this for now. ## ??? + +[ristretto_sage]: https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/aux/ristretto/ristretto.sage +[ristretto_libdecaf]: https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/ +[decaf_paper]: https://eprint.iacr.org/2015/673.pdf +[hwcd_jacobi]: https://eprint.iacr.org/2009/312.pdf +[hwcd_edwards]: https://eprint.iacr.org/2008/522.pdf +[edwards_edwards]: https://www.ams.org/journals/bull/2007-44-03/S0273-0979-07-01153-6/S0273-0979-07-01153-6.pdf +[twisted_edwards]: https://eprint.iacr.org/2008/013.pdf \ No newline at end of file From 83c3d976516b1070a12535fb1300fdaff41a343f Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 11:29:36 -0700 Subject: [PATCH 09/21] clarify wording --- docs/ristretto-notes.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 7c80c25..b558b74 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -1,7 +1,7 @@ Below are some notes on Ristretto, which are not an authoritative writeup and which may have errors. See also the [Decaf paper][decaf_paper], the [libdecaf -implementation][ristretto_libdecaf], and the [Sage +implementation of Ristretto][ristretto_libdecaf], and its [Sage script][ristretto_sage]. Decaf constructs a prime-order group from a cofactor-\\(4\\) Edwards @@ -22,19 +22,17 @@ see the [Decaf paper][decaf_paper] or [_Jacobi Quartic Curves Revisited_][hwcd_jacobi] by Hisil, Wong, Carter, and Dawson). -When \\(e = a\^2\\), \\(\mathcal J\_{e,A}\\) has full +When \\(e = a\^2\\) is a square, \\(\mathcal J\_{e,A}\\) has full \\(2\\)-torsion (i.e., \\(\mathcal J[2] \cong \mathbb Z /2 \times \mathbb Z/2\\)), and we can write the \\(\mathcal J[2]\\)-coset of a point \\(P = (s,t)\\) as $$ P + \mathcal J[2] = \left\\{ - (s,t), (-s,-t), (1/as, -t/as\^2), (-1/as, t/as\^2) - \right\\}. $$ Notice that replacing \\(a\\) by \\(-a\\) just swaps the last two From 862dd33695c53123ba937771ac80d4f1e1c82cfb Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 11:30:35 -0700 Subject: [PATCH 10/21] Add link to curve models --- docs/ristretto-notes.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index b558b74..f88979e 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -52,20 +52,23 @@ The encoding is then the (canonical byte encoding of the) ## The Edwards Curve -Our primary internal model for Curve25519 points are the [_Extended -Twisted Edwards Coordinates_][hwcd_edwards] of Hisil, Wong, Carter, -and Dawson. These correspond to the affine model - -$$\mathcal E\_{a,d} : ax\^2 + y\^2 = 1 + dx\^2y\^2.$$ - +The primary internal model in `curve25519-dalek` for Curve25519 points +is the [_Extended Twisted Edwards Coordinates_][hwcd_edwards] of +Hisil, Wong, Carter, and Dawson. These correspond to the affine model +$$ +\mathcal E\_{a,d} : ax\^2 + y\^2 = 1 + dx\^2y\^2. +$$ In projective coordinates, we represent a point as \\((X:Y:Z:T)\\) -with $$XY = ZT, \quad aX\^2 + Y\^2 = Z\^2 + dT\^2.$$ (For more -details on this model, see the documentation for the `edwards` -module). The case \\(a = 1\\) is the _untwisted_ case; we only -consider \\(a = \pm 1\\), and in particular we focus on the twisted -Edwards form of Curve25519, which has \\(a = -1, d = --121665/121666\\). When not otherwise specified, we write -\\(\mathcal E\\) for \\(\mathcal E\_{-1, -121665/121666}\\). +with +$$ +XY = ZT, \quad aX\^2 + Y\^2 = Z\^2 + dT\^2. +$$ +(For more details on this model, see the +[`curve_models`][curve_models] documentation). The case \\(a = 1\\) is +the _untwisted_ case; we only consider \\(a = \pm 1\\), and in +particular we focus on the twisted Edwards form of Curve25519, which +has \\(a = -1, d = -121665/121666\\). When not otherwise specified, +we write \\(\mathcal E\\) for \\(\mathcal E\_{-1, -121665/121666}\\). When both \\(d\\) and \\(ad\\) are nonsquare (which forces \\(a\\) to be square), the curve is *complete*. In this case the @@ -333,4 +336,5 @@ isogeny \\(\hat{\theta}\\). Defer this for now. [hwcd_jacobi]: https://eprint.iacr.org/2009/312.pdf [hwcd_edwards]: https://eprint.iacr.org/2008/522.pdf [edwards_edwards]: https://www.ams.org/journals/bull/2007-44-03/S0273-0979-07-01153-6/S0273-0979-07-01153-6.pdf -[twisted_edwards]: https://eprint.iacr.org/2008/013.pdf \ No newline at end of file +[twisted_edwards]: https://eprint.iacr.org/2008/013.pdf +[curve_models]: ../../curve_models/index.html \ No newline at end of file From 3f68349480fd9f8bb72fbd1ae5c720f5da7192b2 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 17:40:37 -0700 Subject: [PATCH 11/21] Fix whitespace characters --- docs/ristretto-notes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index f88979e..2305b4f 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -75,19 +75,19 @@ to be square), the curve is *complete*. In this case the four-torsion subgroup is cyclic, and we can write it explicitly as $$ -\mathcal E\_{a,d}[4] = \\{ (0,1),\; (1/\sqrt a, 0),\; (0, -1),\; (-1/\sqrt{a}, 0)\\}. +\mathcal E\_{a,d}[4] = \\{ (0,1),\\; (1/\sqrt a, 0),\\; (0, -1),\\; (-1/\sqrt{a}, 0)\\}. $$ These are the only points with \\(xy = 0\\); the points with \\( y \neq 0 \\) are \\(2\\)-torsion. The \\(\mathcal E\_{a,d}[4]\\)-coset of \\(P = (x,y)\\) is then $$ -P + \mathcal E\_{a,d}[4] = \\{ (x,y),\; (y/\sqrt a, -x\sqrt a),\; (-x, -y),\; (-y/\sqrt a, x\sqrt a)\\}. +P + \mathcal E\_{a,d}[4] = \\{ (x,y),\\; (y/\sqrt a, -x\sqrt a),\\; (-x, -y),\\; (-y/\sqrt a, x\sqrt a)\\}. $$ Notice that if \\(xy \neq 0 \\), then exactly two of these points have \\( xy \\) non-negative, and they differ by the \\(2\\)-torsion point \\( (0,-1) \\). This means that we can select -a representative modulo \\(\mathcal -E\_{a,d}[2] \\) by requiring \\(xy\\) nonnegative and \\(y \neq +a representative modulo \\(\mathcal E\_{a,d}[2] \\) +by requiring \\(xy\\) nonnegative and \\(y \neq 0\\), and we can ensure this condition by conditionally adding a \\(4\\)-torsion point if \\(xy\\) is negative or \\(y = 0\\). From 25024a63bc32cd0ab0a5f35ce8697497cd3fc337 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 17:41:37 -0700 Subject: [PATCH 12/21] Add dual isogeny --- docs/ristretto-notes.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 2305b4f..b0e1610 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -118,8 +118,14 @@ $$ $$ \theta\_{a,d} : (s,t) \mapsto \left( \frac{1}{\sqrt{ad-1}} \cdot \frac{2s}{t},\quad \frac{1+as\^2}{1-as\^2} \right). $$ - -XXX Its dual is ... ? +Its dual is +$$ +\hat{\theta}\_{a,d} : \mathcal E\_{a,d} \longrightarrow \mathcal J\_{a\^2, -a(a+d)/(a-d)}, +$$ +defined by +$$ +\hat{\theta}\_{a,d} : (x,y) \mapsto \left( \sqrt{ad-1} \cdot \frac{xy}{1-ax\^2}, \frac{y^2 + ax^2}{1-ax^2} \right) +$$ The kernel of the isogeny is \\( \{(0, \pm 1)\} \\). The image of the isogeny is \\(\[2\](\mathcal E)\\). To see this, @@ -134,10 +140,12 @@ $$ $$ To determine the image \\(\theta(\mathcal J[2])\\) of the -\\(2\\)-torsion, we consider the image of the coset \\(\theta((s,t) -+ \mathcal J[2])\\). Let \\((x,y) = \theta(s,t)\\); then -\\(\theta(-s,-t) = (x,y)\\) and \\(\theta(1/as, -t/as\^2) = (-x, --y)\\), so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). +\\(2\\)-torsion, we consider the image of the coset +\\(\theta((s,t) + \mathcal J[2])\\). +Let \\((x,y) = \theta(s,t)\\); then +\\(\theta(-s,-t) = (x,y)\\) and +\\(\theta(1/as, -t/as\^2) = (-x, -y)\\), +so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). The Decaf paper recalls that, for a group \\( G \\) with normal subgroup \\(G' \leq G\\), a group homomorphism \\( \phi : G From fbee5e252c2e14e4c2f23a724691481e1977ff88 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 17:42:10 -0700 Subject: [PATCH 13/21] Split explanation of encoding formulas --- docs/ristretto-notes.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index b0e1610..cdc919e 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -179,10 +179,10 @@ apply the encoding for \\( \[2\](\mathcal E) / \mathcal E[2] \\). ## The Ristretto Encoding -We can write the above encoding/decoding procedure concretely (in affine -coordinates) as follows: +We can write the above encoding/decoding procedure in affine +coordinates as follows: -### Encoding +### Encoding in Affine Coordinates On input \\( (x,y) \in \[2\](\mathcal E)\\), a representative for a coset in \\( \[2\](\mathcal E) / \mathcal E[4] \\): @@ -203,8 +203,12 @@ If \\(\mathcal E\\) has cofactor \\(4\\), we skip the first step, since our input already represents a coset in \\( \[2\](\mathcal E) / \mathcal E[2] \\). -To see that this corresponds to the encoding procedure above, notice -that the first step lifts from \\( \mathcal E / \mathcal E[4] \\) to +### Interpreting the Encoding Procedure + +How does this procedure correspond to the description involving +\\( \theta \\)? + +The first step lifts from \\( \mathcal E / \mathcal E[4] \\) to \\(\mathcal E / \mathcal E[2]\\). To understand steps 2 and 3, notice that the \\(y\\)-coordinate of \\(\theta(s,t)\\) is $$ @@ -232,7 +236,7 @@ sign (by choosing the positive square root). Finally, the check that \\(y \neq -1\\) prevents division-by-zero when encoding the identity; it falls out of the optimized formulas below. -### Decoding +### Decoding to Affine Coordinates On input `s_bytes`, decoding proceeds as follows: From 34a6de83e09a665db8595f50e1cef5a5c6c6073a Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 18:25:02 -0700 Subject: [PATCH 14/21] Split out torquing section to cover cof=4 case better --- docs/ristretto-notes.md | 75 ++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index cdc919e..9191f59 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -68,7 +68,7 @@ $$ the _untwisted_ case; we only consider \\(a = \pm 1\\), and in particular we focus on the twisted Edwards form of Curve25519, which has \\(a = -1, d = -121665/121666\\). When not otherwise specified, -we write \\(\mathcal E\\) for \\(\mathcal E\_{-1, -121665/121666}\\). +we write \\(\mathcal E\\) for \\(\mathcal E\_{a,d}\\). When both \\(d\\) and \\(ad\\) are nonsquare (which forces \\(a\\) to be square), the curve is *complete*. In this case the @@ -77,37 +77,62 @@ can write it explicitly as $$ \mathcal E\_{a,d}[4] = \\{ (0,1),\\; (1/\sqrt a, 0),\\; (0, -1),\\; (-1/\sqrt{a}, 0)\\}. $$ -These are the only points with \\(xy = 0\\); the points with \\( y -\neq 0 \\) are \\(2\\)-torsion. The \\(\mathcal -E\_{a,d}[4]\\)-coset of \\(P = (x,y)\\) is then +These are the only points with \\(xy = 0\\); the points with +\\( y \neq 0 \\) are \\(2\\)-torsion. + +We consider two cases: + +* cofactor \\(4\\), where \\( \\# \mathcal E(\mathbb F_p) = 4\cdot \ell \\); +* cofactor \\(8\\) with cyclic \\(8\\)-torsion, where \\( \\# \mathcal E(\mathbb F_p) = 8 \cdot \ell \\) and \\( \mathcal E[8] \cong \mathbb Z / 8 \\). + +In the cofactor \\(4\\) case, we have \\( \[2\](\mathcal E[4]) = +\mathcal E[2] \\), so that \\( \mathcal E[2] \subseteq \[2\](\mathcal +E) \\), and the group we will construct is +$$ +\frac{\[2\](\mathcal E)}{\mathcal E[2]} +$$ +which has prime order \\( (4\ell/2)/2 = \ell \\). + +In the cofactor \\(8\\) case, since the \\(8\\)-torsion is cyclic, we +have \\( \[2\](\mathcal E[8]) = \mathcal E[4] \\), so that \\(\mathcal +E[4] \subseteq \[2\](\mathcal E)\\), and the group we will construct +is +$$ +\frac{\[2\](\mathcal E)}{\mathcal E[4]} +$$ +which has prime order \\( (8\ell/2)/4 = \ell \\). + +In particular, Curve25519 has \\( \mathcal E(\mathbb +F\_p) \cong \mathbb Z / 8 \times \mathbb Z / \ell\\), where \\( \ell += 2\^{252} + \cdots \\) is a large prime, and meets the requirements +for the cofactor \\(8\\) case. + +## Torquing points to lift from \\(\mathcal E[4]\\) to \\(\mathcal E[2]\\) + +To bridge the gap between the cofactor \\(4\\) and cofactor \\(8\\) +cases, we need a way to canonically select a representative modulo +\\(\mathcal E[2] \\), given a representative modulo \\(\mathcal E[4] \\). + +Using the description of \\(\mathcal E[4]\\) above, we can write the +\\(\mathcal E[4]\\)-coset of a point \\(P = (x,y)\\) as $$ P + \mathcal E\_{a,d}[4] = \\{ (x,y),\\; (y/\sqrt a, -x\sqrt a),\\; (-x, -y),\\; (-y/\sqrt a, x\sqrt a)\\}. $$ -Notice that if \\(xy \neq 0 \\), then exactly two of -these points have \\( xy \\) non-negative, and they differ by the -\\(2\\)-torsion point \\( (0,-1) \\). This means that we can select -a representative modulo \\(\mathcal E\_{a,d}[2] \\) -by requiring \\(xy\\) nonnegative and \\(y \neq -0\\), and we can ensure this condition by conditionally adding a -\\(4\\)-torsion point if \\(xy\\) is negative or \\(y = 0\\). +Notice that if \\(xy \neq 0 \\), then exactly two of these points have +\\( xy \\) non-negative, and they differ by the \\(2\\)-torsion point +\\( (0,-1) \\). This means that we can select a representative modulo +\\(\mathcal E[2]\\) by requiring \\(xy\\) nonnegative and \\(y \neq +0\\), and we can ensure that this condition holds by conditionally +adding a \\(4\\)-torsion point \\(T_4\\) if \\(xy\\) is negative or +\\(y = 0\\). + +Convenient choices for \\( T_4 \\) are \\((1,0)\\) when +\\( a = 1 \\) and \\( (i, 0) \\) when \\( a = -1 \\). This procedure gives a canonical lift from \\(\mathcal E / \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\). Since it involves a conditional rotation, we refer to it as *torquing* the point. -The structure of the Curve25519 group is \\( \mathcal E(\mathbb -F\_p) \cong \mathbb Z / 8 \times \mathbb Z / \ell\\), where \\( \ell -= 2\^{252} + \cdots \\) is a large prime. Because \\(\mathcal E[8] -\cong \mathbb Z / 8\\), we have \\(\[2\](\mathcal E[8]) = \mathcal -E[4]\\), \\(\mathcal E[4] \cong \mathbb Z / 4 -\\) and \\( \mathcal E[2] \cong \mathbb Z / 2\\). In particular -this tells us that the group -$$ -\frac{\[2\](\mathcal E)}{\mathcal E[4]} -$$ -is well-defined and has prime order \\( (8\ell / 2) / 4 = \ell \\). -This is the group we will construct using Ristretto. - ## The Isogeny For \\(a = \pm 1\\), we have a \\(2\\)-isogeny @@ -147,6 +172,8 @@ Let \\((x,y) = \theta(s,t)\\); then \\(\theta(1/as, -t/as\^2) = (-x, -y)\\), so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). +## Encoding with the Isogeny + The Decaf paper recalls that, for a group \\( G \\) with normal subgroup \\(G' \leq G\\), a group homomorphism \\( \phi : G \rightarrow H \\) induces a homomorphism From 538539985446d3168c168eef7bd34e96f2c82831 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 4 Apr 2018 18:26:56 -0700 Subject: [PATCH 15/21] Use Q_4 instead of T_4 T_4 is nicer because it sounds like "torsion", but T is also used as a variable in ext. coordinates, so Q is better overall since it avoids conflicts later. --- docs/ristretto-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 9191f59..87b6b71 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -123,10 +123,10 @@ Notice that if \\(xy \neq 0 \\), then exactly two of these points have \\( (0,-1) \\). This means that we can select a representative modulo \\(\mathcal E[2]\\) by requiring \\(xy\\) nonnegative and \\(y \neq 0\\), and we can ensure that this condition holds by conditionally -adding a \\(4\\)-torsion point \\(T_4\\) if \\(xy\\) is negative or +adding a \\(4\\)-torsion point \\(Q_4\\) if \\(xy\\) is negative or \\(y = 0\\). -Convenient choices for \\( T_4 \\) are \\((1,0)\\) when +Convenient choices for \\( Q_4 \\) are \\((1,0)\\) when \\( a = 1 \\) and \\( (i, 0) \\) when \\( a = -1 \\). This procedure gives a canonical lift from \\(\mathcal E / \mathcal From b7132748909e2f590fcb22f91f12cb0f6050b478 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 13:50:15 -0700 Subject: [PATCH 16/21] Describe encoding better and more generally --- docs/ristretto-notes.md | 139 +++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 45 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 87b6b71..45bcf83 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -120,14 +120,18 @@ P + \mathcal E\_{a,d}[4] = \\{ (x,y),\\; (y/\sqrt a, -x\sqrt a),\\; (-x, -y),\\; $$ Notice that if \\(xy \neq 0 \\), then exactly two of these points have \\( xy \\) non-negative, and they differ by the \\(2\\)-torsion point -\\( (0,-1) \\). This means that we can select a representative modulo +\\( (0,-1) \\). + +This means that we can select a representative modulo \\(\mathcal E[2]\\) by requiring \\(xy\\) nonnegative and \\(y \neq 0\\), and we can ensure that this condition holds by conditionally adding a \\(4\\)-torsion point \\(Q_4\\) if \\(xy\\) is negative or \\(y = 0\\). -Convenient choices for \\( Q_4 \\) are \\((1,0)\\) when -\\( a = 1 \\) and \\( (i, 0) \\) when \\( a = -1 \\). +The points of exact order \\(4\\) are \\( (\pm 1/\sqrt{a}, 0 )\\); +convenient choices for \\( Q_4 \\) are \\((1,0)\\) when \\( a = 1 \\) +and \\( (i, 0) \\) when \\( a = -1 \\), although the choice of which +\\(4\\)-torsion point to use doesn't matter. This procedure gives a canonical lift from \\(\mathcal E / \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\). Since it involves a @@ -207,7 +211,8 @@ apply the encoding for \\( \[2\](\mathcal E) / \mathcal E[2] \\). ## The Ristretto Encoding We can write the above encoding/decoding procedure in affine -coordinates as follows: +coordinates, before describing optimized formulas to and from +projective coordinates. ### Encoding in Affine Coordinates @@ -215,8 +220,8 @@ On input \\( (x,y) \in \[2\](\mathcal E)\\), a representative for a coset in \\( \[2\](\mathcal E) / \mathcal E[4] \\): 1. Check if \\( xy \\) is negative or \\( x = 0 \\); if so, torque - the point by setting \\( (x,y) \gets (x,y) + P_4 \\), where - \\(P_4\\) is a \\(4\\)-torsion point. + the point by setting \\( (x,y) \gets (x,y) + Q_4 \\), where + \\(Q_4\\) is a \\(4\\)-torsion point. 2. Check if \\(x\\) is negative or \\( y = -1 \\); if so, set \\( (x,y) \gets (x,y) + (0,-1) = (-x, -y) \\). @@ -291,70 +296,114 @@ not exist. The formulas above are given in affine coordinates, but the usual internal representation is extended twisted Edwards coordinates \\( (X:Y:Z:T) \\) with \\( x = X/Z \\), \\(y = Y/Z\\), \\(xy = T/Z \\). -Selecting the distinguished representative of the coset + +This section only covers the cofactor-\\(8\\) case, since it is more complicated: +selecting the distinguished representative of the coset requires the affine coordinates \\( (x,y) \\), and computing \\( s \\) requires an inverse square root. As inversions are expensive, we'd like to be able to do this whole computation with only one inverse square root, by batching together the inversion and the inverse square root. -However, it is not obvious how to do this, since the inverse square -root computation depends on the affine coordinates (which select the -distinguished representative). +It is not obvious how to do this, since we need the inverse square +root of one of two values, depending on what the distinguished +representative is, but the choice of representative depends on the +affine coordinates. However, an ingenious trick (due to Mike Hamburg) +allows recovering either of the inverse square roots we want. -In what follows we consider only the case -\\(a = -1\\); a similar argument applies to the case \\( a = 1\\). +### Batching the Inversion and Inverse Square Root + +Write \\( (X\_0 : Y\_0 : Z\_0 : T\_0) \\) +for the coordinates of the initial representative, and write +\\( (X:Y:Z:T) \\) for the coordinates of the distinguished +representative of the coset. Since \\(y = Y/Z\\), in extended coordinates the formula for \\(s\\) becomes $$ -s = \sqrt{ \frac{ 1 - Y/Z}{1+Y/Z}} = \sqrt{\frac{Z - Y}{Z+Y}} -= \frac {Z - Y} {\sqrt{Z\^2 - Y\^2}}. +s += \sqrt{ (-a) \frac{ 1 - Y/Z}{1+Y/Z}} = \sqrt{\frac{Z - Y}{Z+Y}} \sqrt{-a} += \frac {Z - Y} {\sqrt{Z\^2 - Y\^2}} \sqrt{-a}, $$ +so we need to compute \\( 1 / \sqrt{Z^2 - Y^2} \\). -Here \\( (X:Y:Z:T) \\) are the coordinates of the distinguished -representative of the coset. -Write \\( (X\_0 : Y\_0 : Z\_0 : T\_0) \\) -for the coordinates of the initial representative. Then the -torquing procedure in step 1 replaces \\( (X\_0 : Y\_0 : Z\_0 : -T\_0) \\) by \\( (iY\_0 : iX\_0 : Z\_0 : -T\_0) \\). This means we -want to obtain either +The distinguished representative \\( (X:Y:Z:T) \\) is selected by the +torquing procedure in step 1, which conditionally adds a +\\(4\\)-torsion point \\(Q_4\\). As noted in the torquing section +above, \\( Q_4 = (\pm 1/\sqrt{a}, 0) \\), so we obtain $$ -\frac {1} { \sqrt{Z\_0\^2 - Y\_0\^2}} -\quad \text{or} \quad -\frac {1} { \sqrt{Z\_0\^2 + X\_0\^2}}. +(X : Y : Z : T ) = +\begin{cases} +(X\_0 : Y\_0 : Z\_0 : T\_0) \\\\ +(\pm Y\_0 / \sqrt{a} : \mp X\_0 \sqrt{a} : Z\_0 : -T\_0) +\end{cases} +. $$ - -We can relate these using the identity +This means we want to compute either of $$ -(a-d)X\^2Y\^2 = (Z\^2 - aX\^2)(Z\^2 - Y\^2), +\frac {1} {\sqrt{Z^2 - Y^2}} += +\begin{cases} +1 / \sqrt{Z\_0^2 - Y\_0^2} \\\\ +1 / \sqrt{Z\_0^2 - aX\_0^2} +\end{cases} +. $$ -which is valid for all curve points. To see this, recall from the curve equation that +To relate these quantities, recall from the curve equation that $$ -dX\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2, $$ -so that +so $$ -(a-d)X\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2 + aX\^2Y\^2 = (Z\^2 - Y\^2)(Z\^2 + X\^2). +(a-d)X\^2Y\^2 = Z\^4 - aZ\^2X\^2 - Z\^2Y\^2 + aX\^2Y\^2. +$$ +Factoring the right-hand side gives +$$ +(a-d)X\^2Y\^2 = (Z\^2 - Y\^2)(Z\^2 - aX\^2), +$$ +which relates the two quantities we want to compute: +$$ +\frac 1 {Z^2 - aX^2} = \frac 1 {a - d} \frac {Z^2 - Y^2} {X^2 Y^2} +$$ +so +$$ +\frac 1 {\sqrt{Z^2 - aX^2}} = \frac 1 {\sqrt{a - d}} \sqrt{ \frac {Z^2 - Y^2} {X^2 Y^2} } $$ -The encoding procedure is as follows: +### Explicit Encoding Formulas -1. \\(u\_1 \gets (Z\_0 + Y\_0)(Z\_0 - Y\_0) = Z\_0\^2 - Y\_0\^2 \\) +Using this trick, we can write the encoding procedure explicitly: + +1. \\(u\_1 \gets (Z\_0 + Y\_0)(Z\_0 - Y\_0) + \textcolor{gray}{= Z\_0\^2 - Y\_0\^2} + \\) 2. \\(u\_2 \gets X\_0 Y\_0 \\) -3. \\(I \gets \mathrm{invsqrt}(u\_1 u\_2\^2) = 1/\sqrt{X\_0\^2 Y\_0\^2 (Z\_0\^2 - Y\_0\^2)} \\) -4. \\(D\_1 \gets u\_1 I = \sqrt{(Z\_0\^2 - Y\_0\^2)/(X\_0\^2 Y\_0\^2)} \\) -5. \\(D\_2 \gets u\_2 I = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) -6. \\(Z\_{inv} \gets D\_1 D\_2 T\_0 = (u\_1 u\_2)/(u\_1 u\_2\^2) T\_0 = T\_0 / X\_0 Y\_0 = 1/Z\_0 \\) -7. If \\( T\_0 Z\_{inv} = x\_0 y\_0 \\) is negative: - 1. \\( X \gets iY\_0 \\) - 2. \\( Y \gets iX\_0 \\) - 3. \\( D \gets D\_1 / \sqrt{a-d} = 1/\sqrt{Z\_0\^2 + X\_0\^2} \\) +3. \\(I \gets \mathrm{invsqrt}(u\_1 u\_2\^2) + \textcolor{gray}{= 1/\sqrt{X\_0\^2 Y\_0\^2 (Z\_0\^2 - Y\_0\^2)}} + \\) +4. \\(D\_1 \gets u\_1 I + \textcolor{gray}{= \sqrt{(Z\_0\^2 - Y\_0\^2)/(X\_0\^2 Y\_0\^2)} } + \\) +5. \\(D\_2 \gets u\_2 I + \textcolor{gray}{= \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} } + \\) +6. \\(Z\_{inv} \gets D\_1 D\_2 T\_0 + \textcolor{gray}{= (u\_1 u\_2)/(u\_1 u\_2\^2) T\_0 = T\_0 / X\_0 Y\_0 = 1/Z\_0} + \\) +7. If \\( T\_0 Z\_{inv} \textcolor{gray}{= x\_0 y\_0 }\\) is negative: + 1. \\( (X, Y) \gets (Y\_0 (\pm 1/\sqrt{a}), X\_0 (\mp \sqrt{a})) \\) + 2. \\( D \gets D\_1 / \sqrt{a-d} + \textcolor{gray}{= 1/\sqrt{Z\_0\^2 - a X\_0\^2} = 1/\sqrt{Z^2 -Y^2} } + \\) 8. Otherwise: - 1. \\( X \gets X\_0 \\) - 2. \\( Y \gets Y\_0 \\) - 3. \\( D \gets D\_2 = \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} \\) -9. If \\( X Z\_{inv} = x \\) is negative, set \\( Y \gets - Y\\) -10. Compute \\( s \gets (Z - Y) D = (Z - Y) / \sqrt{Z\^2 - Y\^2} \\) and return. + 1. \\( (X, Y) \gets (X\_0, Y\_0) \\) + 2. \\( D \gets D\_2 + \textcolor{gray}{= \pm \sqrt{1/(Z\_0\^2 - Y\_0\^2)} = \pm 1/\sqrt{Z^2 - Y^2}} + \\) +9. If \\( X Z\_{inv} \textcolor{gray}{= x} \\) is negative, set \\( Y \gets - Y\\) +10. Compute \\( s \gets |\sqrt{-a} (Z - Y) D| \textcolor{gray}{= |\sqrt{-a} (Z - Y) / \sqrt{Z\^2 - Y\^2}| } \\) +11. Return the canonical byte encoding of \\( s \\). + +The choice of \\( Q\_4 = (i, 0) \\) when \\( a = -1 \\) is convenient since it simplifies 7.1 to \\( (X,Y) \gets (iY_0, iX_0) \\). ## Decoding to Extended Coordinates From 35c18cfc51181df8f35e56a76293642177ce3e23 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 14:00:23 -0700 Subject: [PATCH 17/21] Stub out remaining sections, add overview of batching --- docs/ristretto-notes.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 45bcf83..8f811d0 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -407,16 +407,25 @@ The choice of \\( Q\_4 = (i, 0) \\) when \\( a = -1 \\) is convenient since it s ## Decoding to Extended Coordinates +## Batched Double-and-Encode Using \\( \hat \theta \\) + +The encoding is not batchable, since it requires an inverse square +root. However, since \\( \theta \circ \hat \theta = [2] P \\), it's +possible to compute the encoding of \\( [2]P \\) by using \\( \hat +\theta \\) instead of \\( \theta^{-1} \\). Since \\( \hat \theta \\) only +requires inversions, given \\( P\_1, \ldots, P\_n \\), it's possible +to compute the encodings of \\( [2]P\_1, \ldots, [2]P\_n \\) in a +batch. + +XXX write up details + ## Equality Testing +XXX write up details + ## Elligator -## The Double-Ristretto Encoding - -It's possible to do batch encoding of \\( [2]P \\) using the dual -isogeny \\(\hat{\theta}\\). Defer this for now. - -## ??? +XXX write up details [ristretto_sage]: https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/aux/ristretto/ristretto.sage [ristretto_libdecaf]: https://sourceforge.net/p/ed448goldilocks/code/ci/master/tree/ From f446ea82e0a0556fa599a81328e053c95bba3cd9 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 14:41:58 -0700 Subject: [PATCH 18/21] Explicit decoding formulas --- docs/ristretto-notes.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 8f811d0..6da7ef1 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -403,9 +403,32 @@ Using this trick, we can write the encoding procedure explicitly: 10. Compute \\( s \gets |\sqrt{-a} (Z - Y) D| \textcolor{gray}{= |\sqrt{-a} (Z - Y) / \sqrt{Z\^2 - Y\^2}| } \\) 11. Return the canonical byte encoding of \\( s \\). -The choice of \\( Q\_4 = (i, 0) \\) when \\( a = -1 \\) is convenient since it simplifies 7.1 to \\( (X,Y) \gets (iY_0, iX_0) \\). +The choice of \\( Q\_4 = (i, 0) \\) when \\( a = -1 \\) is convenient +since it simplifies 7.1 to \\( (X,Y) \gets (iY_0, iX_0) \\). -## Decoding to Extended Coordinates +### Explicit Decoding Formulas + +As with encoding, we want to batch operations to use only a single +inverse square root. However, the procedure is much simpler since +there's no torquing. + +On input `s_bytes`: + +1. Check that `s_bytes` is the canonical byte-encoding of a field +element \\(s\\), otherwise reject. +2. Decode `s_bytes` to \\(s\\). +3. Check that \\( s \\) is nonnegative, otherwise reject. +4. \\( u_1 \gets 1 + as^2 \\) +5. \\( u_2 \gets 1 - as^2 \\) +6. \\( v \gets (ad)u_1^2 - u_2^2 \textcolor{gray}{= ad(1+as^2)^2 - (1-as^2)^2} \\) +7. \\( I \gets \mathrm{invsqrt}( v u_2^2 ) \textcolor{gray}{= 1/\sqrt{v u_2^2} } \\) +8. \\( D_x \gets Iu_2 \textcolor{gray}{= 1/\sqrt{v} } \\) +9. \\( D_y \gets ID_x v \textcolor{gray}{= I^2 u_2 v = (v u_2) / (v u_2^2) = 1/u_2 } \\) +10. \\( x \gets |2sD_x| \textcolor{gray}{= +\sqrt{ 4s^2 / (ad(1+as^2)^2 - (1-as^2)^2 )}}\\) +11. \\( y \gets u_1 D_y \textcolor{gray}{= (1+as^2)/(1-as^2) } \\) +12. \\( t \gets xy \\) +12. Check that \\(t \\) is nonnegative and that \\( y \neq 0 \\), otherwise reject. +13. Return \\( P = (x: y: 1: t) \\) ## Batched Double-and-Encode Using \\( \hat \theta \\) From dbca3736394f19ec76fe4ee20e2c6f3ed3b4e046 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 14:43:07 -0700 Subject: [PATCH 19/21] Promote headers --- docs/ristretto-notes.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 6da7ef1..150cd9a 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -13,7 +13,7 @@ a different isogeny, but is otherwise similar. These notes only describe Ristretto, and focus on the cofactor-\\(8\\) case. -## The Jacobi Quartic +# The Jacobi Quartic The Jacobi quartic curve is parameterized by \\(e, A\\), and is of the form $$ \mathcal J\_{e,A} : t\^2 = es\^4 + 2As\^2 + 1, $$ with @@ -39,7 +39,7 @@ Notice that replacing \\(a\\) by \\(-a\\) just swaps the last two points, so this set does not depend on the choice of \\(a\\). In what follows we require \\(a = \pm 1\\). -## Encoding \\(\mathcal J / \mathcal J[2]\\) +# Encoding \\(\mathcal J / \mathcal J[2]\\) To encode points on \\(\mathcal J\\) modulo \\(\mathcal J[2]\\), we need to choose a canonical representative of the above coset. @@ -50,7 +50,7 @@ non-negative and finite, and \\(t/s\\) non-negative or infinite. The encoding is then the (canonical byte encoding of the) \\(s\\)-value of the canonical representative. -## The Edwards Curve +# The Edwards Curve The primary internal model in `curve25519-dalek` for Curve25519 points is the [_Extended Twisted Edwards Coordinates_][hwcd_edwards] of @@ -107,7 +107,7 @@ F\_p) \cong \mathbb Z / 8 \times \mathbb Z / \ell\\), where \\( \ell = 2\^{252} + \cdots \\) is a large prime, and meets the requirements for the cofactor \\(8\\) case. -## Torquing points to lift from \\(\mathcal E[4]\\) to \\(\mathcal E[2]\\) +# Torquing points to lift from \\(\mathcal E[4]\\) to \\(\mathcal E[2]\\) To bridge the gap between the cofactor \\(4\\) and cofactor \\(8\\) cases, we need a way to canonically select a representative modulo @@ -137,7 +137,7 @@ This procedure gives a canonical lift from \\(\mathcal E / \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\). Since it involves a conditional rotation, we refer to it as *torquing* the point. -## The Isogeny +# The Isogeny For \\(a = \pm 1\\), we have a \\(2\\)-isogeny $$ @@ -176,7 +176,7 @@ Let \\((x,y) = \theta(s,t)\\); then \\(\theta(1/as, -t/as\^2) = (-x, -y)\\), so that \\(\theta(\mathcal J[2]) = \mathcal E[2]\\). -## Encoding with the Isogeny +# Encoding with the Isogeny The Decaf paper recalls that, for a group \\( G \\) with normal subgroup \\(G' \leq G\\), a group homomorphism \\( \phi : G @@ -208,13 +208,13 @@ Curve25519 case, we use the torquing procedure to lift \\(\mathcal E / \mathcal E[4]\\) to \\(\mathcal E / \mathcal E[2]\\), and then apply the encoding for \\( \[2\](\mathcal E) / \mathcal E[2] \\). -## The Ristretto Encoding +# The Ristretto Encoding We can write the above encoding/decoding procedure in affine coordinates, before describing optimized formulas to and from projective coordinates. -### Encoding in Affine Coordinates +## Encoding in Affine Coordinates On input \\( (x,y) \in \[2\](\mathcal E)\\), a representative for a coset in \\( \[2\](\mathcal E) / \mathcal E[4] \\): @@ -235,7 +235,7 @@ If \\(\mathcal E\\) has cofactor \\(4\\), we skip the first step, since our input already represents a coset in \\( \[2\](\mathcal E) / \mathcal E[2] \\). -### Interpreting the Encoding Procedure +## Interpreting the Encoding Procedure How does this procedure correspond to the description involving \\( \theta \\)? @@ -268,7 +268,7 @@ sign (by choosing the positive square root). Finally, the check that \\(y \neq -1\\) prevents division-by-zero when encoding the identity; it falls out of the optimized formulas below. -### Decoding to Affine Coordinates +## Decoding to Affine Coordinates On input `s_bytes`, decoding proceeds as follows: @@ -291,7 +291,7 @@ not exist. 5. Check whether \\(xy\\) is negative or \\(y = 0\\); if so, reject. -## Encoding in Extended Coordinates +# Encoding in Extended Coordinates The formulas above are given in affine coordinates, but the usual internal representation is extended twisted Edwards coordinates \\( @@ -311,7 +311,7 @@ representative is, but the choice of representative depends on the affine coordinates. However, an ingenious trick (due to Mike Hamburg) allows recovering either of the inverse square roots we want. -### Batching the Inversion and Inverse Square Root +## Batching the Inversion and Inverse Square Root Write \\( (X\_0 : Y\_0 : Z\_0 : T\_0) \\) for the coordinates of the initial representative, and write @@ -369,7 +369,7 @@ $$ \frac 1 {\sqrt{Z^2 - aX^2}} = \frac 1 {\sqrt{a - d}} \sqrt{ \frac {Z^2 - Y^2} {X^2 Y^2} } $$ -### Explicit Encoding Formulas +## Explicit Encoding Formulas Using this trick, we can write the encoding procedure explicitly: @@ -406,7 +406,7 @@ Using this trick, we can write the encoding procedure explicitly: The choice of \\( Q\_4 = (i, 0) \\) when \\( a = -1 \\) is convenient since it simplifies 7.1 to \\( (X,Y) \gets (iY_0, iX_0) \\). -### Explicit Decoding Formulas +## Explicit Decoding Formulas As with encoding, we want to batch operations to use only a single inverse square root. However, the procedure is much simpler since @@ -430,7 +430,7 @@ element \\(s\\), otherwise reject. 12. Check that \\(t \\) is nonnegative and that \\( y \neq 0 \\), otherwise reject. 13. Return \\( P = (x: y: 1: t) \\) -## Batched Double-and-Encode Using \\( \hat \theta \\) +# Batched Double-and-Encode Using \\( \hat \theta \\) The encoding is not batchable, since it requires an inverse square root. However, since \\( \theta \circ \hat \theta = [2] P \\), it's @@ -442,11 +442,11 @@ batch. XXX write up details -## Equality Testing +# Equality Testing XXX write up details -## Elligator +# Elligator XXX write up details From 9aa208959d4dba074c7ee6753f5cdbf9f71f74c3 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 14:45:03 -0700 Subject: [PATCH 20/21] split into new Ristretto Group section --- docs/ristretto-notes.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 150cd9a..707c299 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -80,10 +80,14 @@ $$ These are the only points with \\(xy = 0\\); the points with \\( y \neq 0 \\) are \\(2\\)-torsion. +# The Ristretto Group + We consider two cases: * cofactor \\(4\\), where \\( \\# \mathcal E(\mathbb F_p) = 4\cdot \ell \\); -* cofactor \\(8\\) with cyclic \\(8\\)-torsion, where \\( \\# \mathcal E(\mathbb F_p) = 8 \cdot \ell \\) and \\( \mathcal E[8] \cong \mathbb Z / 8 \\). +* cofactor \\(8\\) with cyclic \\(8\\)-torsion, + where \\( \\# \mathcal E(\mathbb F_p) = 8 \cdot \ell \\) + and \\( \mathcal E[8] \cong \mathbb Z / 8 \\). In the cofactor \\(4\\) case, we have \\( \[2\](\mathcal E[4]) = \mathcal E[2] \\), so that \\( \mathcal E[2] \subseteq \[2\](\mathcal From e30d764b7fe33221c7959bf79b461afbf7caf868 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Apr 2018 14:49:59 -0700 Subject: [PATCH 21/21] Add eq testing stub --- docs/ristretto-notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/ristretto-notes.md b/docs/ristretto-notes.md index 707c299..8999137 100644 --- a/docs/ristretto-notes.md +++ b/docs/ristretto-notes.md @@ -448,6 +448,17 @@ XXX write up details # Equality Testing +Testing equality of two Ristretto points means testing whether they +are equal in the quotient group, i.e., whether they lie in the same +coset of \\(\mathcal E[4] \\) (for the cofactor-\\(8\\) case) or +\\(\mathcal E[2] \\) (for the cofactor-\\(4\\) case). + +Equality testing of points on the Edwards curve requires comparing to +affine coordinates, which requires an expensive inversion. However, +testing whether two points lie in the same coset can be done in +projective coordinates, making it actually *easier* than equality +testing in the original non-quotient group. + XXX write up details # Elligator