From bfdc77d05defcb6c6adee3032cf2d9e96b089cef Mon Sep 17 00:00:00 2001 From: oshikawatkm Date: Thu, 18 Aug 2022 17:54:10 +0900 Subject: [PATCH 1/5] add tapyrusrb guide --- _pages/guide/tapyrusrb.md | 348 ++++++++++++++++++ docs/guide/tapyrusrb.html | 549 ++++++++++++++++++++++++++++ scripts/generate_color_identifer.rb | 19 + scripts/generate_script.rb | 36 ++ scripts/generate_transaction.rb | 48 +++ scripts/rpc_call.rb | 11 + scripts/scriptinterpreter.rb | 28 ++ 7 files changed, 1039 insertions(+) create mode 100644 _pages/guide/tapyrusrb.md create mode 100644 docs/guide/tapyrusrb.html create mode 100644 scripts/generate_color_identifer.rb create mode 100644 scripts/generate_script.rb create mode 100644 scripts/generate_transaction.rb create mode 100644 scripts/rpc_call.rb create mode 100644 scripts/scriptinterpreter.rb diff --git a/_pages/guide/tapyrusrb.md b/_pages/guide/tapyrusrb.md new file mode 100644 index 0000000..bad8996 --- /dev/null +++ b/_pages/guide/tapyrusrb.md @@ -0,0 +1,348 @@ +--- +layout: single +permalink: /guide/tapyrusrb +title: "tapyrusrb ガイド" +--- + +この記事ではTapyruys rubyライブラリであるtapyrusrbの使用方法を解説します。 +[こちら](https://github.com/chaintope/tapyrus-pages/tree/master/scripts){:target="_blank"}に各項目のサンプルコードがあります。 +公式ドキュメントは[こちら](https://github.com/chaintope/tapyrusrb/wiki){:target="_blank"}です。 + +## tapyrsurbとは? {#about-tapyrusrb} +tapyrsurbとはTapyrusの基本機能を全て実装したrubyライブラリです。 +実装さている機能には以下のようなものがあります。 + +- Tapyrusスクリプトインタプリタ +- Tapyrusプロトコルネットワークメッセージのデシリアライゼーション +- ブロックとトランザクションのデシリアライゼーション +- SchnorrとECDSAの鍵生成と検証(BIP-32とBIP-39のサポートを含む) +- ECDSA署名(RFC6979 -決定論的ECDSA, LOW-S, LOW-R対応) +- [WIP] SPVノード +- [WIP】0ff-chainプロトコル + +## セットアップ方法 {#setup} + +### Level DBのインストール {#setup-leveldb} +tapyrusrbライブラリをインストールするためには、まずLevel DBをインストールする必要があります。 +各環境に応じた以下のコマンドを実行してください。 + +Ubuntu環境の場合: +``` +$ sudo apt-get install libleveldb-dev +``` + +Mac環境の場合: +``` +$ brew install leveldb +``` + +### leveldb-nativeのインストール {#setup-leveldb-native} +次にleveldb用のgemである`leveldb-native`をインストールします +``` +$ gem install leveldb-native +``` + +### tapyrusrbのインストール {#setup-tapyrusrb} +`tapyrusrb`をインストールします +``` +$ gem install tapyrus +``` + +tapyrusrbのモジュールを使用するためには、requireで読み込みをする必要があります。 +``` +require 'tapyrus' +``` + +## RPC呼び出し {#rpc-call} +[TapyrusCoreClientモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/rpc/tapyrus_core_client.rb){:target="_blank"}を用いることで、TapyrusCoreに対してRPC呼び出しを行なうことができます。 + +### createwallet {#rpc-call-createwallet} +`config`変数に実行中のTapyrus Coreの設定を行い、TapyrusCoreClientインスタンスの生成を行います。 +ウォレットの名前を引数に指定し、`createwallet`メソッドを使用することで、createwallet命令が実行されます。 +```ruby +config = { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass' } +client = Tapyrus::RPC::TapyrusCoreClient.new(config) +puts client.createwallet("rbtest") +``` + +実行すると、以下のようにRPCの実行結果が出力されます。 +``` +{"name"=>"rbtest", "warning"=>""} +``` + + +### listunspent {#rpc-call-listunspent} +特定のウォレットを使用する命令を実行する場合、`config`にwallet名を指定する必要があります。 +```ruby +config = { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass', wallet: "rbtest" } +client = Tapyrus::RPC::TapyrusCoreClient.new(config) +puts client.listunspent +``` + +ウォレットが資金を持っている場合、実行すると以下のように出力されます。資金を持っていない場合、何も表示されません。 +``` +{"txid"=>"82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7", "vout"=>1, "address"=>"mryyM31hokZSBfjVMFhNfAN8PtzS9EmoS2", "token"=>"TPC", "amount"=>"49.99994840", "scriptPubKey"=>"76a9147dc57e04a79379bffeb61f3d5ddd1d0cc94bfbe288ac", "confirmations"=>1, "spendable"=>true, "solvable"=>true, "safe"=>true} +{"txid"=>"5da116c8b9f6b85fb8ff26428ddf2d71cb1cb230a4ea6767759cebe9045616f0", "vout"=>0, "address"=>"mma9LALzWZTapAMxB9gN1CDCbNhJxuCwQr", "token"=>"TPC", "amount"=>"50.00000000", "label"=>"", "scriptPubKey"=>"76a914426b371b81a6da4b5ee616de7f7328b36fb813ec88ac", "confirmations"=>11, "spendable"=>true, "solvable"=>true, "safe"=>true} +``` + + +## 鍵ペア作成 {#generate-keypair} +鍵ペアの作成には[Keyモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/key.rb){:target="_blank"}を使用します。 +```ruby +key_pair = Tapyrus::Key.generate +puts "秘密鍵(WIF): #{key_pair.to_wif}" +puts "公開鍵: #{key_pair.pubkey}" +``` + +実行結果例: +``` +秘密鍵(WIF): cMx36XoeCWx6fCMYXRn8J999fn4BuTkw7PaYm4tBBEMPKT3NHZgL +公開鍵: 0201c315cd4bde40c098aa2251227aff1cd3f462c57993a31de3648c27c919a748 +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/generate_key_pair.rb){:target="_blank"}です。 + +## アドレスの生成 {#generate-address} +アドレスの生成は、鍵ペアの作成と同様に[Keyモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/key.rb){:target="_blank"}を使用します。 +```ruby +key_pair = Tapyrus::Key.generate +puts "秘密鍵(WIF): #{key_pair.to_wif}" +puts "アドレス: #{key_pair.to_p2pkh}" +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/generate_address.rb){:target="_blank"}です。 + +## トランザクション作成、署名 {#generate-transaction} +次に送金、 再発行可能なトークン発行、再発行不可能なトークン発行、NFT発行のトランザクション作成と署名方法について解説します。 +各種トランザクション作成には[TxBuilderモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/tx_builder.rb){:target="_blank"}を使用します。 + +トランザクションの作成には、以下のような`script_pubkey`, `txid`、`index`、`value`キーを持つハッシュオブジェクトの変数を定義する必要があります。 +`listunspend`コマンド等を用いてUTXOを取得し、変数を定義してください。 +```ruby +utxo = { + script_pubkey: , + txid: , + index: , + value: +} +``` + +### 送金トランザクションの作成 {#generate-pay-transaction} +TxBuilderインスタンスを生成し、add_utxoメソッドで使用するUTXOを指定します。 +payメソッドに送金先のアドレスと、送金するTPCの量を指定し、buildメソッドを呼び出すとTransactionインスタンスが生成されます。 +```ruby +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +pay_tx = tx_builder.add_utxo(utxo).change_address(key_pair.to_p2pkh).pay(key_pair.to_p2pkh, 1_000).build +puts "トランザクションID: #{pay_tx.txid}" +puts "未署名の送金トランザクション(hex): #{pay_tx.to_hex}" +``` + +実行結果例: +``` +トランザクションID: 0859e1dceef87bcd6b56d75a3b1f2c1762f4c7d4732fc58f8a74f7988bb626d4 +未署名の送金トランザクション(hex): 0100000001f0165604e9eb9c756767eaa430b21ccb712ddf8d4226ffb85fb8f6b9c816a15d0000000000ffffffff02e8030000000000001976a9140a3e199ac283546368f1693452194d23f0b6923488ace8030000000000001976a9140a3e199ac283546368f1693452194d23f0b6923488ac00000000 +``` + + +### 再発行可能なトークン発行トランザクションの作成 {#generate-reissuable-transaction} +reissuableメソッドの引数にパースしたscript_pubkeyとアドレス、発行量を指定し、buildメソッドを呼び出します。 +```ruby +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +non_reissuable_tx = tx_builder.add_utxo(utxo).reissuable(Tapyrus::Script.parse_from_payload(utxo[:script_pubkey]), key_pair.to_p2pkh, 10_000).build +puts "トランザクションID: #{non_reissuable_tx.txid}" +puts "未署名の再発行可能なトークン発行トランザクション(hex): #{non_reissuable_tx.to_hex}" +``` + +### 再発行不可能なトークン発行トランザクションの作成 {#generate-non-reissuable-transaction} +non_reissuableメソッドの引数にトランザクションのアウトポイントとアドレス、発行量を指定し、buildメソッドを呼び出します。 +```ruby +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +non_reissuable_tx = tx_builder.add_utxo(utxo).non_reissuable(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh, 10_000).build +puts "トランザクションID: #{non_reissuable_tx.txid}" +puts "再発行不可能なトークン発行トランザクション(hex): #{non_reissuable_tx.to_hex} +``` + + +### NFT発行トランザクションの作成 {#generate-nft-transaction} +NFTは再発行不可能なトークンと同様に、reissuableメソッドにトランザクションのアウトポイントとアドレス、発行量を指定し、buildを呼び出します。 +```ruby +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +nft_tx = tx_builder.add_utxo(utxo).nft(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh).build +puts "トランザクションID: #{nft_tx.txid}" +puts "未署名のNFT発行トランザクション(hex): #{nft_tx.to_hex}" +``` + + +### 署名 {#sign-transaction} +署名にはKeyモジュールのsignメソッドを用います。 +signメソッドには引数としてsignature hashを指定する必要があります。 +```ruby +sig_hash = pay_tx.sighash_for_input(utxo[:index], Tapyrus::Script.parse_from_payload(utxo[:script_pubkey])) +signature = key_pair.sign(sig_hash) + [Tapyrus::SIGHASH_TYPE[:all]].pack('C') +pay_tx.in[0].script_sig << signature +pay_tx.in[0].script_sig << key_pair.pubkey.htb +puts "トランザクションID: #{pay_tx.txid}" +puts "署名後の送金トランザクション(hex): #{pay_tx.to_hex}" +``` + +実行結果例: +``` +トランザクションID: 4cb35922035998bcdab0dc57058f52b92de30b8fffc1421ca9cf49940715517c +署名後の送金トランザクション(hex): 0100000001f0165604e9eb9c756767eaa430b21ccb712ddf8d4226ffb85fb8f6b9c816a15d000000006a4730440220668d5124f377bd49b580902b108aa4d7345b58682000b85e32d5de6eec77967302202c374cc771a07c96ec20bb5709ab51416e217c88695f9088293a760cf041036e0121020c295f28953568cda55b46a60c23a11132a5f72ef6345edfc9cd2dc175b6a5e9ffffffff02e8030000000000001976a914804abcb8f7cb0be5c9f11f8d9d21a307f25ca04e88ace8030000000000001976a914804abcb8f7cb0be5c9f11f8d9d21a307f25ca04e88ac00000000 +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/generate_transaction.rb){:target="_blank"}です。 + +## COLOR識別子の導出 {#generate-color-id} +COLOR識別子の導出にはscript_pubkeyかtxidとindexを用います。 +以下のように予めキーペアの生成とtxidとindexを変数として定義しておいてください。 + +```ruby +key_pair = Tapyrus::Key.generate +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +``` + + +### 再発行可能なトークン {#generate-color-id-reissuable} +再発行可能なトークンではCOLOR識別子の導出にscript_pubkeyを使用するため、Scriptモジュールのparse_from_addrメソッドを用いて生成します。 +ColorIdentifierモジュールのreissuableメソッドの引数にscript_pubkeyを指定します。 +```ruby +script_pubkey = Tapyrus::Script.parse_from_addr(key_pair.to_p2pkh) +reissuable_color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey) +puts reissuable_color_id.to_payload.bth +``` + +実行結果例: +``` +c118c00898fe9a4b71fddabf68f671ce54ad439acba9a85be5050cf27ccc727c6d +``` + + +### 再発行不可能なトークン {#generate-color-id-non-reissuable} +txidとindexを元に。[OutPointモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/out_point.rb){:target="_blank"}を用いてトランザクションのアウトポイントを生成し、non_reissuableメソッドの引数に指定します。 +```ruby +out_point = Tapyrus::OutPoint.from_txid(txid, index) +non_reissuable_color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point) +puts non_reissuable_color_id.to_payload.bth +``` + +実行結果例: +``` +c26dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b +``` + +### NFT {#generate-color-id-nft} +NFTも再発行不可能なトークンと同様にOutPointを用いてCOLOR識別子を導出します。 +```ruby +out_point = Tapyrus::OutPoint.from_txid(txid, index) +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +puts nft_color_id.to_payload.bth +``` + +実行結果例: +``` +c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/generate_color_identifer.rb){:target="_blank"}です。 + +## Scriptの生成 {#generate-script} +次に各種トランザクションに設定するTapyrusスクリプトの生成方法について解説します。 +スクリプトの生成には[Scriptモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/script/script.rb){:target="_blank"}を使用します。 + +### P2PKH {#generate-script-p2pkh} +P2PKHはBitcoinと同様のスクリプトを記述します。 +```ruby +p2pkh_script = Tapyrus::Script.new << '032ad705d98318241852ba9394a90e85f6afc8f7b5f445675040318a9d9ea29e35' << +Tapyrus::Script::OP_CHECKSIG +puts p2pkh_script +``` + +実行結果例: +``` +032ad705d98318241852ba9394a90e85f6afc8f7b5f445675040318a9d9ea29e35 OP_CHECKSIG +``` + +### P2PH {#generate-script-p2sh} +P2PHもBitcoinと同様です。以下は1-of-2マルチシグの例です。 +```ruby +key_pair1 = Tapyrus::Key.generate +key_pair2 = Tapyrus::Key.generate +p2sh_script = Tapyrus::Script.new << 1 << key_pair1.to_p2pkh << key_pair2.to_p2pkh << 2 << Tapyrus::Script::OP_CHECKMULTISIG +puts p2sh_script +``` + +実行結果例: +``` +1 63dfb8ddfa2e3fa327686bb44bb31251d0 617117b2e0c2338a03161d47b0f436c434 2 OP_CHECKMULTISIG +``` + +### CP2PKH {#generate-script-cp2pkh} +CP2PKHにはスクリプトの生成にはScriptモジュールのto_cp2pkhメソッドを用います。 +```ruby +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +key_pair = Tapyrus::Key.generate +out_point = Tapyrus::OutPoint.from_txid(txid, index) +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +cp2pkh_script = Tapyrus::Script.to_cp2pkh(nft_color_id, key_pair.to_p2pkh) +puts cp2pkh_script +``` + +実行結果: +``` +c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b OP_COLOR OP_DUP OP_HASH160 13afbd331ac0172c623cfa38d123064f5c OP_EQUALVERIFY OP_CHECKSIG +``` + +### CP2SH {#generate-script-cp2sh} +CP2SHにはスクリプトの生成にはScriptモジュールのto_cp2shメソッドを用います。 +```ruby +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +key_pair = Tapyrus::Key.generate +out_point = Tapyrus::OutPoint.from_txid(txid, index) +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +cp2sh_script = Tapyrus::Script.to_cp2sh(nft_color_id, key_pair.to_p2pkh) +puts cp2sh_script +``` + +実行結果例: +``` +c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b OP_COLOR OP_HASH160 63dfb8ddfa2e3fa327686bb44bb31251d0 OP_EQUAL +``` + +### OP_RETURN {#generate-script-opreturn} +OP_RETURNもBitcoinと同様です。 +```ruby +op_return_script = Tapyrus::Script.new << Tapyrus::Script::OP_RETURN << "contents".bth +puts op_return_script +``` + +実行結果例: +``` +OP_RETURN 636f6e74656e7473 +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/generate_script.rb){:target="_blank"}です。 + +## ScriptInterpreterによるスクリプトの評価 {#scriptInterpreter} +[ScriptInterpreterモジュール](https://github.com/chaintope/tapyrusrb/blob/master/lib/tapyrus/script/script_interpreter.rb){:target="_blank"}を使用します。 +```ruby +script_pubkey = Tapyrus::Script.to_p2pkh(key_pair.to_p2pkh) +script_sig = Tapyrus::Script.new << signature << key_pair.pubkey +tx_checker = Tapyrus::TxChecker.new(tx: pay_tx, input_index: 0) +interpreter = Tapyrus::ScriptInterpreter.new(flags: Tapyrus::STANDARD_SCRIPT_VERIFY_FLAGS, checker: tx_checker) +puts interpreter.verify_script(script_sig, script_pubkey) +``` + +実行するとbooleanで検証結果が出力されます。 +``` +false +``` + +サンプルコードは[こちら](https://github.com/chaintope/tapyrus-pages/scripts/tree/master/scriptinterpreter.rb){:target="_blank"}です。 \ No newline at end of file diff --git a/docs/guide/tapyrusrb.html b/docs/guide/tapyrusrb.html new file mode 100644 index 0000000..18cc2f7 --- /dev/null +++ b/docs/guide/tapyrusrb.html @@ -0,0 +1,549 @@ + + + + + + +tapyrusrb ガイド - Tapyrus Guide + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + +
+ + + +
+ + + + + +
+ +
+

tapyrusrb ガイド +

+ + + +
+ + +
+ +

この記事ではTapyruys rubyライブラリであるtapyrusrbの使用方法を解説します。 +こちらに各項目のサンプルコードがあります。 +公式ドキュメントはこちらです。

+ +

tapyrsurbとは?

+

tapyrsurbとはTapyrusの基本機能を全て実装したrubyライブラリです。 +実装さている機能には以下のようなものがあります。

+ +
    +
  • Tapyrusスクリプトインタプリタ
  • +
  • Tapyrusプロトコルネットワークメッセージのデシリアライゼーション
  • +
  • ブロックとトランザクションのデシリアライゼーション
  • +
  • SchnorrとECDSAの鍵生成と検証(BIP-32とBIP-39のサポートを含む)
  • +
  • ECDSA署名(RFC6979 -決定論的ECDSA, LOW-S, LOW-R対応)
  • +
  • [WIP] SPVノード
  • +
  • [WIP】0ff-chainプロトコル
  • +
+ +

セットアップ方法

+ +

Level DBのインストール

+

tapyrusrbライブラリをインストールするためには、まずLevel DBをインストールする必要があります。 +各環境に応じた以下のコマンドを実行してください。

+ +

Ubuntu環境の場合:

+
$ sudo apt-get install libleveldb-dev
+
+ +

Mac環境の場合:

+
$ brew install leveldb
+
+ +

leveldb-nativeのインストール

+

次にleveldb用のgemであるleveldb-nativeをインストールします

+
$ gem install leveldb-native
+
+ +

tapyrusrbのインストール

+

tapyrusrbをインストールします

+
$ gem install tapyrus
+
+ +

tapyrusrbのモジュールを使用するためには、requireで読み込みをする必要があります。

+
require 'tapyrus'
+
+ +

RPC呼び出し

+

TapyrusCoreClientモジュールを用いることで、TapyrusCoreに対してRPC呼び出しを行なうことができます。

+ +

createwallet

+

config変数に実行中のTapyrus Coreの設定を行い、TapyrusCoreClientインスタンスの生成を行います。 +ウォレットの名前を引数に指定し、createwalletメソッドを使用することで、createwallet命令が実行されます。

+
config =  { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass' }
+client = Tapyrus::RPC::TapyrusCoreClient.new(config)
+puts client.createwallet("rbtest")
+
+ +

実行すると、以下のようにRPCの実行結果が出力されます。

+
{"name"=>"rbtest", "warning"=>""}
+
+ +

listunspent

+

特定のウォレットを使用する命令を実行する場合、configにwallet名を指定する必要があります。

+
config =  { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass', wallet: "rbtest" }
+client = Tapyrus::RPC::TapyrusCoreClient.new(config)
+puts client.listunspent
+
+ +

ウォレットが資金を持っている場合、実行すると以下のように出力されます。資金を持っていない場合、何も表示されません。

+
{"txid"=>"82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7", "vout"=>1, "address"=>"mryyM31hokZSBfjVMFhNfAN8PtzS9EmoS2", "token"=>"TPC", "amount"=>"49.99994840", "scriptPubKey"=>"76a9147dc57e04a79379bffeb61f3d5ddd1d0cc94bfbe288ac", "confirmations"=>1, "spendable"=>true, "solvable"=>true, "safe"=>true}
+{"txid"=>"5da116c8b9f6b85fb8ff26428ddf2d71cb1cb230a4ea6767759cebe9045616f0", "vout"=>0, "address"=>"mma9LALzWZTapAMxB9gN1CDCbNhJxuCwQr", "token"=>"TPC", "amount"=>"50.00000000", "label"=>"", "scriptPubKey"=>"76a914426b371b81a6da4b5ee616de7f7328b36fb813ec88ac", "confirmations"=>11, "spendable"=>true, "solvable"=>true, "safe"=>true}
+
+ +

鍵ペア作成

+

鍵ペアの作成にはKeyモジュールを使用します。

+
key_pair = Tapyrus::Key.generate
+puts "秘密鍵(WIF): #{key_pair.to_wif}"
+puts "公開鍵: #{key_pair.pubkey}"
+
+ +

実行結果例:

+
秘密鍵(WIF): cMx36XoeCWx6fCMYXRn8J999fn4BuTkw7PaYm4tBBEMPKT3NHZgL
+公開鍵: 0201c315cd4bde40c098aa2251227aff1cd3f462c57993a31de3648c27c919a748
+
+ +

サンプルコードはこちらです。

+ +

アドレスの生成

+

アドレスの生成は、鍵ペアの作成と同様にKeyモジュールを使用します。

+
key_pair = Tapyrus::Key.generate
+puts "秘密鍵(WIF): #{key_pair.to_wif}"
+puts "アドレス: #{key_pair.to_p2pkh}"
+
+ +

サンプルコードはこちらです。

+ +

トランザクション作成、署名

+

次に送金、 再発行可能なトークン発行、再発行不可能なトークン発行、NFT発行のトランザクション作成と署名方法について解説します。 +各種トランザクション作成にはTxBuilderモジュールを使用します。

+ +

トランザクションの作成には、以下のようなscript_pubkey, txidindexvalueキーを持つハッシュオブジェクトの変数を定義する必要があります。 +listunspendコマンド等を用いてUTXOを取得し、変数を定義してください。

+
utxo = {
+  script_pubkey: <script_pubkeyの文字列>,
+  txid: <txidの文字列>,
+  index: <indexの数値>,
+  value: <amountの数値>
+}
+
+ +

送金トランザクションの作成

+

TxBuilderインスタンスを生成し、add_utxoメソッドで使用するUTXOを指定します。 +payメソッドに送金先のアドレスと、送金するTPCの量を指定し、buildメソッドを呼び出すとTransactionインスタンスが生成されます。

+
key_pair = Tapyrus::Key.generate
+tx_builder = Tapyrus::TxBuilder.new.fee(1_000) 
+pay_tx = tx_builder.add_utxo(utxo).change_address(key_pair.to_p2pkh).pay(key_pair.to_p2pkh, 1_000).build
+puts "トランザクションID: #{pay_tx.txid}"
+puts "未署名の送金トランザクション(hex): #{pay_tx.to_hex}"
+
+ +

実行結果例:

+
トランザクションID: 0859e1dceef87bcd6b56d75a3b1f2c1762f4c7d4732fc58f8a74f7988bb626d4
+未署名の送金トランザクション(hex): 0100000001f0165604e9eb9c756767eaa430b21ccb712ddf8d4226ffb85fb8f6b9c816a15d0000000000ffffffff02e8030000000000001976a9140a3e199ac283546368f1693452194d23f0b6923488ace8030000000000001976a9140a3e199ac283546368f1693452194d23f0b6923488ac00000000
+
+ +

再発行可能なトークン発行トランザクションの作成

+

reissuableメソッドの引数にパースしたscript_pubkeyとアドレス、発行量を指定し、buildメソッドを呼び出します。

+
key_pair = Tapyrus::Key.generate
+tx_builder = Tapyrus::TxBuilder.new.fee(1_000) 
+non_reissuable_tx = tx_builder.add_utxo(utxo).reissuable(Tapyrus::Script.parse_from_payload(utxo[:script_pubkey]), key_pair.to_p2pkh, 10_000).build
+puts "トランザクションID: #{non_reissuable_tx.txid}"
+puts "未署名の再発行可能なトークン発行トランザクション(hex): #{non_reissuable_tx.to_hex}"
+
+ +

再発行不可能なトークン発行トランザクションの作成

+

non_reissuableメソッドの引数にトランザクションのアウトポイントとアドレス、発行量を指定し、buildメソッドを呼び出します。

+
key_pair = Tapyrus::Key.generate
+tx_builder = Tapyrus::TxBuilder.new.fee(1_000) 
+non_reissuable_tx = tx_builder.add_utxo(utxo).non_reissuable(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh, 10_000).build
+puts "トランザクションID: #{non_reissuable_tx.txid}"
+puts "再発行不可能なトークン発行トランザクション(hex): #{non_reissuable_tx.to_hex}
+
+ +

NFT発行トランザクションの作成

+

NFTは再発行不可能なトークンと同様に、reissuableメソッドにトランザクションのアウトポイントとアドレス、発行量を指定し、buildを呼び出します。

+
key_pair = Tapyrus::Key.generate
+tx_builder = Tapyrus::TxBuilder.new.fee(1_000) 
+nft_tx = tx_builder.add_utxo(utxo).nft(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh).build
+puts "トランザクションID: #{nft_tx.txid}"
+puts "未署名のNFT発行トランザクション(hex): #{nft_tx.to_hex}"
+
+ +

署名

+

署名にはKeyモジュールのsignメソッドを用います。 +signメソッドには引数としてsignature hashを指定する必要があります。

+
sig_hash = pay_tx.sighash_for_input(utxo[:index], Tapyrus::Script.parse_from_payload(utxo[:script_pubkey]))
+signature = key_pair.sign(sig_hash) + [Tapyrus::SIGHASH_TYPE[:all]].pack('C')
+pay_tx.in[0].script_sig << signature
+pay_tx.in[0].script_sig << key_pair.pubkey.htb
+puts "トランザクションID: #{pay_tx.txid}"
+puts "署名後の送金トランザクション(hex): #{pay_tx.to_hex}"
+
+ +

実行結果例:

+
トランザクションID: 4cb35922035998bcdab0dc57058f52b92de30b8fffc1421ca9cf49940715517c
+署名後の送金トランザクション(hex): 0100000001f0165604e9eb9c756767eaa430b21ccb712ddf8d4226ffb85fb8f6b9c816a15d000000006a4730440220668d5124f377bd49b580902b108aa4d7345b58682000b85e32d5de6eec77967302202c374cc771a07c96ec20bb5709ab51416e217c88695f9088293a760cf041036e0121020c295f28953568cda55b46a60c23a11132a5f72ef6345edfc9cd2dc175b6a5e9ffffffff02e8030000000000001976a914804abcb8f7cb0be5c9f11f8d9d21a307f25ca04e88ace8030000000000001976a914804abcb8f7cb0be5c9f11f8d9d21a307f25ca04e88ac00000000
+
+ +

サンプルコードはこちらです。

+ +

COLOR識別子の導出

+

COLOR識別子の導出にはscript_pubkeyかtxidとindexを用います。 +以下のように予めキーペアの生成とtxidとindexを変数として定義しておいてください。

+ +
key_pair = Tapyrus::Key.generate
+txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7'
+index = 1
+
+ +

再発行可能なトークン

+

再発行可能なトークンではCOLOR識別子の導出にscript_pubkeyを使用するため、Scriptモジュールのparse_from_addrメソッドを用いて生成します。 +ColorIdentifierモジュールのreissuableメソッドの引数にscript_pubkeyを指定します。

+
script_pubkey = Tapyrus::Script.parse_from_addr(key_pair.to_p2pkh)
+reissuable_color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey)
+puts reissuable_color_id.to_payload.bth
+
+ +

実行結果例:

+
c118c00898fe9a4b71fddabf68f671ce54ad439acba9a85be5050cf27ccc727c6d
+
+ +

再発行不可能なトークン

+

txidとindexを元に。OutPointモジュールを用いてトランザクションのアウトポイントを生成し、non_reissuableメソッドの引数に指定します。

+
out_point = Tapyrus::OutPoint.from_txid(txid, index)
+non_reissuable_color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point)
+puts non_reissuable_color_id.to_payload.bth
+
+ +

実行結果例:

+
c26dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b
+
+ +

NFT

+

NFTも再発行不可能なトークンと同様にOutPointを用いてCOLOR識別子を導出します。

+
out_point = Tapyrus::OutPoint.from_txid(txid, index)
+nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
+puts nft_color_id.to_payload.bth
+
+ +

実行結果例:

+
c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b
+
+ +

サンプルコードはこちらです。

+ +

Scriptの生成

+

次に各種トランザクションに設定するTapyrusスクリプトの生成方法について解説します。 +スクリプトの生成にはScriptモジュールを使用します。

+ +

P2PKH

+

P2PKHはBitcoinと同様のスクリプトを記述します。

+
p2pkh_script = Tapyrus::Script.new << '032ad705d98318241852ba9394a90e85f6afc8f7b5f445675040318a9d9ea29e35' << 
+Tapyrus::Script::OP_CHECKSIG
+puts p2pkh_script
+
+ +

実行結果例:

+
032ad705d98318241852ba9394a90e85f6afc8f7b5f445675040318a9d9ea29e35 OP_CHECKSIG
+
+ +

P2PH

+

P2PHもBitcoinと同様です。以下は1-of-2マルチシグの例です。

+
key_pair1 = Tapyrus::Key.generate
+key_pair2 = Tapyrus::Key.generate
+p2sh_script = Tapyrus::Script.new << 1 << key_pair1.to_p2pkh << key_pair2.to_p2pkh << 2 << Tapyrus::Script::OP_CHECKMULTISIG
+puts p2sh_script
+
+ +

実行結果例:

+
1 63dfb8ddfa2e3fa327686bb44bb31251d0 617117b2e0c2338a03161d47b0f436c434 2 OP_CHECKMULTISIG
+
+ +

CP2PKH

+

CP2PKHにはスクリプトの生成にはScriptモジュールのto_cp2pkhメソッドを用います。

+
txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7'
+index = 1
+key_pair = Tapyrus::Key.generate
+out_point = Tapyrus::OutPoint.from_txid(txid, index)
+nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
+cp2pkh_script = Tapyrus::Script.to_cp2pkh(nft_color_id, key_pair.to_p2pkh)
+puts cp2pkh_script
+
+ +

実行結果:

+
c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b OP_COLOR OP_DUP OP_HASH160 13afbd331ac0172c623cfa38d123064f5c OP_EQUALVERIFY OP_CHECKSIG
+
+ +

CP2SH

+

CP2SHにはスクリプトの生成にはScriptモジュールのto_cp2shメソッドを用います。

+
txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7'
+index = 1
+key_pair = Tapyrus::Key.generate
+out_point = Tapyrus::OutPoint.from_txid(txid, index)
+nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
+cp2sh_script = Tapyrus::Script.to_cp2sh(nft_color_id, key_pair.to_p2pkh)
+puts cp2sh_script
+
+ +

実行結果例:

+
c36dc00eff1382bf20457922fd2fa2b26420b6d7045b28cf5ba90d0ee31055b82b OP_COLOR OP_HASH160 63dfb8ddfa2e3fa327686bb44bb31251d0 OP_EQUAL
+
+ +

OP_RETURN

+

OP_RETURNもBitcoinと同様です。

+
op_return_script = Tapyrus::Script.new << Tapyrus::Script::OP_RETURN << "contents".bth
+puts op_return_script
+
+ +

実行結果例:

+
OP_RETURN 636f6e74656e7473
+
+ +

サンプルコードはこちらです。

+ +

ScriptInterpreterによるスクリプトの評価

+

ScriptInterpreterモジュールを使用します。

+
script_pubkey = Tapyrus::Script.to_p2pkh(key_pair.to_p2pkh)
+script_sig = Tapyrus::Script.new << signature << key_pair.pubkey
+tx_checker = Tapyrus::TxChecker.new(tx: pay_tx, input_index: 0)
+interpreter = Tapyrus::ScriptInterpreter.new(flags: Tapyrus::STANDARD_SCRIPT_VERIFY_FLAGS, checker: tx_checker)
+puts interpreter.verify_script(script_sig, script_pubkey)
+
+ +

実行するとbooleanで検証結果が出力されます。

+
false
+
+ +

サンプルコードはこちらです。

+ + +
+ +
+ + + + + + + +
+ + + + +
+ + +
+ + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/generate_color_identifer.rb b/scripts/generate_color_identifer.rb new file mode 100644 index 0000000..0971bf7 --- /dev/null +++ b/scripts/generate_color_identifer.rb @@ -0,0 +1,19 @@ +require 'tapyrus' + +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +key_pair = Tapyrus::Key.generate + +### 再発行可能なトークン +script_pubkey = Tapyrus::Script.parse_from_addr(key_pair.to_p2pkh) +reissuable_color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey) +puts "reissuable_color_id: #{reissuable_color_id.to_payload.bth}" + +### 再発行不可能なトークン +out_point = Tapyrus::OutPoint.from_txid(txid, index) +non_reissuable_color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point) +puts "non_reissuable_color_id: #{non_reissuable_color_id.to_payload.bth}" + +### NFT +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +puts "nft_color_id: #{nft_color_id.to_payload.bth}" \ No newline at end of file diff --git a/scripts/generate_script.rb b/scripts/generate_script.rb new file mode 100644 index 0000000..2e8e508 --- /dev/null +++ b/scripts/generate_script.rb @@ -0,0 +1,36 @@ +require 'tapyrus' + +### p2pkh +p2pkh_script = Tapyrus::Script.new << '032ad705d98318241852ba9394a90e85f6afc8f7b5f445675040318a9d9ea29e35' << Tapyrus::Script::OP_CHECKSIG +puts "p2pkh_script: #{p2pkh_script}" + + +### p2sh +key_pair1 = Tapyrus::Key.generate +key_pair2 = Tapyrus::Key.generate +p2sh_script = Tapyrus::Script.new << 1 << key_pair1.to_p2pkh << key_pair2.to_p2pkh << 2 << Tapyrus::Script::OP_CHECKMULTISIG +puts "p2sh_script: #{p2sh_script}" + +### cp2pkh +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +out_point = Tapyrus::OutPoint.from_txid(txid, index) +out_point = Tapyrus::OutPoint.from_txid(txid, index) +non_reissuable_color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point) +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +cp2pkh_script = Tapyrus::Script.to_cp2sh(nft_color_id, key_pair1.to_p2pkh) +puts "cp2pkh_script: #{cp2pkh_script}" + + +### cp2sh +txid = '82ef88fbbc7009d5ec8f60a488643c8843e75c3cea5e19a6b9598867689908b7' +index = 1 +out_point = Tapyrus::OutPoint.from_txid(txid, index) +non_reissuable_color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point) +nft_color_id = Tapyrus::Color::ColorIdentifier.nft(out_point) +cp2sh_script = Tapyrus::Script.to_cp2sh(nft_color_id, key_pair1.to_p2pkh) +puts "cp2sh_script: #{cp2sh_script}" + +### OP_RETURN +op_return_script = Tapyrus::Script.new << Tapyrus::Script::OP_RETURN << "contents".bth +puts "op_return_script: #{op_return_script}" \ No newline at end of file diff --git a/scripts/generate_transaction.rb b/scripts/generate_transaction.rb new file mode 100644 index 0000000..dfe9f8b --- /dev/null +++ b/scripts/generate_transaction.rb @@ -0,0 +1,48 @@ +require 'tapyrus' + +utxo = { + script_pubkey: "76a914426b371b81a6da4b5ee616de7f7328b36fb813ec88ac", + txid: '5da116c8b9f6b85fb8ff26428ddf2d71cb1cb230a4ea6767759cebe9045616f0', + index: 0, + value: 3_000 +} + +### 送金トランザクションの作成 +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +pay_tx = tx_builder.add_utxo(utxo).change_address(key_pair.to_p2pkh).pay(key_pair.to_p2pkh, 1_000).build +puts "トランザクションID: #{pay_tx.txid}" +puts "未署名の送金トランザクション(hex): #{pay_tx.to_hex}" + + +### 再発行可能なトークン発行トランザクションの作成 +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +non_reissuable_tx = tx_builder.add_utxo(utxo).non_reissuable(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh, 10_000).build +puts "トランザクションID: #{non_reissuable_tx.txid}" +puts "未署名の再発行可能なトークン発行トランザクション(hex): #{non_reissuable_tx.to_hex}" + + +### 再発行不可能なトークン発行トランザクションの作成 +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +non_reissuable_tx = tx_builder.add_utxo(utxo).non_reissuable(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh, 10_000).build +puts "トランザクションID: #{non_reissuable_tx.txid}" +puts "未署名のNFT発行トランザクション(hex): #{non_reissuable_tx.to_hex}" + + +### NFT発行トランザクションの作成 +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +nft_tx = tx_builder.add_utxo(utxo).nft(Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]), key_pair.to_p2pkh).build +puts "トランザクションID: #{nft_tx.txid}" +puts "未署名のNFT発行トランザクション(hex): #{nft_tx.to_hex}" + + +### 署名 +sig_hash = pay_tx.sighash_for_input(utxo[:index], Tapyrus::Script.parse_from_payload(utxo[:script_pubkey])) +signature = key_pair.sign(sig_hash) + [Tapyrus::SIGHASH_TYPE[:all]].pack('C') +pay_tx.in[0].script_sig << signature +pay_tx.in[0].script_sig << key_pair.pubkey.htb +puts "トランザクションID: #{pay_tx.txid}" +puts "署名後の送金トランザクション(hex): #{pay_tx.to_hex}" \ No newline at end of file diff --git a/scripts/rpc_call.rb b/scripts/rpc_call.rb new file mode 100644 index 0000000..caeed05 --- /dev/null +++ b/scripts/rpc_call.rb @@ -0,0 +1,11 @@ +require 'tapyrus' + +### createwallet +config = { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass' } +client = Tapyrus::RPC::TapyrusCoreClient.new(config) +puts client.createwallet("rbtest") + +### listunspent +config = { schema: 'http', host: 'localhost', port: 12381, user: 'user', password: 'pass', wallet: "rbtest" } +client = Tapyrus::RPC::TapyrusCoreClient.new(config) +puts client.listunspent \ No newline at end of file diff --git a/scripts/scriptinterpreter.rb b/scripts/scriptinterpreter.rb new file mode 100644 index 0000000..f669402 --- /dev/null +++ b/scripts/scriptinterpreter.rb @@ -0,0 +1,28 @@ +require 'tapyrus' + +utxo = { + script_pubkey: "76a914426b371b81a6da4b5ee616de7f7328b36fb813ec88ac", + txid: '5da116c8b9f6b85fb8ff26428ddf2d71cb1cb230a4ea6767759cebe9045616f0', + index: 0, + value: 3_000 +} + +## 送金トランザクションの作成 +key_pair = Tapyrus::Key.generate +tx_builder = Tapyrus::TxBuilder.new.fee(1_000) +pay_tx = tx_builder.add_utxo(utxo).change_address(key_pair.to_p2pkh).pay(key_pair.to_p2pkh, 1_000).build + +## 署名 +sig_hash = pay_tx.sighash_for_input(utxo[:index], Tapyrus::Script.parse_from_payload(utxo[:script_pubkey])) +signature = key_pair.sign(sig_hash) + [Tapyrus::SIGHASH_TYPE[:all]].pack('C') +pay_tx.in[0].script_sig << signature +pay_tx.in[0].script_sig << key_pair.pubkey.htb + +## ScriptInterpreterによるスクリプトの評価 +script_pubkey = Tapyrus::Script.to_p2pkh(key_pair.to_p2pkh) +script_sig = Tapyrus::Script.new << signature << key_pair.pubkey +tx_checker = Tapyrus::TxChecker.new(tx: pay_tx, input_index: 0) +interpreter = Tapyrus::ScriptInterpreter.new(flags: Tapyrus::STANDARD_SCRIPT_VERIFY_FLAGS, checker: tx_checker) +puts interpreter.verify_script(script_sig, script_pubkey) + + From ac356d9ac982de53d281b6de97e5db52ce9a4855 Mon Sep 17 00:00:00 2001 From: oshikawatkm Date: Mon, 1 Aug 2022 15:15:23 +0900 Subject: [PATCH 2/5] add signer overview --- _pages/guide/signer-network-overview.md | 129 ++++++++ docs/guide/signer-network-overview.html | 390 ++++++++++++++++++++++++ 2 files changed, 519 insertions(+) create mode 100644 _pages/guide/signer-network-overview.md create mode 100644 docs/guide/signer-network-overview.html diff --git a/_pages/guide/signer-network-overview.md b/_pages/guide/signer-network-overview.md new file mode 100644 index 0000000..249f9ea --- /dev/null +++ b/_pages/guide/signer-network-overview.md @@ -0,0 +1,129 @@ +--- +layout: single +permalink: /guide/signer-network-overview +title: "Signer Networkの概要" +--- + +本記事ではSignerが用いる閾値署名方式とブロック生成の概要について解説します。 +Tapyrus Signerはあくまで参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。 + +## 秘密分散共有法 +秘密分散共有法とはシャミアが提案したShamir’s Secret Sharing Scheme(ssss)、複数の秘密情報を複数の管理者が協力して管理する方法です。 +一つの秘密情報を分割した情報である**シェア**を複数の管理者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の管理者に対し、それぞれの管理者に対応したシェアを分配します。 + + +## 検証可能秘密分散法(Verifiable Secret Sharing) +通常の秘密分散共有法では、ディーラーから配布されたシェアがその管理者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、管理者は判断することができないことが問題となります。 +その対策を行った方法に検証可能秘密分散(VSS)があります。 +有名なものにFeldmanの検証可能な秘密分散法があります。 + +### Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法) +Feldmanの検証可能な秘密分散法は、ssssにおいてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当にssssの曲線上の点であるか検証できるようにする手法です。 +ディラーは多項式の各係数のコミットメントを計算し、管理者に対して公開します。各管理者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。 + +## 閾値署名方式 {#threshold-signature-scheme} +Tapyrus Signer Network(TSN)の署名アルゴリズムは、"Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates"[^1]に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ署名が発行されません。 +TSNではFeldmanの検証可能な秘密分散法を採用しています。 +詳しくは[こちら](http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps)をご参照ください。 + +## BlockVSSの構成 {#blockvss-structure} +BlockVSSは2つのVSSシークレットを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。 + +- Blockvss[0]: 候補ブロックのSighash。 +- Blockvss[1]: 候補ブロックに賛成するVSSのためのデータのオブジェクト。 + - parameter: 秘密分散パラメータを格納したオブジェクト。 + - threshold: 閾値の整数値 - 1 + - share_count: 署名者数の整数値 + - commitments: コミットメントの配列。コミットメントはsecp256k1曲線点でありxとyの座標を持ちます。 +- Blockvss[2]: 賛成のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 +- Blockvss[3] 反対のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。 +- Blockvss[4] 反対のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 + +*BlockVSSの例* +```javascript +{ + "Blockvss": [ + "d68e99f1135c6661f174f4bee7c9b94a1e7dbb0eb7609f0aea118340ffd05944", + { + "parameters": { + "threshold": 1, + "share_count": 3 + }, + "commitments": [ + { + "x": "1fc491aef36b480160d71b099fe376e58fe0a915d0b382bb2c5daeb2f46665d2", + "y": "d4ec3f9d4e5a7494447c9f97476abdc475376311e49b7ce6000f9d0640c08fe9" + }, + { + "x": "647d33c9bb32320e8b7476743577180021f36e95aa939a96896e7e5be89f08fe", + "y": "6a68092234664285e4fd244623c406d8feead1e44c1be2b7272f77c733c4ab48" + } + ] + }, + "23a7185d3f2b402ff54168b880da783a7535e55cbc3ad657e5da2f2336cb349c", + { + "parameters": { + "threshold": 1, + "share_count": 3 + }, + "commitments": [ + { + "x": "1fc491aef36b480160d71b099fe376e58fe0a915d0b382bb2c5daeb2f46665d2", + "y": "2b13c062b1a58b6bbb836068b895423b8ac89cee1b648319fff062f8bf3f6c46" + }, + { + "x": "4247c04efc03c0c94bb129715d2b8d6128018e607936d9e3075bbb87f411043e", + "y": "fc8a579ca133a73ad27b0e9499b180c18fe51110beb8ebc90e18d12f2a490f4a" + } + ] + }, + "972ad402adf631e5a52ffe14803a40b19c6f578678a57bc833364842cce9c68" + ] +} +``` + +## LocalSigの構成 {#localsig-structure} + +```javascript +{ + "Blocksig": [ + "d68e99f1135c6661f174f4bee7c9b94a1e7dbb0eb7609f0aea118340ffd05944", + "218f1a47f87b48fa5ee77202fd14b15dbd04f8ef63834a56c1821f9b4ee842ed", + "e645628bb53b9902f89771863037e99448069014ab99860b26a3a710a5f746df" + ] +} +``` + + + +### ラウンド {#round} +Signer Networkのブロック生成はラウンド制で行います。 +ラウンドが開始する前に、ラウンドロビン方式で1つのSignerノードをラウンドマスターとして選出します。 +ラウンドマスターは、候補ブロックを生成し、他のSignerノード(ラウンドメンバー)に候補ブロックを公開します。 +候補ブロックを受信したラウンドメンバーは確認をおこない、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与する。 +閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。 + +各ラウンド開始時、タイマーがスタートする。各ラウンドの制限時間は65秒で、制限時間を過ぎるとラウンドは失敗し、次のラウンドが開始されます。 +これにより、一部のSignerが停止している場合でも、閾値を超える署名が生成可能であればブロック生成が可能で、システムの可用性を高めることが可能です。 + +#### ラウンドマスターのフロー {#raund-master-flow} +1. 新しいラウンドを開始する +2. 候補ブロックを生成 +3. 他のSignerノードに新しいブロックを公開(Redis Pub/Subを使用) +4. 署名発行プロトコル([以下](#signature-issuing-protocol)で説明) +5. ブロックの公開 + - ブロックがNGの場合、警告を記録 + - ブロックがOKの場合、次のステップへ + + +#### ラウンドメンバーのフロー {#raund-member-flow} +1. 新しいラウンドを開始する +2. 候補ブロックメッセージの受信を待つ +3. 候補ブロックの確認([以下](#signature-issuing-protocol)で説明) + - ブロックがNGの場合、警告を記録 + - ブロックがOKの場合、次のステップへ + + + +[^1]: Stinson, D. R., & Strobl, R. (2001). Provably secure distributed schnorr signatures and a (T, n) threshold scheme for implicit certificates. In Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics) (Vol. 2119, pp. 417–434). Springer Verlag. https://doi.org/10.1007/3-540-47719-5_33 \ No newline at end of file diff --git a/docs/guide/signer-network-overview.html b/docs/guide/signer-network-overview.html new file mode 100644 index 0000000..1f0eb84 --- /dev/null +++ b/docs/guide/signer-network-overview.html @@ -0,0 +1,390 @@ + + + + + + +Signer Networkの概要 - Tapyrus Guide + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
+ + + + +
+ + + +
+ + + + + +
+ +
+

Signer Networkの概要 +

+ + + +
+ + +
+ +

本記事ではSignerが用いる閾値署名方式とブロック生成の概要について解説します。 +Tapyrus Signerはあくまで参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。

+ +

秘密分散共有法

+

秘密分散共有法とはシャミアが提案したShamir’s Secret Sharing Scheme(ssss)、複数の秘密情報を複数の管理者が協力して管理する方法です。 +一つの秘密情報を分割した情報であるシェアを複数の管理者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の管理者に対し、それぞれの管理者に対応したシェアを分配します。

+ +

検証可能秘密分散法(Verifiable Secret Sharing)

+

通常の秘密分散共有法では、ディーラーから配布されたシェアがその管理者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、管理者は判断することができないことが問題となります。 +その対策を行った方法に検証可能秘密分散(VSS)があります。 +有名なものにFeldmanの検証可能な秘密分散法があります。

+ +

Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法)

+

Feldmanの検証可能な秘密分散法は、ssssにおいてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当にssssの曲線上の点であるか検証できるようにする手法です。 +ディラーは多項式の各係数のコミットメントを計算し、管理者に対して公開します。各管理者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。

+ +

閾値署名方式

+

Tapyrus Signer Network(TSN)の署名アルゴリズムは、”Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates”1に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ署名が発行されません。 +TSNではFeldmanの検証可能な秘密分散法を採用しています。 +詳しくはこちらをご参照ください。

+ +

BlockVSSの構成

+

BlockVSSは2つのVSSシークレットを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。

+ +
    +
  • Blockvss[0]: 候補ブロックのSighash。
  • +
  • Blockvss[1]: 候補ブロックに賛成するVSSのためのデータのオブジェクト。 +
      +
    • parameter: 秘密分散パラメータを格納したオブジェクト。 +
        +
      • threshold: 閾値の整数値 - 1
      • +
      • share_count: 署名者数の整数値
      • +
      +
    • +
    • commitments: コミットメントの配列。コミットメントはsecp256k1曲線点でありxとyの座標を持ちます。
    • +
    +
  • +
  • Blockvss[2]: 賛成のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • +
  • Blockvss[3] 反対のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。
  • +
  • Blockvss[4] 反対のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • +
+ +

BlockVSSの例

+
{
+  "Blockvss": [
+    "d68e99f1135c6661f174f4bee7c9b94a1e7dbb0eb7609f0aea118340ffd05944",
+    {
+      "parameters": {
+        "threshold": 1,
+        "share_count": 3
+      },
+      "commitments": [
+        {
+          "x": "1fc491aef36b480160d71b099fe376e58fe0a915d0b382bb2c5daeb2f46665d2",
+          "y": "d4ec3f9d4e5a7494447c9f97476abdc475376311e49b7ce6000f9d0640c08fe9"
+        },
+        {
+          "x": "647d33c9bb32320e8b7476743577180021f36e95aa939a96896e7e5be89f08fe",
+          "y": "6a68092234664285e4fd244623c406d8feead1e44c1be2b7272f77c733c4ab48"
+        }
+      ]
+    },
+    "23a7185d3f2b402ff54168b880da783a7535e55cbc3ad657e5da2f2336cb349c",
+    {
+      "parameters": {
+        "threshold": 1,
+        "share_count": 3
+      },
+      "commitments": [
+        {
+          "x": "1fc491aef36b480160d71b099fe376e58fe0a915d0b382bb2c5daeb2f46665d2",
+          "y": "2b13c062b1a58b6bbb836068b895423b8ac89cee1b648319fff062f8bf3f6c46"
+        },
+        {
+          "x": "4247c04efc03c0c94bb129715d2b8d6128018e607936d9e3075bbb87f411043e",
+          "y": "fc8a579ca133a73ad27b0e9499b180c18fe51110beb8ebc90e18d12f2a490f4a"
+        }
+      ]
+    },
+    "972ad402adf631e5a52ffe14803a40b19c6f578678a57bc833364842cce9c68"
+  ]
+}
+
+ +

LocalSigの構成

+ +
{
+  "Blocksig": [
+    "d68e99f1135c6661f174f4bee7c9b94a1e7dbb0eb7609f0aea118340ffd05944",
+    "218f1a47f87b48fa5ee77202fd14b15dbd04f8ef63834a56c1821f9b4ee842ed",
+    "e645628bb53b9902f89771863037e99448069014ab99860b26a3a710a5f746df"
+  ]
+}
+
+ +

ラウンド

+

Signer Networkのブロック生成はラウンド制で行います。
+ラウンドが開始する前に、ラウンドロビン方式で1つのSignerノードをラウンドマスターとして選出します。 +ラウンドマスターは、候補ブロックを生成し、他のSignerノード(ラウンドメンバー)に候補ブロックを公開します。 +候補ブロックを受信したラウンドメンバーは確認をおこない、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与する。 +閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。

+ +

各ラウンド開始時、タイマーがスタートする。各ラウンドの制限時間は65秒で、制限時間を過ぎるとラウンドは失敗し、次のラウンドが開始されます。 +これにより、一部のSignerが停止している場合でも、閾値を超える署名が生成可能であればブロック生成が可能で、システムの可用性を高めることが可能です。

+ +

ラウンドマスターのフロー

+
    +
  1. 新しいラウンドを開始する
  2. +
  3. 候補ブロックを生成
  4. +
  5. 他のSignerノードに新しいブロックを公開(Redis Pub/Subを使用)
  6. +
  7. 署名発行プロトコル(以下で説明)
  8. +
  9. ブロックの公開 +
      +
    • ブロックがNGの場合、警告を記録
    • +
    • ブロックがOKの場合、次のステップへ
    • +
    +
  10. +
+ +

ラウンドメンバーのフロー

+
    +
  1. 新しいラウンドを開始する
  2. +
  3. 候補ブロックメッセージの受信を待つ
  4. +
  5. 候補ブロックの確認(以下で説明) +
      +
    • ブロックがNGの場合、警告を記録
    • +
    • ブロックがOKの場合、次のステップへ
    • +
    +
  6. +
+ +
+
    +
  1. +

    Stinson, D. R., & Strobl, R. (2001). Provably secure distributed schnorr signatures and a (T, n) threshold scheme for implicit certificates. In Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics) (Vol. 2119, pp. 417–434). Springer Verlag. https://doi.org/10.1007/3-540-47719-5_33 

    +
  2. +
