Current section

Files

Jump to
elixium_core lib p2p ghost_protocol authentication.ex
Raw

lib/p2p/ghost_protocol/authentication.ex

defmodule Elixium.P2P.Authentication do
alias Elixium.P2P.GhostProtocol.Message
@moduledoc """
SRP authentication handshakes and generation of credentials
"""
# If this node has never communicated with a given peer, it will first
# need to identify itself.
@spec outbound_auth(reference) :: bitstring
def outbound_auth(peer) do
{prime, generator} = Strap.prime_group(1024)
identifier = :crypto.strong_rand_bytes(32)
password = :crypto.strong_rand_bytes(32)
salt = :crypto.strong_rand_bytes(32)
client =
:srp6a
|> Strap.protocol(prime, generator)
|> Strap.client(identifier, password, salt)
"HANDSHAKE"
|> Message.build(%{
prime: prime,
generator: generator,
verifier: Strap.verifier(client),
public_value: Strap.public_value(client)
})
|> Message.send(peer)
%{public_value: peer_public_value} = Message.read(peer)
{:ok, shared_master_key} = Strap.session_key(client, peer_public_value)
shared_master_key
end
@spec inbound_auth(map, reference) :: bitstring
def inbound_auth(message, socket) do
%{
public_value: peer_public_value,
generator: generator,
prime: prime,
verifier: peer_verifier
} = message
server =
:srp6a
|> Strap.protocol(prime, generator)
|> Strap.server(peer_verifier)
"HANDSHAKE_AUTH"
|> Message.build(%{public_value: Strap.public_value(server)})
|> Message.send(socket)
{:ok, shared_master_key} = Strap.session_key(server, peer_public_value)
shared_master_key
end
end