<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 14, 2018 at 3:13 PM, Christopher Wood <span dir="ltr"><<a href="mailto:christopherwood07@gmail.com" target="_blank">christopherwood07@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">On Wed, Jun 13, 2018 at 7:51 PM str4d <<a href="mailto:str4d@i2pmail.org">str4d@i2pmail.org</a>> wrote:<br>
><br>
> On 06/14/2018 08:18 AM, Trevor Perrin wrote:<br>
> > On Wed, Jun 13, 2018 at 4:40 PM, Christopher Wood <<br>
> > <a href="mailto:christopherwood07@gmail.com">christopherwood07@gmail.com</a>> wrote:<br>
> ><br>
> >> On Tue, Jun 12, 2018 at 10:20 AM Trevor Perrin <<a href="mailto:trevp@trevp.net">trevp@trevp.net</a>> wrote:><br>
> >> So the following sketch derives an Additional Symmetric Key (ASK) "master<br>
> >> key" from HKDF, which can then be used to create chains at a later point.<br>
> >>><br>
> >>> The idea is that we can use this during the handshake as well as during<br>
> >> Split(). We haven't used HKDF info before, but using it now means that<br>
> >> ask_master derivation just requires a single extra HMAC, since it can share<br>
> >> the HKDF-Extract step with the existing HKDF:<br>
> >>><br>
> >>> # During handshake<br>
> >>> ck, k = HKDF(ck, ikm)<br>
> >>> ask_master = HKDF(ck, ikm, info="ask")<br>
> >>><br>
> >>> # During split<br>
> >>> transport1, transport2 = HKDF(ck, zerolen)<br>
> >>> ask_master = HKDF(ck, zerolen, info="ask")<br>
> >>><br>
> >>> # Either case<br>
> >>> create_chains(labels):<br>
> >>> ask_chain1 = HMAC(ask_master, h || label1)<br>
> >>> ask_chain2 = HMAC(ask_master, h || label2)<br>
> >>> ask_chain3 = HMAC(ask_master, h || label3)<br>
> >>> ...<br>
> >>> delete ask_master<br>
> >><br>
> >> This is quite nice.<br>
><br>
> I agree :)<br>
><br>
> > Maybe an API vaguely like this?<br>
> ><br>
> > EnableASK():<br>
> > - sets a boolean that causes ASK master keys to be derived, both during<br>
> > the handshake and at the end of it.<br>
> ><br>
> > InitializeASK(labels):<br>
> > - Assuming ASK was enabled, and there is a non-empty ASK master key,<br>
> > derives a set of ASK chain keys from the ASK master key and the input<br>
> > labels, then deletes the ASK master key. This could be called multiple<br>
> > times, including after the handshake and during it, and replaces any<br>
> > previous ASK chains when called.<br>
> ><br>
> > GetASK(label)<br>
> > - Assuming ASK is enabled and initialized, returns the next key from the<br>
> > appropriate chain, and advances the appropriate ASK chain key, deleting the<br>
> > previous chain key.<br>
> ><br>
> > So if you don't EnableASK(), you don't pay any costs for deriving ASK<br>
> > master keys. If you do enable it, they you can call InitializeASK/GetASK<br>
> > either during a handshake or after it, to get ASKs with the same level of<br>
> > security as the current encryption keys.<br>
> This API is very similar to how my current draft implementation (of the<br>
> previous proposal) on snow is organised. I'll massage it to implement<br>
> the above proposal, and see if there are any pain points.<br>
<br>
</div></div>If the price of generating the additional ASKs is not prohibitively<br>
expensive (one HKDF per update), I<br>
would opt to remove the EnableASK() function altogether and always<br>
generate ASKs.</blockquote><div><br></div><div>Maybe not prohibitively expensive, but I think we should keep Noise's default behavior unchanged, and favor efficiency / stability / zero-cost extensions for things like this.</div><div><br></div><div>As seen in Rhys's recent thread, we have some interest from low-end embedded cases. Also we *already* do a lot of hashing during handshake due to HKDF, our use of separate key and transcript "chains", and separate hash/HKDF operations for each MixKey and MixHash. If anything, we should work out options for more efficient hashing.</div><div><br></div><div>Also we're trying to stabilize the core doc and write new features like this in extension docs, so that existing libraries aren't invalidated, but can easily mention the extensions they implement (if any).</div><div><br></div><div>So I think I'd prefer to have this as a zero-cost, opt-in extension that was written up in a separate doc, and which libraries and applications could explicitly choose to support.</div><div> </div><div>Trevor</div></div></div></div>