zcash / zips Goto Github PK
View Code? Open in Web Editor NEWZcash Improvement Proposals
Home Page: https://zips.z.cash
License: MIT License
Zcash Improvement Proposals
Home Page: https://zips.z.cash
License: MIT License
We should mention that the key is 256-bits. I had to look up the RFC to make sure it was, since if it was only 128 bits keys could collide. I suppose this is implied by the output sizes of KDF and PRFdk but I'm not that clever!
"A Pour description is data included in a block that describes a Pour transfer..."
That's true, but maybe it's more accurate to say they're included in transactions, and transactions are included in blocks.
Addresses (and their components) are not inherently public. Limiting their distribution is a valid security decision, and important for anonymity in some use cases. The spec should use terminology that reflects this.
We confusingly attribute agency to transactions.
Cross-repo duplicate of:
I'm mainly testing out the slack integration with this ticket.
This should be done after other necessary edits.
See zcash/zcash#466
"Let SymEncrypt_K(P) be ... with empty nonce, and key K"
Using an empty nonce is fine for most of the calls to SymEncrypt, because the ephemeral key pair will be different every time, and therefore the keys will be different every time. However, for the call:
C_i^disclose = SymEncrypt_{a_{vk}}(K^shared)
If an empty nonce is used there, then (according to my quick look at RFC7539) the keystream XORed into K^shared will get reused every time, which is really bad e.g. if I learn a single K^shared I'll be able to decrypt all future and past K^shared that were encrypted to the same a_vk.
There's a formatting issue where the index of the a_vk on the SymEncrypt in that line is at the same subscript level with the "a" in a_vk. It should be separated from the vk with a comma, or put in a subsubsubscript.
Also this sentence which references the nonce is out of date:
The nonce for each ciphertext component depends on the index i. The particular nonce construction is chosen so that a known-nonce distinguisher for Salsa20 would not directly lead to a break of the IK-CCA (key privacy) property.
I'm looking at: https://github.com/zcash/zips/blob/406.viewing-keys.2/protocol/protocol.pdf
In protocol.pdf
addresses are malleable in a certain sense. For example, if the company puts up a donation address on their website, I can subtly replace it with a different address having the same pkenc but a different apk (for my own ask). Assuming I somehow have the viewing key, the company will see all of the donations (they think everything is fine) but only I would be able to spend them. This is possible in protocol.pdf
because in "Decryption by a recipient" the recipient trusts that the apk they extract from the note plaintext is theirs, the one corresponding to their pkenc. The attack isn't possible in the Zerocash paper because apk is an input to Receive and that value is used in the commitment check.
The Bitcoin serialisation format depends on knowledge of the data types of fields, so these need to be specified. See https://bitcoin.org/en/developer-reference#raw-transaction-format and following for examples.
Add an 8-bit field 'Memo Type' to:
Formally recognised values for 'Memo Type' could be:
The encoding of a note plaintext could look like:
[8-bit version] [8-bit memo type] [64-bit v] [256-bit p] [256-bit r] [memo 128 bytes]
The 'Memo Type' field is positioned after the version byte to keep subsequent fields on word boundaries.
See zcash/zcash#977
joinSplitPubKey
is 33 bytes, so the input to BLAKE2b is 32+32+32+33 = 129 bytes. A BLAKE2b input block is 128 bytes. I believe it's secure, because we only need collision resistance โ but it's untidy: if I were wrong about the hSig only needing collision resistance, this might unnecessarily complicate the security proof. So I intend to reduce randomSeed
to 31 bytes, if no-one can think of an objection.
This repo should also have a licence file.
The "Value pool" sentence is kind of vague, maybe we should specify the algorithm for it. It's important because it's how a pour's validity is bound to a transaction's validity.
Moved from zcash/zcash#700.
This is an important security-critical change to the circuit and protocol. If we get the details wrong then it could allow attacks that violate balance or (less seriously, but still contrary to the intent) allow distinguishing transactions with different numbers of real input coins.
The circuit change was implemented in Electric-Coin-Company/libzerocash@ab777ba . More detail is on zcash/zcash#700 .
The versions need to be unambiguous between each other and they shouldn't be confused with Zcash code release versions.
Maybe for long-hand, spoken English "Zcash protocol v${NUMBER} aka
For our software releases we'll have "Zcash zc.v0.11.2.z7". (I'm not sure how to say that in English, which is a problem...) :-/
0xC2?
Most comments here are minor, and can be ignored if they do not seem helpful.
Ones marked with ** should be addressed
Introduction:
You say only magneta is differences from zero-cash,
but could not find the concept of nullifier in zero-cash paper.
I think that it matches their serial number.
I would mention that notation and names of objects are different from zerocash paper
sometimes, even if not in magneta
In that context, it might even be good to have a `dictionary' of names here to names in zerocash paper
sec 3.2 :
I would mention that the `i-1' is mod 2
Page 5:
You say pk_{enc} is 256 bytes long,
but by looking at paper Daniel Bernstien paper on curve25519
,it outputs an integer in range {0,..,2^255-19-1}.
So, for example, last bit of pk_{enc} is always 0?
** section 4.2.1
You say earlier you will only apply sha-256 on 512 bit blocks,
but here you are using it on a string of length 840 that is not even a multiple of 512
sec 4.2.3 - add a (See Section 5) first time joinSplit is mentioned as it hasn't been defined yet
Sec 4.5 - say a word about what treestate is intuitively,
First thought that comes to mind is that it is like the merkle tree of all transactions in a block, but here you seem to mean something that describes the merkle tree of all transaction since beginning of time
Sec 5 -
You haven't defined transaction.
From what you write in sec 8.1,
seems a transaction is a union of regular bitcoin transactions,
and some joinSplit operations (i.e., Zcash anonymous transactions).
If this is the case, say it explicitly.
You alternately use the terms joinSplit operation and transaction.
and it can sound like they are two names for the same thing.
Page 10-11:
It's hard to understand without context, what is v^old_pub and v^new_pub.
I am guessing v^old_pub is coins from the non-private part of the chain that are used in the transaction?
This should be explained. I did not see any place where it is explained that we are talking about a chain with public and anonymous coins at the same time
** Page 14 value stored' ->
a value stored' or `values stored'
Per zcash/zcash#1119
It's not stated that the Merkle tree is computed using CRH
. That should be mentioned since it could interact with the other uses of CRH
.
The current spec and the paper say 288 bytes (2304 bits), but the output of the prover says "Proof size in bits: 2294". I think the prover output is just not taking into account some padding up to byte boundaries, but it needs checking.
As suggested by @jl777 in zcash/zcash#991 (comment)
In "Pour Transfers and Descriptons" section, scriptPubKey has the description that should go on scriptSig and vice-versa.
The holder of avk knows the symmetric keys used to encrypt the coins, and so they can modify them (potentially to make them unspendable). They can't actually do it, because the transaction non-malleability stops them from changing the ciphertexts.
So, if the coin is sent through a different channel, and still disclosed to the viewkey holder, there's an additional assumption that the viewkey holder didn't intercept the second channel and change the coin. We should document that.
Another question is: Assuming the coins are sent in-band, why do they need to be encrypted with an authenticated mode? Shouldn't the transaction non-malleability catch any changes? If we couldn't safely use a non-authenticated mode for coins in transactions, then the avk holder has some kind of extra power even in the in-band case.
The current spec uses big-endian encoding, but Bitcoin serialization uses little-endian (and so does Curve25519 / AEAD_CHACHA20_POLY1305).
The KDF is going to change when we switch to blake2, but right now it's wrong because it says Trailing246(hSig). I think it should be Trailing254(hSig) to leave two bytes for the i-1 bit and 0.
We want to prove that KDF and the way h_sig is computed are both PRFs seeded on dhsecret and randomSeed, respectively. If we move randomSeed to the same place as dhsecret is in the computation of KDF then one proof can cover both functions.
Eli noted a lot of "intended usage" in our protocol spec. Basically, the protocol.pdf is written from an implementers perspective where the reader is assumed to be the full node and we discuss what the reader should / shouldn't do given what it sees from other parties in the protocol. In order to do a proper security review, the reader needs to make a mental leap along the lines of "I'm like this, and there are a lot of other people like this, but they might not behave exactly like this, and some might behave nothing like this."
We can fix this by separating the protocol into three parts:
This is sort of like what the Zerocash paper does, except (1) and (2) aren't separated in the Zerocash paper. An advantage is that there'll be a more 1:1 mapping between sections of the paper and parts of the code (e.g. in (1) we can list the files where those data structures are implemented). A disadvantage is that it would take me a lot longer to understand the protocol if I had to read it this way, which is why it took me so long to understand it from the Zerocash paper, but OTOH I would be able to implement it from the spec without even understanding it.
This is related to #32. I'm not sure if this would address Eli's comments, since transactions still have agency (they're seen as programs running on full node weird machines).
NoteCommitment
is defined directly, not in terms of COMM.
I suggest renaming some of the basic entities in protocol, to more accurately reflect what they really are:
owner - the tuple (a_{sk}) and all other keys derived from it
title - currently called "coin", defined as a pair (a, v) where a is an owner key, v a value. It means "a has a title to v units of zcash"
title destructor (or simply destructor) - currently called "serial number", is what destroys a previous title as part transaction
title destuctor seed (or destructor seed) - currently denoted "rho", the preimage of a destructor (s.n.)
title commitment - currently called "coin commitment", is the blinded version of (title,destructor seed). It has a blinding key/nonce, which should be called the (title) commitment blinder
title transfer transaction - or, simply, transaction, is the basic operation that destroys one or more titles and creates new titles (to the same amount as that destroyed)
I'll pause here to test the water. It's very different from the zerocash paper (and bitcoin nomenclature) but I think these names better describe what's going on (here and in other crypto-currencies)
A Procedure section will specify "canonical" storage structures and algorithms which implement the protocol. For example, there should be an inductive procedure for "Verify Block".
Implementations may use different data structures/algorithms, and this section should strive to define the simplest to specify data structures and algorithms, rather than the most efficient. If there is a discrepency between an efficient real-world implementation and an algorithm here which affects the protocol, then we need to go through a rigorous process for altering the protocol if we deem it necessary. If there's a discrepency in implementation vs "canonical algorithm" that does not affect the protocol, then the canonical algorithm should either be simplified until there's no discrepency, or we add a footnote about the discrepency, or we change the canonical algorithm to be more complex.
Also, a given canonical algorithm/data-structures will imply a set of invariants / preconditions / postconditions. Those should be explicitly documented also in this spec.
It would be nice for UX if the viewkey holder could see the full address the coin was sent to. I don't think there's a way to do that in the current design; I don't see a way to get the recipient's apk.
As requested by 7S. This would go just before the "Encoding" section.
Let's add an appendix that is kind of a changelog of each version. Actually this might go up front as I've seen in other specs. We've already had some people asking about version 1, so this section would describe that as as an imprecisely specified predecessor design (and also version 0, which was the academic prototype).
Also document the difference from Zerocash in the maximum note value (MAX_MONEY
, not 264 - 1).
2.2
, Nathan's note could mention that output arity also affects the design there, due to PRFฯ.2.4.1
, the text "Any ciphertext components that fail to decrypt with a given recipient's private key will be ignored" needs to be clarified with who, what and why.2.4.2
, "InternalH" needs a better name. I originally called it this probably as a placeholder. Does the zerocash paper not have a name for it?2.7
our description of anchors can be simplified. "A pour description's anchor may reference an earlier block's treestate or the treestate of an earlier pour description." We could also clarify "The treestates of pour descriptions are their anchored trees appended with their commitments" or something, so people know what we mean by their treestates.4.5
the text regarding s
should be in magenta, and we should also be clear that we differ from zerocash in this respect because we can: a naked commitment is perfectly fine there.Feel free to close this once you've considered or fixed everything in this ticket.
What do protocol upgrades look like? Are there forwards compatibility features such as in the block header?
We need to standardize a "Zcash Improvement Proposals" process for making significant changes to Zcash's protocol or even minor changes to the zk-SNARK circuit.
Note: We should not adopt a ZIP process in our development efforts until a public beta.
This would be helpful, I keep making the mistake of printing a dead-tree copy and then forgetting which version it is.
Placeholder. See https://zcash.slack.com/archives/paymentapi/p1468977244000002 for a discussion about how to represent amounts. (To do: that archive is not public, copy the relevant parts.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.