On Sat, 22 Aug 2026 20:23:22 GMT, Andrew Haley <[email protected]> wrote:
>> The existing arbitrary `conditionalSet()` benchmark is not necessarily
>> indicative of susceptibility to a side-channel attack in production code due
>> to a number reasons, including the use of non-constant input arguments and
>> the dependencies of intermediate operations due to adding between successive
>> `lookup()` calls when calculating point multiplication, as an example. As a
>> result, the problem being addressed is a benchmark issue, as the current
>> conditional set benchmark is nothing like what is utilized in EC production
>> operations. This is why I lifted the existing `lookup()` logic as a form of
>> measuring conditional set performance, which better emulates a production
>> state.
>>
>> The above code uses flag arguments that are incorrect which would generate
>> invalid bit masks, subsequently corrupting the associated limbs during
>> conditional sets. Even with non-binary flags, because the pair-wise
>> assignments use the same input, C2 could perform a bitwise OR of the two
>> masks and use the resulting mask only once for the conditional assignment.
>> As a result C2 may i) not need to reload registers for the second call, ii)
>> not need to store the result to memory from the first call when the second
>> call would overwrite the first, and iii) keep the intermediate limbs in
>> registers. Correcting the flag arguments to binary would make it even
>> easier for inlining as it could eliminate the the first call if the second
>> call has a 1 flag. In aggregate, this likely contributes to the 18% drop in
>> performance with intrinsics when using the above code, compared to a 52%
>> performance gain when using intrinsics with the originally proposed
>> solution. The goal is to try to reproduce
the same shape that we see in production EC operations.
>
>> The goal is to try to reproduce the same shape that we see in production EC
>> operations.
>
> Maybe I'm misunderstanding something, but here's what I think is problematic:
>
> We have an implementation that executes in constant time, but only if a
> compiler cannot predict a flag. It would take a little improvement in an
> optimizing compiler to generate two versions of the code, calling either one
> or the other depending on that flag. If it did,even with a non-constant flag
> the supposed constant-time implementation would be no such thing. Am I wrong?
I guess what @theRealAph is referring to is the following. Looking at the spec
of `MutableIntegerModuloP::conditionalSet`, it only accepts the second argument
being 0 or 1. If, we do profiling for `int` parameters, and see that they are
the only possible values of `set`, the compiler may emit code like this:
void conditionalSet(IntegerModuloP b, int set) {
if (set == 0) {
return conditionalSet(b, 0);
} else if (set == 1) {
return conditionalSet(b, 1);
} else {
trap();
}
}
Then, there is a risk of time-based speculation.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/32047#discussion_r3841730953