Module: Crypto::Bech32

Defined in:
lib/wallet_validator/crypto/bech32.rb

Constant Summary collapse

CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l".split(//)
GENERATOR =
[0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3].freeze

Class Method Summary collapse

Class Method Details

.valid?(address, hrp, separator) ⇒ Boolean

Returns:

  • (Boolean)


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/wallet_validator/crypto/bech32.rb', line 6

def self.valid?(address, hrp, separator)
  address = address.downcase.strip

  match = address.match(/^#{hrp}#{separator}([\da-z]+)$/)
  return false if !match

  pos = address.rindex(separator)
  return false if pos.nil? || pos < 1 || pos + 7 > address.length || address.length > 108

  address[pos + 1..-1].each_char do |c|
    return false unless CHARSET.include?(c)
  end

  hrp = address[0..pos - 1]
  data = address[pos + 1..-1].each_char.map { |c| CHARSET.index(c) }
  chk = 1

  (hrp.each_char.map { |c| c.ord >> 5 } + [0] + hrp.each_char.map { |c| c.ord & 31 } + data).each do |v|
    top = chk >> 25
    chk = (chk & 0x1ffffff) << 5 ^ v
    (0..4).each do |i|
      chk ^= if ((top >> i) & 1).zero?
              0
            else
              GENERATOR[i]
            end
    end
  end
  chk == 1
end