README.md

[![CI](https://github.com/BottleFmt/bottlerl/actions/workflows/ci.yml/badge.svg)](https://github.com/BottleFmt/bottlerl/actions/workflows/ci.yml)
[![Hex.pm](https://img.shields.io/hexpm/v/bottlerl.svg)](https://hex.pm/packages/bottlerl)
[![Hex Docs](https://img.shields.io/badge/hex-docs-blue.svg)](https://hexdocs.pm/bottlerl)

# bottlerl

An Erlang/OTP library for the Bottle Protocol, providing layered message containers with encryption and signatures. Compatible with the [Go reference implementation](https://github.com/BottleFmt/gobottle).

## Installation

Add to your `rebar.config` dependencies:

```erlang
{deps, [
    {bottlerl, "0.1.1"}
]}.
```

Or from git:

```erlang
{deps, [
    {bottlerl, {git, "https://github.com/BottleFmt/bottlerl.git", {tag, "0.1.1"}}}
]}.
```

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

```erlang
%% 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

```erlang
%% 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

```erlang
%% 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

```erlang
%% 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](https://github.com/BottleFmt/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

```bash
rebar3 ct
```

## License

MIT License - see [LICENSE](LICENSE) file.