Skip to content

gnart33/storage-proof-noir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Storage Proof with Noir

User can prove that he owns an address which has more than 1_000_000 NOIR ERC20 tokens without revealing the address and the balance.

Workflow for user

  • signs a message with his private key
  • use eth_getProof to retrieve the storage proof data from an Ethereum node
  • run the Noir circuit to generate the proof
  • send the proof to the verifier contract using a anonymous account

Current status:

  • Signing message with private key, get data from Alchemy API and process it to be used as input for Noir circuits: ts/utils/populateInput.ts

  • Generate proof with Noir circuits: circuits/whale using Nargo CLI

  • Verifier contract: verifier-contract/src/WhaleVerifier.sol
    Tested with Foundry with input / proof generated from Nargo CLI

  • Testing circuit, generating proof with TypeScript / on browser:
    Currently, the circuit here exceeds the limit that bb.js can handle, recursion is planned to be implemented that will enable us to generate the proof with TypeScript and run it on browser

  • Enforcing user to get eth_getProof data from a defined contract address

    • Using a web app that with defined contract address
    • Include the contract address / codehash in the proof
  • Better double spending prevention mechanism

Repo structure

.
├── circuits
├── erc20-token # NOIR ERC20 token contract
├── ts # testing noir circuits and Ethereum API endpoints utils
└── verifier-contract # verifier contract

Circuits

  • To prove:

    • Ownership of an address
    • That address has more than 1_000_000 NOIR ERC20 tokens
    • Without revealing the address and its balance
  • How?

    • Sign a message with private key
    • Use ecrecover to get the address in the circuit
    • Calculate the key slot corresponding to the address and the balances mapping
    • Use noir-trie-proofs to prove the storage value belongs to the storage root
    • Compare the value with 1_000_000
  • The circuit output the hash of account public key, to be used in the verifier contract to prevent double spendings

  • The circuit is tested and proof is generated with Noir version f3800c52c81a27d3b52cfe23f45e764234b1c268

ERC20 contracts and storage layout

The Noir ERC20 token contract was deployed on Sepolia testnet at address 0x0041ff33e47eae38ab8b9a1c2070e279d5aaf211

Storage layout

$ cd erc20-token
forge inspect src/Noir.sol:Noir storage --pretty
| Name         | Type                                            | Slot | Offset | Bytes | Contract          |
|--------------|-------------------------------------------------|------|--------|-------|-------------------|
| _balances    | mapping(address => uint256)                     | 0    | 0      | 32    | src/Noir.sol:Noir |
| _allowances  | mapping(address => mapping(address => uint256)) | 1    | 0      | 32    | src/Noir.sol:Noir |
| _totalSupply | uint256                                         | 2    | 0      | 32    | src/Noir.sol:Noir |
| _name        | string                                          | 3    | 0      | 32    | src/Noir.sol:Noir |
| _symbol      | string                                          | 4    | 0      | 32    | src/Noir.sol:Noir |
| _owner       | address                                         | 5    | 0      | 20    | src/Noir.sol:Noir |
  • _balances mapping is stored at slot 0, to get the storage slot that store the balance of an address, we need to compute the keccak256 hash of the address and the slot number 0

  • Foundry has a utility for that, for example to get the slot for balance of the address 0x77fCF983241ceb7e8c928102f6fe63A1de834c5D:

$ cast index address 0x77fCF983241ceb7e8c928102f6fe63A1de834c5D 0
0x198faee1dd5108d4ea2f67cf2ffd891b1e4e7cfe8a157beebd36983e882a0dae
  • To get that slot value from an Ethereum node:
$ cast storage 0x0041ff33E47eAE38ab8B9A1C2070E279d5AAf211 0x198faee1dd5108d4ea2f67cf2ffd891b1e4e7cfe8a157beebd36983e882a0dae --rpc-url $SEPOLIA_RPC_URL
0x00000000000000000000000000000000000000000000e8ef1e96ae3897800000
  • TypeScript utilities are also available in ts/utils

ts - Testing noir circuits and Ethereum API endpoints utils

  • Utility to sign message with private key, get data from Alchemy API and process it to be used as input for Noir circuits

  • Testing Noir circuits with TypeScript (in progress)

  • Proving on browser (in progress)

Verifier contract ./verifier-contract

  • plonk_vk.sol is generated by Nargo

  • WhaleVerifier.sol uses plonk_vk.sol to verify the proof and prevent double spendings with mapping which hash of account public key has been used

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published