+
+ + +
+ +
+ + + + + + + +
+ + + + +
+ + +
+ + + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + From b9e11acfc38e2dde6fc6638a6414b0fa0c6733ba Mon Sep 17 00:00:00 2001 From: oshikawatkm Date: Tue, 16 Aug 2022 13:07:57 +0900 Subject: [PATCH 3/5] modify discriptions --- _pages/guide/signer-network-overview.md | 44 +++++++++++-------------- docs/guide/signer-network-overview.html | 42 +++++++++++------------ 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/_pages/guide/signer-network-overview.md b/_pages/guide/signer-network-overview.md index 249f9ea..594f987 100644 --- a/_pages/guide/signer-network-overview.md +++ b/_pages/guide/signer-network-overview.md @@ -5,30 +5,29 @@ title: "Signer Networkの概要" --- 本記事ではSignerが用いる閾値署名方式とブロック生成の概要について解説します。 -Tapyrus Signerはあくまで参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。 +Tapyrus Signerは参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。 -## 秘密分散共有法 -秘密分散共有法とはシャミアが提案したShamir’s Secret Sharing Scheme(ssss)、複数の秘密情報を複数の管理者が協力して管理する方法です。 -一つの秘密情報を分割した情報である**シェア**を複数の管理者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 -ディーラーが秘密情報をn個のシェアに分割し、n人の管理者に対し、それぞれの管理者に対応したシェアを分配します。 +## 秘密分散法 +秘密分散法とはブラークリーとシャミアによって同時期に独立して提案された、複数の秘密情報を複数の参加者が協力して管理する方法です。 +一つの秘密情報を分割した情報である**シェア**を複数の参加者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。 -## 検証可能秘密分散法(Verifiable Secret Sharing) -通常の秘密分散共有法では、ディーラーから配布されたシェアがその管理者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、管理者は判断することができないことが問題となります。 -その対策を行った方法に検証可能秘密分散(VSS)があります。 -有名なものにFeldmanの検証可能な秘密分散法があります。 +## 検証可能な秘密分散法(Verifiable Secret Sharing) +通常の秘密分散法では、ディーラーから配布されたシェアがその参加者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、参加者は判断することができないことが問題となります。 +そのような問題に対処するために提案されたのが、検証可能な秘密分散法(VSS)で、Feldmanが提案した方式などが有名です。 ### Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法) -Feldmanの検証可能な秘密分散法は、ssssにおいてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当にssssの曲線上の点であるか検証できるようにする手法です。 -ディラーは多項式の各係数のコミットメントを計算し、管理者に対して公開します。各管理者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。 +Feldmanの検証可能な秘密分散法は、通常の秘密分散法においてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当に秘密分散法の曲線上の点であるか検証できるようにする手法です。 +ディラーは多項式の各係数のコミットメントを計算し、参加者に対して公開します。各参加者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。 ## 閾値署名方式 {#threshold-signature-scheme} -Tapyrus Signer Network(TSN)の署名アルゴリズムは、"Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates"[^1]に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ署名が発行されません。 +Tapyrus Signer Network(TSN)の署名方式は、"Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates"[^1]に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ有効な署名が作成されません。 TSNではFeldmanの検証可能な秘密分散法を採用しています。 詳しくは[こちら](http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps)をご参照ください。 ## BlockVSSの構成 {#blockvss-structure} -BlockVSSは2つのVSSシークレットを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。 +BlockVSSは「正」と「負」の2種類のVSSを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。 - Blockvss[0]: 候補ブロックのSighash。 - Blockvss[1]: 候補ブロックに賛成するVSSのためのデータのオブジェクト。 @@ -36,9 +35,9 @@ BlockVSSは2つのVSSシークレットを持っています。一つは候補 - threshold: 閾値の整数値 - 1 - share_count: 署名者数の整数値 - commitments: コミットメントの配列。コミットメントはsecp256k1曲線点でありxとyの座標を持ちます。 -- Blockvss[2]: 賛成のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 -- Blockvss[3] 反対のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。 -- Blockvss[4] 反対のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 +- Blockvss[2]: 正のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 +- Blockvss[3] 負のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。 +- Blockvss[4] 負のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。 *BlockVSSの例* ```javascript @@ -95,14 +94,11 @@ BlockVSSは2つのVSSシークレットを持っています。一つは候補 } ``` - - ### ラウンド {#round} Signer Networkのブロック生成はラウンド制で行います。 ラウンドが開始する前に、ラウンドロビン方式で1つのSignerノードをラウンドマスターとして選出します。 ラウンドマスターは、候補ブロックを生成し、他のSignerノード(ラウンドメンバー)に候補ブロックを公開します。 -候補ブロックを受信したラウンドメンバーは確認をおこない、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与する。 -閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。 +候補ブロックを受信したラウンドメンバーはブロックの有効性を検証し、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与します。閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。 各ラウンド開始時、タイマーがスタートする。各ラウンドの制限時間は65秒で、制限時間を過ぎるとラウンドは失敗し、次のラウンドが開始されます。 これにより、一部のSignerが停止している場合でも、閾値を超える署名が生成可能であればブロック生成が可能で、システムの可用性を高めることが可能です。 @@ -113,16 +109,16 @@ Signer Networkのブロック生成はラウンド制で行います。 3. 他のSignerノードに新しいブロックを公開(Redis Pub/Subを使用) 4. 署名発行プロトコル([以下](#signature-issuing-protocol)で説明) 5. ブロックの公開 - - ブロックがNGの場合、警告を記録 - - ブロックがOKの場合、次のステップへ + - ブロックが無効な場合、警告を記録 + - ブロックが有効な場合、次のステップへ #### ラウンドメンバーのフロー {#raund-member-flow} 1. 新しいラウンドを開始する 2. 候補ブロックメッセージの受信を待つ 3. 候補ブロックの確認([以下](#signature-issuing-protocol)で説明) - - ブロックがNGの場合、警告を記録 - - ブロックがOKの場合、次のステップへ + - ブロックが無効な場合、警告を記録 + - ブロックが有効な場合、次のステップへ diff --git a/docs/guide/signer-network-overview.html b/docs/guide/signer-network-overview.html index 1f0eb84..5718c6c 100644 --- a/docs/guide/signer-network-overview.html +++ b/docs/guide/signer-network-overview.html @@ -159,29 +159,28 @@

