201108192339 joc3i
solved decrypted manual
The IOCCC 2000 checkers program robison.c, byte for byte. 3DES, key MD5(name).
From the post to its content
As posted (encrypted)
E42D22D79C4DEEFD F9FB8E3A207EBA7D 6261C895141B04EB 185CDCB8F74FF7CF 01E9F5F65DCAD30B 4D9E1E13B7ED07B1 3DDD3AEA1DFF6582 7AB1923368B3AB3A F1BBAA0D614BC3D7 C97662EB70479166 0D6AA7F67C843497 CC3E183ECDD83C50 C1F88DAF3EF37E8B 34B01EC7D7D29450 9E7CB58C9E8FA6B5 C5F0BC1030DCFA2D E22F9976517123F9 ABB777C04C0E1BB3 FFCBC4060D6EC87D 88366D1B866FDEDF B794E4F3117DB350 B212568921B24373 383F1176C7FEB7E3 D26BDC515EAA5945 1652CDF2C615EA93 B741CF41751B8F02 DE4BA3BC0F243844 FF9A2BDED1ACA442 B075F089004D05DD 012CAF49F182F12F 01016A994E05805D 355E85BAFEB48E00 6A11D0A4E0849BB4 BFC6F43E27F80339 92B672E3362D0D98 8AA765F33F9D0B2D 45F05E1454454C5C B16C6D060F780DC3 B8BB7CCC76C994A1 2B472EDD820DCBED FB558D862E9D38D3 447823194BBE6E72 C5D3FD9426C09A56 129C4B0B263F9814 B608FF088F28D5DE B73A063668808EBB 1FFC692264DA99F9 0EAA305D7C510711 8EA673FE25BAD8E6 889E5F01D2584A52 68F27C7CFD1CC336 8A60224046ECEDF1 69C1D61E5D37A265 B37EEF1D3050F80E EC7EB53E2544C953 A8431039954E829B EBAC2AD779E5508C B6FB4099161907DD 243E80DF657FA125 01DE6BA9B6F527D5 813E1C532D33DDDB F6029D0C924566A9 8DBC3B2B55C7ECF5 A72E1B865F2DE6FD 49185900109589FC AD3950B8FB6198B5 B579BD09EC9CB0A7 7CF6A6A671E44A4E 9C0E316D09D9094A 05193F3D178E5634 9B06B268CB05CCEC DEDADC09EC5EB92F EF641EDE6A4522D0 F5F8C4D69AD3C573 62B931868FF852F1 7ECECF4B7FA9F452 D32FC51CE71CF44B 8FE199230073EF90 CBB139DC0C6C9495 66D2678592B59472 747343EA086E6734 8219AB96BAFE83BB 64C9861031E10FCD E4116787400595D3 1D5A468484E5486D DBE90D6DE3255BAF ADDBED4B9C512C3B 9758EB2ABDA78D06 65E68BFBCEEEBC4F D345404453F536E1 527F75B55F71D107 7B48F0B31A6E4160 482B0CCE1978AF24 D9DE6C7477B606FE 684F6ABB6101E423 9F45E0D1F3251720 E8D021EA9E06BB0F 6062DC70AA54E34F 367259C722D7D272 ED49AE31C8118D15 768AF0B91A7DF197 7658286F06240E50 C8851EC4220A20E0 782F4BBC5B62A1BA 8F6BA6A18BDAEDE9 70AD753F012E4ADD D883770F2E3CC757 16B0CA879152FD38 5E13B535CF7EB868 1CE7613026DD0D6B 774712AA9D38092D 86531C01A23CB81D AAE53CB667B96311 BD2B4BA6DFBAB3FA 8861F2CDD61BF388 3EBAA8CAEC70861A 389FF56D113D0B11 C98C09B8276CD820 D883770F2E3CC757 1FEFE36E426C39F8 A08A64552CC5416A 7F71CE0FBDA39E3F 7253DE677AC7E634 B28BA1F79AA2E594 43A618611CD7A243 31777F096D209BA9 C984C3D7B20058B6 C9414122EB408391 E1B259869069BED0 D364EE41B75F645E B547BAA707FDAE88 0502E04921C4B84E 60AE8557F5D53367 A9EB49CAE4EDC60A F290C4267483D6B4 7542F2208B9E9702 CB4F05208BFB0C8B 55ACB56CE4B5AFF4 4E18BBCABB260EE7 0F3B55E766618AB9 C93F1E24D1613BFA 8EB2D31D251C3416 75004397B3375E88 1F0A97F58859A909 E0041E7480528933 3E0E4D1AE6B57DB6 4F6431F0D672A5B9 167F9C1CE40BDA40 FD7A0CCEE0EFD9D7 BCB3C5EF25A43DDE 0BB1363E2BFAB141 CC42E626D6025489 8CD488CBA923777B D6027DDF1C613E55 5652DDBEBB2F6F04 F38578EF504E4378 459C2B49E7E54B4D F790AF68ADBB7C29 0F42DE15777A6077 005BFF3DA388C6E7 3D13A04C35A1D5A8 557A01ED11B52A68 67DE214D84BD316B EC61E1B8C19F0BA0 ACA0B729525C402C 4A25ED1CD0C97B95 F845FCC4D0DF4748 C80A5A81F908CF54 8DB4369473EE8267 116F9F60C1C0590E D6FBBF70DD109B9E 65EAA49E1732A73F D73341BA53DBF1F0 184C5E7687774348 90C94A5175AD44B2 9D714C182A9D9CDE 16389E54BFCC2B78 2B01520FED0943CF FCC380252E236372 F1883ED7D8266CDE 80ED27A2BD8FF121 E90388D582204B73 1F0A97F58859A909 91B8276B9BEEEC63 4F08DB140757582A 70FD2B6AA7863251 EF15435AFF171947 58E2D969713B7BDF 7756EFEF00DB289C DAE6ABFE0611E1B2 2B24C3A0FCC9F9D2 5E3DFBF0E73DC338 AEBF5CC75E5A8E18 2973FE35F10DE5A0 E572906F24BCCA7E 9BF6764EF020AD70 3BA009DEA381D89F 5677BCFAE513D2C5 7234B5C7308C204F 963898893042717A 2C56D2536B4D7CC1 765191D3E02D021A 3E7B9D42128D7EB4 738FC7D31F961C32 782C0FF31CAF7DB3 8CFD04EAB781688D 337D58A365E2AC96 EC79517D407A32D1 26B4AA5C62AEDEC7 A45785D93F5E73D0 ADFDB95BCA3C0614 6665CFA246D15CBC 59D52E5547BD6979 136D20767BFCC87E AFC980CE0766F6FA 476B21CA07029E8E 3D532943C0632311 EE1E489489E995E8 308CBED3B3970FD3 2F3E14FAAB43F750 230CD52E00C2FDD7 83F214DB2C0FFB24 3B7558E7CBB71D9C F74B62837BE87EA6 51E1307EDF638FAF 4C50F3495A9A73DB 7A362FBAD70FB1F9 11CC02E6F0B88BBA FA6CB8278F11F498 B3D87A2B3948685A D6CC5DB81E7311BA 97BFD1511BB3DCE0 BDE48CCA4AA7676F 61B678AA37E25BD1 B338083D1717A871 D1F5089B2A13E9B6 4E9B063E40D40AEE 626DA845094796CD 5A6F0B67874C45ED E29CD255BA0118F6 B34F717A5C1B509F 89B87DADC814C01A D8CEFA2B1287EDDE 108D741856840832 C6D12A97C76CCC3F 2F8C9FE63CF76EF3 28FF1D4AEA8DD527 D4E9F128463B284B 81096F41A781117D 4015F768FC6259EE C1C070DE88092370 3C63D85C77C62341 22115EE65727CBF8 E1B7E1F41D9EF924 A03E91F85B8B1EBB BC7BBE14395EDF35 08D9877F781F8005 1D622BB5384B41C1 1880656DCF89D2CB EF50FCD9822B6DF6 C4C4490E48E09943 B2E2042DFCF32971 C8FA1B5A283E3C3B E5F043CC074353BD 680088E4E41CB77A 8DA90604C8CB61CF F65F192C4D091BC2 815EA10E31D3BB24 A0C904D501AC3BED B5BB19541A816EF7 BF1C160392E00822 D75A16FF13ED4D44 DE2806EF95965FEA 7B14897E0BF000F0 9508CF513881B17F 723D210375C925A5 BC63F492B11FF855 E5792675398C7DBF 67F89EA2E82BC3BF 2FFBECC32C9F974E 82CC932CE274C3C3 E24BF65F14F53F26 62AE902EF528945C DCA71B86B2A84A9E A248B6951F304370 A8D465502FDE644D 0FD7E747EB38AE88 A9CB175E8BD9EB3E D50D5A58ED48B2E0 0FCDF5CFF3E9B79E 3BD02C6347B6F6B5 680088E4E41CB77A A713E3D279861344 21416E05D85ABE13 4BD7F6F7D645D973 6AB56F1F8E1E421C 54C394DD1DE2FD72 24A8ED75100E8BFE 9BABBDE866A88FA4 533904D8E6057ACB 3EACEEC2BA46246A 3C9BD9D055E72883 1FD6C8FFF78AE4E8 39DFE7DC0B626925 3BA6545820FFCFD3 88BFCF5B66040BF0 F536CD46E45A0612 F788EBB7B8D0FB58 609A74A10308F2F2 EA16A5D093EB7250 DF4BE1FA23ED567C 65C4B644763FF104 3C4356AC3F92AF37 7DD9D9532D5CFD34 B1C10076B48F01DA 9F3B14ACF24CEB8D EA5F22A286F2CA92 45383B4C74CECD96 E452466E3200C509 57DBE8CA786E4C35 88AFA0DA9204BC5D B91D768D8D6002FD 11E47FAA4E00BAD4 BEE33941667CB229 13A3CEEDD4E09499 642E6FA3F2944429 F93C10712C2FCE8D 7F095F1EC756569D E4F04080544AA48E 514A6A1A56410E34 93C53A75EB1B0910 46B19C45634F2B92 EF2BC3B67C1765CD 8406DAD993E7298E 2DFA820BCB5664F6 4DCCD42941C22C98 154B902BA4179612 46910622A2F6A760 1382B55F6E68212F 836476A8FEE8665D 2CD788C62C2E645B 05108CA3B1E386FC 43F05E585B3A9521 BA99BC44381F0FF8 CA84D0E5C98C9F76 FFAD7CD72269C34D F60C9A3E2E7DEA0B E078E7AC938220C2 9F3B14ACF24CEB8D ED8892C22E148489 8A2FBDD6F1C90B83 A583A936F2750F56 27B04EDD9BE8F465 3D9E0CDD674A5088 FD45546771302164
- Decrypt. Key: MD5(name) ECB. 3DES-EDE2, then strip the PKCS7 padding.
Decrypted
#define A B.
#define C if(
#define D >>E&1
#define F return
#define G typedef
#define H printf( I(
#define J(E,K) for(E=K; E--; )
#define L(M) =N(O.M)+3*N(O.M&O.P),
G
int
Q;
G
unsigned
R;
G
struct
{
Q
N,
S,
P,
T,
U,
V;
}
W;
R
_;
R
N(
R
X)
{
R
Y=
2,
Z;
for
(;
Y
;
Y*=
Y)
{
Z=
-1
/-
~Y
;
X=
(X
/Y
&Z
)+
(X
&Z
)*
(Y
*_
-~-
_)
;
}
F
X;
}
W
S(
W
a)
{
W
B;
_=
1;
A
N=
N(
a.
S)
;
A
S=
N(
a.
N)
;
A
P=
N(
a.
P)
;
A
U=
-1
<<
30
;
A
V=
-a
.U
;
F
B;
}
Q
P(
Q
Y,
Q
b,
R
c)
{
Q
E=
Y+
(b
+8
)%
10
-5
+Y
/4
%2
&31
;
F
c
D||
Y/
4-
E/
4-
~-
(b
&2
)?
-1
:E
;
}
Q
T(
W
B,
Q
a,
Q
b)
{
Q
E=
P(
a,
b,
A
N)
;
F~
E?
A
S
D?
~P
(E
,b
,A
S|
A
N)
?128
|b
*32
|a
:-
1:
b*
32
|a
:E
;
}
Q
U(
W
B,
R
c,
Q
Y)
{
Q
E,
b;
J(
E,
32
)C
(A
N&
c)
D)
J(
b,
2<<
(A
P
D)
)C
T(
B,
E,
b)
>=
Y<<
7)
F
1;
F
0;
}
W
V(
W
B,
Q
Z)
{
R
E=
Z&
31
,b
=Z
/32
&3
,Y
=A
T=
P(
E,
b,
0)
,K
=1
<<
Y;
A
N|=
K;
A
P&=
~K
;
A
P|=
(A
P
D)
<<
Y;
_=
A
S
D&&
U(
B,
K,
1)
;
A
P|=
K&-
1<<
28
;
A
N&=
E=
~(
1<<
E)
;
A
P&=
E;
A
S&=
E;
F
Z>>
7?
V(
B,
b<<
5|
Y)
:B
;
}
W
d(
W
B,
Q
b)
;
R
e;
W
f(
W
B,
Q
E,
Q
b,
Q
g)
{
Q
h,
i=
0,
I,
j,
K,
k,
Z,
Y;
J(
h,
2<<
(A
P
D)
){
j=
T(
B,
E,
h)
;
C~
j&&
j>>
7!=
!~
g)
{
++
i;
C
A
U<=
A
V)
{
W
O;
O=
V(
B,
j)
;
K=
g<
0?
j:
g;
++
e;
I=
_?
f(
O,
O.
T,
b,
K)
.U
:(
Y=
b+
U(
O=
S(
O)
,-
1,
1)
)?
-(
d(
O,
~-
Y)
.U
):
(_
=0
,Z
L(
N)
k
L(
S)
(k
-Z
<<
24
)/
(k
+Z
)+
(short
)rand
()
);
C
I>=
A
U)
{
A
U=
I;
A
T=
K;
}
}
}
}
_=
i;
F
B;
}
W
d(
W
B,
Q
b)
{
Q
E=
32
,Y
=
~U
(B
,-
1,
1)
;
for
(;
E--
&&
A
U<=
A
V;
)C
A
N
D)
{
B=
f(
B,
E,
b,
Y)
;
}
F
B;
}
char
l[
4095
],
*O
=l
,*
b;
char
*I
(char
*X
){
Q
Z=
1,
W=
0,
E,
M=
0,
B;
b=
O;
for
(;
E
=
*X
++
;
){
E=
E%
65
%6
^2
;
M+=
B=
Z+
1+
E/
4;
W=
W<<
B^
E;
Z=
E<
2;
J(
E,
M/
7)
{
M%=
7;
W^=
(*
O++=
W>>
M)
<<
M;
}
}
*O
++=
0;
F
b;
}
Q
main
()
{
Q
K,
Y,
E,
m,
n,
o=
4,
g,
b,
Z;
W
B;
srand
(clock
()
);
A
S=
(A
N=
4095
)<<
20
;
A
P=
0;
for
(;
;
){
J(
K,
8)
{
J(
Y,
8)
{
E=
K*
4+
Y/
2;
H" } { }"
)+
(K
^Y
^1
)%
2*
2,
".xoXO"
[(
A
P
D)
*2
+(
A
S
D)
*2
+(
A
N
D)
])
;
}
H" } } } } } } "
),
-~
E)
;
}
J(
g,
1)
{
O=
l;
H"} } } } { } } } } { ; ; }"
)+
o/
2*
2)
;
e=
0;
C
o<
4)
B=
S(
B)
;
C!
U(
B,
-1
,0
))
{
H" } } { ; { ; } ; } } "
))
;
F
0;
}
H" { { ; { ; ; { ; ; { { } } ; ; { } } } ; ; { ; } } } { ; { ; ; { { ; } } "
)+
(o
&1
)*
13
,I
(" } { { } ; } "
)+
U(
B,
-1
,1
))
;
C
o&
4)
{
o&
1?
scanf
("%d"
,&
n)
:(
scanf
("%d%d"
,&
m,
&n
),
--
m)
;
Z=
A
N>>
m&
1?
T(
B,
m,
n)
:-
1;
C
g=
Z>>
7!=
U(
B,
-1
,1
))
{
H"{ ; { { } { } { ; } ; { "
))
;
}
}
else
{
A
U=
-(
A
V=
1<<
30
);
for
(b
=4
;
e<
65536
&&
b<
20
;
b++
){
Z=
(o
&1
?f
(B
,m
,b
,-
2)
:d
(B
,b
))
.T
;
}
o&
1?
H" } { } "
),
Z>>
5&
3^
3)
:H
" } { } } } { } "
),
32
-(
Z&
31
),
Z>>
5&
3^
3)
;
}
}
B=
V(
B,
Z)
;
g=
o;
C
_)
{
o|=
1;
m=
A
T;
}
else
{
o=
o/
2*
2^
4;
}
C
g<
4)
{
B=
S(
B)
;
}
}
}
Explanation
Write-up
I have been going through some lesser known posts that are not in the auto analysis archive, amongst these I managed to find a solution for joc3i (title 201108192339) which was originally found here. It was the third of three posts within 10 minutes, after the two prime number tables (jobvj and jobzh). The post is 355 blocks of 16 hex characters, here are the first few (line breaks added for readability):
E42D22D79C4DEEFD F9FB8E3A207EBA7D 6261C895141B04EB 185CDCB8F74FF7CF
01E9F5F65DCAD30B 4D9E1E13B7ED07B1 3DDD3AEA1DFF6582 7AB1923368B3AB3A
F1BBAA0D614BC3D7 C97662EB70479166 0D6AA7F67C843497 CC3E183ECDD83C50
...
At the time /u/fragglet noted that "unlike the previous two posts, this doesn't seem to decode to anything immediately meaningful", but it decrypts using des-ede-ecb with the same password/key as the other posts from around this time, MD5(A858DE45F56D9BC9) = 34a14a42e98ff96095af56604e290cae. The result is 2,838 characters of C source code with one token per line, it starts like this:
#define A B.
#define C if(
#define D >>E&1
#define F return
#define G typedef
#define H printf( I(
#define J(E,K) for(E=K; E--; )
#define L(M) =N(O.M)+3*N(O.M&O.P),
G
int
Q;
G
unsigned
R;
...
This is an entry from the International Obfuscated C Code Contest: robison.c, "Highly Compressed Program for Playing Hygienic Checkers" by Arch D. Robison, which won "Best game" in 2000 (https://www.ioccc.org/2000/robison/). It is a checkers game with a computer opponent. I compared it with the original 2000 version of the file from the IOCCC archive and it is byte for byte identical, so no changes or hidden message in the code as far as I can tell (note that the current file on the IOCCC site was modified in 2023 to fix input handling, so compare against the old version). Why A858 posted it is another question.
The post is too long to paste into a command here, so this fetches it from the Arctic Shift archive and decrypts it (needs curl and jq):
curl -s 'https://arctic-shift.photon-reddit.com/api/posts/ids?ids=joc3i&fields=selftext' \
| jq -r '.data[0].selftext' \
| xxd -r -p \
| openssl enc -d -des-ede-ecb -K "$(printf 'A858DE45F56D9BC9' | md5sum | cut -d ' ' -f 1)"
Solution summary
- Method
- 3DES-ECB, key MD5(name)
- Result
- obfuscated C checkers program
- Explanation
- Byte-identical to IOCCC 2000 robison.c; no hidden message
- Re-checked
- 3DES MD5(name) -> IOCCC robison.c