On Sun, Mar 26, 2017 at 04:19:58PM -0400, Ian Goldberg wrote:
On Sun, Mar 26, 2017 at 02:24:41PM +0200, Alec Muffett wrote:
Hi,
So: a bunch of us were discussing Prop224 Onion addresses, and their UX-malleability.
Specifically: that there are small bit fields in the current Prop224 Onion Address schema (eg: version, and other future structure?) which can be tweaked or amended without otherwise changing the functionality of the address, or without much changing what the user sees in the (say) browser address bar.
This is a point of significant concern because of issues like phishing and passing-off - by analogy: t0rpr0ject.0rg versus torproject.org - and other games that can be played with a prop224 address now, or in future, to game user experience.
We discussed the existing "hash the public key before base-32 encoding" approach, but hashing breaks the prop224 key blinding.
Ian Goldberg - thank you Ian - offered this attractive solution: apply a *reversible* "All Or Nothing Transform" (AONT) to the entire Prop224 Onion Address, prior to Base32 Encoding.
This way, even a single-bit mutation of (say) version number will have a "diffusion" effect, impacting ~ N/2 of the bits whilst having O(1) cost and being reversible so as not to impact the rest of Prop224.
The result would be onion addresses which are less "tamperable" / more deterministic, that closer to one-and-only-one published onion address will correspond to an onion endpoint.
What does the panel think?
One thing I thought of later is that, assuming the version field is "under" the AONT, then there is *no* visible version field in the final address, so you would have to commit to "For any possible future onion address of this fixed length, the first thing you have to do to decode it is this particular AONT." This seems a bit suboptimal to me. And since the version field basically *is* the tweakable field in the current prop224 addresses, maybe this actually isn't so useful after all for this version of the spec?
<talking-to-myself>
We could leave the version field outside the AONT, though, but commit to changing the paramaters of the AONT (in particular, the domain separation constant?) if we change the version number, so that an adversary changing the version number to "2" would just cause the client to throw an error (before version 2 exists) or be an invalid address (after version 2 exists)?
Then the address would look something like:
base32( AONT_1( pubkey || checksum ) || version=0x01 )
where AONT_1 is an unkeyed invertible function from 34(?)-byte strings to 34(?)-byte strings.
(Of course, then all addresses would end in "b", or something like that.)
</talking-to-myself>