Ontology Developer Center
DISCOVERCOMMUNITYSUPPORT
  • Introduction
  • Discover Ontology
  • Getting Started
  • Glossary
  • Decentralized Identity and Data
    • ONT ID
      • Decentralized Identifiers
        • Method Specification for Ontology
        • Method Specification for Ethereum
        • Method Specification for BSC
      • Verifiable Credentials
        • Anonymous Credentials
      • ONT Login
        • Scenarios
        • Protocol Specification
        • Front-end JavaScript SDK
          • Integration and Usage
          • API Reference
        • Front-end UI SDK
          • Integration and Usage
          • API Reference
        • Back-end Go SDK
          • Integration and Usage
          • API Reference
        • Back-end Java SDK
          • Integration and Usage
          • API Reference
      • ONT TAG
        • Workflow
        • API Reference
      • Mercury
      • OScore
    • DDXF
      • Components and Interfaces
      • GREP
      • Overall Scheme
      • Solutions
        • Marketplace
          • Deployment
          • Scenarios
          • SaaS Tenant
          • Java SDK
        • Data Storage
          • Deployment
          • Java SDK
        • Resource Auditor
        • Offline Judge
      • Use Cases
        • E-Shops
  • ONTOLOGY ELEMENTS
    • Smart Contracts
      • Types of smart contracts
    • Token Protocols
    • Consensus Mechanism
    • Ontology Oracle
      • Oracle Process Flow
  • GUIDES & TUTORIALS
    • Development Guides
      • dApp Development
        • Using the dAPI
        • Data Synchronization
      • Smart Contract Development
        • EVM Contract
          • Development Environment and Tools
          • Wallet Setup
          • Contract Development
          • How to Deploy a Smart Contract with GetBlock
        • NeoVM Contract
          • Development tools and environment
          • Launching the IDE
          • Writing and editing program logic
          • Deploying and testing on private net
        • WASM Contract
          • Development Environment
          • Project Initiation - Hello World
          • Creating your own project
          • Development using SmartX
          • Runtime API
          • Contract Fundamentals
          • Inter-contract Interaction
          • Developing Contracts in C++
        • Publish Contract Source Code
    • Integration Guides
      • dApp Integration
        • dAPI Integration
          • Chrome Plugin
          • Mobile wallet dApp
          • QR code mechanism
          • Wake call mechanism
        • Cocos 2D-x
        • Unity 3D applications
      • Mobile Wallet Integration
        • SDK integration
        • dAPI Integration
          • In-wallet applications
          • QR code mechanism
          • Wake call mechanism
        • Stake
      • Using ONT ID
      • Exchange Integration
        • Exchange Docking Guide
        • Exchange API
      • Ontology for dApp Stores
    • EVM & Token Decimals Upgrade
  • ONTOLOGY NODE
    • Abstract
    • Node Deployment
      • Standard Node
      • Rosetta Node
    • Interacting with a Public Node
  • DEVELOPER TOOLS
    • dApp Development Framework
      • Punica CLI
      • Punica boxes
      • Solo Chain
    • IDE
    • APIs
      • HTTP API
        • Restful
        • WebSocket
        • Remote Procedure Call (RPC)
      • Explorer v2 API
        • Block
        • Address
        • Contract
        • Token
        • Transactions
        • ONT ID
        • Summary
        • Node
      • Native Token API
        • ONT Contract API
        • ONG Contract API
      • ONT ID Contract API
      • Web3 API
      • OScore Open API
      • Rosetta Node API
        • Data API
        • Construction API
      • DToken Contract API
      • DDXF
        • Marketplace Contract API
        • Storage API
      • Governance API
    • Digital Wallet
      • Chrome Plugin provider
      • Chrome Plugin dAPI
      • Mobile version provider
      • Mobile version dAPI
    • SDKs
    • Signing Server
      • Installation
      • API reference
  • COMMUNITY
    • Ecosystem Programs
    • Community Libraries
    • Community Events
    • Community Channels
    • Core Contributors
  • SUPPORT
    • FAQ
      • Basic blockchain concepts
      • Ontology Nodes
      • Ontology token protocols
      • Smart contracts
      • SDKs and APIs
    • Contact Us
