crypto-lite 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +3 -0
- data/README.md +174 -19
- data/Rakefile +3 -1
- data/lib/crypto-lite.rb +79 -14
- data/lib/crypto-lite/config.rb +32 -0
- data/lib/crypto-lite/version.rb +1 -1
- data/test/test_base58.rb +35 -0
- data/test/test_bitcoin_addr.rb +58 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb39c213dfc1d3d5f0625fceed1aa57ba57094838d6b4fa792388aa914764ec5
|
4
|
+
data.tar.gz: 9222110e4d2a56e99704ae234213438251cc6259d446ea974bb3dcc6f7195669
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f644ce38c52fb2b6bb670616619548752a261147515461558dda726309fed4bba5f1e6f1bdb21eaa9923c8cecfd4bd92dd8d30717487f1dc994d48183848867d
|
7
|
+
data.tar.gz: 594fb0787715b39c9995384f650ed261c4455dd0827d08d65286410d8b9b5f77ce27afae8297f78e558ea0006f592fca6dd52dac55f453528f7b62d90fd43b3e
|
data/Manifest.txt
CHANGED
@@ -3,10 +3,13 @@ Manifest.txt
|
|
3
3
|
README.md
|
4
4
|
Rakefile
|
5
5
|
lib/crypto-lite.rb
|
6
|
+
lib/crypto-lite/config.rb
|
6
7
|
lib/crypto-lite/version.rb
|
7
8
|
lib/crypto.rb
|
8
9
|
lib/crypto/lite.rb
|
9
10
|
test/helper.rb
|
11
|
+
test/test_base58.rb
|
12
|
+
test/test_bitcoin_addr.rb
|
10
13
|
test/test_hash_keccak.rb
|
11
14
|
test/test_hash_sha.rb
|
12
15
|
test/test_version.rb
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
### Secure Hashing / Hash Functions
|
14
14
|
|
15
|
-
**SHA256 - Secure Hash Algorithm (SHA) 256-
|
15
|
+
**SHA256 - Secure Hash Algorithm (SHA) 256-Bit (32 Bytes)**
|
16
16
|
|
17
17
|
|
18
18
|
``` ruby
|
@@ -52,7 +52,7 @@ sha256( "Hello, Cryptos!" ) #=> "33eedea60b0662c66c289ceba71863a864cf84b00e1000
|
|
52
52
|
|
53
53
|
|
54
54
|
|
55
|
-
#### Aside - Hex String `
|
55
|
+
#### Aside - Hex String `"0x616263"` vs Binary String `"\x61\x62\x63" == "abc"`
|
56
56
|
|
57
57
|
Note: All hash functions operate on binary strings ("byte arrays")
|
58
58
|
and NOT hex strings.
|
@@ -62,20 +62,20 @@ Examples of hex strings:
|
|
62
62
|
|
63
63
|
``` ruby
|
64
64
|
# hex string binary string ("byte array")
|
65
|
-
|
66
|
-
|
65
|
+
"61" "\x61" == "a"
|
66
|
+
"0x61" "\x61" == "a"
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
"616263" "\x61\x62\x63" == "abc"
|
69
|
+
"0x616263" "\x61\x62\x63" == "abc"
|
70
|
+
"0X616263" "\x61\x62\x63" == "abc"
|
71
71
|
|
72
72
|
# or 160-bit hex string (hash)
|
73
|
-
|
74
|
-
|
73
|
+
"93ce48570b55c42c2af816aeaba06cfee1224fae"
|
74
|
+
"0x93ce48570b55c42c2af816aeaba06cfee1224fae"
|
75
75
|
|
76
76
|
# or 256-bit hex string (hash)
|
77
|
-
|
78
|
-
|
77
|
+
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
78
|
+
"0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
79
79
|
```
|
80
80
|
|
81
81
|
You can use `[str].pack( 'H*' )`
|
@@ -126,47 +126,113 @@ hash256( '6fe6b145a3908a4d6616b13c1109717add8672c900' )
|
|
126
126
|
|
127
127
|
``` ruby
|
128
128
|
keccak256( "Hello, Cryptos!" ) #=> "2cf14baa817e931f5cc2dcb63c889619d6b7ae0794fc2223ebadf8e672c776f5"
|
129
|
+
keccak256( '' ) #=> "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
129
130
|
```
|
130
131
|
|
131
132
|
|
133
|
+
#### Aside - Keccak vs SHA3 / Original vs Official
|
134
|
+
|
135
|
+
In 2004 the U.S. National Institute of Standards and Technology (NIST)
|
136
|
+
changed the padding to `SHA3-256(M) = KECCAK [512] (M || 01, 256)`.
|
137
|
+
This is different from the padding proposed by the Keccak team in
|
138
|
+
the original Keccak SHA-3 submission version 3 (the final, winning version).
|
139
|
+
The difference is the additional `'01'` bits appended to the message.
|
140
|
+
|
141
|
+
To help avoid confusion the "submitted original version 3" SHA-3 Keccak
|
142
|
+
hashing is now called "Keccak"
|
143
|
+
and the finalized NIST SHA-3 standard "SHA3".
|
144
|
+
|
145
|
+
Tip: If you don't know what variant of the hash function you have -
|
146
|
+
original or official? - check your hash:
|
147
|
+
|
148
|
+
For keccak 256-bit:
|
149
|
+
|
150
|
+
``` ruby
|
151
|
+
keccak256( '' ) #=> "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
152
|
+
keccak256( 'Hello, Cryptos!' ) #=> "2cf14baa817e931f5cc2dcb63c889619d6b7ae0794fc2223ebadf8e672c776f5"
|
153
|
+
```
|
154
|
+
|
155
|
+
For sha3 256-bit:
|
156
|
+
|
157
|
+
``` ruby
|
158
|
+
sha3_256( '' ) #=> "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"
|
159
|
+
sha3_256( 'Hello, Cryptos!' ) #=> "7dddf4bc9b86352b67e8823e5010ddbd2a90a854469e2517992ca7ca89e5bd58"
|
160
|
+
```
|
161
|
+
|
162
|
+
|
163
|
+
|
132
164
|
**RMD - RACE¹ Integrity Primitives Evaluation Message Digest 160-Bit**
|
133
165
|
|
134
166
|
¹: Research and development in Advanced Communications technologies in Europe
|
135
167
|
|
136
168
|
|
137
169
|
``` ruby
|
138
|
-
rmd160( "Hello, Cryptos!" )
|
170
|
+
rmd160( "Hello, Cryptos!" ) #=>"4d65f7b740bbade4097e1348e15d2a7d52ac5f53"
|
171
|
+
# or use the alias / alternate name
|
172
|
+
ripemd160( "Hello, Cryptos!" ) #=>"4d65f7b740bbade4097e1348e15d2a7d52ac5f53"
|
139
173
|
```
|
140
174
|
|
141
175
|
|
142
176
|
|
143
|
-
#### Helpers
|
177
|
+
#### Hash Function Helpers
|
144
178
|
|
145
|
-
**HASH160 - RMD160(SHA256())**
|
179
|
+
**HASH160 - RMD160(SHA256(X))**
|
146
180
|
|
147
181
|
All-in-one "best-of-both-worlds" helper - first hash with sha256 and than hash with rmd160. Why? Get the higher security of sha256 and the smaller size of rmd160.
|
148
182
|
|
149
183
|
|
150
184
|
``` ruby
|
151
185
|
hash160( '02b9d1cc0b793b03b9f64d022e9c67d5f32670b03f636abf0b3147b34123d13990' )
|
152
|
-
|
186
|
+
#=> "e6b145a3908a4d6616b13c1109717add8672c900"
|
153
187
|
|
154
188
|
hash160( '02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737' )
|
155
|
-
|
189
|
+
#=> "93ce48570b55c42c2af816aeaba06cfee1224fae"
|
156
190
|
```
|
157
191
|
|
158
192
|
|
159
|
-
|
160
|
-
**HASH256 - SHA256(SHA256())**
|
193
|
+
**HASH256 - SHA256(SHA256(X))**
|
161
194
|
|
162
195
|
All-in-one double sha256 hash helper, that is, first hash with sha256 and than hash with sha256 again. Why? Arguably higher security.
|
163
196
|
|
197
|
+
> SHA256(SHA256(X)) was proposed by Ferguson and Schneier in their excellent book "Practical Cryptography"
|
198
|
+
> (later updated by Ferguson, Schneier, and Kohno and renamed "Cryptography Engineering") as a way to make SHA256 invulnerable
|
199
|
+
> to "length-extension" attack. They called it "SHA256D".
|
200
|
+
|
201
|
+
|
164
202
|
``` ruby
|
165
203
|
hash256( '6fe6b145a3908a4d6616b13c1109717add8672c900' )
|
166
|
-
|
204
|
+
#=> "02335f08b8fe4ddad263a50b7a33c5d38ea1cbd8fd2056a1320a3ddece541711"
|
205
|
+
```
|
206
|
+
|
207
|
+
##### Base58 Encoding / Decoding Helpers
|
208
|
+
|
209
|
+
**BASE58**
|
210
|
+
|
211
|
+
Base58 encoding / decoding with leading zero bytes (in hex or binary strings) getting encoded from `00` to `1` and back:
|
212
|
+
|
213
|
+
``` ruby
|
214
|
+
base58( "516b6fcd0f" ) #=> "ABnLTmg"
|
215
|
+
base58( "00000000000000000000123456789abcdef0" ) #=> "111111111143c9JGph3DZ"
|
216
|
+
# or with optional 0x or 0X prefix
|
217
|
+
base58( "0x516b6fcd0f" ) #=> "ABnLTmg"
|
218
|
+
base58( "0x00000000000000000000123456789abcdef0" ) #=> "111111111143c9JGph3DZ"
|
219
|
+
|
220
|
+
unbase58( "ABnLTmg" ) #=> "516b6fcd0f"
|
221
|
+
unbase58( "111111111143c9JGph3DZ" ) #=> "00000000000000000000123456789abcdef0"
|
167
222
|
```
|
168
223
|
|
169
224
|
|
225
|
+
**BASE58CHECK - BASE58(X || SHA256(SHA256(X))[:4])**
|
226
|
+
|
227
|
+
Base58 encoding with an extra 4-byte secure hash checksum.
|
228
|
+
|
229
|
+
``` ruby
|
230
|
+
base58check( "516b6fcd0f" ) #=> "237LSrY9NUUas"
|
231
|
+
base58check( "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ) #=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
232
|
+
|
233
|
+
unbase58check( "237LSrY9NUUas" ) #=> "516b6fcd0f"
|
234
|
+
unbase58check( "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs" ) #=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
235
|
+
```
|
170
236
|
|
171
237
|
|
172
238
|
|
@@ -291,6 +357,95 @@ and some more.
|
|
291
357
|
|
292
358
|
|
293
359
|
|
360
|
+
|
361
|
+
## Examples
|
362
|
+
|
363
|
+
### Generate the Bitcoin (Base58) Address from the (Elliptic Curve) Public Key
|
364
|
+
|
365
|
+
Let's follow the steps from [How to create Bitcoin Address](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses#How_to_create_Bitcoin_Address):
|
366
|
+
|
367
|
+
``` ruby
|
368
|
+
# Lets start with the public key ("raw" hex string encoded)
|
369
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
370
|
+
|
371
|
+
# 1. Perform SHA-256 hashing on the public key
|
372
|
+
step1 = sha256( pk )
|
373
|
+
#=> "0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98"
|
374
|
+
|
375
|
+
# 2. Perform RIPEMD-160 hashing on the result of SHA-256
|
376
|
+
step2 = ripemd160( step1 )
|
377
|
+
#=> "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
378
|
+
|
379
|
+
# 3. Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
|
380
|
+
step3 = "00" + step2
|
381
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
382
|
+
|
383
|
+
# 4. Perform SHA-256 hash on the extended RIPEMD-160 result
|
384
|
+
step4 = sha256( step3 )
|
385
|
+
#=> "ad3c854da227c7e99c4abfad4ea41d71311160df2e415e713318c70d67c6b41c"
|
386
|
+
|
387
|
+
# 5. Perform SHA-256 hash on the result of the previous SHA-256 hash
|
388
|
+
step5 = sha256( step4 )
|
389
|
+
#=> "c7f18fe8fcbed6396741e58ad259b5cb16b7fd7f041904147ba1dcffabf747fd"
|
390
|
+
|
391
|
+
# 6. Take the first 4 bytes of the second SHA-256 hash. This is the address checksum
|
392
|
+
step6 = step5[0..7] # note: 4 bytes in hex string are 8 digits/chars
|
393
|
+
#=> "c7f18fe8"
|
394
|
+
|
395
|
+
# 7. Add the 4 checksum bytes from step 6 at the end of
|
396
|
+
# extended RIPEMD-160 hash from step 3.
|
397
|
+
# This is the 25-byte binary Bitcoin Address.
|
398
|
+
step7 = step3 + step6
|
399
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31c7f18fe8"
|
400
|
+
|
401
|
+
# 8. Convert the result from a byte string into a base58 string using Base58 encoding.
|
402
|
+
# This is the most commonly used Bitcoin Address format.
|
403
|
+
addr = base58( step7 )
|
404
|
+
#=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
405
|
+
```
|
406
|
+
|
407
|
+
Or let's try again with the shortcut helpers:
|
408
|
+
|
409
|
+
- `HASH160 - RMD160(SHA256(X))`
|
410
|
+
- `BASE58CHECK - BASE58(X || SHA256(SHA256(X))[:4])`
|
411
|
+
|
412
|
+
``` ruby
|
413
|
+
# Lets start with the public key ("raw" hex string encoded)
|
414
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
415
|
+
|
416
|
+
# 1. Perform HASH-160 hashing on the public key
|
417
|
+
# a) Perform SHA-256 hashing on the public key
|
418
|
+
# b) Perform RIPEMD-160 hashing on the result of SHA-256
|
419
|
+
step1 = hash160( pk )
|
420
|
+
#=> "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
421
|
+
|
422
|
+
# 2. Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
|
423
|
+
step2 = "00" + step1
|
424
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
425
|
+
|
426
|
+
# 3. Encode with BASE58CHECK
|
427
|
+
# a) Perform SHA-256 hash on the extended RIPEMD-160 result
|
428
|
+
# b) Perform SHA-256 hash on the result of the previous SHA-256 hash
|
429
|
+
# c) Take the first 4 bytes of the second SHA-256 hash. This is the address checksum
|
430
|
+
# d) Add the 4 checksum bytes at the end of
|
431
|
+
# extended RIPEMD-160 hash from step 2.
|
432
|
+
# This is the 25-byte binary Bitcoin Address.
|
433
|
+
# e) Convert the result from a byte string into a base58 string
|
434
|
+
# using Base58 encoding.
|
435
|
+
# This is the most commonly used Bitcoin Address format.
|
436
|
+
addr = base58check( step2 )
|
437
|
+
#=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
438
|
+
```
|
439
|
+
|
440
|
+
|
441
|
+
References
|
442
|
+
|
443
|
+
- [How to create Bitcoin Address](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses#How_to_create_Bitcoin_Address)
|
444
|
+
- [Ruby Quiz #15 - Generate the Bitcoin (Base58) Address from the (Elliptic Curve) Public Key](https://github.com/planetruby/quiz/tree/master/015)
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
|
294
449
|
## Install
|
295
450
|
|
296
451
|
Just install the gem:
|
data/Rakefile
CHANGED
data/lib/crypto-lite.rb
CHANGED
@@ -8,10 +8,16 @@ require 'digest/sha3' # e.g. keccak (original submission/proposal NOT official
|
|
8
8
|
## see https://rubygems.org/gems/digest-sha3-patched
|
9
9
|
## https://github.com/teamhedge/digest-sha3-ruby
|
10
10
|
|
11
|
+
## our own 3rd party (2nd party?)
|
12
|
+
require 'base32-alphabets'
|
13
|
+
require 'base58-alphabets'
|
14
|
+
|
11
15
|
|
12
16
|
|
13
17
|
## our own code
|
14
18
|
require 'crypto-lite/version' # note: let version always go first
|
19
|
+
require 'crypto-lite/config'
|
20
|
+
|
15
21
|
|
16
22
|
|
17
23
|
|
@@ -23,13 +29,55 @@ module Crypto
|
|
23
29
|
|
24
30
|
|
25
31
|
|
32
|
+
def self.base58bin( input )
|
33
|
+
## todo/check: input must be a (binary) string - why? why not?
|
34
|
+
Base58::Bitcoin.encode_bin( input )
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.base58( input )
|
38
|
+
input = hex_to_bin_automagic( input ) ## add automagic hex (string) to bin (string) check - why? why not?
|
39
|
+
base58bin( input )
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.base58hex( input )
|
43
|
+
raise ArgumentError, "expected hex string (0-9a-f) - got >#{input}< - can't pack string; sorry" unless input =~ HEX_RE
|
44
|
+
|
45
|
+
input = strip0x( input ) ## check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!
|
46
|
+
base58bin( [input].pack( 'H*' ) )
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def self.base58bin_check( input )
|
51
|
+
## todo/check: input must be a (binary) string - why? why not?
|
52
|
+
hash256 = hash256bin( input )
|
53
|
+
base58bin( input + hash256[0,4] )
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.base58check( input )
|
57
|
+
input = hex_to_bin_automagic( input ) ## add automagic hex (string) to bin (string) check - why? why not?
|
58
|
+
base58bin_check( input )
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.base58hex_check( input )
|
62
|
+
raise ArgumentError, "expected hex string (0-9a-f) - got >#{input}< - can't pack string; sorry" unless input =~ HEX_RE
|
63
|
+
|
64
|
+
input = strip0x( input ) ## check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!
|
65
|
+
base58bin_check( [input].pack( 'H*' ) )
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
########################
|
70
|
+
# (secure) hash functions
|
71
|
+
|
26
72
|
def self.message( input ) ## convert input to (binary) string
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
73
|
+
if debug?
|
74
|
+
input_type = if input.is_a?( String )
|
75
|
+
"#{input.class.name}/#{input.encoding}"
|
76
|
+
else
|
77
|
+
input.class.name
|
78
|
+
end
|
79
|
+
puts " input: #{input} (#{input_type})"
|
80
|
+
end
|
33
81
|
|
34
82
|
message = if input.is_a?( Integer ) ## assume byte if single (unsigned) integer
|
35
83
|
raise ArgumentError, "expected unsigned byte (0-255) - got #{input} (0x#{input.to_s(16)}) - can't pack negative number; sorry" if input < 0
|
@@ -40,12 +88,14 @@ module Crypto
|
|
40
88
|
input
|
41
89
|
end
|
42
90
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
91
|
+
if debug?
|
92
|
+
bytes = message.bytes
|
93
|
+
bin = bytes.map {|byte| byte.to_s(2).rjust(8, "0")}.join( ' ' )
|
94
|
+
hex = bytes.map {|byte| byte.to_s(16).rjust(2, "0")}.join( ' ' )
|
95
|
+
puts " #{pluralize( bytes.size, 'byte')}: #{bytes.inspect}"
|
96
|
+
puts " binary: #{bin}"
|
97
|
+
puts " hex: #{hex}"
|
98
|
+
end
|
49
99
|
|
50
100
|
message
|
51
101
|
end
|
@@ -73,7 +123,12 @@ module Crypto
|
|
73
123
|
input = hex_to_bin_automagic( input ) ## add automagic hex (string) to bin (string) check - why? why not?
|
74
124
|
rmd160bin( input ).unpack( 'H*' )[0]
|
75
125
|
end
|
76
|
-
|
126
|
+
|
127
|
+
## add alias RIPEMD160 - why? why not?
|
128
|
+
class << self
|
129
|
+
alias_method :ripemd160, :rmd160
|
130
|
+
alias_method :ripemd160bin, :rmd160bin
|
131
|
+
end
|
77
132
|
|
78
133
|
|
79
134
|
|
@@ -81,7 +136,7 @@ module Crypto
|
|
81
136
|
message = message( input ) ## "normalize" / convert to (binary) string
|
82
137
|
|
83
138
|
if engine && ['openssl'].include?( engine.to_s.downcase )
|
84
|
-
puts " engine: #{engine}"
|
139
|
+
puts " engine: #{engine}" if debug?
|
85
140
|
digest = OpenSSL::Digest::SHA256.new
|
86
141
|
digest.update( message )
|
87
142
|
digest.digest
|
@@ -228,6 +283,8 @@ def sha256hex( input, engine=nil ) Crypto.sha256hex( input, engine ); end
|
|
228
283
|
def keccak256( input ) Crypto.keccak256( input ); end
|
229
284
|
|
230
285
|
def rmd160( input ) Crypto.rmd160( input ); end
|
286
|
+
def ripemd160( input ) Crypto.rmd160( input ); end
|
287
|
+
## alias_method :ripemd160, :rmd160
|
231
288
|
|
232
289
|
def hash160( input ) Crypto.hash160( input ); end
|
233
290
|
def hash160hex( input ) Crypto.hash160hex( input ); end
|
@@ -236,6 +293,14 @@ def hash256( input ) Crypto.hash256( input ); end
|
|
236
293
|
def hash256hex( input ) Crypto.hash256hex( input ); end
|
237
294
|
|
238
295
|
|
296
|
+
def base58( input ) Crypto.base58( input ); end
|
297
|
+
def base58hex( input ) Crypto.base58hex( input ); end
|
298
|
+
|
299
|
+
|
300
|
+
def base58check( input ) Crypto.base58check( input ); end
|
301
|
+
|
302
|
+
|
303
|
+
|
239
304
|
RSA = Crypto::RSA
|
240
305
|
|
241
306
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Crypto
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@debug = false
|
7
|
+
end
|
8
|
+
|
9
|
+
def debug?() @debug || false; end
|
10
|
+
def debug=(value) @debug = value; end
|
11
|
+
end # class Configuration
|
12
|
+
|
13
|
+
## lets you use
|
14
|
+
## Crypto.configure do |config|
|
15
|
+
## config.debug = true
|
16
|
+
## end
|
17
|
+
|
18
|
+
def self.configuration
|
19
|
+
@configuration ||= Configuration.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.configure
|
23
|
+
yield( configuration )
|
24
|
+
end
|
25
|
+
|
26
|
+
## add convenience helper for format
|
27
|
+
def self.debug?() configuration.debug?; end
|
28
|
+
def self.debug=(value) self.configuration.debug = value; end
|
29
|
+
end # module Crypto
|
30
|
+
|
31
|
+
|
32
|
+
|
data/lib/crypto-lite/version.rb
CHANGED
data/test/test_base58.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
###
|
2
|
+
# to run use
|
3
|
+
# ruby -I ./lib -I ./test test/test_base58.rb
|
4
|
+
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
|
9
|
+
class TestBase58 < MiniTest::Test
|
10
|
+
|
11
|
+
HEX_TESTS = [
|
12
|
+
["00000000000000000000", "1111111111"],
|
13
|
+
["00000000000000000000123456789abcdef0", "111111111143c9JGph3DZ"],
|
14
|
+
]
|
15
|
+
|
16
|
+
def test_hex
|
17
|
+
HEX_TESTS.each do |item|
|
18
|
+
assert_equal item[1], base58hex( item[0] )
|
19
|
+
assert_equal item[1], base58( item[0] )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def test_bitcoin_addr
|
25
|
+
addr_exp = '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs'
|
26
|
+
|
27
|
+
pkh = 'f54a5851e9372b87810a8e60cdd2e7cfd80b6e31'
|
28
|
+
|
29
|
+
## all-in-one
|
30
|
+
assert_equal addr_exp, base58check( '00' + pkh )
|
31
|
+
assert_equal addr_exp, Crypto.base58hex_check( '00' + pkh )
|
32
|
+
assert_equal addr_exp, Crypto.base58bin_check( "\x00" + [pkh].pack('H*') )
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class TestBase58
|
@@ -0,0 +1,58 @@
|
|
1
|
+
###
|
2
|
+
# to run use
|
3
|
+
# ruby -I ./lib -I ./test test/test_bitcoin_addr.rb
|
4
|
+
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestBitcoinAddr < MiniTest::Test
|
9
|
+
|
10
|
+
|
11
|
+
def test_bitcoin_addr_v1
|
12
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
13
|
+
|
14
|
+
step1 = sha256( pk )
|
15
|
+
assert_equal "0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98",
|
16
|
+
step1
|
17
|
+
|
18
|
+
step2 = ripemd160( step1 )
|
19
|
+
assert_equal "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31",
|
20
|
+
step2
|
21
|
+
|
22
|
+
step3 = "00" + step2
|
23
|
+
assert_equal "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31",
|
24
|
+
step3
|
25
|
+
|
26
|
+
step4 = sha256( step3 )
|
27
|
+
assert_equal "ad3c854da227c7e99c4abfad4ea41d71311160df2e415e713318c70d67c6b41c",
|
28
|
+
step4
|
29
|
+
|
30
|
+
step5 = sha256( step4 )
|
31
|
+
assert_equal "c7f18fe8fcbed6396741e58ad259b5cb16b7fd7f041904147ba1dcffabf747fd",
|
32
|
+
step5
|
33
|
+
|
34
|
+
step6 = step5[0..7] # note: 4 bytes in hex string are 8 digits/chars
|
35
|
+
assert_equal "c7f18fe8", step6
|
36
|
+
|
37
|
+
step7 = step3 + step6
|
38
|
+
assert_equal "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31c7f18fe8", step7
|
39
|
+
|
40
|
+
addr = base58( step7 )
|
41
|
+
assert_equal "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs", addr
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def test_bitcoin_addr_v2
|
46
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
47
|
+
|
48
|
+
step1 = hash160( pk )
|
49
|
+
assert_equal "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31", step1
|
50
|
+
|
51
|
+
step2 = "00" + step1
|
52
|
+
assert_equal "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31", step2
|
53
|
+
|
54
|
+
addr = base58check( step2 )
|
55
|
+
assert_equal "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs", addr
|
56
|
+
end
|
57
|
+
|
58
|
+
end # class TestBitcoinAddr
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crypto-lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digest-sha3-patched
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: base32-alphabets
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: base58-alphabets
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rdoc
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,10 +101,13 @@ files:
|
|
73
101
|
- README.md
|
74
102
|
- Rakefile
|
75
103
|
- lib/crypto-lite.rb
|
104
|
+
- lib/crypto-lite/config.rb
|
76
105
|
- lib/crypto-lite/version.rb
|
77
106
|
- lib/crypto.rb
|
78
107
|
- lib/crypto/lite.rb
|
79
108
|
- test/helper.rb
|
109
|
+
- test/test_base58.rb
|
110
|
+
- test/test_bitcoin_addr.rb
|
80
111
|
- test/test_hash_keccak.rb
|
81
112
|
- test/test_hash_sha.rb
|
82
113
|
- test/test_version.rb
|