| 1 | #!/usr/bin/env python |
|---|
| 2 | |
|---|
| 3 | import random, re |
|---|
| 4 | import unittest |
|---|
| 5 | |
|---|
| 6 | from binascii import a2b_hex, b2a_hex |
|---|
| 7 | from pkg_resources import resource_string |
|---|
| 8 | |
|---|
| 9 | from pycryptopp.cipher import xsalsa |
|---|
| 10 | TEST_XSALSA_RE=re.compile("\nCOUNT=([0-9]+)\nKEY=([0-9a-f]+)\nIV=([0-9a-f]+)\nPLAINTEXT=([0-9a-f]+)\nCIPHERTEXT=([0-9a-f]+)") |
|---|
| 11 | |
|---|
| 12 | class XSalsaTest(unittest.TestCase): |
|---|
| 13 | |
|---|
| 14 | enc0="eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c5e5585579625337bd3ab619d615760d8c5b224a85b1d0efe0eb8a7ee163abb0376529fcc09bab506c618e13ce777d82c3ae9d1a6f972d4160287cbfe60bf2130fc0a6ff6049d0a5c8a82f429231f0080" |
|---|
| 15 | |
|---|
| 16 | def test_zero_XSalsa(self): |
|---|
| 17 | key="1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389" |
|---|
| 18 | iv="69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37" |
|---|
| 19 | computedcipher=xsalsa.XSalsa(a2b_hex(key),a2b_hex(iv)).process('\x00'*139) |
|---|
| 20 | self.failUnlessEqual(a2b_hex(self.enc0), computedcipher, "enc0: %s, computedciper: %s" % (self.enc0, b2a_hex(computedcipher))) |
|---|
| 21 | |
|---|
| 22 | cryptor=xsalsa.XSalsa(a2b_hex(key),a2b_hex(iv)) |
|---|
| 23 | |
|---|
| 24 | computedcipher1=cryptor.process('\x00'*69) |
|---|
| 25 | computedcipher2=cryptor.process('\x00'*69) |
|---|
| 26 | computedcipher3=cryptor.process('\x00') |
|---|
| 27 | computedcipher12=b2a_hex(computedcipher1)+b2a_hex(computedcipher2)+b2a_hex(computedcipher3) |
|---|
| 28 | self.failUnlessEqual(self.enc0, computedcipher12) |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | def test_XSalsa(self): |
|---|
| 32 | # The test vector is from Crypto++'s TestVectors/salsa.txt, comment there is: |
|---|
| 33 | # Source: created by Wei Dai using naclcrypto-20090308 |
|---|
| 34 | # naclcrypto being DJB's crypto library and of course DJB designed XSalsa20 |
|---|
| 35 | curfile = open( '../testvectors/testx1.txt', 'r') |
|---|
| 36 | s = curfile.read() |
|---|
| 37 | print s,"\n" |
|---|
| 38 | return self._test_XSalsa(s) |
|---|
| 39 | |
|---|
| 40 | def _test_XSalsa(self, vects_str): |
|---|
| 41 | for mo in TEST_XSALSA_RE.finditer(vects_str): |
|---|
| 42 | count = int(mo.group(1)) |
|---|
| 43 | key = a2b_hex(mo.group(2)) |
|---|
| 44 | iv = a2b_hex(mo.group(3)) |
|---|
| 45 | # plaintext = a2b_hex(mo.group(4)) |
|---|
| 46 | # ciphertext= a2b_hex(mo.group(5)) |
|---|
| 47 | plaintext = mo.group(4) |
|---|
| 48 | ciphertext = mo.group(5) |
|---|
| 49 | computedcipher=xsalsa.XSalsa(key,iv).process(a2b_hex(plaintext)) |
|---|
| 50 | # print "ciphertext", b2a_hex(computedcipher), '\n' |
|---|
| 51 | # print "computedtext", ciphertext, '\n' |
|---|
| 52 | # print count, ": \n" |
|---|
| 53 | self.failUnlessEqual(computedcipher,a2b_hex(ciphertext),"computedcipher: %s, ciphertext: %s" % (b2a_hex(computedcipher), ciphertext)) |
|---|
| 54 | |
|---|
| 55 | #the random decomposing |
|---|
| 56 | plaintext1 = "" |
|---|
| 57 | plaintext2 = "" |
|---|
| 58 | length = len(plaintext) |
|---|
| 59 | rccipher = "" |
|---|
| 60 | cryptor = xsalsa.XSalsa(key,iv) |
|---|
| 61 | if length > 2: |
|---|
| 62 | point = random.randint(0,length-3) |
|---|
| 63 | if (point%2) !=0: |
|---|
| 64 | point -= 1 |
|---|
| 65 | plaintext1 += plaintext[:point+2] |
|---|
| 66 | plaintext2 += plaintext[point+2:] |
|---|
| 67 | rccipher += b2a_hex(cryptor.process(a2b_hex(plaintext1))) |
|---|
| 68 | rccipher += b2a_hex(cryptor.process(a2b_hex(plaintext2))) |
|---|
| 69 | self.failUnlessEqual(rccipher, ciphertext, "random computed cipher: %s, ciphertext: %s" % (rccipher, ciphertext)) |
|---|
| 70 | |
|---|
| 71 | #every byte encrypted |
|---|
| 72 | cryptor = xsalsa.XSalsa(key,iv) |
|---|
| 73 | eccipher="" |
|---|
| 74 | l = 0 |
|---|
| 75 | while l<=(length-2): |
|---|
| 76 | eccipher += b2a_hex(cryptor.process(a2b_hex(plaintext[l:l+2]))) |
|---|
| 77 | l += 2 |
|---|
| 78 | self.failUnlessEqual(eccipher, ciphertext, "every byte computed cipher: %s, ciphertext: %s" % (eccipher, ciphertext)) |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | def test_init_type_check(self): |
|---|
| 82 | self.failUnlessRaises(TypeError, xsalsa.XSalsa, None) |
|---|
| 83 | self.failUnlessRaises(xsalsa.Error, xsalsa.XSalsa, "a"*1) |
|---|
| 84 | self.failUnlessRaises(xsalsa.Error, xsalsa.XSalsa, "a"*17) |
|---|
| 85 | self.failUnlessRaises(xsalsa.Error, xsalsa.XSalsa, "a"*18) |
|---|
| 86 | # self.failUnlessRaises(xsalsa.Error, xsalsa.XSalsa, "a"*32) |
|---|
| 87 | |
|---|
| 88 | if __name__ == "__main__": |
|---|
| 89 | unittest.main() |
|---|