Powered by GitBook
On this page
  • Abstract
  • Background
  • BBS + Signature
  • Non-Interactive Proof of Knowledge (PoK) protocol
  • Setup of the Issuer's key pair
  • Issuance Protocol
  • Generating credential request
  • Issuing Credential
  • Presentation Protocol
  • Proving Algorithm
  • Verification

Was this helpful?

  1. Decentralized Identity and Data
  2. ONT ID
  3. Verifiable Credentials

Anonymous Credentials

A zero knowledge proof signature algorithm

PreviousVerifiable CredentialsNextONT Login

Last updated 5 years ago

Was this helpful?

The anonymous credential scheme is a part of the Ontology Crypto library that provides several cryptography related utilities for the Ontology network. The main features provided by the crypto library basically revolve around digital signature. It provides general APIs for processing digital signatures and keys.

Abstract

There are three parties involved in an anonymous credential scheme, namely the issuer, the user (prover), and the verifier.

The issuer provides a certificate to the user. This certificate contains a list of the user's attributes and the issuer's signature (using BBS+signature). This protocol is formally called credential issuance protocol. The user who is in possession of the credentials can selectively disclose some parts to a verifier. This protocol is formally called credential presentation protocol.

Background

BBS + Signature

Setup: Groups G1,G2G_1, G_2G1​,G2​ and Gt .G_t\ .Gt​ . Pairing function e:G1∗G2→Gt ,e: G_1*G_2 \rightarrow G_t \ ,e:G1​∗G2​→Gt​ , where G1G_1G1​ and G2G_2G2​ are both of order ppp. Common parameters:

  • g1g_1g1​ is the generator of G1G_1G1​

  • g2g_2g2​ is the generator of G2G_2G2​

  • Hrand ,h1,... ,hLH_{rand} \ , h_1, ... \ , h_LHrand​ ,h1​,... ,hL​ are elements from G1G_1G1​

KeyGen: A sample xxx from uniform distribution on ZpZ_pZp​, output sk=x , pk=g2xs_k = x \ ,\ p_k = {g_2}^xsk​=x , pk​=g2​x

Sign(sk,m1,... ,mL)(s_k, m_1, ... \ , m_L)(sk​,m1​,... ,mL​): Two random numbers EEE and sssare selected from ZpZ_pZp​. FirstB=g1∗HRands∗(h1m1∗...∗hLmL)B = g_1 * {H_{Rand}}^s * ({h_1}^{m_1} * ... * {h_L}^{m_L})B=g1​∗HRand​s∗(h1​m1​∗...∗hL​mL​) is calculated, and then A=B1/(E+x)A = B^{1/(E+x)}A=B1/(E+x) is computed. The signature is (A,B,E,s)(A, B, E, s)(A,B,E,s)

Verify (pk,m1,... ,mL,sig)(p_k, m_1, ...\ ,m_L, sig)(pk​,m1​,... ,mL​,sig): Decode sigsigsig as (A,B,E,s)(A, B, E, s)(A,B,E,s) , and check if e(A,g2E∗pk)==e(B,g2)e(A, {g_2}^E * p_k) == e(B, g_2)e(A,g2​E∗pk​)==e(B,g2​) and whether B==g1∗HRands∗(h1m1∗...∗hLmL)B == g_1 * {H_{Rand}}^s * ({h_1}^{m_1} * ... * {h_L}^{m_L})B==g1​∗HRand​s∗(h1​m1​∗...∗hL​mL​)

Non-Interactive Proof of Knowledge (PoK) protocol

1. Commitment (Prover)

r = rand(Zp)

t1 = g2^r

t2 = _g1^r

2. Proof (Prover)

P = t1 || t2 || g2 || _g1 || w || _g2    //join them together in binary format

C = hash_to_int(P)                       //C is challenge

S = (r + C * x) mod p                    //response to verifier

3. Verify (Verifier)

_t1 = g2^S * w^(-c)

_t2 = _g1^S * _g2^(-c)

_P = _t1 || _t2 || g2 || _g1 || w || _g2

_C = hash_to_int(_P)

// use C to compare with _C, which was calculated just now
if C == _C {
    return true
} else {
    return false
} 

Setup of the Issuer's key pair

Given an array of the attribute names AttributeNames, the issuer's key pair is generated in the following manner:

