Convert Figma logo to code with AI

str4d logorage

A simple, secure and modern file encryption tool (and Rust library) with small explicit keys, no config options, and UNIX-style composability.

2,862
109
2,862
42

Top Related Projects

18,759

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

A dead simple tool to sign files and verify digital signatures.

a modern crypto messaging format

18,348

Simple and flexible tool for managing secrets

13,531

Tink is a multi-language, cross-platform, open source library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

A high-level OpenPGP library

Quick Overview

The str4d/rage repository is a Rust library that provides a high-performance, memory-safe, and cryptographically secure implementation of the Ristretto group, which is a prime-order group suitable for use in cryptographic protocols. It is designed to be a building block for higher-level cryptographic primitives and applications.

Pros

  • High Performance: The library is optimized for speed and efficiency, making it suitable for use in performance-critical applications.
  • Memory Safety: The Rust programming language's strong type system and ownership model help ensure that the library is memory-safe, reducing the risk of common security vulnerabilities.
  • Cryptographic Security: The Ristretto group is a well-studied and secure elliptic curve group, providing a strong foundation for cryptographic applications.
  • Modular Design: The library is designed to be a building block for higher-level cryptographic primitives and applications, making it easy to integrate into larger projects.

Cons

  • Limited Documentation: The project's documentation, while generally good, could be more comprehensive, especially for users new to Rust or cryptography.
  • Niche Use Case: The Ristretto group is a relatively specialized cryptographic primitive, so the library may not be relevant for all projects.
  • Dependency on Rust: The library is written in Rust, which may be a barrier for developers who are more familiar with other programming languages.
  • Ongoing Maintenance: As with any open-source project, the long-term maintenance and support of the library may be a concern for some users.

Code Examples

Here are a few examples of how to use the str4d/rage library:

  1. Generating a Ristretto Point:
use rage::ristretto::RistrettoPoint;

let point = RistrettoPoint::random(&mut rand::thread_rng());
println!("Random Ristretto point: {}", point);
  1. Performing Scalar Multiplication:
use rage::ristretto::RistrettoPoint;
use rand::Rng;

let mut rng = rand::thread_rng();
let scalar: [u8; 32] = rng.gen();
let point = RistrettoPoint::random(&mut rng);
let result = point * scalar;
println!("Scalar multiplication result: {}", result);
  1. Verifying a Ristretto Point:
use rage::ristretto::RistrettoPoint;

let point = RistrettoPoint::from_bytes(&[
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
    0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
]);

if point.is_valid() {
    println!("The point is valid!");
} else {
    println!("The point is not valid.");
}

Getting Started

To get started with the str4d/rage library, you'll need to have Rust installed on your system. You can then add the library as a dependency in your Cargo.toml file:

[dependencies]
rage = "0.6.1"

Once you've added the dependency, you can start using the library in your Rust code. Here's a simple example that demonstrates how to generate a random Ristretto point and perform scalar multiplication:

use rage::ristretto::RistrettoPoint;
use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();

    // Generate a random Ristretto point
    let point = RistrettoPoint::random(&mut rng);

Competitor Comparisons

18,759

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

Pros of age

  • Written in Go, which offers better performance and easier deployment
  • More mature project with a larger community and ecosystem
  • Supports additional features like SSH key encryption

Cons of age

  • Less flexible API for integration into other projects
  • Slower development cycle and fewer recent updates
  • Limited support for non-UNIX platforms

Code Comparison

age:

recipient, err := age.ParseX25519Recipient(pubKey)
if err != nil {
    log.Fatalf("Failed to parse public key: %v", err)
}

rage:

let recipient = age::x25519::Recipient::from_str(pub_key)?;

Both projects implement the age encryption protocol, but rage is written in Rust while age is written in Go. The code snippets show how to create a recipient from a public key in each library.

rage offers a more idiomatic Rust API with better error handling through the Result type, while age uses Go's traditional error handling approach. The rage implementation is more concise and leverages Rust's type system for improved safety.

Overall, age is more established and widely used, while rage provides a Rust-native implementation with a more ergonomic API for Rust developers. The choice between them often depends on the programming language preference and specific project requirements.

A dead simple tool to sign files and verify digital signatures.

