Packages

A library for managing one-time pad encryption

Current section

Files

Jump to
nitroglycerin lib nitroglycerin.ex
Raw

lib/nitroglycerin.ex

defmodule Nitroglycerin do
@moduledoc """
A module for encrypting and decrypting the contents of an IO device, eg. a file, using a one-time pad.
"""
import Nitroglycerin.EncryptionMethods
import Nitroglycerin.DecryptionMethods
@doc """
Encrypts `source_io` with the given `pad` (a `Nitroglycerin.Pad`) and outputs the encrypted bytes to the `target_io`.
both `source_io` and `target_io` should be `IO.Stream`s that can be read and written with `IO.binread` and `IO.binwrite`.
Returns the number of bytes left of the pad.
## Examples
> input = File.open!("input.txt")
> pad = Nitroglycerin.Pad.from_path("random.pad")
> output = File.open!("output.txt.nitro", [:write])
> Nitroglycerin.encrypt!(input, pad, output)
15643
"""
def encrypt!(source_io, pad, target_io) do
state = %Nitroglycerin.State{
io: target_io,
index: pad.next_index,
digest: :crypto.hash_init(:md5)
}
state
|> add_magic_bytes
|> add_index(pad)
|> add_space_for_digest(pad)
|> add_data(source_io, pad)
|> rewind_for_digest(pad)
|> add_digest(pad)
|> finalize(pad)
end
@doc """
Decrypts `source_io` with the given `pad` (a `Nitroglycerin.Pad`) and outputs the decrypted bytes to the `target_io`.
both `source_io` and `target_io` should be `IO.Stream`s that can be read and written with `IO.binread` and `IO.binwrite`.
Returns the number of bytes left of the pad.
## Examples
> input = File.open!("input.txt.nitro")
> pad = Nitroglycerin.Pad.from_path("random.pad")
> output = File.open!("output.txt", [:write])
> Nitroglycerin.decrypt!(input, pad, output)
15643
"""
def decrypt!(source_io, pad, target_io) do
state = %Nitroglycerin.State{
io: source_io,
digest: :crypto.hash_init(:md5)
}
state
|> ensure_magic_bytes
|> retrieve_index(pad)
|> retrieve_digest(pad)
|> retrieve_data(target_io, pad)
|> ensure_correct_digest
|> finalize(pad)
end
defp finalize(state, pad), do: Nitroglycerin.Pad.used!(pad, state.index)
end