Skip to content

Instantly share code, notes, and snippets.

View KamilLelonek's full-sized avatar
🏋️‍♂️
Do you even lift?

Kamil Lelonek KamilLelonek

🏋️‍♂️
Do you even lift?
View GitHub Profile
def prepend_index(private_key), do: <<0::8, private_key::binary>>
@version_numbers %{
private: %{
main: <<4, 136, 173, 228>>,
test: <<4, 53, 131, 148>>
},
public: %{
main: <<4, 136, 178, 30>>,
test: <<4, 53, 135, 207>>
}
}
decoded_seed = Base.decode16!(seed, case: :lower)
hashed_seed = :crypto.hmac(:sha512, "Bitcoin seed", decoded_seed)
<<private_key::binary-32, chain_code::binary-32>> = hashed_seed
{private_key, chain_code}
defp iterate(_mnemonic, round_number, _previous_block, result)
when round_number > @rounds_count,
do: result
defp iterate(mnemonic, round_number, previous_block, result) do
with next_block = :crypto.hmac(:sha512, mnemonic, previous_block),
do: iterate(mnemonic, round_number + 1, next_block, :crypto.exor(next_block, result))
end
defp pbkdf2(initial_block, mnemonic),
do: iterate(mnemonic, @initial_round_number + 1, initial_block, initial_block)
def generate(mnemonic, passphrase \\ "") do
passphrase
|> salt()
|> initial_round(mnemonic)
|> pbkdf2(mnemonic)
end
defp hmac_sha512(key, data), do: :crypto.hmac(:sha512, key, data)
defp salt(passphrase \\ ""), do: "mnemonic" <> passphrase
~r/.{1,11}/
|> Regex.scan(entropy)
|> List.flatten()
|> Enum.map(fn part ->
index = String.to_integer(part, 2)
Enum.at(@words, index)
end)
|> Enum.join(" ")
String.slice(binary_string, 0..(checksum_length - 1))