DID 学习日记 - PolygonID DID JS SDK

Flutter SDK 的相关库

如果不是已经对他们之间的调用关系非常熟悉了,平时去查询各种逻辑处理细节还是有点麻烦,需要在 Flutter 和 C++/Golang/Rust 代码里反复穿梭。

特别是 Golang 的工程还引用了很多 Iden3 的其他 Golang 库, 在确认电路输入参数生成细节时非常麻烦。

JS-SDK

正好最近在学习 Verifier 的逻辑时,发现https://github.com/0xPolygonID/js-sdk里除了有 Verifier 的逻辑,还几乎包含了 Holder 的全套逻辑。

而且很多代码就是在同一个类里实现的, 例如 zkproof 的 generate 和 verify, 可以对照比对逻辑,简直是一个宝藏。

相关学习建议如下:

Curcuit Codes

https://github.com/iden3/circuits

其中各种 main 函数在https://github.com/iden3/circuits/tree/master/circuits目录下

实现细节则在以下目录下

电路的文档在 https://docs.circom.io/

Create Identity (Holder)

  /**
   * Create Identity creates Auth BJJ credential,
   * Merkle trees for claims, revocations and root of roots,
   * adds auth BJJ credential to claims tree and generates mtp of inclusion
   * based on the resulting state it provides an identifier in DID form.
   *
   * @param {IdentityCreationOptions} opts - default is did:iden3:polygon:mumbai** with generated key.
   * @returns `Promise<{ did: DID; credential: W3CCredential }>` - returns did and Auth BJJ credential
   * @public
   */

  createIdentity(opts: IdentityCreationOptions): Promise<{ did: DID; credential: W3CCredential }>;

  /**
   * Creates profile based on genesis identifier
   *
   * @param {DID} did - identity to derive profile from
   * @param {number} nonce - unique integer number to generate a profile
   * @param {string} verifier - verifier identity/alias in a string from
   * @returns `Promise<DID>` - profile did
   */
  createProfile(did: DID, nonce: number, verifier: string): Promise<DID>;

https://github.com/0xPolygonID/js-sdk/blob/main/src/identity/identity-wallet.ts

Create Credential (Holder)

  /**
   * Issues new credential from issuer according to the claim request
   *
   * @param {DID} issuerDID - issuer identity
   * @param {CredentialRequest} req - claim request
   * @returns `Promise<W3CCredential>` - returns created W3CCredential
   */
  issueCredential(issuerDID: DID, req: CredentialRequest, opts?: Options): Promise<W3CCredential>;

https://github.com/0xPolygonID/js-sdk/blob/main/src/identity/identity-wallet.ts

  /**
   * Creates a W3C verifiable Credential object
   *
   * @param {string} hostUrl - URL that will be used as a prefix for credential identifier
   * @param {DID} issuer - issuer identity
   * @param {CredentialRequest} request - specification of claim creation parameters
   * @param {JSONSchema} schema - JSON schema for W3C Verifiable Credential
   * @returns W3CCredential
   */
  createCredential(issuer: DID, request: CredentialRequest, schema: JSONSchema): W3CCredential;

https://github.com/0xPolygonID/js-sdk/blob/main/src/credentials/credential-wallet.ts

Handle SDR / ZKProof request (Holder)

  /**
   * Processes zero knowledge proof requests.
   *
   * @param senderIdentifier - The identifier of the sender.
   * @param requests - An array of zero knowledge proof requests.
   * @param from - The identifier of the sender.
   * @param proofService - The proof service.
   * @param opts - Additional options for processing the requests.
   * @returns A promise that resolves to an array of zero knowledge proof responses.
   */
  export const processZeroKnowledgeProofRequests = async (
    senderIdentifier: DID,
    requests: ZeroKnowledgeProofRequest[] | undefined,
    from: DID | undefined,
    proofService: IProofService,
    opts: {
      mediaType?: MediaType;
      packerOptions?: JWSPackerParams;
      supportedCircuits: CircuitId[];
      ethSigner?: Signer;
      challenge?: bigint;
    }
  ): Promise<ZeroKnowledgeProofResponse[]>

