crypto-lite 0.0.1 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +7 -0
- data/README.md +491 -0
- data/Rakefile +5 -1
- data/lib/crypto-lite.rb +113 -48
- data/lib/crypto-lite/config.rb +32 -0
- data/lib/crypto-lite/helper.rb +25 -0
- data/lib/crypto-lite/metal.rb +128 -0
- data/lib/crypto-lite/sign_rsa.rb +29 -0
- data/lib/crypto-lite/version.rb +2 -2
- data/test/test_base58.rb +36 -0
- data/test/test_bitcoin_addr.rb +58 -0
- data/test/test_hash.rb +24 -55
- data/test/test_hash_sha.rb +87 -0
- metadata +55 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7326c07c1553f4f15d79ddbfa19df2ad5dd04bb18e769ccbf564ee521aa97405
|
4
|
+
data.tar.gz: 9602382da425f288147cc4a1a9e5f0fc373dc9f8838204886c990a9e4b611be6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b607671748a9035dce0b505ec757397416f2a70193e8d5890a90815bba03bbeff874ec878462b950427a372657889344f16b04c8349286165a70a61fd48fa86
|
7
|
+
data.tar.gz: bc6ad174e2d5fe8c0b75853bd66e7b69ee963024c33f797b9043a836cbe25fee7b5ada35c2c5c144fc5dad93b80859de4e9b3fb09fe34b5390c0a58b654c7363
|
data/Manifest.txt
CHANGED
@@ -3,9 +3,16 @@ Manifest.txt
|
|
3
3
|
README.md
|
4
4
|
Rakefile
|
5
5
|
lib/crypto-lite.rb
|
6
|
+
lib/crypto-lite/config.rb
|
7
|
+
lib/crypto-lite/helper.rb
|
8
|
+
lib/crypto-lite/metal.rb
|
9
|
+
lib/crypto-lite/sign_rsa.rb
|
6
10
|
lib/crypto-lite/version.rb
|
7
11
|
lib/crypto.rb
|
8
12
|
lib/crypto/lite.rb
|
9
13
|
test/helper.rb
|
14
|
+
test/test_base58.rb
|
15
|
+
test/test_bitcoin_addr.rb
|
10
16
|
test/test_hash.rb
|
17
|
+
test/test_hash_sha.rb
|
11
18
|
test/test_version.rb
|
data/README.md
CHANGED
@@ -2,9 +2,500 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
+
* home :: [github.com/rubycoco/blockchain](https://github.com/rubycoco/blockchain)
|
6
|
+
* bugs :: [github.com/rubycoco/blockchain/issues](https://github.com/rubycoco/blockchain/issues)
|
7
|
+
* gem :: [rubygems.org/gems/crypto-lite](https://rubygems.org/gems/crypto-lite)
|
8
|
+
* rdoc :: [rubydoc.info/gems/crypto-lite](http://rubydoc.info/gems/crypto-lite)
|
5
9
|
|
6
10
|
|
11
|
+
## Usage
|
7
12
|
|
13
|
+
### Secure Hashing / Hash Functions
|
8
14
|
|
15
|
+
**SHA256 - Secure Hash Algorithm (SHA) 256-Bit (32 Bytes)**
|
9
16
|
|
10
17
|
|
18
|
+
``` ruby
|
19
|
+
require 'crypto' ## or use require 'crypto-lite'
|
20
|
+
|
21
|
+
## try abc
|
22
|
+
sha256( "abc" ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
23
|
+
sha256( "abc".b ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
24
|
+
sha256( "\x61\x62\x63" ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
25
|
+
sha256( 0x616263 ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
26
|
+
|
27
|
+
sha256( hex: '616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
28
|
+
sha256( hex: '0x616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
29
|
+
sha256( hex: '0X616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
30
|
+
|
31
|
+
# "auto-magic" hex string to binary string conversion heuristic
|
32
|
+
sha256( '0x616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
33
|
+
sha256( '0X616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
Bonus Back Stage Tip: How does SHA256 work?
|
38
|
+
|
39
|
+
Try this [amazing animation of the SHA256 hash function in your very own terminal](https://github.com/in3rsha/sha256-animation) by Greg Walker.
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
Onwards with more sha256 examples:
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
## try a
|
47
|
+
sha256( "a" ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
48
|
+
sha256( "\x61" ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
49
|
+
sha256( 0b01100001 ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
50
|
+
sha256( 0x61 ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
51
|
+
|
52
|
+
sha256( hex: '61' ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
53
|
+
sha256( hex: '0x61' ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
54
|
+
|
55
|
+
# "auto-magic" hex string to binary string conversion heuristic
|
56
|
+
sha256( '0x61' ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
57
|
+
|
58
|
+
|
59
|
+
## try some more
|
60
|
+
sha256( "Hello, Cryptos!" ) #=> "33eedea60b0662c66c289ceba71863a864cf84b00e10002ca1069bf58f9362d5"
|
61
|
+
```
|
62
|
+
|
63
|
+
|
64
|
+
**SHA3-256 - Secure Hashing Algorthim (SHA) 3, 256-Bit (32 Bytes)**
|
65
|
+
|
66
|
+
``` ruby
|
67
|
+
sha3_256( "Hello, Cryptos!" ) #=> "7dddf4bc9b86352b67e8823e5010ddbd2a90a854469e2517992ca7ca89e5bd58"
|
68
|
+
```
|
69
|
+
|
70
|
+
Note: Yes, SHA256 vs SHA3-256 / SHA-2 vs SHA-3 the hashing functions are
|
71
|
+
different (although the 256-bit hash size output is the same).
|
72
|
+
The sha256 hashing function is part of the Secure Hash Algorithm (SHA) 2 family / standards first published in 2001.
|
73
|
+
The sha3_256 is part of the (newer) Secure Hash Algorithm (SHA) 3 family / standards first published in 2015
|
74
|
+
(and uses the Keccak cryptographic primitive "under the hood").
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
**Keccak 256-Bit**
|
79
|
+
|
80
|
+
``` ruby
|
81
|
+
keccak256( "Hello, Cryptos!" ) #=> "2cf14baa817e931f5cc2dcb63c889619d6b7ae0794fc2223ebadf8e672c776f5"
|
82
|
+
```
|
83
|
+
|
84
|
+
|
85
|
+
#### Aside - Keccak vs SHA3 / Original vs Official
|
86
|
+
|
87
|
+
In 2004 the U.S. National Institute of Standards and Technology (NIST)
|
88
|
+
changed the padding to `SHA3-256(M) = KECCAK [512] (M || 01, 256)`.
|
89
|
+
This is different from the padding proposed by the Keccak team in
|
90
|
+
the original Keccak SHA-3 submission version 3 (the final, winning version).
|
91
|
+
The difference is the additional `'01'` bits appended to the message.
|
92
|
+
|
93
|
+
To help avoid confusion the "submitted original version 3" SHA-3 Keccak
|
94
|
+
hashing is now called "Keccak"
|
95
|
+
and the finalized NIST SHA-3 standard "SHA3".
|
96
|
+
|
97
|
+
Tip: If you don't know what variant of the hash function you have -
|
98
|
+
original or official? - check your hash:
|
99
|
+
|
100
|
+
For keccak 256-bit:
|
101
|
+
|
102
|
+
``` ruby
|
103
|
+
keccak256( '' ) #=> "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
104
|
+
```
|
105
|
+
|
106
|
+
For sha3 256-bit:
|
107
|
+
|
108
|
+
``` ruby
|
109
|
+
sha3_256( '' ) #=> "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"
|
110
|
+
```
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
**RMD / RIPE-MD - RACE¹ Integrity Primitives Evaluation Message Digest 160-Bit**
|
115
|
+
|
116
|
+
¹: Research and development in Advanced Communications technologies in Europe
|
117
|
+
|
118
|
+
|
119
|
+
``` ruby
|
120
|
+
rmd160( "Hello, Cryptos!" ) #=>"4d65f7b740bbade4097e1348e15d2a7d52ac5f53"
|
121
|
+
# or use the alias / alternate name
|
122
|
+
ripemd160( "Hello, Cryptos!" ) #=>"4d65f7b740bbade4097e1348e15d2a7d52ac5f53"
|
123
|
+
```
|
124
|
+
|
125
|
+
|
126
|
+
#### Aside - Hex String `"0x616263"` vs Binary String `"\x61\x62\x63" == "abc"`
|
127
|
+
|
128
|
+
Note: All hash functions operate on binary strings ("byte arrays")
|
129
|
+
and NOT hex strings.
|
130
|
+
|
131
|
+
Note: For hex strings the `0x` or `0X` prefix is optional.
|
132
|
+
Examples of hex strings:
|
133
|
+
|
134
|
+
``` ruby
|
135
|
+
# hex string binary string ("byte array")
|
136
|
+
"61" "\x61" == "a"
|
137
|
+
"0x61" "\x61" == "a"
|
138
|
+
|
139
|
+
"616263" "\x61\x62\x63" == "abc"
|
140
|
+
"0x616263" "\x61\x62\x63" == "abc"
|
141
|
+
"0X616263" "\x61\x62\x63" == "abc"
|
142
|
+
|
143
|
+
# or 160-bit hex string (hash)
|
144
|
+
"93ce48570b55c42c2af816aeaba06cfee1224fae"
|
145
|
+
"0x93ce48570b55c42c2af816aeaba06cfee1224fae"
|
146
|
+
|
147
|
+
# or 256-bit hex string (hash)
|
148
|
+
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
149
|
+
"0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
150
|
+
```
|
151
|
+
|
152
|
+
You can use `[str].pack( 'H*' )`
|
153
|
+
to convert a hex string into a binary string.
|
154
|
+
Note: The standard `Array#pack` conversion
|
155
|
+
will NOT "auto-magically" cut-off the `0x` or `0X` prefix.
|
156
|
+
|
157
|
+
|
158
|
+
If you know you have a hex string use the `hex:` keyword to pass
|
159
|
+
in the arg(ument)
|
160
|
+
to the hash function and that will "automagically"
|
161
|
+
handle the hex-to-bin conversion for you. Example:
|
162
|
+
|
163
|
+
``` ruby
|
164
|
+
sha256( hex: '61' ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
165
|
+
sha256( hex: '0x61' ) #=> "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
|
166
|
+
|
167
|
+
sha256( hex: '616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
168
|
+
sha256( hex: '0x616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
169
|
+
sha256( hex: '0X616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
170
|
+
```
|
171
|
+
|
172
|
+
What about the built-in "auto-magic" hex-to-bin conversion / heuristic?
|
173
|
+
|
174
|
+
Yes, if your passed in string starts with the
|
175
|
+
the `0x` or `0X` prefix the string gets "auto-magically" converted
|
176
|
+
to binary. Or if your passed in string is all hexadecimal characters,
|
177
|
+
that is, `0-9` and `a-f` and has a minimum length of ten characters.
|
178
|
+
Example:
|
179
|
+
|
180
|
+
|
181
|
+
``` ruby
|
182
|
+
# "auto-magic" hex string to binary string conversion heuristic
|
183
|
+
|
184
|
+
sha256( '0x616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
185
|
+
sha256( '0X616263' ) #=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
186
|
+
|
187
|
+
# or without 0x or 0X BUT with minimum heuristic length
|
188
|
+
hash160( '02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737' )
|
189
|
+
#=> "93ce48570b55c42c2af816aeaba06cfee1224fae"
|
190
|
+
|
191
|
+
hash256( '6fe6b145a3908a4d6616b13c1109717add8672c900' )
|
192
|
+
#=> "02335f08b8fe4ddad263a50b7a33c5d38ea1cbd8fd2056a1320a3ddece541711"
|
193
|
+
|
194
|
+
# and so on
|
195
|
+
```
|
196
|
+
|
197
|
+
|
198
|
+
#### Hash Function Helpers
|
199
|
+
|
200
|
+
**HASH160 - RMD160(SHA256(X))**
|
201
|
+
|
202
|
+
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.
|
203
|
+
|
204
|
+
|
205
|
+
``` ruby
|
206
|
+
hash160( '02b9d1cc0b793b03b9f64d022e9c67d5f32670b03f636abf0b3147b34123d13990' )
|
207
|
+
#=> "e6b145a3908a4d6616b13c1109717add8672c900"
|
208
|
+
|
209
|
+
hash160( '02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737' )
|
210
|
+
#=> "93ce48570b55c42c2af816aeaba06cfee1224fae"
|
211
|
+
```
|
212
|
+
|
213
|
+
|
214
|
+
**HASH256 - SHA256(SHA256(X))**
|
215
|
+
|
216
|
+
All-in-one double sha256 hash helper, that is, first hash with sha256 and than hash with sha256 again. Why? Arguably higher security.
|
217
|
+
|
218
|
+
> SHA256(SHA256(X)) was proposed by Ferguson and Schneier in their excellent book "Practical Cryptography"
|
219
|
+
> (later updated by Ferguson, Schneier, and Kohno and renamed "Cryptography Engineering") as a way to make SHA256 invulnerable
|
220
|
+
> to "length-extension" attack. They called it "SHA256D".
|
221
|
+
|
222
|
+
|
223
|
+
``` ruby
|
224
|
+
hash256( '6fe6b145a3908a4d6616b13c1109717add8672c900' )
|
225
|
+
#=> "02335f08b8fe4ddad263a50b7a33c5d38ea1cbd8fd2056a1320a3ddece541711"
|
226
|
+
```
|
227
|
+
|
228
|
+
#### Base58 Encoding / Decoding Helpers
|
229
|
+
|
230
|
+
**BASE58**
|
231
|
+
|
232
|
+
Base58 encoding / decoding with leading zero bytes (in hex or binary strings) getting encoded from `00` to `1` and back:
|
233
|
+
|
234
|
+
``` ruby
|
235
|
+
base58( "516b6fcd0f" ) #=> "ABnLTmg"
|
236
|
+
base58( "00000000000000000000123456789abcdef0" ) #=> "111111111143c9JGph3DZ"
|
237
|
+
# or with optional 0x or 0X prefix
|
238
|
+
base58( "0x516b6fcd0f" ) #=> "ABnLTmg"
|
239
|
+
base58( "0x00000000000000000000123456789abcdef0" ) #=> "111111111143c9JGph3DZ"
|
240
|
+
|
241
|
+
unbase58( "ABnLTmg" ) #=> "516b6fcd0f"
|
242
|
+
unbase58( "111111111143c9JGph3DZ" ) #=> "00000000000000000000123456789abcdef0"
|
243
|
+
```
|
244
|
+
|
245
|
+
|
246
|
+
**BASE58CHECK - BASE58(X || SHA256(SHA256(X))[:4])**
|
247
|
+
|
248
|
+
Base58 encoding with an extra 4-byte secure hash checksum.
|
249
|
+
|
250
|
+
``` ruby
|
251
|
+
base58check( "516b6fcd0f" ) #=> "237LSrY9NUUas"
|
252
|
+
base58check( "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ) #=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
253
|
+
|
254
|
+
unbase58check( "237LSrY9NUUas" ) #=> "516b6fcd0f"
|
255
|
+
unbase58check( "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs" ) #=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
256
|
+
```
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
### Public Key Signature Algorithms
|
261
|
+
|
262
|
+
**RSA - Rivest, Shamir and Adleman**
|
263
|
+
|
264
|
+
|
265
|
+
|
266
|
+
``` ruby
|
267
|
+
alice_key, alice_pub = RSA.generate_keys
|
268
|
+
|
269
|
+
alice_key
|
270
|
+
#=> "-----BEGIN RSA PRIVATE KEY-----
|
271
|
+
# MIIEpAIBAAKCAQEAzLpmAQ+MbUTHU1XxzEaQXqiOvk0Vu/skztaMWz+UoGYWU6eW
|
272
|
+
# cr7zVt/Y0SYqzD8LkYireX22FxNNFfhgu3/uC5yTl+dri6PD6NDAmrG+1cyE8kZZ
|
273
|
+
# MGq91wQEemZPuesjTgKEvwZbknjodIKOAP35QycMr4PuWICSrCjhJLrClI7jInTZ
|
274
|
+
# LOLtD5w5U7/xLOJAIfuhjUA4wrFCLJGPe7214KWgDCLmsan4/GVUloUKa6KAHJiH
|
275
|
+
# q4tNxNdSrbOlluZbKQl8REhXOCIb5bEX2KnbQT0nPgKkuOlXgZ7jeyOIk0FG1RGa
|
276
|
+
# FvcGu8LieMgT39WltcHJLblNkDr9YDRGiNiThQIDAQABAoIBAQCE/FPEPqBeXj4I
|
277
|
+
# MRzHL9MZ2e4XSaVjnYjUXuN/ZnaaFpZMMuF0mfshpHiHq35DfHR8TcXtPi6pIJ2D
|
278
|
+
# NvtG8JvlqQjqtKXUaEWbFvb1xZ4L7TUy12WaIMw+PlrWU11YjJg7VUF7gJq9M5L0
|
279
|
+
# E9ZAaLmg2F3SKSYLEUG1WTyeij5ZFqouNjZxD2xo5U5Agy2UVm2D9aUm/n4g8Wnr
|
280
|
+
# HybadhD6V9+BsZ2e9Q6CamHRah9Hs4nDPnycPFXpbs32wx9nvACPMg5+/Fqxr/ZK
|
281
|
+
# cPM4syVBW0lNhpTzhHkPvimAgwgqJYvAj/o9nQnq5i1XyVyXp3uKVnld3FCddf9i
|
282
|
+
# ovQMPmVlAoGBAPHtUKRehy8df/Zw6oGz0WcZCTjEwZ9DEb5rFN9Pr2IyvOhmZ3UJ
|
283
|
+
# JNx9WmiiGB44dbnafMtr2Ya7u4OAM6e190BbcJKTnpWqVlsXw/wyQqIgJb3AtFu4
|
284
|
+
# 91mqsDepOWsfs1IjTgmR1OM29WXjGoPHtV9E6//uVmVsciEvkCtcRfGDAoGBANij
|
285
|
+
# IbZ3mL1rr8uRT/czPLkZ3KPLsJhPriuc6yyOq+tqQ6d3u/1DjKxoeYa7Jbyj7Dwl
|
286
|
+
# 2wHQf9vRz3Kb2Mw+hPcHGDO9aBWxvZXjxxrVk6g1Ei0mvIP0k8ZbnlReK3cr5ktl
|
287
|
+
# aY/ZWDDVPpY4aqkcOIbAAi95jPlpb2LsntijxoBXAoGABPJRP8sfAHud7jAI23YN
|
288
|
+
# xgnhAmQjgVohtr8Bwj8i2uMmsanGW8JAGrIFczY9QADvh0lMW+xsmjCkeN/aLoet
|
289
|
+
# 8obsGlMiXvUIpvwpabKtYhs+Kk8SYP27MP4odDrljacsR3WpVtDAhZTOF7M5C5C9
|
290
|
+
# yKDkImuBILnC66LJU9mjJHkCgYEAntDxDSCeQ/dnOBh+hB323UgdXaMdAnwflm+C
|
291
|
+
# ZPbvCDWuBV6c3W2g+l/Y/7HBV4rgy7OA29KreU5WA5JHHGyU87gqwPuRC55y+yiy
|
292
|
+
# NXTvu7e0bI9iUmaB00AlUXp76PCw8wMUoVVX9uzN5jjT0MgUlIy8zWsRs2LdOqt3
|
293
|
+
# RCDEjB8CgYAO6ZptzyJ4FS7ucjKfjig5WMOiKMcIUtTG9qedHmE2Z6vt3g0SQWaD
|
294
|
+
# zJJacSoRHAdRK61vOlg4k+9/9LjffDrk9uT555BDbYqKWlmST7JMfvO7EpaIMYUu
|
295
|
+
# CN7+3Rx9gSLyScqtAYiT/LgYgL1Vc6/e0XHaVjA85kPvUDKb785oFg==
|
296
|
+
# -----END RSA PRIVATE KEY-----"
|
297
|
+
|
298
|
+
alice_pub
|
299
|
+
#=> "-----BEGIN PUBLIC KEY-----
|
300
|
+
# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzLpmAQ+MbUTHU1XxzEaQ
|
301
|
+
# XqiOvk0Vu/skztaMWz+UoGYWU6eWcr7zVt/Y0SYqzD8LkYireX22FxNNFfhgu3/u
|
302
|
+
# C5yTl+dri6PD6NDAmrG+1cyE8kZZMGq91wQEemZPuesjTgKEvwZbknjodIKOAP35
|
303
|
+
# QycMr4PuWICSrCjhJLrClI7jInTZLOLtD5w5U7/xLOJAIfuhjUA4wrFCLJGPe721
|
304
|
+
# 4KWgDCLmsan4/GVUloUKa6KAHJiHq4tNxNdSrbOlluZbKQl8REhXOCIb5bEX2Knb
|
305
|
+
# QT0nPgKkuOlXgZ7jeyOIk0FG1RGaFvcGu8LieMgT39WltcHJLblNkDr9YDRGiNiT
|
306
|
+
# hQIDAQAB
|
307
|
+
# -----END PUBLIC KEY-----"
|
308
|
+
|
309
|
+
bob_key, bob_pub = RSA.generate_keys
|
310
|
+
|
311
|
+
bob_key
|
312
|
+
#=> "-----BEGIN RSA PRIVATE KEY-----
|
313
|
+
# MIIEpAIBAAKCAQEAzADannvKlfVkZmKA4EDIxTW0HiJzjD6Auh8wLi02+iz2BScz
|
314
|
+
# fECA65Zv+KHfc1B9AWMqGeBIwFE49NrsnXiZwZR3DqcFS8WbnVqpntvhwzlEARna
|
315
|
+
# RWmZ2XjloD7fxILbXtWfMFNjwSfaK0bpArLkrt9d8eni+JI42+ptIWs/bVynACqm
|
316
|
+
# DqOTjoEgajuHVpxHtskPNQrsjxzP+umsUWkbE0iaO7oN1pcgZIR4VRr0bz/3Juif
|
317
|
+
# WmiCgwbDZo1WolfveoCacVsfAB1iesxeWnrGIJUjq8Mqsu9mQz1dg6RF4ElwNJ57
|
318
|
+
# G3T3nlW+qpVBZDU2sHFqUFxbGmWPdRUn1yn4KwIDAQABAoIBAQCOCwotz4P/Zh3C
|
319
|
+
# LFQP0Qv6RKplURejTuHStmSVwmXFTAkBDYqLuV4Kq3TLaepsIF7p2GI4IjKFtggy
|
320
|
+
# dTzLaG2mm/lJ+oF1gOIZbkcslW1cwULYgWe5bQ3ynntEWIL2ESctoRB2VZnfpCAE
|
321
|
+
# ghs8BdO071I6Xt/qs+VjOpdB7ar8OYhFc1vhwiI03FKbjuScH0CQOETIeLCqK5tC
|
322
|
+
# qPnjMTYdaTp/NgcZujsOeOBgbARLzGtCaESbmXHO6mPDkEED5uqZzsNBtdCZIGMF
|
323
|
+
# ApJkZbF6xSRizQhwwRlak1jCkAk2VCYpKPMiop1+cbjs3jU3RyP94RHc/yKo2Rzm
|
324
|
+
# HCl35XYBAoGBAPJDMV9W2scRsMlLw9In3ZzWtammcouE0oXEgizK61Cg/5C5E06a
|
325
|
+
# 5anrfwF5bURBANKBqTSHV0u71C2fHs1KO+B+EHzQ4DKsXldCSv2PR/0A6lmF9AIL
|
326
|
+
# DFfup/mU55plbqCnjJe2BOUrOmurSd5MbWtShRdGri/LBqF58BFgT+U1AoGBANeS
|
327
|
+
# RZDsCWelZPGN8Wxp9zxhu1AClNO9S7ITjZOQTYlghCVKAkS1wvB/6TIjaw8DyREs
|
328
|
+
# f6WvtkzQA/vZc4mXE+YM/calL8ee3wVEJJzlGBfuh8mQhxtiLa5PTl7Icv/R8DGV
|
329
|
+
# 9hU9GkJgWdi/+Plpqdcv79OWVMTB7igmoN8PAPPfAoGAKqatwI04AygYKbhPB2bB
|
330
|
+
# W2Vpoi6NqAaAUdCg4mXvO8i8daw/u+0FVf8B4y6PkB6pmGX/diIFum2dE1MaRyY0
|
331
|
+
# mHdZS8AyWHmEOnSPY0igceiBWbV9mgZ769c2d3hBtir5aQtWczc2cWpE5MPJQ3vN
|
332
|
+
# H8HtcIWfEQb7ad5f548/QakCgYEAwFDjNRYOkePQ+Vrbjg+/HKRH+mpDId9Xv4eI
|
333
|
+
# H6R2N9/eJHIxMeFCB1Ll1PAaG6wR3ftn6YWnykEtvKpTU+VvQCZI5MYLqTgH2Ofh
|
334
|
+
# DgOoCfmoNF922SwuerqPvSlwxt8hPOt/PZVkbuEMZr1lPgVRGwPOHmKYP2yPrkw/
|
335
|
+
# 6p+1BtsCgYABmMLgWhXVD19XxNHm8XpGnPWTEjqAYrw6I5yDUwNhB0n4129qaC+x
|
336
|
+
# MWrdslKBmQh1r1U5QoSSL0CY4Ef5qN02uZl15FN1kYQzZA6kJi+MoBsjzrZCvzsc
|
337
|
+
# Bbahpg363PyHC75zgvazvOr4tK3mzaRi5RNTMgivTVu4FyhkRdJ5wQ==
|
338
|
+
# -----END RSA PRIVATE KEY-----"
|
339
|
+
|
340
|
+
bob_pub
|
341
|
+
#=> "-----BEGIN PUBLIC KEY-----
|
342
|
+
# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzADannvKlfVkZmKA4EDI
|
343
|
+
# xTW0HiJzjD6Auh8wLi02+iz2BSczfECA65Zv+KHfc1B9AWMqGeBIwFE49NrsnXiZ
|
344
|
+
# wZR3DqcFS8WbnVqpntvhwzlEARnaRWmZ2XjloD7fxILbXtWfMFNjwSfaK0bpArLk
|
345
|
+
# rt9d8eni+JI42+ptIWs/bVynACqmDqOTjoEgajuHVpxHtskPNQrsjxzP+umsUWkb
|
346
|
+
# E0iaO7oN1pcgZIR4VRr0bz/3JuifWmiCgwbDZo1WolfveoCacVsfAB1iesxeWnrG
|
347
|
+
# IJUjq8Mqsu9mQz1dg6RF4ElwNJ57G3T3nlW+qpVBZDU2sHFqUFxbGmWPdRUn1yn4
|
348
|
+
# KwIDAQAB
|
349
|
+
# -----END PUBLIC KEY-----"
|
350
|
+
|
351
|
+
|
352
|
+
tx = "from: alice, to: bob, $21"
|
353
|
+
tx_hash = sha256( tx )
|
354
|
+
#=> "426a472a6c69bf68354391b7822393bea3952cde9df8949ad7a0f5f405b2fcb5"
|
355
|
+
|
356
|
+
tx_signature = RSA.sign( tx_hash, alice_key )
|
357
|
+
#=> "xfhzC6tzXYmA5rFAFybJ9KeWnTcTnC0Plt7cSHky6ZSdBZRKz/sfFcpyIN7w
|
358
|
+
# jWrdPwEREA3nwNu/HSpiGRBFr+lu/YgWGNp6HLGPeL7uHGAfmWPyU5WRzGzf
|
359
|
+
# iEs5B6kdJ3S8LSbP0hkOD8AOgZLPeU5rzA4+/Ymt8e/UOVwwka6Gj13yoBua
|
360
|
+
# mSdsVuQfgh2VpySejCz4ykYlMSHK8Kx8QFt+QbyI5QZUy2dFh6HlcnHR+G9A
|
361
|
+
# RMRZ1vAuQhYqtDSsxwRcZCSFsc6uctAvsgFinhqy6ls5VpcXfuKwZhKAw3Di
|
362
|
+
# E2MYUnT7+i38Mq26iWzgmDbpOrVCO5tjlSiHY1731A=="
|
363
|
+
|
364
|
+
RSA.valid_signature?( tx_hash, tx_signature, alice_pub )
|
365
|
+
#=> true
|
366
|
+
|
367
|
+
tx = "from: alice, to: bob, $22"
|
368
|
+
tx_hash = sha256( tx )
|
369
|
+
#=> "e899604bb4c95d2f1a7cfe561ad65941769e2064bdbbcaa79eb64ce0a2832380"
|
370
|
+
|
371
|
+
RSA.valid_signature?( tx_hash, tx_signature, alice_pub )
|
372
|
+
#=> false
|
373
|
+
```
|
374
|
+
|
375
|
+
|
376
|
+
and some more.
|
377
|
+
|
378
|
+
|
379
|
+
|
380
|
+
|
381
|
+
|
382
|
+
## Examples
|
383
|
+
|
384
|
+
### Generate the Bitcoin (Base58) Address from the (Elliptic Curve) Public Key
|
385
|
+
|
386
|
+
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):
|
387
|
+
|
388
|
+
``` ruby
|
389
|
+
# Lets start with the public key ("raw" hex string encoded)
|
390
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
391
|
+
|
392
|
+
# 1. Perform SHA-256 hashing on the public key
|
393
|
+
step1 = sha256( pk )
|
394
|
+
#=> "0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98"
|
395
|
+
|
396
|
+
# 2. Perform RIPEMD-160 hashing on the result of SHA-256
|
397
|
+
step2 = ripemd160( step1 )
|
398
|
+
#=> "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
399
|
+
|
400
|
+
# 3. Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
|
401
|
+
step3 = "00" + step2
|
402
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
403
|
+
|
404
|
+
# 4. Perform SHA-256 hash on the extended RIPEMD-160 result
|
405
|
+
step4 = sha256( step3 )
|
406
|
+
#=> "ad3c854da227c7e99c4abfad4ea41d71311160df2e415e713318c70d67c6b41c"
|
407
|
+
|
408
|
+
# 5. Perform SHA-256 hash on the result of the previous SHA-256 hash
|
409
|
+
step5 = sha256( step4 )
|
410
|
+
#=> "c7f18fe8fcbed6396741e58ad259b5cb16b7fd7f041904147ba1dcffabf747fd"
|
411
|
+
|
412
|
+
# 6. Take the first 4 bytes of the second SHA-256 hash. This is the address checksum
|
413
|
+
step6 = step5[0..7] # note: 4 bytes in hex string are 8 digits/chars
|
414
|
+
#=> "c7f18fe8"
|
415
|
+
|
416
|
+
# 7. Add the 4 checksum bytes from step 6 at the end of
|
417
|
+
# extended RIPEMD-160 hash from step 3.
|
418
|
+
# This is the 25-byte binary Bitcoin Address.
|
419
|
+
step7 = step3 + step6
|
420
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31c7f18fe8"
|
421
|
+
|
422
|
+
# 8. Convert the result from a byte string into a base58 string using Base58 encoding.
|
423
|
+
# This is the most commonly used Bitcoin Address format.
|
424
|
+
addr = base58( step7 )
|
425
|
+
#=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
426
|
+
```
|
427
|
+
|
428
|
+
Or let's try again with the shortcut helpers:
|
429
|
+
|
430
|
+
- `HASH160 - RMD160(SHA256(X))`
|
431
|
+
- `BASE58CHECK - BASE58(X || SHA256(SHA256(X))[:4])`
|
432
|
+
|
433
|
+
``` ruby
|
434
|
+
# Lets start with the public key ("raw" hex string encoded)
|
435
|
+
pk = "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
|
436
|
+
|
437
|
+
# 1. Perform HASH-160 hashing on the public key
|
438
|
+
# a) Perform SHA-256 hashing on the public key
|
439
|
+
# b) Perform RIPEMD-160 hashing on the result of SHA-256
|
440
|
+
step1 = hash160( pk )
|
441
|
+
#=> "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
442
|
+
|
443
|
+
# 2. Add version byte in front of RIPEMD-160 hash (0x00 for Main Network)
|
444
|
+
step2 = "00" + step1
|
445
|
+
#=> "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31"
|
446
|
+
|
447
|
+
# 3. Encode with BASE58CHECK
|
448
|
+
# a) Perform SHA-256 hash on the extended RIPEMD-160 result
|
449
|
+
# b) Perform SHA-256 hash on the result of the previous SHA-256 hash
|
450
|
+
# c) Take the first 4 bytes of the second SHA-256 hash. This is the address checksum
|
451
|
+
# d) Add the 4 checksum bytes at the end of
|
452
|
+
# extended RIPEMD-160 hash from step 2.
|
453
|
+
# This is the 25-byte binary Bitcoin Address.
|
454
|
+
# e) Convert the result from a byte string into a base58 string
|
455
|
+
# using Base58 encoding.
|
456
|
+
# This is the most commonly used Bitcoin Address format.
|
457
|
+
addr = base58check( step2 )
|
458
|
+
#=> "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs"
|
459
|
+
```
|
460
|
+
|
461
|
+
|
462
|
+
References
|
463
|
+
|
464
|
+
- [How to create Bitcoin Address](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses#How_to_create_Bitcoin_Address)
|
465
|
+
- [Ruby Quiz #15 - Generate the Bitcoin (Base58) Address from the (Elliptic Curve) Public Key](https://github.com/planetruby/quiz/tree/master/015)
|
466
|
+
|
467
|
+
Bonus: Bitcon Tip - How to Buy Bitcoin (The CO₂-Friendly Way)
|
468
|
+
|
469
|
+
> 1. Take one $50 bill, five $10 bills, or ten $5 bills (I wouldn't recommend change - stay with paper money).
|
470
|
+
> 2. Go to the bathroom.
|
471
|
+
> 3. Lift the lid of the loo.
|
472
|
+
> 4. Throw money in.
|
473
|
+
> 5. Flush down water.
|
474
|
+
>
|
475
|
+
> Congrats! You just purchased $50 worth of Bitcoin - without fucking the planet!
|
476
|
+
>
|
477
|
+
> -- Trolly McTrollface, Bitcon Greater Fool Court Jester
|
478
|
+
|
479
|
+
Read more [Crypto Quotes »](https://github.com/openblockchains/crypto-quotes)
|
480
|
+
|
481
|
+
|
482
|
+
|
483
|
+
|
484
|
+
## Install
|
485
|
+
|
486
|
+
Just install the gem:
|
487
|
+
|
488
|
+
$ gem install crypto-lite
|
489
|
+
|
490
|
+
|
491
|
+
## License
|
492
|
+
|
493
|
+
The scripts are dedicated to the public domain.
|
494
|
+
Use it as you please with no restrictions whatsoever.
|
495
|
+
|
496
|
+
|
497
|
+
## Questions? Comments?
|
498
|
+
|
499
|
+
Send them along to the [wwwmake forum](http://groups.google.com/group/wwwmake).
|
500
|
+
Thanks!
|
501
|
+
|