packages feed

crypton-2.1.3: cbits/tests/width/run.sh

#!/bin/sh
# The three implementations that only a 32-bit architecture receives, asked
# the same questions as the 64-bit ones they stand in for.
#
#   cbits/include32/p256          against  cbits/include64/p256
#   cbits/curve25519-donna.c      against  curve25519-donna-c64.c
#   cbits/decaf/p448/arch_32      against  cbits/decaf/p448/arch_ref64
#
# No job in the matrix is 32-bit, so until this ran, none of the left column
# had ever been compiled, let alone executed.  The two sides of each pair
# define the same symbols, so they cannot share a binary: each driver is built
# twice and the two outputs compared.
#
# With a compiler that can target 32-bit x86 -- gcc-multilib on the Linux
# runner -- the 32-bit side is built a second time as a real 32-bit binary,
# which is the only way to see what the narrower int, size_t and pointer do.
#
# Usage: cbits/tests/width/run.sh [build-dir]
set -eu

root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)
out=${1:-$(mktemp -d)}
cc=${CC:-cc}
mkdir -p "$out"
cd "$root"

D=cbits/decaf
decaf_common="$D/ed448goldilocks/decaf_all.c $D/ed448goldilocks/eddsa.c
              $D/ed448goldilocks/scalar.c $D/p448/f_arithmetic.c
              $D/p448/f_generic.c $D/utils.c cbits/crypton_sha3.c"

# name, the flags and sources for the 64-bit side, then for the 32-bit side
build() {
	# shellcheck disable=SC2086
	$cc -O2 -Wno-deprecated-declarations $EXTRA -o "$out/$1" $2 2>&1 |
		grep -vE "^$|deprecated" || true
	test -x "$out/$1" || { echo "did not build: $1"; exit 1; }
}

status=0
compare() {
	if cmp -s "$out/$1.txt" "$out/$2.txt"; then
		echo "ok   $3 ($(wc -l < "$out/$1.txt" | tr -d ' ') lines)"
	else
		echo "FAIL $3"
		diff "$out/$1.txt" "$out/$2.txt" | head -20
		status=1
	fi
}

for width in 64 32; do
	case $width in
	64) p256_inc=cbits/include64; donna=cbits/curve25519/curve25519-donna-c64.c; arch=arch_ref64 ;;
	32) p256_inc=cbits/include32; donna=cbits/curve25519/curve25519-donna.c;     arch=arch_32    ;;
	esac

	# decaf decides its word size twice and from two different things: the
	# field limbs from ARCH_WORD_BITS, which follows the arch directory
	# picked above, and the scalar limbs from CRYPTON_DECAF_WORD_BITS, which
	# common.h reads off the host compiler.  On a 32-bit machine -- the only
	# place cabal asks for arch_32 -- both come out 32.  Here the host is
	# 64-bit whichever side is being built, so say which is wanted rather
	# than compile a half-32-bit-half-64-bit library and compare that.

	EXTRA="-Icbits -I$p256_inc"
	build "p256_$width" "cbits/tests/width/p256_width.c cbits/p256/p256.c cbits/p256/p256_ec.c"

	EXTRA="-Icbits"
	build "x25519_$width" "cbits/tests/width/x25519_width.c $donna"

	EXTRA="-DCRYPTON_DECAF_WORD_BITS=$width -Icbits -I$D/include -I$D/p448 -I$D/include/$arch -I$D/p448/$arch"
	build "ed448_$width" "cbits/tests/width/ed448_width.c $decaf_common $D/p448/$arch/f_impl.c"

	for t in p256 x25519 ed448; do
		"$out/${t}_$width" > "$out/${t}_$width.txt"
	done
done

for t in p256 x25519 ed448; do
	compare "${t}_64" "${t}_32" "$t: the 32-bit implementation answers what the 64-bit one answers"
done

# The same sources again, this time actually narrow.  Only the 32-bit side is
# tried: the 64-bit P-256 wants __uint128_t, which a 32-bit target has not got,
# which is the whole reason the 32-bit side exists.
printf 'int main(void){return 0;}\n' > "$out/probe.c"
if $cc -m32 -o "$out/probe" "$out/probe.c" 2>/dev/null && "$out/probe"; then
	EXTRA="-m32 -Icbits -Icbits/include32"
	build p256_m32 "cbits/tests/width/p256_width.c cbits/p256/p256.c cbits/p256/p256_ec.c"
	EXTRA="-m32 -Icbits"
	build x25519_m32 "cbits/tests/width/x25519_width.c cbits/curve25519/curve25519-donna.c"
	EXTRA="-m32 -DCRYPTON_DECAF_WORD_BITS=32 -Icbits -I$D/include -I$D/p448 -I$D/include/arch_32 -I$D/p448/arch_32"
	build ed448_m32 "cbits/tests/width/ed448_width.c $decaf_common $D/p448/arch_32/f_impl.c"

	for t in p256 x25519 ed448; do
		"$out/${t}_m32" > "$out/${t}_m32.txt"
		compare "${t}_32" "${t}_m32" "$t: a 32-bit host answers what a 64-bit host answers"
	done
else
	echo "skip $cc cannot build and run a 32-bit binary here; the comparison above still ran"
fi

exit $status