zkDocs: Zero-knowledge Information Sharing

Sam RagsdaleDan Boneh

The majority of blockchain transactions are public by design, available to anyone willing to inspect them. While excellent for auditability, this makes them a less obvious choice for relaying private information. You wouldn’t want to commit your social security number to the Ethereum blockchain, for example. We can, however, use zero-knowledge proofs (which allow us to cryptographically prove facts about information without revealing the information) to not only protect privacy, but also improve on today’s traditional information sharing and verification workflows.

For instance, many organizations and institutions rely on carefully sharing private information and verifying its authenticity for applications from mortgage lending to college admissions. But in practice, these privacy-protecting workflows involve a series of subjective access confirmations as humans query other humans. They are often error-prone, inefficient, and leaky processes that expose unnecessary information, and may not be suitable for handling our most sensitive data.

Here we demonstrate how several cryptographic primitives developed and popularized by the web3 movement can improve information verification workflows, while preserving both privacy and decentralization, through our newly released zkDocs repo. It’s a tool for creating “zero-knowledge enabled documents” that allow various parties in a given workflow to share and verify information, and ensure it meets certain criteria — without unnecessarily exposing it.

But first: how it works, key mechanisms, and more

Let’s start with a quick overview of three important actors in the zkDocs workflow, and how they might interact to apply for and approve a mortgage.

  • Verifier: The admin or creator of a zkDoc schema. In our example, the verifier is the mortgage lender.
  • Submitter: The individual or individuals seeking to have data verified by the schema. This is the loan applicant or potential home buyer.
  • Attestor: A trusted individual or institution that can attest to the truthfulness of one or more of the submitter’s fields. This might be an employer or a home appraiser.

Typically, a mortgage application kicks off a verification workflow in which a mortgage lender (verifier) engages other trusted institutions to confirm an applicant (submitter) meets their requirements. Once the application bounces from institution to institution (attestors), the original lender can approve the loan.

The architecture we lay out allows a verifier to specify a schema of fields and trusted attestors, and then specify some constraints over those fields. In the case of a mortgage application, the lender might specify that the sum of an applicant’s collateral value is greater than their outstanding debt.

zkDocs also allows the submitter to only share pertinent information with each attestor. An employer may only be able to attest to an applicant’s wages and employment status, for example, without seeing unnecessary financial details.

The submitter can then generate a zero-knowledge proof showing that the schema has been filled out truthfully — and that each field has been properly attested to — without revealing any of the underlying data. Any party (including the verifier) can validate the zero-knowledge proof via a lightweight computation.

There are two primary mechanisms to note: attestations and zero-knowledge proofs.

Using blockchains for attestations

Public blockchains have a number of properties that make them ideal for attestations: censorship resistance, public data availability, auditability, and secret signing keys. Attestors can use their private key to sign all transactions sent to the blockchain, ensuring attestations cannot be faked or forged.

However, one of the downsides of posting attestations to a blockchain is that the underlying values are publicly visible. zkDocs solves this by broadcasting cryptographic commitments to the values instead of the cleartext values. These commitments remain publicly available, but their underlying values are not visible.

What’s a cryptographic commitment?

A cryptographic commitment allows one party to generate a commitment to some private data. Later the committer can open the commitment to reveal the committed data. 

Commitment schemes must be (1) hiding, meaning that the commitment reveals nothing about the data, and (2) binding, meaning that the committer cannot find a commitment that it can open in two different ways. 

The simplest commitment scheme is built from a cryptographic hash function — for example, the Poseidon hash. To commit to some data, the committer computes: commitment ← poseidon(data, nonce), where nonce is a random 512-bit string. To open the commitment later, the committer reveals the data and the nonce. Anyone can verify that the commitment was opened correctly.

Verifying private data through zero-knowledge proofs

Zero-knowledge proofs are a method of proving a fact about data without revealing anything about the underlying data. With zkDocs, a submitter can create a zero-knowledge proof that all data has been committed to and satisfies the required constraints. Any third party can run the verification computation without knowledge of, or information about, the underlying data.

The result is that the data required to verify a zkDoc schema submission is publicly available, and fully auditable, while always remaining private.

Specifically, the submitter generates a zero-knowledge proof that it knows an array of (value, nonce) pairs such that:

  • poseidon(value[i], nonce[i]) == prior_commitment[i], and
  • value[0], …, value[n] satisfy the constraints

The submitter can generate a zero-knowledge proof using this circuit and broadcast it to any party interested in verifying their data. Anyone can run the proof and confirm the validity of the fields within the schema.

To demonstrate, let’s look at two short case studies.

Example: mortgage application

First let’s return to the mortgage application, a great example of an information attestation workflow that can be improved with zkDocs.

