]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Clear an extra low bit in EdDSA exponent calculation.
authorSimon Tatham <anakin@pobox.com>
Sun, 10 May 2015 13:04:16 +0000 (14:04 +0100)
committerSimon Tatham <anakin@pobox.com>
Sun, 10 May 2015 13:05:57 +0000 (14:05 +0100)
The source paper, and OpenSSH, agree that the lowest bit index used
from the hash of the private key is bit 3, i.e. bits 0,1,2 at the
bottom are all zero. We were only clearing bits 0 and 1, which would
have worked for about half of keys. I must have got lucky during
testing!

sshecc.c

index 3db6434e8a6afda007e85fa5daeff826a43c7d88..5cda17be7d084e6a73ed9cd7584e2e7580b036e5 100644 (file)
--- a/sshecc.c
+++ b/sshecc.c
@@ -2204,9 +2204,10 @@ struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve
         }
         SHA512_Final(&s, hash);
 
-        /* The second part is simply turning the hash into a Bignum, however
-         * the 2^(b-2) bit *must* be set, and the bottom 2 bits *must* not be */
-        hash[0] &= 0xfc; /* Unset bottom two bits (if set) */
+        /* The second part is simply turning the hash into a Bignum,
+         * however the 2^(b-2) bit *must* be set, and the bottom 3
+         * bits *must* not be */
+        hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
         hash[31] &= 0x7f; /* Unset above (b-2) */
         hash[31] |= 0x40; /* Set 2^(b-2) */
         /* Chop off the top part and convert to int */
@@ -3364,9 +3365,10 @@ static unsigned char *ecdsa_sign(void *key, const char *data, int datalen,
 
             SHA512_Final(&hs, hash);
 
-            /* The second part is simply turning the hash into a Bignum, however
-             * the 2^(b-2) bit *must* be set, and the bottom 2 bits *must* not be */
-            hash[0] &= 0xfc; /* Unset bottom two bits (if set) */
+            /* The second part is simply turning the hash into a
+             * Bignum, however the 2^(b-2) bit *must* be set, and the
+             * bottom 3 bits *must* not be */
+            hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
             hash[31] &= 0x7f; /* Unset above (b-2) */
             hash[31] |= 0x40; /* Set 2^(b-2) */
             /* Chop off the top part and convert to int */