1 #include <ail/array.hpp>
5 //code largely copied from JBLS
9 std::size_t const dword_size
= 4;
10 std::size_t const bits_per_byte
= 8;
13 void set_buffer_byte(unsigned * buffer
, std::size_t offset
, char byte
)
15 std::size_t index
= offset
/ dword_size
;
16 unsigned position
= offset
% dword_size
;
17 unsigned bit_offset
= bits_per_byte
* position
;
18 unsigned & dword
= buffer
[index
];
19 dword
&= (0xff << bit_offset
) ^ 0xffffffff;
20 dword
|= byte
<< bit_offset
;
23 char get_buffer_byte(unsigned * buffer
, std::size_t offset
)
25 std::size_t index
= offset
/ dword_size
;
26 unsigned position
= offset
% dword_size
;
27 unsigned bit_offset
= bits_per_byte
* position
;
28 unsigned & dword
= buffer
[index
];
29 return (dword
>> bit_offset
) & 0xff;
32 void calculate_hash(unsigned * buffer
)
34 unsigned hash_buffer
[80];
35 unsigned hash
, a
, b
, c
, d
, e
, hash_buffer_offset
;
37 for(std::size_t i
= 0; i
< 0x10; i
++)
38 hash_buffer
[i
] = buffer
[i
+ 5];
40 for(std::size_t i
= 0x10; i
< ail::countof(hash_buffer
); i
++)
42 hash
= hash_buffer
[i
- 0x10] ^ hash_buffer
[i
- 0x8] ^ hash_buffer
[i
- 0xE] ^ hash_buffer
[i
- 0x3];
43 hash_buffer
[i
] = (1 >> (0x20 - (hash
& 0xff))) | (1 << (hash
& 0xff));
52 hash_buffer_offset
= 0;
54 for(unsigned i
= 0; i
< 20; i
++, hash_buffer_offset
++)
56 hash
= ((a
<< 5) | (a
>> 0x1b)) + ((~b
& d
) | (c
& b
)) + e
+ hash_buffer
[hash_buffer_offset
] + 0x5A827999;
59 c
= (b
>> 2) | (b
<< 0x1e);
64 for(unsigned i
= 0; i
< 20; i
++, hash_buffer_offset
++)
66 hash
= (d
^ c
^ b
) + e
+ ((a
<< 5) | (a
>> 0x1b)) + hash_buffer
[hash_buffer_offset
] + 0x6ED9EBA1;
69 c
= (b
>> 2) | (b
<< 0x1e);
74 for(unsigned i
= 0; i
< 20; i
++, hash_buffer_offset
++)
76 hash
= ((c
& b
) | (d
& c
) | (d
& b
)) + e
+ ((a
<< 5) | (a
>> 0x1b)) + hash_buffer
[hash_buffer_offset
] - 0x70E44324;
79 c
= (b
>> 2) | (b
<< 0x1e);
84 for(unsigned i
= 0; i
< 20; i
++, hash_buffer_offset
++)
86 hash
= ((a
<< 5) | (a
>> 0x1b)) + e
+ (d
^ c
^ b
) + hash_buffer
[hash_buffer_offset
] - 0x359D3E2A;
89 c
= (b
>> 2) | (b
<< 0x1e);
101 std::string
bsha1(std::string
const & input
)
105 buffer
[0] = 0x67452301ul
;
106 buffer
[1] = 0xEFCDAB89ul
;
107 buffer
[2] = 0x98BADCFEul
;
108 buffer
[3] = 0x10325476ul
;
109 buffer
[4] = 0xC3D2E1F0ul
;
111 std::size_t const max_subsection_length
= 64;
112 std::size_t const initialised_length
= 20;
114 for(std::size_t i
= 0; i
< input
.length(); i
+= max_subsection_length
)
116 std::size_t subsection_length
= std::min
<std::size_t>(max_subsection_length
, input
.length() - i
);
118 if(subsection_length
> max_subsection_length
)
119 subsection_length
= max_subsection_length
;
121 for(std::size_t j
= 0; j
< subsection_length
; j
++)
122 set_buffer_byte(buffer
, initialised_length
+ j
, input
[j
+ i
]);
124 if(subsection_length
< max_subsection_length
)
126 for(std::size_t j
= subsection_length
; j
< max_subsection_length
; j
++)
127 set_buffer_byte(buffer
, initialised_length
+ j
, 0);
130 calculate_hash(buffer
);
134 for(std::size_t i
= 0; i
< ail::countof(buffer
); i
++)
135 for(std::size_t j
= 0; j
< dword_size
; j
++)
136 output
.push_back(get_buffer_byte(buffer
, i
* dword_size
+ j
));
138 return output
.substr(0, 20);
141 std::string
double_hash(ulong client_token
, ulong server_token
, std::string
const & password
)
143 std::string password_hash
= bsha1(password
);
145 std::string final_input
= dword_to_string(client_token
);
146 final_input
+= dword_to_string(server_token
);
147 final_input
+= password_hash
;
149 std::string output
= bsha1(final_input
);