Pros of minisign

  • Simpler and more focused on file signing
  • Lightweight and easy to use
  • Cross-platform compatibility

Cons of minisign

  • Limited to file signing, lacks encryption capabilities
  • Fewer features compared to rage's comprehensive toolset

Code comparison

minisign:

minisign -Sm myfile.txt
minisign -Vm myfile.txt -P RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3

rage:

rage -e -o myfile.txt.age myfile.txt
rage -d -i key.txt myfile.txt.age

Key differences

  • minisign focuses on file signing and verification
  • rage offers both encryption and signing capabilities
  • minisign uses Ed25519 signatures, while rage supports multiple encryption algorithms
  • rage provides a more comprehensive set of features for secure communication and file handling

Use cases

minisign is ideal for:

  • Simple file signing and verification
  • Scenarios where lightweight, focused tools are preferred

rage is better suited for:

  • Comprehensive secure communication needs
  • Projects requiring both encryption and signing capabilities
  • Situations where flexibility in encryption algorithms is necessary

Both tools prioritize security and ease of use, but cater to different needs in the cryptographic toolset landscape.

a modern crypto messaging format

Pros of Saltpack

  • More established project with longer history and wider adoption
  • Supports multiple message formats (encryption, signing, detached signing)
  • Designed for both human-readable and binary output

Cons of Saltpack

  • More complex implementation with additional dependencies
  • Slower performance for large file encryption
  • Less active development in recent years

Code Comparison

Saltpack encryption example:

encrypted, err := saltpack.Encrypt(
    message,
    saltpack.NewKeyring(senderSecretKey),
    []saltpack.BoxPublicKey{recipientPublicKey},
)

Rage encryption example:

let encrypted = age::Encryptor::with_recipients(vec![recipient])
    .encrypt_bytes(&message)?;

Key Differences

  • Rage focuses on simplicity and performance, while Saltpack offers more features
  • Rage uses the Age encryption format, Saltpack uses its own custom format
  • Rage is implemented in Rust, Saltpack in Go (with bindings for other languages)
  • Rage has a more active development community currently

Both projects aim to provide secure, modern encryption tools for developers and end-users, but with different approaches to design and implementation. Rage prioritizes simplicity and performance, while Saltpack offers a broader range of features and message formats.

18,348

Simple and flexible tool for managing secrets

Pros of sops

  • Supports multiple key management systems (AWS KMS, GCP KMS, Azure Key Vault, etc.)
  • Allows partial encryption of files, maintaining structure for easy editing
  • Integrates well with version control systems and CI/CD pipelines

Cons of sops

  • More complex setup and configuration compared to rage
  • Requires external key management services for full functionality
  • May have a steeper learning curve for new users

Code comparison

sops:

myapp:
    db:
        user: ENC[AES256_GCM,data:...] # Encrypted value
        password: ENC[AES256_GCM,data:...] # Encrypted value

rage:

age-encryption.org/v1
-> X25519 yXNuRQyPo7W1oT9sHpMvfg1WTHNWcdLCgyx9QLzPukU
... (encrypted content)

Summary

sops offers more flexibility and integration options, making it suitable for complex enterprise environments. It excels in scenarios requiring partial file encryption and integration with cloud key management services. rage, on the other hand, provides a simpler, file-based encryption approach that may be more appropriate for individual users or smaller projects with straightforward encryption needs.

13,531

Tink is a multi-language, cross-platform, open source library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

Pros of Tink

  • Broader cryptographic functionality, including digital signatures, MACs, and hybrid encryption
  • Extensive language support (C++, Java, Go, Python, JavaScript)
  • Backed by Google, potentially offering more resources and long-term support

Cons of Tink

  • More complex API and setup process
  • Larger codebase and dependencies, potentially increasing attack surface
  • Less focused on age encryption format compatibility

Code Comparison

Tink (encryption example):

keysetHandle, err := keyset.NewHandle(aead.AES256GCMKeyTemplate())
a, err := aead.New(keysetHandle)
ciphertext, err := a.Encrypt(plaintext, associatedData)

Rage (encryption example):

let encryptor = age::Encryptor::with_recipients(vec![recipient])
    .expect("failed to create encryptor");
