bitcoin-ruby 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|