seraphis-migration / wallet3

Info and discussions about a hypothetical full 'wallet2' rewrite from scratch
MIT License
13 stars 0 forks source link

First draft about the audit proofs #42

Open DangerousFreedom1984 opened 1 year ago

DangerousFreedom1984 commented 1 year ago

Hello, I would like to make some comments about the audit framework currently and ask for a first review for the one in Seraphis.

Legacy:

Regarding Seraphis:

I may have stated wrong phrases (it might be interesting to discuss the last comments in the ReserveProofs) so I will continue working in the audit proofs but any comment is very welcome to improve this first draft already. If everything seems to be fine, I will move to implementing it.

Thank you! draft_sp.pdf

UkoeHB commented 1 year ago

He would have to scan the whole blockchain and get all the transactions that the specific output (stealth-address) appeared. It looks a bit unfeasibly to me.

This is not that hard, you just need enough storage and a little program to build a table of onetime addresses mapped to a list of the key images from txs where those onetime addresses were referenced as ring members. Then when validating an UnspentProof you just consult that table. (a little more work would be necessary if you want to do UnspentProofs for a certain range of blocks on-chain)

DangerousFreedom1984 commented 1 year ago

Yeah, the execution of UnspentProofs is not that expensive. The problem I see is building this table. How the verifier can build it quickly? The only solution I see is scanning the whole blockchain from the moment that the output was created. Certainly he can't believe that the prover will provide all the information about all the rings that it appeared.

UkoeHB commented 1 year ago

Maybe the verifier can't build it quickly, and that's just the price of using UnspentProofs.

DangerousFreedom1984 commented 1 year ago

Ok. I believe it is worth to implement it. But in the verification side would be good to let a message saying that it may take some time to verify :p I will think about the corresponding proof in Seraphis and write about it soon.

UkoeHB commented 1 year ago

SpendProofSpV1 A more efficient way of doing it would be using the grootle proof to recreate the group signature

This is not sufficient. Grootle proofs only prove membership (and anyone can make a membership proof), they say nothing about whether you own the enotes that were spent. You need to re-create seraphis composition proofs on all the inputs, then check that they verify using the same key images as those from the tx.

OutProofSpV1

You can just publish the enote ephemeral privkey r_t for each non-selfsend output, plus the recipient address. Then the verifier can make a JamtisPaymentProposalV1, covert it to a SpOutputProposalV1, extract the SpEnoteV1 (make_v1_outputs_v1()), and check if the result equals the enote found in the relevant tx (and that the associated enote ephemeral pubkey matches the one from the tx). I'm not sure if there is a way to do it for selfsend enotes without leaking private keys.

InProofSpV1

The Diffie-Hellman stuff is all X25519, so I don't know if you can actually make signatures easily. There is definitely not an extensive X25519 library ready to go for that.

One thing you could do is make a modified seraphis composition proof for the enote. First add an offset x X to the onetime address, then make a composition proof on the modified onetime address and also a Schnorr signature on x X. The offset should ensure the resulting composition proof won't link you to the composition proof you make when you spend that enote (i.e. you are making a fake key image).

If you can make a composition proof then the verifier can assume you also know the amount commitment opening, so there is no need to prove anything about that. EDIT: but you probably want to include the amount and commitment blinding factor so the verifier can learn the enote amount and check the amount commitment.

P.S. It might be better to rename this to SpEnoteOwnershipProofV1.

ReserveProofSpV1

In this case there is no need to make enote images. Just make composition proofs directly on the enotes whose key images you want to expose. The amount commitment blinding factors and amounts can be pasted in the proof explicitly - the verifier recomputes the amount commitments and checks they match with the actual enotes.

DangerousFreedom1984 commented 1 year ago

Hello Koe,

SpendProof: I agree that one has to prove that he knows the private keys to generate the grootle proof + composition proofs. I thought I could be a bit more compact so my reasoning here was: if I can prove that I can recreate the grootle proof exactly as it is (with the same ring members) then the verifier could be sure that I created the transaction since the composition proofs are already validated in the blockchain. The problem here is of course to answer 'how do you prove that it was you that generated this ring signature?' so my idea was to make a proof of knowledge on the image offset 'Q[l] - Q" = -(t_k + t_c) G' (proving that you know t_k and t_c). I thought that practically speaking it would be easier and the signatures shorter (but that doesnt really matter). So we have Option 1) new grootle proof (with same ring members) + new image enote with composition proofs. Option 2) grootle proof + schnorr on the offset. For me both work. Since you implemented all functions to make the proofs, it should be easy doing both ways. I will go for option 1 as you suggest as it seems actually more straightforward.

