【Hyperledger Aries】ACA-PyでW3C準拠のLDP-VCの発行と検証を試す

SSI

こんにちは。GMOグローバルサイン・ホールディングスCTO室で分散型IDの研究をしている開発者の神沼@t_kanumaです。

以下の拙著に記載した通り、 Ariesは最新のAIP2.0からはW3CとDIF持ちの仕様群をインポートしており、相互運用性を高めています。その結果Indy LedgerやAnonCredsに依存しない形を取ることができ、W3C VC Data Model準拠の**LDP-VC(Linked Data Proof – Verifiable Credential)の発行と検証ができます。

Hyperledger Ariesを中心にSSIの技術的な動向について(2022年後半~2023年前半)

この記事では、下記のYouTube上のデモ動画などを参考に、ACA-Pyを用いたLDP-VCの発行と検証のやり方にフォーカスし、実際にそれを試してみます。

参考資料

  1. Indicio社
    1. Identity Insights – ACA-Py and JSON-LD Credentials(2022年12月公開)
    2. Indicio: How to use ACA-Py to issue and verify JSON-LD credentials(2022年11月公開)
  2. DIF: Timo and Karim from Animo Solutions (NL) present their work on Aries & JSON-LD (Code with Us) @IIW32(2021年4月公開)
  3. ACA-Py開発ドキュメント
    1. JSON-LD Credentials in ACA-Py
    2. How to Issue JSON-LD Credentials using Aca-py

No.1-1のIndicio社の動画の中で、なぜデモ動画をYouTubeにアップロードしたのか?という疑問に答えています。その理由について(私のような)”ACA-PyユーザーがJSON-LD Credentialsの発行検証機能を使ってくれない、そもそも機能があるということを認識してないから”と述べており、興味深いポイントです。

No.2は、2021年春のInternet Identity WorkshopでのAnimo社の開発者の方によるデモ動画です。

W3C VCのフォーマット4種

W3C VCのフォーマット(syntax + proof)には、W3C VC Impl GuideのProof Formats比較表から察するに、以下の4つがあると考えています。

  1. JSON + JWT (aka JWT-VC)
  2. JSON-LD + JWT
  3. JSON + LD-Proof
  4. JSON-LD + LD-Proof (aka LDP-VC)

LD-ProofとはProof部がW3C Verifiable Credential Data Integrity 1.0の仕様に則るものだと理解しています。LD-Proofという名前ですが、以下の通りJSON-LDの特性を損なわないProof生成方式というだけで、JSONに対して使うことも問題ないと考えます。(ただCanonicalization/正規化の部分がJSONに対しては行うことができないため、ここがどうなるかわかりません。エラーにするか、無視して進めらるかは実装依存でしょうか。)

2.5 Relationship to Linked Data
While this specification provides mechanisms to digitally sign Linked Data, the use of Linked Data is not necessary to gain some of the advantages provided by this specification.

ただNo.3(JSON + LD-Proof)の場合、LD-Proofが持ちJWTには無いProof SetsやProof Chain機能などを使わないのであれば既に普及していて相互運用性が高いJWTにする方が合理性があると感じます。またNo.2(JSON-LD + JWT)の場合、SEO対策できなくなるなど、Linked Dataの良さをフルに活かせなくなります。結果、多くのケースで合理性が高いNo.1または4に落ち着くのではないかと想定しています。

今回扱うのはNo.4です。

動作確認概要

前述の参考資料3-1によれば、ACA-PyはLD-Proofの生成に対し、W3C Linked Data Cryptographic Suite Registryの中から以下の2つのCryptograhic/Signature Suiteをサポートしています。今回はNo.1を試します。

  1. Ed25519Signature2018
  2. BBS+ Signature 2020(BbsBlsSignature2020)

Holderのプライバシー保護機能には5つの種別があると考えますが、参考資料3-1によればEd255519Signature2018はそれらの機能を1つも持たないタイプのCredentialです。

(なお、VC種別とそこに依存するHolderのプライバシー保護機能については、上記拙著にて参考資料群を記載しています。詳細はそちらをご参照ください。また、BbsBlsSignature2020については本記事の最後に少々補足します。)

仕様セット

ToIP Technical Stackのレイヤーごとに今回使っている仕様について、これまでの拙著群で使っていた仕様セットと比較します。

