1 unstable release

new 0.3.0 Mar 6, 2025

#1299 in Cryptography


Used in pyrus-cert-store

MIT license

79KB
1K SLoC

Pyrus Crypto

This crate provides an OpenPGP inspired crypto system. It is based on generating certificates and using them to sign, encrypt and decrypt messages. Because it is designed for use in a larger application, this crate has some shortcomings. Mainly: symmetric encryption requires supplying a sender's certificate.

Warning!

This is not a serious crypto crate. It has no tests and is not reviewed by third parties. It's security goes as far as the author's will to make his school project seem secure.

Examples

Generate and serialize a certificate keeping its secret parts:

use pyrus_crypto::prelude::*;

let larry = Cert::new("Larry <larry@gentoo.org>");
let cert_bytes = postcard::to_stdvec(&larry)?;

//.. save the certificate
// use the certificate here

Encrypt a message symmetrically using a passphrase:

use pyrus_crypto::prelude::*;

let larry: Cert = ;//..

let secret_text = b"This is a very secret message";
let message = Message::new(&larry)?
    .write(&secret_text[..])?
    .encrypt_with(b"alcmdzmafia")? // don't use such passwords
    .finalize()?;

Sign and encrypt a message asymmetrically:

Note that the certificates are behind an std::sync::Arc. This is how they will usually appear in the wild.

use pyrus_crypto::prelude::*;

let larry: Arc<Cert> = ;//..
let agentcow: Arc<Cert> = ;//..
let agenthorse: Arc<Cert> = ;//..
let agentfox: Arc<Cert> = ;//..
let friends = vec![agentcow.clone(), agenthorse.clone()];

let secret_text = b"Let's meet up in the evening";
let msg = Message::new(&larry)?
    .write(&secret_text[..])?
    .sign()
    .encrypt_for(&friends)?
    .finalize()?;

Decrypt a symmetrically encrypted message

use pyrus_crypto::prelude::*;

// another of the aforementioned shortcomings
let dummy = Cert::new("dummy cert");
// assume we already have a message
let (_, content, sig) = message
    .parse(&dummy)?
    .decrypt_with(&b"alcmdzmafia"[..])?
    .finalize();

assert_eq!(&secret_text[..], &content[..]);
assert!(sig.is_none()); // the message is not signed

Decrypt and verify a signed message

use pyrus_crypto::prelude::*;

let larry: Arc<Cert> = ;//..
let agentcow: Arc<Cert> = ;//..
let agentfox: Arc<Cert> = ;//..

let secret_text = b"Let's meet up in the evening";

let (message, content, signature) = message
    .parse(&agentcow)? // decrypt using agentcow's certificate
    .decrypt(larry.clone())?
    .verify_signature(larry.clone())?
    .finalize();

assert_eq!(&secret_text[..], &content[..]);
assert!(signature.unwrap()); // signature is Some and is good

let fail = message
    .parse(&agentfox)?
    .decrypt(larry.clone());
assert!(fail.is_err()); // cannot decrypt, not a recipient

Dependencies

~6–8MB
~167K SLoC