Created
November 26, 2024 21:16
-
-
Save pierrenoizat/d53e9604c78a7fab3f668105f421deed to your computer and use it in GitHub Desktop.
compute the checksum word knowing the first 11 words of a 12 word-mnemonic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'digest' | |
lang = "english" | |
mnemonic = "claim snack company sea faith vacant blame card come large add" # 11-word or 23-word mnemonic phrase to be completed with checksum word | |
wordlist = File.readlines(File.join(Dir.pwd, "#{lang}.txt"), chomp: true) | |
a = mnemonic.split(" ") | |
entropy = "" | |
a.each do |word| | |
n = 0 | |
digits = "" | |
while n < 2048 and word != wordlist[n] | |
n += 1 | |
end | |
if n == 2048 | |
puts "#{word} is not in bip39 #{lang} wordlist" | |
else | |
puts "#{word} is word #{n+1}" | |
end | |
digits = n.to_s(2).rjust(11, '0') | |
entropy += digits | |
end | |
i = 0 | |
size = (a.count + 1)/3 # checksum size is 8 bits for 256-bit entropy and 4 bits for 128-bit entropy | |
m = 11 - size | |
puts "Valid checksum words:" | |
while i < 2 ** m # number of valid checksum words to complete a given 11-word or 23-word sentence | |
s = i.to_s(2).rjust(m, '0') | |
i += 1 | |
e = entropy + s | |
sha256 = Digest::SHA256.digest([e].pack("B*")) | |
checksum = sha256.unpack("B*").join[0..size-1] | |
full = e + checksum | |
r = full.scan(/.{11}/).last.to_i(2) | |
word = wordlist[r] # get the corresponding checksum word from wordlist | |
puts "#{word} is word #{r+1}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment