Module: Crypto

Defined in:
lib/crypto-lite.rb

Defined Under Namespace

Modules: RSA

Constant Summary collapse

HEX_RE =

check if it is a hex (string)

- allow optiona 0x or 0X  and allow abcdef and ABCDEF
/\A(?:0x)?[0-9a-f]+\z/i

Class Method Summary collapse

Class Method Details

.hash160(input) ⇒ Object



123
124
125
126
# File 'lib/crypto-lite.rb', line 123

def self.hash160( input )
  input = hex_to_bin_automagic( input )  ## add automagic hex (string) to bin (string) check - why? why not?

  hash160bin( input ).unpack( 'H*' )[0]
end

.hash160bin(input) ⇒ Object

helper def hash160( pubkey )

binary    = [pubkey].pack( "H*" )       # Convert to binary first before hashing
sha256    = Digest::SHA256.digest( binary )
ripemd160 = Digest::RMD160.digest( sha256 )
            ripemd160.unpack( "H*" )[0]    # Convert back to hex

end



117
118
119
120
121
# File 'lib/crypto-lite.rb', line 117

def self.hash160bin( input )
  message = message( input )   ## "normalize" / convert to (binary) string


  rmd160bin(sha256bin( message ))
end

.hash160hex(input) ⇒ Object

convenience helper - lets you pass in hex string

Raises:

  • (ArgumentError)


128
129
130
131
132
133
# File 'lib/crypto-lite.rb', line 128

def self.hash160hex( input )  ## convenience helper - lets you pass in hex string

  raise ArgumentError, "expected hex string (0-9a-f) - got >#{input}< - can't pack string; sorry"   unless input =~ HEX_RE

  input = strip0x( input )  ##  check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!

  hash160bin( [input].pack( 'H*' ) ).unpack( 'H*' )[0]
end

.hash256(input) ⇒ Object



143
144
145
146
# File 'lib/crypto-lite.rb', line 143

def self.hash256( input )
  input = hex_to_bin_automagic( input )  ## add automagic hex (string) to bin (string) check - why? why not?

  hash256bin( input ).unpack( 'H*' )[0]
end

.hash256bin(input) ⇒ Object



137
138
139
140
141
# File 'lib/crypto-lite.rb', line 137

def self.hash256bin( input )
  message = message( input )   ## "normalize" / convert to (binary) string


  sha256bin(sha256bin( message ))
end

.hash256hex(input) ⇒ Object

convenience helper - lets you pass in hex string

Raises:

  • (ArgumentError)


148
149
150
151
152
153
# File 'lib/crypto-lite.rb', line 148

def self.hash256hex( input )  ## convenience helper - lets you pass in hex string

  raise ArgumentError, "expected hex string (0-9a-f) - got >#{input}< - can't pack string; sorry"   unless input =~ HEX_RE

  input = strip0x( input )  ##  check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!

  hash256bin( [input].pack( 'H*' ) ).unpack( "H*" )[0]
end

.hex_to_bin(str) ⇒ Object



182
183
184
185
# File 'lib/crypto-lite.rb', line 182

def self.hex_to_bin( str )
  str = strip0x( str )  ##  check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!

  [str].pack( 'H*' )
end

.hex_to_bin_automagic(input) ⇒ Object

more helpers



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/crypto-lite.rb', line 158

def self.hex_to_bin_automagic( input )
  ## todo/check/fix: add configure setting to turn off automagic - why? why not?

   if input.is_a?( String ) && input =~ HEX_RE
      if input[0,2] == '0x' || input[0,2] == '0X'
        ## starting with 0x or 0X always assume hex string for now - why? why not?

        input = input[2..-1]
        [input].pack( 'H*' )
      elsif input.size >= 10
        ## note: hex heuristic!!

        ##   for now assumes string MUST have more than 10 digits to qualify!!!

        [input].pack( 'H*' )
      else
        input ## pass through as is!!! (e.g.   a, abc, etc.)

      end
   else
        input  ## pass through as is

   end
end

.keccak256(input) ⇒ Object



60
61
62
63
# File 'lib/crypto-lite.rb', line 60

def self.keccak256( input )
  input = hex_to_bin_automagic( input )  ## add automagic hex (string) to bin (string) check - why? why not?

  keccak256bin( input ).unpack( 'H*' )[0]
end

