Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
ietf-eddsa
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Simon Josefsson
ietf-eddsa
Commits
06e0835f
Commit
06e0835f
authored
Feb 21, 2015
by
Niels Möller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Describe point addition and decompression.
parent
c87b56a0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
162 additions
and
42 deletions
+162
-42
draft-josefsson-eddsa-ed25519.xml
draft-josefsson-eddsa-ed25519.xml
+162
-42
No files found.
draft-josefsson-eddsa-ed25519.xml
View file @
06e0835f
...
...
@@ -97,7 +97,7 @@
<t>
B generator of the group or subgroup of interest
</t>
<t>
n B
B added to itselt
n times.
</t>
<t>
n B
B added to itself
n times.
</t>
<t>
h_i the i'th bit of h
</t>
...
...
@@ -153,8 +153,6 @@ x3 = -------------------, y3 = -------------------
the generic EdDSA algorithm is given here.
</t>
<t>
EdDSA has seven parameters:
<!-- FIXME: Less general, make q a prime, and drop encoding,
fixing little-endian. -->
<list
style=
"numbers"
>
<t>
an integer b >= 10.
</t>
<t>
a cryptographic hash function H producing 2b-bit outputs.
</t>
...
...
@@ -234,6 +232,119 @@ x3 = -------------------, y3 = -------------------
(15112221349535400772501151409588531511454012693041857206046113283949847762202,
46316835694926478169428394003475163141307993866256225615783033603165251855960).
</t>
<section
title=
"Modular arithmetic"
>
<t>
For advise on how to implement arithmetic modulo p = 2^255
- 1 efficiently and securely, see
<xref
target=
"CURVE25519"
>
Curve25519
</xref>
. For
inversion modulo p, it is recommended to use the identity x^-1
= x^(p-2) (mod p).
</t>
<t>
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:
<list>
<t>
x^2 = a (mod p). Then x is a square root.
</t>
<t>
x^2 = -a (mod p). Then 2^((p-1)/4) x is a square root.
</t>
<t>
a is not a square modulo p.
</t>
</list>
</t>
</section>
<section
title=
"Encoding"
>
<t>
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].
</t>
<t>
A curve point (x,y), with coordiantes 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.
</t>
</section>
<section
title=
"Decoding"
>
<t>
Decoding a point, given as a 32-octet string, is a little
more complicated.
<list
style=
"numbers"
>
<t>
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.
</t>
<t>
To recover the x coordinate, the curve equation implies x^2
= (y^2 - 1) / (d y^2 + 1) (mod p). Since d is a non-square and
-1 is a square, the numerator, (d y^2 + 1), is always
invertible modulo 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 using
the following trick, to use a single modular powering for both
the inversion of v and the square root:
<figure>
<artwork>
(p+3)/8 3 (p-5)/8
x = (u/v) = u v (u v^7) (mod p)
</artwork>
</figure></t>
<t>
Again, there are three cases:
<list>
<t>
If v x^2 = u (mod p), x is a square root.
</t>
<t>
If v x^2 = -u (mod p), set x
<
-- x 2^((p-1)/4),
which is a square root.
</t>
<t>
Otherwise, no square root exists modulo p, and decoding
fails.
</t>
</list>
</t>
<t>
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).
</t>
</list>
</t>
</section>
<section
title=
"Point addition"
>
<t>
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.
</t>
<t>
The following formulas for adding two points, (x3,y3) =
(x1,y1)+(x2,y2) are described in
<xref
target=
"Edwards-revisited"
/>
, section 3.1. They are strongly
unified, i.e., they work for any pair of valid input points.
<!-- FIXME: Also refer to
http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
? -->
</t>
<figure>
<artwork>
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
</artwork>
</figure>
</section>
<section
title=
"Key Generation"
>
<t>
The secret is 32 octets (256 bits, corresponding to b) of
...
...
@@ -273,46 +384,55 @@ x3 = -------------------, y3 = -------------------
</section>
<section
title=
"Sign"
>
<t>
Hash the secret key, 32-octets, using SHA-512. Let h denote
the resulting digest. Construct the secret scalar a 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].
</t>
<t>
Compute SHA-512(prefix || M), where M is the message to be
signed. Interpret the 64-octet digest as a little-endian
integer r.
</t>
<t>
Compute the point rB. For efficiency, do this by first
reducing r modulo q, the group order of B. Let the string R be
the encoding of this point.
</t>
<t>
Compute SHA512(R || A || M), and interpret the 64-octet
digest as a little-endian integer k.
</t>
<t>
Compute s = (r + k a) mod q. For efficiency, again reduce k
modulo q first.
</t>
<t>
Form the signature of the concatenation of R (32 octets) and the
little-endian encoding of s (32 octets, three most significant
bits of the final octets always zero).
</t>
<t>
The imputs to the signing procedure is the secret key, a
32-octet string, and a message M of arbitrary size.
<list
style=
"numbers"
>
<t>
Hash the secret key, 32-octets, using SHA-512. Let h
denote the resulting digest. Construct the secret scalar a
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].
</t>
<t>
Compute SHA-512(prefix || M), where M is the message to
be signed. Interpret the 64-octet digest as a little-endian
integer r.
</t>
<t>
Compute the point rB. For efficiency, do this by first
reducing r modulo q, the group order of B. Let the string R
be the encoding of this point.
</t>
<t>
Compute SHA512(R || A || M), and interpret the 64-octet
digest as a little-endian integer k.
</t>
<t>
Compute s = (r + k a) mod q. For efficiency, again reduce
k modulo q first.
</t>
<t>
Form the signature of the concatenation of R (32 octets)
and the little-endian encoding of s (32 octets, three most
significant bits of the final octets always zero).
</t>
</list>
</t>
</section>
<section
title=
"Verify"
>
<t>
To verify a signature on a message M, 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
<
q. If the decoding fails, the signature is invalid.
<!-- FIXME: Should have a separate section on point
decompression, including some hints on how to do it
efficiently. -->
<t>
<list
style=
"numbers"
>
<t>
To verify a signature on a message M, 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
<
q. If the decoding fails, the signature is
invalid.
</t>
<t>
Compute SHA512(R || A || M), and interpret the 64-octet
digest as a little-endian integer k.
</t>
<t>
Check the group equation 8s B = 8 R + 8k A. It's
sufficient, but not required, to instead check s B = R + k
A.
</t>
</list>
</t>
<t>
Compute SHA512(R || A || M), and interpret the 64-octet
digest as a little-endian integer k.
</t>
<t>
Check the group equation 8s B = 8 R + 8k A. It's
sufficient, but not required, to instead check s B = R + k
A.
</t>
.
</section>
<section
title=
"Python illustration"
>
<t>
The rest of this section describes how Ed25519 can be
...
...
@@ -724,7 +844,7 @@ d25bf5f0595bbe24655141438e7a100b
the secret key.
</t>
<t>
To make an implementation side-channel silent in this way,
the modulo
q
arithmetic must not use any data-dependent
the modulo
p
arithmetic must not use any data-dependent
branches, e.g., related to carry propagation.
<!--FIXME: Refer
to curve25519 paper.-->
Side channel-silent point addition is
straight-forward, thanks to the unified formulas.
...
...
@@ -733,8 +853,8 @@ d25bf5f0595bbe24655141438e7a100b
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 together
with
binary algorithm to examine one bit of the integer at a
time.
with
the binary algorithm to examine one bit of the integer at
a
time.
</t>
<t>
Note that the example implementation in this document does
not attempt to be side-channel silent.
</t>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment