Current section
Files
Jump to
Current section
Files
lib/noise/cipher_state.ex
defmodule Noise.CipherState do
@moduledoc false
alias Noise.Protocol
@enforce_keys [:protocol]
defstruct protocol: nil, k: nil, n: 0
@type t() :: %__MODULE__{
protocol: Protocol.t(),
k: <<_::32, _::_*8>> | nil,
n: integer()
}
defguard is_key(k) when is_binary(k) and byte_size(k) == 32
def initialize(%Protocol{} = protocol) do
%__MODULE__{protocol: protocol}
end
def initialize_key(%__MODULE__{} = state, key) do
state
|> Map.put(:k, key)
|> Map.put(:n, 0)
end
def has_key?(%__MODULE__{k: key}) when is_key(key), do: true
def has_key?(%__MODULE__{}), do: false
def set_nonce(%__MODULE__{} = state, nonce) do
Map.put(state, :n, nonce)
end
def encrypt_with_ad(%__MODULE__{protocol: protocol, k: k, n: n} = state, ad, plain_text)
when is_key(k) do
{Protocol.encrypt(protocol, k, n, ad, plain_text), Map.update!(state, :n, &(&1 + 1))}
end
def encrypt_with_ad(%__MODULE__{} = state, _ad, plain_text) do
{plain_text, state}
end
def decrypt_with_ad(%__MODULE__{protocol: protocol, k: k, n: n} = state, ad, cipher_text)
when is_key(k) do
{Protocol.decrypt(protocol, k, n, ad, cipher_text), Map.update!(state, :n, &(&1 + 1))}
end
def decrypt_with_ad(%__MODULE__{} = state, _ad, cipher_text) do
{cipher_text, state}
end
def rekey(%__MODULE__{protocol: protocol, k: k} = state) do
Map.put(state, :k, Protocol.rekey(protocol, k))
end
end
defimpl Inspect, for: Noise.CipherState do
alias Noise.Utils
def inspect(state, opts) do
Inspect.Map.inspect(%{k: Utils.hex(state.k), n: state.n}, opts)
end
end