Creates a sealed box for a message using a recipient's public key. The sealed box format is compatible with libsodium's sealed box encryption. It uses an ephemeral keypair to perform the encryption, so only the recipient with the corresponding secret key can decrypt the message. The sealed box format is: - First 32 bytes: Ephemeral public key - Remaining bytes: XSalsa20Poly1305 encrypted data wi
(message: &[u8], recipient_pk: &PublicKey)
| 83 | /// |
| 84 | /// A Vec<u8> containing the sealed box ciphertext |
| 85 | pub fn seal(message: &[u8], recipient_pk: &PublicKey) -> Vec<u8> { |
| 86 | // Generate an ephemeral keypair for this sealed box |
| 87 | let ephemeral_sk = StaticSecret::random_from_rng(OsRng); |
| 88 | let ephemeral_pk = PublicKey::from(&ephemeral_sk); |
| 89 | |
| 90 | // Compute the shared secret using X25519 Diffie-Hellman |
| 91 | let shared_secret = ephemeral_sk.diffie_hellman(recipient_pk); |
| 92 | |
| 93 | // Derive the symmetric key using HSalsa20 |
| 94 | let key_bytes = derive_key(shared_secret.as_bytes()); |
| 95 | |
| 96 | // Compute nonce: blake2b(ephemeral_pk || recipient_pk, outlen=24) |
| 97 | let nonce = derive_nonce(ephemeral_pk.as_bytes(), recipient_pk.as_bytes()) |
| 98 | .or_panic("Failed to derive nonce"); |
| 99 | |
| 100 | // Create the XSalsa20Poly1305 cipher with the derived key |
| 101 | let cipher = XSalsa20Poly1305::new_from_slice(&key_bytes) |
| 102 | .or_panic("Failed to create XSalsa20Poly1305 cipher"); |
| 103 | |
| 104 | // Encrypt the message |
| 105 | let ciphertext = cipher |
| 106 | .encrypt(&nonce, message) |
| 107 | .or_panic("Encryption failed"); |
| 108 | |
| 109 | // Combine the ephemeral public key and ciphertext to form the sealed box |
| 110 | let mut sealed_box = Vec::with_capacity(PUBLICKEYBYTES + ciphertext.len()); |
| 111 | sealed_box.extend_from_slice(ephemeral_pk.as_bytes()); |
| 112 | sealed_box.extend_from_slice(&ciphertext); |
| 113 | |
| 114 | sealed_box |
| 115 | } |
| 116 | |
| 117 | /// Opens a sealed box using RustCrypto libraries. |
| 118 | /// |