crypto-lite 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,34 +1,34 @@
1
- require 'hoe'
2
- require './lib/crypto-lite/version.rb'
3
-
4
-
5
- Hoe.spec 'crypto-lite' do
6
-
7
- self.version = CryptoLite::VERSION
8
-
9
- self.summary = "crypto-lite - cryptographic secure hash functions and public key signature algorithms made easy"
10
- self.description = summary
11
-
12
- self.urls = { home: 'https://github.com/rubycoco/blockchain' }
13
-
14
- self.author = 'Gerald Bauer'
15
- self.email = 'wwwmake@googlegroups.com'
16
-
17
- # switch extension to .markdown for gihub formatting
18
- self.readme_file = 'README.md'
19
- self.history_file = 'CHANGELOG.md'
20
-
21
- self.extra_deps = [
22
- ['digest-sha3-patched'],
23
- ['base32-alphabets'],
24
- ['base58-alphabets'],
25
- ['elliptic'],
26
- ]
27
-
28
- self.licenses = ['Public Domain']
29
-
30
- self.spec_extras = {
31
- required_ruby_version: '>= 2.3'
32
- }
33
-
34
- end
1
+ require 'hoe'
2
+ require './lib/crypto-lite/version.rb'
3
+
4
+
5
+ Hoe.spec 'crypto-lite' do
6
+
7
+ self.version = CryptoLite::VERSION
8
+
9
+ self.summary = "crypto-lite - cryptographic secure hash functions and public key signature algorithms made easy"
10
+ self.description = summary
11
+
12
+ self.urls = { home: 'https://github.com/rubycocos/blockchain' }
13
+
14
+ self.author = 'Gerald Bauer'
15
+ self.email = 'wwwmake@googlegroups.com'
16
+
17
+ # switch extension to .markdown for gihub formatting
18
+ self.readme_file = 'README.md'
19
+ self.history_file = 'CHANGELOG.md'
20
+
21
+ self.extra_deps = [
22
+ ['digest-lite'],
23
+ ['base32-alphabets'],
24
+ ['base58-alphabets'],
25
+ ['elliptic'],
26
+ ]
27
+
28
+ self.licenses = ['Public Domain']
29
+
30
+ self.spec_extras = {
31
+ required_ruby_version: '>= 2.3'
32
+ }
33
+
34
+ end
data/lib/crypto/lite.rb CHANGED
@@ -1,2 +1,2 @@
1
- require_relative '../crypto-lite' ## lets you use require 'crypto/lite' too
2
-
1
+ require_relative '../crypto-lite' ## lets you use require 'crypto/lite' too
2
+
@@ -1,32 +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
-
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
+
@@ -1,25 +1,25 @@
1
-
2
- module CryptoHelper
3
- ### note: use include CryptoHelper
4
- ## to get "top-level" / global helpers
5
-
6
- ## add convenience "top-level" helpers
7
- def sha256( *args, **kwargs ) Crypto.sha256( *args, **kwargs ); end
8
- def sha3_256( *args, **kwargs ) Crypto.sha3_256( *args, **kwargs ); end
9
-
10
- def keccak256( *args, **kwargs ) Crypto.keccak256( *args, **kwargs ); end
11
-
12
- def rmd160( *args, **kwargs ) Crypto.rmd160( *args, **kwargs ); end
13
- ## def ripemd160( input ) Crypto.rmd160( input ); end
14
- alias_method :ripemd160, :rmd160
15
-
16
- def hash160( *args, **kwargs ) Crypto.hash160( *args, **kwargs ); end
17
-
18
- def hash256( *args, **kwargs ) Crypto.hash256( *args, **kwargs ); end
19
-
20
-
21
- def base58( *args, **kwargs ) Crypto.base58( *args, **kwargs ); end
22
- def base58check( *args, **kwargs ) Crypto.base58check( *args, **kwargs ); end
23
- end
24
-
25
-
1
+
2
+ module CryptoHelper
3
+ ### note: use include CryptoHelper
4
+ ## to get "top-level" / global helpers
5
+
6
+ ## add convenience "top-level" helpers
7
+ def sha256( *args, **kwargs ) Crypto.sha256( *args, **kwargs ); end
8
+ def sha3_256( *args, **kwargs ) Crypto.sha3_256( *args, **kwargs ); end
9
+
10
+ def keccak256( *args, **kwargs ) Crypto.keccak256( *args, **kwargs ); end
11
+
12
+ def rmd160( *args, **kwargs ) Crypto.rmd160( *args, **kwargs ); end
13
+ ## def ripemd160( input ) Crypto.rmd160( input ); end
14
+ alias_method :ripemd160, :rmd160
15
+
16
+ def hash160( *args, **kwargs ) Crypto.hash160( *args, **kwargs ); end
17
+
18
+ def hash256( *args, **kwargs ) Crypto.hash256( *args, **kwargs ); end
19
+
20
+
21
+ def base58( *args, **kwargs ) Crypto.base58( *args, **kwargs ); end
22
+ def base58check( *args, **kwargs ) Crypto.base58check( *args, **kwargs ); end
23
+ end
24
+
25
+
@@ -1,128 +1,135 @@
1
- module Crypto
2
- module Metal
3
-
4
- def self.debug?() Crypto.debug?; end
5
-
6
- ########################
7
- ### to the "metal" crypto primitives
8
- ## work with binary strings (aka byte arrays) / data
9
-
10
- ##
11
- ## todo/check: use/keep bin-suffix in name - why? why not?
12
-
13
-
14
- def self.base58bin( input )
15
- ## todo/check: input must be a (binary) string - why? why not?
16
- Base58::Bitcoin.encode_bin( input )
17
- end
18
-
19
- def self.base58bin_check( input )
20
- ## todo/check: input must be a (binary) string - why? why not?
21
- hash256 = hash256bin( input )
22
- base58bin( input + hash256[0,4] )
23
- end
24
-
25
-
26
- ########################
27
- # (secure) hash functions
28
-
29
- def self.keccak256bin( input )
30
- message = message( input ) ## "normalize" / convert to (binary) string
31
- Digest::SHA3.digest( message, 256 )
32
- end
33
-
34
- def self.rmd160bin( input )
35
- message = message( input ) ## "normalize" / convert to (binary) string
36
- Digest::RMD160.digest( message )
37
- end
38
-
39
- ## add alias RIPEMD160 - why? why not?
40
- class << self
41
- alias_method :ripemd160bin, :rmd160bin
42
- end
43
-
44
-
45
- def self.sha256bin( input, engine=nil ) ## todo/check: add alias sha256b or such to - why? why not?
46
- message = message( input ) ## "normalize" / convert to (binary) string
47
-
48
- if engine && ['openssl'].include?( engine.to_s.downcase )
49
- puts " engine: #{engine}" if debug?
50
- digest = OpenSSL::Digest::SHA256.new
51
- ## or use OpenSSL::Digest.new( 'SHA256' )
52
- digest.update( message )
53
- digest.digest
54
- else ## use "built-in" hash function from digest module
55
- Digest::SHA256.digest( message )
56
- end
57
- end
58
-
59
- def self.sha3_256bin( input )
60
- message = message( input ) ## "normalize" / convert to (binary) string
61
-
62
- digest = OpenSSL::Digest.new( 'SHA3-256' )
63
- digest.update( message )
64
- digest.digest
65
- end
66
-
67
- ####
68
- ## helper
69
- # def hash160( pubkey )
70
- # binary = [pubkey].pack( "H*" ) # Convert to binary first before hashing
71
- # sha256 = Digest::SHA256.digest( binary )
72
- # ripemd160 = Digest::RMD160.digest( sha256 )
73
- # ripemd160.unpack( "H*" )[0] # Convert back to hex
74
- # end
75
-
76
- def self.hash160bin( input )
77
- message = message( input ) ## "normalize" / convert to (binary) string
78
-
79
- rmd160bin(sha256bin( message ))
80
- end
81
-
82
-
83
- def self.hash256bin( input )
84
- message = message( input ) ## "normalize" / convert to (binary) string
85
-
86
- sha256bin(sha256bin( message ))
87
- end
88
-
89
-
90
- ##############################
91
- ## helpers
92
- def self.message( input ) ## convert input to (binary) string
93
- if debug?
94
- input_type = if input.is_a?( String )
95
- "#{input.class.name}/#{input.encoding}"
96
- else
97
- input.class.name
98
- end
99
- puts " input: #{input} (#{input_type})"
100
- end
101
-
102
- message = if input.is_a?( Integer ) ## assume byte if single (unsigned) integer
103
- raise ArgumentError, "expected unsigned byte (0-255) - got #{input} (0x#{input.to_s(16)}) - can't pack negative number; sorry" if input < 0
104
- ## note: pack - H (String) => hex string (high nibble first)
105
- ## todo/check: is there a better way to convert integer number to (binary) string!!!
106
- [input.to_s(16)].pack('H*')
107
- else ## assume (binary) string
108
- input
109
- end
110
-
111
- if debug?
112
- bytes = message.bytes
113
- bin = bytes.map {|byte| byte.to_s(2).rjust(8, "0")}.join( ' ' )
114
- hex = bytes.map {|byte| byte.to_s(16).rjust(2, "0")}.join( ' ' )
115
- puts " #{pluralize( bytes.size, 'byte')}: #{bytes.inspect}"
116
- puts " binary: #{bin}"
117
- puts " hex: #{hex}"
118
- end
119
-
120
- message
121
- end
122
-
123
- def self.pluralize( count, noun )
124
- count == 1 ? "#{count} #{noun}" : "#{count} #{noun}s"
125
- end
126
-
127
- end # module Metal
128
- end # module Crypto
1
+ module Crypto
2
+ module Metal
3
+
4
+ def self.debug?() Crypto.debug?; end
5
+
6
+ ########################
7
+ ### to the "metal" crypto primitives
8
+ ## work with binary strings (aka byte arrays) / data
9
+
10
+ ##
11
+ ## todo/check: use/keep bin-suffix in name - why? why not?
12
+
13
+
14
+ def self.base58bin( input )
15
+ ## todo/check: input must be a (binary) string - why? why not?
16
+ Base58::Bitcoin.encode_bin( input )
17
+ end
18
+
19
+ def self.base58bin_check( input )
20
+ ## todo/check: input must be a (binary) string - why? why not?
21
+ hash256 = hash256bin( input )
22
+ base58bin( input + hash256[0,4] )
23
+ end
24
+
25
+
26
+ ########################
27
+ # (secure) hash functions
28
+
29
+ def self.keccak256bin( input )
30
+ message = message( input ) ## "normalize" / convert to (binary) string
31
+ Digest::KeccakLite.digest( message, 256 )
32
+ end
33
+
34
+ def self.rmd160bin( input )
35
+ message = message( input ) ## "normalize" / convert to (binary) string
36
+ Digest::RMD160.digest( message )
37
+ end
38
+
39
+ ## add alias RIPEMD160 - why? why not?
40
+ class << self
41
+ alias_method :ripemd160bin, :rmd160bin
42
+ end
43
+
44
+
45
+ def self.sha256bin( input, engine=nil ) ## todo/check: add alias sha256b or such to - why? why not?
46
+ message = message( input ) ## "normalize" / convert to (binary) string
47
+
48
+ if engine && ['openssl'].include?( engine.to_s.downcase )
49
+ puts " engine: #{engine}" if debug?
50
+ digest = OpenSSL::Digest::SHA256.new
51
+ ## or use OpenSSL::Digest.new( 'SHA256' )
52
+ digest.update( message )
53
+ digest.digest
54
+ else ## use "built-in" hash function from digest module
55
+ Digest::SHA256.digest( message )
56
+ end
57
+ end
58
+
59
+
60
+ def self.sha3_256bin( input, engine=nil )
61
+ message = message( input ) ## "normalize" / convert to (binary) string
62
+
63
+ if engine && ['openssl'].include?( engine.to_s.downcase )
64
+ puts " engine: #{engine}" if debug?
65
+ digest = OpenSSL::Digest.new( 'SHA3-256' )
66
+ digest.update( message )
67
+ digest.digest
68
+ else ## use "built-in" hash function from digest module
69
+ Digest::SHA3Lite.digest( message, 256 )
70
+ end
71
+ end
72
+
73
+
74
+ ####
75
+ ## helper
76
+ # def hash160( pubkey )
77
+ # binary = [pubkey].pack( "H*" ) # Convert to binary first before hashing
78
+ # sha256 = Digest::SHA256.digest( binary )
79
+ # ripemd160 = Digest::RMD160.digest( sha256 )
80
+ # ripemd160.unpack( "H*" )[0] # Convert back to hex
81
+ # end
82
+
83
+ def self.hash160bin( input )
84
+ message = message( input ) ## "normalize" / convert to (binary) string
85
+
86
+ rmd160bin(sha256bin( message ))
87
+ end
88
+
89
+
90
+ def self.hash256bin( input )
91
+ message = message( input ) ## "normalize" / convert to (binary) string
92
+
93
+ sha256bin(sha256bin( message ))
94
+ end
95
+
96
+
97
+ ##############################
98
+ ## helpers
99
+ def self.message( input ) ## convert input to (binary) string
100
+ if debug?
101
+ input_type = if input.is_a?( String )
102
+ "#{input.class.name}/#{input.encoding}"
103
+ else
104
+ input.class.name
105
+ end
106
+ puts " input: #{input} (#{input_type})"
107
+ end
108
+
109
+ message = if input.is_a?( Integer ) ## assume byte if single (unsigned) integer
110
+ raise ArgumentError, "expected unsigned byte (0-255) - got #{input} (0x#{input.to_s(16)}) - can't pack negative number; sorry" if input < 0
111
+ ## note: pack - H (String) => hex string (high nibble first)
112
+ ## todo/check: is there a better way to convert integer number to (binary) string!!!
113
+ [input.to_s(16)].pack('H*')
114
+ else ## assume (binary) string
115
+ input
116
+ end
117
+
118
+ if debug?
119
+ bytes = message.bytes
120
+ bin = bytes.map {|byte| byte.to_s(2).rjust(8, "0")}.join( ' ' )
121
+ hex = bytes.map {|byte| byte.to_s(16).rjust(2, "0")}.join( ' ' )
122
+ puts " #{pluralize( bytes.size, 'byte')}: #{bytes.inspect}"
123
+ puts " binary: #{bin}"
124
+ puts " hex: #{hex}"
125
+ end
126
+
127
+ message
128
+ end
129
+
130
+ def self.pluralize( count, noun )
131
+ count == 1 ? "#{count} #{noun}" : "#{count} #{noun}s"
132
+ end
133
+
134
+ end # module Metal
135
+ end # module Crypto
@@ -1,29 +1,29 @@
1
- module Crypto
2
-
3
-
4
- module RSA
5
- def self.generate_keys ## todo/check: add a generate alias - why? why not?
6
- key_pair = OpenSSL::PKey::RSA.new( 2048 )
7
- private_key = key_pair.export
8
- public_key = key_pair.public_key.export
9
-
10
- [private_key, public_key]
11
- end
12
-
13
-
14
- def self.sign( plaintext, private_key )
15
- private_key = OpenSSL::PKey::RSA.new( private_key ) ## note: convert/wrap into to obj from exported text format
16
- Base64.encode64( private_key.private_encrypt( plaintext ))
17
- end
18
-
19
- def self.decrypt( ciphertext, public_key )
20
- public_key = OpenSSL::PKey::RSA.new( public_key ) ## note: convert/wrap into to obj from exported text format
21
- public_key.public_decrypt( Base64.decode64( ciphertext ))
22
- end
23
-
24
-
25
- def self.valid_signature?( plaintext, ciphertext, public_key )
26
- plaintext == decrypt( ciphertext, public_key )
27
- end
28
- end # module RSA
29
- end # module Crypto
1
+ module Crypto
2
+
3
+
4
+ module RSA
5
+ def self.generate_keys ## todo/check: add a generate alias - why? why not?
6
+ key_pair = OpenSSL::PKey::RSA.new( 2048 )
7
+ private_key = key_pair.export
8
+ public_key = key_pair.public_key.export
9
+
10
+ [private_key, public_key]
11
+ end
12
+
13
+
14
+ def self.sign( plaintext, private_key )
15
+ private_key = OpenSSL::PKey::RSA.new( private_key ) ## note: convert/wrap into to obj from exported text format
16
+ Base64.encode64( private_key.private_encrypt( plaintext ))
17
+ end
18
+
19
+ def self.decrypt( ciphertext, public_key )
20
+ public_key = OpenSSL::PKey::RSA.new( public_key ) ## note: convert/wrap into to obj from exported text format
21
+ public_key.public_decrypt( Base64.decode64( ciphertext ))
22
+ end
23
+
24
+
25
+ def self.valid_signature?( plaintext, ciphertext, public_key )
26
+ plaintext == decrypt( ciphertext, public_key )
27
+ end
28
+ end # module RSA
29
+ end # module Crypto
@@ -1,23 +1,23 @@
1
-
2
- module CryptoLite
3
-
4
- MAJOR = 0
5
- MINOR = 3
6
- PATCH = 0
7
- VERSION = [MAJOR,MINOR,PATCH].join('.')
8
-
9
- def self.version
10
- VERSION
11
- end
12
-
13
- def self.banner
14
- "crypto-lite/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
15
- end
16
-
17
- def self.root
18
- File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
19
- end
20
-
21
- end # module CryptoLite
22
-
23
-
1
+
2
+ module CryptoLite
3
+
4
+ MAJOR = 0
5
+ MINOR = 3
6
+ PATCH = 1
7
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
8
+
9
+ def self.version
10
+ VERSION
11
+ end
12
+
13
+ def self.banner
14
+ "crypto-lite/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
15
+ end
16
+
17
+ def self.root
18
+ File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
19
+ end
20
+
21
+ end # module CryptoLite
22
+
23
+