Home
概要
データ発行者が、データ所有者に対して発行した内容を、第三者である発行検証者がオンラインで確認できるゼロ知識エビデンス技術をご提案します。データの発行履歴を、発行者と所有者の署名付きで匿名化した上で発行履歴格納領域に保存し、発行検証者がゼロ知識証明を用いて匿名化された証明書の発行履歴の検証を可能にします。
![](./figures/abstract.png)
本サービスでは、ゼロ知識エビデンス技術をお試し頂くために、発行者/所有者/発行検証者の一連の動作を体験できる webAPI を提供します。
背景
昨今の社会は、個人及び法人の所有する電子データのやり取りによって成り立っています。コロナ禍によって進んだオンライン化により、法人によるオンライン上でのデータやり取りはもちろん、一般の個人でも、オンラインでアプリやリアルな物品を購入することが日常的となっています。
こういったデータのやり取りの来歴は、通常、そのデータをやり取りするプラットフォームによって管理されます。例えばオンライン上での購買履歴は、その購買システムを管轄するプラットフォーマーによって管理されています。従って、購買といったやり取りがあったことの証明などは、プラットフォーマーの一存によって行われます。
特に、プラットフォーマーが自身に有利になるよう取引履歴を改ざんする、といった事態が起こり得る可能性も否定できません。
このようなプラットフォーマーによる情報の独占は、デジタル社会における社会問題としてしばしば取り上げられます。
本技術は、データのやり取りにおいて、取引履歴の正当性を、プラットフォーマーではなく、取引を行った当事者が自発的に行えるようにする仕組みになります。
関連技術
情報の独占を対処する方法として、Verifiable Credential という枠組み が注目されています。
この枠組みは、電子的な個人情報を、管理者ではなく、個人が主権的にコントロールできる仕組みで、W3C により推進されています。
この枠組みは、データを発行する人(発行者)、データを所持する人(所有者)、データを検証する人(検証者)の三者により構成されます。
主な応用例としては、学生証や免許証といった個人の資格情報が念頭に置かれています。
例えば学生証の場合、発行者は学校、所有者は学生です。
所有者である学生は、受け取った学生証を用いることで、自分が学生であることを、検証者に主張できるようになります。
ここで、電子領収書を Verifiable Credential として発行するケースを考えてみましょう。
この場合、発行者は販売者、所有者は購入者となります。
所有者は受け取った電子領収書を用いることで、プラットフォーマーに依存せず、「自分が何を購入したか」を、検証者に主張できるようになります。
しかしながらこの仕組みでは、発行者は依然として、「自分が何を販売したか」を検証者に主張することが困難です。
なぜならば、所有者は電子領収書を所持している一方、発行者は所持していないからです。
そのため、発行者が自らの販売履歴を主張したい場合、発行者は領収書を所有している所有者に依頼する必要がありますが、所有者はその依頼に受け答えてくれるかはわかりませんし、そもそも紛失している可能性もあります。
このように、Verifiable Credential の枠組みだけでは、データ履歴の正当性を自発的に証明することは困難です。
本技術は、こういった関連する技術および枠組みを補強するものでもあります。
技術概要
本技術は、データが発行されたことを、客観的に証明することができる仕組みになります。
本技術の枠組みは、データを発行する人(発行者)、データを所有する人(所有者)、データが発行されたことを検証する人(発行検証者)により構成されています。
発行者は、所有者に向けデータを発行し、その後、「データを発行したこと」を発行検証者に向けて証明します。
公開されるAPIでは、発行者もしくは発行証明者のロールとなって、発行者による発行処理、発行者による発行証明の生成処理、そして発行検証者の発行証明の検証作業を体験することができます。
以下で、本技術が採用している技術の構成要素を示します。
電子署名
本技術では、データの本人性を検証するために、電子署名を活用してます。
具体的には、発行者、所有者の2名が、署名を構成するために必要な署名鍵と、署名を検証するために必要な公開鍵を有してます。
ブロックチェーン
本技術では、通信の秘匿証跡を残すために、ブロックチェーンを活用してます。
ブロックチェーンは一種のデータベースのようなものであり、秘匿された証跡を改ざん困難な形で保存することができます。
具体的には、ブロックチェーンを以下のように活用してます。
- データの発行処理の際、ブロックチェーンにデータを秘匿して書き込みます。
- 発行証明の検証処理の際、ブロックチェーンから秘匿されたデータを呼び出します。
ゼロ知識証明
本技術では、秘匿証跡の整合性を検証するために、ゼロ知識証明を活用してます。
ゼロ知識証明は、秘匿証跡と、秘匿証跡の元となる情報(の一部分)を検証者に開示した際、その開示した情報と秘匿証跡が対応することを、発行検証者になんら追加情報を与えず、証明する技術になります。この技術は、発行者が発行が実際に行われたことを発行検証者に示す際、開示するデータを最小限に抑えるものになっています。
ローカルトークン(LT)とグローバルトークン(GT)
ローカルトークンとグローバルトークンは、本技術において特別に用いられる専門用語です。
発行、取引といった、一つのデータの送信処理に対して、ローカルトークンとグローバルトークンという対が生成されます。
ローカルトークンは、取引の生データに対応するトークンで、具体的には、三つ組 LT = (sn,x,r) により生成されています。sn はトークンの ID、r は乱数、x は生データに相当します。概念的には、「x を発行した/ xというデータを送信した」というデータに相当しており、発行者が秘密裏に所持している情報になります。
グローバルトークンは、秘匿された取引のデータに対応するトークンです。
具体的には、三つ組 GT = (sn,C,pk) により生成されています。
ここで、C はコミットメントと呼ばれるもので、対応するローカルトークンの生データ x を乱数 r の下で秘匿化したものになります。
![](./figures/tokens.png)
プロトコル及びAPIの流れ
本技術におけるAPIの流れを下記に示します。
本APIでは、「あるデータ x が発行者から所有者に渡されている」というシナリオをベースに作られています。
発行者は、「所有者にデータ x を渡した」ことの証跡をブロックチェーンに秘匿して記録し、後に「所有者にデータ x を渡した」ことを、検証者に対して証明することがゴールです。
APIのお試しはこちら
発行者用のAPI:ブロックチェーンへの登録処理
発行者は、「所有者にデータ x を渡した」ことの証跡をブロックチェーンに秘匿して記録することができます。
具体的な一連の処理を、API の使用例として下の図に示します。
![](./figures/protocol1.png)
上記の一連の API のうち、1-1 と 1-6 はブロックチェーンへのアクセスを、1-2 と 1-5 は発行者のローカルな処理を、1-3 と 1-4 は発行者から所有者へのリクエストを、それぞれ再現したものになっています。
各 API の概要を示しつつ、「所有者にデータ x を渡した」ことの証跡を残す一連の流れを説明します。
- 1-1:ブロックチェーンにアクセスし、新規のシリアル番号を取得します。
- 1-2:ローカルトークン、グローバルトークンを生成します。
- 1-3:ローカルトークンとグローバルトークンの正当性を所有者に確認してもらい、署名を貰います。
- 1-4:所有者の公開鍵を取得します。
- 1-5:所有者の署名を検証し、グローバルトークン、所有者の署名、所有者の公開鍵の三つ組に対して署名を打ちます。
- 1-6:グローバルトークンと、エビデンス(=所有者による署名、所有者による公開鍵、発行者による署名、発行者の公開鍵の四つ組)をブロックチェーンに登録します。
以下、APIを詳述します。
1-1. シリアル番号生成API
- シリアル番号 sn を生成します。これは、発行者が所持する生データや、ブロックチェーンに登録されるデータなどに対する一意識別子となります。
1-2. トークンの生成API
- シリアル番号 sn と生データ x に対応して、ローカルトークン LT = (sn,x,r) とグローバルトークン GT = (sn,C,pk) を作成します。
- rは乱数です。
- C は、x,r から生成されるコミットメント(今回は x と r を結合した文字列のハッシュ値)です。
- pk は発行者の電子署名の公開鍵です。
1-3. 所有者署名の付与API
- 発行者が登録するグローバルトークンと、生データであるローカルトークンを、所有者に提示し、所有者からの署名を付与してもらう API です。
- これにより、ブロックチェーンに登録するデータを所有者に確認してもらうことで、発行者が勝手なデータを登録しているわけではないと主張できるようになります。
1-4. 所有者公開鍵取得API
- 所有者が所持している公開鍵を取得する API です。3で生成された、所有者署名を検証するのに必要となります。
1-5. 発行者署名の付与API
- 所有者からもらった署名を検証したうえで、発行者が署名を生成する API です。署名は、グローバルトークン、所有者による署名、所有者による公開鍵の三つ組みに対して打たれます。
- この、所有者による署名、所有者による公開鍵、発行者による署名、発行者の公開鍵の四つ組のことを、本技術ではエビデンスと呼んでいます。
1-6. アセット登録API
- ブロックチェーンに、グローバルトークンとエビデンスを登録する API です。これにより、発行者は取引処理を、ブロックチェーンに秘匿して格納することができました。
上記 API 処理のうち、1-1 によってブロックチェーンにシリアル番号が、1-6 によってブロックチェーンにグローバルトークンとエビデンスが登録されます。
ブロックチェーンには、1-2. トークンの生成API で使用した生データ x が登録されることはありません。
登録されるデータのうち、グローバルトークンは、生データ x を秘匿したものになります。
発行者用のAPI:ゼロ知識証明処理
これにより、発行者は、「所有者にデータ x を渡した」ことの証跡をブロックチェーンに秘匿して記録できました。
次に、「所有者にデータ x を渡した」ことの証明を実施します。
具体的な一連の処理を、API の使用例として下の図に示します。
![](./figures/protocol2.png)
上記の一連の API のうち、2-1 は発行者のローカルな処理を、3-1 と 3-2 は発行者から発行検証者へのリクエストを、3-3 は発行検証者によるブロックチェーンへのアクセスを、それぞれ再現したものになっています。
各 API の概要を示しつつ、「所有者にデータ x を渡した」ことの検証の流れを説明します。
- 2-1:生データ x、コミットメント C、コミットメントを作成した際の乱数 r を用いて、「C は x から生成された」ことを示すゼロ知識証明文を作成します。
- 3-1:検証に必要な検証鍵を取得する API です。
- 3-2:2-1 で作成したゼロ知識証明文を検証してもらう API です。これにより、「C は x から生成されたこと」の検証を行わせることができます。
- 3-3:シリアル番号を用いて、ブロックチェーンに登録された情報を確認する API です。これにより発行検証者は、3-2 で貰ったコミットメント C が実際にブロックチェーンに存在するか確認できます。
以下、API を詳述します。
2-1. ゼロ知識証明の作成API
- コミットメントC、それを生成した生データx、乱数rを用いて、Cはxから作られたことを証明するゼロ知識証明を作成するAPIです。
この生成される証明文は、「ブロックチェーンに記録された秘匿データ GT = (sn,C,r) に対して、対応するローカルトークンLTを知っている」ことを証明していることに相当します。この情報は発行者しか知りません。また、登録されたエビデンスによって、取引は発行者と所有者の間で合意が取れたものであることを確認できるので、「所有者にデータxを渡した」ことの証明になっています。
3-1. 検証鍵取得API
- 検証するために必要な情報である、検証鍵を取得する API です。
3-2. ゼロ知識証明の検証API
- ゼロ知識証明の作成 API で生成されたゼロ知識証明文、コミットメント C、生データ x を入力として、ゼロ知識証明の正しさを検証する API です。
- これによって、コミットメント C は確かに x から生成されたことを、発行検証者に確認してもらうことができます。
3-3. アセット取得API
- シリアル番号を用いて、ブロックチェーンに記録されているグローバルトークン GT = (sn,C,pk) と、エビデンス EV を取得します。
- これにより、検証するコミットメント C が、ブロックチェーンにグローバルトークンの一部として記録されているものかを確認できます。
結果として発行検証者は、ブロックチェーンに記録されたシリアル番号 sn、対応する生データ x、ゼロ知識証明文を提示してもらうことで、生データ x に対応するグローバルトークン GT = (sn,C,pk) がブロックチェーンに登録されていることを検証できます。
この検証によって、発行者と所有者の間で合意のとれた取引が実際に行われたことを、検証することが可能になります。
ゼロ知識証明技術が作用して、ローカルトークン自体をセキュアに保持したまま、上記の検証作業を実施できます。
API機能詳細
APIのお試しはこちら
シリアル番号生成API
パス |
メソッド |
説明 |
/request_serial_number |
POST |
ランダムなシリアル番号を生成し、ブロックチェーンへ登録を行う |
入力データ
なし
レスポンス
{
"serialNumber":<シリアル番号>
}
パラメータ |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
トークン作成API
パス |
メソッド |
説明 |
/create_tokens |
POST |
シリアル番号とデータからトークンを作成する |
入力データ
{
"serialNumber":<シリアル番号>,
"x":<データ>
}
パラメーター |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
x |
string |
生データ |
レスポンス
{
"localToken":<ローカルトークン>,
"globalToken":<グローバルトークン>,
"r":<乱数>,
"comm":<コミットメント>
}
パラメータ |
型 |
説明 |
localToken |
string |
ローカルトークン |
globalToken |
string |
グローバルトークン |
r |
string |
乱数 |
comm |
string |
コミットメント |
所有者署名付与API
パス |
メソッド |
説明 |
/create_gsign |
POST |
所有者の署名を作成する |
入力データ
{
"localToken":<ローカルトークン>,
"globalToken":<グローバルトークン>,
"x":<データ>
}
パラメーター |
型 |
説明 |
localToken |
string |
ローカルトークン |
globalToken |
string |
グローバルトークン |
x |
string |
生データ |
レスポンス
{
"gsign":<所有者による署名>
}
パラメータ |
型 |
説明 |
gsign |
string |
所有者による署名 |
所有者公開鍵取得API
パス |
メソッド |
説明 |
/get_okey |
GET |
署名の検証に必要な所有者の公開鍵を取得する |
レスポンス
{
"okey":<所有者の公開鍵>
}
パラメーター |
型 |
説明 |
okey |
string |
所有者の公開鍵 |
発行者署名付与API
パス |
メソッド |
説明 |
/create_owner_signature |
POST |
所有者による署名を検証し、発行者による署名を作成する |
入力データ
{
"globalToken":<グローバルトークン>,
"gsign":<所有者による署名>,
"okey":<所有者の公開鍵>
}
パラメーター |
型 |
説明 |
globalToken |
string |
グローバルトークン |
gsign |
string |
所有者による署名 |
okey |
string |
所有者の公開鍵 |
レスポンス
{
"globalToken":<グローバルトークン>,
"evidence":<エビデンス>
}
パラメータ |
型 |
説明 |
globalToken |
string |
グローバルトークン |
evidence |
string |
エビデンス(所有者による公開鍵、所有者による署名、発行者の公開鍵、発行者による署名) |
アセット登録API
パス |
メソッド |
説明 |
/register_assets |
POST |
グローバルトークンとエビデンスをブロックチェーンに登録する |
入力データ
{
"serialNumber":<シリアル番号>,
"globalToken":<グローバルトークン>,
"evidence":<エビデンス>
}
パラメーター |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
globalToken |
string |
グローバルトークン |
evidence |
string |
エビデンス(所有者による公開鍵、所有者による署名、発行者の公開鍵、発行者による署名) |
レスポンス
{
"serialNumber":<シリアル番号>,
"globalToken":<グローバルトークン>,
"evidence":<エビデンス>
}
パラメーター |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
globalToken |
string |
グローバルトークン |
evidence |
string |
エビデンス(所有者による公開鍵、所有者による署名、発行者の公開鍵、発行者による署名) |
アセット取得API
パス |
メソッド |
説明 |
/get_asset |
POST |
シリアル番号からブロックチェーンに記録されたアセットを取得する |
入力データ
{
"serialNumber":<シリアル番号>
}
パラメーター |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
レスポンス
{
"serialNumber":<シリアル番号>,
"globalToken":<グローバルトークン>,
"evidence":<エビデンス>
}
パラメーター |
型 |
説明 |
serialNumber |
string |
シリアル番号 |
globalToken |
string |
グローバルトークン |
evidence |
string |
エビデンス(所有者による公開鍵、所有者による署名、発行者の公開鍵、発行者による署名) |
ゼロ知識証明作成API
パス |
メソッド |
説明 |
/create_proof |
POST |
ゼロ知識証明の作成を行う |
入力データ
{
"x":<生データ>,
"r":<乱数>,
"comm":<コミットメント>
}
パラメーター |
型 |
説明 |
x |
string |
生データ |
r |
string |
乱数 |
comm |
string |
コミットメント(生データxを乱数rの下で秘匿化したもの) |
レスポンス
{
"proof":<証明>
}
パラメーター |
型 |
説明 |
proof |
string |
証明 |
検証鍵取得API
パス |
メソッド |
説明 |
/client/get_zkp_verification_key |
GET |
ゼロ知識証明検証鍵の取得 |
レスポンス
{
"verificationKey":<検証鍵>
}
パラメーター |
型 |
説明 |
verificationKey |
string |
検証鍵 |
ゼロ知識証明検証API
パス |
メソッド |
説明 |
/verify_proof |
POST |
ゼロ知識証明の検証を行う |
入力データ
{
"verificationKey":<検証鍵>,
"comm":<コミットメント>,
"x":<生データ>,
"proof":<ゼロ知識証明文>
}
パラメーター |
型 |
説明 |
verificationKey |
string |
検証鍵 |
comm |
string |
コミットメント(生データxを乱数rの下で秘匿化したもの) |
x |
string |
生データ |
proof |
string |
ゼロ知識証明文 |
レスポンス
{
"result":<検証結果>
}
パラメーター |
型 |
説明 |
result |
string |
検証結果 |
引用