Add 2019/diels-grabsch2/try.sh script

The try.sh script looks for sha512sum and shasum. If either of these are
found it will use the one found (in the order of sha512sum first and
shasum -a 512 second) and prog. If neither can be found it uses just
prog. If one of them can be found, however, it shows how the output is
the same.

The prog.c was restored from prog.orig.c. Like 2019/diels-grabsch1 the
purpose is no longer valid and even more problematic is the fact that
the checksum value obviously would not be correct otherwise. Makefile
updated instead.

The README.md file has been format/typo checked.

.gitignore updated - added files that try.sh script uses (though it does
delete them after use).
This commit is contained in:
Cody Boone Ferguson committed 2023-12-15 13:44:53 -08:00
1 parent 4fc1683dc0
commit 51707205e9
6 files changed
+83 -16

No files matched your search

+2
View File
@@ -6,3 +6,5 @@ indent.c
indent.o
prog
prog.orig
prog.txt
sha512sum.txt
+1 -1
View File
@@ -38,7 +38,7 @@ include ../../var.mk
# Common C compiler warnings to silence
#
CSILENCE=
CSILENCE= -Wno-strict-prototypes
# Common C compiler warning flags
#
+10 -10
View File
@@ -15,7 +15,7 @@ make
### Try:
```sh
sha512sum prog.c || shasum -a 512 prog.c
./try.sh
```
@@ -52,11 +52,11 @@ No crypto was broken in the making of this program!
The trick is that under the hood, this program is a quine! That is, it is aware
of its own source code in string representation. But instead of printing that
string, its SHA-512 hash is computed and printed. So two major steps were
needed to obfuscate this program:
string (its own source), its SHA-512 hash is computed and printed. So two major
steps were needed to obfuscate this program:
1. Hide the quine
2. Hide the SHA-512 computation
1. Hide the quine.
2. Hide the SHA-512 computation.
Note that both steps were achieved mostly algorithmically. The code
is otherwise as short and as clean as possible. The implementation is
@@ -110,11 +110,11 @@ the cube roots of the first 80 primes. So the round constants are
calculated at runtime, which makes the program shorter and adds
another layer of obfuscation.
While this sounds like just iterating primes and executing pow(), this
While this sounds like just iterating primes and executing `pow(3)`, this
turned out to be harder than expected. If we were computing SHA-256,
it would have been as simple as that, because the round constants
would have been 32-bit values. However, SHA-512 needs the cube roots
at 64-bit precision, while double has only 53-bit mantissa precision.
at 64-bit precision, while `double` has only 53-bit mantissa precision.
Using higher-precision floating point is no option here, because the
program is meant to be portable C99. And implementing arbitrary-precision
@@ -145,7 +145,7 @@ around 7, so we need to compute with 3 bits for the integral part and
The reason for challenge 3 is that the cube of a 67-bit number is
`3*67=201` bits, but fortunately we only need to check if it is close
enough to the actual prime. It won't be exactly e.g. `409.0000...`
enough to the actual prime. It won't be exactly `409.0000...`
anyway, but must be accurate enough to distinguish the correct cube
root from its neighbours, e.g. the same number with the 64th
fractional digit increased.
@@ -167,8 +167,8 @@ That's it.
Well, I could continue with details about the encoding of the internal
state values into the string, how to avoid escaping issues, how to
find short notations for various loops, how to get rid of if(), where
the final "\";\n" is stored, how to eliminate intermediate values and
find short notations for various loops, how to get rid of `if()`, where
the final `"\";\n"` is stored, how to eliminate intermediate values and
arrays by reordering of operations, and so on. But those were all
minor issues compared to the challenges described above. What's
documented here is all you need to know to write your own version of
+1 -1
View File
@@ -10,6 +10,6 @@ b*c>>32))*a>>21)+(3*a*a*b>>6)+((b>>4)*(b>>4)*b>>46))>>18)+a*a*a)h(m,t((b<<16)|(c
^(~a&c))i(r,b(a,1)^b(a,8)^(a>>7))g(o,0,0,c<8;c++,a*256+w[b*8+c])g(d,0,0,c<13;c++,a*31+w[b*13+c]-96)g(p,0,4,c;c/=2,a|c*m(b,a|c,a)
)g(q,0,1ull<<63,c;c/=2,a|c*m(b,p(b),a|c))g(v,b>1,2,c<b;c++,a&&b%c)g(l,b?l(b-1)+1:2,a,!v(c);c++,c+1)j(n,z d=a[7]+u(a[4])+s(a[4],a
[5],a[6])+q(l(*b))+c[*b%16];f(8,a[7-e]=e-3?e-7?a[6-e]:d+_a(a[0])+x(a[1],a[2],a[3]):d+a[3])f(16*(*b%16>14),c[e]+=c[(e+9)%16]+r(c[
(e+1)%16])+_(c[(e+14)%16])))j(k,f(8,b[e]=a[e])f(80,n(a,&e,c))f(8,a[e]+=b[e]))int main(void){z a[8],b[8],c[16];f(8,a[e]=d(e))f(16,c[e
(e+1)%16])+_(c[(e+14)%16])))j(k,f(8,b[e]=a[e])f(80,n(a,&e,c))f(8,a[e]+=b[e]))int main(){z a[8],b[8],c[16];f(8,a[e]=d(e))f(16,c[e
]=e-15?o(e):d(8))k(a,b,c);f(16,c[e]=e?e-15?0:11264:1ull<<63)k(a,b,c);f(8,printf("%016llx%s",a[e],e-7?"":"\n"))return!w;}y*w=(y*)
"crsmyiajqhwy{unwa|hjoi`hlxhpxrzb~edko~rtr~ileqyjk`znqgsuitvgqnfdfa||wedvnmhozkpokootqzcexeld~oibqzpcsuw{ib{x`m`hsa`jmn}wcfzpb";
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
#
# try.sh - demonstrate IOCCC winner 2019/diels-grabsch2
#
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
# this way allows us to have the user specify a different compiler in an easy
# way.
if [[ -z "$CC" ]]; then
CC="cc"
fi
make CC="$CC" all >/dev/null || exit 1
# clear screen after compilation so that only the entry is shown
clear
SHA512SUM="$(type -P sha512sum)"
SHASUM="$(type -P shasum)"
if [[ -z "$SHA512SUM" && -z "$SHASUM" ]]; then
echo "$ ./prog" 1>&2
./prog
elif [[ -n "$SHA512SUM" ]]; then
echo "$ $SHA512SUM prog.c" 1>&2
"$SHA512SUM" prog.c
echo 1>&2
echo "$ ./prog" 1>&2
./prog
echo 1>&2
echo "$ $SHA512SUM prog.c | cut -f 1 -d' ' > sha512sum.txt" 1>&2
"$SHA512SUM" prog.c | cut -f 1 -d' ' > sha512sum.txt
echo "$ ./prog > prog.txt" 1>&2
./prog > prog.txt
echo 1>&2
echo "$ diff -s sha512sum.txt prog.txt" 1>&2
diff -s sha512sum.txt prog.txt
rm -f sha512sum prog.txt
elif [[ -n "$SHASUM" ]]; then
# Be extra careful and don't use 'else'
echo "$ $SHASUM -a 512 prog.c" 1>&2
"$SHASUM" -a 512 prog.c
echo 1>&2
echo "$ ./prog" 1>&2
./prog
echo 1>&2
echo "$ $SHASUM -a 512 prog.c | cut -f 1 -d' ' > sha512sum.txt" 1>&2
"$SHASUM" -a 512 prog.c | cut -f 1 -d' ' > sha512sum.txt
echo "$ ./prog > prog.txt" 1>&2
./prog > prog.txt
echo 1>&2
echo "$ diff -s sha512sum.txt prog.txt" 1>&2
diff -s sha512sum.txt prog.txt
rm -f sha512sum prog.txt
fi
+5 -4
View File
@@ -4154,10 +4154,11 @@ having tarballs for each individual entry as a convenience.
## <a name="2019_diels-grabsch2"></a>[2019/diels-grabsch2](/2019/diels-grabsch2/prog.c) ([README.md](/2019/diels-grabsch2/README.md]))
[Cody](#cody) made the author's statement that the entry compiles cleanly true by fixing
`warning: a function declaration without a prototype is deprecated in all
versions of C` (in main()). Not strictly necessary but if he's making fixes he
might as well.
[Cody](#cody) added the [try.sh](/2019/diels-grabsch2/try.sh) script. This
script will try and show the difference (i.e. the same output) between the
program and the result of `sha512sum` or `shasum -a 512` if either of those
tools can be found but otherwise it'll just run the program itself, showing its
own sha512sum value.
## <a name="2019_dogon"></a>[2019/dogon](/2019/dogon/prog.c) ([README.md](/2019/dogon/README.md))