Current section
Files
Jump to
Current section
Files
lib/noise/protocol.ex
defmodule Noise.Protocol do
@moduledoc false
alias Noise.Pattern
@enforce_keys [:name, :cipher, :dh, :dhlen, :hash, :hashlen, :pattern]
defstruct [:name, :cipher, :dh, :dhlen, :hash, :hashlen, :pattern, :extensions]
@type t() :: %__MODULE__{
name: String.t(),
cipher: module(),
dh: module(),
hash: module(),
pattern: Pattern.t(),
extensions: []
}
def from_name(protocol_name)
when is_binary(protocol_name) and byte_size(protocol_name) <= 255 do
protocol_name
|> String.split("_")
|> parse()
end
def from_name(protocol_name) do
raise ArgumentError,
"Protocol name has to be 255 or less bytes long string. Got: #{protocol_name}"
end
# DH functions
def generate_keypair(%__MODULE__{dh: dh}), do: dh.generate_keypair()
def dh(%__MODULE__{dh: dh}, keypair, pubkey), do: dh.dh(keypair, pubkey)
# Cipher
def encrypt(%__MODULE__{cipher: cipher}, k, n, ad, plain_text),
do: cipher.encrypt(k, n, ad, plain_text)
def decrypt(%__MODULE__{cipher: cipher}, k, n, ad, cipher_text),
do: cipher.decrypt(k, n, ad, cipher_text)
def rekey(%__MODULE__{cipher: cipher}, key), do: cipher.rekey(key)
# Hash
def hash(%__MODULE__{hash: hash}, data), do: hash.hash(data)
def hkdf(%__MODULE__{hash: hash}, ck, ik, n), do: hash.hkdf(ck, ik, n)
# internal API
defp parse(["Noise", pattern, dh, cipher, hash]) do
%__MODULE__{
name: "Noise_#{pattern}_#{dh}_#{cipher}_#{hash}",
cipher: parse_cipher(cipher),
dh: parse_dh(dh),
dhlen: parse_dh(dh).dhlen(),
hash: parse_hash(hash),
hashlen: parse_hash(hash).hashlen(),
pattern: Pattern.from_name(pattern),
extensions: []
}
end
defp parse(name) do
raise ArgumentError, "Invalid protocol name #{name}"
end
defp parse_dh("secp256k1"), do: Noise.Crypto.DH.Secp256k1
defp parse_dh("448"), do: Noise.Crypto.DH.X448
defp parse_dh("25519"), do: Noise.Crypto.DH.X25519
defp parse_dh(dh), do: raise(ArgumentError, "Unsupported DH type: #{dh}")
defp parse_cipher("AESGCM"), do: Noise.Crypto.Cipher.AESGCM
defp parse_cipher("ChaChaPoly"), do: Noise.Crypto.Cipher.ChaChaPoly
defp parse_cipher(cipher), do: raise("Unsupported Cipher type: #{cipher}")
defp parse_hash("SHA256"), do: Noise.Crypto.Hash.Sha256
defp parse_hash("SHA512"), do: Noise.Crypto.Hash.Sha512
# defp parse_hash("SHA3/256"), do: Noise.Crypto.Hash.Sha3_256
# defp parse_hash("SHA3/512"), do: Noise.Crypto.Hash.Sha3_512
defp parse_hash("BLAKE2s"), do: Noise.Crypto.Hash.Blake2s
defp parse_hash("BLAKE2b"), do: Noise.Crypto.Hash.Blake2b
defp parse_hash(hash), do: raise(ArgumentError, "Unsupported Hash type: #{hash}")
end