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