let mut encrypted = vec![];
let mut writer = encryptor.wrap_output(&mut encrypted)?;
writer.write_all(message.as_bytes())?;
writer.finish()?;

Both libraries offer encryption functionality, but Tink provides a more generalized approach with its keysetHandle and AEAD interface, while Rage focuses specifically on the age encryption format with a more streamlined API.

A high-level OpenPGP library

Pros of gopenpgp

  • Developed by ProtonMail, a well-known privacy-focused company
  • Extensive support for OpenPGP standard, including key management and encryption
  • Well-documented API with examples for various use cases

Cons of gopenpgp

  • Larger codebase and potentially more complex to integrate
  • Focused primarily on OpenPGP, which may be overkill for simpler encryption needs
  • Slower development pace compared to rage

Code Comparison

gopenpgp:

publicKey, err := crypto.NewKeyFromArmored(publicKeyString)
message := crypto.NewPlainMessage([]byte("Hello, World!"))
encrypted, err := publicKey.Encrypt(message, nil)

rage:

let public_key = age::x25519::Recipient::from_str(public_key_string)?;
let encrypted = age::Encryptor::with_recipients(vec![Box::new(public_key)])
    .encrypt_bytes(b"Hello, World!")?;

Both libraries provide encryption functionality, but rage offers a more streamlined API for simple encryption tasks, while gopenpgp provides more comprehensive OpenPGP features.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

The age logo, an wireframe of St. Peters dome in Rome, with the text: age, file encryption

rage: Rust implementation of age

rage is a simple, modern, and secure file encryption tool, using the age format. It features small explicit keys, no config options, and UNIX-style composability.

The format specification is at age-encryption.org/v1. age was designed by @Benjojo and @FiloSottile.

The reference interoperable Go implementation is available at filippo.io/age.

Hardware PIV tokens such as YubiKeys are supported through the age-plugin-yubikey plugin.

For more plugins, implementations, tools, and integrations, check out the awesome age list.

Installation

EnvironmentCLI command
Cargo (Rust 1.65+)cargo install rage
Homebrew (macOS or Linux)brew install rage
MacPortsport install rage
Alpine Linux (edge)apk add rage
Arch Linuxpacman -S rage-encryption
DebianDebian packages
NixOSAdd to config: environment.systemPackages = [ pkgs.rage ];
Or run nix-env -i rage
openSUSE Tumbleweedzypper install rage-encryption
Ubuntu 20.04+Debian packages
FreeBSDpkg install rage-encryption
Scoop (Windows)scoop bucket add main
scoop install main/rage

On Windows, Linux, and macOS, you can use the pre-built binaries.

Help from new packagers is very welcome. Please use the package name rage; the fallback package name rage-encryption should be used only when there are unavoidable name conflicts in package systems that use global namespaces. Do not rename any binaries; instead use your package system's conflicting package mechanism to prevent installation of both packages at once.

Usage

Usage: rage [--encrypt] (-r RECIPIENT | -R PATH)... [-i IDENTITY] [-a] [-o OUTPUT] [INPUT]
       rage [--encrypt] --passphrase [-a] [-o OUTPUT] [INPUT]
       rage --decrypt [-i IDENTITY] [-o OUTPUT] [INPUT]

Arguments:
  [INPUT]  Path to a file to read from.

Options:
  -h, --help                    Print this help message and exit.
  -V, --version                 Print version info and exit.
  -e, --encrypt                 Encrypt the input (the default).
  -d, --decrypt                 Decrypt the input.
  -p, --passphrase              Encrypt with a passphrase instead of recipients.
      --max-work-factor <WF>    Maximum work factor to allow for passphrase decryption.
  -a, --armor                   Encrypt to a PEM encoded format.
  -r, --recipient <RECIPIENT>   Encrypt to the specified RECIPIENT. May be repeated.
  -R, --recipients-file <PATH>  Encrypt to the recipients listed at PATH. May be repeated.
  -i, --identity <IDENTITY>     Use the identity file at IDENTITY. May be repeated.
  -j <PLUGIN-NAME>              Use age-plugin-PLUGIN-NAME in its default mode as an identity.
  -o, --output <OUTPUT>         Write the result to the file at path OUTPUT.

INPUT defaults to standard input, and OUTPUT defaults to standard output.
If OUTPUT exists, it will be overwritten.

RECIPIENT can be:
- An age public key, as generated by rage-keygen ("age1...").
- An SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...").

PATH is a path to a file containing age recipients, one per line
(ignoring "#" prefixed comments and empty lines). "-" may be used to
read recipients from standard input.

IDENTITY is a path to a file with age identities, one per line
(ignoring "#" prefixed comments and empty lines), or to an SSH key file.
Passphrase-encrypted age identity files can be used as identity files.
Multiple identities may be provided, and any unused ones will be ignored.
"-" may be used to read identities from standard input.

Multiple recipients

Files can be encrypted to multiple recipients by repeating -r/--recipient. Every recipient will be able to decrypt the file.

$ rage -o example.png.age -r age1uvscypafkkxt6u2gkguxet62cenfmnpc0smzzlyun0lzszfatawq4kvf2u \
    -r age1ex4ty8ppg02555at009uwu5vlk5686k3f23e7mac9z093uvzfp8sxr5jum example.png

Recipient files

Multiple recipients can also be listed one per line in one or more files passed with the -R/--recipients-file flag.

$ cat recipients.txt
# Alice
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# Bob
age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg
$ rage -R recipients.txt example.jpg > example.jpg.age

If the argument to -R (or -i) is -, the file is read from standard input.

Passphrases

Files can be encrypted with a passphrase by using -p/--passphrase. By default rage will automatically generate a secure passphrase.

$ rage -p -o example.png.age example.png
Type passphrase (leave empty to autogenerate a secure one): [hidden]
Using an autogenerated passphrase:
    kiwi-general-undo-bubble-dwarf-dizzy-fame-side-sunset-sibling
$ rage -d example.png.age >example.png
Type passphrase: [hidden]

If a binary named pinentry is available in $PATH, it will be used to ask the user for a passphrase. The PINENTRY_PROGRAM environment variable can be used to set the binary name or path to use. If a pinentry binary is not available, or PINENTRY_PROGRAM is set to the empty string, rage will fall back to the CLI instead.

Passphrase-protected identity files

If an identity file passed to -i/--identity is a passphrase-encrypted age file, it will be automatically decrypted.

$ rage -p -o key.age <(rage-keygen)
Public key: age1pymw5hyr39qyuc950tget63aq8vfd52dclj8x7xhm08g6ad86dkserumnz
Type passphrase (leave empty to autogenerate a secure one): [hidden]
Using an autogenerated passphrase:
    flash-bean-celery-network-curious-flower-salt-amateur-fence-giant
$ rage -r age1pymw5hyr39qyuc950tget63aq8vfd52dclj8x7xhm08g6ad86dkserumnz secrets.txt > secrets.txt.age
$ rage -d -i key.age secrets.txt.age > secrets.txt
Type passphrase: [hidden]

Passphrase-protected identity files are not necessary for most use cases, where access to the encrypted identity file implies access to the whole system. However, they can be useful if the identity file is stored remotely.

SSH keys

As a convenience feature, rage also supports encrypting to ssh-rsa and ssh-ed25519 SSH public keys, and decrypting with the respective private key file. (ssh-agent is not supported.)

$ rage -R ~/.ssh/id_ed25519.pub example.png > example.png.age
$ rage -d -i ~/.ssh/id_ed25519 example.png.age > example.png

Note that SSH key support employs more complex cryptography, and embeds a public key tag in the encrypted file, making it possible to track files that are encrypted to a specific public key.

Feature flags

When building with Cargo, you can configure rage using --no-default-features and --features comma,separated,flags to enable or disable the following feature flags:

  • mount enables the rage-mount tool, which can mount age-encrypted TAR or ZIP archives as read-only. It is currently only usable on Unix systems, as it relies on libfuse.

  • ssh (enabled by default) enables support for reusing existing SSH key files for age encryption.

  • unstable enables in-development functionality. Anything behind this feature flag has no stability or interoperability guarantees.

Rust Library

Applications wishing to use rage as a library should use the age crate, which rage is built on top of.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.