Crate sam_encrypt
Expand description
SamEncrypt provides a set of cryptographic primitives for building a single-hop proxy self re-encryption scheme.
The implementation is based on the original paper by Selvi et al. entitled Sharing of Encrypted files in Blockchain Made Simpler
Start exploring the Api documentation
§Usage
This crate relies on elliptic curve cryptography to implement the key exchange
protocol. In particular, the curve of choice is the Edwards 25519.
We provide ECPoint
and ECScalar
structs, which are wrappers around
Point<Ed25519>
and Scalar<25519>
respectively.
Currently, the implemented cryptographic primitives are provided as part of a stateful
encryption-decryption pipeline. This state is controlled via the implementation of core::PREState
.
This means that a single user can use the available primitives to self-encrypt/self-decrypt files,
generate re-encryption keys, and re-encrypt/re-decrypt files.
Although all of these functionalities are currently available as part of a single state,
they are robust enough that a user shouldn’t have trouble, for instance, using them
to implement an access control layer on top of an existing application.
§Examples
§Self-Encrypting Files
use sam_encrypt::{core::EncryptedMessage, core::PREState};
use sam_encrypt::elliptic_curve::Curve;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use futures::executor::block_on;
fn self_encrypt_file() -> Result<(), Box<dyn Error>> {
// By default uses the Ed25519 elliptic curve
let curve = Curve::new();
let pre_state = PREState::new(curve);
let file_content = std::fs::read_to_string(Path::new("/file/path"))
.expect("Failed to read file");
let encrypted_file = block_on(pre_state.self_encrypt(
file_content.as_bytes().to_vec(),
String::from("tag").into_bytes(),
))
.expect("Failed to self-encrypt the given file");
let ciphertext = File::create("encrypted_file.cbor")?;
serde_cbor::to_writer(ciphertext, &encrypted_file)?;
Ok(())
}
§Generating Re-Encryption Keys
A re-encryption key is generated using a user’s public key and an optional tag.
use sam_encrypt::{core::ReEncryptionKey, core::PREState, elliptic_curve};
use sam_encrypt::elliptic_curve::Curve;
use std::error::Error;
fn get_re_encryption_keys() -> Result<(), Box<dyn Error>> {
let curve = Curve::new();
let pre_state = PREState::new(curve);
let public_key = pre_state.public_key.to_bytes();
let re_encryption_key = pre_state
.generate_re_encryption_key(&public_key, String::from("tag").into_bytes())
.unwrap();
Ok(())
}
§Re-Encrypt Files
This allows a proxy to re-encrypt an already encrypted file.
use sam_encrypt::{core::{EncryptedMessage, ReEncryptionKey, ReEncryptedMessage, PREState}};
use sam_encrypt::elliptic_curve::Curve;
use std::error::Error;
use std::fs::File;
fn re_encrypt_file() -> Result<(), Box<dyn Error>> {
let curve = Curve::new();
let pre_state = PREState::new(curve.clone());
let ciphertext_file_path = String::from("/file/path");
let re_key_path = String::from("/re_encryption_key/path");
// load up a serialized encrypted file
let encrypted_file = serde_cbor::from_reader(File::open(ciphertext_file_path)?)?;
// load up a serialized re-encryption key
let re_key = serde_cbor::from_reader(File::open(re_key_path)?)?;
let public_key = pre_state.public_key.to_bytes();
let re_encrypted_file = pre_state
.re_encrypt(&public_key, encrypted_file, re_key, &curve)
.expect("failed to re-encrypt the input file");
serde_cbor::to_writer(File::create(String::from("/re_encrypted_file/path"))?, &re_encrypted_file)?;
Ok(())
}