The best way to learn is by doing. In cryptography, we need to deal with big number which may not have native language support. The earliest comprehensive library is http://read.pudn.com/downloads85/sourcecode/crypt/325570/examples/onb/DH.example/onb.c__.htm and http://www.amazon.com/Implementing-Elliptic-Cryptography-Michael-Rosing/dp/1884777694.
There are plenty of c library, like Miracl, PBC, OpenssL, Nacl, libsodium, etc. On the other hand, the low level routine like gmp, ntl, flint, gnugp are also popular. We will however focus on full open source LibTom project http://www.libtom.net/ and ocassionally use Miracl or others.
The decision of choosing LibTom is its code is written for novice or student and it has accompanied book http://shop.oreilly.com/product/9781597491129.do and https://goo.gl/p2QWJt. Of course there is open tex file for each subprojects and a complete book called Tommath.pdf in the archieve file.
Though it has built-in support for long integer. The cryptography modules inside python are not as plentiful as other fields like machine learning or network secruity (see https://lwn.net/Articles/595790/). To the best of our knowledge, the sympy provides somewhat complete cryptography tools http://docs.sympy.org/dev/_modules/sympy/crypto/crypto.html.
If you would like to get a flavor of crypto, sage may be a good choice, and there are relative plenty source for it http://www.sagemath.org/library-publications.html#books.
However, in this tutorial I will use pycrtpo and cryptography instead since it is directly builds upon python, and also contains a collections of great toolkit. See https://www.dlitz.net/software/pycrypto/doc/ and https://cryptography.io/en/latest/
Other python biding like pynacl may also be helpful, keep track with it !!
from Crypto.Cipher import AES key = 'starpasswordhere' plaintext = 'Martinet is god!' encobj = AES.new(key, AES.MODE_ECB) ciphertext = encobj.encrypt(plaintext) print ciphertext.encode('hex') # For read friendly
You might have noticed that the length of hex-encoded ciphertext is 32 characters. By encoding it in hex, we've doubled the size because each binary character is represented by two hex characters, thus the actual ciphertext is only 16 characters
The common encoding way in cryptography is base64 (which is the same as many other applications), see http://blog.rlr-uk.com/2011/03/base64-encoding-is-not-cryptography.html for the reason
You may notice that we could not change the size of key and plaintext arbitrary in this example, we will relax this constraint by padding and utilizing so called KDF (key derivation function) in later sections
import binascii key = 'starpasswordhere' ciphertext = binascii.unhexlify('292138362368e0cdd76508781b3f3b82') decobj = AES.new(key, AES.MODE_ECB) plaintext = decobj.decrypt(ciphertext) # Resulting plaintext print plaintext
Martinet is god!
from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, modes ) from cryptography.hazmat.backends import default_backend key = 'starpasswordhere' plaintext = 'Martinet is god!' encryptor = Cipher(algorithms.AES(key),modes.ECB(),backend=default_backend()).encryptor() ciphertext = encryptor.update(plaintext) + encryptor.finalize() print ciphertext.encode('hex')
decryptor = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()).decryptor() plaintext = decryptor.update(ciphertext) + decryptor.finalize() print plaintext
Martinet is god!