Class: Msn::Challenge

Inherits:
Object
  • Object
show all
Defined in:
lib/msn/challenge.rb

Overview

:nodoc:

Constant Summary collapse

ProductKey =
"RG@XY*28Q5QHS%Q5"
ProductId =
"PROD0113H11T8$X_"
F =
"0x7FFFFFFF".to_i(16)
E =
"0x0E79A9C1".to_i(16)

Class Method Summary collapse

Class Method Details

.challenge(challenge, product_key = ProductKey, product_id = ProductId) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/msn/challenge.rb', line 9

def challenge(challenge, product_key = ProductKey, product_id = ProductId)
  md5hash = Digest::MD5.hexdigest "#{challenge}#{product_key}"
  md5array = md5hash.scan(/.{8}/)
  new_hash_parts = md5array.map! { |s| s.scan(/.{2}/).reverse.join.to_i(16) }
  md5array = new_hash_parts.map { |n| n & F }

  chlstring = "#{challenge}#{product_id}"
  chlstring = "#{chlstring}#{'0' * (8 - chlstring.length % 8)}"

  chlstring_array = chlstring.scan(/.{4}/)
  chlstring_array.map! { |str| str.bytes.map { |b| b.to_s(16) }.reverse.join.to_i(16) }

  low = high = 0

  i = 0
  while i < chlstring_array.length
    temp = (md5array[0] * (((E * chlstring_array[i]) % F) + high) + md5array[1]) % F
    high = (md5array[2] * ((chlstring_array[i + 1] + temp) % F) + md5array[3]) % F
    low = low + high + temp;

    i += 2
  end

  high = (high + md5array[1]) % F
  low = (low + md5array[3]) % F
  key = (high << 32) + low

  new_hash_parts[0] ^= high;
  new_hash_parts[1] ^= low;
  new_hash_parts[2] ^= high;
  new_hash_parts[3] ^= low;

  new_hash_parts.map do |num|
    str = num.to_s(16)
    str = "#{'0' * (8 - str.length)}#{str}" if str.length != 8
    str.scan(/.{2}/).reverse.join
  end.join
end