.keccak256bin(input) ⇒ Object



55
56
57
58
# File 'lib/crypto-lite.rb', line 55

def self.keccak256bin( input )
  message = message( input )   ## "normalize" / convert to (binary) string

  Digest::SHA3.digest( message, 256 )
end

.message(input) ⇒ Object

convert input to (binary) string



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/crypto-lite.rb', line 26

def self.message( input )  ## convert input to (binary) string

  input_type = if input.is_a?( String )
                "#{input.class.name}/#{input.encoding}"
               else
                input.class.name
               end
  puts "  input: #{input} (#{input_type})"

  message = if input.is_a?( Integer )  ## assume byte if single (unsigned) integer

              raise ArgumentError, "expected unsigned byte (0-255) - got #{input} (0x#{input.to_s(16)}) - can't pack negative number; sorry"   if input < 0
              ## note: pack -  H (String) => hex string (high nibble first)

              ## todo/check: is there a better way to convert integer number to (binary) string!!!

              [input.to_s(16)].pack('H*')
            else  ## assume (binary) string

              input
            end

  bytes = message.bytes
  bin   = bytes.map {|byte| byte.to_s(2).rjust(8, "0")}.join( ' ' )
  hex   = bytes.map {|byte| byte.to_s(16).rjust(2, "0")}.join( ' ' )
  puts "  #{pluralize( bytes.size, 'byte')}:  #{bytes.inspect}"
  puts "  binary: #{bin}"
  puts "  hex:    #{hex}"

  message
end

.pluralize(count, noun) ⇒ Object



187
188
189
# File 'lib/crypto-lite.rb', line 187

def self.pluralize( count, noun )
   count == 1 ? "#{count} #{noun}" : "#{count} #{noun}s"
end

.rmd160(input) ⇒ Object



72
73
74
75
# File 'lib/crypto-lite.rb', line 72

def self.rmd160( input )
  input = hex_to_bin_automagic( input )  ## add automagic hex (string) to bin (string) check - why? why not?

  rmd160bin( input ).unpack( 'H*' )[0]
end

.rmd160bin(input) ⇒ Object



67
68
69
70
# File 'lib/crypto-lite.rb', line 67

def self.rmd160bin( input )
  message = message( input )   ## "normalize" / convert to (binary) string

  Digest::RMD160.digest( message )
end

.sha256(input, engine = nil) ⇒ Object



93
94
95
96
# File 'lib/crypto-lite.rb', line 93

def self.sha256( input, engine=nil )
  input = hex_to_bin_automagic( input )  ## add automagic hex (string) to bin (string) check - why? why not?

  sha256bin( input, engine ).unpack( 'H*' )[0]
end

.sha256bin(input, engine = nil) ⇒ Object

todo/check: add alias sha256b or such to - why? why not?



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/crypto-lite.rb', line 80

def self.sha256bin( input, engine=nil )   ## todo/check: add alias sha256b or such to - why? why not?

     message = message( input )  ## "normalize" / convert to (binary) string


     if engine && ['openssl'].include?( engine.to_s.downcase )
       puts "  engine: #{engine}"
       digest = OpenSSL::Digest::SHA256.new
       digest.update( message )
       digest.digest
     else  ## use "built-in" hash function from digest module

       Digest::SHA256.digest( message )
     end
end

.sha256hex(input, engine = nil) ⇒ Object

convenience helper - lets you pass in hex string

Raises:

  • (ArgumentError)


99
100
101
102
103
104
# File 'lib/crypto-lite.rb', line 99

def self.sha256hex( input, engine=nil )  ## convenience helper - lets you pass in hex string

  raise ArgumentError, "expected hex string (0-9a-f) - got >#{input}< - can't pack string; sorry"   unless input =~ HEX_RE

  input = strip0x( input )  ##  check if input starts with 0x or 0X if yes - (auto-)cut off!!!!!

  sha256bin( [input].pack( 'H*' ), engine ).unpack( 'H*' )[0]
end

.strip0x(str) ⇒ Object

todo/check: add alias e.g. strip_hex_prefix or such - why? why not?



178
179
180
# File 'lib/crypto-lite.rb', line 178

def self.strip0x( str )    ## todo/check: add alias e.g. strip_hex_prefix or such - why? why not?

  (str[0,2] == '0x' || str[0,2] == '0X') ?  str[2..-1] : str
end