crypto-lite 0.2.1 → 0.2.2
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/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
|