Class: BipMnemonic

Inherits:
Object
  • Object
show all
Defined in:
lib/bip_mnemonic.rb

Constant Summary collapse

VERSION =
"0.0.2"

Class Method Summary collapse

Class Method Details

.checksum(entropy_binary) ⇒ Object



40
41
42
43
44
# File 'lib/bip_mnemonic.rb', line 40

def self.checksum(entropy_binary)
  sha256hash = OpenSSL::Digest::SHA256.hexdigest([entropy_binary].pack("B*"))
  sha256hash_binary = [sha256hash].pack("H*").unpack("B*").first
  binary_checksum = sha256hash_binary.slice(0,(entropy_binary.length/32))
end

.to_entropy(options) ⇒ Object

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/bip_mnemonic.rb', line 20

def self.to_entropy(options)
  options ||= {}
  raise ArgumentError, "Mnemonic not set" if options[:mnemonic].nil?
  raise ArgumentError, "Mnemonic is empty" if options[:mnemonic] == ""
  words_array = File.readlines(File.join(File.dirname(File.expand_path(__FILE__)), '../words/english.txt')).map(&:strip)
  mnemonic_array = options[:mnemonic].split(" ").map do |word|
    word_index = words_array.index(word)
    raise IndexError, "Word not found in words list" if word_index.nil?
    word_index.to_s(2).rjust(11,"0")
  end
  mnemonic_binary_with_checksum = mnemonic_array.join.to_s
  entropy_binary = mnemonic_binary_with_checksum.slice(0,mnemonic_binary_with_checksum.length*32/33)
  checksum_bits = mnemonic_binary_with_checksum.slice(-(entropy_binary.length/32),(entropy_binary.length/32))
  if checksum(entropy_binary) == checksum_bits
    return [entropy_binary].pack("B*").unpack("H*").first
  else
    raise SecurityError, "Checksum mismatch, invalid mnemonic"
  end
end

.to_mnemonic(options) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/bip_mnemonic.rb', line 5

def self.to_mnemonic(options)
  options ||= {}
  bits = options[:bits] || 128
  unless options[:entropy].nil?
    raise ArgumentError, "Entropy is empty" if options[:entropy] == ""
    entropy_bytes = [options[:entropy]].pack("H*")
  else
    entropy_bytes = OpenSSL::Random.pseudo_bytes(bits/8)
  end
  entropy_binary = entropy_bytes.unpack("B*").first
  seed_binary = entropy_binary + checksum(entropy_binary)
  words_array = File.readlines(File.join(File.dirname(File.expand_path(__FILE__)), '../words/english.txt')).map(&:strip)
  seed_binary.chars.each_slice(11).map(&:join).map{|item| item.to_i(2)}.map {|i| words_array[i]}.join(" ")
end

.to_seed(options) ⇒ Object

Raises:

  • (ArgumentError)


46
47
48
49
# File 'lib/bip_mnemonic.rb', line 46

def self.to_seed(options)
  raise ArgumentError, "Mnemonic not set" if options[:mnemonic].nil?
  PBKDF2.hex_string(password: options[:mnemonic], salt: "mnemonic#{options[:password]}", iterations: 2048, hash_function: OpenSSL::Digest::SHA512, key_length: 512)
end