ToIP Tech Stack これまで (AIP1.0主体) 今回 (Layer3はAIP2.0主体)
Layer 1 did:sov did:sov
Layer 2 DIDComm v1, Connection Protocol, Aries独自のdid:peer相当のPairwise DID 左記と同様
Layer 3 Indy AnonCreds, Issue Credential Protocol 1.0, Present Proof Protocol 1.0 JSON-LD Credentials, Issue Credential Protocol 2.0, Present Proof Protocol 2.0 with DIF Presentation Exchange 1.0

以下、ポイントです。

  • Layer 3が今回の試行における重要な仕様です。
  • Layer 2の理想は、メッセージ交換にDIDComm v2、Pairwise DIDにdid:peer、コネクション生成にDID Exchange Protocol in Out-of-Band Protocolを使うのが理想と思いますが、ACA-PyがAIP2.0のフル実装に向けた途中であるためまだ叶いません。AIP1.0のままになっています。
  • LDP-VCに対する、W3C VC Status List 2021に基づく失効機能については、参考資料1-2の57:00~で述べられている通りACA-Pyではまだ実装されておらず、対象外としています。

環境

以下の図のように、ローカルPCのDocker上に各要素をコンテナとして環境を構築します。
Issuer/Verifier/Holderそれぞれにおいて、筆者がControllerの代わりにSwagger UIからAdmin APIをコールします。

OSSバージョン

  • ACA-Py: 0.8.1
  • von-network: 1.7.2

VC発行準備

Indy AnonCredsと異なりJSON-LD CredentialsはHyperledger Indyの利用が必須ではありません。 すなわち、AnonCredsを発行するために必要なIssuerのPublic DID、Schema、およびCredential DefinitionをIndy Ledger上に作る必要がない、もしくは存在自体必要ないということです。それぞれについて、JSON-LDではどうするのかを述べます。

IssuerのPubilc DID

IssuerがVCに署名するため、つまりVC内のProofプロパティ作成のために、今回はPublic DIDにdid:sovを利用します。そのため、Indy Ledger上にそれを作成します。

SchemaとValidation

1. JSON-LDの妥当性

JSON-LDの妥当性に対するチェック仕様は標準化されておらず、実装に依存すると考えます。(例えば、Contextに定義されているプロパティは必須か、Contextに定義されていないプロパティは存在しても良いか、プロパティ値のデータ型、Non-Nullなど)

参考資料3-iの以下の記述の通り、ACA-Pyの実装では”Contextに定義されていないプロパティの存在は許容されない”ことはチェックするようです。

It is required that every property key in the document can be mapped to an IRI. This means the property key must either be an IRI by default, or have the shorthand property mapped in the @context of the document. If you have properties that are not mapped to IRIs, the Issue Credential API will throw the following error:

実際のACA-Pyの実装内容についての動作確認結果は後述します。

2. Presentation Definition

AIP2.0では、Holder-Verifier間でVC要求定義にDIF Presentation Exchange v1を使います。スキーマ周りについて2つのバリデーション種別があります。

  • Schema URI(presentation_definition.input_descriptors.schema)
    Verifierは、Input Descriptor内のschemaプロパティに、Holderに要求するSchema URIを定義します。Holderは、schemaのURI値が一致するVCを抽出する仕様です。ただ、このURIが何を指すのかは仕様上明記されておらず曖昧です。例えば、vc.credentialSchemaやJSON-LDのcontext+typeがありますが、ここ実装依存だと考えます。加えてVerifierがURIの一致だけでなく中身のデータ構造の妥当性(e.g. 不要なプロパティが無いこと、必須プロパティがあること)までチェックするのかも実装依存です。(さらにURIがJSON-LDを指す場合、前述の通りバリデーション仕様、すなわちどこまでチェックするのかも実装依存になるため、話がややこしいです。)
    実際のACA-Pyの実装内容についての動作確認結果は後述します。

  • Constraints(presentation_definition.input_descriptors.constraints)
    VCのSchemaのバリデーション、
    ConstraintsではClaimの値の条件(e.g. データ型、値、パターンの一致)をJSON SchemaのSyntaxに則り定義します。
    実際のACA-Pyの実装内容についての動作確認結果は後述します。

  • 補足: v1とv2の違い
    前述のschema uriの曖昧さが要因かはわかりませんが、v2ではschemaプロパティが削除されています。代わりに、Claimの必須チェックのためにConstraints内にoptionalプロパティが設けられています。(不要なClaimが無いことのチェックをConstraintsですることはできないように見えますが、そもそもSelective Disclosureを使うことが当たり前、推奨されていることを考えると特段問題ないかと考察します。)