OutProof: Yes, like the proof is showing you just have to share the enote ephemeral privkey. I wrote more than I should. Corrected.

InProof: Oh I see, so there is no definition in your library for the sum of public keys using X25519? Is it the problem? Yes, this is also an alternative like you suggest. I could directly reveal the opening for the amount commitment too. I will think a bit more about what makes more sense to do (implement the missing crypto for X25519 or using this new variant).

ReserveProofs: Oh, I see the idea. Since the enotes have three bases (which is not specified in the specs that I was using to study) then you can make composition proofs directly on the enotes and prove that you have ownership on them. Cool, thanks.

UnspentProofs: Please have a look on this scheme I came up with and let me know what you think. I think it is simple and works fine though we have to reveal kbU.

I will think a bit more about the Inproofs and how to integrate it with the Reserve and Unspent proofs. Thank you for reviewing this first draft! draft_sp_v2.pdf

UkoeHB commented 1 year ago

SpendProof: Suppose we made a transaction, and want to prove it. (ztm2 pg 76)

The values t_k and t_c are discarded, and definitely won't be recoverable from chain data. They are not necessary anyway. As long as the key image is reproduced then we have proven that our account made the transaction ('I made this tx' is shorthand for 'my wallet made this tx'; there is no way to actually prove a given human made a tx in the first place). Your Option 1 should suffice then (with new random offsets t_k and t_c).

implement the missing crypto for X25519

I strongly discourage this, implementing crypto primitives is a dangerous activity especially if you have limited experience.

UnspentProofs:

Ok, I agree with your approach. Given nominal key image KI':

  1. Expose k_g G, (k_x + k_vb) X, (k_u + k_m) U for onetime address Ko. Verify that Ko ?= k_g G + (k_x + k_vb) X + (k_u + k_m) U.
  2. crypto::signature() on k_g G
  3. sp::MatrixProof for keys {(k_x + k_vb) X, (k_x + k_vb) * KI'} on base keys {X, KI'}
  4. sp::MatrixProof for key (k_u + k_m) U on generator U
  5. if (k_x + k_vb) * KI' == (k_u + k_m) U then KI' is the key image of Ko

In general I recommend avoiding custom signature schemes where possible. Right now it looks like all you really need for the audit framework is a new Schnorr scheme that will take a user-defined generator/base key. Missing that, you could even abuse sp::DualBaseVectorProof as a temporary solution (just let the second part of the proof equal the first part).

DangerousFreedom1984 commented 1 year ago

Cool. Thanks for the answers. I believe we have a minimum consensus about the theoretical framework. I will move to implementing it now.

I agree that implementing new crypto should be avoided. I will use your recommendation for the Inproofs but could you tell me exactly the problem with X25519? Btw, I just saw that bulletproofs_plus2.cpp is still using addKeys2, which we know that is wrong for some cases that should never be there but anyway I think it is better to use addKeys. Could you change it later?

About the UnspentProofs, yeah, that's the idea. But I believe I can make a big Schnorr like I wrote. I will look your answer again when I'm implementing it.

UkoeHB commented 1 year ago

the problem with X25519?

"There is definitely not an extensive X25519 library ready to go for that."

Btw, I just saw that bulletproofs_plus2.cpp is still using addKeys2, which we know that is wrong for some cases that should never be there but anyway I think it is better to use addKeys

There is nothing wrong with addKeys2(). bulletproofs_plus2.cpp is just a copy of bulletproofs_plus.cpp with minor changes related to the seraphis transcript utility and multiexp utility. When copying code like this, it is important to minimize the diffs.

But I believe I can make a big Schnorr like I wrote.

Sure you can do it, but don't do it unless you need to (you don't in this case).

UkoeHB commented 1 year ago

Here's a summary of updated proofs. I note the minimum pieces required for a proof, although additional context/tracking information might be required (i.e. to help verifiers identify what enote or tx the proof is about). These assume some jamtis updates are implemented.

UkoeHB commented 1 year ago

These proofs have been implemented in the seraphis_main/sp_knowledge_proof_* files based on an initial draft provided by @DangerousFreedom1984 in this PR.