pure c# now.

This commit is contained in:
Chris Forbes
2009-10-07 22:24:37 +13:00
parent eabc464410
commit 1cf7fdaf06
8 changed files with 527 additions and 678 deletions

View File

@@ -1,4 +0,0 @@
// This is the main DLL file.
#include "MixDecrypt.h"

View File

@@ -1,26 +0,0 @@
// MixDecrypt.h
#pragma once
#pragma unmanaged
#include "mix_decode.h"
#pragma managed
using namespace System;
namespace MixDecrypt {
public ref class MixDecrypt
{
public:
static array<Byte>^ BlowfishKey( array<Byte>^ src )
{
array<Byte>^ dest = gcnew array<Byte>( 56 );
pin_ptr<Byte> s = &src[0];
pin_ptr<Byte> d = &dest[0];
get_blowfish_key( s, d );
return dest;
}
};
}

View File

@@ -1,199 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="MixDecrypt"
ProjectGUID="{6F5D4280-3D23-41FF-AE2A-511B5553E377}"
RootNamespace="MixDecrypt"
Keyword="ManagedCProj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
AssemblyDebug="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
<AssemblyReference
RelativePath="System.dll"
AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
MinFrameworkVersion="131072"
/>
<AssemblyReference
RelativePath="System.Data.dll"
AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
MinFrameworkVersion="131072"
/>
<AssemblyReference
RelativePath="System.XML.dll"
AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
MinFrameworkVersion="131072"
/>
</References>
<Files>
<File
RelativePath=".\mix_decode.h"
>
</File>
<File
RelativePath=".\MixDecrypt.cpp"
>
</File>
<File
RelativePath=".\MixDecrypt.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,428 +0,0 @@
#include <memory>
const static char* pubkey_str = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V";
const static char char2num[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
typedef unsigned int dword;
typedef unsigned short word;
typedef unsigned char byte;
typedef dword bignum4[4];
typedef dword bignum[64];
typedef dword bignum130[130];
static struct
{
bignum key1;
bignum key2;
dword len;
} pubkey;
static bignum glob1;
static dword glob1_bitlen, glob1_len_x2;
static bignum130 glob2;
static bignum4 glob1_hi, glob1_hi_inv;
static dword glob1_hi_bitlen;
static dword glob1_hi_inv_lo, glob1_hi_inv_hi;
static void init_bignum(bignum n, dword val, dword len)
{
memset((void *)n, 0, len * 4);
n[0] = val;
}
static void move_key_to_big(bignum n, char *key, dword klen, dword blen)
{
dword sign;
unsigned i;
if (key[0] & 0x80) sign = 0xff;
else sign = 0;
for (i = blen*4; i > klen; i--)
((char *)n)[i-1] = sign;
for (; i > 0; i--)
((char *)n)[i-1] = key[klen-i];
}
static void key_to_bignum(bignum n, char *key, dword len)
{
dword keylen;
int i;
if (key[0] != 2) return;
key++;
if (key[0] & 0x80)
{
keylen = 0;
for (i = 0; i < (key[0] & 0x7f); i++) keylen = (keylen << 8) | key[i+1];
key += (key[0] & 0x7f) + 1;
}
else
{
keylen = key[0];
key++;
}
if (keylen <= len*4)
move_key_to_big(n, key, keylen, len);
}
static dword len_bignum(bignum n, dword len)
{
int i;
i = len-1;
while ((i >= 0) && (n[i] == 0)) i--;
return i+1;
}
static dword bitlen_bignum(bignum n, dword len)
{
dword ddlen, bitlen, mask;
ddlen = len_bignum(n, len);
if (ddlen == 0) return 0;
bitlen = ddlen * 32;
mask = 0x80000000;
while ((mask & n[ddlen-1]) == 0) {
mask >>= 1;
bitlen--;
}
return bitlen;
}
static void init_pubkey()
{
dword i, i2, tmp;
char keytmp[256];
init_bignum(pubkey.key2, 0x10001, 64);
i = 0;
i2 = 0;
while (i < strlen(pubkey_str))
{
tmp = char2num[pubkey_str[i++]];
tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
keytmp[i2++] = (tmp >> 16) & 0xff;
keytmp[i2++] = (tmp >> 8) & 0xff;
keytmp[i2++] = tmp & 0xff;
}
key_to_bignum(pubkey.key1, keytmp, 64);
pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1;
}
static dword len_predata()
{
dword a = (pubkey.len - 1) / 8;
return (55 / a + 1) * (a + 1);
}
static long int cmp_bignum(bignum n1, bignum n2, dword len)
{
n1 += len-1;
n2 += len-1;
while (len > 0) {
if (*n1 < *n2) return -1;
if (*n1 > *n2) return 1;
n1--;
n2--;
len--;
}
return 0;
}
static void mov_bignum(bignum dest, bignum src, dword len)
{
memmove(dest, src, len*4);
}
static void shr_bignum(bignum n, dword bits, unsigned long int len)
{
dword i, i2;
i2 = bits / 32;
if (i2 > 0) {
for (i = 0; i < len - i2; i++) n[i] = n[i + i2];
for (; i < len; i++) n[i] = 0;
bits = bits % 32;
}
if (bits == 0) return;
for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 -
bits));
n[i] = n[i] >> bits;
}
static void shl_bignum(bignum n, dword bits, dword len)
{
dword i, i2;
i2 = bits / 32;
if (i2 > 0) {
for (i = len - 1; i > i2; i--) n[i] = n[i - i2];
for (; i > 0; i--) n[i] = 0;
bits = bits % 32;
}
if (bits == 0) return;
for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 -
bits));
n[0] <<= bits;
}
static dword sub_bignum(bignum dest, bignum src1, bignum src2, dword carry, dword len)
{
dword i1, i2;
len += len;
while (--len != -1) {
i1 = *(word *)src1;
i2 = *(word *)src2;
*(word *)dest = i1 - i2 - carry;
src1 = (dword *)(((word *)src1) + 1);
src2 = (dword *)(((word *)src2) + 1);
dest = (dword *)(((word *)dest) + 1);
if ((i1 - i2 - carry) & 0x10000) carry = 1; else carry = 0;
}
return carry;
}
static void inv_bignum(bignum n1, bignum n2, dword len)
{
bignum n_tmp;
dword n2_bytelen, bit;
long int n2_bitlen;
init_bignum(n_tmp, 0, len);
init_bignum(n1, 0, len);
n2_bitlen = bitlen_bignum(n2, len);
bit = ((dword)1) << (n2_bitlen % 32);
n1 += ((n2_bitlen + 32) / 32) - 1;
n2_bytelen = ((n2_bitlen - 1) / 32) * 4;
n_tmp[n2_bytelen / 4] |= ((dword)1) << ((n2_bitlen - 1) & 0x1f);
while (n2_bitlen > 0) {
n2_bitlen--;
shl_bignum(n_tmp, 1, len);
if (cmp_bignum(n_tmp, n2, len) != -1) {
sub_bignum(n_tmp, n_tmp, n2, 0, len);
*n1 |= bit;
}
bit >>= 1;
if (bit == 0) {
n1--;
bit = 0x80000000;
}
}
init_bignum(n_tmp, 0, len);
}
static void inc_bignum(bignum n, dword len)
{
while ((++*n == 0) && (--len > 0)) n++;
}
static void init_two_dw(bignum n, dword len)
{
mov_bignum(glob1, n, len);
glob1_bitlen = bitlen_bignum(glob1, len);
glob1_len_x2 = (glob1_bitlen + 15) / 16;
mov_bignum(glob1_hi, glob1 + len_bignum(glob1, len) - 2, 2);
glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32;
shr_bignum(glob1_hi, glob1_hi_bitlen, 2);
inv_bignum(glob1_hi_inv, glob1_hi, 2);
shr_bignum(glob1_hi_inv, 1, 2);
glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1;
inc_bignum(glob1_hi_inv, 2);
if (bitlen_bignum(glob1_hi_inv, 2) > 32)
{
shr_bignum(glob1_hi_inv, 1, 2);
glob1_hi_bitlen--;
}
glob1_hi_inv_lo = *(word *)glob1_hi_inv;
glob1_hi_inv_hi = *(((word *)glob1_hi_inv) + 1);
}
static void mul_bignum_word(bignum n1, bignum n2, dword mul, dword len)
{
dword i, tmp;
tmp = 0;
for (i = 0; i < len; i++) {
tmp = mul * (*(word *)n2) + *(word *)n1 + tmp;
*(word *)n1 = tmp;
n1 = (dword *)(((word *)n1) + 1);
n2 = (dword *)(((word *)n2) + 1);
tmp >>= 16;
}
*(word *)n1 += tmp;
}
static void mul_bignum(bignum dest, bignum src1, bignum src2, dword len)
{
dword i;
init_bignum(dest, 0, len*2);
for (i = 0; i < len*2; i++) {
mul_bignum_word(dest, src1, *(word *)src2, len*2);
src2 = (dword *)(((word *)src2) + 1);
dest = (dword *)(((word *)dest) + 1);
}
}
static void not_bignum(bignum n, dword len)
{
dword i;
for (i = 0; i < len; i++) *(n++) = ~*n;
}
static void neg_bignum(bignum n, dword len)
{
not_bignum(n, len);
inc_bignum(n, len);
}
static dword get_mulword(bignum n)
{
dword i;
word *wn;
wn = (word *)n;
i = (((((((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1)
+ (((*(wn-2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1)
>> 16) + ((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) +
(((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi
* (*wn ^ 0xffff) * 2) >> glob1_hi_bitlen;
if (i > 0xffff) i = 0xffff;
return i & 0xffff;
}
static void dec_bignum(bignum n, dword len)
{
while ((--*n == 0xffffffff) && (--len > 0))
n++;
}
static void calc_a_bignum(bignum n1, bignum n2, bignum n3, dword len)
{
dword g2_len_x2, len_diff;
word *esi, *edi;
word tmp;
mul_bignum(glob2, n2, n3, len);
glob2[len*2] = 0;
g2_len_x2 = len_bignum(glob2, len*2+1)*2;
if (g2_len_x2 >= glob1_len_x2) {
inc_bignum(glob2, len*2+1);
neg_bignum(glob2, len*2+1);
len_diff = g2_len_x2 + 1 - glob1_len_x2;
esi = ((word *)glob2) + (1 + g2_len_x2 - glob1_len_x2);
edi = ((word *)glob2) + (g2_len_x2 + 1);
for (; len_diff != 0; len_diff--) {
edi--;
tmp = get_mulword((dword *)edi);
esi--;
if (tmp > 0) {
mul_bignum_word((dword *)esi, glob1, tmp, 2*len);
if ((*edi & 0x8000) == 0) {
if (sub_bignum((dword *)esi, (dword *)esi, glob1, 0, len)) (*edi)--;
}
}
}
neg_bignum(glob2, len);
dec_bignum(glob2, len);
}
mov_bignum(n1, glob2, len);
}
static void clear_tmp_vars(dword len)
{
init_bignum(glob1, 0, len);
init_bignum(glob2, 0, len);
init_bignum(glob1_hi_inv, 0, 4);
init_bignum(glob1_hi, 0, 4);
glob1_bitlen = 0;
glob1_hi_bitlen = 0;
glob1_len_x2 = 0;
glob1_hi_inv_lo = 0;
glob1_hi_inv_hi = 0;
}
static void calc_a_key(bignum n1, bignum n2, bignum n3, bignum n4, dword len)
{
bignum n_tmp;
dword n3_len, n4_len, n3_bitlen, bit_mask;
init_bignum(n1, 1, len);
n4_len = len_bignum(n4, len);
init_two_dw(n4, n4_len);
n3_bitlen = bitlen_bignum(n3, n4_len);
n3_len = (n3_bitlen + 31) / 32;
bit_mask = (((dword)1) << ((n3_bitlen - 1) % 32)) >> 1;
n3 += n3_len - 1;
n3_bitlen--;
mov_bignum(n1, n2, n4_len);
while (--n3_bitlen != -1)
{
if (bit_mask == 0)
{
bit_mask = 0x80000000;
n3--;
}
calc_a_bignum(n_tmp, n1, n1, n4_len);
if (*n3 & bit_mask)
calc_a_bignum(n1, n_tmp, n2, n4_len);
else
mov_bignum(n1, n_tmp, n4_len);
bit_mask >>= 1;
}
init_bignum(n_tmp, 0, n4_len);
clear_tmp_vars(len);
}
static void process_predata(const byte* pre, dword pre_len, byte *buf)
{
bignum n2, n3;
const dword a = (pubkey.len - 1) / 8;
while (a + 1 <= pre_len)
{
init_bignum(n2, 0, 64);
memmove(n2, pre, a + 1);
calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64);
memmove(buf, n3, a);
pre_len -= a + 1;
pre += a + 1;
buf += a;
}
}
static void get_blowfish_key(const byte* s, byte* d)
{
static bool public_key_initialized = false;
if (!public_key_initialized)
{
init_pubkey();
public_key_initialized = true;
}
byte key[256];
process_predata(s, len_predata(), key);
memcpy(d, key, 56);
}

View File

@@ -0,0 +1,520 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace OpenRa.FileFormats
{
/* possibly the fugliest C# i've ever seen. */
class BlowfishKeyProvider
{
const string pubkeyStr = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V";
static sbyte[] char2num = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
class PublicKey
{
public uint[] key1 = new uint[64];
public uint[] key2 = new uint[64];
public uint len;
}
PublicKey pubkey = new PublicKey();
uint[] glob1 = new uint[64];
uint glob1_bitlen, glob1_len_x2;
uint[] glob2 = new uint[130];
uint[] glob1_hi = new uint[4];
uint[] glob1_hi_inv = new uint[4];
uint glob1_hi_bitlen;
uint glob1_hi_inv_lo, glob1_hi_inv_hi;
void init_bignum(uint[] n, uint val, uint len)
{
for (int i = 0; i < len; i++) n[i] = 0;
n[0] = val;
}
void move_key_to_big(uint[] n, byte[] key, uint klen, uint blen)
{
byte sign;
if ((key[0] & 0x80) != 0) sign = 0xff;
else sign = 0;
unsafe
{
fixed (uint* _pn = &n[0])
{
byte* pn = (byte*)_pn;
uint i = blen * 4;
for (; i > klen; i--) pn[i - 1] = (byte)sign;
for (; i > 0; i--) pn[i - 1] = key[klen - i];
}
}
}
void key_to_bignum(uint[] n, byte[] key, uint len)
{
uint keylen;
int i;
int j = 0;
if (key[j] != 2) return;
j++;
if ((key[j] & 0x80) != 0)
{
keylen = 0;
for (i = 0; i < (key[j] & 0x7f); i++) keylen = (keylen << 8) | key[j + i + 1];
j += (key[j] & 0x7f) + 1;
}
else
{
keylen = key[j];
j++;
}
if (keylen <= len * 4)
move_key_to_big(n, key.Skip(j).ToArray(), keylen, len);
}
uint len_bignum(uint[] n, uint len)
{
uint i;
i = len - 1;
while ((i >= 0) && (n[i] == 0)) i--;
return i + 1;
}
uint bitlen_bignum(uint[] n, uint len)
{
uint ddlen, bitlen, mask;
ddlen = len_bignum(n, len);
if (ddlen == 0) return 0;
bitlen = ddlen * 32;
mask = 0x80000000;
while ((mask & n[ddlen - 1]) == 0)
{
mask >>= 1;
bitlen--;
}
return bitlen;
}
void init_pubkey()
{
int i = 0;
uint i2, tmp;
byte[] keytmp = new byte[256];
init_bignum(pubkey.key2, 0x10001, 64);
i2 = 0;
while (i < pubkeyStr.Length)
{
tmp = (uint)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]];
keytmp[i2++] = (byte)((tmp >> 16) & 0xff);
keytmp[i2++] = (byte)((tmp >> 8) & 0xff);
keytmp[i2++] = (byte)(tmp & 0xff);
}
key_to_bignum(pubkey.key1, keytmp, 64);
pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1;
}
uint len_predata()
{
uint a = (pubkey.len - 1) / 8;
return (55 / a + 1) * (a + 1);
}
int cmp_bignum(uint[] n1, uint[] n2, uint len)
{
while (len > 0)
{
--len;
if (n1[len] < n2[len]) return -1;
if (n1[len] > n2[len]) return 1;
}
return 0;
}
void mov_bignum(uint[] dest, uint[] src, uint len)
{
Array.Copy(src, dest, len);
}
void shr_bignum(uint[] n, int bits, int len)
{
int i; int i2 = bits / 32;
if (i2 > 0)
{
for (i = 0; i < len - i2; i++) n[i] = n[i + i2];
for (; i < len; i++) n[i] = 0;
bits = bits % 32;
}
if (bits == 0) return;
for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 -
bits));
n[i] = n[i] >> bits;
}
void shl_bignum(uint[] n, int bits, int len)
{
int i, i2;
i2 = bits / 32;
if (i2 > 0)
{
for (i = len - 1; i > i2; i--) n[i] = n[i - i2];
for (; i > 0; i--) n[i] = 0;
bits = bits % 32;
}
if (bits == 0) return;
for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 -
bits));
n[0] <<= bits;
}
uint sub_bignum(uint[] dest, uint[] src1, uint[] src2, uint carry, int len)
{
uint i1, i2;
len += len;
unsafe
{
fixed (uint* _ps1 = &src1[0])
fixed (uint* _ps2 = &src2[0])
fixed (uint* _pd = &dest[0])
{
ushort* ps1 = (ushort*)_ps1;
ushort* ps2 = (ushort*)_ps2;
ushort* pd = (ushort*)_pd;
while (--len != -1)
{
i1 = *ps1++;
i2 = *ps2++;
*pd++ = (ushort)(i1 - i2 - carry);
if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0;
}
}
}
return carry;
}
unsafe uint sub_bignum(uint* dest, uint* src1, uint* src2, uint carry, int len)
{
uint i1, i2;
len += len;
ushort* ps1 = (ushort*)src1;
ushort* ps2 = (ushort*)src2;
ushort* pd = (ushort*)dest;
while (--len != -1)
{
i1 = *ps1++;
i2 = *ps2++;
*pd++ = (ushort)(i1 - i2 - carry);
if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0;
}
return carry;
}
void inv_bignum(uint[] n1, uint[] n2, uint len)
{
uint[] n_tmp = new uint[64];
uint n2_bytelen, bit;
int n2_bitlen;
int j = 0;
init_bignum(n_tmp, 0, len);
init_bignum(n1, 0, len);
n2_bitlen = (int)bitlen_bignum(n2, len);
bit = ((uint)1) << (n2_bitlen % 32);
j = ((n2_bitlen + 32) / 32) - 1;
n2_bytelen = (uint)((n2_bitlen - 1) / 32) * 4;
n_tmp[n2_bytelen / 4] |= ((uint)1) << ((n2_bitlen - 1) & 0x1f);
while (n2_bitlen > 0)
{
n2_bitlen--;
shl_bignum(n_tmp, 1, (int)len);
if (cmp_bignum(n_tmp, n2, len) != -1)
{
sub_bignum(n_tmp, n_tmp, n2, 0, (int)len);
n1[j] |= bit;
}
bit >>= 1;
if (bit == 0)
{
j--;
bit = 0x80000000;
}
}
init_bignum(n_tmp, 0, len);
}
void inc_bignum(uint[] n, uint len)
{
int i = 0;
while ((++n[i] == 0) && (--len > 0)) i++;
}
void init_two_dw(uint[] n, uint len)
{
mov_bignum(glob1, n, len);
glob1_bitlen = bitlen_bignum(glob1, len);
glob1_len_x2 = (glob1_bitlen + 15) / 16;
mov_bignum(glob1_hi, glob1.Skip((int)len_bignum(glob1, len) - 2).ToArray(), 2);
glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32;
shr_bignum(glob1_hi, (int)glob1_hi_bitlen, 2);
inv_bignum(glob1_hi_inv, glob1_hi, 2);
shr_bignum(glob1_hi_inv, 1, 2);
glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1;
inc_bignum(glob1_hi_inv, 2);
if (bitlen_bignum(glob1_hi_inv, 2) > 32)
{
shr_bignum(glob1_hi_inv, 1, 2);
glob1_hi_bitlen--;
}
glob1_hi_inv_lo = (ushort)glob1_hi_inv[0];
glob1_hi_inv_hi = (ushort)(glob1_hi_inv[0] >> 16);
}
unsafe void mul_bignum_word(ushort *pn1, uint[] n2, uint mul, uint len)
{
uint i, tmp;
unsafe
{
fixed (uint* _pn2 = &n2[0])
{
ushort* pn2 = (ushort*)_pn2;
tmp = 0;
for (i = 0; i < len; i++)
{
tmp = mul * (*pn2) + (*pn1) + tmp;
*pn1 = (ushort)tmp;
pn1++;
pn2++;
tmp >>= 16;
}
*pn1 += (ushort)tmp;
}
}
}
void mul_bignum(uint[] dest, uint[] src1, uint[] src2, uint len)
{
uint i;
unsafe
{
fixed( uint * _psrc2 = &src2[0] )
fixed(uint* _pdest = &dest[0])
{
ushort* psrc2 = (ushort*)_psrc2;
ushort* pdest = (ushort*)_pdest;
init_bignum(dest, 0, len * 2);
for (i = 0; i < len * 2; i++)
mul_bignum_word(pdest++, src1, *psrc2++, len * 2);
}
}
}
void not_bignum(uint[] n, uint len)
{
uint i;
for (i = 0; i < len; i++) n[i] = ~n[i];
}
void neg_bignum(uint[] n, uint len)
{
not_bignum(n, len);
inc_bignum(n, len);
}
unsafe uint get_mulword(uint* n)
{
ushort* wn = (ushort*)n;
uint i = (uint)((((((((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1)
+ (((*(wn - 2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1)
>> 16) + ((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) +
(((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi
* (*wn ^ 0xffff) * 2) >> (int)glob1_hi_bitlen);
if (i > 0xffff) i = 0xffff;
return i & 0xffff;
}
void dec_bignum(uint[] n, uint len)
{
int i = 0;
while ((--n[i] == 0xffffffff) && (--len > 0))
i++;
}
void calc_a_bignum(uint[] n1, uint[] n2, uint[] n3, uint len)
{
uint g2_len_x2, len_diff;
unsafe
{
fixed( uint* g1 = &glob1[0])
fixed (uint* g2 = &glob2[0])
{
mul_bignum(glob2, n2, n3, len);
glob2[len * 2] = 0;
g2_len_x2 = len_bignum(glob2, len * 2 + 1) * 2;
if (g2_len_x2 >= glob1_len_x2)
{
inc_bignum(glob2, len * 2 + 1);
neg_bignum(glob2, len * 2 + 1);
len_diff = g2_len_x2 + 1 - glob1_len_x2;
ushort* esi = ((ushort*)g2) + (1 + g2_len_x2 - glob1_len_x2);
ushort* edi = ((ushort*)g2) + (g2_len_x2 + 1);
for (; len_diff != 0; len_diff--)
{
edi--;
uint tmp = get_mulword((uint*)edi);
esi--;
if (tmp > 0)
{
mul_bignum_word(esi, glob1, tmp, 2 * len);
if ((*edi & 0x8000) == 0)
{
if (0 != sub_bignum((uint*)esi, (uint*)esi, g1, 0, (int)len)) (*edi)--;
}
}
}
neg_bignum(glob2, len);
dec_bignum(glob2, len);
}
mov_bignum(n1, glob2, len);
}
}
}
void clear_tmp_vars(uint len)
{
init_bignum(glob1, 0, len);
init_bignum(glob2, 0, len);
init_bignum(glob1_hi_inv, 0, 4);
init_bignum(glob1_hi, 0, 4);
glob1_bitlen = 0;
glob1_hi_bitlen = 0;
glob1_len_x2 = 0;
glob1_hi_inv_lo = 0;
glob1_hi_inv_hi = 0;
}
void calc_a_key(uint[] n1, uint[] n2, uint[] n3, uint[] n4, uint len)
{
uint[] n_tmp = new uint[64];
uint n3_len, n4_len;
int n3_bitlen;
uint bit_mask;
unsafe
{
fixed (uint* _pn3 = &n3[0])
{
uint* pn3 = _pn3;
init_bignum(n1, 1, len);
n4_len = len_bignum(n4, len);
init_two_dw(n4, n4_len);
n3_bitlen = (int)bitlen_bignum(n3, n4_len);
n3_len = (uint)((n3_bitlen + 31) / 32);
bit_mask = (((uint)1) << ((n3_bitlen - 1) % 32)) >> 1;
pn3 += n3_len - 1;
n3_bitlen--;
mov_bignum(n1, n2, n4_len);
while (--n3_bitlen != -1)
{
if (bit_mask == 0)
{
bit_mask = 0x80000000;
pn3--;
}
calc_a_bignum(n_tmp, n1, n1, n4_len);
if ((*pn3 & bit_mask) != 0)
calc_a_bignum(n1, n_tmp, n2, n4_len);
else
mov_bignum(n1, n_tmp, n4_len);
bit_mask >>= 1;
}
init_bignum(n_tmp, 0, n4_len);
clear_tmp_vars(len);
}
}
}
unsafe void memcpy(byte* dest, byte* src, int len)
{
while (len-- != 0) *dest++ = *src++;
}
unsafe void process_predata(byte* pre, uint pre_len, byte *buf)
{
uint[] n2 = new uint[64];
uint[] n3 = new uint[64];
uint a = (pubkey.len - 1) / 8;
while (a + 1 <= pre_len)
{
init_bignum(n2, 0, 64);
fixed( uint * pn2 = &n2[0] )
memcpy((byte *)pn2, pre, (int)a + 1);
calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64);
fixed( uint * pn3 = &n3[0] )
memcpy(buf, (byte *)pn3, (int)a);
pre_len -= a + 1;
pre += a + 1;
buf += a;
}
}
public byte[] DecryptKey(byte[] src)
{
init_pubkey();
byte[] dest = new byte[256];
unsafe
{
fixed (byte* pdest = &dest[0])
fixed (byte* psrc = &src[0])
process_predata(psrc, len_predata(), pdest);
}
return dest.Take(56).ToArray();
}
}
}

View File

@@ -14,7 +14,7 @@
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
@@ -36,13 +36,16 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Blowfish.cs" />
<Compile Include="BlowfishKeyProvider.cs" />
<Compile Include="FileSystem.cs" />
<Compile Include="Folder.cs" />
<Compile Include="Format40.cs" />
@@ -62,10 +65,6 @@
<Compile Include="Walkability.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MixDecrypt\MixDecrypt.vcproj">
<Project>{6F5D4280-3D23-41FF-AE2A-511B5553E377}</Project>
<Name>MixDecrypt</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRa.DataStructures\OpenRa.DataStructures.csproj">
<Project>{2F9E7A23-56C0-4286-9C8E-1060A9B2F073}</Project>
<Name>OpenRa.DataStructures</Name>

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
namespace OpenRa.FileFormats
{
@@ -18,11 +19,6 @@ namespace OpenRa.FileFormats
readonly long dataStart;
readonly Stream s;
//public ICollection<PackageEntry> Content
//{
// get { return index.AsReadOnly(); }
//}
public static Dictionary<K, V> MakeDict<K,V>(IEnumerable<V> values, Converter<V, K> keyFunc)
{
var dict = new Dictionary<K, V>();
@@ -63,7 +59,7 @@ namespace OpenRa.FileFormats
{
BinaryReader reader = new BinaryReader(s);
byte[] keyblock = reader.ReadBytes(80);
byte[] blowfishKey = MixDecrypt.MixDecrypt.BlowfishKey(keyblock);
byte[] blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock);
uint[] h = ReadUints(reader, 2);

View File

@@ -1,12 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MixDecrypt", "MixDecrypt\MixDecrypt.vcproj", "{6F5D4280-3D23-41FF-AE2A-511B5553E377}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.FileFormats", "OpenRa.FileFormats\OpenRa.FileFormats.csproj", "{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}"
ProjectSection(ProjectDependencies) = postProject
{6F5D4280-3D23-41FF-AE2A-511B5553E377} = {6F5D4280-3D23-41FF-AE2A-511B5553E377}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.Game", "OpenRa.Game\OpenRa.Game.csproj", "{0DFB103F-2962-400F-8C6D-E2C28CCBA633}"
EndProject
@@ -20,10 +15,6 @@ Global
Release (x86)|Win32 = Release (x86)|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.ActiveCfg = Release|Win32
{6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.Build.0 = Release|Win32
{6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.ActiveCfg = Release|Win32
{6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.Build.0 = Release|Win32
{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.ActiveCfg = Debug|x86
{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.Build.0 = Debug|x86
{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release (x86)|Win32.ActiveCfg = Release|x86