Build Status Crates

Signcryption

Signcryption is a cryptographic technique that combines the functionality of both digital signatures and encryption. It allows a sender to both authenticate the origin of a message and protect its confidentiality, while also allowing the recipient to verify the authenticity of the message and decrypt it without requiring any separate communication channels.

This library implements the Toorani-Beheshti signcryption scheme instantiated over Ristretto255 or Ed25519.

Installation

This library currently depends on the libsodium-sys-stable crate. You will need libsodium installed first.

https://libsodium.gitbook.io/doc/installation

Or simply use the fetch-libsodium feature of this crate on first use which will download and install the current stable version.

To add to your project:

shell cargo add signcryption

or in Cargo.toml:

toml [dependencies] signcryption = "0.1"

Usage

The higher level functions complete the full workflow and handle encryption using the AES-GCM crate.

```rust // Default uses Ristretto255 let alicekeys = Keypair::default(); let bobkeys = Keypair::default();

let alicepublickey = alicekeys.public.clone(); let bobpublickey = bobkeys.public.clone();

let msg = "Hello".as_bytes();

// Sign and encrypt, returns a SignCrypt struct let ciphertext = signcrypt(&alicekeys, &bobpublic_key, &msg)?;

// Verify and decrypt, returns a plaintext Vec let plaintext = unsigncrypt(ciphertext, &alicepublickey, &bob_keys)?;

assert_eq!(payload , &plaintext[..]); ```

To use a different AEAD or for lower level control you'll need to run through the discrete step functions themselves. To remove the aes-gcm crate dependency set default-features = false in Cargo.toml

Signcrypt

```rust // Initialise state let mut state = SignState::default();

// Using Ed25519 keys this time let alicekeys = Keypair::new(Curve::Ed25519); let bobkeys = Keypair::new(Curve::Ed25519);

// Shared secret for encryption let mut crypt_key = [0u8; SHAREDBYTES];

let msg = "Hello".as_bytes()

// Additional Authenticated Data if desired let senderid = "alice".asbytes() let recipientid = "bob".asbytes() let info = "rust-signcryption".as_bytes()

// Sign plaintext signbefore( &mut state, &mut cryptkey, &SENDERID, &RECIPIENTID, &INFO, &alice.expose_secret(), &bob.public, msg, Curve::Ed25519 )?;

///////////////////////////////////////////////////////////// // Encrypt here with your desired AEAD using cryptkey eg. // // let cipher = ChaCha20Poly1305::new(&cryptkey); // /////////////////////////////////////////////////////////////

// Signature to pass to recipient let mut sig = [0u8; SIGNBYTES];

// Sign ciphertext signafter(&mut state, &mut sig, &alice.exposesecret(), &ciphertext, Curve::Ed25519);

// Send ciphertext, signature and correct AAD to recipient ```

Unsigncrypt

```rust let mut state = SignState::default(); let mut crypt_key = [0u8; SHAREDBYTES];

// Additional Authenticated Data used to signcrypt the message let senderid = "alice".asbytes() let recipientid = "bob".asbytes() let info = "rust-signcryption".as_bytes()

// Verify and get shared secret verifybefore( &mut state, &mut cryptkey, &sig, &senderid, &recipientid, &info, &alicepublickey, &bob.expose_secret(), Curve::Ed25519 )?;

//////////////////////////// // Decrypt with crypt_key // ////////////////////////////

// Verify after verifyafter(&mut state, &sig, &alicepublic_key, &ciphertext, Curve::Ed25519)?; ```

Public Verification

Verify the message without learning the decryption key.

rust verify_public( &sig, &sender_id, &recipient_id, &info, &alice_public_key, &ciphertext, Curve::Ed25519 )?;

Why?

Combining encryption and signing has flaws either way you order them:

Encrypt then Sign: An attacker can replace your signature, making it seem as though they encrypted the file.

Sign then Encrypt: The recipient can re-encrypt the file and impersonate you sending the file to someone else.

Signcryption performs signing both before and after the encryption stage, negating these flaws.

Alternatives

This crate is based on the Libsodium-Signcryption library, written in C.

Licensing

All crates 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.