I checked my suspicion that the high and the low 32 bits are simply multiplied by A85A2115 (hex):
We get a FILETIME structure. Then we perform a 32x32->32 bit multiplication (this means we throw away the high 32 bits of the 64 bits result) of the high and the low word independently.
Example:
25 Jan 2021 13:37:07 (and some milliseconds)
Unencrypted FILETIME:
High dword = 1D6F31F (hex)
Low dword = 2C9CA481 (hex)
Multiplication
High dword: 1D6F31F * A85A2115 = 135B55AACDEF08B (hex)
Low dword: 2C9CA481 * A85A2115 = 1D5680CA57681F95 (hex)
Now only take the low 32 bits of the results:
High dword: ACDEF08B (hex)
Low dword: 57681F95 (hex)
Unfortunately, I don't know how to do the the "reverse operation"; I did it by searching for the result in a loop with the following pseudo-code:
encryptedValue = 57681F95 (hex)
originalValue = 0
product = 0
while product not equal to encryptedValue
// 32-bit addition discarding carry:
product = product + A85A2115 (hex)
originalValue = originalValue + 1
end_of_while_loop
We get the following results:
25 Jan 2021 13:37:07 => acdef08b|57681f95
25 Jan 2021 13:40:51 => acdef08b|4a249b35
25 Jan 2021 13:45:07 => 553911a0|e4acfb95
25 Jan 2021 13:49:03 => 553911a0|b922f7b5
25 Jan 2021 13:53:53 => fd9332b5|d2a65be5
25 Jan 2021 13:55:50 => fd9332b5|d15bf495
25 Jan 2021 14:00:39 => a5ed53ca|a8871b95
Addendum
The reverse operation seems to be done by multiplying with 3069263D (hex) (and only using the low 32 bits).
Encrypting:
2C9CA481 * A85A2115 = 1D5680CA57681F95
=> Result: 57681F95
Decrypting:
57681F95 * 3069263D = 10876CAF2C9CA481
=> Result: 2C9CA481
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…