Я знаю, как глупо отвечать на свой вопрос, но мне удалось разгадать его с помощью друга, так что вот решение. В основном, когда я использовал функцию Checksum.compute_for_data, она возвращала шестнадцатеричную строку, а не шестнадцатеричные данные, и это нарушало алгоритм. Вот исправленная версия:
public static string compute_for_data(ChecksumType type, uint8[] key,
uint8[] data) {
int block_size = 64;
switch (type) {
case ChecksumType.MD5:
case ChecksumType.SHA1:
block_size = 64; /* RFC 2104 */
break;
case ChecksumType.SHA256:
block_size = 64; /* RFC draft-kelly-ipsec-ciph-sha2-01 */
break;
}
uint8[] buffer = key;
if (key.length > block_size) {
buffer = Checksum.compute_for_data(type, key).data;
}
buffer.resize(block_size);
Checksum inner = new Checksum(type);
Checksum outer = new Checksum(type);
uint8[] padding = new uint8[block_size];
for (int i=0; i < block_size; i++) {
padding[i] = 0x36 ^ buffer[i];
}
inner.update(padding, padding.length);
for (int i=0; i < block_size; i++) {
padding[i] = 0x5c ^ buffer[i];
}
outer.update(padding, padding.length);
size_t length = buffer.length;
inner.update(data, data.length);
inner.get_digest(buffer, ref length);
outer.update(buffer, length);
return outer.get_string();
}