digibyte-cigs 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/digibyte_cigs/version.rb +1 -1
- data/lib/digibyte_cigs.rb +56 -56
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb30cdeea76099f93cd78d19402f0eee96b9ce53
|
4
|
+
data.tar.gz: a1e8c4d8c58c0fe09c26eba197644e874080a87a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65402ee938428dce00a4142ac76f1339fc76535d356d31d3eea422ca6da057ba722f313be8a212df95247b6e621c9b2516a8bef676a361a84d8763bc1ff9bcd0
|
7
|
+
data.tar.gz: 62b56d4e6fd99fe1a74038cb5ddbfee0e897b53f266e05fa6bd4db2fc18e520731fbc6d50e8159db50bfb530e434d252cf0d95d08e9d3f70a739c8df95d1542c
|
data/lib/digibyte_cigs.rb
CHANGED
@@ -11,7 +11,7 @@ module DigiByteCigs
|
|
11
11
|
:mainnet => 0x00,
|
12
12
|
:testnet => 0x6F
|
13
13
|
}
|
14
|
-
|
14
|
+
|
15
15
|
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
|
16
16
|
R = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
17
17
|
B = 0x0000000000000000000000000000000000000000000000000000000000000007
|
@@ -21,10 +21,10 @@ module DigiByteCigs
|
|
21
21
|
|
22
22
|
CURVE_SECP256K1 = ::DigiByteCigs::CurveFp.new(P, A, B)
|
23
23
|
GENERATOR_SECP256K1 = ::DigiByteCigs::Point.new(CURVE_SECP256K1, Gx, Gy, R)
|
24
|
-
|
24
|
+
|
25
25
|
class << self
|
26
26
|
include ::DigiByteCigs::CryptoHelper
|
27
|
-
|
27
|
+
|
28
28
|
def verify_message(address, signature, message, options = {:network => :mainnet})
|
29
29
|
begin
|
30
30
|
verify_message!(address, signature, message, options)
|
@@ -33,7 +33,7 @@ module DigiByteCigs
|
|
33
33
|
false
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def verify_message!(address, signature, message, options = {:network => :mainnet})
|
38
38
|
|
39
39
|
decoded_address = decode58(address)
|
@@ -43,7 +43,7 @@ module DigiByteCigs
|
|
43
43
|
addr = get_signature_address!(signature, message, options)
|
44
44
|
|
45
45
|
raise ::DigiByteCigs::Error.new("Incorrect address or message for signature.") if address != addr
|
46
|
-
|
46
|
+
|
47
47
|
nil
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,7 @@ module DigiByteCigs
|
|
52
52
|
get_signature_address!(signature, message, options)
|
53
53
|
rescue ::DigiByteCigs::Error
|
54
54
|
false
|
55
|
-
end
|
55
|
+
end
|
56
56
|
end
|
57
57
|
|
58
58
|
def get_signature_address!(signature, message, options = {:network => :mainnet})
|
@@ -62,25 +62,25 @@ module DigiByteCigs
|
|
62
62
|
curve = CURVE_SECP256K1
|
63
63
|
g = GENERATOR_SECP256K1
|
64
64
|
a, b, p = curve.a, curve.b, curve.p
|
65
|
-
|
65
|
+
|
66
66
|
order = g.order
|
67
|
-
|
67
|
+
|
68
68
|
sig = decode64(signature)
|
69
69
|
raise ::DigiByteCigs::Error.new("Bad signature length") if sig.size != 65
|
70
70
|
raise ::DigiByteCigs::Error.new("Bad characters in signature") if signature != encode64(sig)
|
71
|
-
|
71
|
+
|
72
72
|
hb = sig[0].ord
|
73
73
|
r, s = [sig[1...33], sig[33...65]].collect { |s| str_to_num(s) }
|
74
|
-
|
75
|
-
|
74
|
+
|
75
|
+
|
76
76
|
raise ::DigiByteCigs::Error.new("Bad signature first byte") if hb < 27 || hb >= 35
|
77
|
-
|
77
|
+
|
78
78
|
compressed = false
|
79
79
|
if hb >= 31
|
80
80
|
compressed = true
|
81
81
|
hb -= 4
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
recid = hb - 27
|
85
85
|
x = (r + (recid / 2) * order) % p
|
86
86
|
y2 = ((x ** 3 % p) + a * x + b) % p
|
@@ -90,20 +90,20 @@ module DigiByteCigs
|
|
90
90
|
else
|
91
91
|
y = p - yomy
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
r_point = ::DigiByteCigs::Point.new(curve, x, y, order)
|
95
95
|
e = str_to_num(message)
|
96
96
|
minus_e = -e % order
|
97
|
-
|
97
|
+
|
98
98
|
inv_r = inverse_mod(r, order)
|
99
99
|
q = (r_point * s + g * minus_e) * inv_r
|
100
|
-
|
101
|
-
|
100
|
+
|
101
|
+
|
102
102
|
public_key = ::DigiByteCigs::PublicKey.new(g, q, compressed)
|
103
|
-
|
103
|
+
|
104
104
|
public_key_to_bc_address(public_key.ser(), NETWORK_VERSION[options[:network]])
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
def sign_message(wallet_key, message, options = {:network => :mainnet})
|
108
108
|
begin
|
109
109
|
sign_message!(wallet_key, message, options)
|
@@ -111,26 +111,26 @@ module DigiByteCigs
|
|
111
111
|
nil
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
def sign_message!(wallet_key, message, options = {:network => :mainnet})
|
116
116
|
private_key = convert_wallet_format_to_bytes!(wallet_key, options[:network])
|
117
|
-
|
117
|
+
|
118
118
|
msg_hash = sha256(sha256(format_message_to_sign(message)))
|
119
|
-
|
119
|
+
|
120
120
|
ec_key = ::DigiByteCigs::EcKey.new(str_to_num(private_key))
|
121
121
|
private_key = ec_key.private_key
|
122
122
|
public_key = ec_key.public_key
|
123
123
|
addr = public_key_to_bc_address(get_pub_key(ec_key, ec_key.public_key.compressed), NETWORK_VERSION[options[:network]])
|
124
|
-
|
124
|
+
|
125
125
|
sig = private_key.sign(msg_hash, random_k)
|
126
126
|
raise ::DigiByteCigs::Error.new("Unable to sign message") unless public_key.verify(msg_hash, sig)
|
127
|
-
|
127
|
+
|
128
128
|
4.times do |i|
|
129
129
|
hb = 27 + i
|
130
|
-
|
130
|
+
|
131
131
|
sign = "#{hb.chr}#{sig.ser}"
|
132
132
|
sign_64 = encode64(sign)
|
133
|
-
|
133
|
+
|
134
134
|
begin
|
135
135
|
verify_message!(addr, sign_64, message, options)
|
136
136
|
return sign_64
|
@@ -138,10 +138,10 @@ module DigiByteCigs
|
|
138
138
|
next
|
139
139
|
end
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
142
|
raise ::DigiByteCigs::Error, "Unable to construct recoverable key"
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
def convert_wallet_format_to_bytes!(input, network)
|
146
146
|
bytes = if is_wallet_import_format?(input, network)
|
147
147
|
decode_wallet_import_format(input, network)
|
@@ -156,29 +156,29 @@ module DigiByteCigs
|
|
156
156
|
else
|
157
157
|
raise ::DigiByteCigs::Error.new("Unknown Wallet Format")
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
bytes
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
private
|
164
|
-
|
164
|
+
|
165
165
|
def format_message_to_sign(message)
|
166
|
-
"\
|
166
|
+
"\x19DigiByte Signed Message:\n#{::DigiByteCigs::CompactInt.new(message.size).encode}#{message}"
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
def random_k
|
170
170
|
k = 0
|
171
171
|
8.times do |i|
|
172
172
|
k |= (rand * 0xffffffff).to_i << (32 * i)
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
k
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
def get_pub_key(public_key, compressed)
|
179
179
|
i2o_ec_public_key(public_key, compressed)
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
def i2o_ec_public_key(public_key, compressed)
|
183
183
|
key = if compressed
|
184
184
|
"#{public_key.public_key.point.y & 1 > 0 ? '03' : '02'}%064x" % public_key.public_key.point.x
|
@@ -194,85 +194,85 @@ module DigiByteCigs
|
|
194
194
|
#puts "ASDF #{bytes.unpack('H*')}"
|
195
195
|
#puts bytes.bytes.collect {|e| e.to_i}.join(" ")
|
196
196
|
hash = bytes[0..32]
|
197
|
-
|
197
|
+
|
198
198
|
checksum = sha256(sha256(hash))
|
199
199
|
raise ::DigiByteCigs::Error.new("Wallet checksum invalid") if bytes[33..37] != checksum[0..3]
|
200
200
|
|
201
201
|
version, hash = hash[0], hash[1..-1]
|
202
202
|
raise ::DigiByteCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX[network]
|
203
|
-
|
203
|
+
|
204
204
|
hash
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
def decode_compressed_wallet_import_format(input, network)
|
208
208
|
bytes = decode58(input)
|
209
209
|
hash = bytes[0...34]
|
210
|
-
|
210
|
+
|
211
211
|
checksum = sha256(sha256(hash))
|
212
212
|
raise ::DigiByteCigs::Error.new("Wallet checksum invalid") if bytes[34..37] != checksum[0..3]
|
213
213
|
|
214
214
|
version, hash = hash[0], hash[1..32]
|
215
215
|
raise ::DigiByteCigs::Error.new("Wallet Version #{version} not supported") if version.ord != PRIVATE_KEY_PREFIX[network]
|
216
|
-
|
216
|
+
|
217
217
|
hash
|
218
218
|
end
|
219
|
-
|
219
|
+
|
220
220
|
# 64 characters [0-9A-F]
|
221
221
|
def is_hex_format?(key)
|
222
222
|
/^[A-Fa-f0-9]{64}$/ =~ key
|
223
223
|
end
|
224
|
-
|
224
|
+
|
225
225
|
# 51 characters base58 starting with 5
|
226
226
|
def is_wallet_import_format?(key, network)
|
227
227
|
/^#{network == :mainnet ? '5' : '9'}[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/ =~ key
|
228
228
|
end
|
229
|
-
|
229
|
+
|
230
230
|
# 52 characters base58 starting with L or K
|
231
231
|
def is_compressed_wallet_import_format?(key, network)
|
232
232
|
/^[network == :mainnet ? 'LK' : 'c'][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/ =~ key
|
233
233
|
end
|
234
|
-
|
234
|
+
|
235
235
|
# 44 characters
|
236
236
|
def is_base_64_format?(key)
|
237
237
|
/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/ =~ key
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
240
|
# 22, 26 or 30 characters, always starts with an 'S'
|
241
241
|
def is_mini_format?(key)
|
242
242
|
validChars22 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/ =~ key
|
243
243
|
validChars26 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/ =~ key
|
244
244
|
validChars30 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/ =~ key
|
245
|
-
|
245
|
+
|
246
246
|
bytes = sha256("#{key}?")
|
247
|
-
|
247
|
+
|
248
248
|
(bytes[0].ord === 0x00 || bytes[0].ord === 0x01) && (validChars22 || validChars26 || validChars30)
|
249
249
|
end
|
250
|
-
|
250
|
+
|
251
251
|
def debug_bytes(s)
|
252
252
|
s.chars.collect(&:ord).join(', ')
|
253
253
|
end
|
254
|
-
|
254
|
+
|
255
255
|
def calculate_hash(d)
|
256
256
|
sha256(sha256(d))
|
257
257
|
end
|
258
|
-
|
258
|
+
|
259
259
|
def public_key_to_bc_address(public_key, network_version)
|
260
260
|
h160 = hash_160(public_key)
|
261
|
-
|
261
|
+
|
262
262
|
hash_160_to_bc_address(h160, network_version)
|
263
263
|
end
|
264
|
-
|
264
|
+
|
265
265
|
def hash_160_to_bc_address(h160, address_type)
|
266
266
|
vh160 = address_type.chr + h160
|
267
267
|
h = calculate_hash(vh160)
|
268
268
|
addr = vh160 + h[0...4]
|
269
|
-
|
269
|
+
|
270
270
|
encode58(addr)
|
271
271
|
end
|
272
|
-
|
272
|
+
|
273
273
|
def hash_160(public_key)
|
274
274
|
ripemd160(sha256(public_key))
|
275
275
|
end
|
276
|
-
|
276
|
+
|
277
277
|
end
|
278
278
|
end
|