1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! 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](https://eprint.iacr.org/2019/418.pdf)
//!
//! Start exploring the [Api documentation](api/index.html)
//!
//! # Usage
//! This crate relies on elliptic curve cryptography to implement the key exchange
//! protocol. In particular, the curve of choice is the [Edwards 25519](https://docs.rs/curv-kzen/0.8.0/curv/elliptic/curves/enum.Ed25519.html).
//! 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(())
//! }
//! ```
//!