pynacl

Python wrapper for http://nacl.cace-project.eu/
git clone https://code.literati.org/pynacl.git
Log | Files | Refs | README

commit ac2efbd18f31ab81c6f2e61b9cbfdf705172dde7
parent 60a2c434e29682b1d6da76c511ad6f04d049ca8e
Author: Sean Lynch <seanl@literati.org>
Date:   Mon, 13 Jun 2011 22:35:15 -0700

Add auth and onetimeauth functions.

Diffstat:
MREADME.md | 6+++---
Mnacl.i | 46++++++++++++++++++++++++++++++++++++++++++++++
Mtest.py | 31+++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md @@ -7,8 +7,8 @@ Overview This is a simple wrapper for the [NaCl](http://nacl.cace-project.eu/) cryptographic library (not Google's NativeClient). It currently wraps crypto\_hash\_sha256, crypto\_hash\_sha512, crypto\_randombytes, and -the crypto\_box, crypto\_sign, crypto\_secretbox, and crypto\_stream -default primitives. +the crypto\_box, crypto\_sign, crypto\_secretbox, crypto\_stream, +crypto\_auth, and crypto\_onetimeauth default primitives. API @@ -32,7 +32,7 @@ First, download and build NaCl. Then: export NACL_LIB=<location of libnacl.a and randombytes.o, required> export NACL_INCLUDE=<location of NaCl header files> - python setup.py build_ext + python setup.py build sudo python setup.py install diff --git a/nacl.i b/nacl.i @@ -237,6 +237,18 @@ } /** + * Auth typemaps + */ +%typemap(out) int crypto_auth_verify, int crypto_onetimeauth_verify { + if ($1 == 0) { + $result = Py_True; + } else { + $result = Py_False; + } + Py_INCREF($result); +} + +/** * Utilities */ void randombytes(unsigned char *buffer, unsigned long long bytes); @@ -361,3 +373,37 @@ int crypto_stream_xor(unsigned char *c, const unsigned char *in, unsigned long long clen, const unsigned char n[crypto_stream_NONCEBYTES], const unsigned char k[crypto_stream_KEYBYTES]); + + +/** + * Authentication + */ +%constant int crypto_auth_BYTES; +%constant int crypto_auth_KEYBYTES; +%constant char *crypto_auth_PRIMITIVE; +%constant char *crypto_auth_IMPLEMENTATION; +%constant char *crypto_auth_VERSION; + +int crypto_auth(unsigned char a[crypto_auth_BYTES], const unsigned char *m, + unsigned long long mlen, + const unsigned char k[crypto_auth_KEYBYTES]); +int crypto_auth_verify(const unsigned char a[crypto_auth_BYTES], + const unsigned char *m, unsigned long long mlen, + const unsigned char k[crypto_auth_KEYBYTES]); + + +/** + * One-time authentication + */ +%constant int crypto_onetimeauth_BYTES; +%constant int crypto_onetimeauth_KEYBYTES; +%constant char *crypto_onetimeauth_PRIMITIVE; +%constant char *crypto_onetimeauth_IMPLEMENTATION; +%constant char *crypto_onetimeauth_VERSION; + +int crypto_onetimeauth(unsigned char a[crypto_onetimeauth_BYTES], + const unsigned char *m, unsigned long long mlen, + const unsigned char k[crypto_onetimeauth_KEYBYTES]); +int crypto_onetimeauth_verify(const unsigned char a[crypto_onetimeauth_BYTES], + const unsigned char *m, unsigned long long mlen, + const unsigned char k[crypto_onetimeauth_KEYBYTES]); diff --git a/test.py b/test.py @@ -162,5 +162,36 @@ class StreamTestCase(unittest.TestCase): self.assertEqual(m, self.msg) +class AuthTestCaseMixin(object): + msg = "The quick brown fox jumps over the lazy dog." + def attr(self, a): + return getattr(nacl, 'crypto_{0}{1}'.format(self.name, a)) + + def setUp(self): + self.k = nacl.randombytes(self.attr('_KEYBYTES')) + self.auth = self.attr('') + self.verify = self.attr('_verify') + + def test_auth(self): + a = self.auth(self.msg, self.k) + self.assertTrue(self.verify(a, self.msg, self.k)) + + def test_badkey(self): + a = self.auth(self.msg, perturb(self.k)) + self.assertFalse(self.verify(a, self.msg, self.k)) + + def test_badmsg(self): + a = self.auth(self.msg, self.k) + self.assertFalse(self.verify(perturb(a), self.msg, self.k)) + + +class AuthTestCase(AuthTestCaseMixin, unittest.TestCase): + name = 'auth' + + +class OneTimeAuthTestCase(AuthTestCaseMixin, unittest.TestCase): + name = 'onetimeauth' + + if __name__ == '__main__': unittest.main()