-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ian Harvey
committed
May 28, 2014
1 parent
bae88af
commit 2dd6d73
Showing
7 changed files
with
698 additions
and
9 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 |
---|---|---|
@@ -0,0 +1,258 @@ | ||
import random, os | ||
|
||
class TestVector: | ||
|
||
@staticmethod | ||
def toWords(val, nWords): | ||
assert( val >= 0 ) | ||
assert( val < (1 << (nWords*32)) ) | ||
return [ (val >> (i*32)) & 0xFFFFFFFF for i in range(nWords) ] | ||
|
||
@staticmethod | ||
def toC(val, nWords): | ||
return "{ {" + (",".join(["0x%08X" % w for w in TestVector.toWords(val, nWords)])) + "} }" | ||
|
||
@staticmethod | ||
def toStruct(items): | ||
res = " {\n" | ||
res += ",\n".join([" " + i for i in items]) | ||
res += "\n },\n\n" | ||
return res | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def writeFile(self, filename): | ||
count = 0 | ||
with open(filename, "w") as fout: | ||
fout.write(self.file_header()) | ||
for tv in self.generateTestVectors(): | ||
fout.write(self.convert(tv)) | ||
count += 1 | ||
fout.write(self.file_footer()) | ||
print "Wrote", filename, "(", count, "vectors )" | ||
|
||
def file_header(self): | ||
return "/* AUTOGENERATED - do not edit */\n" | ||
|
||
def file_footer(self): | ||
return "" | ||
|
||
def convert(self, tv): | ||
(inA, inB, res) = [ TestVector.toC(val, 8) for val in tv ] | ||
return TestVector.toStruct([inA, inB, res]) | ||
|
||
|
||
class MulTestVectors(TestVector): | ||
def __init__(self): | ||
self.inputs = [ | ||
0, | ||
1, | ||
0xFFFF, | ||
0x10000, | ||
0xFFFF0000, | ||
0xFFFFFFFF, | ||
(1 << 32), | ||
random.getrandbits(64), | ||
(1 << 128)-1, | ||
random.getrandbits(160), | ||
(1<<224) - 1, | ||
random.getrandbits(256), | ||
(1<<256) - 1 | ||
] | ||
|
||
def convert(self, tv): | ||
(inA, inB, res) = tv | ||
return TestVector.toStruct([ | ||
TestVector.toC(inA, 8), | ||
TestVector.toC(inB, 8), | ||
TestVector.toC(res, 16) | ||
]) | ||
|
||
def generateTestVectors(self): | ||
for i in range(len(self.inputs)): | ||
for j in range(i+1): | ||
x = self.inputs[i] | ||
y = self.inputs[j] | ||
res = x*y | ||
yield( (x,y,res) ) | ||
|
||
class AddTestVectors(TestVector): | ||
def __init__(self): | ||
self.inputs = [ | ||
0x0001, | ||
0x10000, | ||
0xFFFE, | ||
0xFFFF, | ||
random.getrandbits(32), | ||
0xFFFFFFFFF, | ||
random.getrandbits(64), | ||
(1<<255)-1, | ||
random.getrandbits(256), | ||
random.getrandbits(256), | ||
(1<<256)-1 | ||
] | ||
|
||
def convert(self, tv): | ||
(inA, inB, res, carry) = tv | ||
return TestVector.toStruct([ | ||
TestVector.toC(inA, 8), | ||
TestVector.toC(inB, 8), | ||
TestVector.toC(res, 8), | ||
"%d" % carry | ||
]) | ||
|
||
def generateTestVectors(self): | ||
nvals = len(self.inputs) | ||
for i in range(nvals): | ||
for j in range(i+1): | ||
x = self.inputs[i] | ||
y = self.inputs[j] | ||
res = x+y | ||
carry = 1 if (res >= (1 << 256)) else 0 | ||
res -= (carry << 256) | ||
yield( (x,y,res,carry) ) | ||
|
||
class SubTestVectors(TestVector): | ||
def __init__(self): | ||
self.inputs = [ | ||
0x0, | ||
0x1, | ||
0xFFFE, | ||
0xFFFF, | ||
random.getrandbits(32), | ||
0xFFFFFFFFF, | ||
random.getrandbits(64), | ||
(1<<255)-1, | ||
random.getrandbits(256), | ||
random.getrandbits(256), | ||
(1<<256)-1 | ||
] | ||
|
||
def convert(self, tv): | ||
(inA, inB, res, carry) = tv | ||
return TestVector.toStruct([ | ||
TestVector.toC(inA, 8), | ||
TestVector.toC(inB, 8), | ||
TestVector.toC(res, 8), | ||
"0x%X" % carry | ||
]) | ||
|
||
def generateTestVectors(self): | ||
nvals = len(self.inputs) | ||
for i in range(nvals): | ||
for j in range(nvals): | ||
x = self.inputs[i] | ||
y = self.inputs[j] | ||
res = x-y | ||
if (res < 0): | ||
res += (1 << 256) | ||
carry = 0xFFFFFFFF | ||
else: | ||
carry = 0 | ||
yield( (x,y,res,carry) ) | ||
|
||
F25519 = (1 << 255)-19 | ||
|
||
F25519_elements = [ | ||
# Not a complete list ;-) | ||
0x0, | ||
0x1, | ||
random.getrandbits(32), | ||
0x80000000, | ||
(1<<127)-1, | ||
random.getrandbits(256) % F25519, | ||
random.getrandbits(256) % F25519, | ||
F25519-0x80000000, | ||
F25519-1, | ||
] | ||
|
||
class F25519AddTestVectors(TestVector): | ||
def __init__(self): | ||
pass | ||
|
||
def generateTestVectors(self): | ||
for i in range(len(F25519_elements)): | ||
for j in range(i+1): | ||
x = F25519_elements[i] | ||
y = F25519_elements[j] | ||
res = (x + y) % F25519 | ||
yield( (x,y,res) ) | ||
|
||
class F25519SubTestVectors(TestVector): | ||
def __init__(self): | ||
pass | ||
|
||
def generateTestVectors(self): | ||
for i in range(len(F25519_elements)): | ||
for j in range(len(F25519_elements)): | ||
x = F25519_elements[i] | ||
y = F25519_elements[j] | ||
res = (x - y) % F25519 | ||
yield( (x,y,res) ) | ||
|
||
class F25519MulTestVectors(TestVector): | ||
def __init__(self): | ||
pass | ||
|
||
def generateTestVectors(self): | ||
for i in range(len(F25519_elements)): | ||
for j in range(i+1): | ||
x = F25519_elements[i] | ||
y = F25519_elements[j] | ||
res = (x * y) % F25519 | ||
yield( (x,y,res) ) | ||
|
||
|
||
class Curve25519TestVectors(TestVector): | ||
baseP = chr(0x09) + (chr(0) * 31) | ||
|
||
def __init__(self, referenceImplFn): | ||
self.curveFn = referenceImplFn | ||
|
||
@staticmethod | ||
def toC(v): | ||
assert(len(v)==32) | ||
return "{ {" + (",".join([hex(ord(ch)) for ch in v])) + "} }" | ||
|
||
def convert(self, tv): | ||
return self.toStruct([self.toC(v) for v in tv]) | ||
|
||
def doKAT(self, a, P): | ||
aP = self.curveFn(a, P) | ||
return (a, P, aP) | ||
|
||
def generateTestVectors(self): | ||
# Checks of LSB operation | ||
for b0 in [ 0x01, 0x02, 0x04, 0x08, 0x10, 0x80 ]: | ||
yield(self.doKAT( chr(b0) + (chr(0)*31), self.baseP )) | ||
|
||
# Checks of high single bits | ||
for bN in [ 0x01, 0x02, 0x04, 0x21, 0x41, 0x81 ]: | ||
yield(self.doKAT( (chr(0)*31) + chr(bN), self.baseP )) | ||
|
||
# Simulate DH key generation and exchange | ||
|
||
for i in range(5): | ||
privA = os.urandom(32) | ||
pubA = self.curveFn(privA, self.baseP) | ||
yield(self.doKAT( privA, self.baseP )) | ||
|
||
privB = os.urandom(32) | ||
pubB = self.curveFn(privB, self.baseP) | ||
yield(self.doKAT( privB, self.baseP )) | ||
|
||
yield(self.doKAT (privA, pubB)) | ||
yield(self.doKAT (privB, pubA)) | ||
|
||
|
||
if __name__ == '__main__': | ||
#MulTestVectors().writeFile("mpimul.inc") | ||
#AddTestVectors().writeFile("mpiadd.inc") | ||
#SubTestVectors().writeFile("mpisub.inc") | ||
#F25519AddTestVectors().writeFile("f25519add.inc") | ||
#F25519SubTestVectors().writeFile("f25519sub.inc") | ||
#F25519MulTestVectors().writeFile("f25519mul.inc") | ||
import curve25519 | ||
Curve25519TestVectors(curve25519.curve25519).writeFile("curve25519.inc") | ||
|
Oops, something went wrong.