derivator 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ module Derivator
2
+ # {https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP39} mnemonic generation.
3
+ class Mnemonic
4
+ # Word list (ordered). Only English is supported.
5
+ WORDS = File.readlines(__dir__ + '/word_lists/english.txt', chomp: true)
6
+
7
+ SEED_ITERATIONS = 2048
8
+ SEED_KEY_LENGTH = 64
9
+
10
+ class << self
11
+ # Generates 128 bits of random
12
+ #
13
+ # @return [String] 16 random bytes
14
+ def random_bytes
15
+ SecureRandom.random_bytes(128 / 8) # 128 bits
16
+ end
17
+
18
+ # Generates mnemonic.
19
+ #
20
+ # @param bytes [String] bytes to generate mnemonic from
21
+ # @return [String] mnemonic (12 words)
22
+ def generate(bytes = random_bytes)
23
+ checksum = OpenSSL::Digest::SHA256.new(bytes).digest[0..0]
24
+ checksum_bits = checksum[0..0].unpack('B4').first # first 4 bits
25
+ bits = bytes.unpack('B*').first + checksum_bits
26
+ mnemonic = bits.chars.
27
+ each_slice(11).
28
+ map(&:join).
29
+ map { |x| x.to_i(2) }.
30
+ map { |x| WORDS[x] }.
31
+ join(' ')
32
+ end
33
+
34
+ # Generates master seed.
35
+ #
36
+ # @param mnemonic [String] mnemonic (12 words) to generate seed from
37
+ # @param password [String] password
38
+ def seed(mnemonic, password = '')
39
+ salt = "mnemonic#{password}"
40
+ result_bytes = OpenSSL::KDF.pbkdf2_hmac(
41
+ mnemonic,
42
+ salt: salt,
43
+ iterations: SEED_ITERATIONS,
44
+ length: SEED_KEY_LENGTH,
45
+ hash: 'SHA512'
46
+ )
47
+ result_bytes.unpack('H*').first
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,37 @@
1
+ module Derivator
2
+ # Internally used refinements
3
+ module Refinements
4
+ refine String do
5
+ def to_hex
6
+ unpack('H*').first
7
+ end
8
+
9
+ def from_hex
10
+ [self].pack('H*')
11
+ end
12
+
13
+ def to_base64
14
+ Base64.encode64(self)
15
+ end
16
+
17
+ def from_base64
18
+ Base64.decode64(self)
19
+ end
20
+
21
+ def parse_der
22
+ OpenSSL::ASN1.decode(self)
23
+ end
24
+
25
+ def to_der_octet_string
26
+ OpenSSL::ASN1::OctetString.new(self)
27
+ end
28
+
29
+ # Returns BIP-0032 key identifier, interpreting string as binary key
30
+ def hash160
31
+ # https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers
32
+ r = OpenSSL::Digest::SHA256.new(self).digest
33
+ OpenSSL::Digest::RIPEMD160.new(r).digest
34
+ end
35
+ end
36
+ end
37
+ end