[noise] Test Vector Specification

Trevor Perrin trevp at trevp.net
Tue Nov 21 16:28:05 PST 2017

On Tue, Nov 21, 2017 at 4:33 AM, Alex <alex at centromere.net> wrote:
>>  - The responder fields ("resp_ephemeral", "resp_prologue", etc) are
>> optional for one-way handshakes, I think?
> The document states:
> init_* and resp_* (except the prologues)
> are optional. Thus, the `resp_ephemeral` field is already optional. As
> for `resp_prologue`, the current spec doesn't lead me to believe that
> it's optional. For example, section 5.3 specifies that the `Initialize`
> function is to unconditionally call `MixHash(prologue)`. Both parties
> must call `Initialize` regardless of the pattern employed, so I conclude
> that it's not optional, even for one-way handshakes.

Good points, you're right.

>>  - Should the prologue fields be optional in all cases (default to
>> empty / zero-length)?
> I think there is a meaningful distinction that should be made between a
> string which is zero-length and one which is not present (or null). As
> a result, I believe that the prologue is 100% required in all cases and
> can never be null. Having said that, I'm completely indifferent as to
> whether the file format should require its presence or whether it should
> give it a default value of a zero-length string.

I don't have a strong opinion here either.

>>  - Should "fail" be attached to a specific message, rather than the
>> protocol run as whole?
> This might be a good idea, since it allows greater specificity.

Yeah, I think we're both in favor of this.

>>  - We could also describe optional failure cases attached to messages,
>> e.g. invalid_public_key = true, in which case the implementation is
>> allowed to reject the message, or continue processing.
> In general, do you think it would be best to change the `fail` key from
> a boolean to a string whose value indicates the type of failure
> expected? In keeping with your example:
> "fail": "invalid_public_key"

Not sure about this.  Implementations might not provide granular error
messages, and there are reasons to avoid fine-grained error messages
(thinking of the Bleichenbacher or Vaudenay attacks on TLS).
Tentatively I think just indicating "this message is allowed to fail"
/ "required to fail" / "must succeed" seems enough.

> A null (or omitted) value would be considered non-failing.
> If we choose to adopt failure cases, I think each case should be
> represented in the test vector spec as a first-class citizen, including
> whether or not the failure is optional/ignorable. The failure cases I
> can think of are:
> 1. Invalid public key (ignorable)
> 2. Static key overwrite -- the remote party sent a static key when it
> was already provided by the local party (fatal)
> 3. Decryption error -- a key or payload failed to decrypt (fatal)
> 4. Key missing -- a particular key is required by the given handshake
> pattern but was not provided (fatal)

Steps 2 and 4 are testing the API more than protocol implementation.
I.e. the test vector's arguments are immediately invalid given the
pattern, and this is detectable before any messages are sent.

Hadn't thought about this before.  Is this an invalid test vector
(don't do it), or do we allow such vectors to ensure the
implementation's API can detect misuse?

>>  - The fallback testing is specific to the XX/IK "pipes" concept, but
>> as we consider other "compound" protocols this will probably become
>> inadequate, and we will need something more general.  Maybe it would
>> be best just to allow [init|resp]_remote_ephemeral so that fallback
>> patterns could be tested directly for now, and we can think more about
>> "compound" test vectors later?
> If `[init|resp]_remote_ephemeral` is provided, would that obviate the
> need for `fallback` and `fallback_pattern`?

Yes, at the level of testing individual, "linear" Noise protocols.

No, if you want to test a complete "Noise Pipes" IK->XXfallback or
some other compound protocol.

But "compound protocols" are a work in progress (see the recent
NoiseSocket, NoiseLink) threads.  So it might be best to leave that
out of scope in this test vector format, and we can have a separate
NoiseSocket / NoiseLink vectors spec later, that tests more
complicated / compound cases.


More information about the Noise mailing list