https://github.com/0xPolygonID/js-sdk/blob/main/src/iden3comm/handlers/common.ts

此函数可以展开为以下逻辑

Generate Circuit Inputs (Holder)
  /**
   * generates auth inputs
   *
   * @param {Uint8Array} hash - challenge that will be signed
   * @param {DID} did - identity that will generate a proof
   * @param {Number} profileNonce - identity that will generate a proof
   * @param {CircuitId} circuitId - circuit id for authentication
   * @returns `Promise<Uint8Array>`
   */
  generateAuthV2Inputs(hash: Uint8Array, did: DID, circuitId: CircuitId): Promise<Uint8Array>;

https://github.com/0xPolygonID/js-sdk/blob/main/src/proof/proof-service.ts

  private credentialAtomicQueryMTPV2PrepareInputs = async ({
    preparedCredential,
    identifier,
    proofReq,
    params,
    circuitQueries
  }: InputContext): Promise<Uint8Array>

https://github.com/0xPolygonID/js-sdk/blob/main/src/proof/provers/inputs-generator.ts

  private credentialAtomicQuerySigV2PrepareInputs = async ({
    preparedCredential,
    identifier,
    proofReq,
    params,
    circuitQueries
  }: InputContext): Promise<Uint8Array>

https://github.com/0xPolygonID/js-sdk/blob/main/src/proof/provers/inputs-generator.ts

Generate & Verify Zkproof (Holder / Verifier)
/**
 * ZKProver is responsible for proof generation and verification
 *
 * @public
 * @interface ZKProver
 */
export interface IZKProver {
  /**
   * generates zero knowledge proof
   *
   * @param {Uint8Array} inputs - inputs that will be used for proof generation
   * @param {string} circuitId - circuit id for proof generation
   * @returns `Promise<ZKProof>`
   */
  generate(inputs: Uint8Array, circuitId: string): Promise<ZKProof>;
  /**
   * verifies zero knowledge proof
   *
   * @param {ZKProof} zkp - zero knowledge proof that will be verified
   * @param {string} circuitId - circuit id for proof verification
   * @returns `Promise<boolean>`
   */
  verify(zkp: ZKProof, circuitId: string): Promise<boolean>;
}

https://github.com/0xPolygonID/js-sdk/blob/main/src/proof/provers/prover.ts

Read Public Signals from Zkproof (Verifier)

  /**
   * PubSignalsUnmarshal unmarshal auth.circom public inputs to AuthPubSignals
   *
   * @param {Uint8Array} data
   * @returns AuthV2PubSignals
   */
  pubSignalsUnmarshal(data: Uint8Array): AuthV2PubSignal

  /**
   * PubSignalsUnmarshal unmarshal credentialAtomicQueryMTP.circom public signals array to AtomicQueryMTPPubSignals
   *
   * @param {Uint8Array} data
   * @returns AtomicQueryMTPV2PubSignals
   */
  pubSignalsUnmarshal(data: Uint8Array): AtomicQueryMTPV2PubSignals

  /**
   *
   * PubSignalsUnmarshal unmarshal credentialAtomicQuerySig.circom public signals array to AtomicQuerySugPubSignals
   * @param {Uint8Array} data
   * @returns AtomicQuerySigV2PubSignals
   */
  pubSignalsUnmarshal(data: Uint8Array): AtomicQuerySigV2PubSignals

https://github.com/0xPolygonID/js-sdk/tree/main/src/circuits

Verify Public Signals (Verifier)

  private authV2Verify = async ({
    sender,
    challenge,
    pubSignals,
    opts
  }: VerifyContext): Promise<BaseConfig>

  private credentialAtomicQueryMTPV2Verify = async ({
    query,
    verifiablePresentation,
    sender,
    challenge,
    pubSignals,
    opts
  }: VerifyContext): Promise<BaseConfig>

  private credentialAtomicQuerySigV2Verify = async ({
    query,
    verifiablePresentation,
    sender,
    challenge,
    pubSignals,
    opts
  }: VerifyContext): Promise<BaseConfig>

https://github.com/0xPolygonID/js-sdk/blob/main/src/proof/verifiers/pub-signals-verifier.ts