summaryrefslogtreecommitdiff
path: root/src/pycryptopp/test/test_ed25519.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pycryptopp/test/test_ed25519.py')
-rw-r--r--src/pycryptopp/test/test_ed25519.py148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/pycryptopp/test/test_ed25519.py b/src/pycryptopp/test/test_ed25519.py
new file mode 100644
index 0000000..6e530ab
--- /dev/null
+++ b/src/pycryptopp/test/test_ed25519.py
@@ -0,0 +1,148 @@
+
+import unittest
+import time
+from binascii import hexlify, unhexlify
+from pycryptopp.publickey import ed25519
+from pycryptopp.publickey.ed25519 import _ed25519 as raw
+
+def flip_bit(s, bit=0, in_byte=-1):
+ as_bytes = [ord(b) for b in s]
+ as_bytes[in_byte] = as_bytes[in_byte] ^ (0x01<<bit)
+ return "".join([chr(b) for b in as_bytes])
+
+# the pure-python demonstration code (on my 2010 MacBookPro) takes 5s to
+# generate a public key, 9s to sign, 14s to verify
+
+# the SUPERCOP-ref version we use takes 2ms for keygen, 2ms to sign, and 7ms
+# to verify
+
+class Basic(unittest.TestCase):
+ timer = None
+ def log(self, msg):
+ return
+ now = time.time()
+ if self.timer is None:
+ self.timer = now
+ else:
+ elapsed = now - self.timer
+ self.timer = now
+ print " (%f elapsed)" % elapsed
+ print msg
+
+ def test_version(self):
+ # just make sure it can be retrieved
+ ver = ed25519.__version__
+ self.failUnless(isinstance(ver, type("")))
+
+ def test_constants(self):
+ # the secret key we get from raw.keypair() are 64 bytes long, and
+ # are mostly the output of a sha512 call. The first 32 bytes are the
+ # private exponent (random, with a few bits stomped).
+ self.failUnlessEqual(raw.SECRETKEYBYTES, 64)
+ # the public key is the encoded public point
+ self.failUnlessEqual(raw.PUBLICKEYBYTES, 32)
+ self.failUnlessEqual(raw.SIGNATUREKEYBYTES, 64)
+
+ def test_raw(self):
+ sk_s = "\x00" * 32 # usually urandom(32)
+ vk_s, skvk_s = raw.publickey(sk_s)
+ self.failUnlessEqual(len(vk_s), 32)
+ exp_vks = unhexlify("3b6a27bcceb6a42d62a3a8d02a6f0d73"
+ "653215771de243a63ac048a18b59da29")
+ self.failUnlessEqual(vk_s, exp_vks)
+ self.failUnlessEqual(skvk_s[:32], sk_s)
+ self.failUnlessEqual(skvk_s[32:], vk_s)
+ msg = "hello world"
+ msg_and_sig = raw.sign(msg, skvk_s)
+ sig = msg_and_sig[:-len(msg)]
+ self.failUnlessEqual(len(sig), 64)
+ exp_sig = unhexlify("b0b47780f096ae60bfff8d8e7b19c36b"
+ "321ae6e69cca972f2ff987ef30f20d29"
+ "774b53bae404485c4391ddf1b3f37aaa"
+ "8a9747f984eb0884e8aa533386e73305")
+ self.failUnlessEqual(sig, exp_sig)
+ ret = raw.open(sig+msg, vk_s) # don't raise exception
+ self.failUnlessEqual(ret, msg)
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ sig+msg+".. NOT!", vk_s)
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ sig+flip_bit(msg), vk_s)
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ sig+msg, flip_bit(vk_s))
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ sig+msg, flip_bit(vk_s, in_byte=2))
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ flip_bit(sig)+msg, vk_s)
+ self.failUnlessRaises(raw.BadSignatureError,
+ raw.open,
+ flip_bit(sig, in_byte=33)+msg, vk_s)
+
+
+ def test_publickey(self):
+ sk_bytes = unhexlify("4ba96b0b5303328c7405220598a587c4"
+ "acb06ed9a9601d149f85400195f1ec3d")
+ sk = ed25519.SigningKey(sk_bytes)
+ self.failUnlessRaises(ValueError, ed25519.SigningKey, "wrong length")
+
+ vk_bytes = sk.get_verifying_key_bytes()
+ self.failUnlessEqual(hexlify(vk_bytes),
+ "a66d161e090652b054740748f059f92a"
+ "5b731f1c27b05571f6d942e4f8b7b264")
+
+ ed25519.VerifyingKey(vk_bytes)
+ self.failUnlessRaises(ValueError, ed25519.VerifyingKey, "wrong length")
+
+ def test_OOP(self):
+ sk_bytes = unhexlify("4ba96b0b5303328c7405220598a587c4"
+ "acb06ed9a9601d149f85400195f1ec3d")
+ sk = ed25519.SigningKey(sk_bytes)
+
+ self.failUnlessEqual(hexlify(sk.get_verifying_key_bytes()),
+ "a66d161e090652b054740748f059f92a"
+ "5b731f1c27b05571f6d942e4f8b7b264")
+ vk = ed25519.VerifyingKey(sk.get_verifying_key_bytes())
+
+ msg = "hello world"
+ sig = sk.sign(msg)
+ self.failUnlessEqual(len(sig), 64)
+ self.failUnlessEqual(hexlify(sig),
+ "6eaffe94f2972b35158b6aaa9b69c1da"
+ "97f0896aca29c41b1dd7b32e6c9e2ff6"
+ "76fc8d8b034709cdcc37d8aeb86bebfb"
+ "173ace3c319e211ea1d7e8d8884c1808")
+ self.failUnlessEqual(vk.verify(sig, msg), None) # also, don't throw
+ self.failUnlessRaises(ed25519.BadSignatureError,
+ vk.verify, sig, msg+".. NOT!")
+
+ def test_object_identity(self):
+ sk1_bytes = unhexlify("ef32972ae3f1252a5aa1395347ea008c"
+ "bd2fed0773a4ea45e2d2d06c8cf8fbd4")
+ sk2_bytes = unhexlify("3d550c158900b4c2922b6656d2f80572"
+ "89de4ee65043745179685ae7d29b944d")
+ sk1a = ed25519.SigningKey(sk1_bytes)
+ sk1b = ed25519.SigningKey(sk1_bytes)
+ sk2 = ed25519.SigningKey(sk2_bytes)
+ self.failUnlessEqual(sk1a, sk1b)
+ self.failIfEqual(sk1a, sk2)
+
+ vk1_bytes = sk1a.get_verifying_key_bytes()
+ self.failUnlessEqual(vk1_bytes, sk1b.get_verifying_key_bytes())
+ vk2_bytes = sk2.get_verifying_key_bytes()
+ vk1a = ed25519.VerifyingKey(vk1_bytes)
+ vk1b = ed25519.VerifyingKey(vk1_bytes)
+ vk2 = ed25519.VerifyingKey(vk2_bytes)
+ self.failUnlessEqual(vk1a, vk1b)
+ self.failIfEqual(vk1a, vk2)
+
+ # exercise compare-against-other-type
+ self.failIfEqual(sk2, "not a SigningKey")
+ self.failIfEqual(vk2, "not a VerifyingKey")
+
+
+if __name__ == '__main__':
+ unittest.main()