6. Deterministic Mappings
The mappings in this section are suitable for implementing either nonuniform or uniform encodings using the constructions in Section 3. Certain mappings restrict the form of the curve or its parameters. For each mapping presented, this document lists the relevant restrictions.
Note that mappings in this section are not interchangeable: different mappings will almost certainly output different points when evaluated on the same input.
6.1. Choosing a Mapping Function
This section gives brief guidelines on choosing a mapping function for a given elliptic curve. Note that the suites given in Section 8 are recommended mappings for the respective curves.
If the target elliptic curve is a Montgomery curve (Section 6.7), the Elligator 2 method (Section 6.7.1) is recommended. Similarly, if the target elliptic curve is a twisted Edwards curve (Section 6.8), the twisted Edwards Elligator 2 method (Section 6.8.2) is recommended.
The remaining cases are Weierstrass curves. For curves supported by the Simplified Shallue-van de Woestijne-Ulas (SWU) method (Section 6.6.2), that mapping is the recommended one. Otherwise, the Simplified SWU method for AB == 0 (Section 6.6.3) is recommended if the goal is best performance, while the Shallue-van de Woestijne method (Section 6.6.1) is recommended if the goal is simplicity of implementation. (The reason for this distinction is that the Simplified SWU method for AB == 0 requires implementing an isogeny map in addition to the mapping function, while the Shallue-van de Woestijne method does not.)
The Shallue-van de Woestijne method (Section 6.6.1) works with any curve and may be used in cases where a generic mapping is required. Note, however, that this mapping is almost always more computationally expensive than the curve-specific recommendations above.
6.2. Interface
The generic interface shared by all mappings in this section is as follows:
(x, y) = map_to_curve(u)
The input u and outputs x and y are elements of the field F. The affine coordinates (x, y) specify a point on an elliptic curve defined over F. Note, however, that the point (x, y) is not a uniformly random point.
6.3. Notation
As a rough guide, the following conventions are used in pseudocode:
-
All arithmetic operations are performed over a field F, unless explicitly stated otherwise.
-
u: the input to the mapping function. This is an element of F produced by the hash_to_field function.
-
(x, y), (s, t), (v, w): the affine coordinates of the point output by the mapping. Indexed variables (e.g., x1, y2, ...) are used for candidate values.
-
tv1, tv2, ...: reusable temporary variables.
-
c1, c2, ...: constant values, which can be computed in advance.
6.4. Sign of the Resulting Point
In general, elliptic curves have equations of the form y^2 = g(x). The mappings in this section first identify an x such that g(x) is square, then take a square root to find y. Since there are two square roots when g(x) != 0, this may result in an ambiguity regarding the sign of y.
When necessary, the mappings in this section resolve this ambiguity by specifying the sign of the y-coordinate in terms of the input to the mapping function. Two main reasons support this approach: first, this covers elliptic curves over any field in a uniform way, and second, it gives implementors leeway in optimizing square-root implementations.
6.5. Exceptional Cases
Mappings may have exceptional cases, i.e., inputs u on which the mapping is undefined. These cases must be handled carefully, especially for constant-time implementations.
For each mapping in this section, we discuss the exceptional cases and show how to handle them in constant time. Note that all implementations SHOULD use inv0 (Section 4) to compute multiplicative inverses, to avoid exceptional cases that result from attempting to compute the inverse of 0.
6.6. Mappings for Weierstrass Curves
The mappings in this section apply to a target curve E defined by the equation
y^2 = g(x) = x^3 + A * x + B
where 4 * A^3 + 27 * B^2 != 0.
6.6.1. Shallue-van de Woestijne Method
Shallue and van de Woestijne [SW06] describe a mapping that applies to essentially any elliptic curve. (Note, however, that this mapping is more expensive to evaluate than the other mappings in this document.)
The parameterization given below is for Weierstrass curves; its derivation is detailed in [W19]. This parameterization also works for Montgomery curves (Section 6.7) and twisted Edwards curves (Section 6.8) via the rational maps given in Appendix D: first, evaluate the Shallue-van de Woestijne mapping to an equivalent Weierstrass curve, then map that point to the target Montgomery or twisted Edwards curve using the corresponding rational map.
Preconditions: A Weierstrass curve y^2 = x^3 + A * x + B.
Constants:
-
A and B, the parameter of the Weierstrass curve.
-
Z, a non-zero element of F meeting the below criteria. Appendix H.1 gives a Sage script [SAGE] that outputs the RECOMMENDED Z.
- g(Z) != 0 in F.
- -(3 * Z^2 + 4 * A) / (4 * g(Z)) != 0 in F.
- -(3 * Z^2 + 4 * A) / (4 * g(Z)) is square in F.
- At least one of g(Z) and g(-Z / 2) is square in F.
Sign of y: Inputs u and -u give the same x-coordinate for many values of u. Thus, we set sgn0(y) == sgn0(u).
Exceptions: The exceptional cases for u occur when (1 + u^2 * g(Z)) * (1 - u^2 * g(Z)) == 0. The restrictions on Z given above ensure that implementations that use inv0 to invert this product are exception free.
Operations:
1. tv1 = u^2 * g(Z)
2. tv2 = 1 + tv1
3. tv1 = 1 - tv1
4. tv3 = inv0(tv1 * tv2)
5. tv4 = sqrt(-g(Z) * (3 * Z^2 + 4 * A)) # can be precomputed
6. If sgn0(tv4) == 1, set tv4 = -tv4 # sgn0(tv4) MUST equal 0
7. tv5 = u * tv1 * tv3 * tv4
8. tv6 = -4 * g(Z) / (3 * Z^2 + 4 * A) # can be precomputed
9. x1 = -Z / 2 - tv5
10. x2 = -Z / 2 + tv5
11. x3 = Z + tv6 * (tv2^2 * tv3)^2
12. If is_square(g(x1)), set x = x1 and y = sqrt(g(x1))
13. Else If is_square(g(x2)), set x = x2 and y = sqrt(g(x2))
14. Else set x = x3 and y = sqrt(g(x3))
15. If sgn0(u) != sgn0(y), set y = -y
16. return (x, y)
Appendix F.1 gives an example straight-line implementation of this mapping.
6.6.2. Simplified Shallue-van de Woestijne-Ulas Method
The function map_to_curve_simple_swu(u) implements a simplification of the Shallue-van de Woestijne-Ulas mapping [U07] described by Brier et al. [BCIMRT10], which they call the "simplified SWU" map. Wahby and Boneh [WB19] generalize and optimize this mapping.
Preconditions: A Weierstrass curve y^2 = x^3 + A * x + B where A != 0 and B != 0.
Constants:
-
A and B, the parameters of the Weierstrass curve.
-
Z, an element of F meeting the below criteria. Appendix H.2 gives a Sage script [SAGE] that outputs the RECOMMENDED Z. The criteria are as follows:
- Z is non-square in F,
- Z != -1 in F,
- the polynomial g(x) - Z is irreducible over F, and
- g(B / (Z * A)) is square in F.
Sign of y: Inputs u and -u give the same x-coordinate. Thus, we set sgn0(y) == sgn0(u).
Exceptions: The exceptional cases are values of u such that Z^2 * u^4 + Z * u^2 == 0. This includes u == 0 and may include other values that depend on Z. Implementations must detect this case and set x1 = B / (Z * A), which guarantees that g(x1) is square by the condition on Z given above.
Operations:
1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
2. x1 = (-B / A) * (1 + tv1)
3. If tv1 == 0, set x1 = B / (Z * A)
4. gx1 = x1^3 + A * x1 + B
5. x2 = Z * u^2 * x1
6. gx2 = x2^3 + A * x2 + B
7. If is_square(gx1), set x = x1 and y = sqrt(gx1)
8. Else set x = x2 and y = sqrt(gx2)
9. If sgn0(u) != sgn0(y), set y = -y
10. return (x, y)
Appendix F.2 gives a general and optimized straight-line implementation of this mapping. For more information on optimizing this mapping, see Section 4 of [WB19] or the example code found at [hash2curve-repo].
6.6.3. Simplified SWU for AB == 0
Wahby and Boneh [WB19] show how to adapt the Simplified SWU mapping to Weierstrass curves having A == 0 or B == 0, which the mapping of Section 6.6.2 does not support. (The case A == B == 0 is excluded because y^2 = x^3 is not an elliptic curve.)
This method applies to curves like secp256k1 [SEC2] and to pairing-friendly curves in the Barreto-Lynn-Scott family [BLS03], Barreto-Naehrig family [BN05], and other families.
This method requires finding another elliptic curve E' given by the equation
y'^2 = g'(x') = x'^3 + A' * x' + B'
that is isogenous to E and has A' != 0 and B' != 0. (See [WB19], Appendix A, for one way of finding E' using [SAGE].) This isogeny defines a map iso_map(x', y') given by a pair of rational functions. iso_map takes as input a point on E' and produces as output a point on E.
Once E' and iso_map are identified, this mapping works as follows: on input u, first apply the Simplified SWU mapping to get a point on E', then apply the isogeny map to that point to get a point on E.
Note that iso_map is a group homomorphism, meaning that point addition commutes with iso_map. Thus, when using this mapping in the hash_to_curve construction discussed in Section 3, one can effect a small optimization by first mapping u0 and u1 to E', adding the resulting points on E', and then applying iso_map to the sum. This gives the same result while requiring only one evaluation of iso_map.
Preconditions: An elliptic curve E' with A' != 0 and B' != 0 that is isogenous to the target curve E with isogeny map iso_map from E' to E.
Helper functions:
-
map_to_curve_simple_swu is the mapping of Section 6.6.2 to E'
-
iso_map is the isogeny map from E' to E
Sign of y: For this map, the sign is determined by map_to_curve_simple_swu. No further sign adjustments are necessary.
Exceptions: map_to_curve_simple_swu handles its exceptional cases. Exceptional cases of iso_map are inputs that cause the denominator of either rational function to evaluate to zero; such cases MUST return the identity point on E.
Operations:
1. (x', y') = map_to_curve_simple_swu(u) # (x', y') is on E'
2. (x, y) = iso_map(x', y') # (x, y) is on E
3. return (x, y)
See [hash2curve-repo] or Section 4.3 of [WB19] for details on implementing the isogeny map.
6.7. Mappings for Montgomery Curves
The mapping defined in this section applies to a target curve M defined by the equation
K * t^2 = s^3 + J * s^2 + s
6.7.1. Elligator 2 Method
Bernstein, Hamburg, Krasnova, and Lange give a mapping that applies to any curve with a point of order 2 [BHKL13], which they call Elligator 2.
Preconditions: A Montgomery curve K * t^2 = s^3 + J * s^2 + s where J != 0, K != 0, and (J^2 - 4) / K^2 is non-zero and non-square in F.
Constants:
-
J and K, the parameters of the elliptic curve.
-
Z, a non-square element of F. Appendix H.3 gives a Sage script [SAGE] that outputs the RECOMMENDED Z.
Sign of t: This mapping fixes the sign of t as specified in [BHKL13]. No additional adjustment is required.
Exceptions: The exceptional case is Z * u^2 == -1, i.e., 1 + Z * u^2 == 0. Implementations must detect this case and set x1 = -(J / K). Note that this can only happen when q = 3 (mod 4).
Operations:
1. x1 = -(J / K) * inv0(1 + Z * u^2)
2. If x1 == 0, set x1 = -(J / K)
3. gx1 = x1^3 + (J / K) * x1^2 + x1 / K^2
4. x2 = -x1 - (J / K)
5. gx2 = x2^3 + (J / K) * x2^2 + x2 / K^2
6. If is_square(gx1), set x = x1, y = sqrt(gx1) with sgn0(y) == 1.
7. Else set x = x2, y = sqrt(gx2) with sgn0(y) == 0.
8. s = x * K
9. t = y * K
10. return (s, t)
Appendix F.3 gives an example straight-line implementation of this mapping. Appendix G.2 gives optimized straight-line procedures that apply to specific classes of curves and base fields.
6.8. Mappings for Twisted Edwards Curves
Twisted Edwards curves (a class of curves that includes Edwards curves) are given by the equation
a * v^2 + w^2 = 1 + d * v^2 * w^2
with a != 0, d != 0, and a != d [BBJLP08].
These curves are closely related to Montgomery curves (Section 6.7): every twisted Edwards curve is birationally equivalent to a Montgomery curve ([BBJLP08], Theorem 3.2). This equivalence yields an efficient way of hashing to a twisted Edwards curve: first, hash to an equivalent Montgomery curve, then transform the result into a point on the twisted Edwards curve via a rational map. This method of hashing to a twisted Edwards curve thus requires identifying a corresponding Montgomery curve and rational map. We describe how to identify such a curve and map immediately below.
6.8.1. Rational Maps from Montgomery to Twisted Edwards Curves
There are two ways to select a Montgomery curve and rational map for use when hashing to a given twisted Edwards curve. The selected Montgomery curve and rational map MUST be specified as part of the hash-to-curve suite for a given twisted Edwards curve; see Section 8.
-
When hashing to a standardized twisted Edwards curve for which a corresponding Montgomery form and rational map are also standardized, the standard Montgomery form and rational map SHOULD be used to ensure compatibility with existing software.
In certain cases, e.g., edwards25519 [RFC7748], the sign of the rational map from the twisted Edwards curve to its corresponding Montgomery curve is not given explicitly. In this case, the sign MUST be fixed such that applying the rational map to the twisted Edwards curve's base point yields the Montgomery curve's base point with correct sign. (For edwards25519, see [RFC7748] and [Err4730].)
When defining new twisted Edwards curves, a Montgomery equivalent and rational map SHOULD also be specified, and the sign of the rational map SHOULD be stated explicitly.
-
When hashing to a twisted Edwards curve that does not have a standardized Montgomery form or rational map, the map given in Appendix D SHOULD be used.
6.8.2. Elligator 2 Method
Preconditions: A twisted Edwards curve E and an equivalent Montgomery curve M meeting the requirements in Section 6.8.1.
Helper functions:
-
map_to_curve_elligator2 is the mapping of Section 6.7.1 to the curve M.
-
rational_map is a function that takes a point (s, t) on M and returns a point (v, w) on E. This rational map should be chosen as defined in Section 6.8.1.
Sign of t (and v): For this map, the sign is determined by map_to_curve_elligator2. No further sign adjustments are required.
Exceptions: The exceptions for the Elligator 2 mapping are as given in Section 6.7.1. The exceptions for the rational map are as given in Section 6.8.1. No other exceptions are possible.
The following procedure implements the Elligator 2 mapping for a twisted Edwards curve. (Note that the output point is denoted (v, w) because it is a point on the target twisted Edwards curve.)
map_to_curve_elligator2_edwards(u)
Input: u, an element of F.
Output: (v, w), a point on E.
1. (s, t) = map_to_curve_elligator2(u) # (s, t) is on M
2. (v, w) = rational_map(s, t) # (v, w) is on E
3. return (v, w)