### 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,...h represents the integer h + 2^8 h + ... + 2^248 h. 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,...,h. 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,...,h. 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!