crypto-lite 0.2.3 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7326c07c1553f4f15d79ddbfa19df2ad5dd04bb18e769ccbf564ee521aa97405
4
- data.tar.gz: 9602382da425f288147cc4a1a9e5f0fc373dc9f8838204886c990a9e4b611be6
3
+ metadata.gz: e32db0712ee1ed53c0720f9dee44533ffb8482e3d9ac6f5bd7a7e6a5c716cdc8
4
+ data.tar.gz: c3e8da15486a23e26d72c97c96bfc4f4c1847c420e7bff833c0ed87efe61303c
5
5
  SHA512:
6
- metadata.gz: 8b607671748a9035dce0b505ec757397416f2a70193e8d5890a90815bba03bbeff874ec878462b950427a372657889344f16b04c8349286165a70a61fd48fa86
7
- data.tar.gz: bc6ad174e2d5fe8c0b75853bd66e7b69ee963024c33f797b9043a836cbe25fee7b5ada35c2c5c144fc5dad93b80859de4e9b3fb09fe34b5390c0a58b654c7363
6
+ metadata.gz: a6593de7e55dbaa353cef41df3cf25cf04fd17cef78f9e2c62fbdcf0bf234627e4ec0dc2f238a341d5de8fa8b3ae33045cb8cf468c80f5ea8a55f312ff7cc0a0
7
+ data.tar.gz: 2e54d60bd80f34568ff7a6852fc3da01d3066131d4c177c023c1c15b4497fe18af7ad28851668b9c45223cab4f7eb8089759fc9e51fac714820b4a7d3a509ef7
data/README.md CHANGED
@@ -38,6 +38,7 @@ Bonus Back Stage Tip: How does SHA256 work?
38
38
 
39
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
40
 
