bottlerl
An Erlang/OTP library for the Bottle Protocol, providing layered message containers with encryption and signatures. Compatible with the Go reference implementation.
Installation
Add to your rebar.config dependencies:
{deps, [
{bottlerl, "0.1.4"}
]}.Or from git:
{deps, [
{bottlerl, {git, "https://github.com/BottleFmt/bottlerl.git", {tag, "0.1.4"}}}
]}.Requires Erlang/OTP 28 or later.
Features
- Bottle: Layered message containers with encryption and signatures
- ECDH Encryption: Message encryption using ECDSA/ECDH and Ed25519/X25519 keys
- Digital Signatures: Support for RSA, ECDSA (P-256), and Ed25519
- IDCard: Identity management with sub-keys and key purposes
- Keychain: Key storage and management
- Serialization: CBOR (RFC 8949) and JSON encoding
Quick Start
Creating and Opening Bottles
%% Create a bottle with a message
Bottle = bottlerl:new(<<"secret message">>),
%% Encrypt for a recipient
{ok, EncryptedBottle} = bottlerl:encrypt(Bottle, [RecipientPublicKey]),
%% Sign the bottle
{ok, SignedBottle} = bottlerl:sign(EncryptedBottle, SenderPrivateKey),
%% Serialize to CBOR
{ok, Binary} = bottlerl:to_cbor(SignedBottle),
%% Open the bottle
Opener = bottlerl:new_opener([RecipientPrivateKey]),
{ok, Message, Result} = bottlerl:open(Opener, SignedBottle),
%% Check signatures
case bottlerl_opener:signed_by(Result#open_result.signatures, SenderPublicKey) of
true -> io:format("Verified signature from sender~n");
false -> io:format("Signature not found~n")
end.Key Generation
%% Generate RSA key pair
RsaPrivateKey = bottlerl_crypto:generate_rsa_key(2048),
%% Generate EC key pair (P-256)
EcPrivateKey = bottlerl_crypto:generate_ec_key(secp256r1),
%% Generate Ed25519 key pair
Ed25519PrivateKey = bottlerl_crypto:generate_ed25519_key(),
%% Get public key from private key
PublicKey = bottlerl_crypto:private_key_to_public_key(PrivateKey),
%% Convert to DER format for storage/transmission
PublicKeyDer = bottlerl_crypto:public_key_to_der(PublicKey).Keychain Management
%% Create a keychain
Keychain = bottlerl:new_keychain(),
%% Add keys
{ok, Keychain1} = bottlerl:add_key(Keychain, PrivateKey1),
{ok, Keychain2} = bottlerl:add_key(Keychain1, PrivateKey2),
%% Use keychain with opener
Opener = bottlerl:new_opener(Keychain2),
{ok, Message, _Result} = bottlerl:open(Opener, EncryptedBottle).IDCard Management
%% Create an IDCard for a public key
{ok, IDCard} = bottlerl_idcard:new(PublicKey),
%% Add metadata
IDCard1 = bottlerl_idcard:set_meta(IDCard, <<"name">>, <<"Alice">>),
%% Add a subkey with purposes
{ok, _SubKey, IDCard2} = bottlerl_idcard:find_key(IDCard1, SubKeyDer, true),
IDCard3 = bottlerl_idcard:set_key_purposes(IDCard2, SubKeyDer, [<<"sign">>, <<"decrypt">>]),
%% Sign and serialize the IDCard
{ok, SignedIDCard} = bottlerl_idcard:sign(IDCard3, PrivateKey),
%% Load and verify an IDCard
{ok, LoadedIDCard} = bottlerl_idcard:from_binary(SignedIDCard).Modules
| Module | Description |
|---|---|
bottlerl | Main API facade |
bottlerl_bottle | Bottle creation, encryption, and signing |
bottlerl_opener | Bottle decryption and signature verification |
bottlerl_crypto | Cryptographic operations |
bottlerl_cbor | CBOR encoding/decoding (RFC 8949) |
bottlerl_json | JSON encoding/decoding |
bottlerl_idcard | Identity card management |
bottlerl_keychain | Key storage and lookup |
bottlerl_membership | Group membership handling |
Supported Key Types
| Type | Signing | Encryption |
|---|---|---|
| ECDSA (P-256) | Yes | Yes (via ECDH) |
| Ed25519 | Yes | Yes (via X25519) |
| RSA | Yes | Yes (OAEP) |
Interoperability
This library is fully compatible with the Go reference implementation (gobottle). Messages encrypted or signed by one implementation can be decrypted and verified by the other.
The test suite includes interoperability tests using test vectors generated by the Go implementation.
Running Tests
rebar3 ctLicense
MIT License - see LICENSE file.