Skip to content

Instantly share code, notes, and snippets.

@pierrenoizat
Created November 26, 2024 21:16
Show Gist options
  • Save pierrenoizat/d53e9604c78a7fab3f668105f421deed to your computer and use it in GitHub Desktop.
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
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