diff --git a/index.html b/index.html index 6f05b1fe5..828f424e4 100644 --- a/index.html +++ b/index.html @@ -24,121 +24,110 @@

To start contributing, first read ZIP 0 which documents the ZIP process. Then clone this repo from GitHub, and start adding your draft ZIP, formatted either as reStructuredText or as Markdown.

For example, if using reStructuredText, use a filename matching draft-*.rst. Use make to check that you are using correct reStructuredText or Markdown syntax, and double-check the generated draft-*.html file before filing a Pull Request. See here for the project dependencies.

-

NU5 ZIPs

-

This is the list of ZIPs relevant to the NU5 Upgrade, which activated on 31st May 2022:

- -

License

Unless otherwise stated in this repository’s individual files, the contents of this repository are released under the terms of the MIT license. See COPYING for more information or see https://opensource.org/licenses/MIT .

Index of ZIPs

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ZIP Title Status
0 ZIP Process Active
1 Network Upgrade Policy and Scheduling Reserved
2 Design Considerations for Network Upgrades Reserved
32 Shielded Hierarchical Deterministic Wallets Final
76 Transaction Signature Validation before Overwinter Reserved
143 Transaction Signature Validation for Overwinter Final
155 addrv2 message Proposed
173 Bech32 Format Final
200 Network Upgrade Mechanism Final
201 Network Peer Management for Overwinter Final
202 Version 3 Transaction Format for Overwinter Final
203 Transaction Expiry Final
204 Zcash P2P Network Protocol Reserved
205 Deployment of the Sapling Network Upgrade Final
206 Deployment of the Blossom Network Upgrade Final
207 Funding Streams Final
208 Shorter Block Target Spacing Final
209 Prohibit Negative Shielded Chain Value Pool Balances Final
210 Sapling Anchor Deduplication within Transactions Withdrawn
211 Disabling Addition of New Value to the Sprout Chain Value Pool Final
212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final
213 Shielded Coinbase Final
214 Consensus rules for a Zcash Development Fund Final
215 Explicitly Defining and Modifying Ed25519 Validation Rules Final
216 Require Canonical Jubjub Point Encodings Final
217 Aggregate Signatures Reserved
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved
220 Zcash Shielded Assets Withdrawn
221 FlyClient - Consensus-Layer Changes Final
222 Transparent Zcash Extensions Draft
224 Orchard Shielded Protocol Final
225 Version 5 Transaction Format Final
226 Transfer and Burn of Zcash Shielded Assets Draft
227 Issuance of Zcash Shielded Assets Draft
228 Asset Swaps for Zcash Shielded Assets Reserved
230 Version 6 Transaction Format Draft
231 Decouple Memos from Transaction Outputs Reserved
239 Relay of Version 5 Transactions Final
243 Transaction Signature Validation for Sapling Final
244 Transaction Identifier Non-Malleability Final
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft
250 Deployment of the Heartwood Network Upgrade Final
251 Deployment of the Canopy Network Upgrade Final
252 Deployment of the NU5 Network Upgrade Final
300 Cross-chain Atomic Transactions Proposed
301 Zcash Stratum Protocol Final
302 Standardized Memo Field Format Draft
303 Sprout Payment Disclosure Reserved
304 Sapling Address Signatures Draft
305 Best Practices for Hardware Wallets supporting Sapling Reserved
306 Security Considerations for Anchor Selection Reserved
307 Light Client Protocol for Payment Detection Draft
308 Sprout to Sapling Migration Final
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved
310 Security Properties of Sapling Viewing Keys Draft
311 Sapling Payment Disclosure Reserved
312 Shielded Multisignatures using FROST Reserved
313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete
314 Privacy upgrades to the Zcash light client protocol Reserved
315 Best Practices for Wallet Handling of Multiple Pools Reserved
316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed
317 Proportional Transfer Fee Mechanism Active
318 Associated Payload Encryption Reserved
319 Options for Shielded Pool Retirement Reserved
320 Defining an Address Type to which funds can only be sent from Transparent Addresses Draft
321 Payment Request URIs Proposed
322 Generic Signed Message Format Reserved
323 Specification of getblocktemplate for Zcash Reserved
332 Wallet Recovery from zcashd HD Seeds Reserved
339 Wallet Recovery Words Reserved
400 Wallet.dat format Draft
401 Addressing Mempool Denial-of-Service Active
402 New Wallet Database Format Reserved
403 Verification Behaviour of zcashd Reserved
416 Support for Unified Addresses in zcashd Reserved
1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete
1002 Opt-in Donation Feature Obsolete
1003 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate Obsolete
1004 Miner-Directed Dev Fund Obsolete
1005 Zcash Community Funding System Obsolete
1006 Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity Obsolete
1007 Enforce Development Fund Commitments with a Legal Charter Obsolete
1008 Fund ECC for Two More Years Obsolete
1009 Five-Entity Strategic Council Obsolete
1010 Compromise Dev Fund Proposal With Diverse Funding Streams Obsolete
1011 Decentralize the Dev Fee Obsolete
1012 Dev Fund to ECC + ZF + Major Grants Obsolete
1013 Keep It Simple, Zcashers: 10% to ECC, 10% to ZF Obsolete
1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active
guide {Something Short and To the Point} Draft
0 ZIP Process Active
1 Network Upgrade Policy and Scheduling Reserved
2 Design Considerations for Network Upgrades Reserved
32 Shielded Hierarchical Deterministic Wallets Final
76 Transaction Signature Validation before Overwinter Reserved
143 Transaction Signature Validation for Overwinter Final
155 addrv2 message Proposed
173 Bech32 Format Final
200 Network Upgrade Mechanism Final
201 Network Peer Management for Overwinter Final
202 Version 3 Transaction Format for Overwinter Final
203 Transaction Expiry Final
204 Zcash P2P Network Protocol Reserved
205 Deployment of the Sapling Network Upgrade Final
206 Deployment of the Blossom Network Upgrade Final
207 Funding Streams Final
208 Shorter Block Target Spacing Final
209 Prohibit Negative Shielded Chain Value Pool Balances Final
210 Sapling Anchor Deduplication within Transactions Withdrawn
211 Disabling Addition of New Value to the Sprout Chain Value Pool Final
212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final
213 Shielded Coinbase Final
214 Consensus rules for a Zcash Development Fund Final
215 Explicitly Defining and Modifying Ed25519 Validation Rules Final
216 Require Canonical Jubjub Point Encodings Final
217 Aggregate Signatures Reserved
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved
220 Zcash Shielded Assets Withdrawn
221 FlyClient - Consensus-Layer Changes Final
222 Transparent Zcash Extensions Draft
224 Orchard Shielded Protocol Final
225 Version 5 Transaction Format Final
226 Transfer and Burn of Zcash Shielded Assets Draft
227 Issuance of Zcash Shielded Assets Draft
228 Asset Swaps for Zcash Shielded Assets Reserved
230 Version 6 Transaction Format Draft
231 Decouple Memos from Transaction Outputs Reserved
239 Relay of Version 5 Transactions Final
243 Transaction Signature Validation for Sapling Final
244 Transaction Identifier Non-Malleability Final
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft
250 Deployment of the Heartwood Network Upgrade Final
251 Deployment of the Canopy Network Upgrade Final
252 Deployment of the NU5 Network Upgrade Final
253 Deployment of the NU6 Network Upgrade Reserved
300 Cross-chain Atomic Transactions Proposed
301 Zcash Stratum Protocol Final
302 Standardized Memo Field Format Draft
303 Sprout Payment Disclosure Reserved
304 Sapling Address Signatures Draft
305 Best Practices for Hardware Wallets supporting Sapling Reserved
306 Security Considerations for Anchor Selection Reserved
307 Light Client Protocol for Payment Detection Draft
308 Sprout to Sapling Migration Final
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved
310 Security Properties of Sapling Viewing Keys Draft
311 Sapling Payment Disclosure Reserved
312 Shielded Multisignatures using FROST Reserved
313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete
314 Privacy upgrades to the Zcash light client protocol Reserved
315 Best Practices for Wallet Handling of Multiple Pools Reserved
316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed
317 Proportional Transfer Fee Mechanism Active
318 Associated Payload Encryption Reserved
319 Options for Shielded Pool Retirement Reserved
320 Defining an Address Type to which funds can only be sent from Transparent Addresses Proposed
321 Payment Request URIs Proposed
322 Generic Signed Message Format Reserved
323 Specification of getblocktemplate for Zcash Reserved
324 URI-Encapsulated Payments Draft
332 Wallet Recovery from zcashd HD Seeds Reserved
339 Wallet Recovery Words Reserved
340
400 Wallet.dat format Draft
401 Addressing Mempool Denial-of-Service Active
402 New Wallet Database Format Reserved
403 Verification Behaviour of zcashd Reserved
416 Support for Unified Addresses in zcashd Reserved
1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete
1002 Opt-in Donation Feature Obsolete
1003 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate Obsolete
1004 Miner-Directed Dev Fund Obsolete
1005 Zcash Community Funding System Obsolete
1006 Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity Obsolete
1007 Enforce Development Fund Commitments with a Legal Charter Obsolete
1008 Fund ECC for Two More Years Obsolete
1009 Five-Entity Strategic Council Obsolete
1010 Compromise Dev Fund Proposal With Diverse Funding Streams Obsolete
1011 Decentralize the Dev Fee Obsolete
1012 Dev Fund to ECC + ZF + Major Grants Obsolete
1013 Keep It Simple, Zcashers: 10% to ECC, 10% to ZF Obsolete
1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active
guide {Something Short and To the Point} Draft
+

