bitcoin-cigs 0.0.3 → 0.0.4
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.
- data/Gemfile.lock +1 -1
- data/README.md +35 -2
- data/lib/bitcoin-cigs.rb +1 -1
- data/lib/bitcoin_cigs.rb +43 -38
- data/lib/bitcoin_cigs/base_58.rb +66 -27
- data/lib/bitcoin_cigs/version.rb +1 -1
- data/spec/bitcoin_cigs/base_58_spec.rb +2 -2
- data/spec/bitcoin_cigs_spec.rb +65 -12
- metadata +3 -3
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,9 +2,42 @@
|
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
5
|
-
|
5
|
+
```sh
|
6
|
+
~$ gem install bitcoin-cigs
|
7
|
+
```
|
8
|
+
|
9
|
+
## Command Line
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
```sh
|
13
|
+
~$ bitcoin-cigs
|
14
|
+
Usage: bitcoin-cigs command [arguments ...] [options ...]
|
15
|
+
|
16
|
+
Commands
|
17
|
+
verify bitcoin-address signature [message-file]
|
18
|
+
sign private-key [message-file]
|
19
|
+
|
20
|
+
Options
|
21
|
+
-m, --message MESSAGE Message can also be read from STDIN
|
22
|
+
-S, --no-strip Do not strip leading and trailing whitespace from message (stripped by default)
|
23
|
+
```
|
24
|
+
|
25
|
+
Examples:
|
26
|
+
```sh
|
27
|
+
~$ # Sign with -m message parameter
|
28
|
+
~$ bitcoin-cigs sign 5JFZuDkLgbEXK4CUEiXyyz4fUqzAsQ5QUqufdJy8MoLA9S1RdNX -m 'this is a message'
|
29
|
+
HIBYi2g3yFimzD/YSD9j+PYwtsdCuHR2xwIQ6n0AN6RPUVDGttgOmlnsiwx90ZSjmaWrH1/HwrINJbaP7eMA6V4=
|
30
|
+
~$
|
31
|
+
~$ # Verify with message from STDIN
|
32
|
+
~$ echo 'this is a message' | bitcoin-cigs verify 11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9 HIBYi2g3yFimzD/YSD9j+PYwtsdCuHR2xwIQ6n0AN6RPUVDGttgOmlnsiwx90ZSjmaWrH1/HwrINJbaP7eMA6V4=
|
33
|
+
~$
|
34
|
+
~$ # Verify with message from file
|
35
|
+
~$ echo 'this is a message' > message.txt
|
36
|
+
~$ bitcoin-cigs verify 11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9 HIBYi2g3yFimzD/YSD9j+PYwtsdCuHR2xwIQ6n0AN6RPUVDGttgOmlnsiwx90ZSjmaWrH1/HwrINJbaP7eMA6V4= message.txt
|
37
|
+
~$
|
38
|
+
```
|
6
39
|
|
7
|
-
##
|
40
|
+
## Ruby API
|
8
41
|
|
9
42
|
Sign a message:
|
10
43
|
```ruby
|
data/lib/bitcoin-cigs.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'bitcoin_cigs'
|
1
|
+
require File.join(File.dirname(__FILE__), 'bitcoin_cigs.rb')
|
data/lib/bitcoin_cigs.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
|
2
|
-
require 'bitcoin_cigs
|
3
|
-
|
4
|
-
require 'bitcoin_cigs/curve_fp'
|
5
|
-
require 'bitcoin_cigs/point'
|
6
|
-
require 'bitcoin_cigs/public_key'
|
7
|
-
require 'bitcoin_cigs/private_key'
|
8
|
-
require 'bitcoin_cigs/signature'
|
9
|
-
require 'bitcoin_cigs/ec_key'
|
1
|
+
%w(error crypto_helper base_58 curve_fp point public_key private_key signature ec_key).each do |f|
|
2
|
+
require File.join(File.dirname(__FILE__), 'bitcoin_cigs', f)
|
3
|
+
end
|
10
4
|
|
11
5
|
module BitcoinCigs
|
12
|
-
PRIVATE_KEY_PREFIX =
|
6
|
+
PRIVATE_KEY_PREFIX = {
|
7
|
+
:mainnet => 0x80,
|
8
|
+
:testnet => 0xEF
|
9
|
+
}
|
10
|
+
NETWORK_VERSION = {
|
11
|
+
:mainnet => 0x00,
|
12
|
+
:testnet => 0x6F
|
13
|
+
}
|
13
14
|
|
14
15
|
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
|
15
16
|
R = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
@@ -24,17 +25,19 @@ module BitcoinCigs
|
|
24
25
|
class << self
|
25
26
|
include ::BitcoinCigs::CryptoHelper
|
26
27
|
|
27
|
-
def verify_message(address, signature, message)
|
28
|
+
def verify_message(address, signature, message, options = {:network => :mainnet})
|
28
29
|
begin
|
29
|
-
verify_message!(address, signature, message)
|
30
|
+
verify_message!(address, signature, message, options)
|
30
31
|
true
|
31
32
|
rescue ::BitcoinCigs::Error
|
32
33
|
false
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
def verify_message!(address, signature, message)
|
37
|
-
|
37
|
+
def verify_message!(address, signature, message, options = {:network => :mainnet})
|
38
|
+
decoded_address = decode58(address)
|
39
|
+
raise ::BitcoinCigs::Error.new("Incorrect address or message for signature.") if decoded_address.nil?
|
40
|
+
network_version = str_to_num(decoded_address) >> (8 * 24)
|
38
41
|
|
39
42
|
message = calculate_hash(format_message_to_sign(message))
|
40
43
|
|
@@ -79,29 +82,29 @@ module BitcoinCigs
|
|
79
82
|
|
80
83
|
|
81
84
|
public_key = ::BitcoinCigs::PublicKey.new(g, q, compressed)
|
82
|
-
addr = public_key_to_bc_address(public_key.ser(),
|
85
|
+
addr = public_key_to_bc_address(public_key.ser(), NETWORK_VERSION[options[:network]])
|
83
86
|
raise ::BitcoinCigs::Error.new("Incorrect address or message for signature.") if address != addr
|
84
87
|
|
85
88
|
nil
|
86
89
|
end
|
87
90
|
|
88
|
-
def sign_message(wallet_key, message)
|
91
|
+
def sign_message(wallet_key, message, options = {:network => :mainnet})
|
89
92
|
begin
|
90
|
-
sign_message!(wallet_key, message)
|
93
|
+
sign_message!(wallet_key, message, options)
|
91
94
|
rescue ::BitcoinCigs::Error
|
92
95
|
nil
|
93
96
|
end
|
94
97
|
end
|
95
98
|
|
96
|
-
def sign_message!(wallet_key, message)
|
97
|
-
private_key = convert_wallet_format_to_bytes!(wallet_key)
|
99
|
+
def sign_message!(wallet_key, message, options = {:network => :mainnet})
|
100
|
+
private_key = convert_wallet_format_to_bytes!(wallet_key, options[:network])
|
98
101
|
|
99
102
|
msg_hash = sha256(sha256(format_msg_to_sign(message)))
|
100
103
|
|
101
104
|
ec_key = ::BitcoinCigs::EcKey.new(str_to_num(private_key))
|
102
105
|
private_key = ec_key.private_key
|
103
106
|
public_key = ec_key.public_key
|
104
|
-
addr = public_key_to_bc_address(get_pub_key(ec_key, ec_key.public_key.compressed))
|
107
|
+
addr = public_key_to_bc_address(get_pub_key(ec_key, ec_key.public_key.compressed), NETWORK_VERSION[options[:network]])
|
105
108
|
|
106
109
|
sig = private_key.sign(msg_hash, random_k)
|
107
110
|
raise ::BitcoinCigs::Error.new("Unable to sign message") unless public_key.verify(msg_hash, sig)
|
@@ -113,7 +116,7 @@ module BitcoinCigs
|
|
113
116
|
sign_64 = encode64(sign)
|
114
117
|
|
115
118
|
begin
|
116
|
-
verify_message!(addr, sign_64, message)
|
119
|
+
verify_message!(addr, sign_64, message, options)
|
117
120
|
return sign_64
|
118
121
|
rescue ::BitcoinCigs::Error
|
119
122
|
next
|
@@ -123,11 +126,11 @@ module BitcoinCigs
|
|
123
126
|
raise ::BitcoinCigs::Error, "Unable to construct recoverable key"
|
124
127
|
end
|
125
128
|
|
126
|
-
def convert_wallet_format_to_bytes!(input)
|
127
|
-
bytes = if is_wallet_import_format?(input)
|
128
|
-
decode_wallet_import_format(input)
|
129
|
-
elsif is_compressed_wallet_import_format?(input)
|
130
|
-
decode_compressed_wallet_import_format(input)
|
129
|
+
def convert_wallet_format_to_bytes!(input, network)
|
130
|
+
bytes = if is_wallet_import_format?(input, network)
|
131
|
+
decode_wallet_import_format(input, network)
|
132
|
+
elsif is_compressed_wallet_import_format?(input, network)
|
133
|
+
decode_compressed_wallet_import_format(input, network)
|
131
134
|
elsif is_mini_format?(input)
|
132
135
|
sha256(input)
|
133
136
|
elsif is_hex_format?(input)
|
@@ -170,28 +173,30 @@ module BitcoinCigs
|
|
170
173
|
decode_hex(key)
|
171
174
|
end
|
172
175
|
|
173
|
-
def decode_wallet_import_format(input)
|
174
|
-
bytes = decode58(input)[1..-1]
|
176
|
+
def decode_wallet_import_format(input, network)
|
177
|
+
bytes = decode58(input)#[1..-1]
|
178
|
+
#puts "ASDF #{bytes.unpack('H*')}"
|
179
|
+
#puts bytes.bytes.collect {|e| e.to_i}.join(" ")
|
175
180
|
hash = bytes[0..32]
|
176
181
|
|
177
182
|
checksum = sha256(sha256(hash))
|
178
|
-
raise ::BitcoinCigs::Error.new("Wallet checksum invalid") if bytes[33
|
183
|
+
raise ::BitcoinCigs::Error.new("Wallet checksum invalid") if bytes[33..37] != checksum[0..3]
|
179
184
|
|
180
185
|
version, hash = hash[0], hash[1..-1]
|
181
|
-
raise ::BitcoinCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX
|
186
|
+
raise ::BitcoinCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX[network]
|
182
187
|
|
183
188
|
hash
|
184
189
|
end
|
185
190
|
|
186
|
-
def decode_compressed_wallet_import_format(input)
|
191
|
+
def decode_compressed_wallet_import_format(input, network)
|
187
192
|
bytes = decode58(input)
|
188
193
|
hash = bytes[0...34]
|
189
194
|
|
190
195
|
checksum = sha256(sha256(hash))
|
191
|
-
raise ::BitcoinCigs::Error.new("Wallet checksum invalid") if bytes[34
|
196
|
+
raise ::BitcoinCigs::Error.new("Wallet checksum invalid") if bytes[34..37] != checksum[0..3]
|
192
197
|
|
193
198
|
version, hash = hash[0], hash[1..32]
|
194
|
-
raise ::BitcoinCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX
|
199
|
+
raise ::BitcoinCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX[network]
|
195
200
|
|
196
201
|
hash
|
197
202
|
end
|
@@ -202,13 +207,13 @@ module BitcoinCigs
|
|
202
207
|
end
|
203
208
|
|
204
209
|
# 51 characters base58 starting with 5
|
205
|
-
def is_wallet_import_format?(key)
|
206
|
-
|
210
|
+
def is_wallet_import_format?(key, network)
|
211
|
+
/^#{network == :mainnet ? '5' : '9'}[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/ =~ key
|
207
212
|
end
|
208
213
|
|
209
214
|
# 52 characters base58 starting with L or K
|
210
|
-
def is_compressed_wallet_import_format?(key)
|
211
|
-
/^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/ =~ key
|
215
|
+
def is_compressed_wallet_import_format?(key, network)
|
216
|
+
/^[network == :mainnet ? 'LK' : 'c'][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/ =~ key
|
212
217
|
end
|
213
218
|
|
214
219
|
# 44 characters
|
@@ -239,7 +244,7 @@ module BitcoinCigs
|
|
239
244
|
"\x18Bitcoin Signed Message:\n#{message.length.chr}#{message}"
|
240
245
|
end
|
241
246
|
|
242
|
-
def public_key_to_bc_address(public_key, network_version
|
247
|
+
def public_key_to_bc_address(public_key, network_version)
|
243
248
|
h160 = hash_160(public_key)
|
244
249
|
|
245
250
|
hash_160_to_bc_address(h160, network_version)
|
data/lib/bitcoin_cigs/base_58.rb
CHANGED
@@ -4,42 +4,81 @@ module BitcoinCigs
|
|
4
4
|
CHAR_SIZE = CHARS.size
|
5
5
|
|
6
6
|
def self.decode(s)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
mod = value % 256
|
13
|
-
result.unshift(mod.chr)
|
14
|
-
value = div
|
7
|
+
int_val = 0
|
8
|
+
s.reverse.split('').each_with_index do |char, index|
|
9
|
+
char_index = CHARS.index(char)
|
10
|
+
return nil if char_index.nil?
|
11
|
+
int_val += char_index * (CHAR_SIZE ** index)
|
15
12
|
end
|
16
|
-
result.unshift(value.chr)
|
17
|
-
|
18
|
-
pad_size = s.chars.inject(0) { |acc, ch| acc + (CHARS[0] == ch ? 1 : 0) }
|
19
13
|
|
20
|
-
|
14
|
+
leading_zeros = /^#{CHARS[0]}*/.match(s).to_s.size
|
21
15
|
|
22
|
-
|
16
|
+
["#{"\x00\x00" * leading_zeros}#{int_val.to_s(16)}"].pack('H*')
|
23
17
|
end
|
24
18
|
|
25
19
|
def self.encode(s)
|
26
|
-
|
20
|
+
int_val = s.unpack('H*').first.to_i(16)
|
27
21
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
result.unshift(CHARS[mod])
|
34
|
-
value = div
|
22
|
+
base58_val = ''
|
23
|
+
while int_val >= CHAR_SIZE
|
24
|
+
mod = int_val % CHAR_SIZE
|
25
|
+
base58_val = CHARS[mod,1] + base58_val
|
26
|
+
int_val = (int_val - mod) / CHAR_SIZE
|
35
27
|
end
|
36
|
-
result.unshift(CHARS[value])
|
37
|
-
|
38
|
-
pad_size = s.chars.inject(0) { |acc, ch| acc + (ch == "\0" ? 1 : 0) }
|
39
28
|
|
40
|
-
result
|
41
|
-
|
42
|
-
|
29
|
+
result = CHARS[int_val, 1] + base58_val
|
30
|
+
|
31
|
+
s.chars.each do |char|
|
32
|
+
if char == "\x00"
|
33
|
+
result = CHARS[0] + result
|
34
|
+
else
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
result
|
43
40
|
end
|
41
|
+
|
42
|
+
# def self.encode(s)
|
43
|
+
# int_val = s.unpack('H*').first.to_i(16)
|
44
|
+
#
|
45
|
+
# var bi = BigInteger.fromByteArrayUnsigned(input);
|
46
|
+
# var chars = [];
|
47
|
+
#
|
48
|
+
# while (bi.compareTo(B58.base) >= 0) {
|
49
|
+
# var mod = bi.mod(B58.base);
|
50
|
+
# chars.unshift(B58.alphabet[mod.intValue()]);
|
51
|
+
# bi = bi.subtract(mod).divide(B58.base);
|
52
|
+
# }
|
53
|
+
# chars.unshift(B58.alphabet[bi.intValue()]);
|
54
|
+
#
|
55
|
+
# for (var i = 0; i < input.length; i++) {
|
56
|
+
# if (input[i] == 0x00) {
|
57
|
+
# chars.unshift(B58.alphabet[0]);
|
58
|
+
# } else break;
|
59
|
+
# }
|
60
|
+
#
|
61
|
+
# return chars.join('');
|
62
|
+
# end
|
63
|
+
|
64
|
+
# def self.encode(s)
|
65
|
+
# value = 0
|
66
|
+
#
|
67
|
+
# value = s.chars.reverse_each.each_with_index.inject(0) { |acc, (ch, i)| acc + (256 ** i) * ch.ord }
|
68
|
+
#
|
69
|
+
# result = []
|
70
|
+
# while value >= CHAR_SIZE
|
71
|
+
# div, mod = value / CHAR_SIZE, value % CHAR_SIZE
|
72
|
+
# result.unshift(CHARS[mod])
|
73
|
+
# value = div
|
74
|
+
# end
|
75
|
+
# result.unshift(CHARS[value])
|
76
|
+
#
|
77
|
+
# pad_size = s.chars.inject(0) { |acc, ch| acc + (ch == "\0" ? 1 : 0) }
|
78
|
+
#
|
79
|
+
# result.unshift(CHARS[0] * pad_size)
|
80
|
+
#
|
81
|
+
# result.join
|
82
|
+
# end
|
44
83
|
end
|
45
84
|
end
|
data/lib/bitcoin_cigs/version.rb
CHANGED
@@ -9,13 +9,13 @@ describe BitcoinCigs::Base58 do
|
|
9
9
|
|
10
10
|
context "with valid data" do
|
11
11
|
it "decodes properly" do
|
12
|
-
expect(
|
12
|
+
expect(subject.unpack('H*').first).to eq("001808678bea2510c902a6cc3cd28ac0734516031620933591")
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe "encode" do
|
18
|
-
let(:data) {
|
18
|
+
let(:data) { ["001808678bea2510c902a6cc3cd28ac0734516031620933591"].pack('H*') }
|
19
19
|
|
20
20
|
subject { BitcoinCigs::Base58.encode(data) }
|
21
21
|
|
data/spec/bitcoin_cigs_spec.rb
CHANGED
@@ -1,20 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BitcoinCigs do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def self.use_mainnet
|
5
|
+
let(:wallet_key) { "5JFZuDkLgbEXK4CUEiXyyz4fUqzAsQ5QUqufdJy8MoLA9S1RdNX" }
|
6
|
+
let(:address) { "11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9" }
|
7
|
+
let(:original_address) { "11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9" }
|
8
|
+
let(:private_key) { ["39678A14ECA8479B3C58DCD25A5C94BE768389E823435C4DDFCAEB13519AB10E"].pack('H*') }
|
9
|
+
let(:signature) { "HIBYi2g3yFimzD/YSD9j+PYwtsdCuHR2xwIQ6n0AN6RPUVDGttgOmlnsiwx90ZSjmaWrH1/HwrINJbaP7eMA6V4=" }
|
10
|
+
let(:network) { :mainnet }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.use_testnet
|
14
|
+
let(:wallet_key) { "92FqDytA43K8unrrZgpzMddhmEbMMRNhBJAU59a3MkYfsUgH8st" }
|
15
|
+
let(:address) { "mh9nRF1ZSqLJB3hbUjPLmfDHdnGUURdYdK" }
|
16
|
+
let(:original_address) { "mh9nRF1ZSqLJB3hbUjPLmfDHdnGUURdYdK" }
|
17
|
+
let(:private_key) { ["585C660C887913E5F40B8E34D99C62766443F9D043B1DE1DFDCC94E386BC6DF6"].pack('H*') }
|
18
|
+
let(:signature) { "HIZQbBLAGJLhSZ310FCQMAo9l1X2ysxyt0kXkf6KcBN3znl2iClC6V9wz9Nkn6mMDUaq4kRlgYQDUUlsm29Bl0o=" }
|
19
|
+
let(:network) { :testnet }
|
20
|
+
end
|
9
21
|
|
22
|
+
use_mainnet
|
10
23
|
let(:message) { "this is a message" }
|
11
24
|
|
12
25
|
describe "sign_message!" do
|
13
|
-
subject { BitcoinCigs.sign_message!(wallet_key, message) }
|
26
|
+
subject { BitcoinCigs.sign_message!(wallet_key, message, :network => network) }
|
14
27
|
|
15
28
|
context "with valid data" do
|
16
29
|
it "generates the correct signature" do
|
17
|
-
expect(BitcoinCigs.verify_message(address, subject, message)).to be_true
|
30
|
+
expect(BitcoinCigs.verify_message(address, subject, message, :network => network)).to be_true
|
18
31
|
end
|
19
32
|
end
|
20
33
|
|
@@ -25,6 +38,16 @@ describe BitcoinCigs do
|
|
25
38
|
expect { subject }.to raise_error(::BitcoinCigs::Error, "Unknown Wallet Format")
|
26
39
|
end
|
27
40
|
end
|
41
|
+
|
42
|
+
context "with testnet" do
|
43
|
+
use_testnet
|
44
|
+
|
45
|
+
context "with valid data" do
|
46
|
+
it "generates the correct signature" do
|
47
|
+
expect(BitcoinCigs.verify_message(address, subject, message, :network => network)).to be_true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
28
51
|
end
|
29
52
|
|
30
53
|
describe "sign_message" do
|
@@ -46,7 +69,7 @@ describe BitcoinCigs do
|
|
46
69
|
end
|
47
70
|
|
48
71
|
describe "convert_wallet_format_to_bytes!" do
|
49
|
-
subject { BitcoinCigs.convert_wallet_format_to_bytes!(wallet_key) }
|
72
|
+
subject { BitcoinCigs.convert_wallet_format_to_bytes!(wallet_key, network) }
|
50
73
|
|
51
74
|
context "with wallet import format" do
|
52
75
|
let(:wallet_key) { "5JFZuDkLgbEXK4CUEiXyyz4fUqzAsQ5QUqufdJy8MoLA9S1RdNX" }
|
@@ -54,6 +77,16 @@ describe BitcoinCigs do
|
|
54
77
|
it "converts to correct bytes" do
|
55
78
|
expect(subject).to eq(private_key)
|
56
79
|
end
|
80
|
+
|
81
|
+
context "with testnet" do
|
82
|
+
use_testnet
|
83
|
+
|
84
|
+
let(:wallet_key) { "92FqDytA43K8unrrZgpzMddhmEbMMRNhBJAU59a3MkYfsUgH8st" }
|
85
|
+
|
86
|
+
it "converts to correct bytes" do
|
87
|
+
expect(subject).to eq(private_key)
|
88
|
+
end
|
89
|
+
end
|
57
90
|
end
|
58
91
|
|
59
92
|
context "with compressed wallet import format" do
|
@@ -62,6 +95,16 @@ describe BitcoinCigs do
|
|
62
95
|
it "converts to correct bytes" do
|
63
96
|
expect(subject).to eq(private_key)
|
64
97
|
end
|
98
|
+
|
99
|
+
context "with testnet" do
|
100
|
+
use_testnet
|
101
|
+
|
102
|
+
let(:wallet_key) { "cQYTrJ4nxRD3v1R3mGnpA4gzvEzcq8akLSknVJpqQbCnZeD6WfNC" }
|
103
|
+
|
104
|
+
it "converts to correct bytes" do
|
105
|
+
expect(subject).to eq(private_key)
|
106
|
+
end
|
107
|
+
end
|
65
108
|
end
|
66
109
|
|
67
110
|
context "with mini format" do
|
@@ -91,7 +134,7 @@ describe BitcoinCigs do
|
|
91
134
|
end
|
92
135
|
|
93
136
|
describe "verify_message!" do
|
94
|
-
subject { BitcoinCigs.verify_message!(address, signature, message) }
|
137
|
+
subject { BitcoinCigs.verify_message!(address, signature, message, :network => network) }
|
95
138
|
|
96
139
|
context "with valid data" do
|
97
140
|
it "verifies valid message" do
|
@@ -122,13 +165,23 @@ describe BitcoinCigs do
|
|
122
165
|
expect { subject }.to raise_error(::BitcoinCigs::Error, "Incorrect address or message for signature.")
|
123
166
|
end
|
124
167
|
end
|
168
|
+
|
169
|
+
context "with testnet" do
|
170
|
+
use_testnet
|
171
|
+
|
172
|
+
context "with valid data" do
|
173
|
+
it "verifies valid message" do
|
174
|
+
expect(subject).to be_nil
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
125
178
|
end
|
126
179
|
|
127
|
-
describe "verify_message
|
180
|
+
describe "verify_message" do
|
128
181
|
subject { BitcoinCigs.verify_message(address, signature, message) }
|
129
182
|
|
130
183
|
context "with valid data" do
|
131
|
-
it "
|
184
|
+
it "returns true" do
|
132
185
|
expect(subject).to be_true
|
133
186
|
end
|
134
187
|
end
|
@@ -136,7 +189,7 @@ describe BitcoinCigs do
|
|
136
189
|
context "with invalid data" do
|
137
190
|
let(:address) { "invalid" }
|
138
191
|
|
139
|
-
it "
|
192
|
+
it "returns false" do
|
140
193
|
expect(subject).to be_false
|
141
194
|
end
|
142
195
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoin-cigs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -96,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
96
|
version: '0'
|
97
97
|
requirements: []
|
98
98
|
rubyforge_project: bitcoin-cigs
|
99
|
-
rubygems_version: 1.8.
|
99
|
+
rubygems_version: 1.8.21
|
100
100
|
signing_key:
|
101
101
|
specification_version: 3
|
102
102
|
summary: Create and Verify Bitcoin Signatures
|