Sapling proving and verifying API#30
Conversation
There was a problem hiding this comment.
We have moved this deserialization in to the implementation of the context but not the deserialization of cv, anchor, spend_auth_sig, etc. I think I would prefer either moving all the desializations or none, unless this is necessary.
Edit: after looking through the rest of the commits, I think this would make sense not to move this read.
There was a problem hiding this comment.
I organised it like this because the serialized form is used in the signature, and I was trying to minimise serialization operations. But you are right that it would be semantically simpler to just treat the Rust API as having Rust types, and serialize on either side as required. I'll adjust.
There was a problem hiding this comment.
We used to accumulate the value commitment before we checked if epk was of small order. I think this makes more sense, but just wanted to confirm that we want to change this.
There was a problem hiding this comment.
I figured it made sense to do the necessary checks before any data processing.
There was a problem hiding this comment.
Below we refer to bvk.0 more than we refer to bvk. It doesn't matter because of the "zero-cost abstractions", but I like saying let mut bvk = self.bvk.clone(); here and PublicKey(bvk).verify( below
There was a problem hiding this comment.
I like that we changed this to return the result of verify rather than having the conditional.
There was a problem hiding this comment.
There are a few places where we are doing this or similar accumulate logic. Now that this is not unsafe it could be more easily done in one line. self.bsk.add_assign(&rcv) or something similar. The same goes for when we are de-accumulating. I'm not sure the best way to abstract this logic across the two contexts perhaps a struct ContextualPoint with the accumulate and de-accumulate methods? This can be done later.
Optimise Boolean::enforce_equal.
83aa9b6 to
527d698
Compare
|
Rebased on master to fix merge conflicts, and addressed @Eirik0's serialisation comment. |
527d698 to
a6b3d14
Compare
|
Edited the proving and binding sig refactor to target the |
a6b3d14 to
a492956
Compare
|
Rebased on master to fix merge conflicts. |
a492956 to
0944cee
Compare
|
Rebased to fix a build error I missed during the previous rebase. |
Eirik0
left a comment
There was a problem hiding this comment.
utACK. There were a couple things I had questions on, and a couple things which could potentially be simplified, but those are beyond the scope of this refactoring.
There was a problem hiding this comment.
The block below this comment could be simplified, but that is beyond the scope of this refactor. See: #30 (comment)
There was a problem hiding this comment.
It feels odd to have asserts in production code, but this has not changed in the move. I wonder if we should be explicitly panicking here with a better error message.
Edit: Actually, why are we not returning None/Err(())/false in the places that we are asserting?
There was a problem hiding this comment.
This is an internal consistency check. We know (via the function's type signature) that nullifier is 32 bytes, and we "know" that when packed this should result in two field elements. The assertion here upgrades the "know" to a know, by catching any bugs that might result in a different-length packing.
There was a problem hiding this comment.
Will params every be anything other than &JUBJUB? Why pass this in rather than use the constant?
There was a problem hiding this comment.
That's something we should address across the entire codebase: which parts will only ever need JUBJUB, and which should be agnostic.
There was a problem hiding this comment.
It's a little hard to follow what happens with this function, but the total number of additions/removals across all commits adds up. The change are that the parameter value: i64_t becomes value: i64 (which makes sense), and we now pass in params rather than refer to &JUBJUB directly.
There was a problem hiding this comment.
One general comment is that it feels odd to return a Result with an empty error (we do this in a few places in this file). I would think that either we would return an Option<...> if we don't care what the error is. Alternatively we could return a Result <...> with an error type that encapsulates the error types that could result from the functions that we are calling - this would allow us to take advantage of the ? operator if nothing else.
There was a problem hiding this comment.
One benefit to returning a Result instead of an Option is that the standard rustc linters will generate a warning if a Result is unused (either via matching or an explicit unwrap()). As for improved error-handling (which is definitely a good idea), this should be tackled as part of a wider refactor.
There was a problem hiding this comment.
Ok(true) feels odd because it makes one wonder what Ok(false) means. It doesn't look like we ever use the Err from verify_proof. IMO it would make more sense if verify_proof just returned a bool, or if the error type it returned encapsulated the situation where this could be false (Result<(), ...>).
There was a problem hiding this comment.
Yeah, I would also prefer to use Result<(), SomeErrorType>; this is something we should think about when doing an error-handling refactor (and which will require changes to bellman in this case).
0944cee to
9139ec4
Compare
|
Rebased on master to fix merge conflict. |
9139ec4 to
2de6301
Compare
|
Force-pushed to rework the PR. It now only contains the proving and verifying API refactor; the |
|
This is difficult to review (specifically, to check that the code movement is just movement). Can it be split into commits that move smaller pieces at a time? |
|
@daira I'm not sure it can, at least while ensuring that the code compiles. I can go back and try it out, but no guarantee that I can simplify it in that way. I could also try doing some refactoring in-place before moving code, and see if that improves the diffs... |
|
If it isn't too much trouble I like the idea of refactoring in place and then moving. I also had wondered about making the new structs and then pulling in the functions one commit at a time. Not necessarily simpler but less to look at all at once. |
2de6301 to
b83234a
Compare
b83234a to
1a1c775
Compare
|
Force-pushed to update the |
|
ACK |
Eirik0
left a comment
There was a problem hiding this comment.
ACK. The refactoring looks good. Some of my previous comments still stand, but those can be addressed later.
38d38af3 Merge pull request zcash#32 from kevaundray/patch-1 af5598da Merge pull request zcash#33 from ZcashFoundation/scalar 109ec40d Add public Scalar type alias for Fr 8e9c5fe6 typo in Fr.rs 8e9337ee Merge pull request zcash#30 from rex4539/typos 5f4374c8 Fix typo git-subtree-dir: jubjub git-subtree-split: 38d38af3b792d2c55d815d214a7cd157dc8f71ad
feat: vote commitment tree
This PR defines a Rust API (with no
unsafe) for creating and verifying the Sapling components of a Zcash transaction.