Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What could be the benefit of such a complicated function to test if variable is not zero?

I'm working on my master's thesis (computer science) on code which is written for post-quantum-secure signatures. The whole thing can be found here but is not important here. For my thesis I tried to explain a 'simple' function, which is not so simple at all.

The function tests, if a variable is non-zero in the galois-field GF(16). (GF(16) here can be understood as 4-bit unsigned integers). This function looks as follows:

static inline uint8_t gf16_is_nonzero(uint8_t a) {
    unsigned a4 = a & 0xf; // mask lowest 4 bits of a
    unsigned r = 0u - a4;  // set 4 high bits if a is nonzero
    r >>= 4;               // right-shift high bits into low bits
    return r & 1;          // return lowest bit
}

I understood how it works but I don't understand why this function needs to be this complex. Could there be a good reason for that? Good reasons could be performance or secureness (e.g. safety against timing attacks) benefits. Because if there are no such benefits, wouldn't it be smarter to write that function in an easy manner like:

static inline uint8_t gf16_is_nonzero(uint8_t a) {
    return (a & 15) != 0;
}

EDITS

This code is not written by me, it is written by crypto-researches, who are trying to get their PQ-algorithm standardized by NIST.

An easier approach for the second code snippet was suggested by TonyDelroy in the comments.

like image 812
linderd Avatar asked Jan 25 '23 19:01

linderd


1 Answers

The reason for this code is because it is branchless.

Testing for a condition tends to be an expensive operation, whereas addition, subtraction, and bitwise operators are not.

This however is premature optimization. With -O3, the first function compiles to this:

andl    $15, %edi
negl    %edi
shrl    $31, %edi
movl    %edi, %eax
ret

While the second function compiles to this:

andl    $15, %edi
setne   %al
ret

The moral of the story: write code that clearly states your intentions and let the compiler figure out the rest.

like image 139
dbush Avatar answered Jan 29 '23 11:01

dbush