@@ -24,15 +24,15 @@ use std::str::FromStr;
24
24
use aes:: cipher:: { BlockDecrypt , BlockEncrypt , KeyInit } ;
25
25
use aes:: { Aes256 , Block } ;
26
26
use amplify:: confinement:: { Confined , SmallOrdMap , U64 as U64MAX } ;
27
- use amplify:: Bytes32 ;
27
+ use amplify:: { Bytes32 , Wrapper } ;
28
28
use armor:: { ArmorHeader , ArmorParseError , AsciiArmor } ;
29
- use ec25519:: { edwards25519, Error } ;
29
+ use ec25519:: edwards25519;
30
30
use rand:: random;
31
31
use sha2:: digest:: generic_array:: GenericArray ;
32
32
use sha2:: { Digest , Sha256 } ;
33
33
use strict_encoding:: { StrictDeserialize , StrictSerialize } ;
34
34
35
- use crate :: { Algo , InvalidPubkey , SsiPub , LIB_NAME_SSI } ;
35
+ use crate :: { Algo , InvalidPubkey , SsiPair , SsiPub , LIB_NAME_SSI } ;
36
36
37
37
#[ derive( Copy , Clone , Debug , Display , Error ) ]
38
38
pub enum EncryptionError {
@@ -42,10 +42,22 @@ pub enum EncryptionError {
42
42
InvalidPubkey ( SsiPub ) ,
43
43
}
44
44
45
+ #[ derive( Copy , Clone , Debug , Display , Error ) ]
46
+ pub enum DecryptionError {
47
+ #[ display( "the message can't be decrypted using key {0}" ) ]
48
+ KeyMismatch ( SsiPub ) ,
49
+ #[ display( "invalid public key {0}" ) ]
50
+ InvalidPubkey ( SsiPub ) ,
51
+ }
52
+
45
53
#[ derive( Clone , Debug , From ) ]
46
54
#[ derive( StrictType , StrictDumb , StrictEncode , StrictDecode ) ]
47
55
#[ strict_type( lib = LIB_NAME_SSI ) ]
48
- pub struct SymmetricKey ( Bytes32 ) ;
56
+ pub struct SymmetricKey (
57
+ #[ from]
58
+ #[ from( [ u8 ; 32 ] ) ]
59
+ Bytes32 ,
60
+ ) ;
49
61
50
62
impl AsRef < [ u8 ] > for SymmetricKey {
51
63
fn as_ref ( & self ) -> & [ u8 ] { self . 0 . as_ref ( ) }
@@ -107,7 +119,7 @@ impl Encrypted {
107
119
for pk in receivers {
108
120
keys. insert (
109
121
pk,
110
- pk. encrypt ( & key)
122
+ pk. encrypt_key ( & key)
111
123
. map_err ( |_| EncryptionError :: InvalidPubkey ( pk) ) ?,
112
124
) ;
113
125
}
@@ -117,28 +129,59 @@ impl Encrypted {
117
129
data : Confined :: from_collection_unsafe ( msg) ,
118
130
} )
119
131
}
132
+
133
+ pub fn decrypt ( & self , pair : SsiPair ) -> Result < Vec < u8 > , DecryptionError > {
134
+ let key = self
135
+ . keys
136
+ . iter ( )
137
+ . find ( |( pk, _) | * pk == & pair. pk )
138
+ . map ( |( _, secret) | secret)
139
+ . ok_or ( DecryptionError :: KeyMismatch ( pair. pk ) ) ?
140
+ . copy ( ) ;
141
+ let key = pair
142
+ . decrypt_key ( key)
143
+ . map_err ( |_| DecryptionError :: InvalidPubkey ( pair. pk ) ) ?;
144
+ Ok ( decrypt ( self . data . to_inner ( ) , key) )
145
+ }
120
146
}
121
147
122
148
impl SsiPub {
123
- pub fn encrypt ( & self , key : & SymmetricKey ) -> Result < Bytes32 , InvalidPubkey > {
149
+ pub fn encrypt_key ( & self , key : & SymmetricKey ) -> Result < Bytes32 , InvalidPubkey > {
124
150
match self . algo ( ) {
125
- Algo :: Ed25519 => self . encrypt_ed25519 ( key) ,
151
+ Algo :: Ed25519 => self . encrypt_key_ed25519 ( key) ,
126
152
Algo :: Bip340 | Algo :: Other ( _) => Err ( InvalidPubkey ) ,
127
153
}
128
154
}
129
155
130
- pub fn encrypt_ed25519 ( & self , key : & SymmetricKey ) -> Result < Bytes32 , InvalidPubkey > {
131
- let pk = ec25519:: PublicKey :: try_from ( * self ) ?;
132
- let ge = edwards25519:: GeP3 :: from_bytes_vartime ( & pk) . ok_or ( InvalidPubkey ) ?;
156
+ pub fn encrypt_key_ed25519 ( & self , key : & SymmetricKey ) -> Result < Bytes32 , InvalidPubkey > {
157
+ let ge =
158
+ edwards25519:: GeP3 :: from_bytes_vartime ( & self . to_byte_array ( ) ) . ok_or ( InvalidPubkey ) ?;
159
+
160
+ Ok ( edwards25519:: ge_scalarmult ( key. as_ref ( ) , & ge)
161
+ . to_bytes ( )
162
+ . into ( ) )
163
+ }
164
+ }
165
+
166
+ impl SsiPair {
167
+ pub fn decrypt_key ( & self , key : Bytes32 ) -> Result < SymmetricKey , InvalidPubkey > {
168
+ match self . pk . algo ( ) {
169
+ Algo :: Ed25519 => self . decrypt_key_ed25519 ( key) ,
170
+ Algo :: Bip340 | Algo :: Other ( _) => Err ( InvalidPubkey ) ,
171
+ }
172
+ }
133
173
174
+ pub fn decrypt_key_ed25519 ( & self , key : Bytes32 ) -> Result < SymmetricKey , InvalidPubkey > {
175
+ let ge = edwards25519:: GeP3 :: from_bytes_negate_vartime ( & self . pk . to_byte_array ( ) )
176
+ . ok_or ( InvalidPubkey ) ?;
134
177
Ok ( edwards25519:: ge_scalarmult ( key. as_ref ( ) , & ge)
135
178
. to_bytes ( )
136
179
. into ( ) )
137
180
}
138
181
}
139
182
140
- pub fn encrypt ( mut source : Vec < u8 > , passwd : impl AsRef < [ u8 ] > ) -> Vec < u8 > {
141
- let key = Sha256 :: digest ( passwd . as_ref ( ) ) ;
183
+ pub fn encrypt ( mut source : Vec < u8 > , key : impl AsRef < [ u8 ] > ) -> Vec < u8 > {
184
+ let key = Sha256 :: digest ( key . as_ref ( ) ) ;
142
185
let key = GenericArray :: from_slice ( key. as_slice ( ) ) ;
143
186
let cipher = Aes256 :: new ( key) ;
144
187
@@ -149,8 +192,8 @@ pub fn encrypt(mut source: Vec<u8>, passwd: impl AsRef<[u8]>) -> Vec<u8> {
149
192
source
150
193
}
151
194
152
- pub fn decrypt ( mut source : Vec < u8 > , passwd : impl AsRef < [ u8 ] > ) -> Vec < u8 > {
153
- let key = Sha256 :: digest ( passwd . as_ref ( ) ) ;
195
+ pub fn decrypt ( mut source : Vec < u8 > , key : impl AsRef < [ u8 ] > ) -> Vec < u8 > {
196
+ let key = Sha256 :: digest ( key . as_ref ( ) ) ;
154
197
let key = GenericArray :: from_slice ( key. as_slice ( ) ) ;
155
198
let cipher = Aes256 :: new ( key) ;
156
199
0 commit comments