Univrse
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.
Sponsors
Supported by:
Your sponsorship will help us continue to release and maintain software that Bitcoin businesses and developers depend on.
👉 Sponsor Chronos Labs' open source work
Installation
The package can be installed by adding univrse to your list of dependencies
in mix.exs.
def deps do
[
{:univrse, "~> 0.1"}
]
endUsage
For full documentation, please refer to:
1. Serialising data
Any arbitrary payload can be wrapped in a t: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 BitcoinOP_RETURNscript
# 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
true2. 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])
true3. 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!"License
Univrse is open source and released under the Apache-2 License.
Copyright (c) 2021 Chronos Labs Ltd.