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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bitcoin-cigs (0.0.3)
4
+ bitcoin-cigs (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -2,9 +2,42 @@
2
2
 
3
3
  ## Installation
4
4
 
5
- gem install bitcoin-cigs
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
- ## Examples
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
- require 'bitcoin_cigs/error'
2
- require 'bitcoin_cigs/crypto_helper'
3
- require 'bitcoin_cigs/base_58'
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 = 0x80
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
- network_version = str_to_num(decode58(address)) >> (8 * 24)
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(), network_version)
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..-1] != checksum[0...4]
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..-1] != checksum[0...4]
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
- /^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/ =~ key
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 = 0)
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)
@@ -4,42 +4,81 @@ module BitcoinCigs
4
4
  CHAR_SIZE = CHARS.size
5
5
 
6
6
  def self.decode(s)
7
- value = s.chars.reverse_each.each_with_index.inject(0) { |acc, (ch, i)| acc + (CHARS.index(ch) || -1) * (CHAR_SIZE ** i) }
8
-
9
- result = []
10
- while value >= 256
11
- div = value / 256
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
- result.unshift(0.chr * pad_size)
14
+ leading_zeros = /^#{CHARS[0]}*/.match(s).to_s.size
21
15
 
22
- result.join
16
+ ["#{"\x00\x00" * leading_zeros}#{int_val.to_s(16)}"].pack('H*')
23
17
  end
24
18
 
25
19
  def self.encode(s)
26
- value = 0
20
+ int_val = s.unpack('H*').first.to_i(16)
27
21
 
28
- value = s.chars.reverse_each.each_with_index.inject(0) { |acc, (ch, i)| acc + (256 ** i) * ch.ord }
29
-
30
- result = []
31
- while value >= CHAR_SIZE
32
- div, mod = value / CHAR_SIZE, value % CHAR_SIZE
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.unshift(CHARS[0] * pad_size)
41
-
42
- result.join
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
@@ -1,3 +1,3 @@
1
1
  module BitcoinCigs
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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(Base64.encode64(subject).strip).to eq("ABgIZ4vqJRDJAqbMPNKKwHNFFgMWIJM1kQ==")
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) { Base64.decode64("ABgIZ4vqJRDJAqbMPNKKwHNFFgMWIJM1kQ==") }
18
+ let(:data) { ["001808678bea2510c902a6cc3cd28ac0734516031620933591"].pack('H*') }
19
19
 
20
20
  subject { BitcoinCigs::Base58.encode(data) }
21
21
 
@@ -1,20 +1,33 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe BitcoinCigs do
4
- let(:wallet_key) { "5JFZuDkLgbEXK4CUEiXyyz4fUqzAsQ5QUqufdJy8MoLA9S1RdNX" }
5
- let(:address) { "11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9" }
6
- let(:original_address) { "11o51X3ciSjoLWFN3sbg3yzCM8RSuD2q9" }
7
- let(:private_key) { ["39678A14ECA8479B3C58DCD25A5C94BE768389E823435C4DDFCAEB13519AB10E"].pack('H*') }
8
- let(:signature) { "HIBYi2g3yFimzD/YSD9j+PYwtsdCuHR2xwIQ6n0AN6RPUVDGttgOmlnsiwx90ZSjmaWrH1/HwrINJbaP7eMA6V4=" }
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!" do
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 "verifies valid message" do
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 "raises ::BitcoinCigs::Error" do
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.3
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-06-07 00:00:00.000000000 Z
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.25
99
+ rubygems_version: 1.8.21
100
100
  signing_key:
101
101
  specification_version: 3
102
102
  summary: Create and Verify Bitcoin Signatures