polygonID SDK部分代码分析

回到polygonID SDK project,在项目中,理论性的iden3和polygonID算法,在实际代码中,如何连接呢?本文接续上文 iden3和polygonID原理应用和实战,讲述具体代码,如何实现的。

算法1:生成最终的proof

从技术角度来看,一个身份包括三棵树:claims tree,revocation tree,roots of roots tree。

代码实现:

https://github.com/0xPolygonID/polygonid-flutter-sdk/blob/a552fc6b2430353b05c0c2ef3c17567704012a90/lib/iden3comm/domain/use_cases/generate_iden3comm_proof_use_case.dart

  1. 为生成proof,准备入参:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // Prepare atomic query inputs 准备计算查询的入参
    Uint8List res = await _proofRepository
    .calculateAtomicQueryInputs(
    id: didEntity.identifier, // 用户 DID
    profileNonce: param.profileNonce, // 用户个人资料随机数
    claimSubjectProfileNonce: param.claimSubjectProfileNonce, // 用户声明主题资料随机数
    authClaim: authClaim, // 用户授权声明
    incProof: incProof, // 如上图中 用户Claims Tree Root
    nonRevProof: nonRevProof, // 如上图中 用户Revocation Tree Root
    gistProof: gistProof, // 如上图中 用户Roots Tree Toot
    treeState: treeState, // 如上图中 用户Identity State
    challenge: param.challenge, // 挑战,由Issuer生成,作为生成proof的一部分
    signature: signature, // 用户针对challenge的签名
    claim: param.credential, // 用户证书,其中包含的PII Data
    proofScopeRequest: param.request.toJson(),
    circuitId: param.request.circuitId, // 使用的电路ID
    config: config,
    )

其中部分参数的示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
"genesisDID": "did:iden3:tT2t3b685r2dKsjo4MioyKeceFT4mQEYfDd69EY5Y",
"profileNonce": "0",
"authClaim": [
"304427537360709784173770334266246861770",
"0",
"17640206035128972995519606214765283372613874593503528180869261482403155458945",
"20634138280259599560273310290025659992320584624461316485434108770067472477956",
"15930428023331155902",
"0",
"0",
"0"
],
"authClaimIncMtp": {
"existence": true,
"siblings": []
},
"authClaimNonRevMtp": {
"existence": false,
"siblings": []
},
"treeState": {
"state": "18656147546666944484453899241916469544090258810192803949522794490493271005313",
"claimsRoot": "9763429684850732628215303952870004997159843236039795272605841029866455670219",
"revocationRoot": "0",
"rootOfRoots": "0"
},
"gistProof": {
"root": "4924303677736085224554833340748086265406229626627819375177261957522622163007",
"proof": {
"existence": false,
"siblings": [],
"node_aux": {
"key": "24846663430375341177084327381366271031641225773947711007341346118923321345",
"value": "6317996369756476782464660619835940615734517981889733696047139451453239145426"
}
}
},
"signature": "fccc15d7aed2bf4f5d7dbe55c81087970344d13e5d9f348e61965ac364f41d29b366b52bc0820c603877352054833da083f5595c29c881ccd8ee47aa639aa103",
"challenge": "10"
}
  1. 生成证明:
    1
    2
    3
    4
    5
    6
    // Prove 生成最终证明,其中的步骤实际是在调用iden3的类库
    return _proveUseCase
    .execute(param: ProveParam(atomicQueryInputs, param.circuitData))
    .then((proof) {
    _stacktraceManager.addTrace("[GenerateIden3commProofUseCase] proof");
    logger().i("[GenerateProofUseCase] proof: $proof");

2.1 生成证明的具体过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Future<ZKProofEntity> execute({required ProveParam param}) async {  
try {
// Calculate witness 计算见证
Uint8List wtnsBytes = await _proofRepository.calculateWitness(
param.circuitData,
param.inputs,
);
// Generate proof 生成证明
ZKProofEntity zkProofEntity = await _proofRepository.prove(
param.circuitData,
wtnsBytes,
);
_stacktraceManager.addTrace("[ProveUseCase] proof");
logger().i("[ProveUseCase] proof: $zkProofEntity");
return zkProofEntity;
}
}

算法2:稀疏默克尔树

代码接口如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
abstract class SMTRepository {  
Future<void> addLeaf(
{required NodeEntity leaf,
required TreeType type,
required String did,
required String privateKey});

Future<NodeEntity> getNode(
{required HashEntity hash,
required TreeType type,
required String did,
required String privateKey});

Future<void> addNode(
{required HashEntity hash,
required NodeEntity node,
required TreeType type,
required String did,
required String privateKey});

Future<HashEntity> getRoot(
{required TreeType type,
required String did,
required String privateKey});

Future<void> setRoot(
{required HashEntity root,
required TreeType type,
required String did,
required String privateKey});

Future<MTProofEntity> generateProof({
required HashEntity key,
required TreeType type,
required String did,
required String privateKey,
});

Future<void> createSMT({
required int maxLevels,
required TreeType type,
required String did,
required String privateKey,
});

Future<void> removeSMT({
required TreeType type,
required String did,
required String privateKey,
});

Future<String> hashState({
required String claims,
required String revocation,
required String roots,
});

Future<Map<String, dynamic>> convertState({required TreeStateEntity state});
}

综上,polygonID 很好地在手机端(Flutter)和web端(JavaScript and TypeScript)实现了DID-Holder端SDK。