Signer Networkの概

本記事ではSignerが用いる閾値署名方式とブロック生成の概要について解説します。 -Tapyrus Signerはあくまで参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。

+Tapyrus Signerは参照実装であり、有効なSchnorr署名が作成が可能であれば、必ずしもTapyrus Signerを利用する必要はありません。

-

秘密分散共有法

-

秘密分散共有法とはシャミアが提案したShamir’s Secret Sharing Scheme(ssss)、複数の秘密情報を複数の管理者が協力して管理する方法です。 -一つの秘密情報を分割した情報であるシェアを複数の管理者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 -ディーラーが秘密情報をn個のシェアに分割し、n人の管理者に対し、それぞれの管理者に対応したシェアを分配します。

+

秘密分散法

+

秘密分散法とはブラークリーとシャミアによって同時期に独立して提案された、複数の秘密情報を複数の参加者が協力して管理する方法です。 +一つの秘密情報を分割した情報であるシェアを複数の参加者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。

-

検証可能秘密分散法(Verifiable Secret Sharing)

-

通常の秘密分散共有法では、ディーラーから配布されたシェアがその管理者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、管理者は判断することができないことが問題となります。 -その対策を行った方法に検証可能秘密分散(VSS)があります。 -有名なものにFeldmanの検証可能な秘密分散法があります。