Credential Definition

Indy AnonCredsでは、Selective Disclosure(All or NothingではなくVC内の一部のClaimのみをVerifierに提示する機能)を実現するために、Issuerが各Claimごとの署名に使う公開鍵ペアを用意します。そして、公開鍵群をCredential DefinitionとしてIndy Ledgerに書き込みます。

一方、JSON-LD CredentialsではCredential Definition相当のモノは必要ありません。
シンプルにIssuerのPublic DIDでClaim群全体に対し署名をするためだと考えます。

Ed25519Signature2018での動作確認

ここから動作確認に入ります。いくつかポイントです。

  • Agent間のコネクション生成部分は割愛します。
  • JSON-LDには以下のcontextとtypeを使います。
    • context: https://w3id.org/citizenship/v1
    • type: Permanent Resident
  • 前述の通り、IssuerによるVC署名にはdid:sovを使います。
  • HolderによるVP署名にはdid: keyを使います。

以下、上記の内容で、VP発行とVP検証が正常にいくことを確認します。
VP検証時にVerifierからの要求内容を変化させた、その他のケースについても後述します。

VC発行

1. IssuerからHolderへのオファー
curl -X 'POST' \
  'http://localhost:8031/issue-credential-2.0/send-offer' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d ' {
  "connection_id": "2a476d18-f59b-49e7-8cf3-0745ad7f38f5",
  "credential_preview": {
    "@type": "issue-credential/2.0/credential-preview",
    "attributes": []
  },
  "filter": {
      "ld_proof": {
        "credential": {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://w3id.org/citizenship/v1"
          ],
          "type": [
            "VerifiableCredential",
            "PermanentResident"
          ],
          "issuer": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt",
          "issuanceDate": "2023-06-20T00:00:00Z",
          "credentialSubject": {
                 "type": [
                        "PermanentResident"
                 ],
               "givenName": "Taro",
               "familyName": "Yamada",
               "gender": "Male",
               "birthCountry": "Japan",
               "birthDate":"2020-01-01"
          }
        },
        "options": {
          "proofType": "Ed25519Signature2018"
        }
      }
  },
  "trace": true,
  "auto_issue": false,
  "auto_remove": false,
  "comment": "try json-ld vc"
}'

なお、Aries RFC 0453: Issue Credential Protocol V2によれば、DIDCommメッセージフォーマットにはDIFのCredential Manifest(dif/credential-manifest@v1.0)を利用できますが、ACA-Pyの実装としてはAries独自のフォーマット(aries/ld-proof-vc-detail@v1.0)を採用している模様です。

2. HolderからIssuerへの発行要求

HolderからIssuerへの発行要求では、DIDComm上でHolderのDIDをIssuerに送ることができます。これはオプションで、VCにClaimとしてcredentialSubject.idを付与したい場合、すなわちVerifierにVP提示の際にHolderがVCのSubjectと同一であることを証明したい場合に付与できます。
ただし、プライバシー保護について前述した通り、そこに強みを持つAnonCredsとは異なり、JSON-LD CredentialsはHolderのCorrelation(名寄せ)を防止するPrivate Holder Binding機能を持ちません。W3C Verifiable Credentials Data Model v1.1で言うところの、Identity Based Correlationが起きるリスクがあります。ここはユースケースに応じた対応が求められるところだと考えます。

また補足として、Claimとしてのidプロパティを付与しない場合、VCは同じくW3C Verifiable Credentials Data Model v1.1で言うところのBearer Credentialsになると考えます。

なお、 参考資料3-2によれば、このDIDに対し現在のACA-PyがサポートするMethodはMethod Identifierから公開鍵を導出可能なdid:keyのみです。今回はこのidプロパティを付与する形で進めます。

まず、HolderにてWallet内にdid:keyを作ります。

curl -X 'POST' 
  'http://localhost:8041/wallet/did/create' 
  -H 'accept: application/json' 
  -H 'Content-Type: application/json' 
  -d '{
  "method": "key",
  "options": {
    "key_type": "ed25519"
  }
}'

# レスポンスとして、以下を取得できます。
did:key:z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu

続いて、HolderのDIDを含めて、HolderからIssuerにVC発行を要求します。

curl -X 'POST' \
  'http://localhost:8041/issue-credential-2.0/records/0c74e52c-72ee-4c5f-b7d9-3cf99bd40fbf/send-request' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "holder_did": "did:key:z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu"
}'
3. IssuerからHolderへの発行と保管

次にIssuerからVCを発行します。

curl -X 'POST' \
  'http://localhost:8031/issue-credential-2.0/records/3769de81-b0da-4448-a535-34428a79bfec/issue' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "comment": "issue json-ld vc"
}'

次にHolderにて、発行されたVCをWalletに保管します。

curl -X 'POST' \
  'http://localhost:8041/issue-credential-2.0/records/0c74e52c-72ee-4c5f-b7d9-3cf99bd40fbf/store' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "credential_id": "json-ld-1"
}'

発行されたVCは以下の通りです。
W3Cのデータモデルに準拠していることが見てとれます。(署名値の形式はJWS Unencoded Payload Optionです。)

        "ld_proof": {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://w3id.org/citizenship/v1"
          ],
          "type": [
            "VerifiableCredential",
            "PermanentResident"
          ],
          "issuer": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt",
          "issuanceDate": "2023-06-20T00:00:00Z",
          "credentialSubject": {
            "type": [
              "PermanentResident"
            ],
            "givenName": "Taro",
            "familyName": "Yamada",
            "gender": "Male",
            "birthCountry": "Japan",
            "birthDate": "2020-01-01",
            "id": "did:key:z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu"
          },
          "proof": {
            "type": "Ed25519Signature2018",
            "verificationMethod": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt#key-1",
            "created": "2023-10-14T14:42:29.995498+00:00",
            "proofPurpose": "assertionMethod",
            "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0.._e-aoRplKQNviWD7maKK-h49FwlDhKhwcOyxZEIaKIg4zu7bSXmsrdXG3D2S7bypurijRxPEXaOm-qYitsxFAQ"
          }
        }

VP検証

Aries Present Proof Protocol2.0と、データフォーマットがDIF Presentation Exchange1.0に則るVP要求と検証の流れです。

1. VerifierからHolderへのVP要求(Presentation DefinitionとPresentation Request)

Presentation Definitionの内容をまとめます。(各プロパティの詳細はDIF Presentation Exchange1.0をご参照ください。)

  • ClaimのgivenNameの値がTaroであるVCを要求しています。
  • VCを発行したDIDが”did:sov :Vtw2qgmuMVy3rk2ipw7Vxt”であるVCを要求しています。VCの署名を基にそれが改竄されていないことの検証はACA-Pyの中で何をせずとも行われると考えますが、それとは別に”誰が発行したのか?”を検証したければこのように定義する必要があると考えます。
  • VPの署名を基にそれが改竄されていないことの検証はACA-Pyの中で何をせずとも行われると考えますが、それとは別に”VCのHolderとSubejctが一致しているか?”、つまりVPの署名者とCredentialSubject.idが一致することを検証したければ、is_holder.directiveをrequiredにする必要があると考えます。
curl -X 'POST' \
  'http://localhost:8021/present-proof-2.0/send-request' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "auto_verify": true,
  "comment": "test",
  "connection_id": "f05c7d90-a776-40b3-8f96-3dbb85f10826",
  "presentation_request": {
    "dif": {
      "options": {
        "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "domain": "4jt78h47fh47"
      },
      "presentation_definition": {
        "id": "f5fc87a5-053d-4c0d-9aaa-7589256981f0",
        "format": {
          "ldp_vp": {
            "proof_type": ["Ed25519Signature2018"]
          }
        },
        "input_descriptors": [
          {
            "id": "input_desc_1",
            "name": "Permanent Rsident",
            "schema": [
              {
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
              },
              {
                "uri": "https://w3id.org/citizenship#PermanentResident"
              }
            ],
            "constraints": {
              "fields": [
                {
                  "path": ["$.credentialSubject.givenName"],
                  "filter": {
                    "const": "Taro"
                  }
                },
                {
                  "path": ["$.issuer"],
                  "filter": {
                    "const": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt"
                  }
                }
              ],
              "is_holder": [
                {
                  "directive": "required",
                  "field_id": ["f5fc87a5-053d-4c0d-9aaa-7589256981f0"]
                }
              ]
            }
          }
        ]
      }
    }
  },
  "trace": true
}'
2. HolderからVerifierへのVP提示(Presentation Submission)

