Univrse (Univrse v0.2.0) View Source

Univrse

License

Univrse is a universal schema for serializing data objects, secured with signatures and encryption.

  • Serialising data - Simple, binary-friendly data exchange using the Concise Binary Object Representation (CBOR) data format.
  • Authenticating data - Protect integrity of data with digital signatures or message authentication code (MAC) algorithms.
  • Securing data - Ensure confidentiality and integrity of data for one or multiple recipients, using standardised authenticated encryption algorithms.

Installation

The package can be installed by adding univrse to your list of dependencies in mix.exs.

def deps do
  [
    {:manic, "~> 0.2.0"}
  ]
end

Usage

For full documentation, please refer to:

1. Serialising data

Any arbitrary payload can be wrapped in a Univrse.Envelope.t/0 structure, and then encoded in one of three serialisation formats, using Univrse.Envelope.encode/2 and Univrse.Envelope.to_script/2

  • :cbor - Concise CBOR-encoded binary value
  • :base64 - Compact Base64-url encoded string value
  • :script - Encoded in a Bitcoin OP_RETURN script
# Wrap any arbitrary data payload in an Envelope structure
iex> payload = "Hello world!"
iex> env = Univrse.wrap(payload, %{proto: "univrse.demo"})

# Encode the data in one of three serialisation formats
iex> env_cbor = Univrse.encode(env, :cbor)
iex> env_base64 = Univrse.encode(env, :base64)
iex> env_script = Univrse.Envelope.to_script(env)

# Decode the serialised data back into an Envelope structure
iex> {:ok, env2} = Univrse.decode(env_cbor)
iex> {:ok, env3} = Univrse.decode(env_base64)
iex> {:ok, env4} = Univrse.Envelope.parse_script(env_script)

# Compare payload
iex> env2.payload == payload and env3.payload == payload and env4.payload == payload
true

2. Using signatures

Digital signatures or message authentication code (MAC) algorithms can be used to protect the integrity of an Envelope's data payload.

# Generate keys
iex> alice_key = Univrse.Key.generate_key({:ec, :secp256k1})
iex> alice_pubkey = Univrse.Key.to_public(alice_key)
iex> app_secret = Univrse.Key.generate_key({:oct, 256})

# Sign and verify using a single key
iex> {:ok, env1} = "Hello world!"
...> |> Univrse.wrap(%{proto: "univrse.demo"})
...> |> Univrse.sign(alice_key, %{"alg" => "ES256K", "kid" => "alice"})

iex> Univrse.verify(env1, alice_pubkey)
true

# Sign and verify using multiple keys and algorithms
iex> {:ok, env2} = "Hello world!"
...> |> Univrse.wrap(%{proto: "univrse.demo"})
...> |> Univrse.sign([
...>      {alice_key, %{"alg" => "ES256K", "kid" => "alice"}},
...>      {app_secret, %{"alg" => "HS256", "kid" => "app"}}
...> ])

iex> Univrse.verify(env2, [alice_pubkey, app_secret])
true

3. Using encryption

Authenticated encryption algorithms may be used to ensure the confidentiality of an Envelope's data payload for one or multiple recipients.

# Generate keys
iex> bob_key = Univrse.Key.generate_key({:ec, :secp256k1})
iex> bob_pubkey = Univrse.Key.to_public(bob_key)
iex> charlie_key = Univrse.Key.generate_key({:ec, :secp256k1})
iex> charlie_pubkey = Univrse.Key.to_public(charlie_key)
iex> app_secret = Univrse.Key.generate_key({:oct, 256})

# Encrypt and decrypt data for a single recipient
iex> {:ok, env1} = "Hello world!"
...> |> Univrse.wrap(%{proto: "univrse.demo"})
...> |> Univrse.encrypt(bob_pubkey, %{"alg" => "ECDH-ES+A128GCM", "kid" => "bob"})

iex> {:ok, env1} = Univrse.decrypt(env1, bob_key)
iex> env1.payload
"Hello world!"

# Encrypt and decrypt data for multiple recipients using multiple algorithms
iex> {:ok, env2} = "Hello world!"
...> |> Univrse.wrap(%{proto: "univrse.demo"})
...> |> Univrse.encrypt([
...>      {app_secret, %{"alg" => "A256GCM"}},
...>      {bob_pubkey, %{"alg" => "ECDH-ES+A128GCM", "kid" => "bob"}},
...>      {charlie_pubkey, %{"alg" => "ECDH-ES+A128GCM", "kid" => "charlie"}}
...> ])

iex> {:ok, bob_env} = Univrse.Envelope.decrypt_at(env2, 1, bob_key)
iex> bob_env.payload
"Hello world!"

iex> {:ok, charlie_env} = Univrse.Envelope.decrypt_at(env2, 2, charlie_key)
iex> charlie_env.payload
"Hello world!"

Link to this section Summary

Link to this section Functions