├── LICENSE ├── README.md ├── build.sh ├── check.sh ├── install.sh ├── movfuscator ├── bind.patch ├── crt0.c ├── crtd.c ├── crtf.c ├── enode.patch ├── expr.patch ├── gen.patch ├── host.c ├── lcc.patch ├── makefile.patch ├── mov.md └── movfuscator.c ├── overview ├── README.md ├── demo_mov.gif ├── demo_nibbles.gif ├── gcc_asm.png ├── gcc_cfg.png ├── mov_asm.png ├── mov_cfg.png ├── prime.c ├── prime_gcc ├── prime_gcc.asm ├── prime_gcc.o ├── prime_mov ├── prime_mov.asm └── prime_mov.o ├── poc ├── README.md ├── crackme │ ├── crackme1 │ ├── crackme1.readme │ ├── crackme2 │ └── crackme2.readme ├── examples │ ├── 99_bottles │ ├── README │ ├── demo.sh │ ├── factor │ ├── nibbles │ └── primes └── movfuscator.c ├── post ├── README.md ├── adc.py ├── add.py ├── andor.py ├── cmpxchgxchg.py ├── mov32.py ├── pushpop.py ├── rand.py ├── rereg.py ├── risc.py ├── rrrrr.py ├── sbb.py ├── shuffle.py ├── sub.py ├── xadd.py └── xor.py ├── slides └── domas_2015_the_movfuscator.pdf ├── softfloat ├── 386-MOV.h ├── Makefile ├── README.txt ├── milieu.h ├── softfloat.c ├── softfloat.h ├── softfloat_inline.c ├── softfloat_specialize.c └── timesoftfloat.c └── validation ├── 3d.c ├── Makefile ├── ant.c ├── arithmetic.c ├── arithmetic_test.sh ├── bf.c ├── bitcoin_address.c ├── crc32.c ├── crypto-algorithms ├── README.md ├── aes.c ├── aes.h ├── aes_test.c ├── arcfour.c ├── arcfour.h ├── arcfour_test.c ├── base64.c ├── base64.h ├── base64_test.c ├── blowfish.c ├── blowfish.h ├── blowfish_test.c ├── des.c ├── des.h ├── des_test.c ├── md2.c ├── md2.h ├── md2_test.c ├── md5.c ├── md5.h ├── md5_test.c ├── rot-13.c ├── rot-13.h ├── rot-13_test.c ├── sha1.c ├── sha1.h ├── sha1_test.c ├── sha256.c ├── sha256.h └── sha256_test.c ├── doom ├── README.md ├── doom.patch └── doom.png ├── e.c ├── float.c ├── float_reg_spill.c ├── galton.c ├── gen_alu_test.c ├── hanoi.c ├── hello.c ├── knight.c ├── life.c ├── mandelbrot.b ├── mandelbrot.c ├── maze.c ├── md5.c ├── md5.h ├── mersenne.c ├── minesweeper.c ├── nibbles.c ├── nqueens.c ├── pi.c ├── prime.c ├── ray.c ├── ray3.c ├── s2.c ├── sin.c ├── sudoku.c ├── tictactoe.c └── timesoftfloat.c /LICENSE: -------------------------------------------------------------------------------- 1 | This software is licensed under a BSD Style License 2 | 3 | Copyright (c) 2015 Battelle Memorial Institute. All Rights Reserved. 4 | http://www.battelle.org/ 5 | 6 | Redistribution and use of this software and associated documentation 7 | ("Software"), with or without modification, are permitted provided that the 8 | following conditions are met: 9 | 10 | 1. Redistributions of source code must retain copyright statements and 11 | notices. Redistributions must also contain a copy of this document. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | 3. The names "M/o/Vfuscator" and "Battelle" must not be used to endorse or 18 | promote products derived from this Software without prior written 19 | permission of Battelle Memorial Institute. For written permission, 20 | please contact solutions@battelle.org 21 | 22 | 4. Products derived from this Software may not be called "M/o/Vfuscator" or 23 | "Battelle", nor may "M/o/Vfuscator" or "Battelle" appear in their names 24 | without prior written permission of Battelle Memorial Institute. 25 | Battelle is a registered trademark of Battelle Memorial Institute. 26 | 27 | 5. Due credit should be given to the Battelle Memorial Institute. 28 | 29 | THIS SOFTWARE IS PROVIDED BY BATTELLE MEMORIAL INSTITUTE "AS IS" AND ANY 30 | EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 32 | DISCLAIMED. IN NO EVENT SHALL BATTELLE MEMORIAL INSTITUTE OR ITS 33 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 36 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 37 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 38 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 39 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | 41 | The original author of this software is Christopher P. Domas, an employee of 42 | the Battelle Memorial Institute. 43 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -v 4 | 5 | # grab the frontend 6 | [ ! -d "lcc" ] && git clone https://github.com/drh/lcc 7 | cd lcc && git reset --hard 3b3f01b4103cd7b519ae84bd1122c9b03233e687 && cd - 8 | 9 | # create a build directory 10 | export BUILDDIR=`pwd`/build 11 | mkdir -p "$BUILDDIR" 12 | 13 | # configure the build includes 14 | mkdir -p "$BUILDDIR/include" 15 | cp -p -R lcc/include/x86/linux/* "$BUILDDIR/include" 16 | 17 | # Link to gcc's library directory 18 | GCCLN=$(gcc --print-search-dirs | grep install | head -1 | cut -d " " -f 2-) 19 | ln -sfn "$GCCLN" "$BUILDDIR/gcc" 20 | 21 | # Bind to the backend 22 | patch -N -r - lcc/src/bind.c movfuscator/bind.patch 23 | 24 | # Add the new backend to the frontend 25 | patch -N -r - lcc/makefile movfuscator/makefile.patch 26 | 27 | # Make LCC more lenient with pointer and const violations that pervade everything 28 | patch -N -r - lcc/src/enode.c movfuscator/enode.patch 29 | 30 | # Fix bug in LCC register allocation 31 | patch -N -r - lcc/src/gen.c movfuscator/gen.patch 32 | 33 | # Fix bug in LCC unary - promotion 34 | patch -N -r - lcc/src/expr.c movfuscator/expr.patch 35 | 36 | # Add additional flag passing for lcc linker 37 | patch -N -r - lcc/etc/lcc.c movfuscator/lcc.patch 38 | 39 | # Build the compiler driver 40 | make -C lcc HOSTFILE=../movfuscator/host.c CFLAGS='-g -DLCCDIR=\"$(BUILDDIR)/\"' lcc 41 | 42 | # Build lcc with the M/o/Vfuscator backend 43 | make -C lcc all 44 | 45 | # Create movcc 46 | ln -sfn "$BUILDDIR/lcc" "$BUILDDIR/movcc" 47 | 48 | # Build the M/o/Vfuscator crt libraries 49 | "$BUILDDIR/movcc" movfuscator/crt0.c -o "$BUILDDIR/crt0.o" -c -Wf--crt0 -Wf--q 50 | "$BUILDDIR/movcc" movfuscator/crtf.c -o "$BUILDDIR/crtf.o" -c -Wf--crtf -Wf--q 51 | "$BUILDDIR/movcc" movfuscator/crtd.c -o "$BUILDDIR/crtd.o" -c -Wf--crtd -Wf--q 52 | 53 | # Build the M/o/Vfuscator crt libraries with unobfuscated control flow 54 | "$BUILDDIR/movcc" movfuscator/crt0.c -o "$BUILDDIR/crt0_cf.o" -c -Wf--crt0 -Wf--q -Wf--no-mov-flow 55 | "$BUILDDIR/movcc" movfuscator/crtf.c -o "$BUILDDIR/crtf_cf.o" -c -Wf--crtf -Wf--q -Wf--no-mov-flow 56 | "$BUILDDIR/movcc" movfuscator/crtd.c -o "$BUILDDIR/crtd_cf.o" -c -Wf--crtd -Wf--q -Wf--no-mov-flow 57 | 58 | # Build the M/o/Vfuscator soft float library 59 | # These may give warnings about overflows, they are (mostly) safe to ignore 60 | make -C softfloat clean && make -C softfloat CC="$BUILDDIR/movcc" 61 | mkdir -p movfuscator/lib 62 | cp softfloat/softfloat32.o movfuscator/lib/softfloat32.o 63 | cp softfloat/softfloat64.o movfuscator/lib/softfloat64.o 64 | cp softfloat/softfloatfull.o movfuscator/lib/softfloatfull.o 65 | 66 | # Build the M/o/Vfuscator soft float library with unobfuscated control flow 67 | # These may give warnings about overflows, they are (mostly) safe to ignore 68 | make -C softfloat clean && make -C softfloat CC="$BUILDDIR/movcc -Wf--no-mov-flow" 69 | mkdir -p movfuscator/lib 70 | cp softfloat/softfloat32.o movfuscator/lib/softfloat32_cf.o 71 | cp softfloat/softfloat64.o movfuscator/lib/softfloat64_cf.o 72 | cp softfloat/softfloatfull.o movfuscator/lib/softfloatfull_cf.o 73 | 74 | make -C softfloat clean 75 | -------------------------------------------------------------------------------- /check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # To verify that the M/o/Vfuscator is working correctly, this script will pull 4 | # down an open source AES implementation, compile it, objdump it, and run it. 5 | # The objdump will take some time, be patient. 6 | 7 | echo 8 | 9 | # Grab some example source 10 | echo "Downloading..." 11 | echo 12 | sleep 2 13 | [ ! -d "validation/aes" ] && git clone https://github.com/kokke/tiny-AES128-C validation/aes 14 | cd validation/aes && git reset --hard 7e42e693288bdf22d8e677da94248115168211b9 && cd - 15 | sleep 2 16 | echo 17 | echo 18 | 19 | # M/o/Vfuscate the program 20 | echo "M/o/Vfuscating..." 21 | echo 22 | sleep 2 23 | movcc validation/aes/aes.c validation/aes/test.c -o validation/aes/aes -s 24 | sleep 2 25 | echo 26 | echo 27 | 28 | # Check the assembly 29 | echo "Dumping..." 30 | echo 31 | sleep 2 32 | objdump -d -Mintel --insn-width=15 validation/aes/aes 33 | sleep 2 34 | echo 35 | echo 36 | 37 | # Check execution 38 | echo "Running..." 39 | echo 40 | sleep 2 41 | ./validation/aes/aes 42 | sleep 2 43 | echo "M/o/Vfuscator check complete." 44 | echo 45 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -v 3 | export BUILDDIR=`pwd`/build 4 | ln -sfn "$BUILDDIR/movcc" /usr/local/bin/movcc 5 | -------------------------------------------------------------------------------- /movfuscator/bind.patch: -------------------------------------------------------------------------------- 1 | @@ -7,6 +7,7 @@ 2 | xx(sparc/solaris,solarisIR) \ 3 | xx(x86/win32, x86IR) \ 4 | xx(x86/linux, x86linuxIR) \ 5 | +xx(x86/mov, x86movIR) \ 6 | xx(symbolic/osf, symbolic64IR) \ 7 | xx(symbolic/irix,symbolicIR) \ 8 | xx(symbolic, symbolicIR) \ 9 | -------------------------------------------------------------------------------- /movfuscator/crt0.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/movfuscator/crt0.c -------------------------------------------------------------------------------- /movfuscator/crtd.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/movfuscator/crtd.c -------------------------------------------------------------------------------- /movfuscator/crtf.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/movfuscator/crtf.c -------------------------------------------------------------------------------- /movfuscator/enode.patch: -------------------------------------------------------------------------------- 1 | @@ -46,7 +46,7 @@ 2 | if (aty) 3 | q = cast(q, aty); 4 | else 5 | - error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f), 6 | + warning("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f), 7 | 8 | q->type, *proto); 9 | if ((isint(q->type) || isenum(q->type)) 10 | -------------------------------------------------------------------------------- /movfuscator/expr.patch: -------------------------------------------------------------------------------- 1 | @@ -163,8 +163,9 @@ 2 | typeerror(ADD, p, NULL); break; 3 | case '-': t = gettok(); p = unary(); p = pointer(p); 4 | if (isarith(p->type)) { 5 | - Type ty = promote(p->type); 6 | - p = cast(p, ty); 7 | + Type ty = p->type; 8 | + //Type ty = promote(p->type); 9 | + //p = cast(p, ty); 10 | if (isunsigned(ty)) { 11 | warning("unsigned operand of unary -\n"); 12 | p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL)); 13 | -------------------------------------------------------------------------------- /movfuscator/gen.patch: -------------------------------------------------------------------------------- 1 | @@ -668,7 +668,6 @@ 2 | Symbol ri = set->x.wildcard[i]; 3 | if ( 4 | ri != NULL && 5 | - ri->x.lastuse && 6 | (ri->x.regnode->mask&tmask[ri->x.regnode->set]&mask[ri->x.regnode->set]) 7 | ) { 8 | Regnode rn = ri->x.regnode; 9 | -------------------------------------------------------------------------------- /movfuscator/host.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef LCCDIR 4 | #define LCCDIR "/usr/local/lib/lcc/" 5 | #endif 6 | 7 | #define CRT0 LCCDIR "/crt0.o" 8 | #define CRTF LCCDIR "/crtf.o" 9 | #define CRTD LCCDIR "/crtd.o" 10 | 11 | #define CRT0_CF LCCDIR "/crt0_cf.o" 12 | #define CRTF_CF LCCDIR "/crtf_cf.o" 13 | #define CRTD_CF LCCDIR "/crtd_cf.o" 14 | 15 | char *suffixes[]={ 16 | ".c", 17 | ".i", 18 | ".s", 19 | ".o", 20 | ".out", 21 | 0 22 | }; 23 | 24 | char inputs[256]=""; 25 | 26 | char *cpp[]={ 27 | "/usr/bin/cpp", 28 | "-U__GNUC__", 29 | "-D_POSIX_SOURCE", 30 | /* "-D__STDC__=1", */ 31 | "-D__STRICT_ANSI__", 32 | "-Dunix", 33 | "-Di386", 34 | "-Dlinux", 35 | "-D__unix__", 36 | "-D__i386__", 37 | "-D__linux__", 38 | "-D__signed__=signed", 39 | "-std=gnu90", 40 | "$1", 41 | "$2", 42 | "$3", 43 | 0 44 | }; 45 | 46 | char *include[]={ 47 | "-I" LCCDIR "include", 48 | "-I" LCCDIR "gcc/include", 49 | "-I/usr/include", 50 | 0 51 | }; 52 | 53 | char *com[]={ 54 | LCCDIR "rcc", 55 | "-target=x86/mov", 56 | "$1", 57 | "$2", 58 | "$3", 59 | 0 60 | }; 61 | 62 | char *as[]={ 63 | "/usr/bin/as", 64 | "--32", 65 | "-o", 66 | "$3", 67 | "$1", 68 | "$2", 69 | 0 70 | }; 71 | 72 | char *ld[]={ 73 | "/usr/bin/ld", 74 | "-m", 75 | "elf_i386", 76 | "-dynamic-linker", 77 | "/lib/ld-linux.so.2", 78 | "-L" LCCDIR, 79 | "-L" LCCDIR "/gcc/32", 80 | "-lgcc", 81 | "-lc", 82 | "-lm", 83 | CRT0, 84 | "$1", 85 | "$2", 86 | CRTF, 87 | CRTD, 88 | "-o", 89 | "$3", 90 | 0 91 | }; 92 | 93 | int option(char* arg) 94 | { 95 | if (strcmp(arg, "-g")==0) { 96 | return 1; 97 | } 98 | else if (strcmp(arg, "--no-mov-flow")==0) { 99 | /* compiling with --no-mov-flow requires linking against the crt 100 | * libraries also compiled with --no-mov-flow */ 101 | int i=0; 102 | while (ld[i]) { 103 | if (strcmp(ld[i], CRT0)==0) { 104 | ld[i]=CRT0_CF; 105 | } 106 | else if (strcmp(ld[i], CRTF)==0) { 107 | ld[i]=CRTF_CF; 108 | } 109 | else if (strcmp(ld[i], CRTD)==0) { 110 | ld[i]=CRTD_CF; 111 | } 112 | i++; 113 | } 114 | return 1; 115 | } 116 | else { 117 | return 0; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /movfuscator/lcc.patch: -------------------------------------------------------------------------------- 1 | --- ../../movfuscator/lcc/etc/lcc.c 2017-09-05 15:08:32.258654206 -0400 2 | +++ lcc/etc/lcc.c 2019-04-12 12:47:53.130761991 -0400 3 | @@ -587,6 +587,13 @@ 4 | xx(unsigned_short,2) 5 | xx(unsigned_int,4) 6 | #undef xx 7 | + /* compiling with --no-mov-flow requires linking against 8 | + * --no-mov-flow compiled libraries; pass the option to the 9 | + * linker option processing */ 10 | + /* it's a kludgy solution, but the lcc flag parsing is rather 11 | + * kludgy to begin with */ 12 | + if (strcmp(&arg[3], "--no-mov-flow") == 0) 13 | + option(&arg[3]); 14 | return; 15 | case 'a': 16 | alist = append(&arg[3], alist); 17 | -------------------------------------------------------------------------------- /movfuscator/makefile.patch: -------------------------------------------------------------------------------- 1 | @@ -62,7 +62,8 @@ 2 | $Bsparc$O \ 3 | $Bstab$O \ 4 | $Bx86$O \ 5 | - $Bx86linux$O 6 | + $Bx86linux$O \ 7 | + $Bmov$O 8 | 9 | $Brcc$E:: $Bmain$O $Blibrcc$A $(EXTRAOBJS) 10 | $(LD) $(LDFLAGS) -o $@ $Bmain$O $(EXTRAOBJS) $Blibrcc$A $(EXTRALIBS) 11 | @@ -108,6 +109,7 @@ 12 | $Bsparc$O: $Bsparc.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bsparc.c 13 | $Bx86$O: $Bx86.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bx86.c 14 | $Bx86linux$O: $Bx86linux.c; $(CC) $(CFLAGS) -c -Isrc -o $@ $Bx86linux.c 15 | +$Bmov$O: $Bmov.c; $(CC) $(CFLAGS) -c -Isrc -I../movfuscator -o $@ $Bmov.c 16 | 17 | $Bdagcheck.c: $Blburg$E src/dagcheck.md; $Blburg src/dagcheck.md $@ 18 | $Balpha.c: $Blburg$E src/alpha.md; $Blburg src/alpha.md $@ 19 | @@ -115,6 +117,7 @@ 20 | $Bsparc.c: $Blburg$E src/sparc.md; $Blburg src/sparc.md $@ 21 | $Bx86.c: $Blburg$E src/x86.md; $Blburg src/x86.md $@ 22 | $Bx86linux.c: $Blburg$E src/x86linux.md; $Blburg src/x86linux.md $@ 23 | +$Bmov.c: $Blburg$E ../movfuscator/mov.md; $Blburg ../movfuscator/mov.md $@ 24 | 25 | $Bbprint$E: $Bbprint$O; $(LD) $(LDFLAGS) -o $@ $Bbprint$O 26 | $Bops$E: $Bops$O; $(LD) $(LDFLAGS) -o $@ $Bops$O 27 | @@ -221,7 +224,7 @@ 28 | 29 | clean:: testclean 30 | $(RM) $B*$O 31 | - $(RM) $Bdagcheck.c $Balpha.c $Bmips.c $Bx86.c $Bsparc.c $Bx86linux.c 32 | + $(RM) $Bdagcheck.c $Balpha.c $Bmips.c $Bx86.c $Bsparc.c $Bx86linux.c $Bmov.c 33 | $(RM) $Brcc1$E $Brcc1$E $B1rcc$E $B2rcc$E 34 | $(RM) $B*.ilk 35 | 36 | @@ -263,6 +266,7 @@ 37 | $Bmips.c \ 38 | $Bsparc.c \ 39 | $Bx86linux.c \ 40 | + $Bmov.c \ 41 | $Bx86.c 42 | 43 | C=$Blcc -A -d0.6 -Wo-lccdir=$(BUILDDIR) -Isrc -I$(BUILDDIR) 44 | -------------------------------------------------------------------------------- /overview/README.md: -------------------------------------------------------------------------------- 1 | # M/o/Vfuscator overview 2 | 3 | This directory provides a basic example of the M/o/Vfuscator. 4 | 5 | In this example, [prime.c](../validation/prime.c) from the validation directory 6 | is compiled with the M/o/Vfuscator. 7 | 8 | Assembly: 9 | 10 | GCC | M/o/Vfuscator 11 | :---------------------------------:|:---------------------------------: 12 | ![gcc asm](gcc_asm.png) | ![mov asm](mov_asm.png) 13 | 14 | Control flow graphs: 15 | 16 | GCC | M/o/Vfuscator 17 | :---------------------------------:|:---------------------------------: 18 | ![gcc CFG](gcc_cfg.png) | ![mov CFG](mov_cfg.png) 19 | 20 | In action: 21 | 22 | | movcc prime.c -o prime | 23 | |:--------------------------------:| 24 | | ![demo_mov](demo_mov.gif) | 25 | 26 | ### [prime_gcc.asm](prime_gcc.asm) 27 | 28 | The assembly generated by gcc for the is_prime function. 29 | ``` 30 | gcc -S ./overview/prime.c -o prime_gcc.asm 31 | ``` 32 | 33 | ### [prime_mov.asm](prime_mov.asm) 34 | 35 | The assembly generated by the M/o/Vfuscator for the is_prime function. 36 | ``` 37 | movcc -S ./overview/prime.c -o prime_mov.asm 38 | ``` 39 | 40 | ### [prime_gcc.o](prime_gcc.o) 41 | 42 | The object generated by gcc for the is_prime function. 43 | ``` 44 | gcc -c ./overview/prime.c -o prime_gcc.o 45 | ``` 46 | 47 | ### [prime_mov.o](prime_mov.o) 48 | 49 | The object generated by the M/o/Vfuscator for the is_prime function. 50 | ``` 51 | movcc -c ./overview/prime.c -o prime_mov.o 52 | ``` 53 | 54 | ### [prime_gcc](prime_gcc) 55 | 56 | A complete executable compiled with gcc via: 57 | ``` 58 | gcc -s ./validation/prime.c -o prime_gcc 59 | ``` 60 | 61 | ### [prime_mov](prime_mov) 62 | 63 | A complete executable compiled with the M/o/Vfuscator via: 64 | ``` 65 | movcc -s ./validation/prime.c -o prime_mov 66 | ``` 67 | -------------------------------------------------------------------------------- /overview/demo_mov.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/demo_mov.gif -------------------------------------------------------------------------------- /overview/demo_nibbles.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/demo_nibbles.gif -------------------------------------------------------------------------------- /overview/gcc_asm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/gcc_asm.png -------------------------------------------------------------------------------- /overview/gcc_cfg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/gcc_cfg.png -------------------------------------------------------------------------------- /overview/mov_asm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/mov_asm.png -------------------------------------------------------------------------------- /overview/mov_cfg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/mov_cfg.png -------------------------------------------------------------------------------- /overview/prime.c: -------------------------------------------------------------------------------- 1 | int is_prime(int x) 2 | { 3 | int i; 4 | if (x==1) { 5 | return 0; 6 | } 7 | if (x==2) { 8 | return 1; 9 | } 10 | for (i=2; i*i<=x; i++) { 11 | if (x%i==0) { 12 | return 0; 13 | } 14 | } 15 | return 1; 16 | } 17 | -------------------------------------------------------------------------------- /overview/prime_gcc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/prime_gcc -------------------------------------------------------------------------------- /overview/prime_gcc.asm: -------------------------------------------------------------------------------- 1 | : 2 | push ebp 3 | mov ebp,esp 4 | sub esp,0x10 5 | cmp DWORD PTR [ebp+0x8],0x1 6 | jne 8048490 7 | mov eax,0x0 8 | jmp 80484cf 9 | cmp DWORD PTR [ebp+0x8],0x2 10 | jne 804849d 11 | mov eax,0x1 12 | jmp 80484cf 13 | mov DWORD PTR [ebp-0x4],0x2 14 | jmp 80484be 15 | mov eax,DWORD PTR [ebp+0x8] 16 | cdq 17 | idiv DWORD PTR [ebp-0x4] 18 | mov eax,edx 19 | test eax,eax 20 | jne 80484ba 21 | mov eax,0x0 22 | jmp 80484cf 23 | add DWORD PTR [ebp-0x4],0x1 24 | mov eax,DWORD PTR [ebp-0x4] 25 | imul eax,DWORD PTR [ebp-0x4] 26 | cmp eax,DWORD PTR [ebp+0x8] 27 | jle 80484a6 28 | mov eax,0x1 29 | leave 30 | ret 31 | -------------------------------------------------------------------------------- /overview/prime_gcc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/prime_gcc.o -------------------------------------------------------------------------------- /overview/prime_mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/prime_mov -------------------------------------------------------------------------------- /overview/prime_mov.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/overview/prime_mov.o -------------------------------------------------------------------------------- /poc/README.md: -------------------------------------------------------------------------------- 1 | # M/o/Vfuscator 2 | The single instruction compiler. 3 | 4 | ## Overview 5 | This original M/o/Vfuscator (M/o/Vfuscator 1.0) compiles programs into mov instructions from the esoteric language BrainF@$!, and is best used in conjunction with the BFBASIC compiler by Jeffry Johnston. 6 | 7 | ## Usage 8 | 9 | Compile the M/o/Vfuscator with: 10 | ``` 11 | gcc movfuscator.c -o movfuscator 12 | ``` 13 | 14 | Compile BF to movs with: 15 | ``` 16 | ./movfuscator < example.bf > example.asm 17 | ``` 18 | 19 | Build a mov executable: 20 | ``` 21 | nasm -felf example.asm -o example.o 22 | ld -melf_i386 example.o -o example 23 | ``` 24 | 25 | The complete process from a BASIC program to a mov-only executable: 26 | ``` 27 | ./bfbasic.sh example.bas example.bf 28 | ./movfuscator < example.bf > example.asm 29 | nasm -felf example.asm -o example.o 30 | ld -melf_i386 example.o -o example 31 | ./example 32 | ``` 33 | 34 | Flags: 35 | ``` 36 | -mmio Use memory mapped I/O. Allows mov instructions instead of int 0x80 for I/O, but requires I/O streams to be backed by files. 37 | -nojmp Replace the single jmp instruction with a faulting mov to implement the program loop. 38 | -mov Use only mov instructions; same as -mmio -nojmp. 39 | -cell16 Use 16 bit memory cells. 40 | -O Enable optimization. 41 | ``` 42 | 43 | ## Author 44 | - chris domas, @xoreaxeaxeax 45 | 46 | ## References 47 | * BFBASIC: http://brainfuck.cvs.sourceforge.net/viewvc/brainfuck/bfbasic/ 48 | * Example BF programs: http://esoteric.sange.fi/brainfuck/bf-source/prog/ 49 | * "mov is Turing-complete", by Stephen Dolan: http://www.cl.cam.ac.uk/~sd601/papers/mov.pdf 50 | -------------------------------------------------------------------------------- /poc/crackme/crackme1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/crackme/crackme1 -------------------------------------------------------------------------------- /poc/crackme/crackme1.readme: -------------------------------------------------------------------------------- 1 | M/o/Vfuscator 2.0 crackme 2 | github.com/xoreaxeaxeax/movfuscator 3 | 4 | Goal: 5 | Find the key. 6 | 7 | Details: 8 | A simple 15 line crackme in C, compiled with the M/o/Vfuscator2. 9 | -------------------------------------------------------------------------------- /poc/crackme/crackme2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/crackme/crackme2 -------------------------------------------------------------------------------- /poc/crackme/crackme2.readme: -------------------------------------------------------------------------------- 1 | M/o/Vfuscator 2.0 crackme2 2 | github.com/xoreaxeaxeax/movfuscator 3 | 4 | Goal: 5 | Find the key. 6 | 7 | Details: 8 | A simple 15 line crackme in C, compiled with the M/o/Vfuscator2. 9 | 10 | Same as crackme1, but with a new key and a constant time strcmp. Should 11 | prevent the easiest solutions to crackme1. 12 | -------------------------------------------------------------------------------- /poc/examples/99_bottles: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/examples/99_bottles -------------------------------------------------------------------------------- /poc/examples/README: -------------------------------------------------------------------------------- 1 | A collection of M/o/Vfuscated example programs: 2 | 3 | nibbles: 4 | Compiled from C to movs with M/o/Vfuscator2. 5 | Move with w, a, s, d. 6 | The jmp at the end and external calls still need to be movfuscated. 7 | 8 | factor: 9 | Compiled from BF to movs with M/o/Vfuscator1. 10 | Example of using no compiler flags, leaving the int 0x80 and single jmp. 11 | 12 | primes: 13 | Compiled from BF to movs with M/o/Vfuscator1. 14 | Example of -nojmp flag, removing the jmp instruction at the end. 15 | 16 | 99_bottles: 17 | Compiled from BASIC to BF with BFBASIC, BF to movs with M/o/Vfuscator1. 18 | Example of -mmio and -nojmp flags, leaving only mov instructions. 19 | Uses MMIO for output, so requires file-backed I/O streams. 20 | 21 | Run with: 22 | 23 | ./example 24 | 25 | Executables compiled with the -mmio flag require file-backed I/O streams, and 26 | should be run with: 27 | 28 | ./example < sample_in > sample_out 29 | 30 | or: 31 | 32 | ./demo.sh example 33 | 34 | to watch the output directly. 35 | -------------------------------------------------------------------------------- /poc/examples/demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | touch sample_in 4 | touch sample_out 5 | (./$1 < sample_in > sample_out &) && watch -t -n .1 'tail -20 sample_out | sed "s/.*\r\([^\r]*\)/\1/g"' 6 | pkill $1 7 | -------------------------------------------------------------------------------- /poc/examples/factor: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/examples/factor -------------------------------------------------------------------------------- /poc/examples/nibbles: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/examples/nibbles -------------------------------------------------------------------------------- /poc/examples/primes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/poc/examples/primes -------------------------------------------------------------------------------- /post/README.md: -------------------------------------------------------------------------------- 1 | # M/o/Vfuscator post-processors 2 | 3 | ## Overview 4 | 5 | The M/o/Vfuscator post-processors take assembly from the M/o/Vfuscator and 6 | translate it for additional obfuscation, new instructions, or optimization. At 7 | some point they may be integrated into the actual compiler; for now they are 8 | separate scripts. 9 | 10 | The post-processors are used as follows: 11 | 12 | ``` 13 | movcc example.c -S 14 | python post_processor.py example.s 15 | as --32 example.s -o example.o 16 | movcc example.o 17 | ``` 18 | 19 | Note that the final linking step above will add the M/o/Vfuscator crt libraries; 20 | you may wish to also run these libraries through the post-processing script, to 21 | ensure the entire executable is processed. See the M/o/Vfuscator build script 22 | for an example of building the crt libraries. 23 | 24 | The current post-processing scripts are outlined below. 25 | 26 | ## XORfuscator 27 | 28 | x86 xor is Turing-complete, so the XORfuscator translates programs into XOR 29 | instructions, and only XOR instructions. 30 | 31 | ## SUBfuscator 32 | 33 | Translates programs into only SUB instructions. 34 | 35 | ## ADDfuscator 36 | 37 | Translates programs into only ADD instructions. 38 | 39 | ## XADDfuscator 40 | 41 | Translates programs into only XADD instructions. 42 | 43 | ## ADCfuscator 44 | 45 | Translates programs into only ADC instructions. 46 | 47 | ## SBBfuscator 48 | 49 | Translates programs into only SBB instructions. 50 | 51 | ## AND/ORfuscator 52 | 53 | Translates programs into only AND/OR instructions. 54 | 55 | ## PUSH/POPfuscator 56 | 57 | Translates programs into only PUSH/POP instructions. 58 | 59 | ## rrrrrfuscator 60 | 61 | Translates programs into only single bit shift and rotate instructions. 62 | 63 | ## CMPXCHG/XCHGfuscator 64 | 65 | Translates programs into only CMPXCGH/XCHG instructions. 66 | 67 | ## randomfuscator 68 | 69 | Selects a random translation from amongst the other translators. 70 | 71 | ## The Peephole Shuffler 72 | 73 | Shuffles the assembly instructions to prevent simple decompilation. 74 | 75 | ## The Register Reallocator 76 | 77 | Reallocates registers to diversify programs and prevent simple decompilation. 78 | 79 | ## The RISC post-processor 80 | 81 | Converts all move instructions to 4-byte indexed addressing, and reduces the 82 | program to using two registers. In general, all accesses become either 83 | "mov esi/edi, [BASE+esi/edi]" or "mov [BASE+esi/edi], esi/edi", where BASE is 84 | some constant address. This allows more easily adapting the M/o/Vfuscator to 85 | RISC-type architectures. 86 | 87 | -------------------------------------------------------------------------------- /post/adc.py: -------------------------------------------------------------------------------- 1 | # The ADCfuscator post-processor - translates M/o/Vfuscated C into only 2 | # adc instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'ebp') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | #NOTE: The ADCfuscator only works if there are less than 2^32 carries in the 28 | # program. If this is (somehow) a problem, you can add a second carry 29 | # bucket to consume the next ~2^64. 30 | f.write(".section .data\n") 31 | f.write(".carry_collector: .long 0\n") 32 | f.write(".section .text\n") 33 | for l in asm: 34 | if l.startswith("mov"): 35 | f.write("#adc> " + l) 36 | 37 | tok = l.find(",", l.find(")")) 38 | if tok == -1: 39 | tok = l.find(",") 40 | source = l[l.index(" "):tok].strip() 41 | dest = l[tok+1:].strip() 42 | 43 | if l.startswith("movb"): 44 | b = 8 45 | s = "b" 46 | reg = "%bl" 47 | elif l.startswith("movw"): 48 | b = 16 49 | s = "w" 50 | reg = "%bx" 51 | elif l.startswith("movl"): 52 | b = 32 53 | s = "l" 54 | reg = "%ebx" 55 | 56 | # ridiculous register shuffling necessary b/c ebx is 57 | # our last byte addressable register 58 | 59 | for i in xrange(0,b): 60 | f.write("adcl $0, (.carry_collector)\n") 61 | f.write("adc%s %s, %s\n" % (s, reg, reg)) 62 | 63 | for i in xrange(0,b): 64 | f.write("adcl $0, (.carry_collector)\n") 65 | f.write("adcl %esi, %esi\n") 66 | 67 | f.write("adcl $0, (.carry_collector)\n") 68 | f.write("adc%s %s, %s\n" % (s, source, reg)) 69 | f.write("adcl $0, (.carry_collector)\n") 70 | f.write("adcl %ebx, %esi\n") 71 | 72 | for i in xrange(0,b): 73 | f.write("adcl $0, (.carry_collector)\n") 74 | f.write("adc%s %s, %s\n" % (s, reg, reg)) 75 | 76 | f.write("adcl $0, (.carry_collector)\n") 77 | f.write("adc%s %s, %s\n" % (s, dest, reg)) 78 | 79 | for i in xrange(0,b): 80 | f.write("adcl $0, (.carry_collector)\n") 81 | f.write("adc%s %s, %s\n" % (s, reg, dest)) 82 | f.write("adcl $0, (.carry_collector)\n") 83 | f.write("adc%s %s, %s\n" % (s, reg, reg)) 84 | 85 | f.write("adcl $0, (.carry_collector)\n") 86 | f.write("adcl %esi, %ebx\n") 87 | f.write("adcl $0, (.carry_collector)\n") 88 | f.write("adc%s %s, %s\n" % (s, reg, dest)) 89 | 90 | else: 91 | f.write(l) 92 | 93 | -------------------------------------------------------------------------------- /post/add.py: -------------------------------------------------------------------------------- 1 | # The ADDfuscator post-processor - translates M/o/Vfuscated C into only 2 | # add instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'ebp') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | for l in asm: 28 | if l.startswith("mov"): 29 | f.write("#add> " + l) 30 | 31 | tok = l.find(",", l.find(")")) 32 | if tok == -1: 33 | tok = l.find(",") 34 | source = l[l.index(" "):tok].strip() 35 | dest = l[tok+1:].strip() 36 | 37 | if l.startswith("movb"): 38 | b = 8 39 | s = "b" 40 | reg = "%bl" 41 | elif l.startswith("movw"): 42 | b = 16 43 | s = "w" 44 | reg = "%bx" 45 | elif l.startswith("movl"): 46 | b = 32 47 | s = "l" 48 | reg = "%ebx" 49 | 50 | # ridiculous register shuffling necessary b/c ebx is 51 | # our last byte addressable register 52 | 53 | for i in xrange(0,b): 54 | f.write("add%s %s, %s\n" % (s, reg, reg)) 55 | 56 | for i in xrange(0,b): 57 | f.write("addl %esi, %esi\n") 58 | 59 | f.write("add%s %s, %s\n" % (s, source, reg)) 60 | f.write("addl %ebx, %esi\n") 61 | 62 | for i in xrange(0,b): 63 | f.write("add%s %s, %s\n" % (s, reg, reg)) 64 | 65 | f.write("add%s %s, %s\n" % (s, dest, reg)) 66 | 67 | for i in xrange(0,b): 68 | f.write("add%s %s, %s\n" % (s, reg, dest)) 69 | f.write("add%s %s, %s\n" % (s, reg, reg)) 70 | 71 | f.write("addl %esi, %ebx\n") 72 | f.write("add%s %s, %s\n" % (s, reg, dest)) 73 | 74 | else: 75 | f.write(l) 76 | 77 | -------------------------------------------------------------------------------- /post/andor.py: -------------------------------------------------------------------------------- 1 | # The ANDORfuscator post-processor - translates M/o/Vfuscated C into only 2 | # and/or instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'esi') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | for l in asm: 28 | if l.startswith("mov"): 29 | f.write("#andor> " + l) 30 | 31 | tok = l.find(",", l.find(")")) 32 | if tok == -1: 33 | tok = l.find(",") 34 | source = l[l.index(" "):tok].strip() 35 | dest = l[tok+1:].strip() 36 | 37 | if l.startswith("movb"): 38 | s = "b" 39 | reg = "%bl" 40 | elif l.startswith("movw"): 41 | s = "w" 42 | reg = "%bx" 43 | elif l.startswith("movl"): 44 | s = "l" 45 | reg = "%ebx" 46 | 47 | f.write("and%s %s, %s\n" % (s, "$0", reg)) 48 | f.write("or%s %s, %s\n" % (s, source, reg)) 49 | f.write("and%s %s, %s\n" % (s, "$0", dest)) 50 | f.write("or%s %s, %s\n" % (s, reg, dest)) 51 | 52 | else: 53 | f.write(l) 54 | 55 | -------------------------------------------------------------------------------- /post/cmpxchgxchg.py: -------------------------------------------------------------------------------- 1 | # The CMPXCHGXCHGfuscator post-processor - translates M/o/Vfuscated C into only 2 | # cmpxchg/xchg instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | import hashlib 21 | 22 | with open(sys.argv[1]) as f: 23 | asm = f.readlines() 24 | 25 | # pass 1 - cmpxchg/xchg can't load constants 26 | # replace all constant references with memory references instead 27 | with open(sys.argv[1], 'w') as f: 28 | for l in asm: 29 | if l.startswith("mov"): 30 | f.write("#constant> " + l) 31 | 32 | tok = l.find(",", l.find(")")) 33 | if tok == -1: 34 | tok = l.find(",") 35 | source = l[l.index(" "):tok].strip() 36 | dest = l[tok+1:].strip() 37 | 38 | # NOTE: requires M/o/Vfuscator to only produce dword constants 39 | if source.startswith("$"): 40 | # have to jump through some hoops due to as and ld limitations 41 | # on absolutes 42 | c = hashlib.md5(source[1:]).hexdigest() 43 | f.write(".section .data\n") 44 | f.write(".ifndef .C%s\n" % c) 45 | f.write(".C%s: .long %s\n" % (c, source[1:])) 46 | f.write(".endif\n") 47 | f.write(".section .text\n") 48 | f.write("movl (.C%s), %%edi\n" % c) 49 | f.write("movl %%edi, %s\n" % dest) 50 | else: 51 | f.write(l) 52 | 53 | else: 54 | f.write(l) 55 | 56 | 57 | with open(sys.argv[1]) as f: 58 | asm = f.readlines() 59 | 60 | # we need to free up eax, but have no other byte-addressable registers. 61 | # free up ebx first. 62 | 63 | # TODO: the register shuffling will break return values from library calls. 64 | asm = [l.replace('%ebx', '%esi') for l in asm] 65 | asm = [l.replace('%eax', '%ebx') for l in asm] 66 | asm = [l.replace('%ax', '%bx') for l in asm] 67 | asm = [l.replace('%al', '%bl') for l in asm] 68 | asm = [l.replace('%ah', '%bh') for l in asm] 69 | 70 | with open(sys.argv[1], 'w') as f: 71 | for l in asm: 72 | if l.startswith("mov"): 73 | f.write("#cmpxchgxchg> " + l) 74 | 75 | tok = l.find(",", l.find(")")) 76 | if tok == -1: 77 | tok = l.find(",") 78 | source = l[l.index(" "):tok].strip() 79 | dest = l[tok+1:].strip() 80 | 81 | if l.startswith("movb"): 82 | s = "b" 83 | reg = "%al" 84 | elif l.startswith("movw"): 85 | s = "w" 86 | reg = "%ax" 87 | elif l.startswith("movl"): 88 | s = "l" 89 | reg = "%eax" 90 | 91 | if source.find("(")>=0: 92 | # source is a memory reference 93 | f.write("cmpxchg%s %s, %s\n" % (s, reg, source)) 94 | f.write("xchg%s %s, %s\n" % (s, dest, reg)) 95 | else: 96 | # source is a register 97 | f.write("cmpxchg%s %s, %s\n" % (s, source, dest)) 98 | f.write("cmpxchg%s %s, %s\n" % (s, source, dest)) 99 | else: 100 | f.write(l) 101 | -------------------------------------------------------------------------------- /post/rereg.py: -------------------------------------------------------------------------------- 1 | # The re-reg post-processor - reallocates registers to diversify programs and 2 | # prevent simple decompilation. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. 6 | 7 | # To use: 8 | # movcc example.c -S 9 | # python this.py example.s 10 | # as --32 example.s -o example.o 11 | # movcc example.o 12 | 13 | # Note that the final linking step above will add the M/o/Vfuscator crt 14 | # libraries; you may wish to run these libraries through this same script, to 15 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 16 | # for an example of building the crt libraries. 17 | 18 | import sys 19 | import random 20 | import re 21 | 22 | r0 = 0 23 | r1 = 1 24 | r2 = 2 25 | r3 = 3 26 | n = 4 27 | 28 | # assumes compiler only emits eax, ebx, ecx, edx 29 | free_regs = ['A', 'B', 'C', 'D'] 30 | 31 | alloc = dict() 32 | 33 | def getfree(): 34 | random.shuffle(free_regs) 35 | return free_regs.pop() 36 | 37 | def free(r): 38 | if not r in free_regs: 39 | free_regs.append(r) 40 | 41 | def getnext(): 42 | global n 43 | nr = n 44 | n = n + 1 45 | return nr 46 | 47 | def genreg(l): 48 | global r0, r1, r2, r3 49 | 50 | if l.startswith("movb"): 51 | s = "b" 52 | elif l.startswith("movw"): 53 | s = "w" 54 | elif l.startswith("movl"): 55 | s = "l" 56 | 57 | tok = l.find(",", l.find(")")) 58 | if tok == -1: 59 | tok = l.find(",") 60 | source = l[l.index(" "):tok].strip() 61 | dest = l[tok+1:].strip() 62 | 63 | if "TR0" in source: 64 | source = source.replace("TR0", "r%d" % r0) 65 | if "TR1" in source: 66 | source = source.replace("TR1", "r%d" % r1) 67 | if "TR2" in source: 68 | source = source.replace("TR2", "r%d" % r2) 69 | if "TR3" in source: 70 | source = source.replace("TR3", "r%d" % r3) 71 | 72 | if s == "l": 73 | if dest.startswith("%TR0"): 74 | r0 = getnext() 75 | dest = dest.replace("TR0", "r%d" % r0) 76 | if dest.startswith("%TR1"): 77 | r1 = getnext() 78 | dest = dest.replace("TR1", "r%d" % r1) 79 | if dest.startswith("%TR2"): 80 | r2 = getnext() 81 | dest = dest.replace("TR2", "r%d" % r2) 82 | if dest.startswith("%TR3"): 83 | r3 = getnext() 84 | dest = dest.replace("TR3", "r%d" % r3) 85 | else: 86 | if dest.startswith("%TR0"): 87 | dest = dest.replace("TR0", "r%d" % r0) 88 | if dest.startswith("%TR1"): 89 | dest = dest.replace("TR1", "r%d" % r1) 90 | if dest.startswith("%TR2"): 91 | dest = dest.replace("TR2", "r%d" % r2) 92 | if dest.startswith("%TR3"): 93 | dest = dest.replace("TR3", "r%d" % r3) 94 | 95 | if "TR0" in dest: 96 | dest = dest.replace("TR0", "r%d" % r0) 97 | if "TR1" in dest: 98 | dest = dest.replace("TR1", "r%d" % r1) 99 | if "TR2" in dest: 100 | dest = dest.replace("TR2", "r%d" % r2) 101 | if "TR3" in dest: 102 | dest = dest.replace("TR3", "r%d" % r3) 103 | 104 | return "mov%s %s, %s" % (s, source, dest) 105 | 106 | def is_used(r, asm, i): 107 | for k in range(i+1, len(asm)): 108 | if r in asm[k]: 109 | return True 110 | return False 111 | 112 | def rereg(l, asm, i): 113 | global alloc 114 | 115 | if l.startswith("movb"): 116 | s = "b" 117 | elif l.startswith("movw"): 118 | s = "w" 119 | elif l.startswith("movl"): 120 | s = "l" 121 | 122 | tok = l.find(",", l.find(")")) 123 | if tok == -1: 124 | tok = l.find(",") 125 | source = l[l.index(" "):tok].strip() 126 | dest = l[tok+1:].strip() 127 | 128 | source_regs = re.findall(r'r\d+_', source) 129 | for r in source_regs: 130 | if not r in alloc: 131 | alloc[r] = getfree() 132 | source = source.replace(r, alloc[r] + "_") 133 | 134 | for r in source_regs: 135 | if not r in dest: 136 | if not is_used(r, asm, i+1): 137 | free(alloc[r]) 138 | 139 | dest_regs = re.findall(r'r\d+_', dest) 140 | for r in dest_regs: 141 | if not r in alloc: 142 | alloc[r] = getfree() 143 | dest = dest.replace(r, alloc[r] + "_") 144 | 145 | for r in dest_regs: 146 | if not is_used(r, asm, i+1): 147 | free(alloc[r]) 148 | 149 | return "mov%s %s, %s" % (s, source, dest) 150 | 151 | with open(sys.argv[1]) as f: 152 | asm = f.readlines() 153 | 154 | for i, l in enumerate(asm): 155 | if l.startswith("mov"): 156 | l = l.replace("%eax", "%TR0_l") 157 | l = l.replace("%ax", "%TR0_w") 158 | l = l.replace("%al", "%TR0_b") 159 | l = l.replace("%ah", "%TR0_h") 160 | 161 | l = l.replace("%ebx", "%TR1_l") 162 | l = l.replace("%bx", "%TR1_w") 163 | l = l.replace("%bl", "%TR1_b") 164 | l = l.replace("%bh", "%TR1_h") 165 | 166 | l = l.replace("%ecx", "%TR2_l") 167 | l = l.replace("%cx", "%TR2_w") 168 | l = l.replace("%cl", "%TR2_b") 169 | l = l.replace("%ch", "%TR2_h") 170 | 171 | l = l.replace("%edx", "%TR3_l") 172 | l = l.replace("%dx", "%TR3_w") 173 | l = l.replace("%dl", "%TR3_b") 174 | l = l.replace("%dh", "%TR3_h") 175 | 176 | asm[i]=l 177 | 178 | for i, l in enumerate(asm): 179 | if l.startswith("mov"): 180 | asm[i]=genreg(l) 181 | 182 | for i, l in enumerate(asm): 183 | if l.startswith("mov"): 184 | asm[i]=rereg(l, asm, i) 185 | 186 | for i, l in enumerate(asm): 187 | if l.startswith("mov"): 188 | l = l.replace("A_l", "eax") 189 | l = l.replace("A_w", "ax") 190 | l = l.replace("A_b", "al") 191 | l = l.replace("A_h", "ah") 192 | 193 | l = l.replace("B_l", "ebx") 194 | l = l.replace("B_w", "bx") 195 | l = l.replace("B_b", "bl") 196 | l = l.replace("B_h", "bh") 197 | 198 | l = l.replace("C_l", "ecx") 199 | l = l.replace("C_w", "cx") 200 | l = l.replace("C_b", "cl") 201 | l = l.replace("C_h", "ch") 202 | 203 | l = l.replace("D_l", "edx") 204 | l = l.replace("D_w", "dx") 205 | l = l.replace("D_b", "dl") 206 | l = l.replace("D_h", "dh") 207 | 208 | asm[i] = l 209 | 210 | for l in asm: 211 | print l.strip() 212 | -------------------------------------------------------------------------------- /post/rrrrr.py: -------------------------------------------------------------------------------- 1 | # The rrrrrfuscator post-processor - translates M/o/Vfuscated C into only 2 | # single-bit shift and rotate instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | import hashlib 21 | 22 | with open(sys.argv[1]) as f: 23 | asm = f.readlines() 24 | 25 | with open(sys.argv[1], 'w') as f: 26 | for l in asm: 27 | if l.startswith("mov"): 28 | f.write("#constant> " + l) 29 | 30 | tok = l.find(",", l.find(")")) 31 | if tok == -1: 32 | tok = l.find(",") 33 | source = l[l.index(" "):tok].strip() 34 | dest = l[tok+1:].strip() 35 | 36 | # NOTE: requires M/o/Vfuscator to only produce dword constants 37 | if source.startswith("$"): 38 | # have to jump through some hoops due to as and ld limitations 39 | # on absolutes 40 | c = hashlib.md5(source[1:]).hexdigest() 41 | f.write(".section .data\n") 42 | f.write(".ifndef .C%s\n" % c) 43 | f.write(".C%s: .long %s\n" % (c, source[1:])) 44 | f.write(".endif\n") 45 | f.write(".section .text\n") 46 | f.write("movl (.C%s), %%edi\n" % c) 47 | f.write("movl %%edi, %s\n" % dest) 48 | else: 49 | f.write(l) 50 | 51 | else: 52 | f.write(l) 53 | 54 | 55 | with open(sys.argv[1]) as f: 56 | asm = f.readlines() 57 | 58 | asm = [l.replace('%ebx', '%esi') for l in asm] 59 | 60 | with open(sys.argv[1], 'w') as f: 61 | f.write(".section .data\n") 62 | f.write("rrr8: .byte 0\n") 63 | f.write("rrr16: .word 0\n") 64 | f.write("rrr32: .long 0\n") 65 | 66 | for l in asm: 67 | if l.startswith("mov"): 68 | f.write("#rrr> " + l) 69 | 70 | tok = l.find(",", l.find(")")) 71 | if tok == -1: 72 | tok = l.find(",") 73 | source = l[l.index(" "):tok].strip() 74 | dest = l[tok+1:].strip() 75 | 76 | if l.startswith("movb"): 77 | b = 8 78 | s = "b" 79 | reg = "%bl" 80 | t = "(rrr8)" 81 | elif l.startswith("movw"): 82 | b = 16 83 | s = "w" 84 | reg = "%bx" 85 | t = "(rrr16)" 86 | elif l.startswith("movl"): 87 | b = 32 88 | s = "l" 89 | reg = "%ebx" 90 | t = "(rrr32)" 91 | 92 | f.write("rcr%s %s\n" % (s, source)) 93 | 94 | for i in range(0,b): 95 | f.write("rcr%s %s\n" % (s, reg)) 96 | f.write("sar%s %s\n" % (s, reg)) 97 | f.write("rcl%s %s\n" % (s, reg)) 98 | f.write("rcr%s %s\n" % (s, t)) 99 | f.write("rcl%s %s\n" % (s, reg)) 100 | f.write("rcr%s %s\n" % (s, source)) 101 | 102 | for i in range(0,b): 103 | f.write("rcr%s %s\n" % (s, t)) 104 | f.write("rcr%s %s\n" % (s, dest)) 105 | 106 | else: 107 | f.write(l) 108 | -------------------------------------------------------------------------------- /post/sbb.py: -------------------------------------------------------------------------------- 1 | # The SBBfuscator post-processor - translates M/o/Vfuscated C into only 2 | # sbb instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'ebp') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | #NOTE: The SBBfuscator only works if there are less than 2^32 borrows in the 28 | # program. If this is (somehow) a problem, you can add a second carry 29 | # bucket to consume the next ~2^64. 30 | f.write(".section .data\n") 31 | f.write(".carry_collector: .long 0xffffffff\n") 32 | f.write(".section .text\n") 33 | for l in asm: 34 | if l.startswith("mov"): 35 | f.write("#sbb> " + l) 36 | 37 | tok = l.find(",", l.find(")")) 38 | if tok == -1: 39 | tok = l.find(",") 40 | source = l[l.index(" "):tok].strip() 41 | dest = l[tok+1:].strip() 42 | 43 | if l.startswith("movb"): 44 | s = "b" 45 | reg = "%bl" 46 | elif l.startswith("movw"): 47 | s = "w" 48 | reg = "%bx" 49 | elif l.startswith("movl"): 50 | s = "l" 51 | reg = "%ebx" 52 | 53 | # ridiculous register shuffling necessary b/c ebx is 54 | # our last byte addressable register 55 | f.write("sbbl $0, (.carry_collector)\n") 56 | f.write("sbbl %ebx, %ebx\n") 57 | f.write("sbbl $0, (.carry_collector)\n") 58 | f.write("sbbl %esi, %esi\n") 59 | f.write("sbbl $0, (.carry_collector)\n") 60 | f.write("sbbl %edi, %edi\n") 61 | f.write("sbbl $0, (.carry_collector)\n") 62 | f.write("sbb%s %s, %s\n" % (s, dest, reg)) 63 | f.write("sbbl $0, (.carry_collector)\n") 64 | f.write("sbbl %ebx, %esi\n") 65 | f.write("sbbl $0, (.carry_collector)\n") 66 | f.write("sbbl %esi, %edi\n") 67 | f.write("sbbl $0, (.carry_collector)\n") 68 | f.write("sbbl %edi, %ebx\n") 69 | f.write("sbbl $0, (.carry_collector)\n") 70 | f.write("sbbl %edi, %ebx\n") 71 | f.write("sbbl $0, (.carry_collector)\n") 72 | f.write("sbb%s %s, %s\n" % (s, source, reg)) 73 | f.write("sbbl $0, (.carry_collector)\n") 74 | f.write("sbb%s %s, %s\n" % (s, reg, dest)) 75 | 76 | else: 77 | f.write(l) 78 | 79 | -------------------------------------------------------------------------------- /post/shuffle.py: -------------------------------------------------------------------------------- 1 | # The shuffle post-processor - shuffles the instructions output from the 2 | # M/o/Vfuscator to prevent simple decompilation. 3 | 4 | # This shuffler takes a naive approach to instruction shuffling. It is 5 | # generally overly restrictive (especially w.r.t. memory access ordering), which 6 | # yields less than ideal results. It is better viewed as a proof of concept or 7 | # useful starting point, rather than actual protection from decompilation. 8 | 9 | # This is a post-processing routine that can be run on assembly output from the 10 | # M/o/Vfuscator. 11 | 12 | # To use: 13 | # movcc example.c -S 14 | # python this.py example.s 15 | # as --32 example.s -o example.o 16 | # movcc example.o 17 | 18 | # Note that the final linking step above will add the M/o/Vfuscator crt 19 | # libraries; you may wish to run these libraries through this same script, to 20 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 21 | # for an example of building the crt libraries. 22 | 23 | import sys 24 | import random 25 | 26 | SWAP_PASSES = 10 27 | 28 | def next_mov(asm, i): 29 | for k in range(i+1, len(asm)): 30 | if asm[k].startswith("mov"): 31 | return (k, asm[k]) 32 | return (-1,"") 33 | 34 | # assumes only eax, ebx, ecx, edx are emitted by compiler 35 | def gen_reg(l): 36 | l=l.replace("eax", "r0") 37 | l=l.replace("ah", "r0") 38 | l=l.replace("al", "r0") 39 | l=l.replace("ax", "r0") 40 | 41 | l=l.replace("ebx", "r1") 42 | l=l.replace("bh", "r1") 43 | l=l.replace("bl", "r1") 44 | l=l.replace("bx", "r1") 45 | 46 | l=l.replace("ecx", "r2") 47 | l=l.replace("ch", "r2") 48 | l=l.replace("cl", "r2") 49 | l=l.replace("cx", "r2") 50 | 51 | l=l.replace("edx", "r3") 52 | l=l.replace("dh", "r3") 53 | l=l.replace("dl", "r3") 54 | l=l.replace("dx", "r3") 55 | 56 | return l 57 | 58 | def can_swap(l1, l2): 59 | l1 = gen_reg(l1) 60 | l2 = gen_reg(l2) 61 | 62 | if l1.startswith("movb"): 63 | s1 = "b" 64 | elif l1.startswith("movw"): 65 | s1 = "w" 66 | elif l1.startswith("movl"): 67 | s1 = "l" 68 | 69 | if l2.startswith("movb"): 70 | s2 = "b" 71 | elif l2.startswith("movw"): 72 | s2 = "w" 73 | elif l2.startswith("movl"): 74 | s2 = "l" 75 | 76 | tok1 = l1.find(",", l1.find(")")) 77 | if tok1 == -1: 78 | tok1 = l1.find(",") 79 | source1 = l1[l1.index(" "):tok1].strip() 80 | dest1 = l1[tok1+1:].strip() 81 | 82 | tok2 = l2.find(",", l2.find(")")) 83 | if tok2 == -1: 84 | tok2 = l2.find(",") 85 | source2 = l2[l2.index(" "):tok2].strip() 86 | dest2 = l2[tok2+1:].strip() 87 | 88 | # assumes compiler outputs () around all memory references 89 | 90 | if "(" in dest1 and "(" in source2: 91 | if "%" in dest1 or "%" in source2: 92 | return False 93 | if s1 != s2: 94 | return False 95 | if dest1 in source2: 96 | return False 97 | if dest1 in dest2: 98 | return False 99 | 100 | if "(" in dest2 and "(" in source1: 101 | if "%" in dest2 or "%" in source1: 102 | return False 103 | if s1 != s2: 104 | return False 105 | if dest2 in source1: 106 | return False 107 | if dest2 in dest1: 108 | return False 109 | 110 | return True 111 | 112 | with open(sys.argv[1]) as f: 113 | asm = f.readlines() 114 | 115 | with open(sys.argv[1], 'w') as f: 116 | swaps = 0 117 | 118 | for k in xrange(SWAP_PASSES): 119 | for i1, l1 in enumerate(asm): 120 | sys.stdout.write("shuffling ... %4.2f%% (%d swaps)\r" % \ 121 | ((k*len(asm)+i1) * 100.0 / (SWAP_PASSES * len(asm)), swaps)) 122 | 123 | if l1.startswith("mov"): 124 | i2, l2 = next_mov(asm, i1) 125 | 126 | if l2 != "": 127 | if can_swap(l1, l2): 128 | if random.randint(0,1) == 0: 129 | asm[i1]=l2 130 | asm[i2]=l1 131 | swaps = swaps + 1 132 | #sys.stdout.write("swap %d: %s <-> %s" % (swaps, l1.strip(), l2.strip())) 133 | 134 | f.write("# (%d swaps)\n" % swaps) 135 | 136 | for l in asm: 137 | f.write(l) 138 | -------------------------------------------------------------------------------- /post/sub.py: -------------------------------------------------------------------------------- 1 | # The SUBfuscator post-processor - translates M/o/Vfuscated C into only 2 | # sub instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'ebp') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | for l in asm: 28 | if l.startswith("mov"): 29 | f.write("#sub> " + l) 30 | 31 | tok = l.find(",", l.find(")")) 32 | if tok == -1: 33 | tok = l.find(",") 34 | source = l[l.index(" "):tok].strip() 35 | dest = l[tok+1:].strip() 36 | 37 | if l.startswith("movb"): 38 | s = "b" 39 | reg = "%bl" 40 | elif l.startswith("movw"): 41 | s = "w" 42 | reg = "%bx" 43 | elif l.startswith("movl"): 44 | s = "l" 45 | reg = "%ebx" 46 | 47 | # ridiculous register shuffling necessary b/c ebx is 48 | # our last byte addressable register 49 | f.write("subl %ebx, %ebx\n") 50 | f.write("subl %esi, %esi\n") 51 | f.write("subl %edi, %edi\n") 52 | f.write("sub%s %s, %s\n" % (s, dest, reg)) 53 | f.write("subl %ebx, %esi\n") 54 | f.write("subl %esi, %edi\n") 55 | f.write("subl %edi, %ebx\n") 56 | f.write("subl %edi, %ebx\n") 57 | f.write("sub%s %s, %s\n" % (s, source, reg)) 58 | f.write("sub%s %s, %s\n" % (s, reg, dest)) 59 | 60 | else: 61 | f.write(l) 62 | 63 | -------------------------------------------------------------------------------- /post/xadd.py: -------------------------------------------------------------------------------- 1 | # The XADDfuscator post-processor - translates M/o/Vfuscated C into only 2 | # xadd instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | import hashlib 21 | 22 | with open(sys.argv[1]) as f: 23 | asm = f.readlines() 24 | 25 | # pass 1 - xadd can't load constants 26 | # replace all constant references with memory references instead 27 | with open(sys.argv[1], 'w') as f: 28 | for l in asm: 29 | if l.startswith("mov"): 30 | tok = l.find(",", l.find(")")) 31 | if tok == -1: 32 | tok = l.find(",") 33 | source = l[l.index(" "):tok].strip() 34 | dest = l[tok+1:].strip() 35 | 36 | # NOTE: requires M/o/Vfuscator to only produce dword constants 37 | if source.startswith("$"): 38 | f.write("#constant> " + l) 39 | 40 | # have to jump through some hoops due to as and ld limitations 41 | # on absolutes 42 | c = hashlib.md5(source[1:]).hexdigest() 43 | f.write(".section .data\n") 44 | f.write(".ifndef .C%s\n" % c) 45 | f.write(".C%s: .long %s\n" % (c, source[1:])) 46 | f.write(".endif\n") 47 | f.write(".section .text\n") 48 | f.write("movl (.C%s), %%edi\n" % c) 49 | f.write("movl %%edi, %s\n" % dest) 50 | else: 51 | f.write(l) 52 | 53 | else: 54 | f.write(l) 55 | 56 | with open(sys.argv[1]) as f: 57 | asm = f.readlines() 58 | 59 | asm = [l.replace('ebx', 'ebp') for l in asm] 60 | 61 | with open(sys.argv[1], 'w') as f: 62 | for l in asm: 63 | if l.startswith("mov"): 64 | f.write("#xadd> " + l) 65 | 66 | tok = l.find(",", l.find(")")) 67 | if tok == -1: 68 | tok = l.find(",") 69 | source = l[l.index(" "):tok].strip() 70 | dest = l[tok+1:].strip() 71 | 72 | if l.startswith("movb"): 73 | b = 8 74 | s = "b" 75 | reg = "%bl" 76 | elif l.startswith("movw"): 77 | b = 16 78 | s = "w" 79 | reg = "%bx" 80 | elif l.startswith("movl"): 81 | b = 32 82 | s = "l" 83 | reg = "%ebx" 84 | 85 | # ridiculous register shuffling necessary b/c ebx is 86 | # our last byte addressable register 87 | 88 | for i in xrange(0,b): 89 | f.write("xadd%s %s, %s\n" % (s, reg, reg)) 90 | 91 | for i in xrange(0,b): 92 | f.write("xaddl %esi, %esi\n") 93 | 94 | f.write("xadd%s %s, %s\n" % (s, reg, source)) 95 | f.write("xaddl %ebx, %esi\n") 96 | 97 | f.write("xadd%s %s, %s\n" % (s, reg, dest)) 98 | 99 | for i in xrange(0,b): 100 | f.write("xadd%s %s, %s\n" % (s, reg, dest)) 101 | f.write("xadd%s %s, %s\n" % (s, reg, reg)) 102 | 103 | f.write("xaddl %ebx, %esi\n") 104 | f.write("xadd%s %s, %s\n" % (s, reg, dest)) 105 | 106 | else: 107 | f.write(l) 108 | 109 | -------------------------------------------------------------------------------- /post/xor.py: -------------------------------------------------------------------------------- 1 | # The XORfuscator post-processor - translates M/o/Vfuscated C into only 2 | # xor instructions. 3 | 4 | # This is a post-processing routine that can be run on assembly output from the 5 | # M/o/Vfuscator. It converts the M/o/Vfuscator's mov instructions into an 6 | # alternative set of minimalistic instructions. 7 | 8 | # To use: 9 | # movcc example.c -S 10 | # python this.py example.s 11 | # as --32 example.s -o example.o 12 | # movcc example.o 13 | 14 | # Note that the final linking step above will add the M/o/Vfuscator crt 15 | # libraries; you may wish to run these libraries through this same script, to 16 | # ensure the entire executable is converted. See the M/o/Vfuscator build script 17 | # for an example of building the crt libraries. 18 | 19 | import sys 20 | 21 | with open(sys.argv[1]) as f: 22 | asm = f.readlines() 23 | 24 | asm = [l.replace('ebx', 'esi') for l in asm] 25 | 26 | with open(sys.argv[1], 'w') as f: 27 | for l in asm: 28 | if l.startswith("mov"): 29 | f.write("#xor> " + l) 30 | 31 | tok = l.find(",", l.find(")")) 32 | if tok == -1: 33 | tok = l.find(",") 34 | source = l[l.index(" "):tok].strip() 35 | dest = l[tok+1:].strip() 36 | 37 | if l.startswith("movb"): 38 | s = "b" 39 | reg = "%bl" 40 | elif l.startswith("movw"): 41 | s = "w" 42 | reg = "%bx" 43 | elif l.startswith("movl"): 44 | s = "l" 45 | reg = "%ebx" 46 | 47 | f.write("xor%s %s, %s\n" % (s, reg, reg)) 48 | f.write("xor%s %s, %s\n" % (s, source, reg)) 49 | f.write("xor%s %s, %s\n" % (s, dest, reg)) 50 | f.write("xor%s %s, %s\n" % (s, reg, dest)) 51 | 52 | else: 53 | f.write(l) 54 | 55 | -------------------------------------------------------------------------------- /slides/domas_2015_the_movfuscator.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/slides/domas_2015_the_movfuscator.pdf -------------------------------------------------------------------------------- /softfloat/386-MOV.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is derived for use by the M/o/Vfuscator from the Berkeley SoftFloat 3 | IEEE Floating-Point Arithmetic Package, Release 2c, by John R. Hauser. 4 | */ 5 | 6 | /* 7 | This C source file is part of the Berkeley SoftFloat IEEE Floating-Point 8 | Arithmetic Package, Release 2c, by John R. Hauser. 9 | 10 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 11 | been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 12 | RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 13 | AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER 14 | PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR 15 | THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY 16 | INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE 17 | (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER 18 | PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR 19 | INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE 20 | SOFTWARE. 21 | 22 | Derivative works require also that (1) the source code for the derivative work 23 | includes prominent notice that the work is derivative, and (2) the source code 24 | includes prominent notice of these three paragraphs for those parts of this 25 | code that are retained. 26 | */ 27 | 28 | #ifndef _386_MOV_H 29 | #define _386_MOV_H 30 | 31 | #define LITTLEENDIAN 32 | /* #define BITS64 */ 33 | 34 | typedef int flag; 35 | typedef unsigned int uint8; 36 | typedef int int8; 37 | typedef int uint16; 38 | typedef int int16; 39 | typedef unsigned int uint32; 40 | typedef signed int int32; 41 | #ifdef BITS64 42 | typedef unsigned long long int uint64; 43 | typedef signed long long int int64; 44 | #endif 45 | 46 | typedef unsigned char bits8; 47 | typedef signed char sbits8; 48 | typedef unsigned short int bits16; 49 | typedef signed short int sbits16; 50 | typedef unsigned int bits32; 51 | typedef signed int sbits32; 52 | #ifdef BITS64 53 | typedef unsigned long long int bits64; 54 | typedef signed long long int sbits64; 55 | #endif 56 | 57 | #ifdef BITS64 58 | #define LIT64( a ) a##LL 59 | #endif 60 | 61 | /* lcc does not support the inline keyword, and manual inlining has shown 62 | * substantially worse performance anyway */ 63 | #define INLINE /* extern inline */ 64 | 65 | #endif // _386_MOV_H 66 | -------------------------------------------------------------------------------- /softfloat/Makefile: -------------------------------------------------------------------------------- 1 | CC = movcc 2 | INCLUDES = -I. -I.. 3 | COMPILE_C = $(CC) -c $(INCLUDES) -o $@ -Wf--q 4 | LINK = $(CC) -o $@ 5 | 6 | ALL: softfloat32.o softfloat64.o softfloatfull.o timesoftfloat 7 | 8 | milieu.h: 386-MOV.h 9 | touch milieu.h 10 | 11 | softfloat32.o: milieu.h softfloat.h softfloat.c softfloat_specialize.c softfloat_inline.c 12 | $(COMPILE_C) softfloat.c -DFLOAT64=0 -DTRIM=1 13 | 14 | softfloat64.o: milieu.h softfloat.h softfloat.c softfloat_specialize.c softfloat_inline.c 15 | $(COMPILE_C) softfloat.c -DFLOAT64=1 -DTRIM=1 16 | 17 | softfloatfull.o: milieu.h softfloat.h softfloat.c softfloat_specialize.c softfloat_inline.c 18 | $(COMPILE_C) softfloat.c -DFLOAT64=1 -DTRIM=0 19 | 20 | timesoftfloat.o: milieu.h softfloat.h timesoftfloat.c 21 | $(COMPILE_C) timesoftfloat.c 22 | 23 | timesoftfloat: softfloatfull.o timesoftfloat.o 24 | $(LINK) softfloatfull.o timesoftfloat.o 25 | 26 | clean: 27 | rm -f *.o *.a timesoftfloat 28 | -------------------------------------------------------------------------------- /softfloat/README.txt: -------------------------------------------------------------------------------- 1 | The M/o/Vfuscator's floating point support is derived from a subset of the 2 | Berkeley SoftFloat Release 2c written by John R. Hauser, which includes the 3 | following legal notice: 4 | 5 | Legal Notice 6 | 7 | SoftFloat was written by John R. Hauser. Release 2c of SoftFloat was made 8 | possible in part by the International Computer Science Institute, located 9 | at Suite 600, 1947 Center Street, Berkeley, California 94704. Funding 10 | was partially provided by the National Science Foundation under grant 11 | MIP-9311980. The original version of this code was written as part of a 12 | project to build a fixed-point vector processor in collaboration with the 13 | University of California at Berkeley, overseen by Profs. Nelson Morgan and 14 | John Wawrzynek. 15 | 16 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 17 | has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 18 | TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 19 | PERSONS AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR 20 | OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN 21 | HAUSER OR THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE 22 | EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE 23 | INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR 24 | OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, 25 | OR INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF 26 | THE SOFTWARE. 27 | 28 | The following are expressly permitted, even for commercial purposes: 29 | (1) distribution of SoftFloat in whole or in part, as long as this and 30 | other legal notices remain and are prominent, and provided also that, for a 31 | partial distribution, prominent notice is given that it is a subset of the 32 | original; and 33 | (2) inclusion or use of SoftFloat in whole or in part in a derivative 34 | work, provided that the use restrictions above are met and the minimal 35 | documentation requirements stated in the source code are satisfied. 36 | 37 | -------------------------------------------------------------------------------- /softfloat/milieu.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is derived for use by the M/o/Vfuscator from the Berkeley SoftFloat 3 | IEEE Floating-Point Arithmetic Package, Release 2c, by John R. Hauser. 4 | */ 5 | 6 | /* 7 | This C source file is part of the Berkeley SoftFloat IEEE Floating-Point 8 | Arithmetic Package, Release 2c, by John R. Hauser. 9 | 10 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 11 | been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 12 | RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 13 | AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER 14 | PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR 15 | THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY 16 | INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE 17 | (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER 18 | PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR 19 | INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE 20 | SOFTWARE. 21 | 22 | Derivative works require also that (1) the source code for the derivative work 23 | includes prominent notice that the work is derivative, and (2) the source code 24 | includes prominent notice of these three paragraphs for those parts of this 25 | code that are retained. 26 | */ 27 | 28 | #ifndef MILIEU_H 29 | #define MILIEU_H 30 | 31 | #include "386-MOV.h" 32 | 33 | enum { 34 | FALSE = 0, 35 | TRUE = 1 36 | }; 37 | 38 | #endif // MILIEU_H 39 | -------------------------------------------------------------------------------- /softfloat/softfloat.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is derived for use by the M/o/Vfuscator from the Berkeley SoftFloat 3 | IEEE Floating-Point Arithmetic Package, Release 2c, by John R. Hauser. 4 | */ 5 | 6 | /* 7 | This C source file is part of the Berkeley SoftFloat IEEE Floating-Point 8 | Arithmetic Package, Release 2c, by John R. Hauser. 9 | 10 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 11 | been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 12 | RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 13 | AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER 14 | PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR 15 | THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY 16 | INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE 17 | (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER 18 | PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR 19 | INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE 20 | SOFTWARE. 21 | 22 | Derivative works require also that (1) the source code for the derivative work 23 | includes prominent notice that the work is derivative, and (2) the source code 24 | includes prominent notice of these three paragraphs for those parts of this 25 | code that are retained. 26 | */ 27 | 28 | #ifndef SOFTFLOAT_H 29 | #define SOFTFLOAT_H 30 | 31 | #include "milieu.h" 32 | 33 | /*---------------------------------------------------------------------------- 34 | | Software IEEE floating-point types. 35 | *----------------------------------------------------------------------------*/ 36 | typedef bits32 float32; 37 | typedef struct { 38 | // bits32 high, low; 39 | bits32 low, high; 40 | } float64; 41 | 42 | /*---------------------------------------------------------------------------- 43 | | Software IEEE floating-point underflow tininess-detection mode. 44 | *----------------------------------------------------------------------------*/ 45 | extern int8 float_detect_tininess; 46 | enum { 47 | float_tininess_after_rounding = 0, 48 | float_tininess_before_rounding = 1 49 | }; 50 | 51 | /*---------------------------------------------------------------------------- 52 | | Software IEEE floating-point rounding mode. 53 | *----------------------------------------------------------------------------*/ 54 | extern int8 float_rounding_mode; 55 | enum { 56 | float_round_nearest_even = 0, 57 | float_round_to_zero = 1, 58 | float_round_down = 2, 59 | float_round_up = 3 60 | }; 61 | 62 | /*---------------------------------------------------------------------------- 63 | | Software IEEE floating-point exception flags. 64 | *----------------------------------------------------------------------------*/ 65 | extern int8 float_exception_flags; 66 | enum { 67 | float_flag_inexact = 1, 68 | float_flag_underflow = 2, 69 | float_flag_overflow = 4, 70 | float_flag_divbyzero = 8, 71 | float_flag_invalid = 16 72 | }; 73 | 74 | /*---------------------------------------------------------------------------- 75 | | Routine to raise any or all of the software IEEE floating-point exception 76 | | flags. 77 | *----------------------------------------------------------------------------*/ 78 | void float_raise( int8 ); 79 | 80 | /*---------------------------------------------------------------------------- 81 | | Software IEEE integer-to-floating-point conversion routines. 82 | *----------------------------------------------------------------------------*/ 83 | float32 int32_to_float32( int32 ); 84 | float64 int32_to_float64( int32 ); 85 | 86 | /*---------------------------------------------------------------------------- 87 | | Software IEEE single-precision conversion routines. 88 | *----------------------------------------------------------------------------*/ 89 | int32 float32_to_int32( float32 ); 90 | int32 float32_to_int32_round_to_zero( float32 ); 91 | float64 float32_to_float64( float32 ); 92 | 93 | /*---------------------------------------------------------------------------- 94 | | Software IEEE single-precision operations. 95 | *----------------------------------------------------------------------------*/ 96 | float32 float32_round_to_int( float32 ); 97 | float32 float32_add( float32, float32 ); 98 | float32 float32_sub( float32, float32 ); 99 | float32 float32_mul( float32, float32 ); 100 | float32 float32_div( float32, float32 ); 101 | float32 float32_rem( float32, float32 ); 102 | float32 float32_sqrt( float32 ); 103 | flag float32_eq( float32, float32 ); 104 | flag float32_le( float32, float32 ); 105 | flag float32_lt( float32, float32 ); 106 | flag float32_eq_signaling( float32, float32 ); 107 | flag float32_le_quiet( float32, float32 ); 108 | flag float32_lt_quiet( float32, float32 ); 109 | flag float32_is_signaling_nan( float32 ); 110 | 111 | /*---------------------------------------------------------------------------- 112 | | Software IEEE double-precision conversion routines. 113 | *----------------------------------------------------------------------------*/ 114 | int32 float64_to_int32( float64 ); 115 | int32 float64_to_int32_round_to_zero( float64 ); 116 | float32 float64_to_float32( float64 ); 117 | 118 | /*---------------------------------------------------------------------------- 119 | | Software IEEE double-precision operations. 120 | *----------------------------------------------------------------------------*/ 121 | float64 float64_round_to_int( float64 ); 122 | float64 float64_add( float64, float64 ); 123 | float64 float64_sub( float64, float64 ); 124 | float64 float64_mul( float64, float64 ); 125 | float64 float64_div( float64, float64 ); 126 | float64 float64_rem( float64, float64 ); 127 | float64 float64_sqrt( float64 ); 128 | flag float64_eq( float64, float64 ); 129 | flag float64_le( float64, float64 ); 130 | flag float64_lt( float64, float64 ); 131 | flag float64_eq_signaling( float64, float64 ); 132 | flag float64_le_quiet( float64, float64 ); 133 | flag float64_lt_quiet( float64, float64 ); 134 | flag float64_is_signaling_nan( float64 ); 135 | 136 | #endif // SOFTFLOAT_H 137 | -------------------------------------------------------------------------------- /validation/3d.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A 3D spinning cube 3 | * Illustrating trigonometric functions, transformation matrices, vector 4 | * rotations, and floating point arithmetic, 5 | * via an infite stream of unconditional data transfers. 6 | */ 7 | 8 | #include 9 | #define _Bool char 10 | #include 11 | 12 | #define PI 3.14159265359f 13 | #define LINE 1 14 | #define CHARACTER_ASPECT_RATIO .7f 15 | 16 | typedef struct { 17 | float x, y, z; 18 | } vector_t; 19 | 20 | typedef struct { 21 | vector_t p1, p2, p3, p4, p5, p6, p7, p8; 22 | } cube_t; 23 | 24 | float msin(float); 25 | float mcos(float); 26 | 27 | vector_t transform(vector_t v, float m[3][3]); 28 | cube_t transform_cube(cube_t c, float m[3][3]); 29 | 30 | void rotate_x(float m[3][3], float r); 31 | void rotate_y(float m[3][3], float r); 32 | void rotate_z(float m[3][3], float r); 33 | void line(int x1, int y1, int x2, int y2); 34 | 35 | int main(void) 36 | { 37 | int ch; 38 | int i=0; 39 | int x, y; 40 | cube_t c={ 41 | {-1, -1, -1}, 42 | {-1, -1, 1}, 43 | {-1, 1, -1}, 44 | {-1, 1, 1}, 45 | { 1, -1, -1}, 46 | { 1, -1, 1}, 47 | { 1, 1, -1}, 48 | { 1, 1, 1} 49 | }; 50 | 51 | float mxp[3][3]; 52 | float myp[3][3]; 53 | float mzp[3][3]; 54 | float mxn[3][3]; 55 | float myn[3][3]; 56 | float mzn[3][3]; 57 | float (*m)[3]; 58 | int height, width; 59 | float size_w, size_h; 60 | int off_x, off_y; 61 | 62 | initscr(); 63 | noecho(); 64 | cbreak(); 65 | timeout(0); 66 | curs_set(0); 67 | 68 | getmaxyx(stdscr, height, width); 69 | if (width>height) { 70 | size_w=height/3; 71 | size_h=size_w*CHARACTER_ASPECT_RATIO; 72 | } 73 | else { 74 | size_w=width/3; 75 | size_h=size_w*CHARACTER_ASPECT_RATIO; 76 | } 77 | off_x=width/2; 78 | off_y=height/2; 79 | 80 | clear(); 81 | 82 | rotate_x(mxp, .1f); 83 | rotate_y(myp, .1f); 84 | rotate_z(mzp, .1f); 85 | rotate_x(mxn, -.1f); 86 | rotate_y(myn, -.1f); 87 | rotate_z(mzn, -.1f); 88 | c=transform_cube(c, mxp); 89 | c=transform_cube(c, mxp); 90 | c=transform_cube(c, mzp); 91 | c=transform_cube(c, mzp); 92 | 93 | m=myp; 94 | 95 | while (1) { 96 | int p1xc, p1yc; 97 | int p2xc, p2yc; 98 | int p3xc, p3yc; 99 | int p4xc, p4yc; 100 | int p5xc, p5yc; 101 | int p6xc, p6yc; 102 | int p7xc, p7yc; 103 | int p8xc, p8yc; 104 | 105 | i++; 106 | c=transform_cube(c, m); 107 | clear(); 108 | move(0,0); 109 | printw( 110 | " \n" 111 | " M/o/Vfuscator Spinning Cube Demo\n" 112 | " \n" 113 | " Trigonometric functions, transformation matrices,\n" 114 | " vector rotations, and floating point arithmetic,\n" 115 | " via an infinite stream of unconditional data transfers.\n" 116 | " \n" 117 | " Use w, a, s, d, q, e to move.\n" 118 | " Frame: %d \n" 119 | , i 120 | ); 121 | 122 | p1xc=(int)(c.p1.x*size_w)+off_x; 123 | p1yc=(int)(c.p1.y*size_h)+off_y; 124 | p2xc=(int)(c.p2.x*size_w)+off_x; 125 | p2yc=(int)(c.p2.y*size_h)+off_y; 126 | p3xc=(int)(c.p3.x*size_w)+off_x; 127 | p3yc=(int)(c.p3.y*size_h)+off_y; 128 | p4xc=(int)(c.p4.x*size_w)+off_x; 129 | p4yc=(int)(c.p4.y*size_h)+off_y; 130 | p5xc=(int)(c.p5.x*size_w)+off_x; 131 | p5yc=(int)(c.p5.y*size_h)+off_y; 132 | p6xc=(int)(c.p6.x*size_w)+off_x; 133 | p6yc=(int)(c.p6.y*size_h)+off_y; 134 | p7xc=(int)(c.p7.x*size_w)+off_x; 135 | p7yc=(int)(c.p7.y*size_h)+off_y; 136 | p8xc=(int)(c.p8.x*size_w)+off_x; 137 | p8yc=(int)(c.p8.y*size_h)+off_y; 138 | 139 | #if LINE 140 | line(p1xc, p1yc, p2xc, p2yc); 141 | line(p2xc, p2yc, p4xc, p4yc); 142 | line(p4xc, p4yc, p3xc, p3yc); 143 | line(p3xc, p3yc, p1xc, p1yc); 144 | 145 | line(p5xc, p5yc, p6xc, p6yc); 146 | line(p6xc, p6yc, p8xc, p8yc); 147 | line(p8xc, p8yc, p7xc, p7yc); 148 | line(p7xc, p7yc, p5xc, p5yc); 149 | 150 | line(p1xc, p1yc, p5xc, p5yc); 151 | line(p2xc, p2yc, p6xc, p6yc); 152 | line(p3xc, p3yc, p7xc, p7yc); 153 | line(p4xc, p4yc, p8xc, p8yc); 154 | #else 155 | move(p1yc,p1xc); addch('o'); 156 | move(p2yc,p2xc); addch('o'); 157 | move(p3yc,p3xc); addch('o'); 158 | move(p4yc,p4xc); addch('o'); 159 | move(p5yc,p5xc); addch('o'); 160 | move(p6yc,p6xc); addch('o'); 161 | move(p7yc,p7xc); addch('o'); 162 | move(p8yc,p8xc); addch('o'); 163 | #endif 164 | 165 | refresh(); 166 | ch=getch(); 167 | if (ch=='w') { 168 | m=mxn; 169 | } 170 | else if (ch=='s') { 171 | m=mxp; 172 | } 173 | else if (ch=='a') { 174 | m=myp; 175 | } 176 | else if (ch=='d') { 177 | m=myn; 178 | } 179 | else if (ch=='e') { 180 | m=mzp; 181 | } 182 | else if (ch=='q') { 183 | m=mzn; 184 | } 185 | } 186 | endwin(); 187 | 188 | return 0; 189 | } 190 | 191 | cube_t transform_cube(cube_t c, float m[3][3]) 192 | { 193 | c.p1=transform(c.p1, m); 194 | c.p2=transform(c.p2, m); 195 | c.p3=transform(c.p3, m); 196 | c.p4=transform(c.p4, m); 197 | c.p5=transform(c.p5, m); 198 | c.p6=transform(c.p6, m); 199 | c.p7=transform(c.p7, m); 200 | c.p8=transform(c.p8, m); 201 | return c; 202 | } 203 | 204 | vector_t transform(vector_t v, float m[3][3]) 205 | { 206 | vector_t r; 207 | r.x=v.x*m[0][0]+v.y*m[0][1]+v.z*m[0][2]; 208 | r.y=v.x*m[1][0]+v.y*m[1][1]+v.z*m[1][2]; 209 | r.z=v.x*m[2][0]+v.y*m[2][1]+v.z*m[2][2]; 210 | return r; 211 | } 212 | 213 | void rotate_x(float m[3][3], float r) 214 | { 215 | m[0][0]=1; 216 | m[0][1]=0; 217 | m[0][2]=0; 218 | 219 | m[1][0]=0; 220 | m[1][1]=mcos(r); 221 | m[1][2]=-msin(r); 222 | 223 | m[2][0]=0; 224 | m[2][1]=msin(r); 225 | m[2][2]=mcos(r); 226 | } 227 | 228 | void rotate_y(float m[3][3], float r) 229 | { 230 | m[0][0]=mcos(r); 231 | m[0][1]=0; 232 | m[0][2]=msin(r); 233 | 234 | m[1][0]=0; 235 | m[1][1]=1; 236 | m[1][2]=0; 237 | 238 | m[2][0]=-msin(r); 239 | m[2][1]=0; 240 | m[2][2]=mcos(r); 241 | } 242 | 243 | void rotate_z(float m[3][3], float r) 244 | { 245 | m[0][0]=mcos(r); 246 | m[0][1]=-msin(r); 247 | m[0][2]=0; 248 | 249 | m[1][0]=msin(r); 250 | m[1][1]=mcos(r); 251 | m[1][2]=0; 252 | 253 | m[2][0]=0; 254 | m[2][1]=0; 255 | m[2][2]=1; 256 | } 257 | 258 | float mcos(float x) 259 | { 260 | x+=PI/2; 261 | if (x>PI/2) { 262 | x=PI-x; 263 | } 264 | return msin(x); 265 | } 266 | 267 | /* from http://codereview.stackexchange.com/questions/5211/sine-function-in-c-c */ 268 | float msin(float x) 269 | { 270 | float x2 = x*x; 271 | float x4 = x2*x2; 272 | 273 | float t1 = x * (1.0f - x2 / (2*3)); 274 | float x5 = x * x4; 275 | float t2 = x5 * (1.0f - x2 / (6*7)) / (1.0f* 2*3*4*5); 276 | float x9 = x5 * x4; 277 | float t3 = x9 * (1.0f - x2 / (10*11)) / (1.0f* 2*3*4*5*6*7*8*9); 278 | float x13 = x9 * x4; 279 | float t4 = x13 * (1.0f - x2 / (14*15)) / (1.0f* 2*3*4*5*6*7*8*9*10*11*12*13); 280 | 281 | float result = t4; 282 | result += t3; 283 | result += t2; 284 | result += t1; 285 | 286 | return result; 287 | } 288 | 289 | #if LINE 290 | void line(int x1, int y1, int x2, int y2) 291 | { 292 | int x,y,i; 293 | int xd, xda, xi, xda2; 294 | int yd, yda, yi, yda2; 295 | xd=x1-x2; 296 | yd=y1-y2; 297 | 298 | if (xd<0) { xda=-xd; xi=1; } else { xda=xd; xi=-1; } 299 | if (yd<0) { yda=-yd; yi=1; } else { yda=yd; yi=-1; } 300 | 301 | /* avoid float math, int division rounding */ 302 | if (xda!=0) { xda2=(xda-1)/2; } else { xda2=0; } 303 | if (yda!=0) { yda2=(yda-1)/2; } else { yda2=0; } 304 | if (xd>0) { yda2=-yda2; } 305 | if (yd>0) { xda2=-xda2; } 306 | 307 | if (xda>yda) { 308 | i=0; 309 | while (x1!=x2) { 310 | move(y1+(i*yd+xda2)/xda, x1); addch('.'); 311 | x1+=xi; 312 | i--; 313 | } 314 | } 315 | else { 316 | i=0; 317 | while (y1!=y2) { 318 | move(y1, x1+(i*xd+yda2)/yda); addch('.'); 319 | y1+=yi; 320 | i--; 321 | } 322 | } 323 | } 324 | #endif 325 | -------------------------------------------------------------------------------- /validation/Makefile: -------------------------------------------------------------------------------- 1 | CC=movcc 2 | CFLAGS=-s -lncurses 3 | 4 | EXAMPLES=\ 5 | ant\ 6 | arithmetic \ 7 | bf \ 8 | crc32 \ 9 | e \ 10 | galton \ 11 | hanoi \ 12 | hello \ 13 | knight \ 14 | life \ 15 | maze \ 16 | md5 \ 17 | mersenne \ 18 | minesweeper \ 19 | nibbles \ 20 | nqueens \ 21 | pi \ 22 | prime \ 23 | s2 \ 24 | sudoku \ 25 | tictactoe 26 | 27 | all: $(EXAMPLES) 28 | 29 | clean: 30 | rm $(EXAMPLES) 31 | -------------------------------------------------------------------------------- /validation/ant.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Langton%27s_ant#C */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int w = 0, h = 0; 9 | unsigned char *pix; 10 | 11 | void refresh(int x, int y) 12 | { 13 | int i, j, k; 14 | printf("\033[H"); 15 | for (i = k = 0; i < h; putchar('\n'), i++) 16 | for (j = 0; j < w; j++, k++) 17 | putchar(pix[k] ? '#' : ' '); 18 | } 19 | 20 | void walk() 21 | { 22 | int dx = 0, dy = 1, i, k; 23 | int x = w / 2, y = h / 2; 24 | 25 | pix = calloc(1, w * h); 26 | printf("\033[H\033[J"); 27 | 28 | while (1) { 29 | i = (y * w + x); 30 | if (pix[i]) k = dx, dx = -dy, dy = k; 31 | else k = dy, dy = -dx, dx = k; 32 | 33 | pix[i] = !pix[i]; 34 | printf("\033[%d;%dH%c", y + 1, x + 1, pix[i] ? '#' : ' '); 35 | 36 | x += dx, y += dy; 37 | 38 | k = 0; 39 | if (x < 0) { 40 | memmove(pix + 1, pix, w * h - 1); 41 | for (i = 0; i < w * h; i += w) pix[i] = 0; 42 | x++, k = 1; 43 | } 44 | else if (x >= w) { 45 | memmove(pix, pix + 1, w * h - 1); 46 | for (i = w-1; i < w * h; i += w) pix[i] = 0; 47 | x--, k = 1; 48 | } 49 | 50 | if (y >= h) { 51 | memmove(pix, pix + w, w * (h - 1)); 52 | memset(pix + w * (h - 1), 0, w); 53 | y--, k = 1; 54 | } 55 | else if (y < 0) { 56 | memmove(pix + w, pix, w * (h - 1)); 57 | memset(pix, 0, w); 58 | y++, k = 1; 59 | } 60 | if (k) refresh(x, y); 61 | printf("\033[%d;%dH\033[31m@\033[m", y + 1, x + 1); 62 | 63 | fflush(stdout); 64 | usleep(10000); 65 | } 66 | } 67 | 68 | int main(int c, char **v) 69 | { 70 | if (c > 1) w = atoi(v[1]); 71 | if (c > 2) h = atoi(v[2]); 72 | if (w < 40) w = 40; 73 | if (h < 25) h = 25; 74 | 75 | walk(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /validation/arithmetic.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | signed int i, j, k; 4 | unsigned int u, v, w; 5 | 6 | /* signed */ 7 | 8 | printf("\naddition\n"); 9 | 10 | i=0; j=0; k=i+j; 11 | printf("%d + %d = %d\n", i, j, k); 12 | 13 | i=1; j=1; k=i+j; 14 | printf("%d + %d = %d\n", i, j, k); 15 | 16 | i=1; j=0; k=i+j; 17 | printf("%d + %d = %d\n", i, j, k); 18 | 19 | i=0; j=1; k=i+j; 20 | printf("%d + %d = %d\n", i, j, k); 21 | 22 | i=0x80000000; j=0x80000000; k=i+j; 23 | printf("%d + %d = %d\n", i, j, k); 24 | 25 | i=0x7fffffff; j=1; k=i+j; 26 | printf("%d + %d = %d\n", i, j, k); 27 | 28 | i=1; j=0x7fffffff; k=i+j; 29 | printf("%d + %d = %d\n", i, j, k); 30 | 31 | printf("\nsubtraction\n"); 32 | 33 | i=0; j=0; k=i-j; 34 | printf("%d - %d = %d\n", i, j, k); 35 | 36 | i=1; j=1; k=i-j; 37 | printf("%d - %d = %d\n", i, j, k); 38 | 39 | i=1; j=0; k=i-j; 40 | printf("%d - %d = %d\n", i, j, k); 41 | 42 | i=0; j=1; k=i-j; 43 | printf("%d - %d = %d\n", i, j, k); 44 | 45 | printf("\nmultiplication\n"); 46 | 47 | i=0; j=0; k=i*j; 48 | printf("%d * %d = %d\n", i, j, k); 49 | 50 | i=1; j=0; k=i*j; 51 | printf("%d * %d = %d\n", i, j, k); 52 | 53 | i=0; j=1; k=i*j; 54 | printf("%d * %d = %d\n", i, j, k); 55 | 56 | i=1; j=1; k=i*j; 57 | printf("%d * %d = %d\n", i, j, k); 58 | 59 | i=1; j=-1; k=i*j; 60 | printf("%d * %d = %d\n", i, j, k); 61 | 62 | i=-1; j=1; k=i*j; 63 | printf("%d * %d = %d\n", i, j, k); 64 | 65 | i=-1; j=-1; k=i*j; 66 | printf("%d * %d = %d\n", i, j, k); 67 | 68 | i=2; j=3; k=i*j; 69 | printf("%d * %d = %d\n", i, j, k); 70 | 71 | i=-2; j=3; k=i*j; 72 | printf("%d * %d = %d\n", i, j, k); 73 | 74 | i=2; j=-3; k=i*j; 75 | printf("%d * %d = %d\n", i, j, k); 76 | 77 | i=-2; j=-3; k=i*j; 78 | printf("%d * %d = %d\n", i, j, k); 79 | 80 | printf("\ndivision\n"); 81 | 82 | i=0; j=1; k=i/j; 83 | printf("%d / %d = %d\n", i, j, k); 84 | 85 | i=1; j=1; k=i/j; 86 | printf("%d / %d = %d\n", i, j, k); 87 | 88 | i=1; j=-1; k=i/j; 89 | printf("%d / %d = %d\n", i, j, k); 90 | 91 | i=-1; j=1; k=i/j; 92 | printf("%d / %d = %d\n", i, j, k); 93 | 94 | i=-1; j=-1; k=i/j; 95 | printf("%d / %d = %d\n", i, j, k); 96 | 97 | i=100; j=10; k=i/j; 98 | printf("%d / %d = %d\n", i, j, k); 99 | 100 | i=-100; j=10; k=i/j; 101 | printf("%d / %d = %d\n", i, j, k); 102 | 103 | i=-100; j=-10; k=i/j; 104 | printf("%d / %d = %d\n", i, j, k); 105 | 106 | i=99; j=10; k=i/j; 107 | printf("%d / %d = %d\n", i, j, k); 108 | 109 | i=-99; j=10; k=i/j; 110 | printf("%d / %d = %d\n", i, j, k); 111 | 112 | i=99; j=-10; k=i/j; 113 | printf("%d / %d = %d\n", i, j, k); 114 | 115 | i=-99; j=-10; k=i/j; 116 | printf("%d / %d = %d\n", i, j, k); 117 | 118 | printf("\nmodulo\n"); 119 | 120 | i=0; j=1; k=i%j; 121 | printf("%d %% %d = %d\n", i, j, k); 122 | 123 | i=1; j=1; k=i%j; 124 | printf("%d %% %d = %d\n", i, j, k); 125 | 126 | i=1; j=-1; k=i%j; 127 | printf("%d %% %d = %d\n", i, j, k); 128 | 129 | i=-1; j=1; k=i%j; 130 | printf("%d %% %d = %d\n", i, j, k); 131 | 132 | i=-1; j=-1; k=i%j; 133 | printf("%d %% %d = %d\n", i, j, k); 134 | 135 | i=100; j=10; k=i%j; 136 | printf("%d %% %d = %d\n", i, j, k); 137 | 138 | i=-100; j=10; k=i%j; 139 | printf("%d %% %d = %d\n", i, j, k); 140 | 141 | i=-100; j=-10; k=i%j; 142 | printf("%d %% %d = %d\n", i, j, k); 143 | 144 | i=99; j=10; k=i%j; 145 | printf("%d %% %d = %d\n", i, j, k); 146 | 147 | i=-99; j=10; k=i%j; 148 | printf("%d %% %d = %d\n", i, j, k); 149 | 150 | i=99; j=-10; k=i%j; 151 | printf("%d %% %d = %d\n", i, j, k); 152 | 153 | i=-99; j=-10; k=i%j; 154 | printf("%d %% %d = %d\n", i, j, k); 155 | 156 | i=0x80000000; j=2; k=i%j; 157 | printf("%08x %% %08x = %08x\n", i, j, k); 158 | 159 | i=0x80000000; j=0x80000000; k=i%j; 160 | printf("%08x %% %08x = %08x\n", i, j, k); 161 | 162 | printf("\ndivision (unsigned)\n"); 163 | 164 | u=0; v=1; w=u/v; 165 | printf("%d / %d = %d\n", u, v, w); 166 | 167 | u=1; v=1; w=u/v; 168 | printf("%d / %d = %d\n", u, v, w); 169 | 170 | u=100; v=10; w=u/v; 171 | printf("%d / %d = %d\n", u, v, w); 172 | 173 | u=99; v=10; w=u/v; 174 | printf("%d / %d = %d\n", u, v, w); 175 | 176 | u=0x80000000; v=2; w=u/v; 177 | printf("%08x / %08x = %08x\n", u, v, w); 178 | 179 | u=0x80000000; v=0x80000000; w=u/v; 180 | printf("%08x / %08x = %08x\n", u, v, w); 181 | 182 | printf("\nmodulo (unsigned)\n"); 183 | 184 | u=0; v=1; w=u%v; 185 | printf("%d %% %d = %d\n", u, v, w); 186 | 187 | u=1; v=1; w=u%v; 188 | printf("%d %% %d = %d\n", u, v, w); 189 | 190 | u=100; v=10; w=u%v; 191 | printf("%d %% %d = %d\n", u, v, w); 192 | 193 | u=99; v=10; w=u%v; 194 | printf("%d %% %d = %d\n", u, v, w); 195 | 196 | u=0x80000000; v=2; w=u%v; 197 | printf("%08x %% %08x = %08x\n", u, v, w); 198 | 199 | u=0x80000000; v=0x80000000; w=u%v; 200 | printf("%08x %% %08x = %08x\n", u, v, w); 201 | 202 | return 0; 203 | } 204 | -------------------------------------------------------------------------------- /validation/arithmetic_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -v 3 | gcc validation/gen_alu_test.c -o gen_alu_test 4 | ./gen_alu_test > alu_test.c 5 | movcc alu_test.c movfuscator/lib/softfloat64.o -Wf--q -o alu_test 6 | ./alu_test | grep FAIL 7 | #rm gen_alu_test 8 | -------------------------------------------------------------------------------- /validation/bf.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Execute_Brain****#C */ 2 | /* This is the Neutron brainfuck interpreter. 3 | * It's rather small and dense, but still readable, more or less. 4 | * 5 | * Robert de Bath -- 2013. 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | struct bfi { char cmd; struct bfi *next, *jmp; }; 12 | struct mem { char val; struct mem *next, *prev; }; 13 | 14 | int main(int argc, char **argv) 15 | { 16 | FILE * ifd; 17 | int ch; 18 | struct bfi *p=0, *n=0, *j=0, *pgm = 0; 19 | struct mem *m = calloc(1,sizeof*m); 20 | setbuf(stdout, NULL); 21 | 22 | /* Open the file from the command line or stdin */ 23 | if (argc < 2 || strcmp(argv[1], "-") == 0) ifd = stdin; 24 | else if ((ifd = fopen(argv[1], "r")) == 0) { perror(argv[1]); exit(1); } 25 | 26 | /* 27 | * For each character, if it's a valid BF command add it onto the 28 | * end of the program. If the input is stdin use the '!' character 29 | * to mark the end of the program and the start of the data, but 30 | * only if we have a complete program. The 'j' variable points 31 | * at the list of currently open '[' commands, one is matched off 32 | * by each ']'. A ']' without a matching '[' is not a legal BF 33 | * command and so is ignored. If there are any '[' commands left 34 | * over at the end they are not valid BF commands and so are ignored. 35 | */ 36 | while((ch = getc(ifd)) != EOF && (ifd!=stdin || ch != '!' || j || !pgm)) { 37 | if (ch == '<' || ch == '>' || ch == '+' || ch == '-' || 38 | ch == ',' || ch == '.' || ch == '[' || (ch == ']' && j)) { 39 | if ((n = calloc(1, sizeof*n)) == 0) { 40 | perror(argv[0]); exit(1); 41 | } 42 | if (p) p->next = n; else pgm = n; 43 | n->cmd = ch; p = n; 44 | if (n->cmd == '[') { n->jmp=j; j = n; } 45 | else if (n->cmd == ']') { 46 | n->jmp = j; j = j->jmp; n->jmp->jmp = n; 47 | } 48 | } 49 | } 50 | 51 | /* Ignore any left over '[' commands */ 52 | while(j) { p = j; j = j->jmp; p->jmp = 0; p->cmd = ' '; } 53 | 54 | if (ifd!=stdin) fclose(ifd); 55 | 56 | /* Execute the loaded BF program */ 57 | for(n=pgm; n; n=n->next) 58 | switch(n->cmd) 59 | { 60 | case '+': m->val++; break; 61 | case '-': m->val--; break; 62 | case '.': putchar(m->val); break; 63 | case ',': if((ch=getchar())!=EOF) m->val=ch; break; 64 | case '[': if (m->val == 0) n=n->jmp; break; 65 | case ']': if (m->val != 0) n=n->jmp; break; 66 | case '<': 67 | if (!(m=m->prev)) { 68 | fprintf(stderr, "%s: Hit start of tape\n", argv[0]); 69 | exit(1); 70 | } 71 | break; 72 | case '>': 73 | if (m->next == 0) { 74 | if ((m->next = calloc(1,sizeof*m)) == 0) { 75 | perror(argv[0]); exit(1); 76 | } 77 | m->next->prev = m; 78 | } 79 | m=m->next; 80 | break; 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /validation/bitcoin_address.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const char *coin_err; 6 | #define bail(s) { coin_err = s; return 0; } 7 | 8 | int unbase58(const char *s, unsigned char *out) { 9 | static const char *tmpl = "123456789" 10 | "ABCDEFGHJKLMNPQRSTUVWXYZ" 11 | "abcdefghijkmnopqrstuvwxyz"; 12 | int i, j, c; 13 | const char *p; 14 | 15 | memset(out, 0, 25); 16 | for (i = 0; s[i]; i++) { 17 | if (!(p = strchr(tmpl, s[i]))) 18 | bail("bad char"); 19 | 20 | c = p - tmpl; 21 | for (j = 25; j--; ) { 22 | c += 58 * out[j]; 23 | out[j] = c % 256; 24 | c /= 256; 25 | } 26 | 27 | if (c) bail("address too long"); 28 | } 29 | 30 | return 1; 31 | } 32 | 33 | int valid(const char *s) { 34 | unsigned char dec[32], d1[SHA256_DIGEST_LENGTH], d2[SHA256_DIGEST_LENGTH]; 35 | 36 | coin_err = ""; 37 | if (!unbase58(s, dec)) return 0; 38 | 39 | SHA256(SHA256(dec, 21, d1), SHA256_DIGEST_LENGTH, d2); 40 | 41 | if (memcmp(dec + 21, d2, 4)) 42 | bail("bad digest"); 43 | 44 | return 1; 45 | } 46 | 47 | int main (void) { 48 | const char *s[] = { 49 | "1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9", 50 | "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", 51 | "1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9", 52 | "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I", 53 | 0 }; 54 | int i; 55 | for (i = 0; s[i]; i++) { 56 | int status = valid(s[i]); 57 | printf("%s: %s\n", s[i], status ? "Ok" : coin_err); 58 | } 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /validation/crc32.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/CRC-32#C */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | uint32_t 8 | rc_crc32(uint32_t crc, const char *buf, size_t len) 9 | { 10 | static uint32_t table[256]; 11 | static int have_table = 0; 12 | uint32_t rem; 13 | uint8_t octet; 14 | int i, j; 15 | const char *p, *q; 16 | 17 | /* This check is not thread safe; there is no mutex. */ 18 | if (have_table == 0) { 19 | /* Calculate CRC table. */ 20 | for (i = 0; i < 256; i++) { 21 | rem = i; /* remainder from polynomial division */ 22 | for (j = 0; j < 8; j++) { 23 | if (rem & 1) { 24 | rem >>= 1; 25 | rem ^= 0xedb88320; 26 | } else 27 | rem >>= 1; 28 | } 29 | table[i] = rem; 30 | } 31 | have_table = 1; 32 | } 33 | 34 | crc = ~crc; 35 | q = buf + len; 36 | for (p = buf; p < q; p++) { 37 | octet = *p; /* Cast to unsigned octet. */ 38 | crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet]; 39 | } 40 | return ~crc; 41 | } 42 | 43 | int 44 | main() 45 | { 46 | const char *s = "The quick brown fox jumps over the lazy dog"; 47 | printf("%" PRIX32 "\n", rc_crc32(0, s, strlen(s))); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/README.md: -------------------------------------------------------------------------------- 1 | crypto-algorithms 2 | ================= 3 | 4 | 5 | About 6 | --- 7 | These are basic implementations of standard cryptography algorithms, written by Brad Conte (brad@bradconte.com) from scratch and without any cross-licensing. They exist to provide publically accessible, restriction-free implementations of popular cryptographic algorithms, like AES and SHA-1. These are primarily intended for educational and pragmatic purposes (such as comparing a specification to actual implementation code, or for building an internal application that computes test vectors for a product). The algorithms have been tested against standard test vectors. 8 | 9 | This code is released into the public domain free of any restrictions. The author requests acknowledgement if the code is used, but does not require it. This code is provided free of any liability and without any quality claims by the author. 10 | 11 | Note that these are *not* cryptographically secure implementations. They have no resistence to side-channel attacks and should not be used in contexts that need cryptographically secure implementations. 12 | 13 | These algorithms are not optimized for speed or space. They are primarily designed to be easy to read, although some basic optimization techniques have been employed. 14 | 15 | Building 16 | --- 17 | The source code for each algorithm will come in a pair of a source code file and a header file. There should be no inter-header file dependencies, no additional libraries, no platform-specific header files, or any other complicating matters. Compiling them should be as easy as adding the relevent source code to the project. -------------------------------------------------------------------------------- /validation/crypto-algorithms/aes.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: aes.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding AES implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef AES_H 10 | #define AES_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | /*********************** FUNCTION DECLARATIONS **********************/ 23 | /////////////////// 24 | // AES 25 | /////////////////// 26 | // Key setup must be done before any AES en/de-cryption functions can be used. 27 | void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits 28 | WORD w[], // Output key schedule to be used later 29 | int keysize); // Bit length of the key, 128, 192, or 256 30 | 31 | void aes_encrypt(const BYTE in[], // 16 bytes of plaintext 32 | BYTE out[], // 16 bytes of ciphertext 33 | const WORD key[], // From the key setup 34 | int keysize); // Bit length of the key, 128, 192, or 256 35 | 36 | void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext 37 | BYTE out[], // 16 bytes of plaintext 38 | const WORD key[], // From the key setup 39 | int keysize); // Bit length of the key, 128, 192, or 256 40 | 41 | /////////////////// 42 | // AES - CBC 43 | /////////////////// 44 | int aes_encrypt_cbc(const BYTE in[], // Plaintext 45 | size_t in_len, // Must be a multiple of AES_BLOCK_SIZE 46 | BYTE out[], // Ciphertext, same length as plaintext 47 | const WORD key[], // From the key setup 48 | int keysize, // Bit length of the key, 128, 192, or 256 49 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 50 | 51 | int aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]); 52 | 53 | // Only output the CBC-MAC of the input. 54 | int aes_encrypt_cbc_mac(const BYTE in[], // plaintext 55 | size_t in_len, // Must be a multiple of AES_BLOCK_SIZE 56 | BYTE out[], // Output MAC 57 | const WORD key[], // From the key setup 58 | int keysize, // Bit length of the key, 128, 192, or 256 59 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 60 | 61 | /////////////////// 62 | // AES - CTR 63 | /////////////////// 64 | void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE 65 | int counter_size); // Bytes of the IV used for counting (low end) 66 | 67 | void aes_encrypt_ctr(const BYTE in[], // Plaintext 68 | size_t in_len, // Any byte length 69 | BYTE out[], // Ciphertext, same length as plaintext 70 | const WORD key[], // From the key setup 71 | int keysize, // Bit length of the key, 128, 192, or 256 72 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 73 | 74 | void aes_decrypt_ctr(const BYTE in[], // Ciphertext 75 | size_t in_len, // Any byte length 76 | BYTE out[], // Plaintext, same length as ciphertext 77 | const WORD key[], // From the key setup 78 | int keysize, // Bit length of the key, 128, 192, or 256 79 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 80 | 81 | /////////////////// 82 | // AES - CCM 83 | /////////////////// 84 | // Returns True if the input parameters do not violate any constraint. 85 | int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. 86 | WORD plaintext_len, // IN - Plaintext length. 87 | const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. 88 | unsigned short associated_data_len, // IN - Associated Data length in bytes. 89 | const BYTE nonce[], // IN - The Nonce to be used for encryption. 90 | unsigned short nonce_len, // IN - Nonce length in bytes. 91 | BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. 92 | WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. 93 | WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. 94 | const BYTE key[], // IN - The AES key for encryption. 95 | int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. 96 | 97 | // Returns True if the input parameters do not violate any constraint. 98 | // Use mac_auth to ensure decryption/validation was preformed correctly. 99 | // If authentication does not succeed, the plaintext is zeroed out. To overwride 100 | // this, call with mac_auth = NULL. The proper proceedure is to decrypt with 101 | // authentication enabled (mac_auth != NULL) and make a second call to that 102 | // ignores authentication explicitly if the first call failes. 103 | int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. 104 | WORD ciphertext_len, // IN - Ciphertext length in bytes. 105 | const BYTE assoc[], // IN - The Associated Data, required for authentication. 106 | unsigned short assoc_len, // IN - Associated Data length in bytes. 107 | const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. 108 | unsigned short nonce_len, // IN - Nonce length in bytes. 109 | BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len. 110 | WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . 111 | WORD mac_len, // IN - The length of the MAC that was calculated. 112 | int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication. 113 | const BYTE key[], // IN - The AES key for decryption. 114 | int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. 115 | 116 | /////////////////// 117 | // Test functions 118 | /////////////////// 119 | int aes_test(); 120 | int aes_ecb_test(); 121 | int aes_cbc_test(); 122 | int aes_ctr_test(); 123 | int aes_ccm_test(); 124 | 125 | #endif // AES_H 126 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/arcfour.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: arcfour.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the ARCFOUR encryption algorithm. 7 | Algorithm specification can be found here: 8 | * http://en.wikipedia.org/wiki/RC4 9 | *********************************************************************/ 10 | 11 | /*************************** HEADER FILES ***************************/ 12 | #include 13 | #include "arcfour.h" 14 | 15 | /*********************** FUNCTION DEFINITIONS ***********************/ 16 | void arcfour_key_setup(BYTE state[], const BYTE key[], int len) 17 | { 18 | int i, j; 19 | BYTE t; 20 | 21 | for (i = 0; i < 256; ++i) 22 | state[i] = i; 23 | for (i = 0, j = 0; i < 256; ++i) { 24 | j = (j + state[i] + key[i % len]) % 256; 25 | t = state[i]; 26 | state[i] = state[j]; 27 | state[j] = t; 28 | } 29 | } 30 | 31 | // This does not hold state between calls. It always generates the 32 | // stream starting from the first output byte. 33 | void arcfour_generate_stream(BYTE state[], BYTE out[], size_t len) 34 | { 35 | int i, j; 36 | size_t idx; 37 | BYTE t; 38 | 39 | for (idx = 0, i = 0, j = 0; idx < len; ++idx) { 40 | i = (i + 1) % 256; 41 | j = (j + state[i]) % 256; 42 | t = state[i]; 43 | state[i] = state[j]; 44 | state[j] = t; 45 | out[idx] = state[(state[i] + state[j]) % 256]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/arcfour.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: arcfour.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding ARCFOUR implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef ARCFOUR_H 10 | #define ARCFOUR_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /**************************** DATA TYPES ****************************/ 16 | typedef unsigned char BYTE; // 8-bit byte 17 | 18 | /*********************** FUNCTION DECLARATIONS **********************/ 19 | // Input: state - the state used to generate the keystream 20 | // key - Key to use to initialize the state 21 | // len - length of key in bytes (valid lenth is 1 to 256) 22 | void arcfour_key_setup(BYTE state[], const BYTE key[], int len); 23 | 24 | // Pseudo-Random Generator Algorithm 25 | // Input: state - the state used to generate the keystream 26 | // out - Must be allocated to be of at least "len" length 27 | // len - number of bytes to generate 28 | void arcfour_generate_stream(BYTE state[], BYTE out[], size_t len); 29 | 30 | #endif // ARCFOUR_H 31 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/arcfour_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: arcfour_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding ARCFOUR 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include "arcfour.h" 18 | 19 | /*********************** FUNCTION DEFINITIONS ***********************/ 20 | int rc4_test() 21 | { 22 | BYTE state[256]; 23 | BYTE key[3][10] = {{"Key"}, {"Wiki"}, {"Secret"}}; 24 | BYTE stream[3][10] = {{0xEB,0x9F,0x77,0x81,0xB7,0x34,0xCA,0x72,0xA7,0x19}, 25 | {0x60,0x44,0xdb,0x6d,0x41,0xb7}, 26 | {0x04,0xd4,0x6b,0x05,0x3c,0xa8,0x7b,0x59}}; 27 | int stream_len[3] = {10,6,8}; 28 | BYTE buf[1024]; 29 | int idx; 30 | int pass = 1; 31 | 32 | // Only test the output stream. Note that the state can be reused. 33 | for (idx = 0; idx < 3; idx++) { 34 | arcfour_key_setup(state, key[idx], strlen(key[idx])); 35 | arcfour_generate_stream(state, buf, stream_len[idx]); 36 | pass = pass && !memcmp(stream[idx], buf, stream_len[idx]); 37 | } 38 | 39 | return(pass); 40 | } 41 | 42 | int main() 43 | { 44 | printf("ARCFOUR tests: %s\n", rc4_test() ? "SUCCEEDED" : "FAILED"); 45 | 46 | return(0); 47 | } 48 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/base64.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: base64.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the Base64 encoding algorithm. 7 | *********************************************************************/ 8 | 9 | /*************************** HEADER FILES ***************************/ 10 | #include 11 | #include "base64.h" 12 | 13 | /****************************** MACROS ******************************/ 14 | #define NEWLINE_INVL 76 15 | 16 | /**************************** VARIABLES *****************************/ 17 | // Note: To change the charset to a URL encoding, replace the '+' and '/' with '*' and '-' 18 | static const BYTE charset[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"}; 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | BYTE revchar(char ch) 22 | { 23 | if (ch >= 'A' && ch <= 'Z') 24 | ch -= 'A'; 25 | else if (ch >= 'a' && ch <='z') 26 | ch = ch - 'a' + 26; 27 | else if (ch >= '0' && ch <='9') 28 | ch = ch - '0' + 52; 29 | else if (ch == '+') 30 | ch = 62; 31 | else if (ch == '/') 32 | ch = 63; 33 | 34 | return(ch); 35 | } 36 | 37 | size_t base64_encode(const BYTE in[], BYTE out[], size_t len, int newline_flag) 38 | { 39 | size_t idx, idx2, blks, blk_ceiling, left_over, newline_count = 0; 40 | 41 | blks = (len / 3); 42 | left_over = len % 3; 43 | 44 | if (out == NULL) { 45 | idx2 = blks * 4 ; 46 | if (left_over) 47 | idx2 += 4; 48 | if (newline_flag) 49 | idx2 += len / 57; // (NEWLINE_INVL / 4) * 3 = 57. One newline per 57 input bytes. 50 | } 51 | else { 52 | // Since 3 input bytes = 4 output bytes, determine out how many even sets of 53 | // 3 bytes the input has. 54 | blk_ceiling = blks * 3; 55 | for (idx = 0, idx2 = 0; idx < blk_ceiling; idx += 3, idx2 += 4) { 56 | out[idx2] = charset[in[idx] >> 2]; 57 | out[idx2 + 1] = charset[((in[idx] & 0x03) << 4) | (in[idx + 1] >> 4)]; 58 | out[idx2 + 2] = charset[((in[idx + 1] & 0x0f) << 2) | (in[idx + 2] >> 6)]; 59 | out[idx2 + 3] = charset[in[idx + 2] & 0x3F]; 60 | // The offical standard requires a newline every 76 characters. 61 | // (Eg, first newline is character 77 of the output.) 62 | if (((idx2 - newline_count + 4) % NEWLINE_INVL == 0) && newline_flag) { 63 | out[idx2 + 4] = '\n'; 64 | idx2++; 65 | newline_count++; 66 | } 67 | } 68 | 69 | if (left_over == 1) { 70 | out[idx2] = charset[in[idx] >> 2]; 71 | out[idx2 + 1] = charset[(in[idx] & 0x03) << 4]; 72 | out[idx2 + 2] = '='; 73 | out[idx2 + 3] = '='; 74 | idx2 += 4; 75 | } 76 | else if (left_over == 2) { 77 | out[idx2] = charset[in[idx] >> 2]; 78 | out[idx2 + 1] = charset[((in[idx] & 0x03) << 4) | (in[idx + 1] >> 4)]; 79 | out[idx2 + 2] = charset[(in[idx + 1] & 0x0F) << 2]; 80 | out[idx2 + 3] = '='; 81 | idx2 += 4; 82 | } 83 | } 84 | 85 | return(idx2); 86 | } 87 | 88 | size_t base64_decode(const BYTE in[], BYTE out[], size_t len) 89 | { 90 | BYTE ch; 91 | size_t idx, idx2, blks, blk_ceiling, left_over; 92 | 93 | if (in[len - 1] == '=') 94 | len--; 95 | if (in[len - 1] == '=') 96 | len--; 97 | 98 | blks = len / 4; 99 | left_over = len % 4; 100 | 101 | if (out == NULL) { 102 | if (len >= 77 && in[NEWLINE_INVL] == '\n') // Verify that newlines where used. 103 | len -= len / (NEWLINE_INVL + 1); 104 | blks = len / 4; 105 | left_over = len % 4; 106 | 107 | idx = blks * 3; 108 | if (left_over == 2) 109 | idx ++; 110 | else if (left_over == 3) 111 | idx += 2; 112 | } 113 | else { 114 | blk_ceiling = blks * 4; 115 | for (idx = 0, idx2 = 0; idx2 < blk_ceiling; idx += 3, idx2 += 4) { 116 | if (in[idx2] == '\n') 117 | idx2++; 118 | out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); 119 | out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2); 120 | out[idx + 2] = (revchar(in[idx2 + 2]) << 6) | revchar(in[idx2 + 3]); 121 | } 122 | 123 | if (left_over == 2) { 124 | out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); 125 | idx++; 126 | } 127 | else if (left_over == 3) { 128 | out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); 129 | out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2); 130 | idx += 2; 131 | } 132 | } 133 | 134 | return(idx); 135 | } 136 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/base64.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: base64.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding Base64 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef BASE64_H 10 | #define BASE64_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /**************************** DATA TYPES ****************************/ 16 | typedef unsigned char BYTE; // 8-bit byte 17 | 18 | /*********************** FUNCTION DECLARATIONS **********************/ 19 | // Returns the size of the output. If called with out = NULL, will just return 20 | // the size of what the output would have been (without a terminating NULL). 21 | size_t base64_encode(const BYTE in[], BYTE out[], size_t len, int newline_flag); 22 | 23 | // Returns the size of the output. If called with out = NULL, will just return 24 | // the size of what the output would have been (without a terminating NULL). 25 | size_t base64_decode(const BYTE in[], BYTE out[], size_t len); 26 | 27 | #endif // BASE64_H 28 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/base64_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: blowfish_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding Base64 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include "base64.h" 18 | 19 | /*********************** FUNCTION DEFINITIONS ***********************/ 20 | int base64_test() 21 | { 22 | BYTE text[3][1024] = {{"fo"}, 23 | {"foobar"}, 24 | {"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."}}; 25 | BYTE code[3][1024] = {{"Zm8="}, 26 | {"Zm9vYmFy"}, 27 | {"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz\nIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg\ndGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu\ndWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo\nZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="}}; 28 | BYTE buf[1024]; 29 | size_t buf_len; 30 | int pass = 1; 31 | int idx; 32 | 33 | for (idx = 0; idx < 3; idx++) { 34 | buf_len = base64_encode(text[idx], buf, strlen(text[idx]), 1); 35 | pass = pass && ((buf_len == strlen(code[idx])) && 36 | (buf_len == base64_encode(text[idx], NULL, strlen(text[idx]), 1))); 37 | pass = pass && !strcmp(code[idx], buf); 38 | 39 | memset(buf, 0, sizeof(buf)); 40 | buf_len = base64_decode(code[idx], buf, strlen(code[idx])); 41 | pass = pass && ((buf_len == strlen(text[idx])) && 42 | (buf_len == base64_decode(code[idx], NULL, strlen(code[idx])))); 43 | pass = pass && !strcmp(text[idx], buf); 44 | } 45 | 46 | return(pass); 47 | } 48 | 49 | int main() 50 | { 51 | printf("Base64 tests: %s\n", base64_test() ? "PASSED" : "FAILED"); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/blowfish.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: blowfish.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding Blowfish implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef BLOWFISH_H 10 | #define BLOWFISH_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define BLOWFISH_BLOCK_SIZE 8 // Blowfish operates on 8 bytes at a time 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | typedef struct { 23 | WORD p[18]; 24 | WORD s[4][256]; 25 | } BLOWFISH_KEY; 26 | 27 | /*********************** FUNCTION DECLARATIONS **********************/ 28 | void blowfish_key_setup(const BYTE user_key[], BLOWFISH_KEY *keystruct, size_t len); 29 | void blowfish_encrypt(const BYTE in[], BYTE out[], const BLOWFISH_KEY *keystruct); 30 | void blowfish_decrypt(const BYTE in[], BYTE out[], const BLOWFISH_KEY *keystruct); 31 | 32 | #endif // BLOWFISH_H 33 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/blowfish_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: blowfish_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding Blowfish 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include "blowfish.h" 18 | 19 | /*********************** FUNCTION DEFINITIONS ***********************/ 20 | int blowfish_test() 21 | { 22 | BYTE key1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 23 | BYTE key2[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 24 | BYTE key3[24] = {0xF0,0xE1,0xD2,0xC3,0xB4,0xA5,0x96,0x87, 25 | 0x78,0x69,0x5A,0x4B,0x3C,0x2D,0x1E,0x0F, 26 | 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; 27 | BYTE p1[BLOWFISH_BLOCK_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 28 | BYTE p2[BLOWFISH_BLOCK_SIZE] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 29 | BYTE p3[BLOWFISH_BLOCK_SIZE] = {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}; 30 | 31 | BYTE c1[BLOWFISH_BLOCK_SIZE] = {0x4e,0xf9,0x97,0x45,0x61,0x98,0xdd,0x78}; 32 | BYTE c2[BLOWFISH_BLOCK_SIZE] = {0x51,0x86,0x6f,0xd5,0xb8,0x5e,0xcb,0x8a}; 33 | BYTE c3[BLOWFISH_BLOCK_SIZE] = {0x05,0x04,0x4b,0x62,0xfa,0x52,0xd0,0x80}; 34 | 35 | BYTE enc_buf[BLOWFISH_BLOCK_SIZE]; 36 | BLOWFISH_KEY key; 37 | int pass = 1; 38 | 39 | // Test vector 1. 40 | blowfish_key_setup(key1, &key, BLOWFISH_BLOCK_SIZE); 41 | blowfish_encrypt(p1, enc_buf, &key); 42 | pass = pass && !memcmp(c1, enc_buf, BLOWFISH_BLOCK_SIZE); 43 | blowfish_decrypt(c1, enc_buf, &key); 44 | pass = pass && !memcmp(p1, enc_buf, BLOWFISH_BLOCK_SIZE); 45 | 46 | // Test vector 2. 47 | blowfish_key_setup(key2, &key, BLOWFISH_BLOCK_SIZE); 48 | blowfish_encrypt(p2, enc_buf, &key); 49 | pass = pass && !memcmp(c2, enc_buf, BLOWFISH_BLOCK_SIZE); 50 | blowfish_decrypt(c2, enc_buf, &key); 51 | pass = pass && !memcmp(p2, enc_buf, BLOWFISH_BLOCK_SIZE); 52 | 53 | // Test vector 3. 54 | blowfish_key_setup(key3, &key, 24); 55 | blowfish_encrypt(p3, enc_buf, &key); 56 | pass = pass && !memcmp(c3, enc_buf, BLOWFISH_BLOCK_SIZE); 57 | blowfish_decrypt(c3, enc_buf, &key); 58 | pass = pass && !memcmp(p3, enc_buf, BLOWFISH_BLOCK_SIZE); 59 | 60 | return(pass); 61 | } 62 | 63 | int main() 64 | { 65 | printf("Blowfish tests: %s\n", blowfish_test() ? "SUCCEEDED" : "FAILED"); 66 | 67 | return(0); 68 | } 69 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/des.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: des.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding DES implementation. 7 | Note that encryption and decryption are defined by how 8 | the key setup is performed, the actual en/de-cryption is 9 | performed by the same function. 10 | *********************************************************************/ 11 | 12 | #ifndef DES_H 13 | #define DESH 14 | 15 | /*************************** HEADER FILES ***************************/ 16 | #include 17 | 18 | /****************************** MACROS ******************************/ 19 | #define DES_BLOCK_SIZE 8 // DES operates on 8 bytes at a time 20 | 21 | /**************************** DATA TYPES ****************************/ 22 | typedef unsigned char BYTE; // 8-bit byte 23 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 24 | 25 | typedef enum { 26 | DES_ENCRYPT, 27 | DES_DECRYPT 28 | } DES_MODE; 29 | 30 | /*********************** FUNCTION DECLARATIONS **********************/ 31 | void des_key_setup(const BYTE key[], BYTE schedule[][6], DES_MODE mode); 32 | void des_crypt(const BYTE in[], BYTE out[], const BYTE key[][6]); 33 | 34 | void three_des_key_setup(const BYTE key[], BYTE schedule[][16][6], DES_MODE mode); 35 | void three_des_crypt(const BYTE in[], BYTE out[], const BYTE key[][16][6]); 36 | 37 | #endif // DES_H 38 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/des_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: des_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding DES 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include "des.h" 18 | 19 | /*********************** FUNCTION DEFINITIONS ***********************/ 20 | int des_test() 21 | { 22 | BYTE pt1[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xE7}; 23 | BYTE pt2[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; 24 | BYTE pt3[DES_BLOCK_SIZE] = {0x54,0x68,0x65,0x20,0x71,0x75,0x66,0x63}; 25 | BYTE ct1[DES_BLOCK_SIZE] = {0xc9,0x57,0x44,0x25,0x6a,0x5e,0xd3,0x1d}; 26 | BYTE ct2[DES_BLOCK_SIZE] = {0x85,0xe8,0x13,0x54,0x0f,0x0a,0xb4,0x05}; 27 | BYTE ct3[DES_BLOCK_SIZE] = {0xc9,0x57,0x44,0x25,0x6a,0x5e,0xd3,0x1d}; 28 | BYTE ct4[DES_BLOCK_SIZE] = {0xA8,0x26,0xFD,0x8C,0xE5,0x3B,0x85,0x5F}; 29 | BYTE key1[DES_BLOCK_SIZE] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; 30 | BYTE key2[DES_BLOCK_SIZE] = {0x13,0x34,0x57,0x79,0x9B,0xBC,0xDF,0xF1}; 31 | BYTE three_key1[DES_BLOCK_SIZE * 3] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 32 | 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 33 | 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; 34 | BYTE three_key2[DES_BLOCK_SIZE * 3] = {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 35 | 0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,0x01, 36 | 0x45,0x67,0x89,0xAB,0xCD,0xEF,0x01,0x23}; 37 | 38 | BYTE schedule[16][6]; 39 | BYTE three_schedule[3][16][6]; 40 | BYTE buf[DES_BLOCK_SIZE]; 41 | int pass = 1; 42 | 43 | des_key_setup(key1, schedule, DES_ENCRYPT); 44 | des_crypt(pt1, buf, schedule); 45 | pass = pass && !memcmp(ct1, buf, DES_BLOCK_SIZE); 46 | 47 | des_key_setup(key1, schedule, DES_DECRYPT); 48 | des_crypt(ct1, buf, schedule); 49 | pass = pass && !memcmp(pt1, buf, DES_BLOCK_SIZE); 50 | 51 | des_key_setup(key2, schedule, DES_ENCRYPT); 52 | des_crypt(pt2, buf, schedule); 53 | pass = pass && !memcmp(ct2, buf, DES_BLOCK_SIZE); 54 | 55 | des_key_setup(key2, schedule, DES_DECRYPT); 56 | des_crypt(ct2, buf, schedule); 57 | pass = pass && !memcmp(pt2, buf, DES_BLOCK_SIZE); 58 | 59 | three_des_key_setup(three_key1, three_schedule, DES_ENCRYPT); 60 | three_des_crypt(pt1, buf, three_schedule); 61 | pass = pass && !memcmp(ct3, buf, DES_BLOCK_SIZE); 62 | 63 | three_des_key_setup(three_key1, three_schedule, DES_DECRYPT); 64 | three_des_crypt(ct3, buf, three_schedule); 65 | pass = pass && !memcmp(pt1, buf, DES_BLOCK_SIZE); 66 | 67 | three_des_key_setup(three_key2, three_schedule, DES_ENCRYPT); 68 | three_des_crypt(pt3, buf, three_schedule); 69 | pass = pass && !memcmp(ct4, buf, DES_BLOCK_SIZE); 70 | 71 | three_des_key_setup(three_key2, three_schedule, DES_DECRYPT); 72 | three_des_crypt(ct4, buf, three_schedule); 73 | pass = pass && !memcmp(pt3, buf, DES_BLOCK_SIZE); 74 | 75 | return(pass); 76 | } 77 | 78 | int main() 79 | { 80 | printf("DES test: %s\n", des_test() ? "SUCCEEDED" : "FAILED"); 81 | 82 | return(0); 83 | } 84 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md2.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md2.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the MD2 hashing algorithm. 7 | Algorithm specification can be found here: 8 | * http://tools.ietf.org/html/rfc1319 . 9 | Input is little endian byte order. 10 | *********************************************************************/ 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include 15 | #include "md2.h" 16 | 17 | /**************************** VARIABLES *****************************/ 18 | static const BYTE s[256] = { 19 | 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 20 | 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 21 | 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 22 | 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 23 | 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 24 | 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 25 | 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 26 | 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 27 | 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 28 | 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 29 | 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 30 | 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 31 | 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 32 | 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 33 | 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 34 | 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 35 | 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 36 | 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 37 | }; 38 | 39 | /*********************** FUNCTION DEFINITIONS ***********************/ 40 | void md2_transform(MD2_CTX *ctx, BYTE data[]) 41 | { 42 | int j,k,t; 43 | 44 | //memcpy(&ctx->state[16], data); 45 | for (j=0; j < 16; ++j) { 46 | ctx->state[j + 16] = data[j]; 47 | ctx->state[j + 32] = (ctx->state[j+16] ^ ctx->state[j]); 48 | } 49 | 50 | t = 0; 51 | for (j = 0; j < 18; ++j) { 52 | for (k = 0; k < 48; ++k) { 53 | ctx->state[k] ^= s[t]; 54 | t = ctx->state[k]; 55 | } 56 | t = (t+j) & 0xFF; 57 | } 58 | 59 | t = ctx->checksum[15]; 60 | for (j=0; j < 16; ++j) { 61 | ctx->checksum[j] ^= s[data[j] ^ t]; 62 | t = ctx->checksum[j]; 63 | } 64 | } 65 | 66 | void md2_init(MD2_CTX *ctx) 67 | { 68 | int i; 69 | 70 | for (i=0; i < 48; ++i) 71 | ctx->state[i] = 0; 72 | for (i=0; i < 16; ++i) 73 | ctx->checksum[i] = 0; 74 | ctx->len = 0; 75 | } 76 | 77 | void md2_update(MD2_CTX *ctx, const BYTE data[], size_t len) 78 | { 79 | size_t i; 80 | 81 | for (i = 0; i < len; ++i) { 82 | ctx->data[ctx->len] = data[i]; 83 | ctx->len++; 84 | if (ctx->len == MD2_BLOCK_SIZE) { 85 | md2_transform(ctx, ctx->data); 86 | ctx->len = 0; 87 | } 88 | } 89 | } 90 | 91 | void md2_final(MD2_CTX *ctx, BYTE hash[]) 92 | { 93 | int to_pad; 94 | 95 | to_pad = MD2_BLOCK_SIZE - ctx->len; 96 | 97 | while (ctx->len < MD2_BLOCK_SIZE) 98 | ctx->data[ctx->len++] = to_pad; 99 | 100 | md2_transform(ctx, ctx->data); 101 | md2_transform(ctx, ctx->checksum); 102 | 103 | memcpy(hash, ctx->state, MD2_BLOCK_SIZE); 104 | } 105 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md2.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md2.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding MD2 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef MD2_H 10 | #define MD2_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define MD2_BLOCK_SIZE 16 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | 21 | typedef struct { 22 | BYTE data[16]; 23 | BYTE state[48]; 24 | BYTE checksum[16]; 25 | int len; 26 | } MD2_CTX; 27 | 28 | /*********************** FUNCTION DECLARATIONS **********************/ 29 | void md2_init(MD2_CTX *ctx); 30 | void md2_update(MD2_CTX *ctx, const BYTE data[], size_t len); 31 | void md2_final(MD2_CTX *ctx, BYTE hash[]); // size of hash must be MD2_BLOCK_SIZE 32 | 33 | #endif // MD2_H 34 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md2_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md2_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding MD2 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include 18 | #include "md2.h" 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | int md2_test() 22 | { 23 | BYTE text1[] = {"abc"}; 24 | BYTE text2[] = {"abcdefghijklmnopqrstuvwxyz"}; 25 | BYTE text3_1[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"}; 26 | BYTE text3_2[] = {"fghijklmnopqrstuvwxyz0123456789"}; 27 | BYTE hash1[MD2_BLOCK_SIZE] = {0xda,0x85,0x3b,0x0d,0x3f,0x88,0xd9,0x9b,0x30,0x28,0x3a,0x69,0xe6,0xde,0xd6,0xbb}; 28 | BYTE hash2[MD2_BLOCK_SIZE] = {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b}; 29 | BYTE hash3[MD2_BLOCK_SIZE] = {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd}; 30 | BYTE buf[16]; 31 | MD2_CTX ctx; 32 | int pass = 1; 33 | 34 | md2_init(&ctx); 35 | md2_update(&ctx, text1, strlen(text1)); 36 | md2_final(&ctx, buf); 37 | pass = pass && !memcmp(hash1, buf, MD2_BLOCK_SIZE); 38 | 39 | // Note that the MD2 object can be re-used. 40 | md2_init(&ctx); 41 | md2_update(&ctx, text2, strlen(text2)); 42 | md2_final(&ctx, buf); 43 | pass = pass && !memcmp(hash2, buf, MD2_BLOCK_SIZE); 44 | 45 | // Note that the data is added in two chunks. 46 | md2_init(&ctx); 47 | md2_update(&ctx, text3_1, strlen(text3_1)); 48 | md2_update(&ctx, text3_2, strlen(text3_2)); 49 | md2_final(&ctx, buf); 50 | pass = pass && !memcmp(hash3, buf, MD2_BLOCK_SIZE); 51 | 52 | return(pass); 53 | } 54 | 55 | int main() 56 | { 57 | printf("MD2 tests: %s\n", md2_test() ? "SUCCEEDED" : "FAILED"); 58 | } 59 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md5.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md5.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the MD5 hashing algorithm. 7 | Algorithm specification can be found here: 8 | * http://tools.ietf.org/html/rfc1321 9 | This implementation uses little endian byte order. 10 | *********************************************************************/ 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include 15 | #include "md5.h" 16 | 17 | /****************************** MACROS ******************************/ 18 | #define ROTLEFT(a,b) ((a << b) | (a >> (32-b))) 19 | 20 | #define F(x,y,z) ((x & y) | (~x & z)) 21 | #define G(x,y,z) ((x & z) | (y & ~z)) 22 | #define H(x,y,z) (x ^ y ^ z) 23 | #define I(x,y,z) (y ^ (x | ~z)) 24 | 25 | #define FF(a,b,c,d,m,s,t) { a += F(b,c,d) + m + t; \ 26 | a = b + ROTLEFT(a,s); } 27 | #define GG(a,b,c,d,m,s,t) { a += G(b,c,d) + m + t; \ 28 | a = b + ROTLEFT(a,s); } 29 | #define HH(a,b,c,d,m,s,t) { a += H(b,c,d) + m + t; \ 30 | a = b + ROTLEFT(a,s); } 31 | #define II(a,b,c,d,m,s,t) { a += I(b,c,d) + m + t; \ 32 | a = b + ROTLEFT(a,s); } 33 | 34 | /*********************** FUNCTION DEFINITIONS ***********************/ 35 | void md5_transform(MD5_CTX *ctx, const BYTE data[]) 36 | { 37 | WORD a, b, c, d, m[16], i, j; 38 | 39 | // MD5 specifies big endian byte order, but this implementation assumes a little 40 | // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them 41 | // on output (in md5_final()). 42 | for (i = 0, j = 0; i < 16; ++i, j += 4) 43 | m[i] = (data[j]) + (data[j + 1] << 8) + (data[j + 2] << 16) + (data[j + 3] << 24); 44 | 45 | a = ctx->state[0]; 46 | b = ctx->state[1]; 47 | c = ctx->state[2]; 48 | d = ctx->state[3]; 49 | 50 | FF(a,b,c,d,m[0], 7,0xd76aa478); 51 | FF(d,a,b,c,m[1], 12,0xe8c7b756); 52 | FF(c,d,a,b,m[2], 17,0x242070db); 53 | FF(b,c,d,a,m[3], 22,0xc1bdceee); 54 | FF(a,b,c,d,m[4], 7,0xf57c0faf); 55 | FF(d,a,b,c,m[5], 12,0x4787c62a); 56 | FF(c,d,a,b,m[6], 17,0xa8304613); 57 | FF(b,c,d,a,m[7], 22,0xfd469501); 58 | FF(a,b,c,d,m[8], 7,0x698098d8); 59 | FF(d,a,b,c,m[9], 12,0x8b44f7af); 60 | FF(c,d,a,b,m[10],17,0xffff5bb1); 61 | FF(b,c,d,a,m[11],22,0x895cd7be); 62 | FF(a,b,c,d,m[12], 7,0x6b901122); 63 | FF(d,a,b,c,m[13],12,0xfd987193); 64 | FF(c,d,a,b,m[14],17,0xa679438e); 65 | FF(b,c,d,a,m[15],22,0x49b40821); 66 | 67 | GG(a,b,c,d,m[1], 5,0xf61e2562); 68 | GG(d,a,b,c,m[6], 9,0xc040b340); 69 | GG(c,d,a,b,m[11],14,0x265e5a51); 70 | GG(b,c,d,a,m[0], 20,0xe9b6c7aa); 71 | GG(a,b,c,d,m[5], 5,0xd62f105d); 72 | GG(d,a,b,c,m[10], 9,0x02441453); 73 | GG(c,d,a,b,m[15],14,0xd8a1e681); 74 | GG(b,c,d,a,m[4], 20,0xe7d3fbc8); 75 | GG(a,b,c,d,m[9], 5,0x21e1cde6); 76 | GG(d,a,b,c,m[14], 9,0xc33707d6); 77 | GG(c,d,a,b,m[3], 14,0xf4d50d87); 78 | GG(b,c,d,a,m[8], 20,0x455a14ed); 79 | GG(a,b,c,d,m[13], 5,0xa9e3e905); 80 | GG(d,a,b,c,m[2], 9,0xfcefa3f8); 81 | GG(c,d,a,b,m[7], 14,0x676f02d9); 82 | GG(b,c,d,a,m[12],20,0x8d2a4c8a); 83 | 84 | HH(a,b,c,d,m[5], 4,0xfffa3942); 85 | HH(d,a,b,c,m[8], 11,0x8771f681); 86 | HH(c,d,a,b,m[11],16,0x6d9d6122); 87 | HH(b,c,d,a,m[14],23,0xfde5380c); 88 | HH(a,b,c,d,m[1], 4,0xa4beea44); 89 | HH(d,a,b,c,m[4], 11,0x4bdecfa9); 90 | HH(c,d,a,b,m[7], 16,0xf6bb4b60); 91 | HH(b,c,d,a,m[10],23,0xbebfbc70); 92 | HH(a,b,c,d,m[13], 4,0x289b7ec6); 93 | HH(d,a,b,c,m[0], 11,0xeaa127fa); 94 | HH(c,d,a,b,m[3], 16,0xd4ef3085); 95 | HH(b,c,d,a,m[6], 23,0x04881d05); 96 | HH(a,b,c,d,m[9], 4,0xd9d4d039); 97 | HH(d,a,b,c,m[12],11,0xe6db99e5); 98 | HH(c,d,a,b,m[15],16,0x1fa27cf8); 99 | HH(b,c,d,a,m[2], 23,0xc4ac5665); 100 | 101 | II(a,b,c,d,m[0], 6,0xf4292244); 102 | II(d,a,b,c,m[7], 10,0x432aff97); 103 | II(c,d,a,b,m[14],15,0xab9423a7); 104 | II(b,c,d,a,m[5], 21,0xfc93a039); 105 | II(a,b,c,d,m[12], 6,0x655b59c3); 106 | II(d,a,b,c,m[3], 10,0x8f0ccc92); 107 | II(c,d,a,b,m[10],15,0xffeff47d); 108 | II(b,c,d,a,m[1], 21,0x85845dd1); 109 | II(a,b,c,d,m[8], 6,0x6fa87e4f); 110 | II(d,a,b,c,m[15],10,0xfe2ce6e0); 111 | II(c,d,a,b,m[6], 15,0xa3014314); 112 | II(b,c,d,a,m[13],21,0x4e0811a1); 113 | II(a,b,c,d,m[4], 6,0xf7537e82); 114 | II(d,a,b,c,m[11],10,0xbd3af235); 115 | II(c,d,a,b,m[2], 15,0x2ad7d2bb); 116 | II(b,c,d,a,m[9], 21,0xeb86d391); 117 | 118 | ctx->state[0] += a; 119 | ctx->state[1] += b; 120 | ctx->state[2] += c; 121 | ctx->state[3] += d; 122 | } 123 | 124 | void md5_init(MD5_CTX *ctx) 125 | { 126 | ctx->datalen = 0; 127 | ctx->bitlen = 0; 128 | ctx->state[0] = 0x67452301; 129 | ctx->state[1] = 0xEFCDAB89; 130 | ctx->state[2] = 0x98BADCFE; 131 | ctx->state[3] = 0x10325476; 132 | } 133 | 134 | void md5_update(MD5_CTX *ctx, const BYTE data[], size_t len) 135 | { 136 | size_t i; 137 | 138 | for (i = 0; i < len; ++i) { 139 | ctx->data[ctx->datalen] = data[i]; 140 | ctx->datalen++; 141 | if (ctx->datalen == 64) { 142 | md5_transform(ctx, ctx->data); 143 | ctx->bitlen += 512; 144 | ctx->datalen = 0; 145 | } 146 | } 147 | } 148 | 149 | void md5_final(MD5_CTX *ctx, BYTE hash[]) 150 | { 151 | size_t i; 152 | 153 | i = ctx->datalen; 154 | 155 | // Pad whatever data is left in the buffer. 156 | if (ctx->datalen < 56) { 157 | ctx->data[i++] = 0x80; 158 | while (i < 56) 159 | ctx->data[i++] = 0x00; 160 | } 161 | else if (ctx->datalen >= 56) { 162 | ctx->data[i++] = 0x80; 163 | while (i < 64) 164 | ctx->data[i++] = 0x00; 165 | md5_transform(ctx, ctx->data); 166 | memset(ctx->data, 0, 56); 167 | } 168 | 169 | // Append to the padding the total message's length in bits and transform. 170 | ctx->bitlen += ctx->datalen * 8; 171 | ctx->data[56] = ctx->bitlen; 172 | ctx->data[57] = ctx->bitlen >> 8; 173 | ctx->data[58] = ctx->bitlen >> 16; 174 | ctx->data[59] = ctx->bitlen >> 24; 175 | ctx->data[60] = ctx->bitlen >> 32; 176 | ctx->data[61] = ctx->bitlen >> 40; 177 | ctx->data[62] = ctx->bitlen >> 48; 178 | ctx->data[63] = ctx->bitlen >> 56; 179 | md5_transform(ctx, ctx->data); 180 | 181 | // Since this implementation uses little endian byte ordering and MD uses big endian, 182 | // reverse all the bytes when copying the final state to the output hash. 183 | for (i = 0; i < 4; ++i) { 184 | hash[i] = (ctx->state[0] >> (i * 8)) & 0x000000ff; 185 | hash[i + 4] = (ctx->state[1] >> (i * 8)) & 0x000000ff; 186 | hash[i + 8] = (ctx->state[2] >> (i * 8)) & 0x000000ff; 187 | hash[i + 12] = (ctx->state[3] >> (i * 8)) & 0x000000ff; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md5.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md5.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding MD5 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef MD5_H 10 | #define MD5_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define MD5_BLOCK_SIZE 16 // MD5 outputs a 16 byte digest 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | typedef struct { 23 | BYTE data[64]; 24 | WORD datalen; 25 | unsigned long long bitlen; 26 | WORD state[4]; 27 | } MD5_CTX; 28 | 29 | /*********************** FUNCTION DECLARATIONS **********************/ 30 | void md5_init(MD5_CTX *ctx); 31 | void md5_update(MD5_CTX *ctx, const BYTE data[], size_t len); 32 | void md5_final(MD5_CTX *ctx, BYTE hash[]); 33 | 34 | #endif // MD5_H 35 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/md5_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: md5_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding MD5 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include 18 | #include "md5.h" 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | int md5_test() 22 | { 23 | BYTE text1[] = {""}; 24 | BYTE text2[] = {"abc"}; 25 | BYTE text3_1[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"}; 26 | BYTE text3_2[] = {"fghijklmnopqrstuvwxyz0123456789"}; 27 | BYTE hash1[MD5_BLOCK_SIZE] = {0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}; 28 | BYTE hash2[MD5_BLOCK_SIZE] = {0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}; 29 | BYTE hash3[MD5_BLOCK_SIZE] = {0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}; 30 | BYTE buf[16]; 31 | MD5_CTX ctx; 32 | int pass = 1; 33 | 34 | md5_init(&ctx); 35 | md5_update(&ctx, text1, strlen((char*)text1)); 36 | md5_final(&ctx, buf); 37 | pass = pass && !memcmp(hash1, buf, MD5_BLOCK_SIZE); 38 | 39 | // Note the MD5 object can be reused. 40 | md5_init(&ctx); 41 | md5_update(&ctx, text2, strlen((char*)text2)); 42 | md5_final(&ctx, buf); 43 | pass = pass && !memcmp(hash2, buf, MD5_BLOCK_SIZE); 44 | 45 | // Note the data is being added in two chunks. 46 | md5_init(&ctx); 47 | md5_update(&ctx, text3_1, strlen((char*)text3_1)); 48 | md5_update(&ctx, text3_2, strlen((char*)text3_2)); 49 | md5_final(&ctx, buf); 50 | pass = pass && !memcmp(hash3, buf, MD5_BLOCK_SIZE); 51 | 52 | return(pass); 53 | } 54 | 55 | int main() 56 | { 57 | printf("MD5 tests: %s\n", md5_test() ? "SUCCEEDED" : "FAILED"); 58 | 59 | return(0); 60 | } 61 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/rot-13.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: rot-13.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the ROT-13 encryption algorithm. 7 | Algorithm specification can be found here: 8 | * 9 | This implementation uses little endian byte order. 10 | *********************************************************************/ 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include "rot-13.h" 15 | 16 | /*********************** FUNCTION DEFINITIONS ***********************/ 17 | void rot13(char str[]) 18 | { 19 | int case_type, idx, len; 20 | 21 | for (idx = 0, len = strlen(str); idx < len; idx++) { 22 | // Only process alphabetic characters. 23 | if (str[idx] < 'A' || (str[idx] > 'Z' && str[idx] < 'a') || str[idx] > 'z') 24 | continue; 25 | // Determine if the char is upper or lower case. 26 | if (str[idx] >= 'a') 27 | case_type = 'a'; 28 | else 29 | case_type = 'A'; 30 | // Rotate the char's value, ensuring it doesn't accidentally "fall off" the end. 31 | str[idx] = (str[idx] + 13) % (case_type + 26); 32 | if (str[idx] < 26) 33 | str[idx] += case_type; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/rot-13.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: rot-13.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding ROT-13 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef ROT13_H 10 | #define ROT13_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /*********************** FUNCTION DECLARATIONS **********************/ 16 | // Performs IN PLACE rotation of the input. Assumes input is NULL terminated. 17 | // Preserves each charcter's case. Ignores non alphabetic characters. 18 | void rot13(char str[]); 19 | 20 | #endif // ROT13_H 21 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/rot-13_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: rot-13_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding ROT-13 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include "rot-13.h" 18 | 19 | /*********************** FUNCTION DEFINITIONS ***********************/ 20 | int rot13_test() 21 | { 22 | char text[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}; 23 | char code[] = {"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"}; 24 | char buf[1024]; 25 | int pass = 1; 26 | 27 | // To encode, just apply ROT-13. 28 | strcpy(buf, text); 29 | rot13(buf); 30 | pass = pass && !strcmp(code, buf); 31 | 32 | // To decode, just re-apply ROT-13. 33 | rot13(buf); 34 | pass = pass && !strcmp(text, buf); 35 | 36 | return(pass); 37 | } 38 | 39 | int main() 40 | { 41 | printf("ROT-13 tests: %s\n", rot13_test() ? "SUCCEEDED" : "FAILED"); 42 | 43 | return(0); 44 | } 45 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha1.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha1.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the SHA1 hashing algorithm. 7 | Algorithm specification can be found here: 8 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 9 | This implementation uses little endian byte order. 10 | *********************************************************************/ 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include 15 | #include "sha1.h" 16 | 17 | /****************************** MACROS ******************************/ 18 | #define ROTLEFT(a, b) ((a << b) | (a >> (32 - b))) 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | void sha1_transform(SHA1_CTX *ctx, const BYTE data[]) 22 | { 23 | WORD a, b, c, d, e, i, j, t, m[80]; 24 | 25 | for (i = 0, j = 0; i < 16; ++i, j += 4) 26 | m[i] = (data[j] << 24) + (data[j + 1] << 16) + (data[j + 2] << 8) + (data[j + 3]); 27 | for ( ; i < 80; ++i) { 28 | m[i] = (m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]); 29 | m[i] = (m[i] << 1) | (m[i] >> 31); 30 | } 31 | 32 | a = ctx->state[0]; 33 | b = ctx->state[1]; 34 | c = ctx->state[2]; 35 | d = ctx->state[3]; 36 | e = ctx->state[4]; 37 | 38 | for (i = 0; i < 20; ++i) { 39 | t = ROTLEFT(a, 5) + ((b & c) ^ (~b & d)) + e + ctx->k[0] + m[i]; 40 | e = d; 41 | d = c; 42 | c = ROTLEFT(b, 30); 43 | b = a; 44 | a = t; 45 | } 46 | for ( ; i < 40; ++i) { 47 | t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[1] + m[i]; 48 | e = d; 49 | d = c; 50 | c = ROTLEFT(b, 30); 51 | b = a; 52 | a = t; 53 | } 54 | for ( ; i < 60; ++i) { 55 | t = ROTLEFT(a, 5) + ((b & c) ^ (b & d) ^ (c & d)) + e + ctx->k[2] + m[i]; 56 | e = d; 57 | d = c; 58 | c = ROTLEFT(b, 30); 59 | b = a; 60 | a = t; 61 | } 62 | for ( ; i < 80; ++i) { 63 | t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[3] + m[i]; 64 | e = d; 65 | d = c; 66 | c = ROTLEFT(b, 30); 67 | b = a; 68 | a = t; 69 | } 70 | 71 | ctx->state[0] += a; 72 | ctx->state[1] += b; 73 | ctx->state[2] += c; 74 | ctx->state[3] += d; 75 | ctx->state[4] += e; 76 | } 77 | 78 | void sha1_init(SHA1_CTX *ctx) 79 | { 80 | ctx->datalen = 0; 81 | ctx->bitlen = 0; 82 | ctx->state[0] = 0x67452301; 83 | ctx->state[1] = 0xEFCDAB89; 84 | ctx->state[2] = 0x98BADCFE; 85 | ctx->state[3] = 0x10325476; 86 | ctx->state[4] = 0xc3d2e1f0; 87 | ctx->k[0] = 0x5a827999; 88 | ctx->k[1] = 0x6ed9eba1; 89 | ctx->k[2] = 0x8f1bbcdc; 90 | ctx->k[3] = 0xca62c1d6; 91 | } 92 | 93 | void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len) 94 | { 95 | size_t i; 96 | 97 | for (i = 0; i < len; ++i) { 98 | ctx->data[ctx->datalen] = data[i]; 99 | ctx->datalen++; 100 | if (ctx->datalen == 64) { 101 | sha1_transform(ctx, ctx->data); 102 | ctx->bitlen += 512; 103 | ctx->datalen = 0; 104 | } 105 | } 106 | } 107 | 108 | void sha1_final(SHA1_CTX *ctx, BYTE hash[]) 109 | { 110 | WORD i; 111 | 112 | i = ctx->datalen; 113 | 114 | // Pad whatever data is left in the buffer. 115 | if (ctx->datalen < 56) { 116 | ctx->data[i++] = 0x80; 117 | while (i < 56) 118 | ctx->data[i++] = 0x00; 119 | } 120 | else { 121 | ctx->data[i++] = 0x80; 122 | while (i < 64) 123 | ctx->data[i++] = 0x00; 124 | sha1_transform(ctx, ctx->data); 125 | memset(ctx->data, 0, 56); 126 | } 127 | 128 | // Append to the padding the total message's length in bits and transform. 129 | ctx->bitlen += ctx->datalen * 8; 130 | ctx->data[63] = ctx->bitlen; 131 | ctx->data[62] = ctx->bitlen >> 8; 132 | ctx->data[61] = ctx->bitlen >> 16; 133 | ctx->data[60] = ctx->bitlen >> 24; 134 | ctx->data[59] = ctx->bitlen >> 32; 135 | ctx->data[58] = ctx->bitlen >> 40; 136 | ctx->data[57] = ctx->bitlen >> 48; 137 | ctx->data[56] = ctx->bitlen >> 56; 138 | sha1_transform(ctx, ctx->data); 139 | 140 | // Since this implementation uses little endian byte ordering and MD uses big endian, 141 | // reverse all the bytes when copying the final state to the output hash. 142 | for (i = 0; i < 4; ++i) { 143 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 144 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 145 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 146 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 147 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha1.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha1.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding SHA1 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef SHA1_H 10 | #define SHA1_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define SHA1_BLOCK_SIZE 20 // SHA1 outputs a 20 byte digest 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | typedef struct { 23 | BYTE data[64]; 24 | WORD datalen; 25 | unsigned long long bitlen; 26 | WORD state[5]; 27 | WORD k[4]; 28 | } SHA1_CTX; 29 | 30 | /*********************** FUNCTION DECLARATIONS **********************/ 31 | void sha1_init(SHA1_CTX *ctx); 32 | void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len); 33 | void sha1_final(SHA1_CTX *ctx, BYTE hash[]); 34 | 35 | #endif // SHA1_H 36 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha1_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha1_test.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding SHA1 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include 18 | #include "sha1.h" 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | int sha1_test() 22 | { 23 | BYTE text1[] = {"abc"}; 24 | BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; 25 | BYTE text3[] = {"aaaaaaaaaa"}; 26 | BYTE hash1[SHA1_BLOCK_SIZE] = {0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}; 27 | BYTE hash2[SHA1_BLOCK_SIZE] = {0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1}; 28 | BYTE hash3[SHA1_BLOCK_SIZE] = {0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e,0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f}; 29 | BYTE buf[SHA1_BLOCK_SIZE]; 30 | int idx; 31 | SHA1_CTX ctx; 32 | int pass = 1; 33 | 34 | sha1_init(&ctx); 35 | sha1_update(&ctx, text1, strlen(text1)); 36 | sha1_final(&ctx, buf); 37 | pass = pass && !memcmp(hash1, buf, SHA1_BLOCK_SIZE); 38 | 39 | sha1_init(&ctx); 40 | sha1_update(&ctx, text2, strlen(text2)); 41 | sha1_final(&ctx, buf); 42 | pass = pass && !memcmp(hash2, buf, SHA1_BLOCK_SIZE); 43 | 44 | sha1_init(&ctx); 45 | for (idx = 0; idx < 100000; ++idx) 46 | sha1_update(&ctx, text3, strlen(text3)); 47 | sha1_final(&ctx, buf); 48 | pass = pass && !memcmp(hash3, buf, SHA1_BLOCK_SIZE); 49 | 50 | return(pass); 51 | } 52 | 53 | int main() 54 | { 55 | printf("SHA1 tests: %s\n", sha1_test() ? "SUCCEEDED" : "FAILED"); 56 | 57 | return(0); 58 | } 59 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha256.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the SHA-256 hashing algorithm. 7 | SHA-256 is one of the three algorithms in the SHA2 8 | specification. The others, SHA-384 and SHA-512, are not 9 | offered in this implementation. 10 | Algorithm specification can be found here: 11 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 12 | This implementation uses little endian byte order. 13 | *********************************************************************/ 14 | 15 | /*************************** HEADER FILES ***************************/ 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /****************************** MACROS ******************************/ 21 | #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 22 | #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 23 | 24 | #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 25 | #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 26 | #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 27 | #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 28 | #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 29 | #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 30 | 31 | /**************************** VARIABLES *****************************/ 32 | static const WORD k[64] = { 33 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 34 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 35 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 36 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 37 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 38 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 39 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 40 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 41 | }; 42 | 43 | /*********************** FUNCTION DEFINITIONS ***********************/ 44 | void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) 45 | { 46 | WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 47 | 48 | for (i = 0, j = 0; i < 16; ++i, j += 4) 49 | m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 50 | for ( ; i < 64; ++i) 51 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 52 | 53 | a = ctx->state[0]; 54 | b = ctx->state[1]; 55 | c = ctx->state[2]; 56 | d = ctx->state[3]; 57 | e = ctx->state[4]; 58 | f = ctx->state[5]; 59 | g = ctx->state[6]; 60 | h = ctx->state[7]; 61 | 62 | for (i = 0; i < 64; ++i) { 63 | t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 64 | t2 = EP0(a) + MAJ(a,b,c); 65 | h = g; 66 | g = f; 67 | f = e; 68 | e = d + t1; 69 | d = c; 70 | c = b; 71 | b = a; 72 | a = t1 + t2; 73 | } 74 | 75 | ctx->state[0] += a; 76 | ctx->state[1] += b; 77 | ctx->state[2] += c; 78 | ctx->state[3] += d; 79 | ctx->state[4] += e; 80 | ctx->state[5] += f; 81 | ctx->state[6] += g; 82 | ctx->state[7] += h; 83 | } 84 | 85 | void sha256_init(SHA256_CTX *ctx) 86 | { 87 | ctx->datalen = 0; 88 | ctx->bitlen = 0; 89 | ctx->state[0] = 0x6a09e667; 90 | ctx->state[1] = 0xbb67ae85; 91 | ctx->state[2] = 0x3c6ef372; 92 | ctx->state[3] = 0xa54ff53a; 93 | ctx->state[4] = 0x510e527f; 94 | ctx->state[5] = 0x9b05688c; 95 | ctx->state[6] = 0x1f83d9ab; 96 | ctx->state[7] = 0x5be0cd19; 97 | } 98 | 99 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) 100 | { 101 | WORD i; 102 | 103 | for (i = 0; i < len; ++i) { 104 | ctx->data[ctx->datalen] = data[i]; 105 | ctx->datalen++; 106 | if (ctx->datalen == 64) { 107 | sha256_transform(ctx, ctx->data); 108 | ctx->bitlen += 512; 109 | ctx->datalen = 0; 110 | } 111 | } 112 | } 113 | 114 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]) 115 | { 116 | WORD i; 117 | 118 | i = ctx->datalen; 119 | 120 | // Pad whatever data is left in the buffer. 121 | if (ctx->datalen < 56) { 122 | ctx->data[i++] = 0x80; 123 | while (i < 56) 124 | ctx->data[i++] = 0x00; 125 | } 126 | else { 127 | ctx->data[i++] = 0x80; 128 | while (i < 64) 129 | ctx->data[i++] = 0x00; 130 | sha256_transform(ctx, ctx->data); 131 | memset(ctx->data, 0, 56); 132 | } 133 | 134 | // Append to the padding the total message's length in bits and transform. 135 | ctx->bitlen += ctx->datalen * 8; 136 | ctx->data[63] = ctx->bitlen; 137 | ctx->data[62] = ctx->bitlen >> 8; 138 | ctx->data[61] = ctx->bitlen >> 16; 139 | ctx->data[60] = ctx->bitlen >> 24; 140 | ctx->data[59] = ctx->bitlen >> 32; 141 | ctx->data[58] = ctx->bitlen >> 40; 142 | ctx->data[57] = ctx->bitlen >> 48; 143 | ctx->data[56] = ctx->bitlen >> 56; 144 | sha256_transform(ctx, ctx->data); 145 | 146 | // Since this implementation uses little endian byte ordering and SHA uses big endian, 147 | // reverse all the bytes when copying the final state to the output hash. 148 | for (i = 0; i < 4; ++i) { 149 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 150 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 151 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 152 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 153 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 154 | hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 155 | hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 156 | hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha256.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding SHA1 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef SHA256_H 10 | #define SHA256_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | typedef struct { 23 | BYTE data[64]; 24 | WORD datalen; 25 | unsigned long long bitlen; 26 | WORD state[8]; 27 | } SHA256_CTX; 28 | 29 | /*********************** FUNCTION DECLARATIONS **********************/ 30 | void sha256_init(SHA256_CTX *ctx); 31 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); 32 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]); 33 | 34 | #endif // SHA256_H 35 | -------------------------------------------------------------------------------- /validation/crypto-algorithms/sha256_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding SHA1 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | int sha256_test() 22 | { 23 | BYTE text1[] = {"abc"}; 24 | BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; 25 | BYTE text3[] = {"aaaaaaaaaa"}; 26 | BYTE hash1[SHA256_BLOCK_SIZE] = {0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, 27 | 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}; 28 | BYTE hash2[SHA256_BLOCK_SIZE] = {0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, 29 | 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}; 30 | BYTE hash3[SHA256_BLOCK_SIZE] = {0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, 31 | 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0}; 32 | BYTE buf[SHA256_BLOCK_SIZE]; 33 | SHA256_CTX ctx; 34 | int idx; 35 | int pass = 1; 36 | 37 | sha256_init(&ctx); 38 | sha256_update(&ctx, text1, strlen((char*)text1)); 39 | sha256_final(&ctx, buf); 40 | pass = pass && !memcmp(hash1, buf, SHA256_BLOCK_SIZE); 41 | 42 | sha256_init(&ctx); 43 | sha256_update(&ctx, text2, strlen((char*)text2)); 44 | sha256_final(&ctx, buf); 45 | pass = pass && !memcmp(hash2, buf, SHA256_BLOCK_SIZE); 46 | 47 | sha256_init(&ctx); 48 | for (idx = 0; idx < 100000; ++idx) { 49 | sha256_update(&ctx, text3, strlen((char*)text3)); 50 | } 51 | sha256_final(&ctx, buf); 52 | pass = pass && !memcmp(hash3, buf, SHA256_BLOCK_SIZE); 53 | 54 | return(pass); 55 | } 56 | 57 | int main() 58 | { 59 | printf("SHA-256 tests: %s\n", sha256_test() ? "SUCCEEDED" : "FAILED"); 60 | 61 | return(0); 62 | } 63 | -------------------------------------------------------------------------------- /validation/doom/README.md: -------------------------------------------------------------------------------- 1 | ## A branchless DOOM 2 | 3 | This directory provides a branchless, mov-only version of the classic DOOM video 4 | game. 5 | 6 | | ![mov doom](doom.png) | 7 | |:--:| 8 | | *DOOM, running with only mov instructions.* | 9 | 10 | This is thought to be entirely secure against the Meltdown and Spectre CPU 11 | vulnerabilities, which require speculative execution on branch instructions. 12 | 13 | To build and run a branchless, mov-only, exploit-hardened DOOM: 14 | 15 | ``` 16 | # Download the DOOM source code 17 | git clone https://github.com/id-Software/DOOM 18 | 19 | # Download a DOOM WAD file 20 | wget http://distro.ibiblio.org/pub/linux/distributions/slitaz/sources/packages/d/doom1.wad -P ./DOOM/linuxdoom-1.10 21 | 22 | # Apply the M/o/Vfuscator patches 23 | # These make DOOM compatible with the mov-compiler 24 | patch -s -p0 < doom.patch 25 | 26 | # M/o/Vfuscate DOOM 27 | export MOVCC=~/movfuscator/ # your movfuscator source directory 28 | cd DOOM/linuxdoom-1.10 29 | mkdir linux 30 | make 31 | 32 | # Play DOOM 33 | ./linux/linuxxdoom -episode 0 34 | ``` 35 | 36 | The mov-only DOOM renders approximately one frame every 7 hours, so playing this 37 | version requires somewhat increased patience. 38 | 39 | ### Requirements 40 | 41 | DOOM requires a 256 color desktop. Setting this up will vary depending on your 42 | flavor of Linux, but one approach is proposed below. 43 | 44 | Start an 8-bit X desktop: 45 | 46 | ``` 47 | sudo startx -- :1 -depth 8 vt8 48 | ``` 49 | 50 | Switch to that desktop with ctrl-alt-f8. 51 | 52 | ### Patches 53 | 54 | Some small patches are applied to DOOM first to fix various build issues. This 55 | set of patches corrects some issues in DOOM, replaces some missing library 56 | functions like alloca, and works around the C warnings that LCC (the compiler 57 | frontend) treats as errors. 58 | 59 | ### Notes 60 | 61 | Tested on i386 Debian 7.11. 62 | 63 | This project is entirely tongue-in-cheek, and only serves as a correctness test 64 | for the M/o/Vfuscator compiler. 65 | -------------------------------------------------------------------------------- /validation/doom/doom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoreaxeaxeax/movfuscator/ea37dae93fbcd93f642c71a53878da588bd7ddb4/validation/doom/doom.png -------------------------------------------------------------------------------- /validation/e.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* from http://numbers.computation.free.fr/Constants/TinyPrograms/tinycodes.pdf */ 4 | main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n; 5 | for(;N>9;printf("%d\n",x)) 6 | for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n);} 7 | -------------------------------------------------------------------------------- /validation/float.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float x=10; 6 | float y=3; 7 | float z; 8 | int i; 9 | 10 | /* see notes in README - ABI conflict between libc's printf and 11 | * M/o/Vfuscator's 32 bit doubles */ 12 | z=x+y; 13 | printf("%08x %08x %08x\n", *(int*)&x, *(int*)&y, *(int*)&z); 14 | z=x-y; 15 | printf("%08x %08x %08x\n", *(int*)&x, *(int*)&y, *(int*)&z); 16 | z=x*y; 17 | printf("%08x %08x %08x\n", *(int*)&x, *(int*)&y, *(int*)&z); 18 | z=x/y; 19 | printf("%08x %08x %08x\n", *(int*)&x, *(int*)&y, *(int*)&z); 20 | z=-x; 21 | printf("%08x %08x %08x\n", *(int*)&x, *(int*)&y, *(int*)&z); 22 | 23 | i=x; 24 | printf("%d %08x\n", i, *(int*)&x); 25 | y=i; 26 | printf("%d %08x\n", i, *(int*)&y); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /validation/float_reg_spill.c: -------------------------------------------------------------------------------- 1 | /* tests an issue in lcc spilling of floating point registers */ 2 | 3 | #include 4 | #include 5 | 6 | void stub(double x) {} 7 | 8 | int main(void) 9 | { 10 | int a, b; 11 | double c, d; 12 | 13 | a=2, b=8; 14 | 15 | c = ((double)a) / ((double)b) * .1; 16 | stub(c); 17 | 18 | d = ((double)a) / ((double)b); 19 | d = d * .1; 20 | 21 | if (c!=d) { 22 | printf("%f != %f\n", c, d); 23 | printf("float spill failed.\n"); 24 | } 25 | else { 26 | printf("%f == %f\n", c, d); 27 | printf("float spill passed.\n"); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /validation/galton.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Galton_box_animation#C */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define BALLS 1024 8 | int n, w, h = 45, *x, *y, cnt = 0; 9 | char *b; 10 | 11 | #define B(y, x) b[(y)*w + x] 12 | #define C(y, x) ' ' == b[(y)*w + x] 13 | #define V(i) B(y[i], x[i]) 14 | int rnd(int a) { return (rand()/(RAND_MAX/a))%a; } 15 | 16 | void show_board() 17 | { 18 | int i, j; 19 | for (puts("\033[H"), i = 0; i < h; i++, putchar('\n')) 20 | for (j = 0; j < w; j++, putchar(' ')) 21 | printf(B(i, j) == '*' ? 22 | C(i - 1, j) ? "\033[32m%c\033[m" : 23 | "\033[31m%c\033[m" : "%c", B(i, j)); 24 | } 25 | 26 | void init() 27 | { 28 | int i, j; 29 | puts("\033[H\033[J"); 30 | b = malloc(w * h); 31 | memset(b, ' ', w * h); 32 | 33 | x = malloc(sizeof(int) * BALLS * 2); 34 | y = x + BALLS; 35 | 36 | for (i = 0; i < n; i++) 37 | for (j = -i; j <= i; j += 2) 38 | B(2 * i+2, j + w/2) = '*'; 39 | srand(time(0)); 40 | } 41 | 42 | void move(int idx) 43 | { 44 | int xx = x[idx], yy = y[idx], c, kill = 0, sl = 3, o = 0; 45 | 46 | if (yy < 0) return; 47 | if (yy == h - 1) { y[idx] = -1; return; } 48 | 49 | switch(c = B(yy + 1, xx)) { 50 | case ' ': yy++; break; 51 | case '*': sl = 1; 52 | default: if (xx < w - 1 && C(yy, xx + 1) && C(yy + 1, xx + 1)) 53 | if (!rnd(sl++)) o = 1; 54 | if (xx && C(yy, xx - 1) && C(yy + 1, xx - 1)) 55 | if (!rnd(sl++)) o = -1; 56 | if (!o) kill = 1; 57 | xx += o; 58 | } 59 | 60 | c = V(idx); V(idx) = ' '; 61 | idx[y] = yy, idx[x] = xx; 62 | B(yy, xx) = c; 63 | if (kill) idx[y] = -1; 64 | } 65 | 66 | int run(void) 67 | { 68 | static int step = 0; 69 | int i; 70 | for (i = 0; i < cnt; i++) move(i); 71 | if (2 == ++step && cnt < BALLS) { 72 | step = 0; 73 | x[cnt] = w/2; 74 | y[cnt] = 0; 75 | if (V(cnt) != ' ') return 0; 76 | V(cnt) = rnd(80) + 43; 77 | cnt++; 78 | } 79 | return 1; 80 | } 81 | 82 | int main(int c, char **v) 83 | { 84 | if (c < 2 || (n = atoi(v[1])) <= 3) n = 5; 85 | if (n >= 20) n = 20; 86 | w = n * 2 + 1; 87 | init(); 88 | 89 | do { show_board(), usleep(60000); } while (run()); 90 | 91 | return 0; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /validation/gen_alu_test.c: -------------------------------------------------------------------------------- 1 | /* this program generates an arithmetic test for the M/o/Vfuscator */ 2 | 3 | /* it should be compiled with gcc, and its output compiled with the 4 | * M/o/Vfuscator, to verify the MOV ALU calculates the same results as those 5 | * from a program compiled with gcc */ 6 | 7 | /* gcc gen_test.c && ./a.out > test.c && movcc test.c movfusator/lib/softfloat64.o && ./a.out | grep FAIL */ 8 | 9 | #include 10 | 11 | static const double vd[]={-2.0, -1.0, 0.0, 1.0, 2.0}; 12 | static const float vf[]={-2.0f, -1.0f, 0.0f, 1.0f, 2.0f}; 13 | 14 | static const signed int vsi[]={0x80000000, 0x80000001, -2, -1, 0, 1, 2, 0x7ffffffe, 0x7fffffff}; 15 | static const signed short vss[]={0x8000, 0x8001, -2, -1, 0, 1, 2, 0x7ffe, 0x7fff}; 16 | static const signed char vsc[]={0x80, 0x81, -2, -1, 0, 1, 2, 0x7e, 0x7f}; 17 | 18 | static const unsigned int vui[]={0x80000000, 0x80000001, -2, -1, 0, 1, 2, 0x7ffffffe, 0x7fffffff}; 19 | static const unsigned short vus[]={0x8000, 0x8001, -2, -1, 0, 1, 2, 0x7ffe, 0x7fff}; 20 | static const unsigned char vuc[]={0x80, 0x81, -2, -1, 0, 1, 2, 0x7e, 0x7f}; 21 | 22 | #define TEST_STRING " printf(\"%%20s: %%20d %%2s %%-20d == %%-20d => %%8s (%%d)\\n\","\ 23 | "\"%s\",%d,\"%s\",%d,%d,(%s)(x%sy)==%d?\"PASS\":\"FAIL\",(%s)(x%sy));\n" 24 | 25 | #define TEST_STRING_F " printf(\"%%20s: %%20f %%2s %%-20f == %%-20f => %%8s (%%f)\\n\","\ 26 | "\"%s\",%f,\"%s\",%f,%f,(%s)(x%sy)==%f?\"PASS\":\"FAIL\",(%s)(x%sy));\n" 27 | 28 | #define TEST_PARMS(type,set,op) \ 29 | #type,set[i],#op,set[j],(type)(set[i] op set[j]),#type,#op,(type)(set[i] op set[j]),#type,#op 30 | 31 | #define S_F "%f" 32 | #define S_I "%d" 33 | 34 | #define FOR_SET(ss,tt,string,type,set,op) {\ 35 | int i, j; \ 36 | int c=sizeof((set))/sizeof(*(set)); \ 37 | for (i=0; i>); \ 56 | FOR_SET(S_I,I,TEST_STRING,type,set,&&); \ 57 | FOR_SET(S_I,I,TEST_STRING,type,set,||); \ 58 | FOR_SET(S_I,I,TEST_STRING,type,set,>) \ 59 | FOR_SET(S_I,I,TEST_STRING,type,set,<) \ 60 | FOR_SET(S_I,I,TEST_STRING,type,set,>=) \ 61 | FOR_SET(S_I,I,TEST_STRING,type,set,<=) \ 62 | FOR_SET(S_I,I,TEST_STRING,type,set,==) \ 63 | FOR_SET(S_I,I,TEST_STRING,type,set,!=) \ 64 | FOR_SET(S_I,I,TEST_STRING,type,set,*); \ 65 | FOR_SET(S_I,I,TEST_STRING,type,set,/); \ 66 | FOR_SET(S_I,I,TEST_STRING,type,set,%); \ 67 | } 68 | 69 | #define FOR_SET_FLOAT(type,set) {\ 70 | FOR_SET(S_F,F,TEST_STRING_F,type,set,+); \ 71 | FOR_SET(S_F,F,TEST_STRING_F,type,set,-); \ 72 | FOR_SET(S_F,F,TEST_STRING_F,type,set,*); \ 73 | FOR_SET(S_F,F,TEST_STRING_F,type,set,/); \ 74 | FOR_SET(S_F,F,TEST_STRING_F,type,set,>) \ 75 | FOR_SET(S_F,F,TEST_STRING_F,type,set,<) \ 76 | FOR_SET(S_F,F,TEST_STRING_F,type,set,>=) \ 77 | FOR_SET(S_F,F,TEST_STRING_F,type,set,<=) \ 78 | FOR_SET(S_F,F,TEST_STRING_F,type,set,==) \ 79 | FOR_SET(S_F,F,TEST_STRING_F,type,set,!=) \ 80 | } 81 | 82 | typedef enum { I, F } type; 83 | 84 | int exclude(type t, char* op, int x, int y) 85 | { 86 | if (t==I) { 87 | if (op=="/" || op=="%") { 88 | if (y==0 || (y==-1 && x==0x80000000)) { 89 | return 1; 90 | } 91 | } 92 | else if (op==">>" || op=="<<") { 93 | if (y>31 || y<0) { 94 | return 1; 95 | } 96 | } 97 | } 98 | else if (t==F) { 99 | if (op=="/") { 100 | if (y==0) { 101 | return 1; 102 | } 103 | } 104 | } 105 | return 0; 106 | } 107 | 108 | int main(void) 109 | { 110 | printf("#include \n"); 111 | printf("int main(void) {\n"); 112 | 113 | FOR_SET_ALL(signed int, vsi); 114 | FOR_SET_ALL(signed short, vss); 115 | FOR_SET_ALL(signed char, vsc); 116 | 117 | FOR_SET_ALL(unsigned int, vui); 118 | FOR_SET_ALL(unsigned short, vus); 119 | FOR_SET_ALL(unsigned char, vuc); 120 | 121 | FOR_SET_FLOAT(float, vf); 122 | FOR_SET_FLOAT(double, vf); 123 | 124 | printf("}\n"); 125 | 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /validation/hanoi.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Towers_of_Hanoi#C */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct { int *x, n; } tower; 8 | tower *new_tower(int cap) 9 | { 10 | tower *t = calloc(1, sizeof(tower) + sizeof(int) * cap); 11 | t->x = (int*)(t + 1); 12 | return t; 13 | } 14 | 15 | tower *t[3]; 16 | int height; 17 | 18 | void text(int y, int i, int d, const char *s) 19 | { 20 | printf("\033[%d;%dH", height - y + 1, (height + 1) * (2 * i + 1) - d); 21 | while (d--) printf("%s", s); 22 | } 23 | 24 | void add_disk(int i, int d) 25 | { 26 | t[i]->x[t[i]->n++] = d; 27 | text(t[i]->n, i, d, "=="); 28 | 29 | usleep(100000); 30 | fflush(stdout); 31 | } 32 | 33 | int remove_disk(int i) 34 | { 35 | int d = t[i]->x[--t[i]->n]; 36 | text(t[i]->n + 1, i, d, " "); 37 | return d; 38 | } 39 | 40 | void move(int n, int from, int to, int via) 41 | { 42 | if (!n) return; 43 | 44 | move(n - 1, from, via, to); 45 | add_disk(to, remove_disk(from)); 46 | move(n - 1, via, to, from); 47 | } 48 | 49 | int main(int c, char *v[]) 50 | { 51 | puts("\033[H\033[J"); 52 | 53 | if (c <= 1 || (height = atoi(v[1])) <= 0) 54 | height = 8; 55 | for (c = 0; c < 3; c++) t[c] = new_tower(height); 56 | for (c = height; c; c--) add_disk(0, c); 57 | 58 | move(height, 0, 2, 1); 59 | 60 | text(1, 0, 1, "\n"); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /validation/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Hello, world!\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /validation/knight.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Knight%27s_tour#C */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | typedef unsigned char cell; 9 | int dx[] = { -2, -2, -1, 1, 2, 2, 1, -1 }; 10 | int dy[] = { -1, 1, 2, 2, 1, -1, -2, -2 }; 11 | 12 | void init_board(int w, int h, cell **a, cell **b) 13 | { 14 | int i, j, k, x, y, p = w + 4, q = h + 4; 15 | /* b is board; a is board with 2 rows padded at each side */ 16 | a[0] = (cell*)(a + q); 17 | b[0] = a[0] + 2; 18 | 19 | for (i = 1; i < q; i++) { 20 | a[i] = a[i-1] + p; 21 | b[i] = a[i] + 2; 22 | } 23 | 24 | memset(a[0], 255, p * q); 25 | for (i = 0; i < h; i++) { 26 | for (j = 0; j < w; j++) { 27 | for (k = 0; k < 8; k++) { 28 | x = j + dx[k], y = i + dy[k]; 29 | if (b[i+2][j] == 255) b[i+2][j] = 0; 30 | b[i+2][j] += x >= 0 && x < w && y >= 0 && y < h; 31 | } 32 | } 33 | } 34 | } 35 | 36 | #define E "\033[" 37 | int walk_board(int w, int h, int x, int y, cell **b) 38 | { 39 | int i, nx, ny, least; 40 | int steps = 0; 41 | printf(E"H"E"J"E"%d;%dH"E"32m[]"E"m", y + 1, 1 + 2 * x); 42 | 43 | while (1) { 44 | /* occupy cell */ 45 | b[y][x] = 255; 46 | 47 | /* reduce all neighbors' neighbor count */ 48 | for (i = 0; i < 8; i++) 49 | b[ y + dy[i] ][ x + dx[i] ]--; 50 | 51 | /* find neighbor with lowest neighbor count */ 52 | least = 255; 53 | for (i = 0; i < 8; i++) { 54 | if (b[ y + dy[i] ][ x + dx[i] ] < least) { 55 | nx = x + dx[i]; 56 | ny = y + dy[i]; 57 | least = b[ny][nx]; 58 | } 59 | } 60 | 61 | if (least > 7) { 62 | printf(E"%dH", h + 2); 63 | return steps == w * h - 1; 64 | } 65 | 66 | if (steps++) printf(E"%d;%dH[]", y + 1, 1 + 2 * x); 67 | x = nx, y = ny; 68 | printf(E"%d;%dH"E"31m[]"E"m", y + 1, 1 + 2 * x); 69 | fflush(stdout); 70 | usleep(120000); 71 | } 72 | } 73 | 74 | int solve(int w, int h) 75 | { 76 | int x = 0, y = 0; 77 | cell **a, **b; 78 | a = malloc((w + 4) * (h + 4) + sizeof(cell*) * (h + 4)); 79 | b = malloc((h + 4) * sizeof(cell*)); 80 | 81 | while (1) { 82 | init_board(w, h, a, b); 83 | if (walk_board(w, h, x, y, b + 2)) { 84 | printf("Success!\n"); 85 | return 1; 86 | } 87 | if (++x >= w) x = 0, y++; 88 | if (y >= h) { 89 | printf("Failed to find a solution\n"); 90 | return 0; 91 | } 92 | printf("Any key to try next start position"); 93 | getchar(); 94 | } 95 | } 96 | 97 | int main(int c, char **v) 98 | { 99 | int w, h; 100 | if (c < 2 || (w = atoi(v[1])) <= 0) w = 8; 101 | if (c < 3 || (h = atoi(v[2])) <= 0) h = w; 102 | solve(w, h); 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /validation/life.c: -------------------------------------------------------------------------------- 1 | /* adapted from http://rosettacode.org/wiki/Conway%27s_Game_of_Life */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define w 60 8 | #define h 60 9 | 10 | void show(void *u) 11 | { 12 | int x,y; 13 | int (*univ)[w] = u; 14 | printf("\033[H"); 15 | for (y=0;y 2 | 3 | int main() 4 | { 5 | int iX,iY; 6 | const int iXmax=80; 7 | const int iYmax=40; 8 | float cx,cy; 9 | const float cxMin=-2.5f; 10 | const float cxMax=1.5f; 11 | const float cyMin=-1.0f; 12 | const float cyMax=1.0f; 13 | float PixelWidth=(cxMax-cxMin)/iXmax; 14 | float PixelHeight=(cyMax-cyMin)/iYmax; 15 | float zx, zy; 16 | float zx2, zy2; 17 | int i; 18 | const int iterations=50; //200; 19 | const float r=2; 20 | float r2=r*r; 21 | for(iY=0; iY 4 | #include 5 | #include 6 | #include 7 | 8 | #define DOUBLE_SPACE 0 9 | 10 | #if DOUBLE_SPACE 11 | # define SPC " " 12 | #else 13 | # define SPC " " 14 | #endif 15 | 16 | //wchar_t glyph[] = L""SPC"│││─┘┐┤─└┌├─┴┬┼"SPC"┆┆┆┄╯╮ ┄╰╭ ┄"; 17 | int glyph[] = {0x0020, 0x2502, 0x2502, 0x2502, 0x2500, 0x2518, 0x2510, 0x2524, 0x2500, 0x2514, 0x250c, 0x251c, 0x2500, 0x2534, 0x252c, 0x253c, 0x0020, 0x2506, 0x2506, 0x2506, 0x2504, 0x256f, 0x256e, 0x0020, 0x2504, 0x2570, 0x256d, 0x0020, 0x2504, 0x0000}; 18 | 19 | typedef unsigned char byte; 20 | enum { N = 1, S = 2, W = 4, E = 8, V = 16 }; 21 | 22 | byte **cell; 23 | int w, h, avail; 24 | #define each(i, x, y) for (i = x; i <= y; i++) 25 | 26 | int irand(int n) 27 | { 28 | int r, rmax = n * (RAND_MAX / n); 29 | while ((r = rand()) >= rmax); 30 | return r / (RAND_MAX/n); 31 | } 32 | 33 | void show() 34 | { 35 | int i, j, c; 36 | each(i, 0, 2 * h) { 37 | each(j, 0, 2 * w) { 38 | c = cell[i][j]; 39 | if (c > V) printf("\033[31m"); 40 | printf("%lc", glyph[c]); 41 | if (c > V) printf("\033[m"); 42 | } 43 | putchar('\n'); 44 | } 45 | } 46 | 47 | int max(int a, int b) { return a >= b ? a : b; } 48 | int min(int a, int b) { return b >= a ? a : b; } 49 | 50 | static int dirs[4][2] = {{-2, 0}, {0, 2}, {2, 0}, {0, -2}}; 51 | void walk(int x, int y) 52 | { 53 | int i, t, x1, y1, d[4] = { 0, 1, 2, 3 }; 54 | 55 | cell[y][x] |= V; 56 | avail--; 57 | 58 | for (x1 = 3; x1; x1--) 59 | if (x1 != (y1 = irand(x1 + 1))) 60 | i = d[x1], d[x1] = d[y1], d[y1] = i; 61 | 62 | for (i = 0; avail && i < 4; i++) { 63 | x1 = x + dirs[ d[i] ][0], y1 = y + dirs[ d[i] ][1]; 64 | 65 | if (cell[y1][x1] & V) continue; 66 | 67 | /* break walls */ 68 | if (x1 == x) { 69 | t = (y + y1) / 2; 70 | cell[t][x+1] &= ~W, cell[t][x] &= ~(E|W), cell[t][x-1] &= ~E; 71 | } else if (y1 == y) { 72 | t = (x + x1)/2; 73 | cell[y-1][t] &= ~S, cell[y][t] &= ~(N|S), cell[y+1][t] &= ~N; 74 | } 75 | walk(x1, y1); 76 | } 77 | } 78 | 79 | int solve(int x, int y, int tox, int toy) 80 | { 81 | int i, t, x1, y1; 82 | 83 | cell[y][x] |= V; 84 | if (x == tox && y == toy) return 1; 85 | 86 | each(i, 0, 3) { 87 | x1 = x + dirs[i][0], y1 = y + dirs[i][1]; 88 | if (cell[y1][x1]) continue; 89 | 90 | /* mark path */ 91 | if (x1 == x) { 92 | t = (y + y1)/2; 93 | if (cell[t][x] || !solve(x1, y1, tox, toy)) continue; 94 | 95 | cell[t-1][x] |= S, cell[t][x] |= V|N|S, cell[t+1][x] |= N; 96 | } else if (y1 == y) { 97 | t = (x + x1)/2; 98 | if (cell[y][t] || !solve(x1, y1, tox, toy)) continue; 99 | 100 | cell[y][t-1] |= E, cell[y][t] |= V|E|W, cell[y][t+1] |= W; 101 | } 102 | return 1; 103 | } 104 | 105 | /* backtrack */ 106 | cell[y][x] &= ~V; 107 | return 0; 108 | } 109 | 110 | void make_maze() 111 | { 112 | int i, j; 113 | int h2 = 2 * h + 2, w2 = 2 * w + 2; 114 | byte **p; 115 | 116 | p = calloc(sizeof(byte*) * (h2 + 2) + w2 * h2 + 1, 1); 117 | 118 | p[1] = (byte*)(p + h2 + 2) + 1; 119 | each(i, 2, h2) p[i] = p[i-1] + w2; 120 | p[0] = p[h2]; 121 | cell = &p[1]; 122 | 123 | each(i, -1, 2 * h + 1) cell[i][-1] = cell[i][w2 - 1] = V; 124 | each(j, 0, 2 * w) cell[-1][j] = cell[h2 - 1][j] = V; 125 | each(i, 0, h) each(j, 0, 2 * w) cell[2*i][j] |= E|W; 126 | each(i, 0, 2 * h) each(j, 0, w) cell[i][2*j] |= N|S; 127 | each(j, 0, 2 * w) cell[0][j] &= ~N, cell[2*h][j] &= ~S; 128 | each(i, 0, 2 * h) cell[i][0] &= ~W, cell[i][2*w] &= ~E; 129 | 130 | avail = w * h; 131 | walk(irand(2) * 2 + 1, irand(h) * 2 + 1); 132 | 133 | /* reset visited marker (it's also used by path finder) */ 134 | each(i, 0, 2 * h) each(j, 0, 2 * w) cell[i][j] &= ~V; 135 | solve(1, 1, 2 * w - 1, 2 * h - 1); 136 | 137 | show(); 138 | } 139 | 140 | int main(int c, char **v) 141 | { 142 | srand(time(0)); 143 | setlocale(LC_ALL, ""); 144 | if (c < 2 || (w = atoi(v[1])) <= 0) w = 16; 145 | if (c < 3 || (h = atoi(v[2])) <= 0) h = 8; 146 | 147 | make_maze(); 148 | 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /validation/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* 25 | Independent implementation of MD5 (RFC 1321). 26 | 27 | This code implements the MD5 Algorithm defined in RFC 1321. 28 | It is derived directly from the text of the RFC and not from the 29 | reference implementation. 30 | 31 | The original and principal author of md5.h is L. Peter Deutsch 32 | . Other authors are noted in the change history 33 | that follows (in reverse chronological order): 34 | 35 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 36 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 37 | added conditionalization for C++ compilation from Martin 38 | Purschke . 39 | 1999-05-03 lpd Original version. 40 | */ 41 | 42 | #ifndef md5_INCLUDED 43 | # define md5_INCLUDED 44 | 45 | /* 46 | * This code has some adaptations for the Ghostscript environment, but it 47 | * will compile and run correctly in any environment with 8-bit chars and 48 | * 32-bit ints. Specifically, it assumes that if the following are 49 | * defined, they have the same meaning as in Ghostscript: P1, P2, P3, 50 | * ARCH_IS_BIG_ENDIAN. 51 | */ 52 | 53 | typedef unsigned char md5_byte_t; /* 8-bit byte */ 54 | typedef unsigned int md5_word_t; /* 32-bit word */ 55 | 56 | /* Define the state of the MD5 Algorithm. */ 57 | typedef struct md5_state_s { 58 | md5_word_t count[2]; /* message length in bits, lsw first */ 59 | md5_word_t abcd[4]; /* digest buffer */ 60 | md5_byte_t buf[64]; /* accumulate block */ 61 | } md5_state_t; 62 | 63 | #ifdef __cplusplus 64 | extern "C" 65 | { 66 | #endif 67 | 68 | /* Initialize the algorithm. */ 69 | #ifdef P1 70 | void md5_init(P1(md5_state_t *pms)); 71 | #else 72 | void md5_init(md5_state_t *pms); 73 | #endif 74 | 75 | /* Append a string to the message. */ 76 | #ifdef P3 77 | void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes)); 78 | #else 79 | void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); 80 | #endif 81 | 82 | /* Finish the message and return the digest. */ 83 | #ifdef P2 84 | void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16])); 85 | #else 86 | void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); 87 | #endif 88 | 89 | #ifdef __cplusplus 90 | } /* end extern "C" */ 91 | #endif 92 | 93 | #endif /* md5_INCLUDED */ 94 | -------------------------------------------------------------------------------- /validation/mersenne.c: -------------------------------------------------------------------------------- 1 | /* adapted from http://rosettacode.org/wiki/Factors_of_a_Mersenne_number#C */ 2 | int isPrime(int n){ 3 | int d=5; 4 | if (n%2==0) return n==2; 5 | if (n%3==0) return n==3; 6 | while(d*d<=n){ 7 | if(n%d==0) return 0; 8 | d+=2; 9 | if(n%d==0) return 0; 10 | d+=4;} 11 | return 1;} 12 | 13 | main() {int i,d,p,r,q=929; 14 | if (!isPrime(q)) return 1; 15 | r=q; 16 | while(r>0) r<<=1; 17 | d=2*q+1; 18 | do { for(p=r, i= 1; p; p<<= 1){ 19 | i=((long long)i * i) % d; 20 | if (p < 0) i *= 2; 21 | if (i > d) i -= d;} 22 | if (i != 1) d += 2*q; 23 | else break; 24 | } while(1); 25 | printf("2^%d - 1 = 0 (mod %d)\n", q, d);} 26 | -------------------------------------------------------------------------------- /validation/nibbles.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define _Bool unsigned int /* lcc doesn't define this */ 3 | #include 4 | 5 | #define MAX_LENGTH 100 6 | 7 | typedef enum { NONE, UP, DOWN, LEFT, RIGHT } dir_t; 8 | 9 | typedef struct { 10 | int x, y; 11 | } point_t; 12 | 13 | typedef struct { 14 | int width, height; 15 | } dim_t; 16 | 17 | typedef struct { 18 | int top, bottom, left, right; 19 | } rect_t; 20 | 21 | typedef struct { 22 | point_t body[MAX_LENGTH]; 23 | int length; 24 | int index; 25 | int dead; 26 | } snake_t; 27 | 28 | point_t create_food(dim_t); 29 | void print_board(rect_t); 30 | void print_food(point_t, rect_t); 31 | void print_head(snake_t*, rect_t); 32 | void clear_tail(snake_t*, rect_t); 33 | dir_t get_dir(int); 34 | void move_snake(snake_t*, dir_t); 35 | int is_dead(snake_t*, dim_t); 36 | int has_food(snake_t*, point_t); 37 | 38 | int main(void) 39 | { 40 | snake_t snake={0}; 41 | point_t food; 42 | rect_t board; 43 | dim_t screen; 44 | dim_t game_size; 45 | dir_t dir=RIGHT; 46 | dir_t move_dir=NONE; 47 | int c; 48 | 49 | srand(time(0)); 50 | initscr(); 51 | 52 | getmaxyx(stdscr, screen.height, screen.width); 53 | 54 | game_size.width=screen.width/2; 55 | game_size.height=screen.height/2; 56 | 57 | food=create_food(game_size); 58 | 59 | snake.body[0].x=game_size.width/2; 60 | snake.body[0].y=game_size.height/2; 61 | snake.body[1].x=game_size.width/2; 62 | snake.body[1].y=game_size.height/2+1; 63 | snake.length=2; 64 | snake.index=1; 65 | 66 | board.left=screen.width/2-game_size.width/2-1; 67 | board.right=board.left+game_size.width+1; 68 | board.top=screen.height/2-game_size.height/2-1; 69 | board.bottom=board.top+game_size.height+1; 70 | 71 | noecho(); 72 | cbreak(); 73 | timeout(0); 74 | curs_set(0); 75 | 76 | clear(); 77 | do { 78 | print_board(board); 79 | print_food(food,board); 80 | print_head(&snake,board); 81 | clear_tail(&snake,board); 82 | refresh(); 83 | 84 | c=getch(); 85 | move_dir=get_dir(c); 86 | if (move_dir!=NONE) { 87 | dir=move_dir; 88 | } 89 | 90 | move_snake(&snake, dir); 91 | snake.dead=is_dead(&snake,game_size); 92 | 93 | if (has_food(&snake, food)) { 94 | snake.length++; 95 | food=create_food(game_size); 96 | } 97 | 98 | usleep (100000-snake.length*5000<5000?5000:100000-snake.length*5000); 99 | 100 | } while (c!=27 && !snake.dead); 101 | 102 | move( 103 | screen.height/2, 104 | screen.width/2-5 105 | ); 106 | printw("GAME OVER"); 107 | refresh(); 108 | nocbreak(); 109 | timeout(-1); 110 | c=getch(); 111 | endwin(); 112 | 113 | return 0; 114 | } 115 | 116 | point_t create_food(dim_t game_size) 117 | { 118 | point_t f; 119 | f.x=rand()%game_size.width; 120 | f.y=rand()%game_size.height; 121 | return f; 122 | } 123 | 124 | void print_board(rect_t board) 125 | { 126 | int i; 127 | 128 | for (i=board.left; i<=board.right; i++) { 129 | move(board.top, i); 130 | addch(' '|A_REVERSE); 131 | move(board.bottom, i); 132 | addch(' '|A_REVERSE); 133 | } 134 | 135 | for (i=board.top; i<=board.bottom; i++) { 136 | move(i, board.left); 137 | addch(' '|A_REVERSE); 138 | move(i, board.right); 139 | addch(' '|A_REVERSE); 140 | } 141 | } 142 | 143 | void print_food(point_t food, rect_t board) 144 | { 145 | move( 146 | food.y+board.top+1, 147 | food.x+board.left+1 148 | ); 149 | printw("@"); 150 | } 151 | 152 | void print_head(snake_t* snake, rect_t board) 153 | { 154 | move( 155 | snake->body[snake->index].y+board.top+1, 156 | snake->body[snake->index].x+board.left+1 157 | ); 158 | printw("o"); 159 | } 160 | 161 | void clear_tail(snake_t* snake, rect_t board) 162 | { 163 | int t=snake->index-snake->length; 164 | if (t<0) { 165 | t+=MAX_LENGTH; 166 | } 167 | move( 168 | snake->body[t].y+board.top+1, 169 | snake->body[t].x+board.left+1 170 | ); 171 | printw(" "); 172 | } 173 | 174 | dir_t get_dir(int c) 175 | { 176 | if (c=='a') { 177 | return LEFT; 178 | } 179 | else if (c=='w') { 180 | return UP; 181 | } 182 | else if (c=='d') { 183 | return RIGHT; 184 | } 185 | else if (c=='s') { 186 | return DOWN; 187 | } 188 | else { 189 | return NONE; 190 | } 191 | } 192 | 193 | void move_snake(snake_t* snake, dir_t dir) 194 | { 195 | point_t p; 196 | p=snake->body[snake->index]; 197 | 198 | if (dir==LEFT) { 199 | p.x--; 200 | } 201 | else if (dir==DOWN) { 202 | p.y++; 203 | } 204 | else if (dir==RIGHT) { 205 | p.x++; 206 | } 207 | else if (dir==UP) { 208 | p.y--; 209 | } 210 | 211 | snake->index++; 212 | if (snake->index==MAX_LENGTH) { 213 | snake->index=0; 214 | } 215 | 216 | snake->body[snake->index]=p; 217 | } 218 | 219 | int is_dead(snake_t* snake, dim_t game_size) 220 | { 221 | int i, j; 222 | point_t head=snake->body[snake->index]; 223 | 224 | if (head.x==-1) return 1; 225 | if (head.x==game_size.width) return 1; 226 | if (head.y==-1) return 1; 227 | if (head.y==game_size.height) return 1; 228 | 229 | i=1; 230 | while (i!=snake->length) { 231 | j=snake->index-i; 232 | if (j<0) { 233 | j+=MAX_LENGTH; 234 | } 235 | if (head.x==snake->body[j].x && head.y==snake->body[j].y) { 236 | return 1; 237 | } 238 | i++; 239 | } 240 | 241 | return 0; 242 | } 243 | 244 | int has_food(snake_t* snake, point_t food) 245 | { 246 | return 247 | snake->body[snake->index].x==food.x && 248 | snake->body[snake->index].y==food.y; 249 | } 250 | -------------------------------------------------------------------------------- /validation/nqueens.c: -------------------------------------------------------------------------------- 1 | /* adapted from http://rosettacode.org/wiki/N-queens_problem#C */ 2 | #include 3 | #include 4 | 5 | int count = 0; 6 | void solve(int n, int col, int *hist) 7 | { 8 | int i, j; 9 | if (col == n) { 10 | printf("\nNo. %d\n-----\n", ++count); 11 | for (i = 0; i < n; i++, putchar('\n')) 12 | for (j = 0; j < n; j++) 13 | putchar(j == hist[i] ? 'Q' : ((i + j) & 1) ? ' ' : '.'); 14 | 15 | return; 16 | } 17 | 18 | # define attack(i, j) (hist[j] == i || abs(hist[j] - i) == col - j) 19 | for (i = 0, j = 0; i < n; i++) { 20 | for (j = 0; j < col && !attack(i, j); j++); 21 | if (j < col) continue; 22 | 23 | hist[col] = i; 24 | solve(n, col + 1, hist); 25 | } 26 | } 27 | 28 | int main(int n, char **argv) 29 | { 30 | int hist[100]; 31 | if (n <= 1 || (n = atoi(argv[1])) <= 0) n = 8; 32 | solve(n, 0, hist); 33 | } 34 | -------------------------------------------------------------------------------- /validation/pi.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* from http://numbers.computation.free.fr/Constants/TinyPrograms/tinycodes.pdf */ 4 | int a=10000,b,c=8400,d,e,f[8401],g;main(){ 5 | for(;b-c;)f[b++]=a/5; 6 | for(;d=0,g=c*2;c-=14,printf("%.4d\n",e+d/a),e=d%a) 7 | for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);} 8 | -------------------------------------------------------------------------------- /validation/prime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int is_prime(int x) 4 | { 5 | int i; 6 | if (x==1) { 7 | return 0; 8 | } 9 | if (x==2) { 10 | return 1; 11 | } 12 | for (i=2; i*i<=x; i++) { 13 | if (x%i==0) { 14 | return 0; 15 | } 16 | } 17 | return 1; 18 | } 19 | 20 | int main(void) 21 | { 22 | int i; 23 | printf("primes, 1-100000: \n"); 24 | for (i=1; i<10000; i++) { 25 | if (is_prime(i)) { 26 | printf("%d ", i); 27 | } 28 | } 29 | printf("\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /validation/ray.c: -------------------------------------------------------------------------------- 1 | /* adapted from http://www.purplealienplanet.com/sites/default/files/raytrace_part1.c */ 2 | /* A simple ray tracer - part 1 */ 3 | 4 | #include 5 | //#include /* Needed for boolean datatype */ 6 | typedef char bool; 7 | #define true 1 8 | #define false 0 9 | 10 | 11 | /* The vector structure */ 12 | typedef struct{ 13 | float x,y,z; 14 | }vector; 15 | 16 | /* The sphere */ 17 | typedef struct{ 18 | vector pos; 19 | float radius; 20 | }sphere; 21 | 22 | /* The ray */ 23 | typedef struct{ 24 | vector start; 25 | vector dir; 26 | }ray; 27 | 28 | /* Subtract two vectors and return the resulting vector */ 29 | vector vectorSub(vector *v1, vector *v2){ 30 | vector result; 31 | result.x=v1->x - v2->x; 32 | result.y=v1->y - v2->y; 33 | result.z=v1->z - v2->z; 34 | return result; 35 | } 36 | 37 | /* Multiply two vectors and return the resulting scalar (dot product) */ 38 | float vectorDot(vector *v1, vector *v2){ 39 | return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; 40 | } 41 | 42 | 43 | /* Check if the ray and sphere intersect */ 44 | bool intersectRaySphere(ray *r, sphere *s){ 45 | 46 | /* A = d.d, the vector dot product of the direction */ 47 | float A = vectorDot(&r->dir, &r->dir); 48 | 49 | /* We need a vector representing the distance between the start of 50 | * the ray and the position of the circle. 51 | * This is the term (p0 - c) 52 | */ 53 | vector dist = vectorSub(&r->start, &s->pos); 54 | 55 | /* 2d.(p0 - c) */ 56 | float B = 2 * vectorDot(&r->dir, &dist); 57 | 58 | /* (p0 - c).(p0 - c) - r^2 */ 59 | float C = vectorDot(&dist, &dist) - (s->radius * s->radius); 60 | 61 | /* Solving the discriminant */ 62 | float discr = B * B - 4 * A * C; 63 | 64 | /* If the discriminant is negative, there are no real roots. 65 | * Return false in that case as the ray misses the sphere. 66 | * Return true in all other cases (can be one or two intersections) 67 | */ 68 | if(discr < 0) 69 | return false; 70 | else 71 | return true; 72 | } 73 | 74 | 75 | int main(int argc, char *argv){ 76 | 77 | /* Our ray and a sphere */ 78 | sphere s; 79 | ray r; 80 | 81 | /* x, y for screen 'resolution' */ 82 | int x,y; 83 | 84 | /* Intersect ray/sphere or not */ 85 | bool hit; 86 | 87 | /* Position the sphere */ 88 | s.pos.x = 20; 89 | s.pos.y = 20; 90 | s.pos.z = 20; 91 | 92 | /* Sphere radius */ 93 | s.radius = 10; 94 | 95 | /* Direction of the ray */ 96 | r.dir.x = 0; 97 | r.dir.y = 0; 98 | r.dir.z = 1; 99 | 100 | /* Start position of the ray, z coordinate */ 101 | r.start.z = 0; 102 | 103 | /* Iterate over every 'pixel' of our screen 104 | * We use a 40x40 virtual ASCII screen for now 105 | */ 106 | for(y=0;y<40;y++){ 107 | /* Set the y-coordinate of the start position of the ray */ 108 | r.start.y = y; 109 | for(x=0;x<40;x++){ 110 | /* Set the x-coordinate of the start position of the ray */ 111 | r.start.x = x; 112 | 113 | /* Check if the ray intersects with the shpere */ 114 | hit = intersectRaySphere(&r, &s); 115 | if(hit) 116 | printf("++"); 117 | else 118 | printf("--"); 119 | } 120 | /* First row of the screen done, move to next row */ 121 | printf("\n"); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /validation/s2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* from http://numbers.computation.free.fr/Constants/TinyPrograms/tinycodes.pdf */ 4 | 5 | main(){int a=1000,b=0,c=1413,d,f[1414],n=800,k; 6 | for(;b 2 | 3 | #define PI 3.14159265359f 4 | 5 | float sin(float); 6 | 7 | int main(void) 8 | { 9 | float f; 10 | 11 | for (f=-PI; f<=PI+.01f; f+=PI/16) { 12 | printf("sin(%.4f): %.4f\n", f, sin(f)); 13 | } 14 | 15 | return 0; 16 | } 17 | 18 | /* from http://codereview.stackexchange.com/questions/5211/sine-function-in-c-c */ 19 | float sin(float x) 20 | { 21 | float x2 = x*x; 22 | float x4 = x2*x2; 23 | 24 | float t1 = x * (1.0f - x2 / (2*3)); 25 | float x5 = x * x4; 26 | float t2 = x5 * (1.0f - x2 / (6*7)) / (1.0f* 2*3*4*5); 27 | float x9 = x5 * x4; 28 | float t3 = x9 * (1.0f - x2 / (10*11)) / (1.0f* 2*3*4*5*6*7*8*9); 29 | float x13 = x9 * x4; 30 | float t4 = x13 * (1.0f - x2 / (14*15)) / (1.0f* 2*3*4*5*6*7*8*9*10*11*12*13); 31 | 32 | float result = t4; 33 | result += t3; 34 | result += t2; 35 | result += t1; 36 | 37 | return result; 38 | } 39 | -------------------------------------------------------------------------------- /validation/sudoku.c: -------------------------------------------------------------------------------- 1 | /* from http://codereview.stackexchange.com/questions/37430/sudoku-solver-in-c */ 2 | 3 | #include 4 | 5 | int isAvailable(int puzzle[][9], int row, int col, int num) 6 | { 7 | int rowStart = (row/3) * 3; 8 | int colStart = (col/3) * 3; 9 | int i, j; 10 | 11 | for(i=0; i<9; ++i) 12 | { 13 | if (puzzle[row][i] == num) return 0; 14 | if (puzzle[i][col] == num) return 0; 15 | if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0; 16 | } 17 | return 1; 18 | } 19 | 20 | int fillSudoku(int puzzle[][9], int row, int col) 21 | { 22 | int i; 23 | if(row<9 && col<9) 24 | { 25 | if(puzzle[row][col] != 0) 26 | { 27 | if((col+1)<9) return fillSudoku(puzzle, row, col+1); 28 | else if((row+1)<9) return fillSudoku(puzzle, row+1, 0); 29 | else return 1; 30 | } 31 | else 32 | { 33 | for(i=0; i<9; ++i) 34 | { 35 | if(isAvailable(puzzle, row, col, i+1)) 36 | { 37 | puzzle[row][col] = i+1; 38 | if((col+1)<9) 39 | { 40 | if(fillSudoku(puzzle, row, col +1)) return 1; 41 | else puzzle[row][col] = 0; 42 | } 43 | else if((row+1)<9) 44 | { 45 | if(fillSudoku(puzzle, row+1, 0)) return 1; 46 | else puzzle[row][col] = 0; 47 | } 48 | else return 1; 49 | } 50 | } 51 | } 52 | return 0; 53 | } 54 | else return 1; 55 | } 56 | 57 | int main() 58 | { 59 | int i, j; 60 | int puzzle[9][9]={{0, 0, 0, 0, 0, 0, 0, 9, 0}, 61 | {1, 9, 0, 4, 7, 0, 6, 0, 8}, 62 | {0, 5, 2, 8, 1, 9, 4, 0, 7}, 63 | {2, 0, 0, 0, 4, 8, 0, 0, 0}, 64 | {0, 0, 9, 0, 0, 0, 5, 0, 0}, 65 | {0, 0, 0, 7, 5, 0, 0, 0, 9}, 66 | {9, 0, 7, 3, 6, 4, 1, 8, 0}, 67 | {5, 0, 6, 0, 8, 1, 0, 7, 4}, 68 | {0, 8, 0, 0, 0, 0, 0, 0, 0}}; 69 | 70 | if(fillSudoku(puzzle, 0, 0)) 71 | { 72 | printf("\n+-----+-----+-----+\n"); 73 | for(i=1; i<10; ++i) 74 | { 75 | for(j=1; j<10; ++j) printf("|%d", puzzle[i-1][j-1]); 76 | printf("|\n"); 77 | if (i%3 == 0) printf("+-----+-----+-----+\n"); 78 | } 79 | } 80 | else printf("\n\nNO SOLUTION\n\n"); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /validation/tictactoe.c: -------------------------------------------------------------------------------- 1 | /* from http://rosettacode.org/wiki/Tic-tac-toe#C */ 2 | 3 | #include 4 | #include 5 | 6 | int b[3][3]; /* board. 0: blank; -1: computer; 1: human */ 7 | 8 | int check_winner() 9 | { 10 | int i; 11 | for (i = 0; i < 3; i++) { 12 | if (b[i][0] && b[i][1] == b[i][0] && b[i][2] == b[i][0]) 13 | return b[i][0]; 14 | if (b[0][i] && b[1][i] == b[0][i] && b[2][i] == b[0][i]) 15 | return b[0][i]; 16 | } 17 | if (!b[1][1]) return 0; 18 | 19 | if (b[1][1] == b[0][0] && b[2][2] == b[0][0]) return b[0][0]; 20 | if (b[1][1] == b[2][0] && b[0][2] == b[1][1]) return b[1][1]; 21 | 22 | return 0; 23 | } 24 | 25 | void showboard() 26 | { 27 | const char *t = "X O"; 28 | int i, j; 29 | for (i = 0; i < 3; i++, putchar('\n')) 30 | for (j = 0; j < 3; j++) 31 | printf("%c ", t[ b[i][j] + 1 ]); 32 | printf("-----\n"); 33 | } 34 | 35 | #define for_ij for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) 36 | int best_i, best_j; 37 | int test_move(int val, int depth) 38 | { 39 | int i, j, score; 40 | int best = -1, changed = 0; 41 | 42 | if ((score = check_winner())) return (score == val) ? 1 : -1; 43 | 44 | for_ij { 45 | if (b[i][j]) continue; 46 | 47 | changed = b[i][j] = val; 48 | score = -test_move(-val, depth + 1); 49 | b[i][j] = 0; 50 | 51 | if (score <= best) continue; 52 | if (!depth) { 53 | best_i = i; 54 | best_j = j; 55 | } 56 | best = score; 57 | } 58 | 59 | return changed ? best : 0; 60 | } 61 | 62 | const char* game(int user) 63 | { 64 | int i, j, k, move, win = 0; 65 | for_ij b[i][j] = 0; 66 | 67 | printf("Board postions are numbered so:\n1 2 3\n4 5 6\n7 8 9\n"); 68 | printf("You have O, I have X.\n\n"); 69 | for (k = 0; k < 9; k++, user = !user) { 70 | while(user) { 71 | printf("your move: "); 72 | if (!scanf("%d", &move)) { 73 | scanf("%*s"); 74 | continue; 75 | } 76 | if (--move < 0 || move >= 9) continue; 77 | if (b[i = move / 3][j = move % 3]) continue; 78 | 79 | b[i][j] = 1; 80 | break; 81 | } 82 | if (!user) { 83 | if (!k) { /* randomize if computer opens, less boring */ 84 | best_i = rand() % 3; 85 | best_j = rand() % 3; 86 | } else 87 | test_move(-1, 0); 88 | 89 | b[best_i][best_j] = -1; 90 | printf("My move: %d\n", best_i * 3 + best_j + 1); 91 | } 92 | 93 | showboard(); 94 | if ((win = check_winner())) 95 | return win == 1 ? "You win.\n\n": "I win.\n\n"; 96 | } 97 | return "A draw.\n\n"; 98 | } 99 | 100 | int main() 101 | { 102 | int first = 0; 103 | while (1) printf("%s", game(first = !first)); 104 | return 0; 105 | } 106 | --------------------------------------------------------------------------------