summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc8032.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rfc/rfc8032.txt')
-rw-r--r--doc/rfc/rfc8032.txt3363
1 files changed, 3363 insertions, 0 deletions
diff --git a/doc/rfc/rfc8032.txt b/doc/rfc/rfc8032.txt
new file mode 100644
index 0000000..b5dfdf0
--- /dev/null
+++ b/doc/rfc/rfc8032.txt
@@ -0,0 +1,3363 @@
+
+
+
+
+
+
+Internet Research Task Force (IRTF) S. Josefsson
+Request for Comments: 8032 SJD AB
+Category: Informational I. Liusvaara
+ISSN: 2070-1721 Independent
+ January 2017
+
+
+ Edwards-Curve Digital Signature Algorithm (EdDSA)
+
+Abstract
+
+ This document describes elliptic curve signature scheme Edwards-curve
+ Digital Signature Algorithm (EdDSA). The algorithm is instantiated
+ with recommended parameters for the edwards25519 and edwards448
+ curves. An example implementation and test vectors are provided.
+
+Status of This Memo
+
+ This document is not an Internet Standards Track specification; it is
+ published for informational purposes.
+
+ This document is a product of the Internet Research Task Force
+ (IRTF). The IRTF publishes the results of Internet-related research
+ and development activities. These results might not be suitable for
+ deployment. This RFC represents the consensus of the Crypto Forum
+ Research Group of the Internet Research Task Force (IRTF). Documents
+ approved for publication by the IRSG are not a candidate for any
+ level of Internet Standard; see Section 2 of RFC 7841.
+
+ Information about the current status of this document, any errata,
+ and how to provide feedback on it may be obtained at
+ http://www.rfc-editor.org/info/rfc8032.
+
+Copyright Notice
+
+ Copyright (c) 2017 IETF Trust and the persons identified as the
+ document authors. All rights reserved.
+
+ This document is subject to BCP 78 and the IETF Trust's Legal
+ Provisions Relating to IETF Documents
+ (http://trustee.ietf.org/license-info) in effect on the date of
+ publication of this document. Please review these documents
+ carefully, as they describe your rights and restrictions with respect
+ to this document.
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 1]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2. Notation and Conventions . . . . . . . . . . . . . . . . . . 4
+ 3. EdDSA Algorithm . . . . . . . . . . . . . . . . . . . . . . . 5
+ 3.1. Encoding . . . . . . . . . . . . . . . . . . . . . . . . 7
+ 3.2. Keys . . . . . . . . . . . . . . . . . . . . . . . . . . 7
+ 3.3. Sign . . . . . . . . . . . . . . . . . . . . . . . . . . 8
+ 3.4. Verify . . . . . . . . . . . . . . . . . . . . . . . . . 8
+ 4. PureEdDSA, HashEdDSA, and Naming . . . . . . . . . . . . . . 8
+ 5. EdDSA Instances . . . . . . . . . . . . . . . . . . . . . . . 9
+ 5.1. Ed25519ph, Ed25519ctx, and Ed25519 . . . . . . . . . . . 9
+ 5.1.1. Modular Arithmetic . . . . . . . . . . . . . . . . . 10
+ 5.1.2. Encoding . . . . . . . . . . . . . . . . . . . . . . 10
+ 5.1.3. Decoding . . . . . . . . . . . . . . . . . . . . . . 11
+ 5.1.4. Point Addition . . . . . . . . . . . . . . . . . . . 11
+ 5.1.5. Key Generation . . . . . . . . . . . . . . . . . . . 13
+ 5.1.6. Sign . . . . . . . . . . . . . . . . . . . . . . . . 13
+ 5.1.7. Verify . . . . . . . . . . . . . . . . . . . . . . . 14
+ 5.2. Ed448ph and Ed448 . . . . . . . . . . . . . . . . . . . . 15
+ 5.2.1. Modular Arithmetic . . . . . . . . . . . . . . . . . 16
+ 5.2.2. Encoding . . . . . . . . . . . . . . . . . . . . . . 16
+ 5.2.3. Decoding . . . . . . . . . . . . . . . . . . . . . . 16
+ 5.2.4. Point Addition . . . . . . . . . . . . . . . . . . . 17
+ 5.2.5. Key Generation . . . . . . . . . . . . . . . . . . . 18
+ 5.2.6. Sign . . . . . . . . . . . . . . . . . . . . . . . . 19
+ 5.2.7. Verify . . . . . . . . . . . . . . . . . . . . . . . 19
+ 6. Ed25519 Python Illustration . . . . . . . . . . . . . . . . . 20
+ 7. Test Vectors . . . . . . . . . . . . . . . . . . . . . . . . 23
+ 7.1. Test Vectors for Ed25519 . . . . . . . . . . . . . . . . 24
+ 7.2. Test Vectors for Ed25519ctx . . . . . . . . . . . . . . . 27
+ 7.3. Test Vectors for Ed25519ph . . . . . . . . . . . . . . . 30
+ 7.4. Test Vectors for Ed448 . . . . . . . . . . . . . . . . . 30
+ 7.5. Test Vectors for Ed448ph . . . . . . . . . . . . . . . . 38
+ 8. Security Considerations . . . . . . . . . . . . . . . . . . . 40
+ 8.1. Side-Channel Leaks . . . . . . . . . . . . . . . . . . . 40
+ 8.2. Randomness Considerations . . . . . . . . . . . . . . . . 40
+ 8.3. Use of Contexts . . . . . . . . . . . . . . . . . . . . . 41
+ 8.4. Signature Malleability . . . . . . . . . . . . . . . . . 41
+ 8.5. Choice of Signature Primitive . . . . . . . . . . . . . . 41
+ 8.6. Mixing Different Prehashes . . . . . . . . . . . . . . . 42
+ 8.7. Signing Large Amounts of Data at Once . . . . . . . . . . 42
+ 8.8. Multiplication by Cofactor in Verification . . . . . . . 43
+ 8.9. Use of SHAKE256 as a Hash Function . . . . . . . . . . . 43
+ 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 43
+ 9.1. Normative References . . . . . . . . . . . . . . . . . . 43
+ 9.2. Informative References . . . . . . . . . . . . . . . . . 44
+
+
+
+
+Josefsson & Liusvaara Informational [Page 2]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ Appendix A. Ed25519/Ed448 Python Library . . . . . . . . . . . . 46
+ Appendix B. Library Driver . . . . . . . . . . . . . . . . . . . 58
+ Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 60
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 60
+
+1. Introduction
+
+ The Edwards-curve Digital Signature Algorithm (EdDSA) is a variant of
+ Schnorr's signature system with (possibly twisted) Edwards curves.
+ EdDSA needs to be instantiated with certain parameters, and this
+ document describes some recommended variants.
+
+ To facilitate adoption of EdDSA in the Internet community, this
+ document describes the signature scheme in an implementation-oriented
+ way and provides sample code and test vectors.
+
+ The advantages with EdDSA are as follows:
+
+ 1. EdDSA provides high performance on a variety of platforms;
+
+ 2. The use of a unique random number for each signature is not
+ required;
+
+ 3. It is more resilient to side-channel attacks;
+
+ 4. EdDSA uses small public keys (32 or 57 bytes) and signatures (64
+ or 114 bytes) for Ed25519 and Ed448, respectively;
+
+ 5. The formulas are "complete", i.e., they are valid for all points
+ on the curve, with no exceptions. This obviates the need for
+ EdDSA to perform expensive point validation on untrusted public
+ values; and
+
+ 6. EdDSA provides collision resilience, meaning that hash-function
+ collisions do not break this system (only holds for PureEdDSA).
+
+ The original EdDSA paper [EDDSA] and the generalized version
+ described in "EdDSA for more curves" [EDDSA2] provide further
+ background. RFC 7748 [RFC7748] discusses specific curves, including
+ Curve25519 [CURVE25519] and Ed448-Goldilocks [ED448].
+
+ Ed25519 is intended to operate at around the 128-bit security level
+ and Ed448 at around the 224-bit security level. A sufficiently large
+ quantum computer would be able to break both. Reasonable projections
+ of the abilities of classical computers conclude that Ed25519 is
+ perfectly safe. Ed448 is provided for those applications with
+ relaxed performance requirements and where there is a desire to hedge
+ against analytical attacks on elliptic curves.
+
+
+
+Josefsson & Liusvaara Informational [Page 3]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+2. Notation and Conventions
+
+ The following notation is used throughout the document:
+
+ p Denotes the prime number defining the underlying field
+
+ GF(p) Finite field with p elements
+
+ x^y x multiplied by itself y times
+
+ B Generator of the group or subgroup of interest
+
+ [n]X X added to itself n times
+
+ h[i] The i'th octet of octet string
+
+ h_i The i'th bit of h
+
+ a || b (bit-)string a concatenated with (bit-)string b
+
+ a <= b a is less than or equal to b
+
+ a >= b a is greater than or equal to b
+
+ i+j Sum of i and j
+
+ i*j Multiplication of i and j
+
+ i-j Subtraction of j from i
+
+ i/j Division of i by j
+
+ i x j Cartesian product of i and j
+
+ (u,v) Elliptic curve point with x-coordinate u and
+ y-coordinate v
+
+ SHAKE256(x, y) The y first octets of SHAKE256 [FIPS202] output for
+ input x
+
+ OCTET(x) The octet with value x
+
+ OLEN(x) The number of octets in string x
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 4]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ dom2(x, y) The blank octet string when signing or verifying
+ Ed25519. Otherwise, the octet string: "SigEd25519 no
+ Ed25519 collisions" || octet(x) || octet(OLEN(y)) ||
+ y, where x is in range 0-255 and y is an octet string
+ of at most 255 octets. "SigEd25519 no Ed25519
+ collisions" is in ASCII (32 octets).
+
+ dom4(x, y) The octet string "SigEd448" || octet(x) ||
+ octet(OLEN(y)) || y, where x is in range 0-255 and y
+ is an octet string of at most 255 octets. "SigEd448"
+ is in ASCII (8 octets).
+
+ Parentheses (i.e., '(' and ')') are used to group expressions, in
+ order to avoid having the description depend on a binding order
+ between operators.
+
+ Bit strings are converted to octet strings by taking bits from left
+ to right, packing those from the least significant bit of each octet
+ to the most significant bit, and moving to the next octet when each
+ octet fills up. The conversion from octet string to bit string is
+ the reverse of this process; for example, the 16-bit bit string
+
+ b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
+
+ is converted into two octets x0 and x1 (in this order) as
+
+ x0 = b7*128+b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0
+ x1 = b15*128+b14*64+b13*32+b12*16+b11*8+b10*4+b9*2+b8
+
+ Little-endian encoding into bits places bits from left to right and
+ from least significant to most significant. If combined with
+ bit-string-to-octet-string conversion defined above, this results in
+ little-endian encoding into octets (if length is not a multiple of 8,
+ the most significant bits of the last octet remain unused).
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC2119].
+
+3. EdDSA Algorithm
+
+ EdDSA is a digital signature system with 11 parameters.
+
+ The generic EdDSA digital signature system with its 11 input
+ parameters is not intended to be implemented directly. Choosing
+ parameters is critical for secure and efficient operation. Instead,
+ you would implement a particular parameter choice for EdDSA (such as
+
+
+
+
+Josefsson & Liusvaara Informational [Page 5]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ Ed25519 or Ed448), sometimes slightly generalized to achieve code
+ reuse to cover Ed25519 and Ed448.
+
+ Therefore, a precise explanation of the generic EdDSA is thus not
+ particularly useful for implementers. For background and
+ completeness, a succinct description of the generic EdDSA algorithm
+ is given here.
+
+ The definition of some parameters, such as n and c, may help to
+ explain some steps of the algorithm that are not intuitive.
+
+ This description closely follows [EDDSA2].
+
+ EdDSA has 11 parameters:
+
+ 1. An odd prime power p. EdDSA uses an elliptic curve over the
+ finite field GF(p).
+
+ 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b
+ bits, and EdDSA signatures have exactly 2*b bits. b is
+ recommended to be a multiple of 8, so public key and signature
+ lengths are an integral number of octets.
+
+ 3. A (b-1)-bit encoding of elements of the finite field GF(p).
+
+ 4. A cryptographic hash function H producing 2*b-bit output.
+ Conservative hash functions (i.e., hash functions where it is
+ infeasible to create collisions) are recommended and do not have
+ much impact on the total cost of EdDSA.
+
+ 5. An integer c that is 2 or 3. Secret EdDSA scalars are multiples
+ of 2^c. The integer c is the base-2 logarithm of the so-called
+ cofactor.
+
+ 6. An integer n with c <= n < b. Secret EdDSA scalars have exactly
+ n + 1 bits, with the top bit (the 2^n position) always set and
+ the bottom c bits always cleared.
+
+ 7. A non-square element d of GF(p). The usual recommendation is to
+ take it as the value nearest to zero that gives an acceptable
+ curve.
+
+ 8. A non-zero square element a of GF(p). The usual recommendation
+ for best performance is a = -1 if p mod 4 = 1, and a = 1 if
+ p mod 4 = 3.
+
+ 9. An element B != (0,1) of the set E = { (x,y) is a member of
+ GF(p) x GF(p) such that a * x^2 + y^2 = 1 + d * x^2 * y^2 }.
+
+
+
+Josefsson & Liusvaara Informational [Page 6]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ 10. An odd prime L such that [L]B = 0 and 2^c * L = #E. The number
+ #E (the number of points on the curve) is part of the standard
+ data provided for an elliptic curve E, or it can be computed as
+ cofactor * order.
+
+ 11. A "prehash" function PH. PureEdDSA means EdDSA where PH is the
+ identity function, i.e., PH(M) = M. HashEdDSA means EdDSA where
+ PH generates a short output, no matter how long the message is;
+ for example, PH(M) = SHA-512(M).
+
+ Points on the curve form a group under addition, (x3, y3) = (x1, y1)
+ + (x2, y2), with the formulas
+
+ x1 * y2 + x2 * y1 y1 * y2 - a * x1 * x2
+ x3 = --------------------------, y3 = ---------------------------
+ 1 + d * x1 * x2 * y1 * y2 1 - d * x1 * x2 * y1 * y2
+
+ The neutral element in the group is (0,1).
+
+ Unlike many other curves used for cryptographic applications, these
+ formulas are "complete"; they are valid for all points on the curve,
+ with no exceptions. In particular, the denominators are non-zero for
+ all input points.
+
+ There are more efficient formulas, which are still complete, that use
+ homogeneous coordinates to avoid the expensive modulo p inversions.
+ See [Faster-ECC] and [Edwards-revisited].
+
+3.1. Encoding
+
+ An integer 0 < S < L - 1 is encoded in little-endian form as a b-bit
+ string ENC(S).
+
+ An element (x,y) of E is encoded as a b-bit string called ENC(x,y),
+ which is the (b-1)-bit encoding of y concatenated with one bit that
+ is 1 if x is negative and 0 if x is not negative.
+
+ The encoding of GF(p) is used to define "negative" elements of GF(p):
+ specifically, x is negative if the (b-1)-bit encoding of x is
+ lexicographically larger than the (b-1)-bit encoding of -x.
+
+3.2. Keys
+
+ An EdDSA private key is a b-bit string k. Let the hash H(k) =
+ (h_0, h_1, ..., h_(2b-1)) determine an integer s, which is 2^n plus
+ the sum of m = 2^i * h_i for all integer i, c <= i < n. Let s
+ determine the multiple A = [s]B. The EdDSA public key is ENC(A).
+ The bits h_b, ..., h_(2b-1) are used below during signing.
+
+
+
+Josefsson & Liusvaara Informational [Page 7]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+3.3. Sign
+
+ The EdDSA signature of a message M under a private key k is defined
+ as the PureEdDSA signature of PH(M). In other words, EdDSA simply
+ uses PureEdDSA to sign PH(M).
+
+ The PureEdDSA signature of a message M under a private key k is the
+ 2*b-bit string ENC(R) || ENC(S). R and S are derived as follows.
+ First define r = H(h_b || ... || h_(2b-1) || M) interpreting 2*b-bit
+ strings in little-endian form as integers in {0, 1, ..., 2^(2*b) -
+ 1}. Let R = [r]B and S = (r + H(ENC(R) || ENC(A) || PH(M)) * s) mod
+ L. The s used here is from the previous section.
+
+3.4. Verify
+
+ To verify a PureEdDSA signature ENC(R) || ENC(S) on a message M under
+ a public key ENC(A), proceed as follows. Parse the inputs so that A
+ and R are elements of E, and S is a member of the set {0, 1, ...,
+ L-1}. Compute h = H(ENC(R) || ENC(A) || M), and check the group
+ equation [2^c * S] B = 2^c * R + [2^c * h] A in E. The signature is
+ rejected if parsing fails (including S being out of range) or if the
+ group equation does not hold.
+
+ EdDSA verification for a message M is defined as PureEdDSA
+ verification for PH(M).
+
+4. PureEdDSA, HashEdDSA, and Naming
+
+ One of the parameters of the EdDSA algorithm is the "prehash"
+ function. This may be the identity function, resulting in an
+ algorithm called PureEdDSA, or a collision-resistant hash function
+ such as SHA-512, resulting in an algorithm called HashEdDSA.
+
+ Choosing which variant to use depends on which property is deemed to
+ be more important between 1) collision resilience and 2) a single-
+ pass interface for creating signatures. The collision resilience
+ property means EdDSA is secure even if it is feasible to compute
+ collisions for the hash function. The single-pass interface property
+ means that only one pass over the input message is required to create
+ a signature. PureEdDSA requires two passes over the input. Many
+ existing APIs, protocols, and environments assume digital signature
+ algorithms only need one pass over the input and may have API or
+ bandwidth concerns supporting anything else.
+
+ Note that single-pass verification is not possible with most uses of
+ signatures, no matter which signature algorithm is chosen. This is
+ because most of the time, one can't process the message until the
+ signature is validated, which needs a pass on the entire message.
+
+
+
+Josefsson & Liusvaara Informational [Page 8]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ This document specifies parameters resulting in the HashEdDSA
+ variants Ed25519ph and Ed448ph and the PureEdDSA variants Ed25519 and
+ Ed448.
+
+5. EdDSA Instances
+
+ This section instantiates the general EdDSA algorithm for the
+ edwards25519 and edwards448 curves, each for the PureEdDSA and
+ HashEdDSA variants (plus a contextualized extension of the Ed25519
+ scheme). Thus, five different parameter sets are described.
+
+5.1. Ed25519ph, Ed25519ctx, and Ed25519
+
+ Ed25519 is EdDSA instantiated with:
+
+ +-----------+-------------------------------------------------------+
+ | Parameter | Value |
+ +-----------+-------------------------------------------------------+
+ | p | p of edwards25519 in [RFC7748] (i.e., 2^255 - 19) |
+ | b | 256 |
+ | encoding | 255-bit little-endian encoding of {0, 1, ..., p-1} |
+ | of GF(p) | |
+ | H(x) | SHA-512(dom2(phflag,context)||x) [RFC6234] |
+ | c | base 2 logarithm of cofactor of edwards25519 in |
+ | | [RFC7748] (i.e., 3) |
+ | n | 254 |
+ | d | d of edwards25519 in [RFC7748] (i.e., -121665/121666 |
+ | | = 370957059346694393431380835087545651895421138798432 |
+ | | 19016388785533085940283555) |
+ | a | -1 |
+ | B | (X(P),Y(P)) of edwards25519 in [RFC7748] (i.e., (1511 |
+ | | 22213495354007725011514095885315114540126930418572060 |
+ | | 46113283949847762202, 4631683569492647816942839400347 |
+ | | 5163141307993866256225615783033603165251855960)) |
+ | L | order of edwards25519 in [RFC7748] (i.e., |
+ | | 2^252+27742317777372353535851937790883648493). |
+ | PH(x) | x (i.e., the identity function) |
+ +-----------+-------------------------------------------------------+
+
+ Table 1: Parameters of Ed25519
+
+ For Ed25519, dom2(f,c) is the empty string. The phflag value is
+ irrelevant. The context (if present at all) MUST be empty. This
+ causes the scheme to be one and the same with the Ed25519 scheme
+ published earlier.
+
+ For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty.
+
+
+
+
+Josefsson & Liusvaara Informational [Page 9]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input
+ is hashed using SHA-512 before signing with Ed25519.
+
+ Value of context is set by the signer and verifier (maximum of 255
+ octets; the default is empty string, except for Ed25519, which can't
+ have context) and has to match octet by octet for verification to be
+ successful.
+
+ The curve used is equivalent to Curve25519 [CURVE25519], under a
+ change of coordinates, which means that the difficulty of the
+ discrete logarithm problem is the same as for Curve25519.
+
+5.1.1. Modular Arithmetic
+
+ For advice on how to implement arithmetic modulo p = 2^255 - 19
+ efficiently and securely, see Curve25519 [CURVE25519]. For inversion
+ modulo p, it is recommended to use the identity x^-1 = x^(p-2) (mod
+ p). Inverting zero should never happen, as it would require invalid
+ input, which would have been detected before, or would be a
+ calculation error.
+
+ For point decoding or "decompression", square roots modulo p are
+ needed. They can be computed using the Tonelli-Shanks algorithm or
+ the special case for p = 5 (mod 8). To find a square root of a,
+ first compute the candidate root x = a^((p+3)/8) (mod p). Then there
+ are three cases:
+
+ x^2 = a (mod p). Then x is a square root.
+
+ x^2 = -a (mod p). Then 2^((p-1)/4) * x is a square root.
+
+ a is not a square modulo p.
+
+5.1.2. Encoding
+
+ All values are coded as octet strings, and integers are coded using
+ little-endian convention, i.e., a 32-octet string h h[0],...h[31]
+ represents the integer h[0] + 2^8 * h[1] + ... + 2^248 * h[31].
+
+ A curve point (x,y), with coordinates in the range 0 <= x,y < p, is
+ coded as follows. First, encode the y-coordinate as a little-endian
+ string of 32 octets. The most significant bit of the final octet is
+ always zero. To form the encoding of the point, copy the least
+ significant bit of the x-coordinate to the most significant bit of
+ the final octet.
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 10]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+5.1.3. Decoding
+
+ Decoding a point, given as a 32-octet string, is a little more
+ complicated.
+
+ 1. First, interpret the string as an integer in little-endian
+ representation. Bit 255 of this number is the least significant
+ bit of the x-coordinate and denote this value x_0. The
+ y-coordinate is recovered simply by clearing this bit. If the
+ resulting value is >= p, decoding fails.
+
+ 2. To recover the x-coordinate, the curve equation implies
+ x^2 = (y^2 - 1) / (d y^2 + 1) (mod p). The denominator is always
+ non-zero mod p. Let u = y^2 - 1 and v = d y^2 + 1. To compute
+ the square root of (u/v), the first step is to compute the
+ candidate root x = (u/v)^((p+3)/8). This can be done with the
+ following trick, using a single modular powering for both the
+ inversion of v and the square root:
+
+ (p+3)/8 3 (p-5)/8
+ x = (u/v) = u v (u v^7) (mod p)
+
+ 3. Again, there are three cases:
+
+ 1. If v x^2 = u (mod p), x is a square root.
+
+ 2. If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a
+ square root.
+
+ 3. Otherwise, no square root exists for modulo p, and decoding
+ fails.
+
+ 4. Finally, use the x_0 bit to select the right square root. If
+ x = 0, and x_0 = 1, decoding fails. Otherwise, if x_0 != x mod
+ 2, set x <-- p - x. Return the decoded point (x,y).
+
+5.1.4. Point Addition
+
+ For point addition, the following method is recommended. A point
+ (x,y) is represented in extended homogeneous coordinates (X, Y, Z,
+ T), with x = X/Z, y = Y/Z, x * y = T/Z.
+
+ The neutral point is (0,1), or equivalently in extended homogeneous
+ coordinates (0, Z, Z, 0) for any non-zero Z.
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 11]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ The following formulas for adding two points, (x3,y3) =
+ (x1,y1)+(x2,y2), on twisted Edwards curves with a=-1, square a, and
+ non-square d are described in Section 3.1 of [Edwards-revisited] and
+ in [EFD-TWISTED-ADD]. They are complete, i.e., they work for any
+ pair of valid input points.
+
+ A = (Y1-X1)*(Y2-X2)
+ B = (Y1+X1)*(Y2+X2)
+ C = T1*2*d*T2
+ D = Z1*2*Z2
+ E = B-A
+ F = D-C
+ G = D+C
+ H = B+A
+ X3 = E*F
+ Y3 = G*H
+ T3 = E*H
+ Z3 = F*G
+
+ For point doubling, (x3,y3) = (x1,y1)+(x1,y1), one could just
+ substitute equal points in the above (because of completeness, such
+ substitution is valid) and observe that four multiplications turn
+ into squares. However, using the formulas described in Section 3.2
+ of [Edwards-revisited] and in [EFD-TWISTED-DBL] saves a few smaller
+ operations.
+
+ A = X1^2
+ B = Y1^2
+ C = 2*Z1^2
+ H = A+B
+ E = H-(X1+Y1)^2
+ G = A-B
+ F = C+G
+ X3 = E*F
+ Y3 = G*H
+ T3 = E*H
+ Z3 = F*G
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 12]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+5.1.5. Key Generation
+
+ The private key is 32 octets (256 bits, corresponding to b) of
+ cryptographically secure random data. See [RFC4086] for a discussion
+ about randomness.
+
+ The 32-byte public key is generated by the following steps.
+
+ 1. Hash the 32-byte private key using SHA-512, storing the digest in
+ a 64-octet large buffer, denoted h. Only the lower 32 bytes are
+ used for generating the public key.
+
+ 2. Prune the buffer: The lowest three bits of the first octet are
+ cleared, the highest bit of the last octet is cleared, and the
+ second highest bit of the last octet is set.
+
+ 3. Interpret the buffer as the little-endian integer, forming a
+ secret scalar s. Perform a fixed-base scalar multiplication
+ [s]B.
+
+ 4. The public key A is the encoding of the point [s]B. First,
+ encode the y-coordinate (in the range 0 <= y < p) as a little-
+ endian string of 32 octets. The most significant bit of the
+ final octet is always zero. To form the encoding of the point
+ [s]B, copy the least significant bit of the x coordinate to the
+ most significant bit of the final octet. The result is the
+ public key.
+
+5.1.6. Sign
+
+ The inputs to the signing procedure is the private key, a 32-octet
+ string, and a message M of arbitrary size. For Ed25519ctx and
+ Ed25519ph, there is additionally a context C of at most 255 octets
+ and a flag F, 0 for Ed25519ctx and 1 for Ed25519ph.
+
+ 1. Hash the private key, 32 octets, using SHA-512. Let h denote the
+ resulting digest. Construct the secret scalar s from the first
+ half of the digest, and the corresponding public key A, as
+ described in the previous section. Let prefix denote the second
+ half of the hash digest, h[32],...,h[63].
+
+ 2. Compute SHA-512(dom2(F, C) || prefix || PH(M)), where M is the
+ message to be signed. Interpret the 64-octet digest as a little-
+ endian integer r.
+
+ 3. Compute the point [r]B. For efficiency, do this by first
+ reducing r modulo L, the group order of B. Let the string R be
+ the encoding of this point.
+
+
+
+Josefsson & Liusvaara Informational [Page 13]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ 4. Compute SHA512(dom2(F, C) || R || A || PH(M)), and interpret the
+ 64-octet digest as a little-endian integer k.
+
+ 5. Compute S = (r + k * s) mod L. For efficiency, again reduce k
+ modulo L first.
+
+ 6. Form the signature of the concatenation of R (32 octets) and the
+ little-endian encoding of S (32 octets; the three most
+ significant bits of the final octet are always zero).
+
+5.1.7. Verify
+
+ 1. To verify a signature on a message M using public key A, with F
+ being 0 for Ed25519ctx, 1 for Ed25519ph, and if Ed25519ctx or
+ Ed25519ph is being used, C being the context, first split the
+ signature into two 32-octet halves. Decode the first half as a
+ point R, and the second half as an integer S, in the range
+ 0 <= s < L. Decode the public key A as point A'. If any of the
+ decodings fail (including S being out of range), the signature is
+ invalid.
+
+ 2. Compute SHA512(dom2(F, C) || R || A || PH(M)), and interpret the
+ 64-octet digest as a little-endian integer k.
+
+ 3. Check the group equation [8][S]B = [8]R + [8][k]A'. It's
+ sufficient, but not required, to instead check [S]B = R + [k]A'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 14]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+5.2. Ed448ph and Ed448
+
+ Ed448 is EdDSA instantiated with:
+
+ +-----------+-------------------------------------------------------+
+ | Parameter | Value |
+ +-----------+-------------------------------------------------------+
+ | p | p of edwards448 in [RFC7748] (i.e., 2^448 - 2^224 - |
+ | | 1) |
+ | b | 456 |
+ | encoding | 455-bit little-endian encoding of {0, 1, ..., p-1} |
+ | of GF(p) | |
+ | H(x) | SHAKE256(dom4(phflag,context)||x, 114) |
+ | phflag | 0 |
+ | c | base 2 logarithm of cofactor of edwards448 in |
+ | | [RFC7748] (i.e., 2) |
+ | n | 447 |
+ | d | d of edwards448 in [RFC7748] (i.e., -39081) |
+ | a | 1 |
+ | B | (X(P),Y(P)) of edwards448 in [RFC7748] (i.e., (224580 |
+ | | 04029592430018760433409989603624678964163256413424612 |
+ | | 54616869504154674060329090291928693579532825780320751 |
+ | | 46446173674602635247710, 2988192100784814926760179304 |
+ | | 43930673437544040154080242095928241372331506189835876 |
+ | | 00353687865541878473398230323350346250053154506283266 |
+ | | 0)) |
+ | L | order of edwards448 in [RFC7748] (i.e., 2^446 - 13818 |
+ | | 06680989511535200738674851542688033669247488217860989 |
+ | | 4547503885). |
+ | PH(x) | x (i.e., the identity function) |
+ +-----------+-------------------------------------------------------+
+
+ Table 2: Parameters of Ed448
+
+ Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag
+ being 1, i.e., the input is hashed before signing with Ed448 with a
+ hash constant modified.
+
+ Value of context is set by signer and verifier (maximum of 255
+ octets; the default is empty string) and has to match octet by octet
+ for verification to be successful.
+
+ The curve is equivalent to Ed448-Goldilocks under change of the
+ basepoint, which preserves difficulty of the discrete logarithm.
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 15]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+5.2.1. Modular Arithmetic
+
+ For advice on how to implement arithmetic modulo p = 2^448 - 2^224 -
+ 1 efficiently and securely, see [ED448]. For inversion modulo p, it
+ is recommended to use the identity x^-1 = x^(p-2) (mod p). Inverting
+ zero should never happen, as it would require invalid input, which
+ would have been detected before, or would be a calculation error.
+
+ For point decoding or "decompression", square roots modulo p are
+ needed. They can be computed by first computing candidate root
+ x = a ^ (p+1)/4 (mod p) and then checking if x^2 = a. If it is, then
+ x is the square root of a; if it isn't, then a does not have a square
+ root.
+
+5.2.2. Encoding
+
+ All values are coded as octet strings, and integers are coded using
+ little-endian convention, i.e., a 57-octet string h h[0],...h[56]
+ represents the integer h[0] + 2^8 * h[1] + ... + 2^448 * h[56].
+
+ A curve point (x,y), with coordinates in the range 0 <= x,y < p, is
+ coded as follows. First, encode the y-coordinate as a little-endian
+ string of 57 octets. The final octet is always zero. To form the
+ encoding of the point, copy the least significant bit of the
+ x-coordinate to the most significant bit of the final octet.
+
+5.2.3. Decoding
+
+ Decoding a point, given as a 57-octet string, is a little more
+ complicated.
+
+ 1. First, interpret the string as an integer in little-endian
+ representation. Bit 455 of this number is the least significant
+ bit of the x-coordinate, and denote this value x_0. The
+ y-coordinate is recovered simply by clearing this bit. If the
+ resulting value is >= p, decoding fails.
+
+ 2. To recover the x-coordinate, the curve equation implies
+ x^2 = (y^2 - 1) / (d y^2 - 1) (mod p). The denominator is always
+ non-zero mod p. Let u = y^2 - 1 and v = d y^2 - 1. To compute
+ the square root of (u/v), the first step is to compute the
+ candidate root x = (u/v)^((p+1)/4). This can be done using the
+ following trick, to use a single modular powering for both the
+ inversion of v and the square root:
+
+ (p+1)/4 3 (p-3)/4
+ x = (u/v) = u v (u^5 v^3) (mod p)
+
+
+
+
+Josefsson & Liusvaara Informational [Page 16]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ 3. If v * x^2 = u, the recovered x-coordinate is x. Otherwise, no
+ square root exists, and the decoding fails.
+
+ 4. Finally, use the x_0 bit to select the right square root. If
+ x = 0, and x_0 = 1, decoding fails. Otherwise, if x_0 != x mod
+ 2, set x <-- p - x. Return the decoded point (x,y).
+
+5.2.4. Point Addition
+
+ For point addition, the following method is recommended. A point
+ (x,y) is represented in projective coordinates (X, Y, Z), with
+ x = X/Z, y = Y/Z.
+
+ The neutral point is (0,1), or equivalently in projective coordinates
+ (0, Z, Z) for any non-zero Z.
+
+ The following formulas for adding two points, (x3,y3) =
+ (x1,y1)+(x2,y2) on untwisted Edwards curve (i.e., a=1) with non-
+ square d, are described in Section 4 of [Faster-ECC] and in
+ [EFD-ADD]. They are complete, i.e., they work for any pair of valid
+ input points.
+
+ A = Z1*Z2
+ B = A^2
+ C = X1*X2
+ D = Y1*Y2
+ E = d*C*D
+ F = B-E
+ G = B+E
+ H = (X1+Y1)*(X2+Y2)
+ X3 = A*F*(H-C-D)
+ Y3 = A*G*(D-C)
+ Z3 = F*G
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 17]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ Again, similar to the other curve, doubling formulas can be obtained
+ by substituting equal points, turning four multiplications into
+ squares. However, this is not even nearly optimal; the following
+ formulas described in Section 4 of [Faster-ECC] and in [EFD-DBL] save
+ multiple multiplications.
+
+ B = (X1+Y1)^2
+ C = X1^2
+ D = Y1^2
+ E = C+D
+ H = Z1^2
+ J = E-2*H
+ X3 = (B-E)*J
+ Y3 = E*(C-D)
+ Z3 = E*J
+
+5.2.5. Key Generation
+
+ The private key is 57 octets (456 bits, corresponding to b) of
+ cryptographically secure random data. See [RFC4086] for a discussion
+ about randomness.
+
+ The 57-byte public key is generated by the following steps:
+
+ 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the
+ digest in a 114-octet large buffer, denoted h. Only the lower 57
+ bytes are used for generating the public key.
+
+ 2. Prune the buffer: The two least significant bits of the first
+ octet are cleared, all eight bits the last octet are cleared, and
+ the highest bit of the second to last octet is set.
+
+ 3. Interpret the buffer as the little-endian integer, forming a
+ secret scalar s. Perform a known-base-point scalar
+ multiplication [s]B.
+
+ 4. The public key A is the encoding of the point [s]B. First encode
+ the y-coordinate (in the range 0 <= y < p) as a little-endian
+ string of 57 octets. The most significant bit of the final octet
+ is always zero. To form the encoding of the point [s]B, copy the
+ least significant bit of the x coordinate to the most significant
+ bit of the final octet. The result is the public key.
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 18]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+5.2.6. Sign
+
+ The inputs to the signing procedure is the private key, a 57-octet
+ string, a flag F, which is 0 for Ed448, 1 for Ed448ph, context C of
+ at most 255 octets, and a message M of arbitrary size.
+
+ 1. Hash the private key, 57 octets, using SHAKE256(x, 114). Let h
+ denote the resulting digest. Construct the secret scalar s from
+ the first half of the digest, and the corresponding public key A,
+ as described in the previous section. Let prefix denote the
+ second half of the hash digest, h[57],...,h[113].
+
+ 2. Compute SHAKE256(dom4(F, C) || prefix || PH(M), 114), where M is
+ the message to be signed, F is 1 for Ed448ph, 0 for Ed448, and C
+ is the context to use. Interpret the 114-octet digest as a
+ little-endian integer r.
+
+ 3. Compute the point [r]B. For efficiency, do this by first
+ reducing r modulo L, the group order of B. Let the string R be
+ the encoding of this point.
+
+ 4. Compute SHAKE256(dom4(F, C) || R || A || PH(M), 114), and
+ interpret the 114-octet digest as a little-endian integer k.
+
+ 5. Compute S = (r + k * s) mod L. For efficiency, again reduce k
+ modulo L first.
+
+ 6. Form the signature of the concatenation of R (57 octets) and the
+ little-endian encoding of S (57 octets; the ten most significant
+ bits of the final octets are always zero).
+
+5.2.7. Verify
+
+ 1. To verify a signature on a message M using context C and public
+ key A, with F being 0 for Ed448 and 1 for Ed448ph, first split
+ the signature into two 57-octet halves. Decode the first half as
+ a point R, and the second half as an integer S, in the range 0 <=
+ s < L. Decode the public key A as point A'. If any of the
+ decodings fail (including S being out of range), the signature is
+ invalid.
+
+ 2. Compute SHAKE256(dom4(F, C) || R || A || PH(M), 114), and
+ interpret the 114-octet digest as a little-endian integer k.
+
+ 3. Check the group equation [4][S]B = [4]R + [4][k]A'. It's
+ sufficient, but not required, to instead check [S]B = R + [k]A'.
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 19]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+6. Ed25519 Python Illustration
+
+ The rest of this section describes how Ed25519 can be implemented in
+ Python (version 3.2 or later) for illustration. See Appendix A for
+ the complete implementation and Appendix B for a test-driver to run
+ it through some test vectors.
+
+ Note that this code is not intended for production as it is not
+ proven to be correct for all inputs, nor does it protect against
+ side-channel attacks. The purpose is to illustrate the algorithm to
+ help implementers with their own implementation.
+
+## First, some preliminaries that will be needed.
+
+import hashlib
+
+def sha512(s):
+ return hashlib.sha512(s).digest()
+
+# Base field Z_p
+p = 2**255 - 19
+
+def modp_inv(x):
+ return pow(x, p-2, p)
+
+# Curve constant
+d = -121665 * modp_inv(121666) % p
+
+# Group order
+q = 2**252 + 27742317777372353535851937790883648493
+
+def sha512_modq(s):
+ return int.from_bytes(sha512(s), "little") % q
+
+## Then follows functions to perform point operations.
+
+# Points are represented as tuples (X, Y, Z, T) of extended
+# coordinates, with x = X/Z, y = Y/Z, x*y = T/Z
+
+def point_add(P, Q):
+ A, B = (P[1]-P[0]) * (Q[1]-Q[0]) % p, (P[1]+P[0]) * (Q[1]+Q[0]) % p;
+ C, D = 2 * P[3] * Q[3] * d % p, 2 * P[2] * Q[2] % p;
+ E, F, G, H = B-A, D-C, D+C, B+A;
+ return (E*F, G*H, F*G, E*H);
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 20]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+# Computes Q = s * Q
+def point_mul(s, P):
+ Q = (0, 1, 1, 0) # Neutral element
+ while s > 0:
+ if s & 1:
+ Q = point_add(Q, P)
+ P = point_add(P, P)
+ s >>= 1
+ return Q
+
+def point_equal(P, Q):
+ # x1 / z1 == x2 / z2 <==> x1 * z2 == x2 * z1
+ if (P[0] * Q[2] - Q[0] * P[2]) % p != 0:
+ return False
+ if (P[1] * Q[2] - Q[1] * P[2]) % p != 0:
+ return False
+ return True
+
+## Now follows functions for point compression.
+
+# Square root of -1
+modp_sqrt_m1 = pow(2, (p-1) // 4, p)
+
+# Compute corresponding x-coordinate, with low bit corresponding to
+# sign, or return None on failure
+def recover_x(y, sign):
+ if y >= p:
+ return None
+ x2 = (y*y-1) * modp_inv(d*y*y+1)
+ if x2 == 0:
+ if sign:
+ return None
+ else:
+ return 0
+
+ # Compute square root of x2
+ x = pow(x2, (p+3) // 8, p)
+ if (x*x - x2) % p != 0:
+ x = x * modp_sqrt_m1 % p
+ if (x*x - x2) % p != 0:
+ return None
+
+ if (x & 1) != sign:
+ x = p - x
+ return x
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 21]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+# Base point
+g_y = 4 * modp_inv(5) % p
+g_x = recover_x(g_y, 0)
+G = (g_x, g_y, 1, g_x * g_y % p)
+
+def point_compress(P):
+ zinv = modp_inv(P[2])
+ x = P[0] * zinv % p
+ y = P[1] * zinv % p
+ return int.to_bytes(y | ((x & 1) << 255), 32, "little")
+
+def point_decompress(s):
+ if len(s) != 32:
+ raise Exception("Invalid input length for decompression")
+ y = int.from_bytes(s, "little")
+ sign = y >> 255
+ y &= (1 << 255) - 1
+
+ x = recover_x(y, sign)
+ if x is None:
+ return None
+ else:
+ return (x, y, 1, x*y % p)
+
+## These are functions for manipulating the private key.
+
+def secret_expand(secret):
+ if len(secret) != 32:
+ raise Exception("Bad size of private key")
+ h = sha512(secret)
+ a = int.from_bytes(h[:32], "little")
+ a &= (1 << 254) - 8
+ a |= (1 << 254)
+ return (a, h[32:])
+
+def secret_to_public(secret):
+ (a, dummy) = secret_expand(secret)
+ return point_compress(point_mul(a, G))
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 22]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+## The signature function works as below.
+
+def sign(secret, msg):
+ a, prefix = secret_expand(secret)
+ A = point_compress(point_mul(a, G))
+ r = sha512_modq(prefix + msg)
+ R = point_mul(r, G)
+ Rs = point_compress(R)
+ h = sha512_modq(Rs + A + msg)
+ s = (r + h * a) % q
+ return Rs + int.to_bytes(s, 32, "little")
+
+## And finally the verification function.
+
+def verify(public, msg, signature):
+ if len(public) != 32:
+ raise Exception("Bad public key length")
+ if len(signature) != 64:
+ Exception("Bad signature length")
+ A = point_decompress(public)
+ if not A:
+ return False
+ Rs = signature[:32]
+ R = point_decompress(Rs)
+ if not R:
+ return False
+ s = int.from_bytes(signature[32:], "little")
+ if s >= q: return False
+ h = sha512_modq(Rs + public + msg)
+ sB = point_mul(s, G)
+ hA = point_mul(h, A)
+ return point_equal(sB, point_add(R, hA))
+
+7. Test Vectors
+
+ This section contains test vectors for Ed25519ph, Ed25519ctx,
+ Ed448ph, Ed25519, and Ed448.
+
+ Each section contains a sequence of test vectors. The octets are hex
+ encoded, and whitespace is inserted for readability. Ed25519,
+ Ed25519ctx, and Ed25519ph private and public keys are 32 octets;
+ signatures are 64 octets. Ed448 and Ed448ph private and public keys
+ are 57 octets; signatures are 114 octets. Messages are of arbitrary
+ length. If the context is non-empty, it is given as 1-255 octets.
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 23]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+7.1. Test Vectors for Ed25519
+
+ These test vectors are taken from [ED25519-TEST-VECTORS] (but we
+ removed the public key as a suffix of the private key and removed the
+ message from the signature) and [ED25519-LIBGCRYPT-TEST-VECTORS].
+
+ -----TEST 1
+
+ ALGORITHM:
+ Ed25519
+
+ SECRET KEY:
+ 9d61b19deffd5a60ba844af492ec2cc4
+ 4449c5697b326919703bac031cae7f60
+
+ PUBLIC KEY:
+ d75a980182b10ab7d54bfed3c964073a
+ 0ee172f3daa62325af021a68f707511a
+
+ MESSAGE (length 0 bytes):
+
+ SIGNATURE:
+ e5564300c360ac729086e2cc806e828a
+ 84877f1eb8e5d974d873e06522490155
+ 5fb8821590a33bacc61e39701cf9b46b
+ d25bf5f0595bbe24655141438e7a100b
+
+ -----TEST 2
+
+ ALGORITHM:
+ Ed25519
+
+ SECRET KEY:
+ 4ccd089b28ff96da9db6c346ec114e0f
+ 5b8a319f35aba624da8cf6ed4fb8a6fb
+
+ PUBLIC KEY:
+ 3d4017c3e843895a92b70aa74d1b7ebc
+ 9c982ccf2ec4968cc0cd55f12af4660c
+
+ MESSAGE (length 1 byte):
+ 72
+
+ SIGNATURE:
+ 92a009a9f0d4cab8720e820b5f642540
+ a2b27b5416503f8fb3762223ebdb69da
+ 085ac1e43e15996e458f3613d0f11d8c
+ 387b2eaeb4302aeeb00d291612bb0c00
+
+
+
+Josefsson & Liusvaara Informational [Page 24]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ -----TEST 3
+
+ ALGORITHM:
+ Ed25519
+
+ SECRET KEY:
+ c5aa8df43f9f837bedb7442f31dcb7b1
+ 66d38535076f094b85ce3a2e0b4458f7
+
+ PUBLIC KEY:
+ fc51cd8e6218a1a38da47ed00230f058
+ 0816ed13ba3303ac5deb911548908025
+
+ MESSAGE (length 2 bytes):
+ af82
+
+ SIGNATURE:
+ 6291d657deec24024827e69c3abe01a3
+ 0ce548a284743a445e3680d7db5ac3ac
+ 18ff9b538d16f290ae67f760984dc659
+ 4a7c15e9716ed28dc027beceea1ec40a
+
+ -----TEST 1024
+
+ ALGORITHM:
+ Ed25519
+
+ SECRET KEY:
+ f5e5767cf153319517630f226876b86c
+ 8160cc583bc013744c6bf255f5cc0ee5
+
+ PUBLIC KEY:
+ 278117fc144c72340f67d0f2316e8386
+ ceffbf2b2428c9c51fef7c597f1d426e
+
+ MESSAGE (length 1023 bytes):
+ 08b8b2b733424243760fe426a4b54908
+ 632110a66c2f6591eabd3345e3e4eb98
+ fa6e264bf09efe12ee50f8f54e9f77b1
+ e355f6c50544e23fb1433ddf73be84d8
+ 79de7c0046dc4996d9e773f4bc9efe57
+ 38829adb26c81b37c93a1b270b20329d
+ 658675fc6ea534e0810a4432826bf58c
+ 941efb65d57a338bbd2e26640f89ffbc
+ 1a858efcb8550ee3a5e1998bd177e93a
+ 7363c344fe6b199ee5d02e82d522c4fe
+ ba15452f80288a821a579116ec6dad2b
+ 3b310da903401aa62100ab5d1a36553e
+
+
+
+Josefsson & Liusvaara Informational [Page 25]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ 06203b33890cc9b832f79ef80560ccb9
+ a39ce767967ed628c6ad573cb116dbef
+ efd75499da96bd68a8a97b928a8bbc10
+ 3b6621fcde2beca1231d206be6cd9ec7
+ aff6f6c94fcd7204ed3455c68c83f4a4
+ 1da4af2b74ef5c53f1d8ac70bdcb7ed1
+ 85ce81bd84359d44254d95629e9855a9
+ 4a7c1958d1f8ada5d0532ed8a5aa3fb2
+ d17ba70eb6248e594e1a2297acbbb39d
+ 502f1a8c6eb6f1ce22b3de1a1f40cc24
+ 554119a831a9aad6079cad88425de6bd
+ e1a9187ebb6092cf67bf2b13fd65f270
+ 88d78b7e883c8759d2c4f5c65adb7553
+ 878ad575f9fad878e80a0c9ba63bcbcc
+ 2732e69485bbc9c90bfbd62481d9089b
+ eccf80cfe2df16a2cf65bd92dd597b07
+ 07e0917af48bbb75fed413d238f5555a
+ 7a569d80c3414a8d0859dc65a46128ba
+ b27af87a71314f318c782b23ebfe808b
+ 82b0ce26401d2e22f04d83d1255dc51a
+ ddd3b75a2b1ae0784504df543af8969b
+ e3ea7082ff7fc9888c144da2af58429e
+ c96031dbcad3dad9af0dcbaaaf268cb8
+ fcffead94f3c7ca495e056a9b47acdb7
+ 51fb73e666c6c655ade8297297d07ad1
+ ba5e43f1bca32301651339e22904cc8c
+ 42f58c30c04aafdb038dda0847dd988d
+ cda6f3bfd15c4b4c4525004aa06eeff8
+ ca61783aacec57fb3d1f92b0fe2fd1a8
+ 5f6724517b65e614ad6808d6f6ee34df
+ f7310fdc82aebfd904b01e1dc54b2927
+ 094b2db68d6f903b68401adebf5a7e08
+ d78ff4ef5d63653a65040cf9bfd4aca7
+ 984a74d37145986780fc0b16ac451649
+ de6188a7dbdf191f64b5fc5e2ab47b57
+ f7f7276cd419c17a3ca8e1b939ae49e4
+ 88acba6b965610b5480109c8b17b80e1
+ b7b750dfc7598d5d5011fd2dcc5600a3
+ 2ef5b52a1ecc820e308aa342721aac09
+ 43bf6686b64b2579376504ccc493d97e
+ 6aed3fb0f9cd71a43dd497f01f17c0e2
+ cb3797aa2a2f256656168e6c496afc5f
+ b93246f6b1116398a346f1a641f3b041
+ e989f7914f90cc2c7fff357876e506b5
+ 0d334ba77c225bc307ba537152f3f161
+ 0e4eafe595f6d9d90d11faa933a15ef1
+ 369546868a7f3a45a96768d40fd9d034
+ 12c091c6315cf4fde7cb68606937380d
+
+
+
+Josefsson & Liusvaara Informational [Page 26]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ b2eaaa707b4c4185c32eddcdd306705e
+ 4dc1ffc872eeee475a64dfac86aba41c
+ 0618983f8741c5ef68d3a101e8a3b8ca
+ c60c905c15fc910840b94c00a0b9d0
+
+ SIGNATURE:
+ 0aab4c900501b3e24d7cdf4663326a3a
+ 87df5e4843b2cbdb67cbf6e460fec350
+ aa5371b1508f9f4528ecea23c436d94b
+ 5e8fcd4f681e30a6ac00a9704a188a03
+
+ -----TEST SHA(abc)
+
+ ALGORITHM:
+ Ed25519
+
+ SECRET KEY:
+ 833fe62409237b9d62ec77587520911e
+ 9a759cec1d19755b7da901b96dca3d42
+
+ PUBLIC KEY:
+ ec172b93ad5e563bf4932c70e1245034
+ c35467ef2efd4d64ebf819683467e2bf
+
+ MESSAGE (length 64 bytes):
+ ddaf35a193617abacc417349ae204131
+ 12e6fa4e89a97ea20a9eeee64b55d39a
+ 2192992a274fc1a836ba3c23a3feebbd
+ 454d4423643ce80e2a9ac94fa54ca49f
+
+ SIGNATURE:
+ dc2a4459e7369633a52b1bf277839a00
+ 201009a3efbf3ecb69bea2186c26b589
+ 09351fc9ac90b3ecfdfbc7c66431e030
+ 3dca179c138ac17ad9bef1177331a704
+ -----
+
+7.2. Test Vectors for Ed25519ctx
+
+ -----foo
+
+ ALGORITHM:
+ Ed25519ctx
+
+ SECRET KEY:
+ 0305334e381af78f141cb666f6199f57
+ bc3495335a256a95bd2a55bf546663f6
+
+
+
+
+Josefsson & Liusvaara Informational [Page 27]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ PUBLIC KEY:
+ dfc9425e4f968f7f0c29f0259cf5f9ae
+ d6851c2bb4ad8bfb860cfee0ab248292
+
+ MESSAGE (length 16 bytes):
+ f726936d19c800494e3fdaff20b276a8
+
+ CONTEXT:
+ 666f6f
+
+ SIGNATURE:
+ 55a4cc2f70a54e04288c5f4cd1e45a7b
+ b520b36292911876cada7323198dd87a
+ 8b36950b95130022907a7fb7c4e9b2d5
+ f6cca685a587b4b21f4b888e4e7edb0d
+
+ -----bar
+
+ ALGORITHM:
+ Ed25519ctx
+
+ SECRET KEY:
+ 0305334e381af78f141cb666f6199f57
+ bc3495335a256a95bd2a55bf546663f6
+
+ PUBLIC KEY:
+ dfc9425e4f968f7f0c29f0259cf5f9ae
+ d6851c2bb4ad8bfb860cfee0ab248292
+
+ MESSAGE (length 16 bytes):
+ f726936d19c800494e3fdaff20b276a8
+
+ CONTEXT:
+ 626172
+
+ SIGNATURE:
+ fc60d5872fc46b3aa69f8b5b4351d580
+ 8f92bcc044606db097abab6dbcb1aee3
+ 216c48e8b3b66431b5b186d1d28f8ee1
+ 5a5ca2df6668346291c2043d4eb3e90d
+
+ -----foo2
+
+ ALGORITHM:
+ Ed25519ctx
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 28]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SECRET KEY:
+ 0305334e381af78f141cb666f6199f57
+ bc3495335a256a95bd2a55bf546663f6
+
+ PUBLIC KEY:
+ dfc9425e4f968f7f0c29f0259cf5f9ae
+ d6851c2bb4ad8bfb860cfee0ab248292
+
+ MESSAGE (length 16 bytes):
+ 508e9e6882b979fea900f62adceaca35
+
+ CONTEXT:
+ 666f6f
+
+ SIGNATURE:
+ 8b70c1cc8310e1de20ac53ce28ae6e72
+ 07f33c3295e03bb5c0732a1d20dc6490
+ 8922a8b052cf99b7c4fe107a5abb5b2c
+ 4085ae75890d02df26269d8945f84b0b
+
+ -----foo3
+
+ ALGORITHM:
+ Ed25519ctx
+
+ SECRET KEY:
+ ab9c2853ce297ddab85c993b3ae14bca
+ d39b2c682beabc27d6d4eb20711d6560
+
+ PUBLIC KEY:
+ 0f1d1274943b91415889152e893d80e9
+ 3275a1fc0b65fd71b4b0dda10ad7d772
+
+ MESSAGE (length 16 bytes):
+ f726936d19c800494e3fdaff20b276a8
+
+ CONTEXT:
+ 666f6f
+
+ SIGNATURE:
+ 21655b5f1aa965996b3f97b3c849eafb
+ a922a0a62992f73b3d1b73106a84ad85
+ e9b86a7b6005ea868337ff2d20a7f5fb
+ d4cd10b0be49a68da2b2e0dc0ad8960f
+ -----
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 29]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+7.3. Test Vectors for Ed25519ph
+
+ -----TEST abc
+
+ ALGORITHM:
+ Ed25519ph
+
+ SECRET KEY:
+ 833fe62409237b9d62ec77587520911e
+ 9a759cec1d19755b7da901b96dca3d42
+
+ PUBLIC KEY:
+ ec172b93ad5e563bf4932c70e1245034
+ c35467ef2efd4d64ebf819683467e2bf
+
+ MESSAGE (length 3 bytes):
+ 616263
+
+ SIGNATURE:
+ 98a70222f0b8121aa9d30f813d683f80
+ 9e462b469c7ff87639499bb94e6dae41
+ 31f85042463c2a355a2003d062adf5aa
+ a10b8c61e636062aaad11c2a26083406
+ -----
+
+7.4. Test Vectors for Ed448
+
+ -----Blank
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ 6c82a562cb808d10d632be89c8513ebf
+ 6c929f34ddfa8c9f63c9960ef6e348a3
+ 528c8a3fcc2f044e39a3fc5b94492f8f
+ 032e7549a20098f95b
+
+ PUBLIC KEY:
+ 5fd7449b59b461fd2ce787ec616ad46a
+ 1da1342485a70e1f8a0ea75d80e96778
+ edf124769b46c7061bd6783df1e50f6c
+ d1fa1abeafe8256180
+
+ MESSAGE (length 0 bytes):
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 30]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SIGNATURE:
+ 533a37f6bbe457251f023c0d88f976ae
+ 2dfb504a843e34d2074fd823d41a591f
+ 2b233f034f628281f2fd7a22ddd47d78
+ 28c59bd0a21bfd3980ff0d2028d4b18a
+ 9df63e006c5d1c2d345b925d8dc00b41
+ 04852db99ac5c7cdda8530a113a0f4db
+ b61149f05a7363268c71d95808ff2e65
+ 2600
+
+ -----1 octet
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ c4eab05d357007c632f3dbb48489924d
+ 552b08fe0c353a0d4a1f00acda2c463a
+ fbea67c5e8d2877c5e3bc397a659949e
+ f8021e954e0a12274e
+
+ PUBLIC KEY:
+ 43ba28f430cdff456ae531545f7ecd0a
+ c834a55d9358c0372bfa0c6c6798c086
+ 6aea01eb00742802b8438ea4cb82169c
+ 235160627b4c3a9480
+
+ MESSAGE (length 1 byte):
+ 03
+
+ SIGNATURE:
+ 26b8f91727bd62897af15e41eb43c377
+ efb9c610d48f2335cb0bd0087810f435
+ 2541b143c4b981b7e18f62de8ccdf633
+ fc1bf037ab7cd779805e0dbcc0aae1cb
+ cee1afb2e027df36bc04dcecbf154336
+ c19f0af7e0a6472905e799f1953d2a0f
+ f3348ab21aa4adafd1d234441cf807c0
+ 3a00
+
+ -----1 octet (with context)
+
+ ALGORITHM:
+ Ed448
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 31]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SECRET KEY:
+ c4eab05d357007c632f3dbb48489924d
+ 552b08fe0c353a0d4a1f00acda2c463a
+ fbea67c5e8d2877c5e3bc397a659949e
+ f8021e954e0a12274e
+
+ PUBLIC KEY:
+ 43ba28f430cdff456ae531545f7ecd0a
+ c834a55d9358c0372bfa0c6c6798c086
+ 6aea01eb00742802b8438ea4cb82169c
+ 235160627b4c3a9480
+
+ MESSAGE (length 1 byte):
+ 03
+
+ CONTEXT:
+ 666f6f
+
+ SIGNATURE:
+ d4f8f6131770dd46f40867d6fd5d5055
+ de43541f8c5e35abbcd001b32a89f7d2
+ 151f7647f11d8ca2ae279fb842d60721
+ 7fce6e042f6815ea000c85741de5c8da
+ 1144a6a1aba7f96de42505d7a7298524
+ fda538fccbbb754f578c1cad10d54d0d
+ 5428407e85dcbc98a49155c13764e66c
+ 3c00
+
+ -----11 octets
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ cd23d24f714274e744343237b93290f5
+ 11f6425f98e64459ff203e8985083ffd
+ f60500553abc0e05cd02184bdb89c4cc
+ d67e187951267eb328
+
+ PUBLIC KEY:
+ dcea9e78f35a1bf3499a831b10b86c90
+ aac01cd84b67a0109b55a36e9328b1e3
+ 65fce161d71ce7131a543ea4cb5f7e9f
+ 1d8b00696447001400
+
+ MESSAGE (length 11 bytes):
+ 0c3e544074ec63b0265e0c
+
+
+
+
+Josefsson & Liusvaara Informational [Page 32]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SIGNATURE:
+ 1f0a8888ce25e8d458a21130879b840a
+ 9089d999aaba039eaf3e3afa090a09d3
+ 89dba82c4ff2ae8ac5cdfb7c55e94d5d
+ 961a29fe0109941e00b8dbdeea6d3b05
+ 1068df7254c0cdc129cbe62db2dc957d
+ bb47b51fd3f213fb8698f064774250a5
+ 028961c9bf8ffd973fe5d5c206492b14
+ 0e00
+
+ -----12 octets
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ 258cdd4ada32ed9c9ff54e63756ae582
+ fb8fab2ac721f2c8e676a72768513d93
+ 9f63dddb55609133f29adf86ec9929dc
+ cb52c1c5fd2ff7e21b
+
+ PUBLIC KEY:
+ 3ba16da0c6f2cc1f30187740756f5e79
+ 8d6bc5fc015d7c63cc9510ee3fd44adc
+ 24d8e968b6e46e6f94d19b945361726b
+ d75e149ef09817f580
+
+ MESSAGE (length 12 bytes):
+ 64a65f3cdedcdd66811e2915
+
+ SIGNATURE:
+ 7eeeab7c4e50fb799b418ee5e3197ff6
+ bf15d43a14c34389b59dd1a7b1b85b4a
+ e90438aca634bea45e3a2695f1270f07
+ fdcdf7c62b8efeaf00b45c2c96ba457e
+ b1a8bf075a3db28e5c24f6b923ed4ad7
+ 47c3c9e03c7079efb87cb110d3a99861
+ e72003cbae6d6b8b827e4e6c143064ff
+ 3c00
+
+ -----13 octets
+
+ ALGORITHM:
+ Ed448
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 33]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SECRET KEY:
+ 7ef4e84544236752fbb56b8f31a23a10
+ e42814f5f55ca037cdcc11c64c9a3b29
+ 49c1bb60700314611732a6c2fea98eeb
+ c0266a11a93970100e
+
+ PUBLIC KEY:
+ b3da079b0aa493a5772029f0467baebe
+ e5a8112d9d3a22532361da294f7bb381
+ 5c5dc59e176b4d9f381ca0938e13c6c0
+ 7b174be65dfa578e80
+
+ MESSAGE (length 13 bytes):
+ 64a65f3cdedcdd66811e2915e7
+
+ SIGNATURE:
+ 6a12066f55331b6c22acd5d5bfc5d712
+ 28fbda80ae8dec26bdd306743c5027cb
+ 4890810c162c027468675ecf645a8317
+ 6c0d7323a2ccde2d80efe5a1268e8aca
+ 1d6fbc194d3f77c44986eb4ab4177919
+ ad8bec33eb47bbb5fc6e28196fd1caf5
+ 6b4e7e0ba5519234d047155ac727a105
+ 3100
+
+ -----64 octets
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ d65df341ad13e008567688baedda8e9d
+ cdc17dc024974ea5b4227b6530e339bf
+ f21f99e68ca6968f3cca6dfe0fb9f4fa
+ b4fa135d5542ea3f01
+
+ PUBLIC KEY:
+ df9705f58edbab802c7f8363cfe5560a
+ b1c6132c20a9f1dd163483a26f8ac53a
+ 39d6808bf4a1dfbd261b099bb03b3fb5
+ 0906cb28bd8a081f00
+
+ MESSAGE (length 64 bytes):
+ bd0f6a3747cd561bdddf4640a332461a
+ 4a30a12a434cd0bf40d766d9c6d458e5
+ 512204a30c17d1f50b5079631f64eb31
+ 12182da3005835461113718d1a5ef944
+
+
+
+
+Josefsson & Liusvaara Informational [Page 34]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SIGNATURE:
+ 554bc2480860b49eab8532d2a533b7d5
+ 78ef473eeb58c98bb2d0e1ce488a98b1
+ 8dfde9b9b90775e67f47d4a1c3482058
+ efc9f40d2ca033a0801b63d45b3b722e
+ f552bad3b4ccb667da350192b61c508c
+ f7b6b5adadc2c8d9a446ef003fb05cba
+ 5f30e88e36ec2703b349ca229c267083
+ 3900
+
+ -----256 octets
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ 2ec5fe3c17045abdb136a5e6a913e32a
+ b75ae68b53d2fc149b77e504132d3756
+ 9b7e766ba74a19bd6162343a21c8590a
+ a9cebca9014c636df5
+
+ PUBLIC KEY:
+ 79756f014dcfe2079f5dd9e718be4171
+ e2ef2486a08f25186f6bff43a9936b9b
+ fe12402b08ae65798a3d81e22e9ec80e
+ 7690862ef3d4ed3a00
+
+ MESSAGE (length 256 bytes):
+ 15777532b0bdd0d1389f636c5f6b9ba7
+ 34c90af572877e2d272dd078aa1e567c
+ fa80e12928bb542330e8409f31745041
+ 07ecd5efac61ae7504dabe2a602ede89
+ e5cca6257a7c77e27a702b3ae39fc769
+ fc54f2395ae6a1178cab4738e543072f
+ c1c177fe71e92e25bf03e4ecb72f47b6
+ 4d0465aaea4c7fad372536c8ba516a60
+ 39c3c2a39f0e4d832be432dfa9a706a6
+ e5c7e19f397964ca4258002f7c0541b5
+ 90316dbc5622b6b2a6fe7a4abffd9610
+ 5eca76ea7b98816af0748c10df048ce0
+ 12d901015a51f189f3888145c03650aa
+ 23ce894c3bd889e030d565071c59f409
+ a9981b51878fd6fc110624dcbcde0bf7
+ a69ccce38fabdf86f3bef6044819de11
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 35]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SIGNATURE:
+ c650ddbb0601c19ca11439e1640dd931
+ f43c518ea5bea70d3dcde5f4191fe53f
+ 00cf966546b72bcc7d58be2b9badef28
+ 743954e3a44a23f880e8d4f1cfce2d7a
+ 61452d26da05896f0a50da66a239a8a1
+ 88b6d825b3305ad77b73fbac0836ecc6
+ 0987fd08527c1a8e80d5823e65cafe2a
+ 3d00
+
+ -----1023 octets
+
+ ALGORITHM:
+ Ed448
+
+ SECRET KEY:
+ 872d093780f5d3730df7c212664b37b8
+ a0f24f56810daa8382cd4fa3f77634ec
+ 44dc54f1c2ed9bea86fafb7632d8be19
+ 9ea165f5ad55dd9ce8
+
+ PUBLIC KEY:
+ a81b2e8a70a5ac94ffdbcc9badfc3feb
+ 0801f258578bb114ad44ece1ec0e799d
+ a08effb81c5d685c0c56f64eecaef8cd
+ f11cc38737838cf400
+
+ MESSAGE (length 1023 bytes):
+ 6ddf802e1aae4986935f7f981ba3f035
+ 1d6273c0a0c22c9c0e8339168e675412
+ a3debfaf435ed651558007db4384b650
+ fcc07e3b586a27a4f7a00ac8a6fec2cd
+ 86ae4bf1570c41e6a40c931db27b2faa
+ 15a8cedd52cff7362c4e6e23daec0fbc
+ 3a79b6806e316efcc7b68119bf46bc76
+ a26067a53f296dafdbdc11c77f7777e9
+ 72660cf4b6a9b369a6665f02e0cc9b6e
+ dfad136b4fabe723d2813db3136cfde9
+ b6d044322fee2947952e031b73ab5c60
+ 3349b307bdc27bc6cb8b8bbd7bd32321
+ 9b8033a581b59eadebb09b3c4f3d2277
+ d4f0343624acc817804728b25ab79717
+ 2b4c5c21a22f9c7839d64300232eb66e
+ 53f31c723fa37fe387c7d3e50bdf9813
+ a30e5bb12cf4cd930c40cfb4e1fc6225
+ 92a49588794494d56d24ea4b40c89fc0
+ 596cc9ebb961c8cb10adde976a5d602b
+ 1c3f85b9b9a001ed3c6a4d3b1437f520
+
+
+
+Josefsson & Liusvaara Informational [Page 36]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ 96cd1956d042a597d561a596ecd3d173
+ 5a8d570ea0ec27225a2c4aaff26306d1
+ 526c1af3ca6d9cf5a2c98f47e1c46db9
+ a33234cfd4d81f2c98538a09ebe76998
+ d0d8fd25997c7d255c6d66ece6fa56f1
+ 1144950f027795e653008f4bd7ca2dee
+ 85d8e90f3dc315130ce2a00375a318c7
+ c3d97be2c8ce5b6db41a6254ff264fa6
+ 155baee3b0773c0f497c573f19bb4f42
+ 40281f0b1f4f7be857a4e59d416c06b4
+ c50fa09e1810ddc6b1467baeac5a3668
+ d11b6ecaa901440016f389f80acc4db9
+ 77025e7f5924388c7e340a732e554440
+ e76570f8dd71b7d640b3450d1fd5f041
+ 0a18f9a3494f707c717b79b4bf75c984
+ 00b096b21653b5d217cf3565c9597456
+ f70703497a078763829bc01bb1cbc8fa
+ 04eadc9a6e3f6699587a9e75c94e5bab
+ 0036e0b2e711392cff0047d0d6b05bd2
+ a588bc109718954259f1d86678a579a3
+ 120f19cfb2963f177aeb70f2d4844826
+ 262e51b80271272068ef5b3856fa8535
+ aa2a88b2d41f2a0e2fda7624c2850272
+ ac4a2f561f8f2f7a318bfd5caf969614
+ 9e4ac824ad3460538fdc25421beec2cc
+ 6818162d06bbed0c40a387192349db67
+ a118bada6cd5ab0140ee273204f628aa
+ d1c135f770279a651e24d8c14d75a605
+ 9d76b96a6fd857def5e0b354b27ab937
+ a5815d16b5fae407ff18222c6d1ed263
+ be68c95f32d908bd895cd76207ae7264
+ 87567f9a67dad79abec316f683b17f2d
+ 02bf07e0ac8b5bc6162cf94697b3c27c
+ d1fea49b27f23ba2901871962506520c
+ 392da8b6ad0d99f7013fbc06c2c17a56
+ 9500c8a7696481c1cd33e9b14e40b82e
+ 79a5f5db82571ba97bae3ad3e0479515
+ bb0e2b0f3bfcd1fd33034efc6245eddd
+ 7ee2086ddae2600d8ca73e214e8c2b0b
+ db2b047c6a464a562ed77b73d2d841c4
+ b34973551257713b753632efba348169
+ abc90a68f42611a40126d7cb21b58695
+ 568186f7e569d2ff0f9e745d0487dd2e
+ b997cafc5abf9dd102e62ff66cba87
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 37]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ SIGNATURE:
+ e301345a41a39a4d72fff8df69c98075
+ a0cc082b802fc9b2b6bc503f926b65bd
+ df7f4c8f1cb49f6396afc8a70abe6d8a
+ ef0db478d4c6b2970076c6a0484fe76d
+ 76b3a97625d79f1ce240e7c576750d29
+ 5528286f719b413de9ada3e8eb78ed57
+ 3603ce30d8bb761785dc30dbc320869e
+ 1a00
+ -----
+
+7.5. Test Vectors for Ed448ph
+
+ -----TEST abc
+
+ ALGORITHM:
+ Ed448ph
+
+ SECRET KEY:
+ 833fe62409237b9d62ec77587520911e
+ 9a759cec1d19755b7da901b96dca3d42
+ ef7822e0d5104127dc05d6dbefde69e3
+ ab2cec7c867c6e2c49
+
+ PUBLIC KEY:
+ 259b71c19f83ef77a7abd26524cbdb31
+ 61b590a48f7d17de3ee0ba9c52beb743
+ c09428a131d6b1b57303d90d8132c276
+ d5ed3d5d01c0f53880
+
+ MESSAGE (length 3 bytes):
+ 616263
+
+ SIGNATURE:
+ 822f6901f7480f3d5f562c592994d969
+ 3602875614483256505600bbc281ae38
+ 1f54d6bce2ea911574932f52a4e6cadd
+ 78769375ec3ffd1b801a0d9b3f4030cd
+ 433964b6457ea39476511214f97469b5
+ 7dd32dbc560a9a94d00bff07620464a3
+ ad203df7dc7ce360c3cd3696d9d9fab9
+ 0f00
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 38]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ -----TEST abc (with context)
+
+ ALGORITHM:
+ Ed448ph
+
+ SECRET KEY:
+ 833fe62409237b9d62ec77587520911e
+ 9a759cec1d19755b7da901b96dca3d42
+ ef7822e0d5104127dc05d6dbefde69e3
+ ab2cec7c867c6e2c49
+
+ PUBLIC KEY:
+ 259b71c19f83ef77a7abd26524cbdb31
+ 61b590a48f7d17de3ee0ba9c52beb743
+ c09428a131d6b1b57303d90d8132c276
+ d5ed3d5d01c0f53880
+
+ MESSAGE (length 3 bytes):
+ 616263
+
+ CONTEXT:
+ 666f6f
+
+ SIGNATURE:
+ c32299d46ec8ff02b54540982814dce9
+ a05812f81962b649d528095916a2aa48
+ 1065b1580423ef927ecf0af5888f90da
+ 0f6a9a85ad5dc3f280d91224ba9911a3
+ 653d00e484e2ce232521481c8658df30
+ 4bb7745a73514cdb9bf3e15784ab7128
+ 4f8d0704a608c54a6b62d97beb511d13
+ 2100
+ -----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 39]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+8. Security Considerations
+
+8.1. Side-Channel Leaks
+
+ For implementations performing signatures, secrecy of the private key
+ is fundamental. It is possible to protect against some side-channel
+ attacks by ensuring that the implementation executes exactly the same
+ sequence of instructions and performs exactly the same memory
+ accesses, for any value of the private key.
+
+ To make an implementation side-channel silent in this way, the modulo
+ p arithmetic must not use any data-dependent branches, e.g., related
+ to carry propagation. Side-channel silent point addition is
+ straightforward, thanks to the unified formulas.
+
+ Scalar multiplication, multiplying a point by an integer, needs some
+ additional effort to implement in a side-channel silent manner. One
+ simple approach is to implement a side-channel silent conditional
+ assignment, and use it together with the binary algorithm to examine
+ one bit of the integer at a time.
+
+ Compared to other signature schemes, avoiding data-dependent branches
+ is easier due to side-channel silent modulo p arithmetic being easier
+ (with recommended curves) and having complete addition formulas
+ instead of having a number of special cases.
+
+ Note that the example implementations in this document do not attempt
+ to be side-channel silent.
+
+8.2. Randomness Considerations
+
+ EdDSA signatures are deterministic. This protects against attacks
+ arising from signing with bad randomness; the effects of which can,
+ depending on the algorithm, range up to full private key compromise.
+ It can be surprisingly hard to ensure good-quality random numbers,
+ and there have been numerous security failures relating to this.
+
+ Obviously, private key generation requires randomness, but due to the
+ fact that the private key is hashed before use, a few missing bits of
+ entropy doesn't constitute a disaster.
+
+ The basic signature verification is also deterministic. However,
+ some speedups by verifying multiple signatures at once do require
+ random numbers.
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 40]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+8.3. Use of Contexts
+
+ Contexts can be used to separate uses of the protocol between
+ different protocols (which is very hard to reliably do otherwise) and
+ between different uses within the same protocol. However, the
+ following SHOULD be kept in mind when using this facility:
+
+ The context SHOULD be a constant string specified by the protocol
+ using it. It SHOULD NOT incorporate variable elements from the
+ message itself.
+
+ Contexts SHOULD NOT be used opportunistically, as that kind of use
+ is very error prone. If contexts are used, one SHOULD require all
+ signature schemes available for use in that purpose support
+ contexts.
+
+ Contexts are an extra input, which percolate out of APIs; as such,
+ even if the signature scheme supports contexts, those may not be
+ available for use. This problem is compounded by the fact that
+ many times the application is not invoking the signing and
+ verification functions directly but via some other protocol.
+
+8.4. Signature Malleability
+
+ Some systems assume signatures are not malleable: that is, given a
+ valid signature for some message under some key, the attacker can't
+ produce another valid signature for the same message and key.
+
+ Ed25519 and Ed448 signatures are not malleable due to the
+ verification check that decoded S is smaller than l. Without this
+ check, one can add a multiple of l into a scalar part and still pass
+ signature verification, resulting in malleable signatures.
+
+8.5. Choice of Signature Primitive
+
+ Ed25519 and Ed25519ph have a nominal strength of 128 bits, whereas
+ Ed448 and Ed448ph have the strength of 224. While the lower strength
+ is sufficient for the foreseeable future, the higher level brings
+ some defense against possible future cryptographic advances. Both
+ are demolished by quantum computers just about the same.
+
+ The Ed25519ph and Ed448ph variants are prehashed. This is mainly
+ useful for interoperation with legacy APIs, since in most of the
+ cases, either the amount of data signed is not large or the protocol
+ is in the position to do digesting in ways better than just
+ prehashing (e.g., tree hashing or splitting the data). The
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 41]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ prehashing also makes the functions greatly more vulnerable to
+ weaknesses in hash functions used. These variants SHOULD NOT be
+ used.
+
+ Ed25519ctx and Ed448 have contexts. However, this is balanced by the
+ problems noted in Section 8.3 about contexts.
+
+ On the implementation front, Ed25519 is widely implemented and has
+ many high-quality implementations. The others have much worse
+ support.
+
+ In summary, if a high 128-bit security level is enough, use of
+ Ed25519 is RECOMMENDED; otherwise, Ed448 is RECOMMENDED.
+
+8.6. Mixing Different Prehashes
+
+ The schemes described in this document are designed to be resistant
+ to mixing prehashes. That is, it is infeasible to find a message
+ that verifies using the same signature under another scheme, even if
+ the original signed message was chosen. Thus, one can use the same
+ key pair for Ed25519, Ed25519ctx, and Ed25519ph and correspondingly
+ with Ed448 and Ed448ph.
+
+ The "SigEd25519 no Ed25519 collisions" constant is chosen to be a
+ textual string such that it does not decode as a point. Because the
+ inner hash input in the Ed25519 signature always starts with a valid
+ point, there is no way trivial collision can be constructed. In the
+ case of seed hash, trivial collisions are so unlikely, even with an
+ attacker choosing all inputs, that it is much more probable that
+ something else goes catastrophically wrong.
+
+8.7. Signing Large Amounts of Data at Once
+
+ Avoid signing large amounts of data at once (where "large" depends on
+ the expected verifier). In particular, unless the underlying
+ protocol does not require it, the receiver MUST buffer the entire
+ message (or enough information to reconstruct it, e.g., compressed or
+ encrypted version) to be verified.
+
+ This is needed because most of the time, it is unsafe to process
+ unverified data, and verifying the signature makes a pass through the
+ whole message, causing ultimately at least two passes through.
+
+ As an API consideration, this means that any Initialize Update
+ Finalize (IFU) verification interface is prone to misuse.
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 42]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ It is a bad idea to modify Ed25519 or Ed448 signing to be able to
+ create valid Ed25519/Ed448 signatures using an IUF interface with
+ only constant buffering. Pretty much any error in such would cause
+ catastrophic security failure.
+
+8.8. Multiplication by Cofactor in Verification
+
+ The given verification formulas for both Ed25519 and Ed448 multiply
+ points by the cofactor. While this is not strictly necessary for
+ security (in fact, any signature that meets the non-multiplied
+ equation will satisfy the multiplied one), in some applications it is
+ undesirable for implementations to disagree about the exact set of
+ valid signatures. Such disagreements could open up, e.g.,
+ fingerprinting attacks.
+
+8.9. Use of SHAKE256 as a Hash Function
+
+ Ed448 uses SHAKE256 as a hash function, even if SHAKE256 is
+ specifically defined not to be a hash function.
+
+ The first potentially troublesome property is that shorter outputs
+ are prefixes of longer ones. This is acceptable because output
+ lengths are fixed.
+
+ The second potentially troublesome property is failing to meet
+ standard hash security notions (especially with preimages). However,
+ the estimated 256-bit security level against collisions and preimages
+ is sufficient to pair with a 224-bit level elliptic curve.
+
+9. References
+
+9.1. Normative References
+
+ [FIPS202] National Institute of Standards and Technology, "SHA-3
+ Standard: Permutation-Based Hash and Extendable-Output
+ Functions", FIPS PUB 202, August 2015,
+ <http://dx.doi.org/10.6028/NIST.FIPS.202>.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, DOI
+ 10.17487/RFC2119, March 1997,
+ <http://www.rfc-editor.org/info/rfc2119>.
+
+ [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms
+ (SHA and SHA-based HMAC and HKDF)", RFC 6234,
+ DOI 10.17487/RFC6234, May 2011,
+ <http://www.rfc-editor.org/info/rfc6234>.
+
+
+
+
+Josefsson & Liusvaara Informational [Page 43]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ [RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
+ for Security", RFC 7748, DOI 10.17487/RFC7748, January
+ 2016, <http://www.rfc-editor.org/info/rfc7748>.
+
+9.2. Informative References
+
+ [CURVE25519]
+ Bernstein, D., "Curve25519: new Diffie-Hellman speed
+ records", DOI 10.1007/11745853_14, February 2006,
+ <http://cr.yp.to/ecdh.html>.
+
+ [ED25519-LIBGCRYPT-TEST-VECTORS]
+ Koch, W., "Ed25519 Libgcrypt test vectors", July 2014,
+ <http://git.gnupg.org/cgi-bin/
+ gitweb.cgi?p=libgcrypt.git;a=blob;f=tests/t-ed25519.inp;
+ h=e13566f826321eece65e02c593bc7d885b3dbe23;hb=refs/
+ heads/master>.
+
+ [ED25519-TEST-VECTORS]
+ Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B.
+ Yang, "Ed25519 test vectors", July 2011,
+ <http://ed25519.cr.yp.to/python/sign.input>.
+
+ [ED448] Hamburg, M., "Ed448-Goldilocks, a new elliptic curve",
+ June 2015, <http://eprint.iacr.org/2015/625>.
+
+ [EDDSA] Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B.
+ Yang, "High-speed high-security signatures",
+ DOI 10.1007/978-3-642-23951-9_9, September 2011,
+ <http://ed25519.cr.yp.to/ed25519-20110926.pdf>.
+
+ [EDDSA2] Bernstein, D., Josefsson, S., Lange, T., Schwabe, P., and
+ B. Yang, "EdDSA for more curves", July 2015,
+ <http://ed25519.cr.yp.to/eddsa-20150704.pdf>.
+
+ [Edwards-revisited]
+ Hisil, H., Wong, K., Carter, G., and E. Dawson, "Twisted
+ Edwards Curves Revisited",
+ DOI 10.1007/978-3-540-89255-7_20, December 2008,
+ <http://eprint.iacr.org/2008/522>.
+
+ [EFD-ADD] Bernstein, D. and T. Lange, "Projective coordinates for
+ Edwards curves", The 'add-2007-bl' addition formulas,
+ 2007, <http://www.hyperelliptic.org/EFD/g1p/
+ auto-edwards-projective.html#addition-add-2007-bl>.
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 44]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ [EFD-DBL] Bernstein, D. and T. Lange, "Projective coordinates for
+ Edwards curves", The 'dbl-2007-bl' doubling formulas,
+ 2007, <http://www.hyperelliptic.org/EFD/g1p/
+ auto-edwards-projective.html#doubling-dbl-2007-bl>.
+
+ [EFD-TWISTED-ADD]
+ Hisil, H., Wong, K., Carter, G., and E. Dawson, "Extended
+ coordinates with a=-1 for twisted Edwards curves", The
+ 'add-2008-hwcd-3' addition formulas, December 2008,
+ <http://www.hyperelliptic.org/EFD/g1p/
+ auto-twisted-extended-1.html#addition-add-2008-hwcd-3>.
+
+ [EFD-TWISTED-DBL]
+ Hisil, H., Wong, K., Carter, G., and E. Dawson, "Extended
+ coordinates with a=-1 for twisted Edwards curves", The
+ 'dbl-2008-hwcd' doubling formulas, December 2008,
+ <http://www.hyperelliptic.org/EFD/g1p/
+ auto-twisted-extended-1.html#doubling-dbl-2008-hwcd>.
+
+ [Faster-ECC]
+ Bernstein, D. and T. Lange, "Faster addition and doubling
+ on elliptic curves", DOI 10.1007/978-3-540-76900-2_3,
+ July 2007, <http://eprint.iacr.org/2007/286>.
+
+ [RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker,
+ "Randomness Requirements for Security", BCP 106, RFC 4086,
+ DOI 10.17487/RFC4086, June 2005,
+ <http://www.rfc-editor.org/info/rfc4086>.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 45]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+Appendix A. Ed25519/Ed448 Python Library
+
+ Below is an example implementation of Ed25519/Ed448 written in
+ Python; version 3.2 or higher is required.
+
+ Note: This code is not intended for production. Although it should
+ produce correct results for every input, it is slow and makes no
+ attempt to avoid side-channel attacks.
+
+import hashlib;
+import os;
+
+#Compute candidate square root of x modulo p, with p = 3 (mod 4).
+def sqrt4k3(x,p): return pow(x,(p + 1)//4,p)
+
+#Compute candidate square root of x modulo p, with p = 5 (mod 8).
+def sqrt8k5(x,p):
+ y = pow(x,(p+3)//8,p)
+ #If the square root exists, it is either y or y*2^(p-1)/4.
+ if (y * y) % p == x % p: return y
+ else:
+ z = pow(2,(p - 1)//4,p)
+ return (y * z) % p
+
+#Decode a hexadecimal string representation of the integer.
+def hexi(s): return int.from_bytes(bytes.fromhex(s),byteorder="big")
+
+#Rotate a word x by b places to the left.
+def rol(x,b): return ((x << b) | (x >> (64 - b))) & (2**64-1)
+
+#From little endian.
+def from_le(s): return int.from_bytes(s, byteorder="little")
+
+#Do the SHA-3 state transform on state s.
+def sha3_transform(s):
+ ROTATIONS = [0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,15,\
+ 21,8,18,2,61,56,14]
+ PERMUTATION = [1,6,9,22,14,20,2,12,13,19,23,15,4,24,21,8,16,5,3,\
+ 18,17,11,7,10]
+ RC = [0x0000000000000001,0x0000000000008082,0x800000000000808a,\
+ 0x8000000080008000,0x000000000000808b,0x0000000080000001,\
+ 0x8000000080008081,0x8000000000008009,0x000000000000008a,\
+ 0x0000000000000088,0x0000000080008009,0x000000008000000a,\
+ 0x000000008000808b,0x800000000000008b,0x8000000000008089,\
+ 0x8000000000008003,0x8000000000008002,0x8000000000000080,\
+ 0x000000000000800a,0x800000008000000a,0x8000000080008081,\
+ 0x8000000000008080,0x0000000080000001,0x8000000080008008]
+
+
+
+
+Josefsson & Liusvaara Informational [Page 46]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ for rnd in range(0,24):
+ #AddColumnParity (Theta)
+ c = [0]*5;
+ d = [0]*5;
+ for i in range(0,25): c[i%5]^=s[i]
+ for i in range(0,5): d[i]=c[(i+4)%5]^rol(c[(i+1)%5],1)
+ for i in range(0,25): s[i]^=d[i%5]
+ #RotateWords (Rho)
+ for i in range(0,25): s[i]=rol(s[i],ROTATIONS[i])
+ #PermuteWords (Pi)
+ t = s[PERMUTATION[0]]
+ for i in range(0,len(PERMUTATION)-1):
+ s[PERMUTATION[i]]=s[PERMUTATION[i+1]]
+ s[PERMUTATION[-1]]=t;
+ #NonlinearMixRows (Chi)
+ for i in range(0,25,5):
+ t=[s[i],s[i+1],s[i+2],s[i+3],s[i+4],s[i],s[i+1]]
+ for j in range(0,5): s[i+j]=t[j]^((~t[j+1])&(t[j+2]))
+ #AddRoundConstant (Iota)
+ s[0]^=RC[rnd]
+
+#Reinterpret octet array b to word array and XOR it to state s.
+def reinterpret_to_words_and_xor(s,b):
+ for j in range(0,len(b)//8):
+ s[j]^=from_le(b[8*j:][:8])
+
+#Reinterpret word array w to octet array and return it.
+def reinterpret_to_octets(w):
+ mp=bytearray()
+ for j in range(0,len(w)):
+ mp+=w[j].to_bytes(8,byteorder="little")
+ return mp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 47]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+#(semi-)generic SHA-3 implementation
+def sha3_raw(msg,r_w,o_p,e_b):
+ r_b=8*r_w
+ s=[0]*25
+ #Handle whole blocks.
+ idx=0
+ blocks=len(msg)//r_b
+ for i in range(0,blocks):
+ reinterpret_to_words_and_xor(s,msg[idx:][:r_b])
+ idx+=r_b
+ sha3_transform(s)
+ #Handle last block padding.
+ m=bytearray(msg[idx:])
+ m.append(o_p)
+ while len(m) < r_b: m.append(0)
+ m[len(m)-1]|=128
+ #Handle padded last block.
+ reinterpret_to_words_and_xor(s,m)
+ sha3_transform(s)
+ #Output.
+ out = bytearray()
+ while len(out)<e_b:
+ out+=reinterpret_to_octets(s[:r_w])
+ sha3_transform(s)
+ return out[:e_b]
+
+#Implementation of SHAKE256 functions.
+def shake256(msg,olen): return sha3_raw(msg,17,31,olen)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 48]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+#A (prime) field element.
+class Field:
+ #Construct number x (mod p).
+ def __init__(self,x,p):
+ self.__x=x%p
+ self.__p=p
+ #Check that fields of self and y are the same.
+ def __check_fields(self,y):
+ if type(y) is not Field or self.__p!=y.__p:
+ raise ValueError("Fields don't match")
+ #Field addition. The fields must match.
+ def __add__(self,y):
+ self.__check_fields(y)
+ return Field(self.__x+y.__x,self.__p)
+ #Field subtraction. The fields must match.
+ def __sub__(self,y):
+ self.__check_fields(y)
+ return Field(self.__p+self.__x-y.__x,self.__p)
+ #Field negation.
+ def __neg__(self):
+ return Field(self.__p-self.__x,self.__p)
+ #Field multiplication. The fields must match.
+ def __mul__(self,y):
+ self.__check_fields(y)
+ return Field(self.__x*y.__x,self.__p)
+ #Field division. The fields must match.
+ def __truediv__(self,y):
+ return self*y.inv()
+ #Field inverse (inverse of 0 is 0).
+ def inv(self):
+ return Field(pow(self.__x,self.__p-2,self.__p),self.__p)
+ #Field square root. Returns none if square root does not exist.
+ #Note: not presently implemented for p mod 8 = 1 case.
+ def sqrt(self):
+ #Compute candidate square root.
+ if self.__p%4==3: y=sqrt4k3(self.__x,self.__p)
+ elif self.__p%8==5: y=sqrt8k5(self.__x,self.__p)
+ else: raise NotImplementedError("sqrt(_,8k+1)")
+ _y=Field(y,self.__p);
+ #Check square root candidate valid.
+ return _y if _y*_y==self else None
+ #Make the field element with the same field as this, but
+ #with a different value.
+ def make(self,ival): return Field(ival,self.__p)
+ #Is the field element the additive identity?
+ def iszero(self): return self.__x==0
+ #Are field elements equal?
+ def __eq__(self,y): return self.__x==y.__x and self.__p==y.__p
+
+
+
+Josefsson & Liusvaara Informational [Page 49]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ #Are field elements not equal?
+ def __ne__(self,y): return not (self==y)
+ #Serialize number to b-1 bits.
+ def tobytes(self,b):
+ return self.__x.to_bytes(b//8,byteorder="little")
+ #Unserialize number from bits.
+ def frombytes(self,x,b):
+ rv=from_le(x)%(2**(b-1))
+ return Field(rv,self.__p) if rv<self.__p else None
+ #Compute sign of number, 0 or 1. The sign function
+ #has the following property:
+ #sign(x) = 1 - sign(-x) if x != 0.
+ def sign(self): return self.__x%2
+
+#A point on (twisted) Edwards curve.
+class EdwardsPoint:
+ #base_field = None
+ #x = None
+ #y = None
+ #z = None
+ def initpoint(self, x, y):
+ self.x=x
+ self.y=y
+ self.z=self.base_field.make(1)
+ def decode_base(self,s,b):
+ #Check that point encoding is the correct length.
+ if len(s)!=b//8: return (None,None)
+ #Extract signbit.
+ xs=s[(b-1)//8]>>((b-1)&7)
+ #Decode y. If this fails, fail.
+ y = self.base_field.frombytes(s,b)
+ if y is None: return (None,None)
+ #Try to recover x. If it does not exist, or if zero and xs
+ #are wrong, fail.
+ x=self.solve_x2(y).sqrt()
+ if x is None or (x.iszero() and xs!=x.sign()):
+ return (None,None)
+ #If sign of x isn't correct, flip it.
+ if x.sign()!=xs: x=-x
+ # Return the constructed point.
+ return (x,y)
+ def encode_base(self,b):
+ xp,yp=self.x/self.z,self.y/self.z
+ #Encode y.
+ s=bytearray(yp.tobytes(b))
+ #Add sign bit of x to encoding.
+ if xp.sign()!=0: s[(b-1)//8]|=1<<(b-1)%8
+ return s
+
+
+
+Josefsson & Liusvaara Informational [Page 50]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ def __mul__(self,x):
+ r=self.zero_elem()
+ s=self
+ while x > 0:
+ if (x%2)>0:
+ r=r+s
+ s=s.double()
+ x=x//2
+ return r
+ #Check that two points are equal.
+ def __eq__(self,y):
+ #Need to check x1/z1 == x2/z2 and similarly for y, so cross
+ #multiply to eliminate divisions.
+ xn1=self.x*y.z
+ xn2=y.x*self.z
+ yn1=self.y*y.z
+ yn2=y.y*self.z
+ return xn1==xn2 and yn1==yn2
+ #Check if two points are not equal.
+ def __ne__(self,y): return not (self==y)
+
+#A point on Edwards25519.
+class Edwards25519Point(EdwardsPoint):
+ #Create a new point on the curve.
+ base_field=Field(1,2**255-19)
+ d=-base_field.make(121665)/base_field.make(121666)
+ f0=base_field.make(0)
+ f1=base_field.make(1)
+ xb=base_field.make(hexi("216936D3CD6E53FEC0A4E231FDD6DC5C692CC76"+\
+ "09525A7B2C9562D608F25D51A"))
+ yb=base_field.make(hexi("666666666666666666666666666666666666666"+\
+ "6666666666666666666666658"))
+ #The standard base point.
+ @staticmethod
+ def stdbase():
+ return Edwards25519Point(Edwards25519Point.xb,\
+ Edwards25519Point.yb)
+ def __init__(self,x,y):
+ #Check the point is actually on the curve.
+ if y*y-x*x!=self.f1+self.d*x*x*y*y:
+ raise ValueError("Invalid point")
+ self.initpoint(x, y)
+ self.t=x*y
+ #Decode a point representation.
+ def decode(self,s):
+ x,y=self.decode_base(s,256);
+ return Edwards25519Point(x, y) if x is not None else None
+
+
+
+
+Josefsson & Liusvaara Informational [Page 51]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ #Encode a point representation.
+ def encode(self):
+ return self.encode_base(256)
+ #Construct a neutral point on this curve.
+ def zero_elem(self):
+ return Edwards25519Point(self.f0,self.f1)
+ #Solve for x^2.
+ def solve_x2(self,y):
+ return ((y*y-self.f1)/(self.d*y*y+self.f1))
+ #Point addition.
+ def __add__(self,y):
+ #The formulas are from EFD.
+ tmp=self.zero_elem()
+ zcp=self.z*y.z
+ A=(self.y-self.x)*(y.y-y.x)
+ B=(self.y+self.x)*(y.y+y.x)
+ C=(self.d+self.d)*self.t*y.t
+ D=zcp+zcp
+ E,H=B-A,B+A
+ F,G=D-C,D+C
+ tmp.x,tmp.y,tmp.z,tmp.t=E*F,G*H,F*G,E*H
+ return tmp
+ #Point doubling.
+ def double(self):
+ #The formulas are from EFD (with assumption a=-1 propagated).
+ tmp=self.zero_elem()
+ A=self.x*self.x
+ B=self.y*self.y
+ Ch=self.z*self.z
+ C=Ch+Ch
+ H=A+B
+ xys=self.x+self.y
+ E=H-xys*xys
+ G=A-B
+ F=C+G
+ tmp.x,tmp.y,tmp.z,tmp.t=E*F,G*H,F*G,E*H
+ return tmp
+ #Order of basepoint.
+ def l(self):
+ return hexi("1000000000000000000000000000000014def9dea2f79cd"+\
+ "65812631a5cf5d3ed")
+ #The logarithm of cofactor.
+ def c(self): return 3
+ #The highest set bit
+ def n(self): return 254
+ #The coding length
+ def b(self): return 256
+
+
+
+
+Josefsson & Liusvaara Informational [Page 52]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ #Validity check (for debugging)
+ def is_valid_point(self):
+ x,y,z,t=self.x,self.y,self.z,self.t
+ x2=x*x
+ y2=y*y
+ z2=z*z
+ lhs=(y2-x2)*z2
+ rhs=z2*z2+self.d*x2*y2
+ assert(lhs == rhs)
+ assert(t*z == x*y)
+
+#A point on Edwards448.
+class Edwards448Point(EdwardsPoint):
+ #Create a new point on the curve.
+ base_field=Field(1,2**448-2**224-1)
+ d=base_field.make(-39081)
+ f0=base_field.make(0)
+ f1=base_field.make(1)
+ xb=base_field.make(hexi("4F1970C66BED0DED221D15A622BF36DA9E14657"+\
+ "0470F1767EA6DE324A3D3A46412AE1AF72AB66511433B80E18B00938E26"+\
+ "26A82BC70CC05E"))
+ yb=base_field.make(hexi("693F46716EB6BC248876203756C9C7624BEA737"+\
+ "36CA3984087789C1E05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD98"+\
+ "08795BF230FA14"))
+ #The standard base point.
+ @staticmethod
+ def stdbase():
+ return Edwards448Point(Edwards448Point.xb,Edwards448Point.yb)
+ def __init__(self,x,y):
+ #Check that the point is actually on the curve.
+ if y*y+x*x!=self.f1+self.d*x*x*y*y:
+ raise ValueError("Invalid point")
+ self.initpoint(x, y)
+ #Decode a point representation.
+ def decode(self,s):
+ x,y=self.decode_base(s,456);
+ return Edwards448Point(x, y) if x is not None else None
+ #Encode a point representation.
+ def encode(self):
+ return self.encode_base(456)
+ #Construct a neutral point on this curve.
+ def zero_elem(self):
+ return Edwards448Point(self.f0,self.f1)
+ #Solve for x^2.
+ def solve_x2(self,y):
+ return ((y*y-self.f1)/(self.d*y*y-self.f1))
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 53]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ #Point addition.
+ def __add__(self,y):
+ #The formulas are from EFD.
+ tmp=self.zero_elem()
+ xcp,ycp,zcp=self.x*y.x,self.y*y.y,self.z*y.z
+ B=zcp*zcp
+ E=self.d*xcp*ycp
+ F,G=B-E,B+E
+ tmp.x=zcp*F*((self.x+self.y)*(y.x+y.y)-xcp-ycp)
+ tmp.y,tmp.z=zcp*G*(ycp-xcp),F*G
+ return tmp
+ #Point doubling.
+ def double(self):
+ #The formulas are from EFD.
+ tmp=self.zero_elem()
+ x1s,y1s,z1s=self.x*self.x,self.y*self.y,self.z*self.z
+ xys=self.x+self.y
+ F=x1s+y1s
+ J=F-(z1s+z1s)
+ tmp.x,tmp.y,tmp.z=(xys*xys-x1s-y1s)*J,F*(x1s-y1s),F*J
+ return tmp
+ #Order of basepoint.
+ def l(self):
+ return hexi("3ffffffffffffffffffffffffffffffffffffffffffffff"+\
+ "fffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c2"+\
+ "92ab5844f3")
+ #The logarithm of cofactor.
+ def c(self): return 2
+ #The highest set bit.
+ def n(self): return 447
+ #The coding length.
+ def b(self): return 456
+ #Validity check (for debugging).
+ def is_valid_point(self):
+ x,y,z=self.x,self.y,self.z
+ x2=x*x
+ y2=y*y
+ z2=z*z
+ lhs=(x2+y2)*z2
+ rhs=z2*z2+self.d*x2*y2
+ assert(lhs == rhs)
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 54]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+#Simple self-check.
+def curve_self_check(point):
+ p=point
+ q=point.zero_elem()
+ z=q
+ l=p.l()+1
+ p.is_valid_point()
+ q.is_valid_point()
+ for i in range(0,point.b()):
+ if (l>>i)&1 != 0:
+ q=q+p
+ q.is_valid_point()
+ p=p.double()
+ p.is_valid_point()
+ assert q.encode() == point.encode()
+ assert q.encode() != p.encode()
+ assert q.encode() != z.encode()
+
+#Simple self-check.
+def self_check_curves():
+ curve_self_check(Edwards25519Point.stdbase())
+ curve_self_check(Edwards448Point.stdbase())
+
+#PureEdDSA scheme.
+#Limitation: only b mod 8 = 0 is handled.
+class PureEdDSA:
+ #Create a new object.
+ def __init__(self,properties):
+ self.B=properties["B"]
+ self.H=properties["H"]
+ self.l=self.B.l()
+ self.n=self.B.n()
+ self.b=self.B.b()
+ self.c=self.B.c()
+ #Clamp a private scalar.
+ def __clamp(self,a):
+ _a = bytearray(a)
+ for i in range(0,self.c): _a[i//8]&=~(1<<(i%8))
+ _a[self.n//8]|=1<<(self.n%8)
+ for i in range(self.n+1,self.b): _a[i//8]&=~(1<<(i%8))
+ return _a
+ #Generate a key. If privkey is None, a random one is generated.
+ #In any case, the (privkey, pubkey) pair is returned.
+ def keygen(self,privkey):
+ #If no private key data is given, generate random.
+ if privkey is None: privkey=os.urandom(self.b//8)
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 55]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ #Expand key.
+ khash=self.H(privkey,None,None)
+ a=from_le(self.__clamp(khash[:self.b//8]))
+ #Return the key pair (public key is A=Enc(aB).
+ return privkey,(self.B*a).encode()
+ #Sign with key pair.
+ def sign(self,privkey,pubkey,msg,ctx,hflag):
+ #Expand key.
+ khash=self.H(privkey,None,None)
+ a=from_le(self.__clamp(khash[:self.b//8]))
+ seed=khash[self.b//8:]
+ #Calculate r and R (R only used in encoded form).
+ r=from_le(self.H(seed+msg,ctx,hflag))%self.l
+ R=(self.B*r).encode()
+ #Calculate h.
+ h=from_le(self.H(R+pubkey+msg,ctx,hflag))%self.l
+ #Calculate s.
+ S=((r+h*a)%self.l).to_bytes(self.b//8,byteorder="little")
+ #The final signature is a concatenation of R and S.
+ return R+S
+ #Verify signature with public key.
+ def verify(self,pubkey,msg,sig,ctx,hflag):
+ #Sanity-check sizes.
+ if len(sig)!=self.b//4: return False
+ if len(pubkey)!=self.b//8: return False
+ #Split signature into R and S, and parse.
+ Rraw,Sraw=sig[:self.b//8],sig[self.b//8:]
+ R,S=self.B.decode(Rraw),from_le(Sraw)
+ #Parse public key.
+ A=self.B.decode(pubkey)
+ #Check parse results.
+ if (R is None) or (A is None) or S>=self.l: return False
+ #Calculate h.
+ h=from_le(self.H(Rraw+pubkey+msg,ctx,hflag))%self.l
+ #Calculate left and right sides of check eq.
+ rhs=R+(A*h)
+ lhs=self.B*S
+ for i in range(0, self.c):
+ lhs = lhs.double()
+ rhs = rhs.double()
+ #Check eq. holds?
+ return lhs==rhs
+
+def Ed25519_inthash(data,ctx,hflag):
+ if (ctx is not None and len(ctx) > 0) or hflag:
+ raise ValueError("Contexts/hashes not supported")
+ return hashlib.sha512(data).digest()
+
+
+
+
+Josefsson & Liusvaara Informational [Page 56]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+#The base PureEdDSA schemes.
+pEd25519=PureEdDSA({\
+ "B":Edwards25519Point.stdbase(),\
+ "H":Ed25519_inthash\
+})
+
+def Ed25519ctx_inthash(data,ctx,hflag):
+ dompfx = b""
+ PREFIX=b"SigEd25519 no Ed25519 collisions"
+ if ctx is not None:
+ if len(ctx) > 255: raise ValueError("Context too big")
+ dompfx=PREFIX+bytes([1 if hflag else 0,len(ctx)])+ctx
+ return hashlib.sha512(dompfx+data).digest()
+
+pEd25519ctx=PureEdDSA({\
+ "B":Edwards25519Point.stdbase(),\
+ "H":Ed25519ctx_inthash\
+})
+
+def Ed448_inthash(data,ctx,hflag):
+ dompfx = b""
+ if ctx is not None:
+ if len(ctx) > 255: raise ValueError("Context too big")
+ dompfx=b"SigEd448"+bytes([1 if hflag else 0,len(ctx)])+ctx
+ return shake256(dompfx+data,114)
+
+pEd448 = PureEdDSA({\
+ "B":Edwards448Point.stdbase(),\
+ "H":Ed448_inthash\
+})
+
+#EdDSA scheme.
+class EdDSA:
+ #Create a new scheme object, with the specified PureEdDSA base
+ #scheme and specified prehash.
+ def __init__(self,pure_scheme,prehash):
+ self.__pflag = True
+ self.__pure=pure_scheme
+ self.__prehash=prehash
+ if self.__prehash is None:
+ self.__prehash = lambda x,y:x
+ self.__pflag = False
+ # Generate a key. If privkey is none, it generates a random
+ # privkey key, otherwise it uses a specified private key.
+ # Returns pair (privkey, pubkey).
+ def keygen(self,privkey): return self.__pure.keygen(privkey)
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 57]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+ # Sign message msg using specified key pair.
+ def sign(self,privkey,pubkey,msg,ctx=None):
+ if ctx is None: ctx=b"";
+ return self.__pure.sign(privkey,pubkey,self.__prehash(msg,ctx),\
+ ctx,self.__pflag)
+ # Verify signature sig on message msg using public key pubkey.
+ def verify(self,pubkey,msg,sig,ctx=None):
+ if ctx is None: ctx=b"";
+ return self.__pure.verify(pubkey,self.__prehash(msg,ctx),sig,\
+ ctx,self.__pflag)
+
+def Ed448ph_prehash(data,ctx):
+ return shake256(data,64)
+
+#Our signature schemes.
+Ed25519 = EdDSA(pEd25519,None)
+Ed25519ctx = EdDSA(pEd25519ctx,None)
+Ed25519ph = EdDSA(pEd25519ctx,lambda x,y:hashlib.sha512(x).digest())
+Ed448 = EdDSA(pEd448,None)
+Ed448ph = EdDSA(pEd448,Ed448ph_prehash)
+
+def eddsa_obj(name):
+ if name == "Ed25519": return Ed25519
+ if name == "Ed25519ctx": return Ed25519ctx
+ if name == "Ed25519ph": return Ed25519ph
+ if name == "Ed448": return Ed448
+ if name == "Ed448ph": return Ed448ph
+ raise NotImplementedError("Algorithm not implemented")
+
+Appendix B. Library Driver
+
+ Below is a command-line tool that uses the library above to perform
+ computations for interactive use or for self-checking.
+
+import sys
+import binascii
+
+from eddsa2 import Ed25519
+
+
+def munge_string(s, pos, change):
+ return (s[:pos] +
+ int.to_bytes(s[pos] ^ change, 1, "little") +
+ s[pos+1:])
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 58]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+# Read a file in the format of
+# http://ed25519.cr.yp.to/python/sign.input
+lineno = 0
+while True:
+ line = sys.stdin.readline()
+ if not line:
+ break
+ lineno = lineno + 1
+ print(lineno)
+ fields = line.split(":")
+ secret = (binascii.unhexlify(fields[0]))[:32]
+ public = binascii.unhexlify(fields[1])
+ msg = binascii.unhexlify(fields[2])
+ signature = binascii.unhexlify(fields[3])[:64]
+
+ privkey,pubkey = Ed25519.keygen(secret)
+ assert public == pubkey
+ assert signature == Ed25519.sign(privkey, pubkey, msg)
+ assert Ed25519.verify(public, msg, signature)
+ if len(msg) == 0:
+ bad_msg = b"x"
+ else:
+ bad_msg = munge_string(msg, len(msg) // 3, 4)
+ assert not Ed25519.verify(public,bad_msg,signature)
+ assert not Ed25519.verify(public, msg, munge_string(signature,20,8))
+ assert not Ed25519.verify(public,msg,munge_string(signature,40,16))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 59]
+
+RFC 8032 EdDSA: Ed25519 and Ed448 January 2017
+
+
+Acknowledgements
+
+ EdDSA and Ed25519 were initially described in a paper due to Daniel
+ J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin
+ Yang. The Ed448 curve is due to Mike Hamburg.
+
+ An earlier draft version of this document was coauthored by Niels
+ Moeller.
+
+ Feedback on this document was received from Werner Koch, Damien
+ Miller, Bob Bradley, Franck Rondepierre, Alexey Melnikov, Kenny
+ Paterson, and Robert Edmonds.
+
+ The Ed25519 test vectors were double checked by Bob Bradley using
+ three separate implementations (one based on TweetNaCl and two
+ different implementations based on code from SUPERCOP).
+
+Authors' Addresses
+
+ Simon Josefsson
+ SJD AB
+
+ Email: simon@josefsson.org
+ URI: http://josefsson.org/
+
+
+ Ilari Liusvaara
+ Independent
+
+ Email: ilariliusvaara@welho.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson & Liusvaara Informational [Page 60]
+