]> git.codecow.com Git - Monocypher.git/commitdiff
Hoisted negations out of loops
authorLoup Vaillant <loup@loup-vaillant.fr>
Mon, 29 Jul 2019 22:43:35 +0000 (00:43 +0200)
committerLoup Vaillant <loup@loup-vaillant.fr>
Mon, 29 Jul 2019 22:43:35 +0000 (00:43 +0200)
Turns out compilers don't do this naturally, and this leads to
observable slow downs in some cases.

Also noted that we are relying on 2's complement representation (we
already were).  We could be more portable by going unsigned, but by this
logic the entire field arithmetic should go unsigned.  It's possible,
but it's not trivial.  I've kinda tried it in the past, and failed.

Every architecture of interest is 2's complement anyway, so I think this
will be good enough.

src/monocypher.c

index c44e2ef329f7867170b8e7654392938a502cf899..777d00daac76a25ff64abd76af6eb6a21457ecf2 100644 (file)
@@ -1026,8 +1026,9 @@ static void fe_sub (fe h,const fe f,const fe g){FOR(i,0,10) h[i] = f[i] - g[i];}
 
 static void fe_cswap(fe f, fe g, int b)
 {
+    i32 mask = -b; // rely on 2's complement: -1 = 0xffffffff
     FOR (i, 0, 10) {
-        i32 x = (f[i] ^ g[i]) & -b;
+        i32 x = (f[i] ^ g[i]) & mask;
         f[i] = f[i] ^ x;
         g[i] = g[i] ^ x;
     }
@@ -1035,8 +1036,9 @@ static void fe_cswap(fe f, fe g, int b)
 
 static void fe_ccopy(fe f, const fe g, int b)
 {
+    i32 mask = -b; // rely on 2's complement: -1 = 0xffffffff
     FOR (i, 0, 10) {
-        i32 x = (f[i] ^ g[i]) & -b;
+        i32 x = (f[i] ^ g[i]) & mask;
         f[i] = f[i] ^ x;
     }
 }