Coder Social home page Coder Social logo

zcash / zips Goto Github PK

View Code? Open in Web Editor NEW
268.0 57.0 148.0 371.66 MB

Zcash Improvement Proposals

Home Page: https://zips.z.cash

License: MIT License

TeX 32.32% Makefile 0.32% Shell 0.17% HTML 66.64% CSS 0.24% Dockerfile 0.02% Python 0.30% Perl 0.01%
zcash cryptocurrency cryptography specifications

zips's Issues

Pours go in transactions inside blocks

"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.

SymEncrypt keystream reuse

"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.

Undocumented difference between Zerocash and Zcash with Viewing Keys

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.

Add 8-bit 'Memo Type' to indicate type of data in Memo Field

Add an 8-bit field 'Memo Type' to:

  • enable the 'Memo Field' to store 128 bytes of raw data, without the need for a 0xF5 start byte
  • make it easier for applications to determine/hint at the type of data

Formally recognised values for 'Memo Type' could be:

  • 0x00 = there is no memo field (thereby reducing size of note plaintext)
  • 0x01 = raw data (arbitrary sequence of 128 bytes)
  • 0x02 = UTF-8 encoded byte sequence (128 bytes, padded with trailing zero bytes)
  • 0x03 - 0x1F = reserved for Zcash extensions or other memo types in the future
  • 0x20 - 0xFF = free for community to use

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.

Computation of hSig requires 1 byte more than a BLAKE2b input block

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.

Add explicit version to protocol spec

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 $CODENAME" and for short hand: "zcp${NUMBER}", so for example: "Zcash protocol v2 aka Trafford" or "zcp2" for shorthand.

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...) :-/

Comments on tech spec

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'

Specify proof format

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.

Is authenticated encryption for coins useful?

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.

Switch to little-endian

The current spec uses big-endian encoding, but Bitcoin serialization uses little-endian (and so does Curve25519 / AEAD_CHACHA20_POLY1305).

KDF's Trailing_246(hSig) is wrong

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.

Use HMAC for KDF and hSig

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.

Address "intended usage" descriptions in the protocol

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:

  1. Define what a full node's state is. We have the blockchain, the nullifier set, a list of unspent notes, etc.
  2. Define the types of messages full nodes receive. Blocks, which contain transactions, which contain JoinSplits.
  3. Define how those messages affect the full node's state. For example a new block will cause all of its transactions to get "executed" and upon execution a transaction can cause..., and so on.

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).

Naming

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)

Add "Procedure" section to protocol spec.

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.

Add a version changelog appendix.

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).

Review of protocol spec

  1. In 2.2, Nathan's note could mention that output arity also affects the design there, due to PRFฯ.
  2. In 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.
  3. In 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?
  4. In 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.
  5. In 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.

ZIP 0: Standardize ZIP process

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.