LogoLogo
zkBob AppLinks & Resources
  • 🦹zkBob Overview
    • zkBob
    • Basic Concepts
      • Getting Started
      • Open-Source and Decentralized
      • Multichain Deployment
      • Usage Statistics
      • Use Cases
        • Employee Salary
        • Vendor Purchasing
      • Development Timeline
      • zk Privacy Solution Comparison
    • zkBob Pools
      • USDC Pool on Polygon (sunsets January 31, 2025)
      • USDC Pool on Optimism
      • ETH Pool on Optimism
      • USDT Pool on Tron (sunsets Oct 29, 2024)
    • Fees
      • Unspent note handling
    • Deposit & Withdrawal Limits
    • Compliance & Security
      • TRM Labs Integration
    • Conferences, Workshops, Videos
      • International Videos
    • Governance
    • BOB Stablecoin
    • zkBob FAQ
  • 🦸‍♂️zkBob Application
    • UI Overview
    • Account Creation
      • Login to an existing account
      • Lost Password
      • Metamask / Web3 Wallet Warning
    • Deposits
    • Transfers
      • Multitransfers
    • Withdrawals
      • Native Token Conversion
    • Generate a Receiving Address
    • Optional KYC
    • zkBob Direct Deposits
    • Support ID
    • Payment Links
    • Integrated Services
    • Multilingual support
      • Português
      • Русский
      • 中文
  • 👩‍⚕️Technical Implementation
    • zkBob Application Overview
    • Deployed Contracts
    • Smart Contracts
      • zkBob Pool Contract
        • Transaction Calldata
      • Bob Token Contract
      • Verifier contracts
      • Operator Manager Contract
        • Mutable Operator Manager
      • Voucher (XP) Token Contract
    • Accounts and Notes
      • Accounts
      • Notes
    • Relayer Node
      • Relayer Operations
      • Optimistic State
      • REST API
    • zkBob Keys
      • Address derivation
      • Ephemeral keys
    • zkSNARKs & Circuits
      • Transfer verifier circuit overview
    • zkBob Merkle Tree
      • The Poseidon Hash
    • Elliptic Curve Cryptography
    • Transaction Overview
      • Common Structure
      • Memo Block
        • Memo Block Encryption
      • Transaction Types
      • Nullifiers
      • Signing a Transaction
      • The Transaction Lifecycle
    • Client Library SDK
      • Configuration
        • Initializing the client
          • Client Configuration
        • Attaching a User Account
          • Account Configuration
        • Switching Between Pools
      • Account-less Mode Operations
        • Converting Token Amounts
        • Transaction Fees
        • Transaction Constraints
        • Using the Delegated Prover
        • Getting the State
        • Gift Cards
        • Client Library Status
        • Helpers
        • Versioning
      • Full Mode Operations
        • Balances and History
        • Shielded Addresses
        • Account State
        • Fee Estimations
        • Transaction Configuration
        • Sending Transactions
        • Transaction Maintenance
        • Direct Deposits
        • Gift Cards Maintenance
        • Ephemeral Deposits
        • Forced Exit
        • Other Routines
      • Common Types
      • Full Functions List
      • Utilities
  • 👩‍🏫Deployment
    • Trusted Setup Ceremony
    • Contract Deployment
    • Relayer Subsystem
  • 👷‍♂️Roadmap
    • On the Roadmap
    • Exploratory Features
      • XP (Experience Points)
        • XP-based Auctions
      • Multi-chain Custom Rollup Deployment
      • Round-robin Operator Manager
      • Compounding
  • 🧑‍💻Jobs
    • Zero-Knowledge Researcher & Protocol Developer
  • 🧩Resources
    • Visual Assets
    • Hackathons
      • zkBob Cloud
    • Release Notes
      • October 11, 2023
      • July 13, 2023
      • June 13, 2023
      • March 28, 2023
      • January 30, 2023
      • January 16, 2023
      • January 2, 2023
      • Releases 2022
    • Security Audit
    • Github
    • Link tree
Powered by GitBook
On this page

Was this helpful?

  1. Technical Implementation
  2. zkBob Keys

Address derivation

Private payment address

PreviouszkBob KeysNextEphemeral keys

Last updated 2 years ago

Was this helpful?

The zkBob account doesn't contain any fixed address. Instead if you want to receive funds you should generate and provide private addresses. In general a new private address can be generated for every incoming transaction. It is not possible to link different private addresses derived from the single account to one another or to the primary account. Only the account owner can confirm a private address belongs to the account.

A new private payment address is generated by:

  • Generate a random 80-bit diversifier ddd

  • Calculate diversifier subgroup generator point: Gd=ToSubGroupHashE(Fr)(d)G_d = \text{ToSubGroupHash}_{E(F_r)}(d)Gd​=ToSubGroupHashE(Fr​)​(d)

  • Derive diversifier public part: Pd=ηGdP_d=\eta G_dPd​=ηGd​​

  • Prepare address data buffer (bufbufbuf, 42 bytes): join 10 byte of the diversifier with 32 bytes of the Pd.xP_d.xPd​.x

  • Get address checksum: checksum=keccak256(buf)checksum = keccak256(buf)checksum=keccak256(buf)

  • Attach checksumchecksumchecksum first 4 bytes to the bufbufbuf

  • Encode bufbufbuf with Base58 to the string

Thus the address string contains the diversifier public key (d,Pd)(d, P_d)(d,Pd​) protected with checksum to avoid typos. Checking any private addresses for ownership is very straightforward. You decode the address string and extract ddd and PdP_dPd​ values. Next you derive Pd′P'_dPd′​​ with the your η\etaη key. The private address belongs to your account only if Pd′=PdP'_d = P_dPd′​=Pd​.