以下、Admin APIコールのリクエストとレスポンスです。

curl -X 'POST' \
  'http://localhost:8041/present-proof-2.0/records/2bddeb32-3761-44cc-9178-b2cb36476b9a/send-presentation' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "dif": {}
  }'

以下のレスポンから抜粋したpresプロパティです。これがVerifierにDIDCommメッセージとして送られます。Presentation Submissionプロパティを持ち、VPの形式になっていることがわかります。またVPに対する署名が前述のcredentialSubject.idのDIDで成されていることがわかります。

  "pres": {
    "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/2.0/presentation",
    "@id": "c63bd249-6603-4705-9691-c33072aaffcf",
    "formats": [
      {
        "attach_id": "dif",
        "format": "dif/presentation-exchange/submission@v1.0"
      }
    ],
    "presentations~attach": [
      {
        "@id": "dif",
        "mime-type": "application/json",
        "data": {
          "json": {
            "@context": [
              "https://www.w3.org/2018/credentials/v1"
            ],
            "type": [
              "VerifiablePresentation"
            ],
            "verifiableCredential": [
              {
                "@context": [
                  "https://www.w3.org/2018/credentials/v1",
                  "https://w3id.org/citizenship/v1"
                ],
                "type": [
                  "VerifiableCredential",
                  "PermanentResident"
                ],
                "issuer": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt",
                "issuanceDate": "2023-06-20T00:00:00Z",
                "credentialSubject": {
                  "type": [
                    "PermanentResident"
                  ],
                  "givenName": "Taro",
                  "familyName": "Yamada",
                  "gender": "Male",
                  "birthCountry": "Japan",
                  "birthDate": "2020-01-01",
                  "id": "did:key:z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu"
                },
                "proof": {
                  "type": "Ed25519Signature2018",
                  "proofPurpose": "assertionMethod",
                  "verificationMethod": "did:sov:Vtw2qgmuMVy3rk2ipw7Vxt#key-1",
                  "created": "2023-10-14T14:42:29.995498+00:00",
                  "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0.._e-aoRplKQNviWD7maKK-h49FwlDhKhwcOyxZEIaKIg4zu7bSXmsrdXG3D2S7bypurijRxPEXaOm-qYitsxFAQ"
                }
              }
            ],
            "presentation_submission": {
              "id": "907d0264-4be1-44b2-85d2-98bdec69e931",
              "definition_id": "f5fc87a5-053d-4c0d-9aaa-7589256981f0",
              "descriptor_map": [
                {
                  "id": "input_desc_1",
                  "format": "ldp_vc",
                  "path": "$.verifiableCredential[0]"
                }
              ]
            },
            "proof": {
              "type": "Ed25519Signature2018",
              "verificationMethod": "did:key:z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu#z6MkoQv3CoSgAXcLdiM4DYqfaAWjLTbAXL3nkifb1WaNkypu",
              "created": "2023-10-14T15:15:10.270937+00:00",
              "proofPurpose": "authentication",
              "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
              "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..ztc4MZRpivmFuiLgHNDz_oB83PpH6jj-F7-qcIMfYSbjzibdqFD8NXsZWtPHGSgcnp3ZgtAcm0-P9lGn7KA5Bg"
            }
          }
        }
      }
    ]
  }
3. 検証結果確認

詳細は省きますが、Verifier側で検証結果がTrueで完了していることを確認できました。

上記の正常ケース以外のケース実施結果

