Christopher J Peikert writes:
> 4. Compute e := Decode(C0,Gamma').
> If e = Fail set e:=s and b:=0.
> 5. Compute C'1 := H(2,e).
> 6. If C'1 != C1 set e:=s and b:=0.
This is an excerpt from the specification of the decapsulation function.
The specification requires e to be set to s (and b to be set to 0;
otherwise b is 1) in both failure cases, Step 4 and Step 6, producing
output H(0,s,C).
If there's a Step 4 failure then Step 6 is a no-op, since e is already s
(and b is already 0). The rest of the algorithm shows that there is no
use of C'_1 after Step 6. Consequently, in the case of a Step 4 failure,
the computation using e in Step 5 is irrelevant to the output.
This fact opens up more implementation options, using whatever e you
want in Step 5 in case of failure, _but_ you still have to set e to s in
Step 6. This, once again, is exactly what the implementation note says:
As an implementation note, the output of decapsulation is unchanged
if “e←s” in Step 4 is changed to assign something else to e.
Implementors may prefer, e.g., to set e to a fixed n-bit string, or a
random n-bit string other than s. However, the definition of
decapsulation does depend on e being set to s in Step 6.
I already wrote essentially all of this in my previous message, the
message that Dr. Peikert (1) claims to be replying to, and (2) posts
various characterizations of, but (3) does not quote. I request that he
follow the traditional email-handling practice of quoting and replying
to each point, to reduce the risk of error and to assist readers
tracking the discussions.
> A natural interpretation of this -- in my opinion, the most natural one -- is:
> (a) in Step 4 you can replace "e := s" with "e := 00...0" (n bits);
> (b) but in Step 6 you must preserve the "e := s".
This "interpretation" would replace the specified mathematical function
with a different function, contradicting
(1) the paragraph's explicit statement that "the output of
decapsulation is unchanged" and
(2) the paragraph's explicit label as an "implementation note",
not to mention that this "interpretation" would make the paragraph have
the same meaning as the paragraph _without_ the final sentence (the
sentence that Mr. Fleming omitted), begging the question of why that
sentence is there.
Even for readers who manage to miss the final sentence, this is two
direct contradictions with what's stated at the beginning of the same
paragraph. This "interpretation" is simply not correct.
> (Notably, both "e := ..." assignments are behind conditionals, and the note
> says nothing about changing the logical control flow of the code.
I don't know what Dr. Peikert thinks he means by "the logical control
flow", so the claim of a change is hard to evaluate, never mind the
question of why this is supposed to be relevant. In the end everything
is fed through standard transformations to constant-time code, so the
data flow ends up being independent of inputs.
> In
> particular, there's no instruction that the outcome of the test in Step 4
> should influence the action taken in Step 6.)
The specification indisputably requires e to be set to s in both of the
failure cases, producing a final output of H(0,s,C) in those cases. The
implementation note correctly points out the implementor's freedom to
vary an intermediate computation without affecting the final output.
> Reader, do you find this to be a reasonable interpretation of the note?
An "interpretation" that contradicts what's stated in the text is
incorrect. Repeatedly claiming that an incorrect "interpretation" is
"natural" and "reasonable" does not change the fact that it's wrong.
> If so, Dan seems to think that you have "maliciously misinterpret[ed]"
> it.
What I stated was "If you maliciously misinterpret this by omitting the
'but'/'However' part then of course you get different results and a fake
contradiction." It's of course also possible for one person maliciously
misinterpreting it to deceive other, non-malicious, people, which is an
example of why something as important as standardizing post-quantum
crypto should have evaluation procedures designed to resist attack.
> In any case, this interpretation leads to a total break of CCA
> security, as Fleming has demonstrated.
"Doctor, doctor, it hurts when I don't do what the documentation tells
me to do."
There are some types of bugs in post-quantum software that are hard to
catch with standard verification techniques. This isn't one of them.
> Now let's consider the interpretation that Dan appears to have:
Many people expect the word "interpretation" to mean that there's an
ambiguity. There's no ambiguity here.
Furthermore, most people expect the word "appears" to indicate some lack
of clarity. I see nothing unclear in the message that Dr. Peikert claims
to be replying to here. If he thinks there's a lack of clarity in
something I wrote, the normal way forward would be to quote it and ask
for clarification.
> (a) in Step 4 you can replace "e := s" with "e := 00...0";
> (b) but for Step 6 you must change the control flow. Specifically:
> (b1) test whether e was 'Fail' in Step 4 (e has since been overwritten, but
> we can check if b=0);
> (b2) if so, then *unconditionally* set e:=s, regardless of whether C'1 != C1
> or not;
> (b3) otherwise, do Step 6 as written above.
> (It's plausible that this interpretation preserves CCA security, but I may have
> missed something, so no promises.)
Consider the following line of pseudocode:
6. If C'_1 != C_1, set b:=0. If b=0, set e:=s.
Notice that this line is much more concise, and much easier to read,
than the above series of several b-b1-b2-b3 lines.
Why, one wonders, was something so short and simple stated in such an
obfuscated b-b1-b2-b3 way, using vastly more space than necessary, with
a claim of a "change" in the "control flow" etc., a scary-sounding
comment about possible losses of CCA security, etc.?
Most readers seeing this obfuscated presentation of X won't take the
time to strip away the obfuscation---they'll simply assume, incorrectly,
that X really is so complicated, and they'll tend to wonder whether a
short implementation note could really have been saying something so
complicated. This obfuscation thus contributes to the effort to convince
readers to accept a wrong "interpretation" of the implementation note,
rather than taking the implementation note to mean exactly what it says.
> I'll freely grant that if you know why the tests in Steps 4 and 6 are there,
> and why those steps set e:=s --- perhaps because you know the subtleties of the
> CCA security proof --- and if you intelligently use this knowledge to
> extrapolate from the text of the implementation note, then you can see this
> interpretation as being consistent with it.
I don't see any _overt_ errors in the statement being "freely" granted
here. However, the paragraph tries to make readers believe that one
_needs_ to go to all this work to understand a simple implementation
note. This belief is simply wrong.
I already spelled out the data-flow details that allow implementors to
vary e in this way without changing the function being computed. Those
details are entirely about the structure of the function being computed.
Again, the function is unchanged, so the question of _why_ the function
is designed this way is irrelevant, and the question made no appearance
in my explanation.
More broadly, there's an impressive circularity between
(1) repeatedly talking about CCA security to make the reader think
that the function being computed is changing, and
(2) repeatedly claiming that the function being computed is changing
to make the reader think that there's a CCA security question,
all of which is completely out of whack with the fact that this is
explicitly an _implementation note_, correctly and explicitly saying
that it computes the _same_ function.
> But is this really the most natural interpretation? More to the point, is it
> one that implementors --- who may not have the above knowledge --- are likely
> to arrive at on their own from reading the note? I strongly doubt it. (No
> offense intended, implementors.)
Again biased wording ("natural", "strongly doubt", etc.) is being used
to push an "interpretation" of a paragraph that directly contradicts
what the paragraph says.
> At the very least, the note is ambiguous, and a perfectly reasonable
> reading of it leads to a devastating security failure.
No. The claimed ambiguity is resolved by what the note says. Calling an
incorrect interpretation "perfectly reasonable" does not make it so.
> So, the specification should be updated to ensure that there is no ambiguity.
We are talking about an explicitly labeled _implementation note_ that
explicitly and correctly says that it does _not_ change the function
being computed. The explicit text is not consistent with your claimed
"interpretation". Furthermore, it's simply wrong to label a request for
a change in the note as requesting a change in the specification; we
should all be clear about the roles of specifications, reference
implementations, further implementations, and further text.
---Dan
P.S. Side question for NIST: Is it okay to be putting extra text into
the subject line of OFFICIAL COMMENTs, as in this thread? This isn't
what the official links show, but it would generally be helpful for
tracking other discussions, for example to split the discussions of
Kyber's patent issues from the discussions of Kyber-512's security.