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