Additional well-formedness check for G2 elements
libsnark currently checks that G<sub>1</sub> and G<sub>2</sub> elements are well-formed by ensuring that they satisfy their respective curve equations, and although this is enough for G<sub>1</sub> (which is instantiated as an order r curve E/F<sub>p</sub>: y^2 = x^3 + b), G<sub>2</sub> is the order r *subgroup* of the composite order r(2q-r) curve E'/Fp<sup>2</sup>: y^2 = x^3 + b/e constructed via a sextic twisting isomorphism. This means we need to ensure these points are order r as well.
None of the proofs on the Zcash blockchain violate this check, and it may not even be possible for them to violate this check (bilinearity is not preserved). Let's be cautious and do it anyway.
Isolate verification to a ProofVerifier context object that allows verification behavior to be tuned by the caller.
This is an alternative foundation for #1892, i.e., #1892 will have to be changed if this PR is accepted.
I think this is a safer approach because it allows us to isolate verification behavior to a single object. This will come in handy when @arielgabizon finishes the batching code.
Improve joinsplit diagnostics
I don't advocate merging this for the hotfix release (to fix#1779) but this PR can be used to diagnose the real issue and should be merged ASAP afterward.
~I still need to add tests for `last()` and `element()` though.~ Done.
Add a make command for checking expected failures
With this merged, we can add gtests prefixed with `DISABLED_`, and then configure Buildbot to run those tests but not require they pass in order to merge.
Tweaks to difficulty adjustment algorithm
This PR changes the difficulty algorithm to adjust from the average difficulty over the
block window instead of from the last difficulty. It also removes the special rules for the
testnet, which are incompatible with difficulty averaging.
Closes#147 again.
The min-difficulty blocks are incompatible with difficulty averaging.
Network difficulty is also now defined as the difficulty the network is
currently working to solve, rather than the last non-min-difficulty block
difficulty.
Separate concepts of block difficulty and network difficulty in RPC
"Block difficulty" is the difficulty listed in a block's header, which in the
testnet can sometimes be min-difficulty (if time-since-last-block is too large).
"Network difficulty" is the difficulty that the network was trying to satisfy
at a particular block height. In mainnet this is always equal to the difficulty
of the solved block for that height, but in testnet the network difficulty is
derived from the last non-min-difficulty block difficulty.
This commit fixes the RPC APIs that are intended to show network difficulty, so
that on testnet they don't sometimes drop to 1.0, confusing users.
Closes#1181
Output Equihash solution in RPC results as a hex string
When the Equihash solution was changed to a compact form in #1175, the block header changed from storing a vector of indices to a vector of chars. `blockToJSON()` was not updated, which meant that RPC calls like `getblock` returned the solution as a list of 1344 integers.
This PR changes `blockToJSON()` to output the Equihash solution as a hex string, identical to how it appears in the block header.
The genesis blocks and miner tests have been regenerated, because changing the
block header serialisation format changes the block hash, and thus validity.
The Equihash solutions have been removed from the bloom test inputs for
simplicity (block validity is not checked there; only a valid serialisation is
necessary).
Changes:
- floor(512/n)*n/8 bytes of BLAKE2b output is split between floor(512/n)
adjacent indices, instead of using one hash call per index.
- Parameters with n/(k+1) mod 8 != 0 will expand the BLAKE2b output to byte
boundaries for colliding, instead of using a longer output and clearing bits.
- The genesis blocks have been regenerated.
- The test vectors have been regenerated.
- The Equihash inputs for the cancellation tests were modified to ensure that
valid solutions were available to exercise the full solver.
Add gtest for non-malleable txids.
1. Test txid of normal transaction is double sha256 with sigscript input data removed
2. Test txid of coinbase transaction is double sha256 over whole tx
You can run a single test with:
./zcash-gtest --gtest_filter="txid_tests*"
CPourTx structural changes
* Enable binary serialization of proofs and the proving key (closes#799) and make the proofs fixed-size.
* Reorder fields of CPourTx to match the spec (closes#927)
libzcash and new zkSNARK circuit implementation
This PR completes [`libzcash`](https://github.com/zcash/zcash/tree/zc.v0.11.2.latest/src/zcash), the implementation of the [Zcash protocol specification](9bb4410e45/protocol/protocol.pdf) and replacement of [`libzerocash`](https://github.com/Zerocash/libzerocash), our old Zerocash protocol implementation. The new spec comes with some improvements to security and terminology, with minimal differences from the original academic design.
This implementation includes:
* A rewrite of the zkSNARK circuit for `JoinSplit` operations. This rewrite is cleaner, broken up into separate gadgets, easier to audit and review, and fixes some security bugs. (Closes#822, Closes#809, Closes#500, Closes#854)
* A minimal API for interacting with `JoinSplit`s and surrounding primitives. This PR removes almost twice as much code as it introduces. (Closes#877, Closes#315, Closes#824, Closes#798, Closes#707, Closes#512, Closes#247, Closes#128, Closes#514)
Implement and integrate new Incremental Merkle Tree
This supersedes #823.
----
This is an implementation of a new incremental merkle tree with
* no memory safety issues
* a more sensible internal design
* better space efficiency (tree representation, witnessing)
* simpler API
It is intended that this tracks the behavior of the previous tree, which it does, as verified by tests. I even wrote a little circuit for testing that all the paths work.
This PR also integrates the tree into the codebase and deprecates the old tree in almost all of our code. (I left it alone in `zerocashTest` but everything else has been changed.)
This change is compatible with the testnet but you will need to clear your *local* blockchain data out since the serialized representation of the merkle tree is now different.
Closes#517, Closes#519, Closes#591, Closes#460, Closes#473