+

検証可能な秘密分散法(Verifiable Secret Sharing)

+

通常の秘密分散法では、ディーラーから配布されたシェアがその参加者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、参加者は判断することができないことが問題となります。 +そのような問題に対処するために提案されたのが、検証可能な秘密分散法(VSS)で、Feldmanが提案した方式などが有名です。

Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法)

-

Feldmanの検証可能な秘密分散法は、ssssにおいてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当にssssの曲線上の点であるか検証できるようにする手法です。 -ディラーは多項式の各係数のコミットメントを計算し、管理者に対して公開します。各管理者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。

+

Feldmanの検証可能な秘密分散法は、通常の秘密分散法においてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当に秘密分散法の曲線上の点であるか検証できるようにする手法です。 +ディラーは多項式の各係数のコミットメントを計算し、参加者に対して公開します。各参加者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。

閾値署名方式

-

Tapyrus Signer Network(TSN)の署名アルゴリズムは、”Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates”1に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ署名が発行されません。 +

Tapyrus Signer Network(TSN)の署名方式は、”Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates”1に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ有効な署名が作成されません。 TSNではFeldmanの検証可能な秘密分散法を採用しています。 詳しくはこちらをご参照ください。

BlockVSSの構成

-

BlockVSSは2つのVSSシークレットを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。

+

BlockVSSは「正」と「負」の2種類のVSSを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。

  • Blockvss[0]: 候補ブロックのSighash。
  • @@ -196,9 +195,9 @@

    BlockVSSの構成

  • commitments: コミットメントの配列。コミットメントはsecp256k1曲線点でありxとyの座標を持ちます。
-
  • Blockvss[2]: 賛成のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • -
  • Blockvss[3] 反対のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。
  • -
  • Blockvss[4] 反対のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • +
  • Blockvss[2]: 正のシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • +
  • Blockvss[3] 負のVSSの追加データのオブジェクト。フィールドのプロパティは賛成のVSSのデータのオブジェクトと同じです。
  • +
  • Blockvss[4] 負のVSSのシークレットシェア。secp256k1曲線のスカラー値をhex形式で表したものです。
  • BlockVSSの例

    @@ -258,8 +257,7 @@

    ラウンド

    Signer Networkのブロック生成はラウンド制で行います。
    ラウンドが開始する前に、ラウンドロビン方式で1つのSignerノードをラウンドマスターとして選出します。 ラウンドマスターは、候補ブロックを生成し、他のSignerノード(ラウンドメンバー)に候補ブロックを公開します。 -候補ブロックを受信したラウンドメンバーは確認をおこない、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与する。 -閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。

    +候補ブロックを受信したラウンドメンバーはブロックの有効性を検証し、候補ブロックの賛成・反対を判断し、各判断に対応したシークレットシェアを用いて署名を付与します。閾値以上の賛成署名が付与されると、ラウンドが成功し1つのブロックが生成されます。

    各ラウンド開始時、タイマーがスタートする。各ラウンドの制限時間は65秒で、制限時間を過ぎるとラウンドは失敗し、次のラウンドが開始されます。 これにより、一部のSignerが停止している場合でも、閾値を超える署名が生成可能であればブロック生成が可能で、システムの可用性を高めることが可能です。

    @@ -272,8 +270,8 @@

    ラウンドマスターのフロー

  • 署名発行プロトコル(以下で説明)
  • ブロックの公開
      -
    • ブロックがNGの場合、警告を記録
    • -
    • ブロックがOKの場合、次のステップへ
    • +
    • ブロックが無効な場合、警告を記録
    • +
    • ブロックが有効な場合、次のステップへ
  • @@ -284,8 +282,8 @@

    ラウンドメンバーのフロー

  • 候補ブロックメッセージの受信を待つ
  • 候補ブロックの確認(以下で説明)
      -
    • ブロックがNGの場合、警告を記録
    • -
    • ブロックがOKの場合、次のステップへ
    • +
    • ブロックが無効な場合、警告を記録
    • +
    • ブロックが有効な場合、次のステップへ
  • From b5f85de80cfb393d1c1e1316a00ed03844863d29 Mon Sep 17 00:00:00 2001 From: oshikawatkm Date: Fri, 19 Aug 2022 13:55:25 +0900 Subject: [PATCH 4/5] modyfy vss description --- _pages/guide/signer-network-overview.md | 8 ++++++-- docs/guide/signer-network-overview.html | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/_pages/guide/signer-network-overview.md b/_pages/guide/signer-network-overview.md index 594f987..023c83d 100644 --- a/_pages/guide/signer-network-overview.md +++ b/_pages/guide/signer-network-overview.md @@ -10,22 +10,25 @@ Tapyrus Signerは参照実装であり、有効なSchnorr署名が作成が可 ## 秘密分散法 秘密分散法とはブラークリーとシャミアによって同時期に独立して提案された、複数の秘密情報を複数の参加者が協力して管理する方法です。 一つの秘密情報を分割した情報である**シェア**を複数の参加者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 -ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。 ## 検証可能な秘密分散法(Verifiable Secret Sharing) 通常の秘密分散法では、ディーラーから配布されたシェアがその参加者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、参加者は判断することができないことが問題となります。 そのような問題に対処するために提案されたのが、検証可能な秘密分散法(VSS)で、Feldmanが提案した方式などが有名です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。 + -### Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法) +### Feldman’s VSS, Feldmanの検証可能な秘密分散法 (Feldman’s Verifiable Secret Sharing Scheme) Feldmanの検証可能な秘密分散法は、通常の秘密分散法においてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当に秘密分散法の曲線上の点であるか検証できるようにする手法です。 ディラーは多項式の各係数のコミットメントを計算し、参加者に対して公開します。各参加者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。 + ## 閾値署名方式 {#threshold-signature-scheme} Tapyrus Signer Network(TSN)の署名方式は、"Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold Scheme for Implicit Certificates"[^1]に基づいています。この署名方式では、n人の署名者のうちt人が協力しなければ有効な署名が作成されません。 TSNではFeldmanの検証可能な秘密分散法を採用しています。 詳しくは[こちら](http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps)をご参照ください。 + ## BlockVSSの構成 {#blockvss-structure} BlockVSSは「正」と「負」の2種類のVSSを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。 @@ -103,6 +106,7 @@ Signer Networkのブロック生成はラウンド制で行います。 各ラウンド開始時、タイマーがスタートする。各ラウンドの制限時間は65秒で、制限時間を過ぎるとラウンドは失敗し、次のラウンドが開始されます。 これにより、一部のSignerが停止している場合でも、閾値を超える署名が生成可能であればブロック生成が可能で、システムの可用性を高めることが可能です。 + #### ラウンドマスターのフロー {#raund-master-flow} 1. 新しいラウンドを開始する 2. 候補ブロックを生成 diff --git a/docs/guide/signer-network-overview.html b/docs/guide/signer-network-overview.html index 5718c6c..d2dd632 100644 --- a/docs/guide/signer-network-overview.html +++ b/docs/guide/signer-network-overview.html @@ -163,14 +163,14 @@

    Signer Networkの概

    秘密分散法

    秘密分散法とはブラークリーとシャミアによって同時期に独立して提案された、複数の秘密情報を複数の参加者が協力して管理する方法です。 -一つの秘密情報を分割した情報であるシェアを複数の参加者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。 -ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。

    +一つの秘密情報を分割した情報であるシェアを複数の参加者に配布し、特定の数のシェアが集まれば、元の秘密データを復元できるという手法です。

    検証可能な秘密分散法(Verifiable Secret Sharing)

    通常の秘密分散法では、ディーラーから配布されたシェアがその参加者に対応したシェアであるか、または悪意をもったディーラーが誤ったシェアを分配していないか、参加者は判断することができないことが問題となります。 -そのような問題に対処するために提案されたのが、検証可能な秘密分散法(VSS)で、Feldmanが提案した方式などが有名です。

    +そのような問題に対処するために提案されたのが、検証可能な秘密分散法(VSS)で、Feldmanが提案した方式などが有名です。 +ディーラーが秘密情報をn個のシェアに分割し、n人の参加者に対し、それぞれの参加者に対応したシェアを分配します。

    -

    Feldman’s Verifiable Secret Sharing Scheme(Feldman’s VSS, Feldmanの検証可能な秘密分散法)

    +

    Feldman’s VSS, Feldmanの検証可能な秘密分散法 (Feldman’s Verifiable Secret Sharing Scheme)

    Feldmanの検証可能な秘密分散法は、通常の秘密分散法においてディーラー(マスター秘密鍵生成者)から受け取ったシークレットシェアが本当に秘密分散法の曲線上の点であるか検証できるようにする手法です。 ディラーは多項式の各係数のコミットメントを計算し、参加者に対して公開します。各参加者はコミットメントを用いて自分のシークレットシェアが正しいものであるか検証することができます。

    From 0aca60f4b6dbc6e01dabca2c2c3f27064aac0c1c Mon Sep 17 00:00:00 2001 From: oshikawatkm Date: Fri, 19 Aug 2022 16:04:05 +0900 Subject: [PATCH 5/5] modyfy blockvss description --- _pages/guide/signer-network-overview.md | 2 +- docs/guide/signer-network-overview.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_pages/guide/signer-network-overview.md b/_pages/guide/signer-network-overview.md index 023c83d..108703f 100644 --- a/_pages/guide/signer-network-overview.md +++ b/_pages/guide/signer-network-overview.md @@ -30,7 +30,7 @@ TSNではFeldmanの検証可能な秘密分散法を採用しています。 ## BlockVSSの構成 {#blockvss-structure} -BlockVSSは「正」と「負」の2種類のVSSを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。 +BlockVSSは「正」と「負」の2種類のVSSを持っています。候補ブロックに賛成する際に、正のシークレットシェアを用いて署名を生成します。 - Blockvss[0]: 候補ブロックのSighash。 - Blockvss[1]: 候補ブロックに賛成するVSSのためのデータのオブジェクト。 diff --git a/docs/guide/signer-network-overview.html b/docs/guide/signer-network-overview.html index d2dd632..dc0f0af 100644 --- a/docs/guide/signer-network-overview.html +++ b/docs/guide/signer-network-overview.html @@ -180,7 +180,7 @@

    閾値署名方式

    詳しくはこちらをご参照ください。

    BlockVSSの構成

    -

    BlockVSSは「正」と「負」の2種類のVSSを持っています。一つは候補ブロックに賛成するための署名を生成するシークレットシェアで、もう一つは反対するための署名を生成するシークレットシェアです。

    +

    BlockVSSは「正」と「負」の2種類のVSSを持っています。候補ブロックに賛成する際に、正のシークレットシェアを用いて署名を生成します。

    • Blockvss[0]: 候補ブロックのSighash。