Generate sig / mtp proofs
Credential is issued to the user with a BJJ signature proof, so we can generate a zkp that we have such credentials!!
async function generateProofs() {
console.log("=============== transit state ===============");
const dataStorage = initDataStorage();
const credentialWallet = await initCredentialWallet(dataStorage);
const identityWallet = await initIdentityWallet(
dataStorage,
credentialWallet
);
const proofService = await initProofService(identityWallet,credentialWallet,dataStorage.states)
const { did:userDID, credential:authBJJCredentialUser } =
await wallet.createIdentity({
method: DidMethod.Iden3,
blockchain: Blockchain.Polygon,
networkId: NetworkId.Mumbai,
seed: seedPhraseIssuer,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
baseUrl: "https://rhs-staging.polygonid.me"
}
});
console.log("=============== user did ===============");
console.log(userDID.string());
const { did:issuerDID, credential:issuerAuthBJJCredential } =
await wallet.createIdentity({
method: DidMethod.Iden3,
blockchain: Blockchain.Polygon,
networkId: NetworkId.Mumbai,
seed: seedPhraseIssuer,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
baseUrl: "https://rhs-staging.polygonid.me"
}
});
const credentialRequest: CredentialRequest = {
credentialSchema:
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json",
type: "KYCAgeCredential",
credentialSubject: {
id: userDID.string(),
birthday: 19960424,
documentType: 99,
},
expiration: 12345678888,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
baseUrl: "https://rhs-staging.polygonid.me"
}
};
const credential = await identityWallet.issueCredential(issuerDID, credentialRequest);
await dataStorage.credential.saveCredential(credential)
console.log("================= generate Iden3SparseMerkleTreeProof =======================")
const res = await identityWallet.addCredentialsToMerkleTree([credential], issuerDID);
console.log("================= push states to rhs ===================")
await identityWallet.publishStateToRHS(issuerDID, "https://rhs-staging.polygonid.me");
console.log("================= publish to blockchain ===================")
const ethSigner = new ethers.Wallet('',(dataStorage.states as EthStateStorage).provider);
const txId = await proofService.transitState(
issuerDID,
res.oldTreeState,
true,
dataStorage.states,
ethSigner
);
console.log(txId)
console.log("================= generate credentialAtomicSigV2 ===================")
const proofReqSig: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: CircuitId.AtomicQuerySigV2,
optional: false,
query: {
allowedIssuers: ['*'],
type: credentialRequest.type,
context:
'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld',
req: {
documentType: {
$eq: 99
}
}
}
};
// find and choose credential to generate proof
let credsToChooseForZKPReq = await credentialWallet.findByQuery(
proofReqSig.query
);
const { proof } = await proofService.generateProof(
proofReqSig,
userDID,
credsToChooseForZKPReq[0] // e.g. user chose first
);
const sigProofOk = await proofService.verifyProof(proof, CircuitId.AtomicQuerySigV2);
console.log("valid: ", sigProofOk);
console.log("================= generate credentialAtomicMTPV2 ===================")
const credsWithIden3MTPProof = await identityWallet.generateIden3SparseMerkleTreeProof(
issuerDID,
res.credentials,
txId
);
console.log(credsWithIden3MTPProof)
credentialWallet.saveAll(credsWithIden3MTPProof);
const proofReqMtp: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: CircuitId.AtomicQueryMTPV2,
optional: false,
query: {
allowedIssuers: ['*'],
type: credentialRequest.type,
context:
'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld',
req: {
documentType: {
$eq: 99
}
}
}
};
credsToChooseForZKPReq = await credentialWallet.findByQuery(
proofReqMtp.query
);
const { proof, pub_signals } = await proofService.generateProof(
proofReqMtp,
userDID,
credsToChooseForZKPReq[0]
);
console.log(JSON.stringify(proofMTP));
const mtpProofOk = await proofService.verifyProof({ proof, pub_signals }, CircuitId.AtomicQueryMTPV2);
console.log("valid: ", mtpProofOk);
}
init circuit storage with mtp / sig data
async function initProofService(
identityWallet:IIdentityWallet,
credentialWallet:ICredentialWallet,
stateStorage:IStateStorage
) :Promise<ProofService>{
const circuitStorage = new CircuitStorage(new InMemoryDataSource<CircuitData>());
const loader = new FSKeyLoader(path.join(__dirname, '../testdata'));
await circuitStorage.saveCircuitData(CircuitId.AtomicQuerySigV2, {
circuitId: CircuitId.AtomicQuerySigV2,
wasm: await loader.load(`${CircuitId.AtomicQuerySigV2.toString()}/circuit.wasm`),
provingKey: await loader.load(`${CircuitId.AtomicQuerySigV2.toString()}/circuit_final.zkey`),
verificationKey: await loader.load(
`${CircuitId.AtomicQuerySigV2.toString()}/verification_key.json`
)
});
await circuitStorage.saveCircuitData(CircuitId.StateTransition, {
circuitId: CircuitId.StateTransition,
wasm: await loader.load(`${CircuitId.StateTransition.toString()}/circuit.wasm`),
provingKey: await loader.load(`${CircuitId.StateTransition.toString()}/circuit_final.zkey`),
verificationKey: await loader.load(
`${CircuitId.StateTransition.toString()}/verification_key.json`
)
});
await circuitStorage.saveCircuitData(CircuitId.AtomicQueryMTPV2, {
circuitId: CircuitId.AtomicQueryMTPV2,
wasm: await loader.load(`${CircuitId.AtomicQueryMTPV2.toString()}/circuit.wasm`),
provingKey: await loader.load(`${CircuitId.AtomicQueryMTPV2.toString()}/circuit_final.zkey`),
verificationKey: await loader.load(
`${CircuitId.AtomicQueryMTPV2.toString()}/verification_key.json`
)
});
return new ProofService(identityWallet, credentialWallet, circuitStorage, stateStorage);
}
signature proof request
console.log(
"================= generate credentialAtomicSigV2 ==================="
);
const proofReqSig: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: CircuitId.AtomicQuerySigV2,
optional: false,
query: {
allowedIssuers: ["*"],
type: credentialRequest.type,
context:
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
req: {
documentType: {
$eq: 99,
},
},
},
};
// find and choose credential to generate proof
let credsToChooseForZKPReq = await credentialWallet.findByQuery(
proofReqSig.query
);
const { proof } = await proofService.generateProof(
proofReqSig,
userDID,
credsToChooseForZKPReq[0] // e.g. user chose first
);
💡 ZeroKnowledgeProofRequest is a protocol proof request, in this case for credential with a BJJ signature proof
mtp proof request
console.log(
"================= generate credentialAtomicSigV2 ==================="
);
const proofReqMtp: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: CircuitId.AtomicQueryMTPV2,
optional: false,
query: {
allowedIssuers: ["*"],
type: credentialRequest.type,
context:
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
req: {
documentType: {
$eq: 99,
},
},
},
};
credsToChooseForZKPReq = await credentialWallet.findByQuery(
proofReqMtp.query
);
const { proof, pub_signals } = await proofService.generateProof(
proofReqMtp,
userDID,
credsToChooseForZKPReq[0]
);
console.log(JSON.stringify(proof));
const mtpProofOk = await proofService.verifyProof({ proof, pub_signals }, CircuitId.AtomicQueryMTPV2);
console.log("valid: ", mtpProofOk);
💡 ZeroKnowledgeProofRequest is a protocol proof request, in this case for credential with a Iden3SparseMerkleTreeProof