Generate deterministic streams of random data based off a secret key and random nonce.
length of cipher stream in bytes
secret key used by the cipher
non-secret unique data to randomize the cipher
Random streams form the basis for most cryptographic methods. Based a shared secret (the key) we generate a predictable random data stream of equal length as the message we need to encrypt. Then we xor the message data with this random stream, which effectively inverts each byte in the message with probabiliy 0.5. The message can be decrypted by re-generating exactly the same random data stream and xor'ing it back. See the examples.
Each stream generator requires a
key and a
nonce. Both are required to re-generate
the same stream for decryption. The key forms the shared secret and should only known to
the trusted parties. The
nonce is not secret and should be stored or sent along
with the ciphertext. The purpose of the
nonce is to make a random stream unique
to protect gainst re-use attacks. This way you can re-use a your key to encrypt multiple
messages, as long as you never re-use the same nonce.
# Very basic encryption myfile <- file.path(R.home(), "COPYING") message <- readBin(myfile, raw(), file.info(myfile)$size) passwd <- charToRaw("My secret passphrase") # Encrypt: key <- hash(passwd) nonce8 <- random(8) stream <- chacha20(length(message), key, nonce8) ciphertext <- base::xor(stream, message) # Decrypt: stream <- chacha20(length(ciphertext), key, nonce8) out <- base::xor(ciphertext, stream) stopifnot(identical(out, message)) # Other stream ciphers stream <- salsa20(10000, key, nonce8) stream <- xsalsa20(10000, key, random(24))