Drafts without assigned ZIP numbers

+

These are works-in-progress, and may never be assigned ZIP numbers if their ideas become obsoleted or abandoned. Do not assume that these drafts will exist in perpetuity; instead assume that they will either move to a numbered ZIP, or be deleted.

+ +
Title
diff --git a/protocol/blossom.pdf b/protocol/blossom.pdf index 2b34f68b3..28201a3bd 100644 Binary files a/protocol/blossom.pdf and b/protocol/blossom.pdf differ diff --git a/protocol/canopy.pdf b/protocol/canopy.pdf index 763e92127..695fca737 100644 Binary files a/protocol/canopy.pdf and b/protocol/canopy.pdf differ diff --git a/protocol/heartwood.pdf b/protocol/heartwood.pdf index c25342862..528de36cc 100644 Binary files a/protocol/heartwood.pdf and b/protocol/heartwood.pdf differ diff --git a/protocol/nu5.pdf b/protocol/nu5.pdf index b9b2c0f4e..2515078bf 100644 Binary files a/protocol/nu5.pdf and b/protocol/nu5.pdf differ diff --git a/protocol/protocol.pdf b/protocol/protocol.pdf index b9b2c0f4e..2515078bf 100644 Binary files a/protocol/protocol.pdf and b/protocol/protocol.pdf differ diff --git a/protocol/sapling.pdf b/protocol/sapling.pdf index c65d927d4..344b01df5 100644 Binary files a/protocol/sapling.pdf and b/protocol/sapling.pdf differ diff --git a/zip-0216.html b/zip-0216.html index 482288d30..61828ba2b 100644 --- a/zip-0216.html +++ b/zip-0216.html @@ -29,9 +29,9 @@ \(u\!\) -coordinate is zero, there are two encodings that will be accepted:

// Fix the sign of `u` if necessary
-let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
+let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
 let u_negated = -u;
-let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
+let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);

This code accepts either sign bit, because u_negated == u.

There are two points on the Jubjub curve with \(u\!\) diff --git a/zip-0253.html b/zip-0253.html new file mode 100644 index 000000000..089d649f9 --- /dev/null +++ b/zip-0253.html @@ -0,0 +1,17 @@ + + + + ZIP 253: Deployment of the NU6 Network Upgrade + + + +