The mortgage lender (the verifier, in this case) would create a schema for a zkDoc as follows:


{
  "fields": [
    {
      "field_name": "salary"
    },
    {
      "field_name": "401k_income"
    },
    {
      "field_name": "bank_account_balance"
    },
    {
      "field_name": "property_value"
    },
    {
      "field_name": "loan_value"
    }
  ],
  "constraints": [
    {
      "fieldA": "bank_account_balance",
      "fieldB": "property_value",
      "op": "ADD",
      "constraint": "GT",
      "fieldCompare": "loan_value"
    },
    {
      "fieldA": "salary",
      "fieldB": "401k_income",
      "op": "ADD",
      "constraint": "GT",
      "constant": 65000
    }
  ],
  "trusted_institutions": [
    {
      "human_name": "Employer",
      "address": "0xabcd..."
    },
    {
      "human_name": "Home Appraiser",
      "address": "0xabcd..."
    },
    {
      "human_name": "401k Provider",
      "address": "0xabcd..."
    },
    {
      "human_name": "Checking Account Provider",
      "address": "0xabcd..."
    },
    {
      "human_name": "Creditor",
      "address": "0xabcd..."
    }
  ]
}

First the schema specifies several fields that the lender is interested in: salary, 401(k) income, checking account balance, property value, and loan value. Then two constraints over those fields: 

  1. The sum of property value and bank account balance is greater than the loan value
  2. The sum of 401(k) income and salary is greater than $65,000 per year

And finally, five institutions it trusts to attest to this information:

  1. Employer
  2. Home appraiser
  3. 401(k) provider
  4. Checking account provider
  5. Creditor

To apply for a mortgage, the applicant fills out the fields listed in the “fields” section using the zkDocs UI and publishes an on-chain cryptographic commitment to each. The applicant then sends the relevant cleartext fields, along with the nonces for each commitment, to each of the attesting institutions (from the set listed under trusted_institutions). The zkDocs UI does this through hyperlinks.

zkDocs user interface, where submitter fills out fields

Each attestor verifies the relevant cleartext information and attests to the commitment by signing with their Ethereum private key. Then the applicant can submit a transaction to the blockchain including the zero-knowledge proof on the validity of the commitments and constraints, thus qualifying as a valid mortgage recipient. The verifying mortgage institution will not need to perform additional verification to confirm the integrity of the application.

Example: MakerDAO RWA loans

MakerDAO is a lending protocol which, to date, has issued $6 billion in loans denominated in DAI (a USD-pegged token). Maker’s Real World Assets (RWA) division is working on providing DAI-denominated loans to downstream lenders, enabling DAI to directly fuel real-world economic growth. But Maker is a DAO, whose governance token is owned by about 78,000 unique wallets, each with the right to participate in the governance process and steer the future of the protocol.

Most large Maker decisions, such as one to take on a new source of collateral, are discussed in public forums. But an institution or individual applying for a loan from Maker might not be interested in sharing the entirety of their financials with the public for a number of reasons, from privacy to trade secrets. Maker could instead publish a zkDoc with a schema similar to the following:


{
  "fields": [
    {
      "field_name": "custodian_name"
    }, 
    {
      "field_name""total_loan"
    },
    {
      "field_name": "total_collateral_value"
    },
    {
      "field_name": "amount_repaid"
    }
  ],
  "constraints": [
    {
      "fieldA": "total_loan",
      "fieldB": "amount_repaid",
      "op": "SUB",
      "constraint": "LT",
      "fieldCompare": "total_collateral_value"
    }
  ],
  "trusted_institutions": [
    {
      "address": "0xabcd…",
      "human_name": "Bob the Custodian"
    }
  ]
}

This schema would allow governance participants to ensure that the protocol is not taking unreasonable risk, without requiring all RWA loan applicants to violate their privacy.

 

***
zkDocs, as currently implemented, uses:

  • Signed transactions (or any EVM-compatible chain) to verify authenticity of attestations
  • Public blockspace to store both the commitments and attestations
  • Smart contracts to verify zero-knowledge proofs 

Beyond the auditability and privacy properties of zkDocs, there is another interesting axis: Once private information verification is live on a public blockchain, users and developers can compose zkDoc-verified information with their own applications. One could imagine loan history playing into a DAO reputation, community-verified quarterly filings to adjust protocol parameters, instantaneous college applications, discounted protocol rates for users trusted within another community, and much more.

Our goal in sharing this proof of concept is to demonstrate how these new computing primitives can be used in production today, and to help accelerate their adoption by bringing more applications online. If you’re planning to deploy zkDocs to prod or use a similar scheme, please feel free to reach out on Twitter.