class Analyzers::VigenereXor
Public Instance Methods
analyse_single(buf,key_length)
click to toggle source
# File lib/crypto-toolbox/analyzers/vigenere_xor.rb, line 99 def analyse_single(buf,key_length) candidate_map = Analyzers::Utils::KeyCandidateMap.create(buf,key_length) candidate_amount = candidate_map.map{|k,v| v.length}.reduce(&:*) if candidate_amount.zero? jot("no combinations for keylen #{key_length} (at least one byte has no candidates)",debug: true) return [] end jot "Amount of candidate keys: #{candidate_map.map{|k,v| v.length}.reduce(&:*)}. Starting Permutation (RAM intensive)",debug: true # split the candidate map into head and*tail to create the prduct of all combinations head,*tail = candidate_map.map{|k,v|v} begin combinations = head.product(*tail) # we simply skip too big products rescue RangeError => ex jot "keylen: #{key_length}: #{ex}" return [] end if ENV["DEBUG_ANALYSIS"] ensure_consistent_result!(combinations,candidate_map) print_candidate_decryptions(candidate_map,key_length,buf) end keys = Analyzers::Utils::KeyFilter::AsciiPlain.new(combinations,buf).filter.reject(&:empty?) # return the result, not the key keys.map do|key| key.xor(buf) end end
analyze(input, keylength_strategy=EightBitPatternFinder.new)
click to toggle source
# File lib/crypto-toolbox/analyzers/vigenere_xor.rb, line 89 def analyze(input, keylength_strategy=EightBitPatternFinder.new) buf = CryptBuffer.from_hex(input) keylength_strategy.keylen_for(buf).map do |keylen| analyse_single(buf,keylen) end.flatten end
Private Instance Methods
ensure_consistent_result!(combinations,candidate_map)
click to toggle source
# File lib/crypto-toolbox/analyzers/vigenere_xor.rb, line 138 def ensure_consistent_result!(combinations,candidate_map) # NOTE Consistency check ( enable if you dont trust the generation anymore ) # make sure all permutations are still according to the bytes per position map combinations.select do |arr| raise "Inconsistent key candidate combinations" unless arr.map.with_index{|e,i| candidate_map[i].include?(e) }.all?{|e| e ==true} end end
print_candidate_decryptions(candidate_map,keylen,buf)
click to toggle source
# File lib/crypto-toolbox/analyzers/vigenere_xor.rb, line 146 def print_candidate_decryptions(candidate_map,keylen,buf) # printout for debugging. (Manual analysis of the characters) print "======= Decryption result of first #{keylen} bytes with all candidate keys =======\n" (0..keylen-1).each do|i| candidate_map[i].each do |byte| print CryptBuffer.new(buf.bytes[i,keylen]).xor(byte).to_s + " " end print "\n" end print_delimiter_line end