-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add simple limb overflow checker for Poly1305
Monocypher now grabs at the graal of Formal Verification. It is very crude, but it works for Poly1305. Just transliterate the C program into Python, add some preconditions and asserts, and execute the result as Python to prove the absence of overflow (provided the preconditions are correct). ECC code might be more difficult, we'll see. See #246
- Loading branch information
1 parent
2d3738d
commit 9a49a3d
Showing
6 changed files
with
119 additions
and
7 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
*.includes | ||
*.su | ||
*.su.* | ||
*.gen.* | ||
tests/formal-analysis/* | ||
tests/formal-analysis | ||
*.tar.gz | ||
|
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#! /bin/env sh | ||
|
||
echo "#! /bin/env python3" | ||
echo "from overflow import *" | ||
echo "" | ||
sed -n "/PROOF $1/,/CQFD $1/p" |\ | ||
sed '1d;$d' |\ | ||
sed 's| ||' |\ | ||
sed 's|//- ||' |\ | ||
sed 's|^.*//-.*$||' |\ | ||
sed 's| *//.*||' |\ | ||
sed 's|//|#|' |\ | ||
sed 's|const ||' |\ | ||
sed 's|;||' |\ | ||
sed 's|ctx->|ctx_|' |\ | ||
sed 's|\[|_|g' |\ | ||
sed 's|\]||g' |\ | ||
sed 's|(\([a-zA-Z0-9_]*\))\([a-zA-Z0-9_]*\)|\1(\2)|g' |\ | ||
sed 's|^\([a-zA-Z0-9_]*\) \([a-zA-Z0-9_]*\) = \(.*\)$|\2 = \1(\3)|' |\ | ||
sed 's|\* \([0-9][0-9]*\)|\* cast(\1)|g' |\ | ||
sed 's|\+ \([0-9][0-9]*\)|\+ cast(\1)|g' |\ | ||
sed 's|\- \([0-9][0-9]*\)|\- cast(\1)|g' |\ | ||
cat |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
|
||
def number(limit, overflow): | ||
if limit > overflow: | ||
raise AssertionError("limit exceeds overflow", limit, overflow) | ||
return (limit, overflow) | ||
|
||
def add (a, b): return number(a[0] + b[0], max(a[1], b[1])) | ||
def sub (a, b): return number(a[0] + b[0], max(a[1], b[1])) # still + | ||
def mul (a, b): return number(a[0] * b[0], max(a[1], b[1])) | ||
def rshift(a, n): return number(a[0] >> n, a[1]) | ||
def lshift(a, n): return number(a[0] << n, a[1]) | ||
def b_and (a, n): return number(a[0] & n, a[1]) | ||
|
||
inttype = int #we're overriding int down the line | ||
def cast(n): | ||
if type(n) is inttype: | ||
return Number(number(n, 2**16-1)) | ||
return n | ||
|
||
class Number: | ||
def __init__ (self, num ): self.num = num | ||
def limit (self) : return self.num[0] | ||
def overflow (self) : return self.num[1] | ||
def __add__ (self, other): return Number(add(self.num, cast(other.num))) | ||
def __sub__ (self, other): return Number(sub(self.num, cast(other.num))) | ||
def __mul__ (self, other): return Number(mul(self.num, cast(other.num))) | ||
def __rshift__(self, n) : return Number(rshift(self.num, n)) | ||
def __lshift__(self, n) : return Number(lshift(self.num, n)) | ||
def __and__ (self, n) : return Number(b_and (self.num, n)) | ||
def __str__(self): return "Number(" + str(self.num) + ")" | ||
|
||
def make(num, limit, overflow): | ||
if num is not None: | ||
limit = num.limit() | ||
return Number(number(limit, overflow)) | ||
|
||
def u16(num=None, limit = 2**16-1): return make(num, limit, 2**16-1) | ||
def u32(num=None, limit = 2**32-1): return make(num, limit, 2**32-1) | ||
def u64(num=None, limit = 2**64-1): return make(num, limit, 2**64-1) | ||
unsigned = u16 | ||
|
||
def i16(num=None, limit = 2**15-1): return make(num, limit, 2**15-1) | ||
def i32(num=None, limit = 2**31-1): return make(num, limit, 2**31-1) | ||
def i64(num=None, limit = 2**63-1): return make(num, limit, 2**63-1) | ||
int = i16 | ||
|
||
def ASSERT(truth): | ||
if not truth: | ||
raise AssertionError("ASSERT failed") |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#! /bin/env sh | ||
|
||
set -e | ||
|
||
DIR=$(dirname "$0") | ||
|
||
POLY=$DIR/poly1305.gen.py | ||
|
||
echo "Check limb overflow: $POLY" | ||
$DIR/filter.sh Poly1305 <$DIR/../../src/monocypher.c >$POLY | ||
python3 $DIR/poly1305.gen.py | ||
|
||
echo "No limb overflow detected" |