bitcoin-ruby 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +2 -7
- data/COPYING +1 -1
- data/Gemfile +2 -6
- data/Gemfile.lock +34 -0
- data/README.rdoc +16 -68
- data/Rakefile +3 -6
- data/bin/bitcoin_shell +0 -1
- data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
- data/lib/bitcoin.rb +350 -296
- data/lib/bitcoin/builder.rb +3 -1
- data/lib/bitcoin/connection.rb +2 -1
- data/lib/bitcoin/contracthash.rb +76 -0
- data/lib/bitcoin/dogecoin.rb +97 -0
- data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
- data/lib/bitcoin/ffi/openssl.rb +98 -2
- data/lib/bitcoin/ffi/secp256k1.rb +144 -0
- data/lib/bitcoin/key.rb +12 -2
- data/lib/bitcoin/logger.rb +3 -12
- data/lib/bitcoin/protocol/block.rb +3 -9
- data/lib/bitcoin/protocol/parser.rb +6 -2
- data/lib/bitcoin/protocol/tx.rb +44 -13
- data/lib/bitcoin/protocol/txin.rb +4 -2
- data/lib/bitcoin/protocol/txout.rb +2 -2
- data/lib/bitcoin/script.rb +212 -37
- data/lib/bitcoin/trezor/mnemonic.rb +130 -0
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bitcoin_spec.rb +32 -3
- data/spec/bitcoin/builder_spec.rb +18 -0
- data/spec/bitcoin/contracthash_spec.rb +45 -0
- data/spec/bitcoin/dogecoin_spec.rb +176 -0
- data/spec/bitcoin/ffi_openssl.rb +45 -0
- data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
- data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
- data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
- data/spec/bitcoin/fixtures/coinbase.json +24 -0
- data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
- data/spec/bitcoin/protocol/block_spec.rb +0 -22
- data/spec/bitcoin/protocol/tx_spec.rb +145 -2
- data/spec/bitcoin/script/script_spec.rb +282 -0
- data/spec/bitcoin/secp256k1_spec.rb +48 -0
- data/spec/bitcoin/spec_helper.rb +0 -51
- data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
- metadata +48 -98
- data/bin/bitcoin_dns_seed +0 -130
- data/bin/bitcoin_gui +0 -80
- data/bin/bitcoin_node +0 -153
- data/bin/bitcoin_node_cli +0 -81
- data/bin/bitcoin_wallet +0 -402
- data/doc/CONFIG.rdoc +0 -66
- data/doc/EXAMPLES.rdoc +0 -13
- data/doc/NAMECOIN.rdoc +0 -34
- data/doc/NODE.rdoc +0 -225
- data/doc/STORAGE.rdoc +0 -33
- data/doc/WALLET.rdoc +0 -102
- data/examples/balance.rb +0 -66
- data/examples/forwarder.rb +0 -73
- data/examples/index_nhash.rb +0 -24
- data/examples/reindex_p2sh_addrs.rb +0 -44
- data/examples/relay_tx.rb +0 -22
- data/examples/verify_tx.rb +0 -57
- data/lib/bitcoin/config.rb +0 -58
- data/lib/bitcoin/gui/addr_view.rb +0 -44
- data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
- data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
- data/lib/bitcoin/gui/conn_view.rb +0 -38
- data/lib/bitcoin/gui/connection.rb +0 -70
- data/lib/bitcoin/gui/em_gtk.rb +0 -30
- data/lib/bitcoin/gui/gui.builder +0 -1643
- data/lib/bitcoin/gui/gui.rb +0 -292
- data/lib/bitcoin/gui/helpers.rb +0 -115
- data/lib/bitcoin/gui/tree_view.rb +0 -84
- data/lib/bitcoin/gui/tx_view.rb +0 -69
- data/lib/bitcoin/namecoin.rb +0 -280
- data/lib/bitcoin/network/command_client.rb +0 -104
- data/lib/bitcoin/network/command_handler.rb +0 -570
- data/lib/bitcoin/network/connection_handler.rb +0 -387
- data/lib/bitcoin/network/node.rb +0 -565
- data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
- data/lib/bitcoin/storage/models.rb +0 -171
- data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
- data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
- data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
- data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
- data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
- data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
- data/lib/bitcoin/storage/storage.rb +0 -517
- data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
- data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
- data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
- data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
- data/lib/bitcoin/validation.rb +0 -400
- data/lib/bitcoin/wallet/coinselector.rb +0 -33
- data/lib/bitcoin/wallet/keygenerator.rb +0 -77
- data/lib/bitcoin/wallet/keystore.rb +0 -207
- data/lib/bitcoin/wallet/txdp.rb +0 -118
- data/lib/bitcoin/wallet/wallet.rb +0 -281
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
- data/spec/bitcoin/namecoin_spec.rb +0 -182
- data/spec/bitcoin/node/command_api_spec.rb +0 -663
- data/spec/bitcoin/storage/models_spec.rb +0 -104
- data/spec/bitcoin/storage/reorg_spec.rb +0 -236
- data/spec/bitcoin/storage/storage_spec.rb +0 -387
- data/spec/bitcoin/storage/validation_spec.rb +0 -300
- data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
- data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
- data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
- data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
- data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
|
@@ -265,6 +265,8 @@ describe 'Bitcoin::Script' do
|
|
|
265
265
|
Script.new(SCRIPT[4]).is_p2sh?.should == false
|
|
266
266
|
Script.new(SCRIPT[5]).is_p2sh?.should == true
|
|
267
267
|
Script.new(SCRIPT[6]).is_p2sh?.should == false
|
|
268
|
+
Script.from_string("OP_DUP OP_HASH160 b689ebc262f50297139e7d16c4f8909e14ed4322 OP_EQUALVERIFY OP_CHECKSIGVERIFY OP_HASH160 1b6246121883816fc0637e4aa280aca1df219b1a OP_EQUAL")
|
|
269
|
+
.is_p2sh?.should == false
|
|
268
270
|
end
|
|
269
271
|
|
|
270
272
|
it '#is_op_return?' do
|
|
@@ -371,6 +373,7 @@ describe 'Bitcoin::Script' do
|
|
|
371
373
|
|
|
372
374
|
Script.to_pubkey_script_sig(@sig, pub).should == expected_script
|
|
373
375
|
end
|
|
376
|
+
|
|
374
377
|
it "should reject an improperly encoding public key" do
|
|
375
378
|
# Not binary encoded, like it's supposed to be.
|
|
376
379
|
pub = '02bc3e2b520d4be3e2651f2ba554392ea31edd69d2081186ab98acda3c4bf45e41'
|
|
@@ -379,6 +382,21 @@ describe 'Bitcoin::Script' do
|
|
|
379
382
|
Script.to_pubkey_script_sig(@sig, pub)
|
|
380
383
|
}.should.raise
|
|
381
384
|
end
|
|
385
|
+
|
|
386
|
+
it "should support different hash types" do
|
|
387
|
+
hash_type = Script::SIGHASH_TYPE[:single]
|
|
388
|
+
pub = '04bc3e2b520d4be3e2651f2ba554392ea31edd69d2081186ab98acda3c4bf45e41a5f6e093277b774b5893347e38ffafce2b9e82226e6e0b378cf79b8c2eed983c'.htb
|
|
389
|
+
expected_script = '483045022062437a8f60651cd968137355775fa8bdb83d4ca717fdbc08bf9868a051e0542f022100f5cd626c15ef0de0803ddf299e8895743e7ff484d6335874edfe086ee0a08fec034104bc3e2b520d4be3e2651f2ba554392ea31edd69d2081186ab98acda3c4bf45e41a5f6e093277b774b5893347e38ffafce2b9e82226e6e0b378cf79b8c2eed983c'.htb
|
|
390
|
+
|
|
391
|
+
Script.to_pubkey_script_sig(@sig, pub, hash_type).should == expected_script
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
it "should generate multisig script sig" do
|
|
395
|
+
hash_type = Script::SIGHASH_TYPE[:none]
|
|
396
|
+
expected_script = '00483045022062437a8f60651cd968137355775fa8bdb83d4ca717fdbc08bf9868a051e0542f022100f5cd626c15ef0de0803ddf299e8895743e7ff484d6335874edfe086ee0a08fec02483045022062437a8f60651cd968137355775fa8bdb83d4ca717fdbc08bf9868a051e0542f022100f5cd626c15ef0de0803ddf299e8895743e7ff484d6335874edfe086ee0a08fec02'.htb
|
|
397
|
+
|
|
398
|
+
Script.to_multisig_script_sig(@sig, @sig, hash_type).should == expected_script
|
|
399
|
+
end
|
|
382
400
|
end
|
|
383
401
|
|
|
384
402
|
|
|
@@ -635,4 +653,268 @@ OP_ENDIF")
|
|
|
635
653
|
script.run.should == true
|
|
636
654
|
end
|
|
637
655
|
|
|
656
|
+
def build_p2sh_multisig_tx(m, *keys)
|
|
657
|
+
redeem_script = Bitcoin::Script.to_multisig_script(m, *keys.map(&:pub))
|
|
658
|
+
p2sh_address = Bitcoin.hash160_to_p2sh_address(Bitcoin.hash160(redeem_script.hth))
|
|
659
|
+
|
|
660
|
+
prev_tx = build_tx {|t| t.input {|i| i.coinbase}
|
|
661
|
+
t.output {|o| o.to p2sh_address; o.value 50e8 } }
|
|
662
|
+
tx = build_tx {|t| t.input {|i| i.prev_out prev_tx, 0 }
|
|
663
|
+
t.output {|o| o.to Bitcoin::Key.generate.addr; o.value 50e8 } }
|
|
664
|
+
|
|
665
|
+
sig_hash = tx.signature_hash_for_input(0, redeem_script)
|
|
666
|
+
return prev_tx, tx, redeem_script, sig_hash
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
it "#sort_p2sh_multisig_signatures 3-of-3" do
|
|
670
|
+
keys = 3.times.map { Bitcoin::Key.generate }
|
|
671
|
+
|
|
672
|
+
prev_tx, tx, redeem_script, sig_hash = build_p2sh_multisig_tx(3, *keys)
|
|
673
|
+
sigs = keys.map {|k| k.sign(sig_hash) }
|
|
674
|
+
|
|
675
|
+
# add sigs in all possible orders, sort them, and see if they are valid
|
|
676
|
+
[0, 1, 2].permutation do |order|
|
|
677
|
+
script_sig = Script.to_p2sh_multisig_script_sig(redeem_script)
|
|
678
|
+
order.each{|i| script_sig = Script.add_sig_to_multisig_script_sig(sigs[i], script_sig)}
|
|
679
|
+
script_sig = Script.sort_p2sh_multisig_signatures(script_sig, sig_hash)
|
|
680
|
+
tx.in[0].script_sig = script_sig
|
|
681
|
+
tx.verify_input_signature(0, prev_tx).should == true
|
|
682
|
+
end
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
it "#sort_p2sh_multisig_signatures 2-of-3" do
|
|
686
|
+
keys = 3.times.map { Bitcoin::Key.generate }
|
|
687
|
+
|
|
688
|
+
prev_tx, tx, redeem_script, sig_hash = build_p2sh_multisig_tx(2, *keys)
|
|
689
|
+
sigs = keys.map {|k| k.sign(sig_hash) }
|
|
690
|
+
|
|
691
|
+
# add sigs in all possible orders, sort them, and see if they are valid
|
|
692
|
+
[0, 1, 2].permutation(2) do |order|
|
|
693
|
+
script_sig = Script.to_p2sh_multisig_script_sig(redeem_script)
|
|
694
|
+
order.each{|i| script_sig = Script.add_sig_to_multisig_script_sig(sigs[i], script_sig)}
|
|
695
|
+
script_sig = Script.sort_p2sh_multisig_signatures(script_sig, sig_hash)
|
|
696
|
+
tx.in[0].script_sig = script_sig
|
|
697
|
+
tx.verify_input_signature(0, prev_tx).should == true
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
describe "Implements BIP62" do
|
|
704
|
+
it 'tests for incorrectly encoded S-values in signatures' do
|
|
705
|
+
# TX 3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae
|
|
706
|
+
sig_orig = ["304502210088984573e3e4f33db7df6aea313f1ce67a3ef3532ea89991494c7f018258371802206ceefc9291450dbd40d834f249658e0f64662d52a41cf14e20c9781144f2fe0701"].pack("H*")
|
|
707
|
+
Bitcoin::Script::is_low_der_signature?(sig_orig).should == true
|
|
708
|
+
|
|
709
|
+
# Set the start of the S-value to 0xff so it's well above the order of the curve divided by two
|
|
710
|
+
sig = sig_orig.unpack("C*")
|
|
711
|
+
length_r = sig[3]
|
|
712
|
+
sig[6 + length_r] = 0xff
|
|
713
|
+
|
|
714
|
+
Bitcoin::Script::is_low_der_signature?(sig.pack("C*")).should == false
|
|
715
|
+
end
|
|
716
|
+
it 'enforces rules 3 and 4' do
|
|
717
|
+
Script.new([75].pack("C") + 'A' * 75).pushes_are_canonical?.should == true
|
|
718
|
+
Script.new([Bitcoin::Script::OP_PUSHDATA1, 75].pack("CC") + 'A' * 75).pushes_are_canonical?.should == false
|
|
719
|
+
Script.new([Bitcoin::Script::OP_PUSHDATA2, 255].pack("Cv") + 'A' * 255).pushes_are_canonical?.should == false
|
|
720
|
+
Script.new([Bitcoin::Script::OP_PUSHDATA4, 1645].pack("CV") + 'A' * 1645).pushes_are_canonical?.should == false
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
describe "Implements BIP66" do
|
|
725
|
+
def build_crediting_tx(script_pk)
|
|
726
|
+
tx = Bitcoin::P::Tx.new
|
|
727
|
+
input = Bitcoin::P::TxIn.new(nil, 0xffffffff, 2, "\x00\x00")
|
|
728
|
+
output = Bitcoin::P::TxOut.new(0, script_pk)
|
|
729
|
+
tx.add_in(input)
|
|
730
|
+
tx.add_out(output)
|
|
731
|
+
Bitcoin::P::Tx.new(tx.to_payload)
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
def build_spending_tx(script_sig, tx_credit)
|
|
735
|
+
tx = Bitcoin::P::Tx.new
|
|
736
|
+
input = Bitcoin::P::TxIn.new(tx_credit.binary_hash, 0, 2, script_sig)
|
|
737
|
+
output = Bitcoin::P::TxOut.new(0, '')
|
|
738
|
+
tx.add_in(input)
|
|
739
|
+
tx.add_out(output)
|
|
740
|
+
Bitcoin::P::Tx.new(tx.to_payload)
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
# essentially DoTest() from script_tests.cpp
|
|
744
|
+
def run_script_test(script_sig_str, script_pk_str, opts={})
|
|
745
|
+
script_sig = Bitcoin::Script.from_string(script_sig_str)
|
|
746
|
+
script_pk = Bitcoin::Script.from_string(script_pk_str)
|
|
747
|
+
tx_credit = build_crediting_tx(script_pk.raw)
|
|
748
|
+
tx = build_spending_tx(script_sig.raw, tx_credit)
|
|
749
|
+
tx.verify_input_signature(0, tx_credit, Time.now.to_i, opts)
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
it 'overly long signature fails with DERSIG passes without' do
|
|
753
|
+
script_sig = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
754
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
755
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
756
|
+
run_script_test(script_sig, script_pk).should == true
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
it 'missing S fails with DERSIG passes without' do
|
|
760
|
+
script_sig = "3022022000000000000000000000000000000000000000000000000000000000000000000"
|
|
761
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
762
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
763
|
+
run_script_test(script_sig, script_pk).should == true
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
it 'S with invalid fails with DERSIG passes without' do
|
|
767
|
+
script_sig = "3024021077777777777777777777777777777777020a7777777777777777777777777777777701"
|
|
768
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
769
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
770
|
+
run_script_test(script_sig, script_pk).should == true
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
it 'non-integer R fails with DERSIG passes without' do
|
|
774
|
+
script_sig = "302403107777777777777777777777777777777702107777777777777777777777777777777701"
|
|
775
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
776
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
777
|
+
run_script_test(script_sig, script_pk).should == true
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
it 'non-integer S fails with DERSIG passes without' do
|
|
781
|
+
script_sig = "302402107777777777777777777777777777777703107777777777777777777777777777777701"
|
|
782
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
783
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
784
|
+
run_script_test(script_sig, script_pk).should == true
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
it 'zero length R fails with DERSIG passes without' do
|
|
788
|
+
script_sig = "3014020002107777777777777777777777777777777701"
|
|
789
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
790
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
791
|
+
run_script_test(script_sig, script_pk).should == true
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
it 'zero length S fails with DERSIG passes without' do
|
|
795
|
+
script_sig = "3014021077777777777777777777777777777777020001"
|
|
796
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
797
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
798
|
+
run_script_test(script_sig, script_pk).should == true
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
it 'negative S fails with DERSIG passes without' do
|
|
802
|
+
script_sig = "302402107777777777777777777777777777777702108777777777777777777777777777777701"
|
|
803
|
+
script_pk = "0 OP_CHECKSIG OP_NOT"
|
|
804
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
805
|
+
run_script_test(script_sig, script_pk).should == true
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# see: https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki#examples
|
|
809
|
+
# see also: https://github.com/bitcoin/bitcoin/pull/5713/files
|
|
810
|
+
P1 = "038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"
|
|
811
|
+
P2 = "03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640"
|
|
812
|
+
|
|
813
|
+
# Example 1: S1' P1 CHECKSIG (fails w/ verify_dersig, passes w/o)
|
|
814
|
+
it 'example 1' do
|
|
815
|
+
script_sig = "30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201"
|
|
816
|
+
script_pk = "#{P1} OP_CHECKSIG"
|
|
817
|
+
run_script_test(script_sig, script_pk).should == true
|
|
818
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
# Example 2: S1' P1 CHECKSIG NOT (fails with either)
|
|
822
|
+
it 'example 2' do
|
|
823
|
+
script_sig = "304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01"
|
|
824
|
+
script_pk = "#{P1} OP_CHECKSIG OP_NOT"
|
|
825
|
+
run_script_test(script_sig, script_pk).should == false
|
|
826
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
# Example 3: F P1 CHECKSIG fails (fails with either)
|
|
830
|
+
it 'example 3' do
|
|
831
|
+
script_sig = "0"
|
|
832
|
+
script_pk = "#{P1} OP_CHECKSIG"
|
|
833
|
+
run_script_test(script_sig, script_pk).should == false
|
|
834
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
# Example 4: F P1 CHECKSIG NOT (passes with either)
|
|
838
|
+
it 'example 4' do
|
|
839
|
+
script_sig = "0"
|
|
840
|
+
script_pk = "#{P1} OP_CHECKSIG OP_NOT"
|
|
841
|
+
run_script_test(script_sig, script_pk).should == true
|
|
842
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == true
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
# Example 5: F' P1 CHECKSIG (fails with either)
|
|
846
|
+
it 'example 5' do
|
|
847
|
+
script_sig = "1"
|
|
848
|
+
script_pk = "#{P1} OP_CHECKSIG"
|
|
849
|
+
run_script_test(script_sig, script_pk).should == false
|
|
850
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
# Example 6: F' P1 CHECKSIG NOT (fails w/verify_dersig, passes w/o)
|
|
854
|
+
it 'example 6' do
|
|
855
|
+
script_sig = "1"
|
|
856
|
+
script_pk = "#{P1} OP_CHECKSIG OP_NOT"
|
|
857
|
+
run_script_test(script_sig, script_pk).should == true
|
|
858
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
# Example 7: 0 S1' S2 2 P1 P2 2 CHECKMULTISIG (fails w/verify_dersig, passes w/o)
|
|
862
|
+
it 'example 7' do
|
|
863
|
+
s1 = "30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501"
|
|
864
|
+
s2 = "304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01"
|
|
865
|
+
script_sig = "0 #{s1} #{s2}"
|
|
866
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG"
|
|
867
|
+
run_script_test(script_sig, script_pk).should == true
|
|
868
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
# Example 8: 0 S1' S2 2 P1 P2 2 CHECKMULTISIG NOT (fails for either)
|
|
872
|
+
it 'example 8' do
|
|
873
|
+
s1 = "30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601"
|
|
874
|
+
s2 = "3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801"
|
|
875
|
+
script_sig = "0 #{s1} #{s2}"
|
|
876
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG OP_NOT"
|
|
877
|
+
run_script_test(script_sig, script_pk).should == false
|
|
878
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
# Example 9: 0 F S2' 2 P1 P2 2 CHECKMULTISIG fails (fails for either)
|
|
882
|
+
it 'example 9' do
|
|
883
|
+
s1 = "0"
|
|
884
|
+
s2 = "3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01"
|
|
885
|
+
script_sig = "0 #{s1} #{s2}"
|
|
886
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG"
|
|
887
|
+
run_script_test(script_sig, script_pk).should == false
|
|
888
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
889
|
+
end
|
|
890
|
+
|
|
891
|
+
# Example 10: 0 F S2' 2 P1 P2 2 CHECKMULTISIG NOT (fails w/verify_dersig, passes w/o)
|
|
892
|
+
it 'example 10' do
|
|
893
|
+
s1 = "0"
|
|
894
|
+
s2 = "30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501"
|
|
895
|
+
script_sig = "0 #{s1} #{s2}"
|
|
896
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG OP_NOT"
|
|
897
|
+
run_script_test(script_sig, script_pk).should == true
|
|
898
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
# Example 11: 0 S1' F 2 P1 P2 2 CHECKMULTISIG (fails for either)
|
|
902
|
+
it 'example 11' do
|
|
903
|
+
s1 = "30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501"
|
|
904
|
+
s2 = "0"
|
|
905
|
+
script_sig = "0 #{s1} #{s2}"
|
|
906
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG"
|
|
907
|
+
run_script_test(script_sig, script_pk).should == false
|
|
908
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == false
|
|
909
|
+
end
|
|
910
|
+
|
|
911
|
+
# Example 12: 0 S1' F 2 P1 P2 2 CHECKMULTISIG NOT (passes for either)
|
|
912
|
+
it 'example 12' do
|
|
913
|
+
s1 = "30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601"
|
|
914
|
+
s2 = "0"
|
|
915
|
+
script_sig = "0 #{s1} #{s2}"
|
|
916
|
+
script_pk = "2 #{P1} #{P2} 2 OP_CHECKMULTISIG OP_NOT"
|
|
917
|
+
run_script_test(script_sig, script_pk).should == true
|
|
918
|
+
run_script_test(script_sig, script_pk, {verify_dersig: true}).should == true
|
|
919
|
+
end
|
|
638
920
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
require_relative 'spec_helper.rb'
|
|
4
|
+
require 'bitcoin'
|
|
5
|
+
|
|
6
|
+
describe 'libsecp256k1' do
|
|
7
|
+
|
|
8
|
+
it 'generate key pair' do
|
|
9
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair(compressed = true)
|
|
10
|
+
[priv, pub].map(&:bytesize).should == [32, 33]
|
|
11
|
+
["\x03", "\x02"].include?(pub[0]).should == true
|
|
12
|
+
|
|
13
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair(compressed = false)
|
|
14
|
+
[priv, pub].map(&:bytesize).should == [32, 65]
|
|
15
|
+
["\x04"].include?(pub[0]).should == true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'sign and verify' do
|
|
19
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair
|
|
20
|
+
signature = Bitcoin::Secp256k1.sign("derp", priv)
|
|
21
|
+
Bitcoin::Secp256k1.verify("derp", signature, pub).should == true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'sign compact and recover' do
|
|
25
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair(compressed=true)
|
|
26
|
+
signature = Bitcoin::Secp256k1.sign_compact("derp", priv, compressed=true)
|
|
27
|
+
signature.bytesize.should == 65
|
|
28
|
+
pub2 = Bitcoin::Secp256k1.recover_compact("derp", signature)
|
|
29
|
+
pub2.bytesize.should == 33
|
|
30
|
+
pub2.should == pub
|
|
31
|
+
|
|
32
|
+
# uncompressed
|
|
33
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair(compressed=false)
|
|
34
|
+
signature = Bitcoin::Secp256k1.sign_compact("derp", priv, compressed=false)
|
|
35
|
+
signature.bytesize.should == 65
|
|
36
|
+
pub2 = Bitcoin::Secp256k1.recover_compact("derp", signature)
|
|
37
|
+
pub2.bytesize.should == 65
|
|
38
|
+
pub2.should == pub
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'deterministic signature using rfc6979' do
|
|
42
|
+
priv, pub = Bitcoin::Secp256k1.generate_key_pair
|
|
43
|
+
first = Bitcoin::Secp256k1.sign("derp", priv)
|
|
44
|
+
second = Bitcoin::Secp256k1.sign("derp", priv)
|
|
45
|
+
first.should == second
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
data/spec/bitcoin/spec_helper.rb
CHANGED
|
@@ -9,8 +9,6 @@ begin
|
|
|
9
9
|
["bitcoin.rb", "opcodes.rb", "script.rb", "key.rb"].include?(file.filename.split("/").last)
|
|
10
10
|
end
|
|
11
11
|
add_group "Protocol", "lib/bitcoin/protocol"
|
|
12
|
-
add_group "Storage", "lib/bitcoin/storage"
|
|
13
|
-
add_group "Wallet", "lib/bitcoin/wallet"
|
|
14
12
|
add_group("Utilities") do |file|
|
|
15
13
|
["logger.rb", "openssl.rb"].include?(file.filename.split("/").last)
|
|
16
14
|
end
|
|
@@ -49,33 +47,6 @@ def create_block prev, store = true, tx = [], key = Bitcoin::Key.generate, coinb
|
|
|
49
47
|
block
|
|
50
48
|
end
|
|
51
49
|
|
|
52
|
-
# create transaction given builder +tx+
|
|
53
|
-
# +outputs+ is an array of [value, key] pairs
|
|
54
|
-
def create_tx(tx, prev_tx, prev_out_index, outputs, key = @key)
|
|
55
|
-
tx.input {|i| i.prev_out prev_tx; i.prev_out_index prev_out_index; i.signature_key key }
|
|
56
|
-
outputs.each do |value, key|
|
|
57
|
-
tx.output {|o| o.value value; o.script {|s| s.recipient key.addr } }
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# create a chain of +n+ blocks, based on +prev_hash+ block.
|
|
62
|
-
# influence chain properties via options:
|
|
63
|
-
# time: start time all other times are based on
|
|
64
|
-
# interval: time between blocks
|
|
65
|
-
# bits: target bits each block must match
|
|
66
|
-
def create_blocks prev_hash, n, opts = {}
|
|
67
|
-
interval = opts[:interval] || 600
|
|
68
|
-
time = opts[:time] || Time.now.to_i
|
|
69
|
-
bits = opts[:bits] || 553713663
|
|
70
|
-
block = @store.get_block(prev_hash)
|
|
71
|
-
n.times do |i|
|
|
72
|
-
block = create_block block.hash, true, [], @key, 50e8, {
|
|
73
|
-
time: time += interval, bits: bits }
|
|
74
|
-
# block = @store.get_block(block.hash)
|
|
75
|
-
# puts "#{i} #{block.hash[0..8]} #{block.prev_block.reverse_hth[0..8]} #{Time.at(block.time).strftime('%Y-%m-%d %H:%M:%S')} c: #{block.chain} b: #{block.bits} n: #{block.nonce} w: #{block.work}"
|
|
76
|
-
end
|
|
77
|
-
block
|
|
78
|
-
end
|
|
79
50
|
|
|
80
51
|
|
|
81
52
|
Bitcoin::network = :bitcoin
|
|
@@ -112,28 +83,6 @@ end
|
|
|
112
83
|
Bacon.summary_on_exit
|
|
113
84
|
require 'minitest/mock'
|
|
114
85
|
|
|
115
|
-
require 'sequel'
|
|
116
|
-
def setup_db backend, db = nil, conf = {}
|
|
117
|
-
uri = case db
|
|
118
|
-
when :sqlite
|
|
119
|
-
"sqlite:/"
|
|
120
|
-
when :postgres
|
|
121
|
-
ENV["TEST_DB_POSTGRES"].dup rescue nil
|
|
122
|
-
when :mysql
|
|
123
|
-
ENV["TEST_DB_MYSQL"].dup rescue nil
|
|
124
|
-
end
|
|
125
|
-
if [:postgres, :mysql].include?(db)
|
|
126
|
-
unless uri
|
|
127
|
-
puts "Skipping #{db} tests"
|
|
128
|
-
return nil
|
|
129
|
-
end
|
|
130
|
-
db = Sequel.connect(uri)
|
|
131
|
-
db.drop_table(*db.tables, cascade: true)
|
|
132
|
-
end
|
|
133
|
-
Bitcoin::Storage.send(backend, conf.merge(db: uri, log_level: :warn))
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
|
|
137
86
|
class Time
|
|
138
87
|
class << self
|
|
139
88
|
alias_method :real_new, :new
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Bitcoin::Trezor::Mnemonic" do
|
|
4
|
+
|
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#Test_vectors
|
|
6
|
+
# https://github.com/trezor/python-mnemonic/blob/master/vectors.json
|
|
7
|
+
|
|
8
|
+
it "test vectors" do
|
|
9
|
+
[
|
|
10
|
+
[
|
|
11
|
+
"00000000000000000000000000000000",
|
|
12
|
+
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
13
|
+
"c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04"
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
|
17
|
+
"legal winner thank year wave sausage worth useful legal winner thank yellow",
|
|
18
|
+
"2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607"
|
|
19
|
+
],
|
|
20
|
+
[
|
|
21
|
+
"80808080808080808080808080808080",
|
|
22
|
+
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
|
23
|
+
"d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8"
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
"ffffffffffffffffffffffffffffffff",
|
|
27
|
+
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
|
28
|
+
"ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069"
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
"000000000000000000000000000000000000000000000000",
|
|
32
|
+
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
|
33
|
+
"035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa"
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
|
37
|
+
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
|
|
38
|
+
"f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd"
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"808080808080808080808080808080808080808080808080",
|
|
42
|
+
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
|
|
43
|
+
"107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65"
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"ffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
47
|
+
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
|
|
48
|
+
"0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528"
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
52
|
+
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
|
53
|
+
"bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8"
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
|
57
|
+
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
|
|
58
|
+
"bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87"
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"8080808080808080808080808080808080808080808080808080808080808080",
|
|
62
|
+
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
|
|
63
|
+
"c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f"
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
67
|
+
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
|
|
68
|
+
"dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad"
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
"77c2b00716cec7213839159e404db50d",
|
|
72
|
+
"jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge",
|
|
73
|
+
"b5b6d0127db1a9d2226af0c3346031d77af31e918dba64287a1b44b8ebf63cdd52676f672a290aae502472cf2d602c051f3e6f18055e84e4c43897fc4e51a6ff"
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
"b63a9c59a6e641f288ebc103017f1da9f8290b3da6bdef7b",
|
|
77
|
+
"renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
|
|
78
|
+
"9248d83e06f4cd98debf5b6f010542760df925ce46cf38a1bdb4e4de7d21f5c39366941c69e1bdbf2966e0f6e6dbece898a0e2f0a4c2b3e640953dfe8b7bbdc5"
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"3e141609b97933b66a060dcddc71fad1d91677db872031e85f4c015c5e7e8982",
|
|
82
|
+
"dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
|
|
83
|
+
"ff7f3184df8696d8bef94b6c03114dbee0ef89ff938712301d27ed8336ca89ef9635da20af07d4175f2bf5f3de130f39c9d9e8dd0472489c19b1a020a940da67"
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
"0460ef47585604c5660618db2e6a7e7f",
|
|
87
|
+
"afford alter spike radar gate glance object seek swamp infant panel yellow",
|
|
88
|
+
"65f93a9f36b6c85cbe634ffc1f99f2b82cbb10b31edc7f087b4f6cb9e976e9faf76ff41f8f27c99afdf38f7a303ba1136ee48a4c1e7fcd3dba7aa876113a36e4"
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
"72f60ebac5dd8add8d2a25a797102c3ce21bc029c200076f",
|
|
92
|
+
"indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
|
|
93
|
+
"3bbf9daa0dfad8229786ace5ddb4e00fa98a044ae4c4975ffd5e094dba9e0bb289349dbe2091761f30f382d4e35c4a670ee8ab50758d2c55881be69e327117ba"
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"2c85efc7f24ee4573d2b81a6ec66cee209b2dcbd09d8eddc51e0215b0b68e416",
|
|
97
|
+
"clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
|
|
98
|
+
"fe908f96f46668b2d5b37d82f558c77ed0d69dd0e7e043a5b0511c48c2f1064694a956f86360c93dd04052a8899497ce9e985ebe0c8c52b955e6ae86d4ff4449"
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"eaebabb2383351fd31d703840b32e9e2",
|
|
102
|
+
"turtle front uncle idea crush write shrug there lottery flower risk shell",
|
|
103
|
+
"bdfb76a0759f301b0b899a1e3985227e53b3f51e67e3f2a65363caedf3e32fde42a66c404f18d7b05818c95ef3ca1e5146646856c461c073169467511680876c"
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
"7ac45cfe7722ee6c7ba84fbc2d5bd61b45cb2fe5eb65aa78",
|
|
107
|
+
"kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
|
|
108
|
+
"ed56ff6c833c07982eb7119a8f48fd363c4a9b1601cd2de736b01045c5eb8ab4f57b079403485d1c4924f0790dc10a971763337cb9f9c62226f64fff26397c79"
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"4fa1a8bc3e6d80ee1316050e862c1812031493212b7ec3f3bb1b08f168cabeef",
|
|
112
|
+
"exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
|
|
113
|
+
"095ee6f817b4c2cb30a5a797360a81a40ab0f9a4e25ecd672a3f58a0b5ba0687c096a6b14d2c0deb3bdefce4f61d01ae07417d502429352e27695163f7447a8c"
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
"18ab19a9f54a9274f03e5209a2ac8a91",
|
|
117
|
+
"board flee heavy tunnel powder denial science ski answer betray cargo cat",
|
|
118
|
+
"6eff1bb21562918509c73cb990260db07c0ce34ff0e3cc4a8cb3276129fbcb300bddfe005831350efd633909f476c45c88253276d9fd0df6ef48609e8bb7dca8"
|
|
119
|
+
],
|
|
120
|
+
[
|
|
121
|
+
"18a2e1d81b8ecfb2a333adcb0c17a5b9eb76cc5d05db91a4",
|
|
122
|
+
"board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
|
|
123
|
+
"f84521c777a13b61564234bf8f8b62b3afce27fc4062b51bb5e62bdfecb23864ee6ecf07c1d5a97c0834307c5c852d8ceb88e7c97923c0a3b496bedd4e5f88a9"
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419",
|
|
127
|
+
"beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
|
|
128
|
+
"b15509eaa2d09d3efd3e006ef42151b30367dc6e3aa5e44caba3fe4d3e352e65101fbdb86a96776b91946ff06f8eac594dc6ee1d3e82a42dfe1b40fef6bcc3fd"
|
|
129
|
+
]
|
|
130
|
+
].each{|data,expected_mnemonic,expected_seed|
|
|
131
|
+
mnemonic = Bitcoin::Trezor::Mnemonic.to_mnemonic( [data].pack("H*") )
|
|
132
|
+
mnemonic.should == expected_mnemonic
|
|
133
|
+
Bitcoin::Trezor::Mnemonic.to_seed(expected_mnemonic, 'TREZOR').should == expected_seed
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
=begin
|
|
138
|
+
it 'test utf8 nfkd' do
|
|
139
|
+
# The same sentence in various UTF-8 forms
|
|
140
|
+
words_nfkd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
|
141
|
+
words_nfc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
|
142
|
+
words_nfkc = "P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
|
143
|
+
words_nfd = "Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
|
144
|
+
|
|
145
|
+
passphrase_nfkd = "Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
|
146
|
+
passphrase_nfc = "Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
|
147
|
+
passphrase_nfkc = "Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
|
148
|
+
passphrase_nfd = "Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
|
149
|
+
|
|
150
|
+
seed_nfkd = Bitcoin::Trezor::Mnemonic.to_seed(words_nfkd, passphrase_nfkd)
|
|
151
|
+
seed_nfc = Bitcoin::Trezor::Mnemonic.to_seed(words_nfc, passphrase_nfc)
|
|
152
|
+
seed_nfkc = Bitcoin::Trezor::Mnemonic.to_seed(words_nfkc, passphrase_nfkc)
|
|
153
|
+
seed_nfd = Bitcoin::Trezor::Mnemonic.to_seed(words_nfd, passphrase_nfd)
|
|
154
|
+
|
|
155
|
+
seed_nfkd.should == seed_nfc
|
|
156
|
+
seed_nfkd.should == seed_nfkc
|
|
157
|
+
seed_nfkd.should == seed_nfd
|
|
158
|
+
end
|
|
159
|
+
=end
|
|
160
|
+
|
|
161
|
+
end
|