Commit 06e0835f by Niels Möller

### Describe point addition and decompression.

parent c87b56a0
 ... ... @@ -97,7 +97,7 @@ B generator of the group or subgroup of interest n B B added to itselt n times. n B B added to itself n times. h_i the i'th bit of h ... ... @@ -153,8 +153,6 @@ x3 = -------------------, y3 = ------------------- the generic EdDSA algorithm is given here. EdDSA has seven parameters: an integer b >= 10. a cryptographic hash function H producing 2b-bit outputs. ... ... @@ -234,6 +232,119 @@ x3 = -------------------, y3 = ------------------- (15112221349535400772501151409588531511454012693041857206046113283949847762202, 46316835694926478169428394003475163141307993866256225615783033603165251855960).
For advise on how to implement arithmetic modulo p = 2^255 - 1 efficiently and securely, see Curve25519. For inversion modulo p, it is recommended to use the identity x^-1 = x^(p-2) (mod p). 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.
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 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.
Decoding a point, given as a 32-octet string, is a little more complicated. 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. 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: Again, there are three cases: If v x^2 = u (mod p), x is a square root. If v x^2 = -u (mod p), set x <-- x 2^((p-1)/4), which is a square root. Otherwise, no square root exists modulo p, and decoding fails. 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).
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 following formulas for adding two points, (x3,y3) = (x1,y1)+(x2,y2) are described in , section 3.1. They are strongly unified, i.e., they work for any pair of valid input points.
The secret is 32 octets (256 bits, corresponding to b) of ... ... @@ -273,46 +384,55 @@ x3 = -------------------, y3 = -------------------
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]. Compute SHA-512(prefix || M), where M is the message to be signed. Interpret the 64-octet digest as a little-endian integer r. 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. Compute SHA512(R || A || M), and interpret the 64-octet digest as a little-endian integer k. Compute s = (r + k a) mod q. For efficiency, again reduce k modulo q first. 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). The imputs to the signing procedure is the secret key, a 32-octet string, and a message M of arbitrary size. 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]. Compute SHA-512(prefix || M), where M is the message to be signed. Interpret the 64-octet digest as a little-endian integer r. 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. Compute SHA512(R || A || M), and interpret the 64-octet digest as a little-endian integer k. Compute s = (r + k a) mod q. For efficiency, again reduce k modulo q first. 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).
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. 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. Compute SHA512(R || A || M), and interpret the 64-octet digest as a little-endian integer k. Check the group equation 8s B = 8 R + 8k A. It's sufficient, but not required, to instead check s B = R + k A. Compute SHA512(R || A || M), and interpret the 64-octet digest as a little-endian integer k. Check the group equation 8s B = 8 R + 8k A. It's sufficient, but not required, to instead check s B = R + k A..
The rest of this section describes how Ed25519 can be ... ... @@ -724,7 +844,7 @@ d25bf5f0595bbe24655141438e7a100b the secret key. 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. 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. Note that the example implementation in this document does not attempt to be side-channel silent. ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!