@@ -3,89 +3,90 @@ use hpke::{
3
3
kdf:: HkdfSha384 ,
4
4
kem:: X25519HkdfSha256 ,
5
5
rand_core:: { CryptoRng , RngCore } ,
6
- HpkeError , Kem , OpModeR , OpModeS ,
6
+ HpkeError , Kem as KemTrait , OpModeR , OpModeS ,
7
7
} ;
8
+ type Kem = X25519HkdfSha256 ;
9
+ type Kdf = HkdfSha384 ;
10
+ type Aead = ChaCha20Poly1305 ;
8
11
9
12
// TODO: Define info that can be sent alongside the message - application defined
10
13
// like which sk to use etc.
11
14
const INFO_STR : & [ u8 ] = b"test" ;
12
15
13
- pub struct SealedMessage {
14
- pub encapped_key : <X25519HkdfSha256 as Kem >:: EncappedKey ,
15
- pub ciphertext : Box < [ u8 ] > ,
16
- pub tag : AeadTag < ChaCha20Poly1305 > ,
16
+ pub struct SealedMessage < ' a > {
17
+ pub encapped_key : <Kem as KemTrait >:: EncappedKey ,
18
+ pub ciphertext : & ' a [ u8 ] ,
19
+ pub tag : AeadTag < Aead > ,
17
20
}
18
21
19
- pub fn seal_message < R : CryptoRng + RngCore > (
20
- msg : & [ u8 ] ,
22
+ pub fn seal_message_in_place < ' a , R : CryptoRng + RngCore > (
23
+ msg : & ' a mut [ u8 ] ,
21
24
associated_data : & [ u8 ] ,
22
- pk_recipient : <X25519HkdfSha256 as Kem >:: PublicKey ,
23
- pk_sender : <X25519HkdfSha256 as Kem >:: PublicKey ,
24
- sk_sender : <X25519HkdfSha256 as Kem >:: PrivateKey ,
25
+ pk_recipient : <Kem as KemTrait >:: PublicKey ,
26
+ pk_sender : <Kem as KemTrait >:: PublicKey ,
27
+ sk_sender : <Kem as KemTrait >:: PrivateKey ,
25
28
csprng : & mut R ,
26
- ) -> Result < SealedMessage , HpkeError > {
27
- let ( encapsulated_key, mut encryption_context) =
28
- hpke:: setup_sender :: < ChaCha20Poly1305 , HkdfSha384 , X25519HkdfSha256 , _ > (
29
- & OpModeS :: Auth ( ( sk_sender, pk_sender) ) ,
30
- & pk_recipient,
31
- INFO_STR ,
32
- csprng,
33
- ) ?;
34
- let mut msg_copy = msg. to_vec ( ) ;
35
- // TODO: add option for seal in place or use seal in place instead?
36
- let tag = encryption_context. seal_in_place_detached ( & mut msg_copy, associated_data) ?;
29
+ ) -> Result < SealedMessage < ' a > , HpkeError > {
30
+ let ( encapsulated_key, mut encryption_context) = hpke:: setup_sender :: < Aead , Kdf , Kem , _ > (
31
+ & OpModeS :: Auth ( ( sk_sender, pk_sender) ) ,
32
+ & pk_recipient,
33
+ INFO_STR ,
34
+ csprng,
35
+ ) ?;
36
+
37
+ let tag = encryption_context. seal_in_place_detached ( msg, associated_data) ?;
37
38
38
39
Ok ( SealedMessage {
39
40
encapped_key : encapsulated_key,
40
- ciphertext : msg_copy. into_boxed_slice ( ) ,
41
+ // TODO: don't copy
42
+ ciphertext : msg,
41
43
tag,
42
44
} )
43
45
}
44
46
45
- pub fn unseal_message (
46
- sealed_message : & SealedMessage ,
47
+ pub fn unseal_message_in_place < ' a > (
48
+ ciphertext : & ' a mut [ u8 ] ,
49
+ encapped_key : <Kem as KemTrait >:: EncappedKey ,
50
+ tag : AeadTag < Aead > ,
47
51
associated_data : & [ u8 ] ,
48
- sk_recipient : <X25519HkdfSha256 as Kem >:: PrivateKey ,
49
- pk_sender : <X25519HkdfSha256 as Kem >:: PublicKey ,
50
- ) -> Result < Box < [ u8 ] > , HpkeError > {
51
- let mut receiver_ctx = hpke:: setup_receiver :: < ChaCha20Poly1305 , HkdfSha384 , X25519HkdfSha256 > (
52
+ sk_recipient : <Kem as KemTrait >:: PrivateKey ,
53
+ pk_sender : <Kem as KemTrait >:: PublicKey ,
54
+ ) -> Result < & ' a [ u8 ] , HpkeError > {
55
+ let mut receiver_ctx = hpke:: setup_receiver :: < Aead , Kdf , Kem > (
52
56
& OpModeR :: Auth ( pk_sender) ,
53
57
& sk_recipient,
54
- & sealed_message . encapped_key ,
58
+ & encapped_key,
55
59
INFO_STR ,
56
60
) ?;
57
61
58
- let mut cipherext_copy = sealed_message. ciphertext . to_vec ( ) ;
59
-
60
- receiver_ctx. open_in_place_detached (
61
- & mut cipherext_copy,
62
- associated_data,
63
- & sealed_message. tag ,
64
- ) ?;
62
+ receiver_ctx. open_in_place_detached ( ciphertext, associated_data, & tag) ?;
65
63
66
64
// Rename for clarity
67
- let plaintext = cipherext_copy ;
65
+ let plaintext = ciphertext ;
68
66
69
- Ok ( plaintext. into_boxed_slice ( ) )
67
+ Ok ( plaintext)
70
68
}
71
69
72
70
#[ cfg( test) ]
73
71
mod test {
74
72
73
+ use std:: vec;
74
+
75
75
use super :: * ;
76
76
use rand:: { self , SeedableRng } ;
77
77
78
78
#[ test]
79
79
fn seal_unseal_roundtrip_success ( ) {
80
- let message = b"some string to send" ;
80
+ let message = vec ! [ 1 , 2 , 3 , 4 ] ;
81
+ let mut message_copy = message. clone ( ) ;
81
82
let associated_data = b"some associated data to share" ;
82
83
let ( sk_sender, pk_sender) = X25519HkdfSha256 :: derive_keypair ( b"some key material" ) ;
83
84
let ( sk_recipient, pk_recipient) =
84
85
X25519HkdfSha256 :: derive_keypair ( b"some different key material" ) ;
85
86
let mut csprng = rand:: rngs:: StdRng :: from_entropy ( ) ;
86
87
87
- let sealed_message = seal_message (
88
- message ,
88
+ let sealed_message = seal_message_in_place (
89
+ & mut message_copy ,
89
90
associated_data,
90
91
pk_recipient,
91
92
pk_sender. clone ( ) ,
@@ -94,9 +95,18 @@ mod test {
94
95
)
95
96
. unwrap ( ) ;
96
97
97
- let unsealed_message =
98
- unseal_message ( & sealed_message, associated_data, sk_recipient, pk_sender) . unwrap ( ) ;
98
+ let mut ciphertext = sealed_message. ciphertext . to_vec ( ) ;
99
+
100
+ let unsealed_message = unseal_message_in_place (
101
+ & mut ciphertext,
102
+ sealed_message. encapped_key ,
103
+ sealed_message. tag ,
104
+ associated_data,
105
+ sk_recipient,
106
+ pk_sender,
107
+ )
108
+ . unwrap ( ) ;
99
109
100
- assert_eq ! ( unsealed_message, message. to_vec ( ) . into_boxed_slice ( ) ) ;
110
+ assert_eq ! ( unsealed_message, message) ;
101
111
}
102
112
}
0 commit comments