以下のケースについて、ACA-Pyの振る舞いを確認しました。

  1. Presentation Exchange v1のpresentation_definition.input_descriptors.schemaに対するACA-Py実装について
    • input_descriptors.schemaに対するLDのContext+Type URI(e.g. https://w3id.org/citizenship#PermanentResident) の有無による違い
      • 結論から言うと、Holderはここで定義したURIに一致するVCのみを提示の対象とする実装でした。
      • 前述の正常系ではschemaにPermanent ResidentのURIを記載していました。これを除いてVP要求を送ると、Holder側での抽出において、Context+Typeが異なる別のVCも提示対象になりました。
      • Holderがschema uriに合致するVCを持たないケースについて補足します。HolderはVP要求を受け取った後、Controller(Webhook)で対象があるかをAdmin API(Endpoint: present-proof-2.0/records/{presentation_exchange_id}/credentials)を呼んで確認します。ここで対象がない場合はPresentation Proof v2のシーケンスに則ればProblem Reportを送出しプロトコルを双方が完了するのが妥当だと考えます。
  2. Presentation Exchange v1のpresentation.definition.input_descriptors.constraintsに対するACA-Py実装について
    • 上記のPresentation DefinitionでgivenName=TaroのVCを要求しましたが、Taro以外の値で要求すると、発行済みのVCが提示対象にならないことを確認しました。(その際のHolderの取るべき処理は上記No.1で述べた通りです。)
    • VCにexpirationDateプロパティを設け、その値を過去の日時にしてVPの提示をしたところ、検証はTrueで終わりました。このことからexpirationDateでVCの妥当性を判断したい場合は、前述のgivenNameの様にInput DescriptorのConstraintを記述する必要があると言えます。(ACA-Pyの実装依存だと考える。)
  3. JSON-LDの妥当性に対するACA-Py実装について
    • Permanent Residentのコンテキストに無いプロパティを入れるとどうなるか? -> 発行オファーを出す時点でそれが理由でエラーになります。つまり、”VC発行準備”で前述した通り不要なプロパティを弾くチェックを実装しています。(Verifier側の対応までは見ていませんが、仮にそのようなVCが提示された場合同じように弾く振る舞いをすると推測します。)
    • Permanent Resident内のプロパティのデータ型を定義と異なるものにするとどうなるか? -> 発行から検証まで問題なく終わりました。JSON-LDのデータ型までは見ていない実装です。(このチェックはconstraintsで対応できます。)
  4. その他
    • credentialSubject.idプロパティを含めずにVCを発行するとどうなるか? -> VPに署名するDIDが指定されていないためだと思いますが、VP内にProofプロパティが作られずに提示が行われました。その際、そもそもVPのProofがないことから、Presentaion Definition内のis_holderプロパティの有無に関わらず、VPの検証はFalseで終わりました。
    • VCの@contextにhttps://w3id.org/citizenship を記載せず、typeにPermanent Residentを記載して発行しようとするとどうなるか? -> つまりはJSON + LD-Proofの形式で発行する際のACA-Pyの振る舞いですが、上記3のContext上になりClaimを入れた場合と同様でオファー時点でエラーになります。
    • (未検証ですが)1つのinput descriptorに対し、提示対象のVCが複数ある場合、HolderはVP提示のAPI Endpointの呼び出しのボディにて提示するVCを1つに決める記述をする必要があると考えます。(詳細は参考資料3-2をご参照ください。)

補足: BBS+ Signatureについて

BbsBlsSignature2020 – Newer, but supports zero knowledge proofs and selective disclosure.

Generally you should always use BbsBlsSignature2020 as it allows the holder to derive a new credential during the proving, meaning it doesn’t have to disclose all fields and doesn’t have to reveal the signature.

参考資料3-1の上記の記述の通り、BBS+ Signatureは、ACA-PyにおいてはSignature Blinding(ZKPを用いてCorrelationのキーになり得るIssuerのVC署名値を開示しない機能。Unlinkable Proofとも呼ばれると認識)とSelective Disclosure(All or NothingではなくVC内の一部のClaimのみをVerifierに提示する機能)の2つのプライバシー保護機能を実装していると記載があります。(なおBBS+ Signatureの仕様は日々進展している模様で、現在においてPrivate Holder Bindingの仕組みも策定済みであると認識しています。ただこのCryptographic Suitesではサポートされていないと言うことだと考えます)

Selective Disclosure機能においては、仕組みがIndy AnonCredsと異なります。参考資料2の動画のこの部分によれば、IssuerによるVC発行時点では、Ed25519Signature2018と違いはなく、IssuerのPubilc DIDでClaim群全体に対し署名がなされます。

違いはVerifierからHolderへのVP要求の際に起きます。Holderは保管したVCから、Verifierの要求に見合うよう一部のClaimのみを抜き出した新たなVCを導出し(Derived Credentialと呼ぶ)、それをVPに埋め込み提示します。その際、元のProof値は前述のUnlinkable Proof機能により開示されません。

おわりに

ACA-Pyを使いW3C VCs Data Modelに準拠したLDP-VCの発行と検証ができました。
以上でこの記事を終わります。どなたかのお役に立てたならば幸いです。