Address derivation example

Let's imagine you have an account with the intermediate key:

η=0x2dedcb9b32000d350bf1055d764302b9d4f4a3820015ea49aaf02438aaa72a85\eta = \mathrm{0x2dedcb9b32000d350bf1055d764302b9d4f4a3820015ea49aaf02438aaa72a85}η=0x2dedcb9b32000d350bf1055d764302b9d4f4a3820015ea49aaf02438aaa72a85​

The big numbers representation

All big numbers on this page are presented in the hexadecimal form to reduce line width. If you want to convert them to the decimal form please use a third-party tool ()

To derive a private address we should generate a random diversifier ddd and calculate the hash for it:

d=0xc2767ac851b6b1e19edad = \mathrm{0xc2767ac851b6b1e19eda}d=0xc2767ac851b6b1e19eda

Add a checksum. To do it we must compute keccak256 hash from the buffer above:

Get the first 4 bytes from the hash above and append them to the end of buffer:

Finally encode this buffer with Base58 to get private address:

QsnTijXekjRm9hKcq5kLNPsa6P4HtMRrc3RxVx3jsLHeo2AiysYxVJP86mriHfN

Hash(d)=0x998ed1a2c59ea1ac23ea4519bd11e88cefe5c888d22bf245b8c22923b4b5488Hash(d) = \mathrm{0x998ed1a2c59ea1ac23ea4519bd11e88cefe5c888d22bf245b8c22923b4b5488}Hash(d)=0x998ed1a2c59ea1ac23ea4519bd11e88cefe5c888d22bf245b8c22923b4b5488​

Convert scalar Hash(d)Hash(d)Hash(d) to the subgroup generator point:

Gd={x=0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef,y=0x2e23e2751abbb64461e9a852b7b20c8337fc279ed748c77dfa23cf6158f6a6c3}G_d = \{\\x = \mathrm{0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef}, \\ y = \mathrm{0x2e23e2751abbb64461e9a852b7b20c8337fc279ed748c77dfa23cf6158f6a6c3}\}Gd​={x=0x2f6f6ef223959602c05afd2b73ea8952fe0a10ad19ed665b3ee5a0b0b9e4e3ef,y=0x2e23e2751abbb64461e9a852b7b20c8337fc279ed748c77dfa23cf6158f6a6c3}​

Put ddd and Gd.xG_d.xGd​.x into the buffer as little-endian numbers (start with the last significant byte):

da 9e e1 b1 b6 51 c8 7a 76 c2 ef e3 e4 b9 b0 a0 e5 3e 5b 66 ed 19 ad 10 0a fe 52 89 ea 73 2b fd 5a c0 02 96 95 23 f2 6e 6f 2f\mathrm{da\ 9e\ e1\ b1\ b6\ 51\ c8\ 7a\ 76\ c2\ ef\ e3\ e4\ b9\ b0\ a0\ } \\ \mathrm{e5\ 3e\ 5b\ 66\ ed\ 19\ ad\ 10\ 0a\ fe\ 52\ 89\ ea\ 73\ 2b\ fd\ } \\ \mathrm{5a\ c0\ 02\ 96\ 95\ 23\ f2\ 6e\ 6f\ 2f}da 9e e1 b1 b6 51 c8 7a 76 c2 ef e3 e4 b9 b0 a0 e5 3e 5b 66 ed 19 ad 10 0a fe 52 89 ea 73 2b fd 5a c0 02 96 95 23 f2 6e 6f 2f

f4 e1 d3 a9 45 a0 c6 4a 2c 8c 60 a6 4b ad 38 04 0f 3f 75 24 30 79 7c 30 d1 41 91 a8 0a b5 4a be \mathrm{f4\ e1\ d3\ a9\ 45\ a0\ c6\ 4a\ 2c\ 8c\ 60\ a6\ 4b\ ad\ 38\ 04\ 0f\ 3f\ 75\ 24\ 30\ 79\ 7c\ 30\ d1\ 41\ 91\ a8\ 0a\ b5\ 4a\ be\ }f4 e1 d3 a9 45 a0 c6 4a 2c 8c 60 a6 4b ad 38 04 0f 3f 75 24 30 79 7c 30 d1 41 91 a8 0a b5 4a be ​

da 9e e1 b1 b6 51 c8 7a 76 c2 ef e3 e4 b9 b0 a0 e5 3e 5b 66 ed 19 ad 10 0a fe 52 89 ea 73 2b fd 5a c0 02 96 95 23 f2 6e 6f 2f f4 e1 d3 a9\mathrm{da\ 9e\ e1\ b1\ b6\ 51\ c8\ 7a\ 76\ c2\ ef\ e3\ e4\ b9\ b0\ a0\ } \\ \mathrm{e5\ 3e\ 5b\ 66\ ed\ 19\ ad\ 10\ 0a\ fe\ 52\ 89\ ea\ 73\ 2b\ fd\ } \\ \mathrm{5a\ c0\ 02\ 96\ 95\ 23\ f2\ 6e\ 6f\ 2f\ f4\ e1\ d3\ a9}da 9e e1 b1 b6 51 c8 7a 76 c2 ef e3 e4 b9 b0 a0 e5 3e 5b 66 ed 19 ad 10 0a fe 52 89 ea 73 2b fd 5a c0 02 96 95 23 f2 6e 6f 2f f4 e1 d3 a9
👩‍⚕️
example
Poseidon