pure-chacha20

a pure Python implementation of ChaCha20 and XChaCha20


License
CC0-1.0
Install
pip install pure-chacha20==0.1.0

Documentation

Pure Python Salsa and ChaCha Actions Status

This project contains pure Python implementations of the Salsa20, XSalsa20, ChaCha20 (IETF), and XChaCha20 stream ciphers. These are intended for educational and testing use only. These implementations are too slow for production use, and they have not been audited.

Note that these are unauthenticated stream ciphers, which are low-level cryptographic building blocks, not suitable for application code. If you need to encrypt real data in an application, use an authenticated cipher like SecretBox. If some of these terms are new to you, Cryptographic Right Answers is an excellent starting point.

Installation

pip install pure_salsa20
pip install pure_chacha20

Note that some environments might refer to pip as pip3, and some environments might need you to run those commands with sudo.

Examples

Salsa20

import pure_salsa20
import secrets

key = secrets.token_bytes(32)
nonce = secrets.token_bytes(8)
plaintext = b"hello world"

# encryption
ciphertext = pure_salsa20.salsa20_xor(key, nonce, plaintext)

# decryption
assert plaintext == pure_salsa20.salsa20_xor(key, nonce, ciphertext)

XSalsa20

import pure_salsa20
import secrets

key = secrets.token_bytes(32)
nonce = secrets.token_bytes(24)
plaintext = b"hello world"

# encryption
ciphertext = pure_salsa20.xsalsa20_xor(key, nonce, plaintext)

# decryption
assert plaintext == pure_salsa20.xsalsa20_xor(key, nonce, ciphertext)

ChaCha20 (IETF RFC 7539)

import pure_chacha20
import secrets

key = secrets.token_bytes(32)
nonce = secrets.token_bytes(12) # note the 12-byte/96-bit nonce from RFC 7539
plaintext = b"hello world"

# encryption
ciphertext = pure_chacha20.chacha20_xor(key, nonce, plaintext)

# decryption
assert plaintext == pure_chacha20.chacha20_xor(key, nonce, ciphertext)

XChaCha20 (draft RFC)

import pure_chacha20
import secrets

key = secrets.token_bytes(32)
nonce = secrets.token_bytes(24)
plaintext = b"hello world"

# encryption
ciphertext = pure_chacha20.xchacha20_xor(key, nonce, plaintext)

# decryption
assert plaintext == pure_chacha20.xchacha20_xor(key, nonce, ciphertext)