Commit d47f6df0 authored by Simon Josefsson's avatar Simon Josefsson

fix

parent f491d935
......@@ -69,6 +69,8 @@ Table of Contents
4.3. Sign . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4.4. Verify . . . . . . . . . . . . . . . . . . . . . . . . . 5
5. Ed25519 . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.1. Key Generation . . . . . . . . . . . . . . . . . . . . . 5
5.2. Python illustration . . . . . . . . . . . . . . . . . . . 6
6. Security considerations . . . . . . . . . . . . . . . . . . . 10
6.1. Side-channel leaks . . . . . . . . . . . . . . . . . . . 10
7. Test Vectors for Ed25519 . . . . . . . . . . . . . . . . . . 10
......@@ -103,8 +105,6 @@ Table of Contents
4. Small public keys (32 bytes) and signatures (64 bytes).
5. The formulas are "strongly unified", i.e., they are valid for all
points on the curve, with no exceptions. This obviates the need
......@@ -114,6 +114,8 @@ Josefsson & Moeller Expires August 21, 2015 [Page 2]
Internet-Draft EdDSA & Ed25519 February 2015
5. The formulas are "strongly unified", 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.
......@@ -158,9 +160,7 @@ Internet-Draft EdDSA & Ed25519 February 2015
curve, with no exceptions. In particular, the denominators are non-
zero for all input points.
There are more efficient formulas, which are still strongly unified,
which use homogeneous coordinates to avoid the expensive modulo q
inversions. See [Faster-ECC] and [Edwards-revisited].
......@@ -170,6 +170,10 @@ Josefsson & Moeller Expires August 21, 2015 [Page 3]
Internet-Draft EdDSA & Ed25519 February 2015
There are more efficient formulas, which are still strongly unified,
which use homogeneous coordinates to avoid the expensive modulo q
inversions. See [Faster-ECC] and [Edwards-revisited].
4. EdDSA
EdDSA is a digital signature system with several parameters. The
......@@ -217,10 +221,6 @@ Internet-Draft EdDSA & Ed25519 February 2015
Josefsson & Moeller Expires August 21, 2015 [Page 4]
Internet-Draft EdDSA & Ed25519 February 2015
......@@ -246,41 +246,56 @@ Internet-Draft EdDSA & Ed25519 February 2015
5. Ed25519
Ed25519 is EdDSA instantiated with b=256, H being SHA-512 [RFC4634],
q is the prime 2^255-19, the 255-bit encoding of GF(2^255-19) being
the little-endian encoding of {0, 1, ..., 2^255-20}, l is the prime
2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed, d = -121665/121666 which
is a member of GF(q), and B is the unique point (x, 4/5) in E for
which x is positive. The curve q, prime l, d and B follows from
[I-D.irtf-cfrg-curves].
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.
First some preliminaries that will be needed.
Theoretically, Ed25519 is EdDSA instantiated with b=256, H being
SHA-512 [RFC4634], q is the prime 2^255-19, the 255-bit encoding of
GF(2^255-19) being the little-endian encoding of {0, 1, ...,
2^255-20}, l is the prime 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed,
d = -121665/121666 which is a member of GF(q), and B is the unique
point (x, 4/5) in E for which x is positive. The curve q, prime l, d
and B follows from [I-D.irtf-cfrg-curves].
5.1. Key Generation
The secret is 32 byte (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 secret using SHA-512, forming a sequence 64-byte
large buffer. Only the lower 32 bytes are used for generating
the public key.
2. Prune the buffer. In C terminology:
buf[0] &= ~0x07;
buf[0] &= 0x7F;
buf[31] |= 0x40;
3. Perform a known-base-point scalar multiplication of the buffer
and B = (15112221349535400772501151409588531511454012693041857206
Josefsson & Moeller Expires August 21, 2015 [Page 5]
Internet-Draft EdDSA & Ed25519 February 2015
046113283949847762202,4631683569492647816942839400347516314130799
3866256225615783033603165251855960).
4. Encode the resulting value (which is called aB earlier) and
output it as the 32-byte public key.
5.2. Python illustration
Josefsson & Moeller Expires August 21, 2015 [Page 5]
Internet-Draft EdDSA & Ed25519 February 2015
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.
First some preliminaries that will be needed.
import hashlib
......@@ -312,21 +327,6 @@ Internet-Draft EdDSA & Ed25519 February 2015
......@@ -788,6 +788,9 @@ Internet-Draft EdDSA & Ed25519 February 2015
11.2. Informative References
[RFC4086] Eastlake, D., Schiller, J., and S. Crocker, "Randomness
Requirements for Security", BCP 106, RFC 4086, June 2005.
[EDDSA] Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B.
Yang, "High-speed high-security signatures", WWW
http://ed25519.cr.yp.to/ed25519-20110926.pdf, September
......@@ -832,9 +835,6 @@ Appendix A. Ed25519 Python Library
import hashlib
def sha512(s):
return hashlib.sha512(s).digest()
Josefsson & Moeller Expires August 21, 2015 [Page 15]
......@@ -842,6 +842,9 @@ Josefsson & Moeller Expires August 21, 2015 [Page 15]
Internet-Draft EdDSA & Ed25519 February 2015
def sha512(s):
return hashlib.sha512(s).digest()
# Base field Z_p
p = 2**255 - 19
......@@ -887,9 +890,6 @@ def point_mul(s, P):
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:
......@@ -898,6 +898,9 @@ Josefsson & Moeller Expires August 21, 2015 [Page 16]
Internet-Draft EdDSA & Ed25519 February 2015
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
......@@ -943,9 +946,6 @@ def point_compress(P):
def point_decompress(s):
if len(s) != 32:
raise Exception("Invalid input length for decompression")
y = int.from_bytes(s, "little")
sign = y >> 255
......@@ -954,6 +954,9 @@ Josefsson & Moeller Expires August 21, 2015 [Page 17]
Internet-Draft EdDSA & Ed25519 February 2015
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)
......@@ -999,9 +1002,6 @@ def verify(public, msg, signature):
return False
Rs = signature[:32]
R = point_decompress(Rs)
if not R:
return False
s = int.from_bytes(signature[32:], "little")
......@@ -1010,6 +1010,9 @@ Josefsson & Moeller Expires August 21, 2015 [Page 18]
Internet-Draft EdDSA & Ed25519 February 2015
if not R:
return False
s = int.from_bytes(signature[32:], "little")
h = sha512_modq(Rs + public + msg)
sB = point_mul(s, G)
hA = point_mul(h, A)
......@@ -1055,9 +1058,6 @@ Appendix B. Library driver
lineno = 0
while True:
line = sys.stdin.readline()
if not line:
break
lineno = lineno + 1
......@@ -1066,6 +1066,9 @@ Josefsson & Moeller Expires August 21, 2015 [Page 19]
Internet-Draft EdDSA & Ed25519 February 2015
if not line:
break
lineno = lineno + 1
print(lineno)
fields = line.split(":")
secret = (binascii.unhexlify(fields[0]))[:32]
......@@ -1114,7 +1117,4 @@ Authors' Addresses
Josefsson & Moeller Expires August 21, 2015 [Page 20]
<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC4086 PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.4086.xml'>
<!ENTITY RFC4634 PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.4634.xml'>
<!ENTITY CURVES PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.irtf-cfrg-curves.xml'>
]>
......@@ -212,24 +213,61 @@ x3 = -------------------, y3 = -------------------
<section title="Ed25519">
<t>Ed25519 is EdDSA instantiated with b=256, H being <xref
target="RFC4634">SHA-512</xref>, q is the prime 2^255-19, the
255-bit encoding of GF(2^255-19) being the little-endian
encoding of {0, 1, ..., 2^255-20}, l is the prime 2^252 +
0x14def9dea2f79cd65812631a5cf5d3ed, d = -121665/121666 which is
a member of GF(q), and B is the unique point (x, 4/5) in E for
which x is positive. The curve q, prime l, d and B follows from
<xref target="I-D.irtf-cfrg-curves"/>.</t>
<t>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.</t>
<t>First some preliminaries that will be needed.</t>
<t>Theoretically, Ed25519 is EdDSA instantiated with b=256, H
being <xref target="RFC4634">SHA-512</xref>, q is the prime
2^255-19, the 255-bit encoding of GF(2^255-19) being the
little-endian encoding of {0, 1, ..., 2^255-20}, l is the prime
2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed, d = -121665/121666
which is a member of GF(q), and B is the unique point (x, 4/5)
in E for which x is positive. The curve q, prime l, d and B
follows from <xref target="I-D.irtf-cfrg-curves"/>.</t>
<section title="Key Generation">
<t>The secret is 32 byte (256 bits, corresponding to b) of
cryptographically-secure random data. See <xref
target="RFC4086" /> for a discussion about randomness.</t>
<t>The 32-byte public key is generated by the following steps.
<list style="numbers">
<t>Hash the 32-byte secret using SHA-512, forming a sequence
64-byte large buffer. Only the lower 32 bytes are used for
generating the public key.</t>
<t>Prune the buffer. In C terminology:
<figure>
<artwork>
buf[0] &amp;= ~0x07;
buf[0] &amp;= 0x7F;
buf[31] |= 0x40;
</artwork>
</figure>
</t>
<t>Perform a known-base-point scalar multiplication of the
buffer and B =
(15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960).</t>
<t>Encode the resulting value (which is called aB earlier)
and output it as the 32-byte public key.</t>
</list></t>
</section>
<section title="Python illustration">
<t>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.</t>
<t>First some preliminaries that will be needed.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
import hashlib
def sha512(s):
......@@ -250,12 +288,12 @@ q = 2**252 + 27742317777372353535851937790883648493
def sha512_modq(s):
return int.from_bytes(sha512(s), "little") % q
]]></artwork>
</figure>
</figure>
<t>Then follows functions to perform point operations.</t>
<t>Then follows functions to perform point operations.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
# Points are represented as tuples (X, Y, Z, T) of extended coordinates,
# with x = X/Z, y = Y/Z, x*y = T/Z
......@@ -289,12 +327,12 @@ def point_equal(P, Q):
return False
return True
]]></artwork>
</figure>
</figure>
<t>Now follows functions for point compression.</t>
<t>Now follows functions for point compression.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
# Square root of -1
modp_sqrt_m1 = pow(2, (p-1) // 4, p)
......@@ -343,12 +381,12 @@ def point_decompress(s):
else:
return (x, y, 1, x*y % p)
]]></artwork>
</figure>
</figure>
<t>These are functions for manipulating the secret.</t>
<t>These are functions for manipulating the secret.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
def secret_expand(secret):
if len(secret) != 32:
raise Exception("Bad size of private key")
......@@ -362,12 +400,12 @@ def secret_to_public(secret):
(a, dummy) = secret_expand(secret)
return point_compress(point_mul(a, G))
]]></artwork>
</figure>
</figure>
<t>The signature function works as below.</t>
<t>The signature function works as below.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
def sign(secret, msg):
a, prefix = secret_expand(secret)
A = point_compress(point_mul(a, G))
......@@ -378,12 +416,12 @@ def sign(secret, msg):
s = (r + h * a) % q
return Rs + int.to_bytes(s, 32, "little")
]]></artwork>
</figure>
</figure>
<t>And finally the verification function.</t>
<t>And finally the verification function.</t>
<figure>
<artwork><![CDATA[
<figure>
<artwork><![CDATA[
def verify(public, msg, signature):
if len(public) != 32:
raise Exception("Bad public-key length")
......@@ -402,7 +440,9 @@ def verify(public, msg, signature):
hA = point_mul(h, A)
return point_equal(sB, point_add(R, hA))
]]></artwork>
</figure>
</figure>
</section>
</section>
......@@ -663,6 +703,8 @@ d25bf5f0595bbe24655141438e7a100b
<references title="Informative References">
&RFC4086;
<reference anchor="EDDSA">
<front>
<title>High-speed high-security signatures</title>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment