-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ZIP 32] Shielded Hierarchical Deterministic Wallets #157
Conversation
zip-0032.rst
Outdated
|
||
- *a* || *b* means the concatenation of sequences *a* then *b*. | ||
|
||
- [*k*] *P* means scalar multiplication in the group *P*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scalar multiplication of the (elliptic curve) group element P by the scalar k.
zip-0032.rst
Outdated
- BLAKE2b-512(*p*, *x*) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of 64 | ||
bytes, 16-byte personalization string *p*, and input *x*. | ||
|
||
- PRF\ :sup:`expand`\ (*sk, t*) := BLAKE2b-512("Zcash_ExpandSeed", *sk* || *t*) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: *sk*, *t*
(the comma should not be in italic :-) )
- We do not derive Sapling public keys directly, as this would prevent the use of diversified addresses. | ||
Instead, we derive Sapling full viewing keys, from which payment addresses can be generated. This maintains | ||
the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all | ||
transactions involving that address, which a Sapling full viewing key also enables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With hindsight, it would have been useful to support an "address derivation key" which allows creating (and linking) diversified addresses but without being able to decrypt notes sent to them. I don't see a way to do this with Sapling's current key derivation structure, though. We should consider this issue for the next circuit upgrade — at which time we'll have more experience with diversified addresses.
(Aside: Sapling payment addresses were intentionally made not to be "rediversifiable" –i.e. it is not possible to create one diversified address directly from another– as part of preventing Brian Warner's attack in which a note for one address is encrypted to a different address in order to attempt to link them. But that attack does not preclude support for an address derivation key, because we would not be trying to prevent linking of addresses given this key.)
zip-0032.rst
Outdated
Specification: Sprout key derivation | ||
==================================== | ||
|
||
For completeness, we define a system for deriving a tree of Sprout keys components. It is unlikely that this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/key/keys/
zip-0032.rst
Outdated
|
||
- ``coin_type``: a constant identifying the cybercoin that this subtree's keys are used with. For | ||
compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44 | ||
[#slip-0044]_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note that all testnets share coin_type
index 1.
zip-0032.rst
Outdated
|
||
Unlike BIP 44, neither Sprout nor Sapling have a `change` path level. This is because shielded addresses are | ||
never publicly visible in transactions, which means that sending change back to the originating address is | ||
indistinguishable from using a change address. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only makes sense if you already know that the motivation for using separate change addresses in Bitcoin was to attempt to improve privacy.
zip-0032.rst
Outdated
Wallets MUST support generating the default payment address (corresponding to the default diversifier). They | ||
MAY also support generating a stream of payment addresses for a given account, if they wish to maintain the | ||
user experience of giving a unique address to each recipient. Note that a given account can have a maximum of | ||
2\ :sup:`88` payment addresses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need some discussion of diversifier collisions here. If wallet implementors attempt to do this in the most obvious way, they will start to hit collisions after ~244 (or fewer, with lower probability) addresses. Should we define a PRP-based derivation method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correction: ~243.5 (because half of diversifiers are invalid). And the maximum number is 287.
18b1bc6
to
96a829b
Compare
@daira and I had a pairing to figure out how to derive pseudo-random diversifiers without hitting the 244 birthday bound on collisions, by using a PRP. We've decided to use FFX-A2 |
a69ef8c
to
30493b3
Compare
zip-0032.rst
Outdated
@@ -199,7 +199,7 @@ The 88-bit diversifiers for a Sapling extended key are derived from its diversif | |||
In order to reach the maximum possible diversifier range without running into the birthday bound, we use | |||
FF1-AES256 as a Pseudo-Random Permutation as follows: | |||
|
|||
- Let *j* be the index of the desired diversifier. | |||
- Let *j* be the index of the desired diversifier, in the range 0 .. 2\ :sup:`88`\ -1. | |||
- *d*\ :sub:`i,j` = FF1-AES256.Encrypt(*dk*\ :sub:`i`\ , "", I2LEBSP\ :sub:`88`\ (*j*)) | |||
|
|||
The default diversifier for a Sapling extended key is defined to be *d*\ :sub:`i,0`\ . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we need to be clearer here: it's not simply j = 0
, but the first j
that results in a valid diversifier.
32 bytes, 16-byte personalization string *p*, and input *x*. | ||
|
||
- BLAKE2b-512(*p*, *x*) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of | ||
64 bytes, 16-byte personalization string *p*, and input *x*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, does unkeyed BLAKE2b-512 in sequential mode, with an output digest length of 64 bytes
(and likewise for BLAKE2b-256
) convey the correct meaning? We want to indicate that the only difference between the two is the digest length (so maybe unkeyed BLAKE2b in [...]
, but that it is not the same thing as truncating (so maybe we need more than output digest length
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same wording as in the protocol spec, and I believe it's unambiguous.
zip-0032.rst
Outdated
parent address tag *parent_addr_tag* and child number *i*, is represented as a | ||
byte sequence:: | ||
|
||
I2LEOSP\ :sub:`8`\ (*depth*) || *parent_addr_tag* || I2LEOSP\ :sub:`32`\ (*i*) || *ASK* || *c* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put ASK
after c
to match the Sapling encodings.
f78fa32
to
1824b3d
Compare
Note that this means they are encoded in little-endian order, which is the opposite of BIP 32.
Signed-off-by: Daira Hopwood <[email protected]>
Hardened derivation is undefined for an extended FVK
Signed-off-by: Daira Hopwood <[email protected]>
Signed-off-by: Daira Hopwood <[email protected]>
Signed-off-by: Daira Hopwood <[email protected]>
Signed-off-by: Daira Hopwood <[email protected]>
Signed-off-by: Daira Hopwood <[email protected]>
Signed-off-by: Daira Hopwood <[email protected]>
…rent addresses. Signed-off-by: Daira Hopwood <[email protected]>
zip-0032.rst
Outdated
.. [#bip-0044] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets <https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki>`_ | ||
.. [#slip-0044] `SLIP 44: Registered coin types for BIP-0044 <https://github.com/satoshilabs/slips/blob/master/slip-0044.md>`_ | ||
.. [#bip-0173] `BIP 173: Base32 address format for native v0-16 witness outputs <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>`_ | ||
.. [#sapling-spec] `Zcash Protocol Specification, Version 2018.0-beta-21 or later [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/sapling.pdf>`_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update these links to protocol.pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filename changes weren't made until 2018.0-beta-25. But it's correct to update it to protocol.pdf if the version is changed to be later than that.
- *dk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x16] || *dk*\ :sub:`par`\ )) | ||
- *c*\ :sub:`i` = *I*\ :sub:`R` | ||
|
||
Deriving a child extended full viewing key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to "Deriving a normal child extended full viewing key from a parent extended full viewing key"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this implied? The subheading above it doesn't say "Deriving a child extended spending key from a parent extended spending key".
- *dk*\ :sub:`i` = truncate\ :sub:`32`\ (PRF\ :sup:`expand`\ (*I*\ :sub:`L`\ , [0x16] || *dk*\ :sub:`par`\ )) | ||
- *c*\ :sub:`i` = *I*\ :sub:`R` | ||
|
||
Diversifier derivation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dk
seems better than dki in this section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only if di,j is also changed to dj.
zip-0032.rst
Outdated
|
||
m_Sapling / purpose' / coin_type' / account' | ||
|
||
Wallets MUST support generating the default payment address (corresponding to the default diversifier). They |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps add 'as defined above' after 'default diversifier'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In summary to discussions, would change sentence to
"Furthermore, Wallets MUST support generating the default payment address (corresponding to the default diversifier as defined above) for any account they support".
zip-0032.rst
Outdated
- ToScalar(*x*) := LEOS2IP\ :sub:`512`\ (*x*) (mod *r*\ :sub:`J`\ ), where *r*\ :sub:`J` \ is the order | ||
of the Jubjub large prime subgroup. | ||
|
||
- DiversifyHash(*d*) maps a diversifier *d* to a base point on the Jubjub elliptic curve, or to ⊥ if the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps add 'prime order subgroup' after 'elliptic curve'
zip-0032.rst
Outdated
|
||
The above key path levels include an account identifier, which in all user interfaces is represented as a | ||
"bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling | ||
ZIP 32 derivation MUST support the following path:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add 'for any account' in {0,..,2^31-1}' ?
zip-0032.rst
Outdated
- Use *I*\ :sub:`L` as the master spending key *sk*\ :sub:`m`\ , and *I*\ :sub:`R` as the master chain code | ||
*c*\ :sub:`m`\ . | ||
- Calculate the master extended spending key *m*\ :sub:`Sapling` = (*ask*\ :sub:`m`\ , *nsk*\ :sub:`m`\ , | ||
*ovk*\ :sub:`m`\ , *dk*\ :sub:`m`\ , *c*\ :sub:`m`\ ) via the standard Sapling derivation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
via -> similarly - cause dk isn't in the Sapling derivation
zip-0032.rst
Outdated
---------------------- | ||
|
||
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key *dk*\ :sub:`i`\ . | ||
In order to reach the maximum possible diversifier range without running into the birthday bound, we use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate about what you mean 'running into the birthday problem'? I think you mean also you want to get some independence of diversifier sequences of different base keys. If I just want no collisions, I could define d_{i,j} = j.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, diversifiers should follow an independent random sequence for each ivk. Otherwise, the diversifier leaks information about how many previous diversifiers were obtained from that ivk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, this should be explained though.. added two new comments with suggested phrasings.
My ACK is to indicate that I approve of the design -- though I would personally have advocated against specifying a Sprout key derivation model. Also, I think it may be worth mentioning the security properties like BIP32 does. (We should indicate that using the same seed byte sequence for master key derivation in BIP32 and ZIP32 is fine, even though it may be obvious to some.) I'm confused about how this document progresses through the ZIP process, and whether we're supposed to label this as a draft or not. Do we not merge until we have test vectors and the spec is complete? |
zip-0032.rst
Outdated
@@ -329,7 +329,7 @@ relevant transactions. | |||
|
|||
The above key path levels include an account identifier, which in all user interfaces is represented as a | |||
"bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling | |||
ZIP 32 derivation MUST support the following path:: | |||
ZIP 32 derivation MUST support the following path for any account in range {0..2\ :sup:`31`\ -1}:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
account -> account'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Account is already defined earlier up as hardened, so the meaning here is clear enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and account
is in range 0..2^31-1
, while account'
is technically in range 2^31..2^32-1
which doesn't read as easily)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right.
zip-0032.rst
Outdated
---------------------- | ||
|
||
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key *dk*. | ||
In order to reach the maximum possible diversifier range without running into the birthday bound, we use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"without running into the birthday bound," --> "without running into repetitions due to the birthday bound,".
zip-0032.rst
Outdated
Diversifier derivation | ||
---------------------- | ||
|
||
The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key *dk*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add after sentence "To prevent the diversifier leaking how many diversified addresses have already been generated for an account; we make the sequence of diversifiers pseudorandom and uncorrelated to that of any other account."
No description provided.