41
+ More of a code golfer? See [½ Kilo of SHA256](https://idiosyncratic-ruby.com/51-half-kilo-of-sha256.html) by Jan Lelis - yes, the SHA256 algorithm coded (from scratch) in 500 bytes of ruby.
41
42
 
42
43
 
43
44
  Onwards with more sha256 examples:
@@ -259,122 +260,131 @@ unbase58check( "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs" ) #=> "00f54a5851e9372b878
259
260
 
260
261
  ### Public Key Signature Algorithms
261
262
 
262
- **RSA - Rivest, Shamir and Adleman**
263
263
 
264
+ **Elliptic Curve Digital Signature Algorithm (ECDSA)**
265
+
266
+
267
+ Private Key
268
+
269
+ An ECDSA (Elliptic Curve Digital Signature Algorithm) private key is a random number between 1 and the order of the elliptic curve group.
264
270
 
265
271
 
266
272
  ``` 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 )
273
+ # Auto-generate (random) private key
274
+ private_key = EC::PrivateKey.generate # by default uses Secp256k1 curve (used in Bitcoin and Ethereum)
275
+
276
+ private_key.to_i
277
+ #=> 72190737707147846840353520312904745954595478835413056312168022784020322830309
278
+ ```
279
+
280
+
281
+ (Auto-)Calculate the Public Key - Enter Elliptic Curve (EC) Cryptography
282
+
283
+ The public key are two numbers (that is, a point with the coordinates x and y) computed by multiplying
284
+ the generator point (`G`) of the curve with the private key.
285
+ This is equivalent to adding the generator to itself `private_key` times.
286
+ Magic?
287
+ Let's try:
288
+
289
+
290
+ ``` ruby
291
+ # This private key is just an example. It should be much more secure!
292
+ private_key = EC::PrivateKey.new( 1234 ) # by default uses Secp256k1 curve (used in Bitcoin and Ethereum)
293
+
294
+ public_key = private_key.public_key ## the "magic" one-way K=k*G curve multiplication (K=public key,k=private key, G=generator point)
295
+ point = public_key.point
296
+
297
+ point.x
298
+ #=> 102884003323827292915668239759940053105992008087520207150474896054185180420338
299
+ point.y
300
+ #=> 49384988101491619794462775601349526588349137780292274540231125201115197157452
301
+
302
+ point.x.to_s(16)
303
+ #=> "e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2"
304
+ point.y.to_s(16)
305
+ #=> "6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c"
306
+ ```
307
+
308
+
309
+ Sign a transaction with an (elliptic curve) private key:
310
+
311
+ ``` ruby
312
+ # Step 1 - Calculate the Transaction (tx) Hash
313
+ tx = 'from: Alice to: Bob cryptos: 43_000_000_000'
314
+ txhash = sha256( tx )
315
+
316
+ # Step 2 - Get the Signer's Private key
317
+ private_key = EC::PrivateKey.new( 1234 ) # This private key is just an example. It should be much more secure!
318
+
319
+ # Sign!
320
+ signature = private_key.sign( txhash )
321
+ # -or-
322
+ signature = EC.sign( txhash, private_key )
323
+
324
+ signature.r
325
+ #=> 80563021554295584320113598933963644829902821722081604563031030942154621916407
326
+ signature.s
327
+ #=> 58316177618967642068351252425530175807242657664855230973164972803783751708604
328
+
329
+ signature.r.to_s(16)
330
+ #=> "3306a2f81ad2b2f62ebe0faec129545bc772babe1ca5e70f6e56556b406464c0"
331
+ signature.s.to_s(16)
332
+ #=> "4fe202bb0835758f514cd4a0787986f8f6bf303df629dc98c5b1a438a426f49a"
333
+ ```
334
+
335
+
336
+ Verify a signed transaction with an (elliptic curve) public key:
337
+
338
+ ``` ruby
339
+ # Step 1 - Calculate the Transaction (tx) Hash
340
+ tx = 'from: Alice to: Bob cryptos: 43_000_000_000'
341
+ txhash = sha256( tx )
342
+
343
+ # Step 2 - Get the Signer's Public Key
344
+ public_key = EC::PublicKey.new(
345
+ 102884003323827292915668239759940053105992008087520207150474896054185180420338,
346
+ 49384988101491619794462775601349526588349137780292274540231125201115197157452
347
+ )
348
+
349
+ # Step 3 - Get the Transaction's Signature
350
+ signature = EC::Signature.new(
351
+ 80563021554295584320113598933963644829902821722081604563031030942154621916407,
352
+ 58316177618967642068351252425530175807242657664855230973164972803783751708604
353
+ )
354
+
355
+ # Don't Trust - Verify
356
+ public_key.verify?( txhash, signature )
357
+ # -or-
358
+ EC.verify?( txhash, signature, public_key )
365
359
  #=> true
366
360
 
367
- tx = "from: alice, to: bob, $22"
368
- tx_hash = sha256( tx )
369
- #=> "e899604bb4c95d2f1a7cfe561ad65941769e2064bdbbcaa79eb64ce0a2832380"
370
361
 
371
- RSA.valid_signature?( tx_hash, tx_signature, alice_pub )
372
- #=> false
362
+ # or using hexadecimal numbers
363
+
364
+ public_key = EC::PublicKey.new(
365
+ 0xe37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2,
366
+ 0x6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c
367
+ )
368
+
369
+ signature = EC::Signature.new(
370
+ 0x3306a2f81ad2b2f62ebe0faec129545bc772babe1ca5e70f6e56556b406464c0,
371
+ 0x4fe202bb0835758f514cd4a0787986f8f6bf303df629dc98c5b1a438a426f49a
372
+ )
373
+
374
+ public_key.verify?( txhash, signature )
375
+ # -or-
376
+ EC.verify?( txhash, signature, public_key )
377
+ #=> true
373
378
  ```
374
379
 
375
380
 
376
- and some more.
381
+ To sum up:
382
+
383
+ - The (raw) private key is a 256-bit unsigned integer number
384
+ - The (raw) public key is a point (x,y), that is, two 256-bit unsigned integer numbers - derived (calculated) from the private key
385
+ - A (raw) signature is composed of (r,s), that is, two 256-bit unsigned integer numbers
377
386
 
387
+ That's all the magic.
378
388
 
379
389
 
380
390
 
data/Rakefile CHANGED
@@ -22,6 +22,7 @@ Hoe.spec 'crypto-lite' do
22
22
  ['digest-sha3-patched'],
23
23
  ['base32-alphabets'],
24
24
  ['base58-alphabets'],
25
+ ['elliptic'],
25
26
  ]
26
27
 
27
28
  self.licenses = ['Public Domain']
@@ -11,6 +11,7 @@ require 'digest/sha3' # e.g. keccak (original submission/proposal NOT official
11
11
  ## our own 3rd party (2nd party?)
12
12
  require 'base32-alphabets'
13
13
  require 'base58-alphabets'
14
+ require 'elliptic'
14
15
 
15
16
 
16
17
 
@@ -2,8 +2,8 @@
2
2
  module CryptoLite
3
3
 
4
4
  MAJOR = 0
5
- MINOR = 2
6
- PATCH = 3
5
+ MINOR = 3
6
+ PATCH = 0
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
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.3
4
+ version: 0.3.0
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-20 00:00:00.000000000 Z
11
+ date: 2021-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: digest-sha3-patched
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: elliptic
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rdoc
57
71
  requirement: !ruby/object:Gem::Requirement