The following are the reference data structures for the issuer's key pair:

type IssuerSecretKey struct {
    x BigNum
}
type IssuerPublicKey struct {
    AttributeNames []string
    HAttrs         []G1Point // one G1-element for one attribute
    HRand          G1Point   // a random G1 point 
    HSk            G1Point   // a random G1 point to encode user's secret key 

    w              G2Point   // element from G2  
    _g1            G1Point   // point of G1
    _g2            G1Point   // point of G1

    //PoK{x: w = g2^x && _g2 = _g1^x}
    C              BigNum    // challenge
    S              BigNum    // response
}

Issuance Protocol

Issuance protocol is an interactive protocol that consists of the following steps:

  1. The user creates a credential request using the public key, the secret, and the nonce. This request consists of a commitment to the user secret (can be seen as a public key), and a zero-knowledge proof of the knowledge of the user secret key. The user sends this credential request to the issuer

  2. The issuer verifies the credential request by verifying the zero-knowledge proof If the request is valid, the issuer issues a credential to the user by signing the commitment to the secret key along with the attribute values and then sends the credential back to the user

  3. The user verifies the issuer's signature and stores the credential that consists of the signature value, a randomness used to create the signature, the user secret, and the attribute values

The following diagram represents the interaction between the user and the issuer:

  • Credential contains the BBS+signature on the attributes and the Nym

Generating credential request

The user generates the credential request using the attribute values and the nonce as input. The process is as follows:

The data structure of the credential request is of the following manner:

type CredRequest struct {
   Nym             G1Point  //commitment to user's master secret
   IssuerNonce     BigNum   //nonce 
   Attrs           []BigNum //user's attributes

   //PoK that Nym is constructed as in the issuance protocol
   // i.e. PoK{(sk): HSk^sk = Nym }
   C               BigNum   //challenge in Sigma-protocol
   S               BigNum   //response in Sigma-protocol
}

Issuing Credential

  1. Calculate B = g1 · HRand^s · Nym · MulAll(HAttrs[i]^(Attrs[i]))

  2. Compute A = B^(1/(e+x))

The data structure of a credential looks something like:

type Credential struct {
   A               G1Point
   B               G1Point
   e               BigNum
   s               BigNum
   Attrs           []BigNum
}

Presentation Protocol

In the presentation protocol, the prover tries to convince the verifier that they are aware of some secret input, such that some hypothetical predicate is true. A typical example of a predicate is that the prover is in possession of an anonymous credential, and they can selectively disclose certain attributes while hiding the other attributes.

The information that is available to the user is:

  • BBS +signature (A, B, e, s)

  • Extra input

    • (D, I) : Attribute predicate, describes what attributes will be disclosed. If D[j] == 1, I[j] = attrs[j] = aj, else I[j] = null

Proving Algorithm

The selective disclosure proof can be generated in the following manner:

  • _A/B' = A'^(-e) · HRand^r2

  • g1 · MulAll(hi^ai_reveal) = (B')^r3 · HRand^(-s') · HSk^(-sk) ·MulAll(hi^(-ai_hidden)), where hi stands for HAttrs[i]

The proof can be generated as follows:

