diff --git a/Cargo.toml b/Cargo.toml index 965090f..f57f898 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,4 @@ tiny-keccak = "1.4" [dev-dependencies] bincode = "1.0.0" +serde_derive = "1.0.55" diff --git a/examples/README.md b/examples/README.md index ee723cb..1c58aef 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,5 +1,11 @@ # Examples +- [`Public-Key Cryptography`](basic_pkc.rs) - Demonstrates how to generate a +random secret-key and corresponding public-key, sign some bytes using a +secret-key, validate the signature for some bytes using a public-key, encrypt +some bytes using a public-key, and how to decrypt a ciphertext using a +secret-key. + - [`Threshold Encryption`](threshold_enc.rs) - Demonstrates how to encrypt a message to a group of actors with a master public-key, where the number of actors collaborating in the decryption process must exceed a given threshold diff --git a/examples/basic_pkc.rs b/examples/basic_pkc.rs new file mode 100644 index 0000000..aa26fe3 --- /dev/null +++ b/examples/basic_pkc.rs @@ -0,0 +1,61 @@ +extern crate bincode; +#[macro_use] +extern crate serde_derive; +extern crate threshold_crypto; + +use bincode::{deserialize, serialize}; +use threshold_crypto::{PublicKey, SecretKey, Signature}; + +#[derive(Deserialize, Serialize)] +struct SignedMsg { + msg: Vec, + sig: Signature, +} + +#[derive(Debug)] +struct KeyPair { + sk: SecretKey, + pk: PublicKey, +} + +impl KeyPair { + fn random() -> Self { + let sk = SecretKey::random(); + let pk = sk.public_key(); + KeyPair { sk, pk } + } + + fn create_signed_msg(&self, msg: &[u8]) -> SignedMsg { + let sig = self.sk.sign(msg); + let msg = msg.to_vec(); + SignedMsg { msg, sig } + } +} + +fn main() { + // Alice and Bob each generate a public/private key-pair. + // + // Note: it is against best practices to use the same key-pair for both encryption/decryption + // and signing. The following example could be interpreted as advocating this, which it is not + // meant to. This is just a basic example. In this example, Bob's key-pair is used for signing + // where as Alice's is used for encryption/decryption. + let alice = KeyPair::random(); + let bob = KeyPair::random(); + + // Bob wants to send Alice a message. He signs the plaintext message with his secret key. He + // then encrypts the signed message with Alice's public key. + let msg = b"let's get pizza"; + let signed_msg = bob.create_signed_msg(msg); + let serialized = serialize(&signed_msg).expect("Failed to serialize `SignedMsg`"); + let ciphertext = alice.pk.encrypt(&serialized); + + // Alice receives Bob's encrypted message. She decrypts the message using her secret key. She + // then verifies that the signature of the plaintext is valid using Bob's public key. + let decrypted = alice.sk.decrypt(&ciphertext).expect("Invalid ciphertext"); + let deserialized: SignedMsg = + deserialize(&decrypted).expect("Failed to deserialize bytes to `SignedMsg`"); + assert!(bob.pk.verify(&deserialized.sig, &deserialized.msg)); + + // We assert that the message that Alice received is the same message that Bob sent. + assert_eq!(msg, &deserialized.msg[..]); +}