From: Loup Vaillant Date: Mon, 29 Jul 2019 22:43:35 +0000 (+0200) Subject: Hoisted negations out of loops X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=c5b95903146e51d1498e954cbc66c8e3ff391699;p=Monocypher.git Hoisted negations out of loops 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. --- diff --git a/src/monocypher.c b/src/monocypher.c index c44e2ef..777d00d 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -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; } }