-
Notifications
You must be signed in to change notification settings - Fork 135
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
Improved bulletproof rewind scheme #105
Comments
Awesome work!
Why is knowledge of |
@chisa0a Switch commitments offset the blinding factor with |
Would it make sense to generalize to nonce_A = H(H(root_key|i_A)|commit) where i_A and i_B default to 0 and 1 (or 1 and 2 as you have) but could be chosen larger if the user wants to obfuscate her rewind info some more, at the cost of having to grind more if she can't remember the exact values used, but only an upper bound? |
@jaspervdm nice design 👍 1st question regarding
Without telling
2nd, (suggestion instead of question) regarding:
May I suggest use
nothing special but like the concept of |
@tromp I'm not convinced we should. It would complicate the code (we have to implement the grinding) and UX but in my opinion there is not a very clear upside. Anyone that doesn't want their outputs detected by others just shouldn't give out their @garyyu Thanks! Unfortunately the second suggestion would also break the scheme in a similar way, since a watch only wallet would know |
Okay, sorry it took me a bit to get through it, had to go through the existing implementation in secp-zkp to remind myself exactly what's going on. Very good improvement to what's there. It's still relatively simple and shouldn't be too difficult to implement, with the only real downside being a slight optional loss of privacy on the root wallet owner's side. I still very much wish we could store the restore information somewhere other than the bullet proof, but that's a problem for another day. If nobody finds any major issues with this over the next few days, I'm happy to start working towards getting this in for 1.1.0. If you wanted to insert support for the new scheme on the libsecp side and I can make the needed changes in grin-wallet and grin, that might work. But if you're too busy I can handle all of it, just let me know. |
Thanks for checking. I am happy to do the libsecp side of things, will get started on it this week. To be sure, we should include it in v2.0.0, not v1.1.0 right? |
Definitely, yes, and obviously targeting the hard fork block (all outputs before use old rewind scheme, all outputs after use new one). |
Just a quick reminder that there's not really an easy way to enforce all new transactions using the new rewind scheme. There could be pre-fork slates that get finalized post-fork. The only way to actually mandate that would be on the wallet side, by bumping slate version post-HF and not accepting old slates after the hardfork block. |
Depending on what we end up tweaking for the HF, it could definitely be the case that we invalidate old transactions. Think we need to discuss/clarify exactly what will change for the HF |
Great scheme, 👍 No particular remark or concern beyond what's been discussed, we should prolly start on a wiki page listing what we're breaking for the 2.0.0 HF, so we don't forget anything. |
Cool. A few questions/comments:
|
|
Ah, thank you. Just to make sure I'm clear on this: in the current scheme, |
In practice currently |
@ignopeverell I made an effort to start this, all please feel free to contributing and help with this: https://github.com/mimblewimble/docs/wiki/Release-planning |
Hi @jaspervdm, we are trying to do something similar to what you have done here. If you have a moment, I would appreciate any comments you may have on the issue I registered with Dalek: dalek-cryptography/bulletproofs#335. |
Edit 2019-06-10: rename
nonce_A
->rewind_nonce
,nonce_B
->private_nonce
, small change message contentsEdit 2019-05-25: fixed some inaccuracies
Edit 2019-05-22: clarified
nonce_B
for child walletsI would like to propose a new scheme for hiding information inside the Bulletproof, that will increase wallet flexibility.
Recap
For context I will briefly explain relevant parts of the Bulletproof generation process:
alpha
,rho
,tau_1
andtau_2
.mu = alpha + rho*x
, wherex
is a verifier challenge (it is derived from hashing public data)tau_x = tau_2*x^2 + tau_1*x + z^2*gamma
(*), wherez
is again a verifier challenge andgamma
is the secret key of the commitThe final proof contains (among other things)
mu
andtau_x
.In the current generation scheme, the nonce for the 4 secret variables is given by something like
H(root_key|commit)
. However,mu
is actually replaced withwhere
v
is the amount.A wallet can find its own outputs by going through each UTXO bulletproof and
mu
to find the amountv
and derivation path by subtracting itsmu
from themu'
in the BPgamma
, using the calculatedtau_1
,tau_2
and thetau_x
encoded in the proofgamma*G + v*H
is equal to the original commit, we know the output belongs to us (with extremely high probability).There are several downsides to this method:
root_key
, so there is no possibility for watch-only or child walletsH(root_key)
in the nonce, we are left with a similar issueNew scheme
In an attempt to solve these issues, here is a proposal for a new scheme. To prevent having to grind the old and new scheme, I suggest that any output created after the first hard fork be created with this scheme.
First we generate 2 nonces:
We use
rewind_nonce
to derivealpha
andrho
, andprivate_nonce
to derivetau_1
andtau_2
. This immediately solves problem 1) and 2) in the list.We also replace
mu
withWhere
flags
are 4 bytes:0|type|switch_commitment_scheme|derivation_depth
. The first byte is reserved for future use (hence the 0), the 2nd byte can be used to indicate different wallet types (regular, child wallet, musig), the 3rd byte can be used for different switch commitment types (0
for none,1
for the current one) and the final byte is used to store the level of the derivation path (assumed to be 3 in the old scheme). There should be enough room to encode all this information, since the path is 16 bytes andv
is 8 bytes, whilemu
can contain nearly 32.Wallet restore
For a wallet to find their own outputs, they need to know the extended public key. They calculate
mu
and from this findflags|path|v
. This operation will be successful for all outputs, but we can quickly discard most of them, namely the ones with unknown flag bytes. The left over ones are candidates for which we can use the derivation path and the extended public key (or secret key in the case of a hardened path), together with the amount to derive the candidate commitment. If the commitment matches the original, we know the output belongs to us. This solves problem 3) in the list.Conclusion
This enables different kind of wallets:
H(pub_root_key)
and the extended secret child key. They should use some other value forprivate_nonce
, for exampleH(H(child_key), commit)
. Children will be able to detect/create/spend their own outputs. Parents can detect/create/spend all of their child wallets. When scanning the chain children will detect candidate outputs from other children but there is some deniability here.pub_root_key
. This will allow users to detect their outputs, but not spend themOne thing to note is that the watch-only and multisig wallets are harder to use in combination with switch commitments, but I think not impossible. It would require knowing an additional extended public key, one that uses
J
instead ofG
as generator point.Any comments and suggestions are welcome! This idea has been brewing in my mind for a while and I think it will work pretty well, but I might have missed some downsides or problems.
The text was updated successfully, but these errors were encountered: