init
This commit is contained in:
commit
79a13d3941
6 changed files with 2009 additions and 0 deletions
74
README.md
Normal file
74
README.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
# 🔮 Sage
|
||||
**Sage** is a lightweight cryptographic library built with Rust that layers [age](https://github.com/FiloSottile/age) encryption and [minisign](https://jedisct1.github.io/minisign/) signatures to enable **signed encryption** — ensuring both confidentiality **and** authenticity.
|
||||
|
||||
Sage signs a message before encryption and again after encryption, verifying both layers on decryption. This offers **end-to-end message integrity, trust, and non-repudiation**.
|
||||
|
||||
## 🚀 Features
|
||||
- 🔐 Encryption with age
|
||||
- ✍️ Dual minisign signatures (before and after encryption)
|
||||
- ✅ Signature verification on both layers during decryption
|
||||
- 📦 Easy key serialization and identity management
|
||||
|
||||
## 🌱 Getting Started
|
||||
### Generate a New Identity
|
||||
|
||||
```rust
|
||||
let id = sage::Identity::new();
|
||||
let persona = id.public();
|
||||
```
|
||||
|
||||
- `Identity`: holds your private encryption and signing keys.
|
||||
- `Persona`: a tuple of `(age_public_key, minisign_public_key)` for sharing public keys.
|
||||
|
||||
### Encrypt and Sign
|
||||
|
||||
```rust
|
||||
let message = b"Hello, secure world!";
|
||||
let recipient = persona.enc_key().unwrap(); // Recipient's age public key
|
||||
|
||||
let ciphertext = id.encrypt(message, &recipient);
|
||||
```
|
||||
|
||||
### Verify and Decrypt
|
||||
|
||||
```rust
|
||||
let sender_pk = persona.sign_key().unwrap(); // Sender's minisign public key
|
||||
|
||||
match id.decrypt(&ciphertext, &sender_pk) {
|
||||
Ok(msg) => {
|
||||
println!("Decrypted: {}", String::from_utf8_lossy(&msg.payload));
|
||||
println!("Signed at timestamp: {}", msg.timestamp);
|
||||
}
|
||||
Err(err) => eprintln!("Failed to decrypt: {:?}", err),
|
||||
}
|
||||
```
|
||||
|
||||
## 📁 Saving & Loading Identities
|
||||
|
||||
```rust
|
||||
id.save("my_keys/");
|
||||
|
||||
let loaded = sage::Identity::try_load("my_keys/").unwrap();
|
||||
```
|
||||
|
||||
- Saves two files: `age.key` and `sign.key`
|
||||
|
||||
## 🔍 How It Works
|
||||
|
||||
### Encryption Flow
|
||||
|
||||
1. **Sign the plaintext** with minisign and add meta information (timestamp)
|
||||
2. **Encrypt** the signed payload using age
|
||||
3. **Sign the encrypted blob** with minisign again
|
||||
|
||||
### Decryption Flow
|
||||
|
||||
1. **Verify the outer signature** (authenticity of ciphertext)
|
||||
2. **Decrypt** using the age identity
|
||||
3. **Verify the inner signature** (authenticity of plaintext)
|
||||
4. **Extract** message and timestamp
|
||||
|
||||
## 🙏 Credits
|
||||
|
||||
- [age](https://github.com/FiloSottile/age) by Filippo Valsorda
|
||||
- [minisign](https://jedisct1.github.io/minisign/) by Frank Denis (jedisct1)
|
Loading…
Add table
Add a link
Reference in a new issue