+
ZIP: 253
+Title: Deployment of the NU6 Network Upgrade
+Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
+Status: Reserved
+Category: Consensus / Network
+Discussions-To: <https://github.com/zcash/zips/issues/806>
+
+ + \ No newline at end of file diff --git a/zip-0316.html b/zip-0316.html index 31323f82b..7aa727f8a 100644 --- a/zip-0316.html +++ b/zip-0316.html @@ -165,8 +165,16 @@
  • Revision 1: This version adds support for MUST-understand Typecodes and Address Expiration Metadata. It also drops the restriction that a UA/UVK must contain at least one shielded Item.
  • A Revision 0 UA/UVK is distinguished from a Revision 1 UA/UVK by its Human-Readable Part, as follows.

    -

    Let prefix be: * “u”, if this is a UA/UVK prior to Revision 1; * “ur”, if this is a UA/UVK from Revision 1 onward.

    -

    The Human-Readable Parts (as defined in 36) of Unified Addresses are defined as: * prefix, for Unified Addresses on Mainnet; * prefix || “test”, for Unified Addresses on Testnet.

    +

    Let prefix be:

    + +

    The Human-Readable Parts (as defined in 36) of Unified Addresses are defined as:

    +

    The Human-Readable Parts of Unified Viewing Keys are defined as:

    -

    Semantics

    +

    Semantics

    The values of key and amount deterministically imply a unique payment note corresponding to this URI, which is a Zcash Sapling note that carries the given amount and is spendable by a Sapling spending key derived from key. The derivation of this note is done by the following procedure:

    DerivePaymentNote(key,amount):

    -

    Centralized Deployment

    +

    Centralized Deployment

    The owner of the withzcash.com domain name MUST NOT create a DNS record for the pay.withzcash.com domain name, nor a TLS certificate for it. All feasible means SHOULD be taken to ensure this, and to prevent unintended transfer of ownership or control over the withzcash.com domain name. (See Rationale for URI Format and Security Considerations below for discussion.)

    Applink mechanisms let domain name owners provide a whitelist, specifying which apps are authorized to handle URLs with that domain name. This is implemented by serving suitable files at well-known paths on the web server of that domain or, in the case of a subdomain, its parent domain. Thus, the owner of the withzcash.com domain effectively controls the whitelist of apps that may be launched by users' platform to handle URI-Encapsulated Payments (see Security Considerations). This whitelist should protect users from installing rogue apps that intercept incoming payments. Thus, the domain owner MUST do the following:

      @@ -136,17 +136,17 @@
    • Strive for the whitelist to include all apps that would not place the user at any greater security risk than reputable state-of-the-art wallet apps.
    -

    Testing

    +

    Testing

    For testing purposes, all of the above specification is duplicated for the Zcash testnet network, substituting TAZ (Zcash testnet coins) for ZEC and testzcash.com for withzcash.com.

    A separate “testnet whitelist” MUST be maintained by the owner of the testzcash.com domain name, with a separate policy that SHOULD allow any legitimate third-party developer to add their work-in-progress wallet for testing purposes. Integrity and availability MAY be looser.

    Wallets apps MAY support just one type of payments (ZEC or TAZ), and if they support both then they MUST keep separate accounting and must clearly distinguish the type when payments or balances are conveyed to users.

    -

    Lifecycle Specification

    +

    Lifecycle Specification

    The lifecycle of a Payment-Encapsulating URI consists of several stages, which in the usual case culminate in the funds being irrevocably deposited into the recipient's personal wallet irrevocably:

    -

    Generating the notes and URI

    +

    Generating the notes and URI

    The sender's Zcash wallet app creates an ephemeral spending key, sends ZEC funds to the payment addressed derived from that key, and creates a Payment-Encapsulating URI that contains this ephemeral spending key and the newly-generated note commitments.

    -

    Ephemeral key derivation

    +

    Ephemeral key derivation

    The ephemeral keys within payment URIs are derived deterministically from the same seed as the main wallet. This ensures that if a wallet is recovered from backup, sent-but-unfinalized payments can be reclaimed.

    The derivation mechanism is as follows:

      @@ -159,17 +159,17 @@
    -

    URI Transmission

    +

    URI Transmission

    The sender conveys the Payment-Encapsulating URI to the intended recipient, over some secure channel (e.g., an end-to-end encrypted messaging platform such as Signal, WhatsApp or Magic Wormhole; or a QR code scanned in person).

    If transmitted via a human-readable medium, such as a messaging app, the Payment-Encapsulating URI MAY be accompanied by a contextual explanation that the URI encapsulates a payment, and a suggested action by the recipient to complete the process (see Usage Story above for an example).

    When sent via a human-readable medium that consists of discrete messages, the message that contains the URI SHOULD NOT contain any payment-specific or manually-entered information outside the URI itself, since this information may not be visible to the recipient (see “Message Rendering” below).

    From this point, and until finalization or cancellation (see below), from the sender's perspective the payment is “in progress”; it SHOULD be conveyed as such to the sender; and MUST NOT be conveyed as “finalized” or other phrasing that conveys successful completion.

    -

    Message Rendering

    +

    Message Rendering

    The recipient's device renders the Payment-Encapsulating URI, or an indication of its arrival, along with the aforementioned contextual explanation (if any). The user has the option of “opening” the URI (i.e., by clicking it), which results in the device opening a Zcash wallet app, using the local platforms app link mechanism.

    A messaging app MAY recognize URI-Encapsulated Payments, and render them in a way that conveys their nature more clearly than raw URI strings. If the messaging medium consists of discrete messages, and a message contains one or more URI-Encapsulated Payments, then the messaging app MAY assume that all other content in that message is automatically generated and contains no payment-specific or manually-generated information, and thus may be discarded during rendering.

    -

    Payment Rendering and Blockchain Lookup

    +

    Payment Rendering and Blockchain Lookup

    The recipient's Zcash wallet app SHOULD present the payment amount and MAY present the description, as conveyed in the URI, along with an indication of the tentative nature of this information.

    In parallel, the wallet app SHOULD retrieve the relevant transactions from the Zcash blockchain, by looking up the transaction given by the cmu parameter (this MAY use an efficient index, perhaps assisted by a server), and check whether:

      @@ -186,22 +186,22 @@

      Within the Pending state, the wallet app MAY also consider “0 confirmations” transactions (i.e., transactions that have been broadcast on the node network but are neither mined nor expired), and convey their existence to the user. These do not suffice for entering the Ready-to-finalize state (since unmined notes cannot be immediately spent.)

      The aforementioned conditions may change over time (e.g., the transactions may be spent by someone else in the interim), so the status SHOULD be updated periodically.

    -

    Finalization

    +

    Finalization

    When the recipient chooses to finalize the payment, the wallet app generates transactions that spends the aforementioned notes (using the ephemeral spending key) and send these Zcash funds to the user's own persistent payment address. These transactions carry the default expiry time (currently 100 blocks).

    The recipient's wallet app SHOULD convey the payment status as “Finalizing…” starting at the time that the uses initiates the finalization process. It MAY in addition convey the specific action done or event waited.

    The sender's wallet SHOULD convey the payment status as “Finalizing…” as soon as it detects that relevant transactions have been broadcast on the peer-to-peer network, or mined to the blockchain.

    Once these transactions are confirmed (to an extent considered satisfactory by the local wallet app; currently 10 confirmations is common practice), their status SHOULD be conveyed as “Finalized”, by both the sender's wallet app and the recipient's wallet app. Both wallets MUST NOT convey the payment as “finalized”, or other phrasing that conveys irrevocability, until this point.

    If these transactions expire unmined, or are otherwise rendered irrevocably invalidated (e.g., by a rollback), then both wallets' status SHOULD convey this, and the recipient's wallet SHOULD revert to the “Payment Rendering and Blockchain Lookup” stage above.

    -

    Payment Cancellation

    +

    Payment Cancellation

    At any time prior to the payment being finalized, the sender is capable of cancelling the payment, by themselves finalizing the payment into their own wallet (thereby “clawing back” the funds). If the wallet has not yet sent, for inclusion in the blockchain, any of the transactions associated with the ephemeral spending key, then cancellation can also be done by discarding these transactions or aborting their generation. The sender's wallet app SHOULD offer this feature, and in this case, MUST appropriately handle the race condition where the recipient initiated finalization concurrently.

    Cancellation requires the sender to know the ephemeral spending key. If the sender has lost this state, it can be recovered deterministically (see Recovery From Wallet Crash, below).

    -

    Status View

    +

    Status View

    Wallet apps SHOULD let the user view the status of all payments they have generated, as well as all inbound payment (i.e., URI-Encapsulated Payments that have been sent to the app, e.g., by invocation from messaging apps). The status includes the available metadata, and the payment's current state. When pertinent, the wallet app SHOULD offer the ability to finalize any Pending inbound payment, and MAY offer the ability to cancel any outbound payment.

    Wallet apps SHOULD actively alert the user (e.g., via status notifications) if a payment that they sent has not been finalized within a reasonable time period (e.g., 1 week), and offer to cancel the payment.

    -

    Recovery From Wallet Crash

    +

    Recovery From Wallet Crash

    When recovering from a backed-up wallet phrase, wallet implementations already need to scan the entire chain (from the wallet's birthday) to find transactions that were received by or sent from the wallet. Simultaneously with this, the wallet may recover state about previously-created payment URIs, and regain access to non-finalized funds.

    We define a “gap limit” N, similar to the “address gap limit” in BIP 44. If a wallet implementation observes N sequentially-derived payment URIs that have no corresponding on-chain note, they may safely expect that no payment URIs beyond that point have ever been derived.

    Given that both the derivation of a payment URI and the action of “filling” it with a note are performed by the same entity (and in most cases sequentially), it is unlikely that there would be a significantly large gap in payment URI usage. As a balance between the cost of scanning multiple ivks, and the likelihood of missing on-chain funds due to out-of-order payment URI generation, we specify a standard gap limit of N = 3.

    @@ -222,7 +222,7 @@

    For this recovery process to succeed, wallet implementations MUST fund payment URIs with a Sapling spending key in the wallet. Alternatively, wallet implementations MAY include the set of payment URI ivks within the set of ivks they are using for normal chain scanning, but this will slow down the recovery process by a factor of 4 (for a gap limit of N = 3, and a wallet with one Sapling account).

    -

    Security Considerations

    +

    Security Considerations

    • Anyone who intercepts the URI-Encapsulated Payments may steal the encapsulated funds. Therefore, URI-Encapsulated Payments should be sent over a secure channel, and should be kept secret from anyone but the intended recipient.
        @@ -244,8 +244,8 @@
      • Usage of URI-Encapsulated Payments may train users to, generally, click on other types of URI/URL links sent in other messaging contexts. Malicious links sent via unauthenticated messaging channels (e.g., emails and SMS texts) are a common attack vector, used for exploiting vulnerabilities in the apps triggered to handle these links. Even though the fault for vulnerabilities lies with those other apps, and even though this ZIP uses deep link URIs in the way intended, there are none the less these negative externalities to encouraging such use.
    -

    Design Decisions and Rationale

    -

    Rationale for URI Format

    +

    Design Decisions and Rationale

    +

    Rationale for URI Format

    The URI format https://pay.withzcash.com:65536/v1#... was chosen to allow automatic triggering of wallet software on mobile devices, using the platform's applink mechanism, while minimizing the risk of payment information being intercepted by third parties. The latter is prevented by a defense in depth, where any of the following suffices to prevent the payment information from being exposed over the network:

    • The pay.withzcash.com domain should not resolve.
    • @@ -263,7 +263,7 @@

      Another option, which can be added to any of the above, is to add a confirmation code outside the URI that needs to be manually entered by the user into the wallet app, so that merely intercepting the URI link would not suffice. This does not seem to significantly reduce risk in the scenarios considered, and so deemed to not justify the reduced usability.

    -

    Identifying Notes

    +

    Identifying Notes

    The recipient's wallet needs to identify the notes related to the payment (and the on-chain transactions that contain them), in order to verify their validity and then (during the finalization process) spend them.

    The following is out of date, and reflects an earlier design choice (“0”), while we have transitioned to a different choice (“4”). To be revised.

    In the above description, we explicitly list the notes involved in the payment (which are easily mapped to the transactions containing them, using a suitable index). This results in long URIs when multiple notes are involved (e.g., when using the aforementioned “powers-of-2 amounts” technique).

    @@ -280,7 +280,7 @@

    System Message: INFO/1 (zip-0324.rst line 355)

    Enumerated list start value not ordinal-1: "0" (ordinal 0)

    -

    Additional rationale

    +

    Additional rationale

    1. The metadata (amount and description) is provided within the URI. An alternative would be to encode the description in the encrypted memo fields of the associated shielded transactions, and compute the amount from those transactions. However, in that case the metadata would not be available for presentation to the user until the transactions have been retrieved from the blockchain.
    2. We support multiple spending keys and multiple notes in one URI, because these payments may be speculatively generated and mined before the payment amount is determined (to allow payments with no latency). For example, the sending wallets may pre-generate transactions for powers-of-2 amounts, and then include only a subset of them in the URI, totalling to the desired amount.
    3. @@ -288,8 +288,8 @@

      System Message: INFO/1 (zip-0324.rst line 355)

    -

    Open Questions

    -

    URI Usability

    +

    Open Questions

    +

    URI Usability

    The URI could be changed in several ways due to usability concerns:

    1. It may be desirable to prevent the amount and desc parameters from being human readable. This is to discourage people from just looking at the URI, seeing the numbers and text, and mistakenly thinking this is already a confirmation of successful receipt (without going through the finalization process).
    2. @@ -302,15 +302,15 @@

      System Message: INFO/1 (zip-0324.rst line 355)

    -

    Note retrieval

    +

    Note retrieval

    Ideally: a lightweight wallet can receive the funds with the assistance of a more powerful node, with minimal information leakage to that node (e.g., using simple lookups queries that can be implemented via Private Information Retrieval). The open question is how to do this given that most practical PIR are for retrieving an index out of an array, not a key from a key value standpoint.

    -

    Other Questions

    +

    Other Questions

    Should senders delay admitting a generated transaction by a random amount to prevent traffic analysis (i.e., so the messaging service operator cannot correlate messages with on-chain transactions)?

    Consider the behavior in case a chain reorgs invalidates a sent payment. Should we specify a Merkle root or block hash to help detect this reason for payment failure? Or have some servers that maintain a cache of payments that were invalidated by reorgs?

    -

    References

    +

    References

    @@ -376,7 +376,7 @@

    System Message: INFO/1 (zip-0324.rst line 355)

    -

    Publication Blockers

    +

    Publication Blockers

    • Clean up semantics.
    • Clean up rationale.
    • diff --git a/zip-0340.html b/zip-0340.html new file mode 100644 index 000000000..1362fc5e3 --- /dev/null +++ b/zip-0340.html @@ -0,0 +1,438 @@ + + + + ZIP 340 + + + + + +

      Coin Voting

      +

      This ZIP describes a mechanism for the organization of coin-weighted +election.

      +

      Use Case

      +

      A person or organization, referred as the Election Board (EB) decides +to request the opinion of the zcash holders (ZH) on a particular topic. +The EB defines the parameters of the referendum: - when it starts +(snapshot height) and stops (closing height) - An optional lockdown +period before it closes - the question asked - the criteria for +aggregating the votes

      +

      They publically ask the ZH to participate by sending them ballots. +They verify and tally the votes following the aggregation method +(typicall linear, but it could be quadratic or something else). Then +they publish the outcome.

      +

      The final result of the election is a list of valid ballots that +have: - a value in ZEC - a message

      +

      The content of the message depends on the type of referendum. The +acceptable options should be defined by EB. For example, for a yes/no +question, it could simply be a value of 0 or 1.

      +

      The EB could decide to accept write-in votes too. The format of the +message is not part of this ZIP.

      +

      The value of the ballot MUST be an amount of ZEC that the ZH can +spend at the snapshot height.

      +

      The ZH is not obligated to vote with all the ZEC that they have. But +it MUST be impossible to use the same coins to vote twice on the same +election.

      +

      It MUST be possible to use the same ZEC on DIFFERENT elections.

      +

      See Privacy section on important caveats regarding concurrent +voting.

      +

      Other Uses Cases

      +

      Airdrop

      +

      This ZIP can be used to perform air-drops. An organization that wants +to give their tokens/coins based on an amount of ZEC can organize an +election. The ballots contain the ZH’s address where they want to +receive the airdrop.

      +

      Proof of Balance

      +

      In this case, the ZH sends an empty message because the ballot value +is all that matters.

      +

      Requirements

      +

      Participants / Actors

      +

      Election Board

      +

      The Election Board (EB) is the entity in charge of organizing the +election (E). - The EB MUST have a website secured by https that clearly +reflects their identity. - They MUST make their announcements through +their website. - The EB SHOULD have a forum for election related +discussions - The EB MUST set the election parameters described in a +later section - The EB MUST publish the election parameters on their +website - The election parameters are immutable. If the EB wants to make +a modification, another election MUST be created

      +

      Voter (ZH)

      +

      Anyone who has spending authority of ZEC (either transparent +or shielded) can participate.

      +
        +
      • Ballots MUST have a ZEC value
      • +
      • Ballots MUST have a message in the format defined by the +Election
      • +
      • Ballots MUST include a proof of spending authority for the amount +specified, valid at the snapshot height
      • +
      • Ballots MUST not prevent the ZH from spending the coins in a +transaction
      • +
      • Coins spent before the snapshot height MUST not be eligible for +voting
      • +
      • Voting MUST not disclose information that would allow someone to use +the coins themselves (in a transaction or an election)
      • +
      • Ballots MUST follow the format specified in the section Ballot
      • +
      • ZEC held in transparent t3 addresses CANNOT be used. They introduce +most complexity and are not used much
      • +
      +

      Notes: - Having coins on an exchange such as Binance, Bitfinex, etc. +does not allow you to vote because the coins are under their custody - +The EB MAY set special rules for the election. For example, there MAY be +a fee for casting a vote or a minimum ZEC requirement

      +

      Privacy

      +
      +

      If the coins used for voting for a given election are not moved +before voting for another election, it is possible to link the +votes.

      +
      +
        +
      1. Transparent inputs are in clear
      2. +
      3. Shielded inputs reveal their nullifier
      4. +
      +

      The total value is also revealed since it is the weight of the +vote.

      +

      To mitigate this issue, the user SHOULD be offered to move their +coins after a vote. However, if multiple elections are carried out +concurrently with similar snapshot heights, it will be impossible for a +Voter to participate in both without linking their votes.

      +

      A possible solution is suggested in Air drops, +Proof-of-Balance, and Stake-weighted Polling

      +

      Alternatively, homomorphic encryption could be used in order to tally +the votes without decrypting them individually. However, this would be +less flexible than the above.

      +

      Workflow

      +

      The election E is carried in several sequential phases.

      +
        +
      1. The EB publishes the E parameters and advertise the E
      2. +
      3. Each V prepares his/her ballot and send it to the EB
      4. +
      5. The EB returns a receipt to the V
      6. +
      7. The E enters a lockdown period
      8. +
      9. The E closes and the results are published
      10. +
      +
      sequenceDiagram
      +    EB->>Public: Publish Election
      +    Note over V,EB: When snapshot height reached
      +    loop every Voter, concurrently
      +    V->>EB: Ballot
      +    EB-->>V: Receipt
      +    end
      +
      +    Note over V,EB: When lockdown height reached
      +    EB->>Public: List of Ballot ID
      +    Note over V,EB: When expiration height reached
      +    loop every Voter, concurrently
      +    V->>EB: Ballot Decryption Key
      +    end
      +    EB->>Public: Publish Decrypted Ballots, E results
      +

      Ballots

      +

      The message part of a Ballot is encrypted with the V key. The +decryption key is sent to the EB after the lockdown period. The EB +validates the ballot coin value and returns a receipt. The Receipt +contains a signature from the EB.

      +

      Lockdown Period / Ballot +List commitment

      +

      The lockdown period is optional but RECOMMENDED.

      +

      It gives time for the Voters to check that their ballot is recorded +by the EB publicly and that no additional ballots are added after their +opening.

      +

      If a V does not see their ballot on the list, they MUST contact the +EB and resolve the dispute. Their receipt has the EB signature and +proves the integrity of the ballot. Failure to recognize a valid ballot +is a serious breach of trust.

      +

      Counting

      +

      After the lockdown period, V MUST send their decryption key to the +EB.

      +

      EB decrypts the vote and updates the tally.

      +

      Finally EB publishes the results for everyone to see.

      +

      The encrypted ballots and their decryption keys are published for +verification.

      +

      Verification

      +
        +
      • Check that the ballot hashes correspond to the ballot published
      • +
      • For each ballot,
      • +
      +
        +
      1. Check the validity of the signatures and the zkps
      2. +
      3. Compute the coin value
      4. +
      5. Decrypt the vote
      6. +
      7. Tally the vote weighted by the coin value
      8. +
      +

      Specifications

      +

      The communication uses binary messages in protobuf format.

      +

      EB

      +
        +
      • URL: +
          +
        • MUST be https
        • +
        • MUST identify the organization
        • +
      • +
      • Name +
          +
        • MUST be unique to organization
        • +
      • +
      • start_height
      • +
      • snapshot height
      • +
      • lockdown height
      • +
      • closing height
      • +
      • the EB public key
      • +
      +

      Example:

      +
      url = "https://election.methyl.cc"
      +name = "Test Election 2024"
      +start_height = 2397000
      +snapshot_height = 2462430
      +lockdown_height = 2460000
      +closing_height = 2460000
      +msg_size = 64
      +public= "788ff50468e2c095d97f8249e27eef3afe8a07712988a475583eb89494d64abe"
      +cmx_root = "063121a1fed23f154e18d9dfc70a13867f295207fd3c59d0e3f86615b857d332"
      +nf_root = "5341fe36634580cdf8862a106dab2cf7bd39f67d171a2877995babb435a5ee0e"
      +

      Only notes received and unspent between the start_height and the +snapshot height are eligible.

      +

      The start_height defaults to the Sapling activation height.

      +

      In addition, the EB MUST define a message in protobuf format. The +message MUST have a fixed size.

      +

      public is defined in the section Message Encryption

      +

      Example:

      +
      message BallotContent {
      +    uint8 candidate = 1;
      +}
      +

      From the E definition, the E domain is calculated as

      +

      domain = Blake2b-256(b"Zcash_WCV_domain", E)

      +

      The E domain is included in the ballot and ensures that ballots +cannot be replayed.

      +

      Ballot

      +
      syntax = "proto3";
      +package proof_balance;
      +// Protobuf does not support fixed size arrays
      +// This type MUST be 32 byte-long
      +message b256 {
      +    bytes b = 1;
      +}
      +
      +// A ballot is made of 2 parts, 
      +// the data part is non malleable and is used to calculate the sighash
      +// the witness part has the signatures and the zkp
      +message Ballot {
      +    BallotData data = 1;
      +    Witness witness = 2;
      +}
      +
      +message Header {
      +    uint32 version = 1; // version = 1
      +    b256 domain = 2; // Election Domain
      +}
      +
      +message BallotData {
      +    Header header = 1;
      +    TransparentData tdata = 2; // transparent inputs
      +    ShieldedData zdata = 3; // sapling inputs
      +    ShieldedData odata = 4; // orchard inputs
      +    EncMessage enc_message = 5; // encrypted vote
      +}
      +
      +message EncMessage {
      +    bytes epk = 1;
      +    bytes data = 2;
      +    bytes tag = 3;
      +}
      +
      +message Witness {
      +    TransparentWitness twitness = 1; // transparent sigs
      +    SaplingWitness zwitness = 2; // sapling sigs & zkp
      +    OrchardWitness owitness = 3; // orchard sigs & zkp
      +}
      +
      +// Transparent Input, i.e UTXO
      +message TxIn {
      +    b256 txid = 1;    // prev txout
      +    uint32 vout = 2;  // index of the output
      +}
      +
      +message TransparentData {
      +    repeated TxIn txin = 1;
      +}
      +
      +// See section 7.3 and 7.5 of [protocol doc]
      +message Spend {
      +    b256 commitment_value = 1;
      +    b256 nullifier = 2;
      +    b256 rk = 3;
      +}
      +
      +message ShieldedData {
      +    // b256 anchor = 1; // MUST be the anchor at snapshot height
      +    repeated Spend spends = 2;
      +    uint64 valuebalance = 3;
      +}
      +
      +message Signature {
      +    bytes b = 1; // 64 bytes, r, s
      +}
      +
      +message TransparentProof {
      +    b256 pk = 1;
      +    Signature signature = 2;
      +}
      +
      +message TransparentWitness {
      +    repeated TransparentProof proofs = 1;
      +}
      +
      +message SaplingSpendProof {
      +    bytes zkproof = 1; // 192 bytes
      +    Signature signature = 2;
      +}
      +
      +message SaplingWitness {
      +    repeated SaplingSpendProof proofs = 1;
      +    Signature binding_signature = 2;
      +}
      +
      +message OrchardWitness {
      +    repeated Signature signatures = 1;
      +    bytes zkproof = 2; // 2720 + 2272 * nOrchard
      +    Signature binding_signature = 3;
      +}
      +
      +message ElectionId {
      +    string name = 1;
      +}
      +
      +message ElectionInfo {
      +    string url = 1;
      +    string name = 2;
      +    uint32 start_height = 3;
      +    uint32 snapshot_height = 4;
      +    uint32 lockdown_height = 5;
      +    uint32 closing_height = 6;
      +    string pk = 7;
      +    uint32 msg_size = 8;
      +    bytes cmx_root = 9;
      +    bytes nf_root = 10;
      +}
      +
      +message ProofDomain {
      +    bytes domain = 1;
      +}
      +
      +message Proof {
      +    bytes cv = 1;
      +    bytes nullifier = 2;
      +    bytes rk = 3;
      +    bytes proof = 4;
      +}
      +
      +

      Ballot Hash / Sighash

      +

      For the signatures, the sighash is the blake2b-256 hash of the +serialization of the ballot data (in protobuf 3) with personalization +string Zcash_WCV___Hash.

      +

      hash = Blake2b-256("Zcash_WCVSigHash", BallotData).

      +

      Message Encryption

      +

      The EB MUST sign the ballot sighash with a ed25519 signing key and +return a receipt as a bech32m encoded signature with hrp +pob-receipt-

      +

      The Voter MUST add a message in the format specified by the EB. The +message is encrypted into EncMessage. - epk is a 32 byte public key on +x25519 - the Voter reveals his own ed25519 signing key after the vote +closes - the EB converts the key to a x25519 secret key - the EB uses DH +to calculate a shared key KA - SymKey = Blake2b-256(KA, +perso=“Zcash_ProofBlnce”) - SymKey is used with Chacha20-Poly1305 to +decrypt the message - The tag MUST match the decrypted tag

      +

      Rationale: This design allows the use of ed25519 SSH keys for both +Voter and EB.

      +
      +

      The Voter SHOULD not reuse the signing key!

      +
      +

      POC

      +

      The POC is for a modified version specific to Orchard that uses +nullifiers scoped by elections.

      +

      Poll/Election Setup

      +

      The EB (Election Board) generates an openssh ed25519 signing key

      +
      openssl genpkey -algorithm ed25519 -out poller.pem
      +
      +

      The key MAY be reused. It is used for signing ballot receipts. It is +RECOMMENDED to use a different key per election.

      +
      +

      The EB chooses a event properties

      +
      url = "https://election.methyl.cc"
      +name = "Test Election 2024"
      +start_height = 2397000
      +snapshot_height = 2462430
      +lockdown_height = 2460000
      +closing_height = 2460000
      +msg_size = 64
      +public= "788ff50468e2c095d97f8249e27eef3afe8a07712988a475583eb89494d64abe"
      +cmx_root = "063121a1fed23f154e18d9dfc70a13867f295207fd3c59d0e3f86615b857d332"
      +nf_root = "5341fe36634580cdf8862a106dab2cf7bd39f67d171a2877995babb435a5ee0e"
      +

      The public key MUST match the EB signing key.

      +

      The cmx_root and nf_root are OPTIONAL but +if present MUST match the hashes calculated by building the reference +data.

      +
      +

      If the snapshot height is not in the past, it is impossible to +calculate the tree roots.

      +
      +

      The EB publishes the election.toml file so that voters +can download it.

      +

      Voter Send their Ballots

      +

      Once the snapshot height is reached and before the lockdown height, +voters can submit their vote.

      +

      They have to follow the steps: - generate an openssh ed25519 key; - +download block data for the range from start height to snapshot height; +- build reference data, i.e. cmx and nf Merkle trees; - copy their +wallet file zec.db from Ywallet. The vote does not have to +use this wallet app as long as it has the note data: - d, pkd, - v, - +rseed, - ρ, ψ - note position - create the proof +with a ballot message; - submit the ballot to the EB; - wait until the +election reaches the closing height.

      +
      >> load-identity voter.pem
      +c76a89174ed64479c5f567b955ce27ce998568e72a044de80b0ebe748d826b3c
      +>> download https://lwd1.zcash-infra.com:9067
      +>> build-reference-data
      +Root cmxs: 5de18172c1c9d2a526a9c73067e75dfbe1ac4e774e1bfec9a31ee178db98a635
      +Root nfs: 12d4776996da7929255bccfcb21c99853d840c4008da547b113c4c857eec3d29
      +>> create-proof pob.bin 1 "Vote for BOB!"
      +5c70068567d0b8d52e4dcfc395a67dc83fd6bdf9c65a835b41d2bfeb776480fb
      +cmx anchor: 5de18172c1c9d2a526a9c73067e75dfbe1ac4e774e1bfec9a31ee178db98a635
      +nf  anchor: 12d4776996da7929255bccfcb21c99853d840c4008da547b113c4c857eec3d29
      +

      EB Collects Votes

      +

      The EB collects votes and verifies the validity of the ZKP, spending +signatures and binding signature. It also checks that the root hashes +match and that the nullifiers are not used.

      +

      If everything is fine, the EB returns a receipt that is a signature +on the sighash of the ballot.

      +
      >> load-identity poller.pem
      +3f8a41af400aa0197594a7b5c2e21bb6307753840a8513b28b816aad43fb30c0
      +>> init-db
      +>> verify-proof pob.bin
      +ZK Proof verified!
      +Spending Signature verified!
      +Binding Signature verified!
      +Verified 0.05000000 ZEC
      +Receipt: pob-receipt-1djsvezm3wep2ganwd4upzawxsgz60hq2e86cqkv4djmusut4fjzzvzu2ut5z3uda4eedvff6anlmzz3k48d7ugxsrs0gxfn36nscvqqzn4js8
      +

      At this point, the ballot is verified and its amount can be accounted +for but the vote payload is not revealed.

      +
      +

      The EB publishes the ballot hashes and receipts on their website.

      +
      +

      Opening Votes

      +

      Voters uploads their signing key to the EB.

      +
      >> load-identity voter.pem
      +c76a89174ed64479c5f567b955ce27ce998568e72a044de80b0ebe748d826b3c
      +>> open-proof pob.bin
      +5c70068567d0b8d52e4dcfc395a67dc83fd6bdf9c65a835b41d2bfeb776480fb
      +Decrypted message: Vote for BOB!
      +
      +

      The EB counts the votes and publishes the results

      +
      +

      Audit

      +
      +

      The EB publishes all ballots and their opening keys for verification +by auditors.

      +
      + + diff --git a/zip-0340.md b/zip-0340.md new file mode 100644 index 000000000..7f9a2629c --- /dev/null +++ b/zip-0340.md @@ -0,0 +1,537 @@ +--- +title: Coin Voting +breaks: false +tags: coin_voting +--- + +# Coin Voting + +This ZIP describes a mechanism for the organization of +coin-weighted election. + +## Use Case + +A person or organization, referred as the Election Board (EB) +decides to request the opinion of the zcash holders (ZH) +on a particular topic. The EB defines the parameters of the +referendum: +- when it starts (snapshot height) and stops (closing height) +- An optional lockdown period before it closes +- the question asked +- the criteria for aggregating the votes + +They publically ask the ZH to participate by sending them ballots. +They verify and tally the votes following the aggregation method (typicall linear, but it could be quadratic or something else). Then they publish the outcome. + +The final result of the election is a list of valid ballots that have: +- a value in ZEC +- a message + +The content of the message depends on the type of referendum. +The acceptable options should be defined by EB. For example, for a +yes/no question, it could simply be a value of 0 or 1. + +The EB could decide to accept write-in votes too. The format of the +message is not part of this ZIP. + +The value of the ballot MUST be an amount of ZEC that the ZH +can spend at the snapshot height. + +The ZH is not obligated to vote with all the ZEC that they have. +But it MUST be impossible to use the same coins to vote +twice on the same election. + +It MUST be possible to use the same ZEC on DIFFERENT elections. + +**See Privacy section on important caveats regarding concurrent +voting.** + +## Other Uses Cases + +### Airdrop +This ZIP can be used to perform air-drops. An organization +that wants to give their tokens/coins based on an amount +of ZEC can organize an election. The ballots contain +the ZH's address where they want to receive the airdrop. + +### Proof of Balance +In this case, the ZH sends an empty message because the +ballot value is all that matters. + +# Requirements + +## Participants / Actors + +### Election Board + +The Election Board (EB) is the entity in charge of organizing +the election (E). +- The EB MUST have a website secured by https that clearly +reflects their identity. +- They MUST make their announcements +through their website. +- The EB SHOULD have a forum for election related discussions +- The EB MUST set the election parameters described in a later +section +- The EB MUST publish the election parameters on their website +- The election parameters are immutable. If the EB +wants to make a modification, another election MUST be created + +### Voter (ZH) + +Anyone who has *spending authority* of ZEC +(either transparent or shielded) can +participate. + +- Ballots MUST have a ZEC value +- Ballots MUST have a message in the format defined by the Election +- Ballots MUST include a proof of spending authority for the +amount specified, valid at the snapshot height +- Ballots MUST not prevent the ZH from spending the coins in a transaction +- Coins spent before the snapshot height MUST not be eligible for voting +- Voting MUST not disclose information that would allow someone +to use the coins themselves (in a transaction or an election) +- Ballots MUST follow the format specified in the section Ballot +- ZEC held in transparent t3 addresses CANNOT be used. They introduce +most complexity and are not used much + +Notes: +- Having coins on an exchange such as Binance, Bitfinex, etc. +does not allow you to vote because the coins are under their custody +- The EB MAY set special rules for the election. For example, +there MAY be a fee for casting a vote or a minimum ZEC requirement + +## Privacy +:::danger +If the coins used for voting for a given election are not moved +before voting for another election, it is possible to link +the votes. +::: + +1. Transparent inputs are in clear +1. Shielded inputs reveal their nullifier + +The total value is also revealed since it is the weight +of the vote. + +To mitigate this issue, the user SHOULD be offered to move +their coins after a vote. However, if multiple elections +are carried out concurrently with similar snapshot +heights, it will be impossible for a Voter to participate +in both without linking their votes. + +A possible solution is suggested in +[Air drops, Proof-of-Balance, and Stake-weighted Polling](https://hackmd.io/ujald5ElTMumppM7juk2WA?both) + +Alternatively, homomorphic encryption could be used in +order to tally the votes without decrypting them individually. +However, this would be less flexible than the above. + +## Workflow + +The election E is carried in several sequential phases. + +1. The EB publishes the E parameters and advertise the E +1. Each V prepares his/her ballot and send it to the EB +1. The EB returns a receipt to the V +1. The E enters a lockdown period +1. The E closes and the results are published + +```mermaid +sequenceDiagram + EB->>Public: Publish Election + Note over V,EB: When snapshot height reached + loop every Voter, concurrently + V->>EB: Ballot + EB-->>V: Receipt + end + + Note over V,EB: When lockdown height reached + EB->>Public: List of Ballot ID + Note over V,EB: When expiration height reached + loop every Voter, concurrently + V->>EB: Ballot Decryption Key + end + EB->>Public: Publish Decrypted Ballots, E results +``` + +## Ballots + +The message part of a Ballot is encrypted with the V key. +The decryption key is sent to the EB after the lockdown period. +The EB validates the ballot coin value and returns a receipt. +The Receipt contains a signature from the EB. + +## Lockdown Period / Ballot List commitment +The lockdown period is optional but RECOMMENDED. + +It gives time for the Voters to check that their ballot is +recorded by the EB publicly and that no additional ballots are +added after their opening. + +If a V does not see their ballot on the list, they MUST +contact the EB and resolve the dispute. Their receipt +has the EB signature and proves the integrity of the ballot. +Failure to recognize a valid ballot is a serious breach +of trust. + +## Counting + +After the lockdown period, V MUST send their +decryption key to the EB. + +EB decrypts the vote and updates the tally. + +Finally EB publishes the results for everyone to see. + +The encrypted ballots and their decryption keys are published +for verification. + +## Verification + +- Check that the ballot hashes correspond to the ballot published +- For each ballot, +1. Check the validity of the signatures and the zkps +1. Compute the coin value +1. Decrypt the vote +1. Tally the vote weighted by the coin value + +# Specifications + +The communication uses binary messages in protobuf format. + +## EB + +- URL: + - MUST be https + - MUST identify the organization +- Name + - MUST be unique to organization +- start_height +- snapshot height +- lockdown height +- closing height +- the EB public key + +Example: +```toml= +url = "https://election.methyl.cc" +name = "Test Election 2024" +start_height = 2397000 +snapshot_height = 2462430 +lockdown_height = 2460000 +closing_height = 2460000 +msg_size = 64 +public= "788ff50468e2c095d97f8249e27eef3afe8a07712988a475583eb89494d64abe" +cmx_root = "063121a1fed23f154e18d9dfc70a13867f295207fd3c59d0e3f86615b857d332" +nf_root = "5341fe36634580cdf8862a106dab2cf7bd39f67d171a2877995babb435a5ee0e" +``` + +Only notes received and unspent between the start_height and the snapshot height +are eligible. + +The start_height defaults to the Sapling activation height. + +In addition, the EB MUST define a message in protobuf format. +The message MUST have a fixed size. + +`public` is defined in the section Message Encryption + +Example: +```proto +message BallotContent { + uint8 candidate = 1; +} +``` + +From the E definition, the E domain is calculated as + +`domain = Blake2b-256(b"Zcash_WCV_domain", E)` + +The E domain is included in the ballot and ensures that +ballots cannot be replayed. + +## Ballot + +```protobuf= +syntax = "proto3"; +package proof_balance; +// Protobuf does not support fixed size arrays +// This type MUST be 32 byte-long +message b256 { + bytes b = 1; +} + +// A ballot is made of 2 parts, +// the data part is non malleable and is used to calculate the sighash +// the witness part has the signatures and the zkp +message Ballot { + BallotData data = 1; + Witness witness = 2; +} + +message Header { + uint32 version = 1; // version = 1 + b256 domain = 2; // Election Domain +} + +message BallotData { + Header header = 1; + TransparentData tdata = 2; // transparent inputs + ShieldedData zdata = 3; // sapling inputs + ShieldedData odata = 4; // orchard inputs + EncMessage enc_message = 5; // encrypted vote +} + +message EncMessage { + bytes epk = 1; + bytes data = 2; + bytes tag = 3; +} + +message Witness { + TransparentWitness twitness = 1; // transparent sigs + SaplingWitness zwitness = 2; // sapling sigs & zkp + OrchardWitness owitness = 3; // orchard sigs & zkp +} + +// Transparent Input, i.e UTXO +message TxIn { + b256 txid = 1; // prev txout + uint32 vout = 2; // index of the output +} + +message TransparentData { + repeated TxIn txin = 1; +} + +// See section 7.3 and 7.5 of [protocol doc] +message Spend { + b256 commitment_value = 1; + b256 nullifier = 2; + b256 rk = 3; +} + +message ShieldedData { + // b256 anchor = 1; // MUST be the anchor at snapshot height + repeated Spend spends = 2; + uint64 valuebalance = 3; +} + +message Signature { + bytes b = 1; // 64 bytes, r, s +} + +message TransparentProof { + b256 pk = 1; + Signature signature = 2; +} + +message TransparentWitness { + repeated TransparentProof proofs = 1; +} + +message SaplingSpendProof { + bytes zkproof = 1; // 192 bytes + Signature signature = 2; +} + +message SaplingWitness { + repeated SaplingSpendProof proofs = 1; + Signature binding_signature = 2; +} + +message OrchardWitness { + repeated Signature signatures = 1; + bytes zkproof = 2; // 2720 + 2272 * nOrchard + Signature binding_signature = 3; +} + +message ElectionId { + string name = 1; +} + +message ElectionInfo { + string url = 1; + string name = 2; + uint32 start_height = 3; + uint32 snapshot_height = 4; + uint32 lockdown_height = 5; + uint32 closing_height = 6; + string pk = 7; + uint32 msg_size = 8; + bytes cmx_root = 9; + bytes nf_root = 10; +} + +message ProofDomain { + bytes domain = 1; +} + +message Proof { + bytes cv = 1; + bytes nullifier = 2; + bytes rk = 3; + bytes proof = 4; +} + +``` + +### Ballot Hash / Sighash + +For the signatures, the sighash is the blake2b-256 +hash of the serialization of the ballot data (in protobuf 3) +with personalization string `Zcash_WCV___Hash`. + +`hash = Blake2b-256("Zcash_WCVSigHash", BallotData)`. + +## Message Encryption + +The EB MUST sign the ballot sighash with a ed25519 signing key and return +a receipt as a bech32m encoded signature with hrp `pob-receipt-` + +The Voter MUST add a message in the format specified by the EB. +The message is encrypted into EncMessage. +- epk is a 32 byte public key on x25519 +- the Voter reveals his own ed25519 signing key after the vote closes +- the EB converts the key to a x25519 secret key +- the EB uses DH to calculate a shared key KA +- SymKey = Blake2b-256(KA, perso="Zcash_ProofBlnce") +- SymKey is used with Chacha20-Poly1305 to decrypt the message +- The tag MUST match the decrypted tag + +Rationale: This design allows the use of ed25519 SSH keys for both Voter and EB. + +:::warning +The Voter SHOULD not reuse the signing key! +::: + + +# POC + +The POC is for a modified version specific to Orchard that uses +nullifiers scoped by elections. + +## Poll/Election Setup + +The EB (Election Board) generates an openssh ed25519 signing key + +```bash= +openssl genpkey -algorithm ed25519 -out poller.pem +``` + +:::info +The key MAY be reused. It is used for signing ballot receipts. +It is RECOMMENDED to use a different key per election. +::: + +The EB chooses a event properties + +```toml= +url = "https://election.methyl.cc" +name = "Test Election 2024" +start_height = 2397000 +snapshot_height = 2462430 +lockdown_height = 2460000 +closing_height = 2460000 +msg_size = 64 +public= "788ff50468e2c095d97f8249e27eef3afe8a07712988a475583eb89494d64abe" +cmx_root = "063121a1fed23f154e18d9dfc70a13867f295207fd3c59d0e3f86615b857d332" +nf_root = "5341fe36634580cdf8862a106dab2cf7bd39f67d171a2877995babb435a5ee0e" +``` + +The public key MUST match the EB signing key. + +The `cmx_root` and `nf_root` are OPTIONAL but if present +MUST match the hashes calculated by building the reference data. + +:::info +If the snapshot height is not in the past, it is impossible +to calculate the tree roots. +::: + +The EB publishes the `election.toml` file so that voters can download it. + +## Voter Send their Ballots + +Once the snapshot height is reached and before the lockdown height, +voters can submit their vote. + +They have to follow the steps: +- generate an openssh ed25519 key; +- download block data for the range from start height to snapshot height; +- build reference data, i.e. cmx and nf Merkle trees; +- copy their wallet file `zec.db` from Ywallet. The vote does not +have to use this wallet app as long as it has the note data: + - d, pkd, + - v, + - rseed, + - $\rho$, $\psi$ + - note position +- create the proof with a ballot message; +- submit the ballot to the EB; +- wait until the election reaches the closing height. + +``` +>> load-identity voter.pem +c76a89174ed64479c5f567b955ce27ce998568e72a044de80b0ebe748d826b3c +>> download https://lwd1.zcash-infra.com:9067 +>> build-reference-data +Root cmxs: 5de18172c1c9d2a526a9c73067e75dfbe1ac4e774e1bfec9a31ee178db98a635 +Root nfs: 12d4776996da7929255bccfcb21c99853d840c4008da547b113c4c857eec3d29 +>> create-proof pob.bin 1 "Vote for BOB!" +5c70068567d0b8d52e4dcfc395a67dc83fd6bdf9c65a835b41d2bfeb776480fb +cmx anchor: 5de18172c1c9d2a526a9c73067e75dfbe1ac4e774e1bfec9a31ee178db98a635 +nf anchor: 12d4776996da7929255bccfcb21c99853d840c4008da547b113c4c857eec3d29 +``` + +## EB Collects Votes + +The EB collects votes and verifies the validity of the ZKP, spending +signatures and binding signature. It also checks that the root hashes +match and that the nullifiers are not used. + +If everything is fine, the EB returns a receipt that is a +signature on the sighash of the ballot. + +``` +>> load-identity poller.pem +3f8a41af400aa0197594a7b5c2e21bb6307753840a8513b28b816aad43fb30c0 +>> init-db +>> verify-proof pob.bin +ZK Proof verified! +Spending Signature verified! +Binding Signature verified! +Verified 0.05000000 ZEC +Receipt: pob-receipt-1djsvezm3wep2ganwd4upzawxsgz60hq2e86cqkv4djmusut4fjzzvzu2ut5z3uda4eedvff6anlmzz3k48d7ugxsrs0gxfn36nscvqqzn4js8 +``` + +At this point, the ballot is verified and its amount can be accounted +for but the vote payload is not revealed. + +:::info +The EB publishes the ballot hashes and receipts on their website. +::: + +## Opening Votes + +Voters uploads their signing key to the EB. + +``` +>> load-identity voter.pem +c76a89174ed64479c5f567b955ce27ce998568e72a044de80b0ebe748d826b3c +>> open-proof pob.bin +5c70068567d0b8d52e4dcfc395a67dc83fd6bdf9c65a835b41d2bfeb776480fb +Decrypted message: Vote for BOB! +``` + +:::info +The EB counts the votes and publishes the results +::: + +## Audit + +:::info +The EB publishes all ballots and their opening keys for verification +by auditors. +:::