r_ai : for i belongs to _D(attributes not disclosed), means D[i]==0
r_e : random from Zp
r_r2 : random from Zp
r_r3 : random from Zp
r_s' : random from Zp
r_sk : random from Zp
E : E = HSk^r_sk
t1 : t1 = A'^r_e · HRand^r_r2
t2 : t2 = (B')^r_r3 · HRand^r_s' · E^(-1) · MulAll(hi^r_ai)
c' : c' = H(A', _A, B', nym, t1, t2, g1, HRand, h1, ... , hL, w)
nonce : nonce, with τ bit length, randomly generated again
c : c = H(nonce, c', (D, I))
s_sk : s_sk = r_sk + c · sk
s_ai : s_ai = r_ai - c · ai, for i belongs to _D(attributes not disclosed)
s_e : s_e = r_e - c · e
s_r2 : s_r2 = r_r2 + c · r2
s_r3 : s_r3 = r_r3 + c · r3
s_s' : s_s' = r_s' - c · s'
π : {c, s_sk, {s_ai}, s_e, s_r2, s_r3, s_s', nonce}, i belong to _D

Here is the reference data structure for the zero knowledge proof:

type Proof struct {
    APrime             G1Point  // randomized credential signature values
    ABar               G1Point  // randomized credential signature values
    BPrime             G1Point  // randomized credential signature values

    /* challenge in sigma-protocol */
    ProofC             BigNum
    /* response in sigma-protocol */
    ProofSSk           BigNum
    ProofSE            BigNum
    ProofSR2           BigNum
    ProofSR3           BigNum
    ProofSSPrime       BigNum
    ProofSAttrs        []BigNum

    Nonce              BigNum   // nonce used to avoid replay attack
    Nym                G1Point  
}

Verification

The verifier has the following input information available:

The verification algorithm proceeds as in the following manner:

  1. Check if A' != 1 in G1; if false, return false.

    • the i above, first MulAll( ) belongs to _D, where D[i]==0(false)

    • the i above, second MulAll( ) belongs to D, where D[i]==1(true)

  2. Check if c == c' : if false, return false. Otherwise return true.

In this subsection, we will look at an example of the non-interactive proof of knowledge protocol which proves that the public key is generated as specified in the BBS + signature scheme. That is, π=PoK{x:w=g2x && _g2=_g1x}\pi = PoK \{ x : w = {g_2}^x \ \&\& \ \_g_2 = \_{g_1}^x\}π=PoK{x:w=g2​x && _g2​=_g1​x}. This means the prover proves the knowledge of xxx such that g2x=w{g_2}^x = wg2​x=w and _g2=_g1x\_g_2 = \_{g_1}^x_g2​=_g1​x. It is assumed that w,g2,_g1,_g2w, g_2, \_g_1, \_g_2w,g2​,_g1​,_g2​ are all public.

The protocol that we provide is a standard sigma protocol. It involves three steps, which are commit, challenge, and response. Sigma protocol is an interactive protocol and can be modified to be a non-interactive zero knowledge proof by using the well-known . The proof π={C,S}.\pi = \{ C, S\}.π={C,S}.

Select a random element xxx from ZpZ_pZp​, and compute w=g2xw = {g_2}^xw=g2​x

Select a random element _g1\_g_1_g1​from G1G_1G1​, and compute _g2=_g1x\_g_2 = \_{g_1}^x_g2​=_g1​x

Generate non-interactive proof of knowledge π=PoK{x:w=g2x && _g1x}=(C,S)\pi = PoK\{ x: w = {g_2}^x \ \&\& \ {\_g_1}^x \} = (C, S)π=PoK{x:w=g2​x && _g1​x}=(C,S) Here,

r : A random element rrr from ZpZ_pZp​

t1 : Computed as t1=g2rt_1 = {g_2}^rt1​=g2​r

t2 : Computed as t2=_g1rt_2 = \_{g_1}^rt2​=_g1​r

C : C=H(t1∣∣t2∣∣g2∣∣_g1∣∣w∣∣_g2)C = H(t_1 || t_2 || g_2 || \_g_1||w||\_g_2)C=H(t1​∣∣t2​∣∣g2​∣∣_g1​∣∣w∣∣_g2​)

s : S=(r+C∗x) mod pS = (r + C *x) \bmod pS=(r+C∗x)modp

4. Select an array of elements from G1G_1G1​ from AttributeNames. Next, calculate HAttrs[i] = random(G1) for each attribute in AttributeNames

5. Select two random elements HRand And HSk from G1G_1G1​ 6. The issuer's public key is set to ipk = (w, _g1, _g2, π, HAttrs, AttributeNames, HRand, HSk), and the private key is set to isk = x 7. Return isk and ipk

The issuer sends a random to the user

The credential request CredRequest contains a commitment NymN_{ym}Nym​ to user's secret key which is of the form HSksk{H_{Sk}}^{sk}HSk​sk and a zk-PoK of the NymN_{ym}Nym​

Select a random element sk from ZpZ_pZp​ as the user's master secret key

Calculate Nym=HSkskN_{ym} = {H_{Sk}}^{sk}Nym​=HSk​sk , which represents the commitment to the user's master secret

Generate the zero knowledge proof π=PoK{sk:Nym=HSksk}=(C,S)\pi = PoK \{ sk : N_{ym} = {H_{Sk}}^{sk} \} = (C, S)π=PoK{sk:Nym​=HSk​sk}=(C,S) in the following manner-

Select a random element sksksk from ZpZ_pZp​ which acts as the user's master secret

Calculate t1=HSkrt_1 = {H_{Sk}}^rt1​=HSk​r

Compute the challenge C=H(t1∣∣HSk∣∣Nym∣∣nonce)C = H(t_1 || H_{Sk}||N_{ym}||nonce)C=H(t1​∣∣HSk​∣∣Nym​∣∣nonce)

Compute the response S=(r+C∗sk) mod pS = (r+C*sk) \bmod pS=(r+C∗sk)modp

After receiving the credential request from the user, the issuer verifies π=(C,S)\pi = (C, S)π=(C,S) and generates credentials for the user. The credential is generated using the issuer's private key iski_{sk}isk​ as follows:

Select two random elements e,se, se,s from ZpZ_pZp​

Return the credential (A,B,e,s,Attrs)(A, B, e, s, Attrs)(A,B,e,s,Attrs)

User's secret key sksksk and its commitment NymN_{ym}Nym​

Attribute values attrs=(a1,... ,aL)attrs = (a_1, ...\ , a_L)attrs=(a1​,... ,aL​)

Randomize A : Select a random element r1r_1r1​ from Zp∗{Z_p}^*Zp​∗, and compute A′=Ar1A' = A^{r_1}A′=Ar1​

Calculate _A=A′(−e) ⋅Br1, r3=1/r1\_A = A'^{(−e)} \ · B^{r_1},\ r_3 = 1/r_1_A=A′(−e) ⋅Br1​, r3​=1/r1​

Select an element r2r_2r2​ from ZpZ_pZp​

Calculate B′=Br1⋅HRand−r2B' = B^{r_1} · {H_{Rand}}^{-r_2}B′=Br1​⋅HRand​−r2​ , s′=s−r2⋅r3s' = s - r_2 · r_3s′=s−r2​⋅r3​

Generate zero knowledge proof π=PoK{(sk,ai_hidden,e,r2,r3,s′)}\pi = PoK\{ (s_k, {a_i}\_{hidden}, e, r_2, r_3, s') \}π=PoK{(sk​,ai​_hidden,e,r2​,r3​,s′)} such that-

The output is (A′,_A,d,nym,π)(A', \_A, d, n_{ym}, \pi)(A′,_A,d,nym​,π) where π={c,ssk,sai,se,sr2,sr3,ss′,nonce}\pi = \{c, s_{sk}, s_{ai}, s_e, s_{r_2}, s_{r_3}, {s_s}', nonce\}π={c,ssk​,sai​,se​,sr2​​,sr3​​,ss​′,nonce}

(A′,_A,B′,nym,π)(A', \_A, B', n_{ym}, \pi)(A′,_A,B′,nym​,π) : from the signer

{c,ssk,sai,se,sr2,sr3,ss′,nonce}\{c, s_{sk}, {s_{a_i}}, s_e, s_{r_2}, s_{r_3}, {s_s}', nonce\}{c,ssk​,sai​​,se​,sr2​​,sr3​​,ss​′,nonce} : obtained by parsing π\piπ

Check if e(A', w) == e(_A, g2); if false, return false. This is zk−PoKz_k-PoKzk​−PoK for A.

Parse π\piπ : {c, s_sk, {s_ai}, s_e, s_r2, s_r3, s_s', nonce} <- π; if failed, return false.

~ t1t_1t1​ : ~t1 = A'^s_e · HRand^s_r2 · (_A/B')^(-c) . This is zk−PoKz_k-PoKzk​−PoK for e, r2.

~ t2t_2t2​ : (B')^s_r3 · HRand^s_s' · HSk^(-s_sk) · MulAll(hi^(-s_ai)) · (g1·MulAll(hi^ai))^(-c)

This is Zk−PoKZ_k - PoKZk​−PoK for r3, s', gsk, ai of _D.

c′c'c′ : c' = H(nonce, H(A', _A, B', nym, ~t1, ~t2, g1, HRand, h1, ... , hL, w), (D, I))

Fiat-Shamir heuristic
nonce