arrow-left

All pages
gitbookPowered by GitBook
1 of 5

Loading...

Loading...

Loading...

Loading...

Loading...

Data Holder

The Data Holder should follow four steps to integrate with zkPass:

  1. Retrieving the DVR from the Proof Verifier

  2. Retrieving the user data from the Data Issuer

hashtag
Sample Implementation

Sample codes for the Data Holder implementation follow. Each step is explained in detail in the subsections. The code is also available on the zkpass-sdk repo, as shown here:

Generating the ZkPass Proof from the two inputs: DVR and user data
Sending the ZkPass Proof to the Proof Verifier for the proof verification

4. Verifying the Proof

Sending the ZkpassProof object to the Proof Verifier for verification

From Data Holder perspective, no integration with the Dvr module client SDK library is needed for this step.

Once the Data Holder receives the Zkpass Proof from the zkPass Service, it will pass it along to the Proof Verifier for verification. The Proof Verifier provides a for this purpose.

The zkPass call sequence diagram, specifically steps 10–12, corresponds to the proof verification process.

1. Retrieving the DVR

Retrieving the Data Verification Request (DVR) from the Proof Verifier

From Data Holder perspective, no integration with the Dvr module client SDK library is needed for this step.

The Data Holder first gets the DVR by calling the provided by the Proof Verifier.

The zkPass call sequence diagram, specifically steps 1–3, corresponds to the DVR retrieval process.

REST API
REST API

2. Retrieving the User Data

Retrieving the User Data from the Data Issuer

From Data Holder perspective, no integration with the Dvr module client SDK library is needed for this step.

The User Data retrieves the user data that is needed by the DVR by calling the provided by the Data Issuer.

The zkPass call sequence diagram, specifically steps 4–6, corresponds to the User Data retrieval process.

REST API

3. Generating the Proof

Calling zkPass Service's generate_zkpass_proof REST API to create the ZkPass Proof

To generate the ZkPass Proof, the Data Holder needs to use the zkpass-client SDK library. The following section illustrates how the coding is done.

hashtag
Dvr Module Client Integration

The zkPass call sequence diagram, specifically steps 7–9, corresponds to the proof generation process.

The Data Holder generates the proof by using the Dvr module client SDK library, as shown here.

// Step 1: Instantiate DvrModuleClient
const dvrModuleClient = new DvrModuleClient({
      baseUrl: SERVICE_URL,
      apiKey: API_KEY,
      secretApiKey: API_SECRET,
    });

// Step 2: Call the DVR module client's callDvrGenerateZkPassProof
const zkPassProof = dvrModuleClient.callDvrGenerateZkPassProof(
      JSON.stringify(userDataToken),
      dvrToken
    );
https://github.com/gl-zkPass/zkpass-sdk/blob/main/rust/zkpass-demo/src/data_holder.rs
/*
 * data_holder.rs
 * Simulating the Data Holder process for the zkPass Demo
 *
 * ---
 * References:
 *   https://docs.ssi.id/zkpass/zkpass-developers-guide/privacy-apps/dvr/dvr-client-roles/data-holder
 * ---
 * Copyright (c) 2024 PT Darta Media Indonesia. All rights reserved.
 */
use crate::{
    data_issuer::DataIssuer,
    proof_verifier::ProofVerifier,
    lib_loader::generate_zkpass_proof,
};
use client_utils::interface::PrivacyAppCredentialsFfi;
use std::{ collections::HashMap, time::Instant, ffi::CString };
use tracing::info;
use zkpass_query_types::OutputReader;

pub struct DataHolder;

impl DataHolder {
    ///
    /// Starts the Data Holder process.
    ///
    pub async fn start(&self, zkvm: &str, data_files: HashMap<String, String>, dvr_file: &str) {
        //
        //  Get the user data from the data issuer
        //
        let data_issuer = DataIssuer;
        let user_data_tokens_map = data_issuer.get_user_data_tokens(data_files);
        let user_data_tags_list: Vec<&String> = user_data_tokens_map.keys().collect();
        let user_data_tokens = serde_json::to_string(&user_data_tokens_map).unwrap();

        //
        //  Get the dvr from the verifier
        //
        let mut proof_verifier = ProofVerifier::default();
        let dvr_token = proof_verifier.get_dvr_token(zkvm, dvr_file, user_data_tags_list);

        let zkpass_service_url = std::env
            ::var("ZKPASS_URL")
            .unwrap_or("https://staging-zkpass.ssi.id".to_string());
        info!("service_url={}", zkpass_service_url);
        println!("\n#### starting zkpass proof generation...");
        let start = Instant::now();

        //
        //  Data Holder's integration points with the zkpass-client SDK library
        //

        //
        // Step 1: Call the dvr client's generate_zk_pass_proof
        //         to get the zkpass_proof_token.
        //
        let credentials = self.generate_credential();
        let zkpass_proof_token = unsafe {
            generate_zkpass_proof(credentials, user_data_tokens, dvr_token)
        };

        let duration = start.elapsed();
        println!("#### generation completed [time={:?}]", duration);

        //
        //  Step 2: Send the zkpass_proof_token to the Proof Verifier
        //          to get the proof verified and retrieve the query result.
        //
        let query_result = proof_verifier.verify_zkpass_proof(zkvm, &zkpass_proof_token).await;

        println!("json-result={}", OutputReader::pretty_print(&query_result));
        let output_reader = OutputReader::from_json(&query_result).unwrap();
        println!(">> output list:");
        for entry in output_reader.enumerate() {
            println!("key={}, value={:?}", entry.key, entry.val);
        }
        println!("<< end of list");

        let val = output_reader.find_bool("result").unwrap();
        println!("the query result is {}", val);
    }

    ///
    /// Generates the privacy app credentials.
    ///
    fn generate_credential(&self) -> PrivacyAppCredentialsFfi {
        let base_url = std::env
            ::var("ZKPASS_URL")
            .unwrap_or("https://staging-zkpass.ssi.id".to_string());
        let api_key = std::env::var("API_KEY").expect("API_KEY must be set");
        let secret_api_key = std::env::var("SECRET_API_KEY").expect("SECRET_API_KEY must be set");

        PrivacyAppCredentialsFfi {
            base_url: CString::new(base_url).unwrap().into_raw(),
            api_key: CString::new(api_key).unwrap().into_raw(),
            secret_api_key: CString::new(secret_api_key).unwrap().into_raw(),
            using_queue: true,
        }
    }
}