[noise] Symmetric-crypto overhaul and stateful hashing
Trevor Perrin
trevp at trevp.net
Mon Nov 12 03:50:35 PST 2018
On Mon, Nov 12, 2018 at 8:06 AM Trevor Perrin <trevp at trevp.net> wrote:
>
> MixHash() would be split into fixed-length and variable-length
> versions, so we can pack inputs into hash blocks efficiently (omitting
> length fields for fixed-length values). Length fields are added after
> inputs to support streaming, using right-parseable "byte-reversed
> varints" for efficiency.
Mistake already!
For any Squeeze() output, the transcript needs to be parseable from
the right to determine the type of output ("k", "h, "i", "r", "a").
Then the remainder of the transcript needs to be parseable from the
left to determine at what point in the transcript this output was
produced.
So variable-length fields need the length prepended for left-parsing,
and appended for right-parsing. At the moment the right-parsing only
affects the ASK label (and not ratcheting, as I incorrectly stated,
since ratcheting just has to zero-pad to the next hash block boundary,
thus it can be left-parsed unambiguously).
An alternative design would be to hash a type byte (and maybe length
field) before every input, so the transcript could branch at any point
and be left-parseable. But I don't think we need that flexibility, so
this way seems more efficient and simple.
MixHashVariableLen(x):
Absorb(len(x) || x) // len: varint
MixHashVariableLenRight(x):
Absorb(x || reverse_len(x)) // len: byte-reversed varint
...
transcript = len(name) || name || len(prologue) || prologue || e || es
k1 = HASH(transcript || "k")
transcript = transcript || s || ss
k2 = HASH(transcript || "k")
k3 = HASH(transcript || "i")
transcript = transcript || len(payload_ciphertext) || payload_ciphertext
h = HASH(transcript || "h")
ask = HASH(transcript || label || reverse_len(label) || "a")
Trevor
More information about the Noise
mailing list