Created
December 17, 2014 20:19
-
-
Save loreb/fb52824e296b2cfbd100 to your computer and use it in GitHub Desktop.
abomination: Spritz/RS14 in portable /bin/sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/sh | |
# "Spritz - a spongy RC4-like stream cipher and hash function" | |
# http://people.csail.mit.edu/rivest/pubs/RS14.bib.txt | |
# In case you're insane enough to use it, keep in mind that the registers | |
# (i,j,...) have NO PREFIX, so you'll have to add it(_spritz_i, ...). | |
# This script is meant to run on any POSIX shell with local variables | |
# ("local" is not included in POSIX. Idiots!) and POSIX commands (printf(1)). | |
# Bash,dash,mksh,zsh: see how fast they Absorb()/Drip() compared to vim... | |
# seq(1) is from plan9; linux/freebsd have it, openbsd does not. | |
seq() { | |
# zsh, seq 512: "job table full or recursion limit exceeded" | |
test $# -eq 1 && { seq 0 $1; return; } | |
test $# -eq 2 || { echo>&2 "seq!"; exit 100; } | |
test $1 -ge $2 || { echo $1; seq $((1 + $1)) $2; } | |
} | |
seq() { | |
test $# -eq 1 && { seq 0 $1; return; } | |
test $# -eq 2 || { echo>&2 "seq!"; exit 100; } | |
local n=$1 | |
while [ $n -lt $2 ] ; do echo $n; n=$(($n + 1)) ; done | |
} | |
Swap() { | |
# S is implicit, params are the two indexes | |
local temp | |
eval "temp=\$S$1" | |
eval "S$1=\$S$2" | |
eval "S$2=$temp" | |
} | |
InitializeState() { | |
i=0 | |
j=0 | |
k=0 | |
z=0 | |
a=0 | |
w=1 | |
for v in $(seq 256) ; do | |
eval S"$v=$v" | |
done | |
} | |
Absorb() { | |
for v in "$@" ; do | |
AbsorbByte $v | |
done | |
} | |
AbsorbByte() { | |
AbsorbNibble $((0xF & $1)) | |
AbsorbNibble $((0xF & ($1 >> 4) )) | |
} | |
AbsorbNibble() { | |
if [ $a -eq 128 ] ; then | |
Shuffle | |
fi | |
Swap $a $((128 + $1)) | |
a=$(($a + 1)) | |
} | |
AbsorbStop() { | |
if [ $a -eq 128 ] ; then | |
Shuffle | |
fi | |
a=$(($a + 1)) | |
} | |
Shuffle() { | |
Whip 512 | |
Crush | |
Whip 512 | |
Crush | |
Whip 512 | |
a=0 | |
} | |
Whip() { | |
for v in $(seq $1) ; do | |
Update | |
done | |
w=$(($w + 2)) | |
w=$(($w & 0xFF)) | |
} | |
Crush() { | |
for v in $(seq 128) ; do | |
# if $[v] > S[N-1-v] | |
local N1v=$((256 - 1 - $v)) | |
eval "test \$S$v -gt \$S$N1v" && Swap $v $N1v | |
done | |
} | |
# Squeeze() in /bin/sh is too ugly, even for me. | |
Drip() { | |
if [ $a -gt 0 ] ; then | |
Shuffle | |
fi | |
Update | |
# z = S[j + S[i + S[z + k]]] | |
local Szk | |
zk=$((0xFF & ($z+$k) )) | |
eval "Szk=\$S$zk" | |
local iS=$((0xFF & ($i + $Szk) )) | |
local Si | |
eval "Si=\$S$iS" | |
local jS=$((0xFF & ($j + $Si) )) | |
eval "z=\$S$jS" | |
return $z # POSIX says this is ok. | |
} | |
Update() { | |
i=$((0xFF & ($i + $w) )) | |
# j = 0xFF &(k + S[0xFF &(j + S[i])]); | |
eval "local jSi=\$(($j + \$S$i))" ; jSi=$((0xFF & $jSi)) | |
eval "local SjSi=\$S$jSi" | |
j=$((0xFF & ($k + $SjSi) )) | |
# k = 0xFF &(i + k + S[j]); | |
eval "local Sj=\$S$j" | |
k=$((0xFF & ($i + $k + $Sj) )) | |
Swap $i $j | |
} | |
# "If the value of n is greater than 255, the results are undefined" | |
retcheck() { | |
return $1 | |
} | |
for i in $(seq 256) ; do | |
retcheck $i | |
j=$? | |
test $i = $j&&continue | |
echo>&2 "canthappen: return $i yields $j..." | |
exit 123 | |
done | |
if [ x"$NDEBUG" = x ] ; then | |
echo "Checking Spritz/RS14 test vectors..." | |
# Test stream cipher | |
InitializeState | |
Absorb 0x41 0x42 0x43 # "ABC" | |
for byte in q w e r t y u i ; do | |
Drip | |
printf %02x $? | |
done | |
echo | |
echo '77 9a 8e 01 f9 e9 cb c0 ... # streamcipher("ABC")' | |
# Test hash function | |
InitializeState | |
Absorb 0x41 0x42 0x43 # "ABC" | |
AbsorbStop | |
Absorb 32 # 256 bit => 32 bytes, as specified in the paper. | |
for byte in q w e r t y u i ; do | |
Drip | |
printf %02x $? | |
done | |
echo | |
echo '02 8f a2 b4 8b 93 4a 18 ... # hash("ABC")' | |
fi | |
# Reset ^^ | |
InitializeState | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment