]> git.codecow.com Git - Monocypher.git/commitdiff
Allows crypto_sign() to overlap its message and output
authorLoup Vaillant <loup@loup-vaillant.fr>
Fri, 22 Sep 2017 22:59:13 +0000 (00:59 +0200)
committerLoup Vaillant <loup@loup-vaillant.fr>
Fri, 22 Sep 2017 22:59:13 +0000 (00:59 +0200)
Fixes #32

The signature output buffer was set before the last message read.  If
they overlaped, we would have a bogus signature.

src/monocypher.c

index f9de62be60a8d8013bb32c2538be4e5c4afe24e8..140543c1ac1f2c1948147405ffd91c88db8aa874 100644 (file)
@@ -1532,22 +1532,26 @@ void crypto_sign(u8        signature[64],
 
     // first half of the signature = "random" nonce times basepoint
     ge R;
+    u8 half_sig[32];
     ge_scalarmult_base(&R, r);
-    ge_tobytes(signature, &R);
+    ge_tobytes(half_sig, &R);
 
     // Hash R, the public key, and the message together.
     // It cannot be done in paralell with the first hash.
     u8 h_ram[64];
-    hash_ram(h_ram, signature, pk, message, message_size);
+    hash_ram(h_ram, half_sig, pk, message, message_size);
 
     i64 s[64]; // s = r + h_ram * a
-    FOR(i,  0, 32) { s[i] = (u64) r[i]; }
-    FOR(i, 32, 64) { s[i] = 0;          }
-    FOR(i,  0, 32) {
-        FOR(j, 0, 32) {
+    FOR (i,  0, 32) { s[i] = (u64) r[i]; }
+    FOR (i, 32, 64) { s[i] = 0;          }
+    FOR (i,  0, 32) {
+        FOR (j, 0, 32) {
             s[i+j] += h_ram[i] * (u64) a[j];
         }
     }
+    FOR (i, 0, 32) {
+        signature[i] = half_sig[i];
+    }
     modL(signature + 32, s);  // second half of the signature = s
 }