1use dryoc::classic::crypto_box;
2use dryoc::classic::crypto_sign;
3use dryoc::classic::crypto_core;
4use dryoc::generichash::GenericHash;
5use dryoc::sign::SigningKeyPair;
6use dryoc::constants::{
7 CRYPTO_BOX_MACBYTES, CRYPTO_BOX_NONCEBYTES, CRYPTO_BOX_PUBLICKEYBYTES,
8 CRYPTO_BOX_SECRETKEYBYTES, CRYPTO_SIGN_BYTES, CRYPTO_SIGN_PUBLICKEYBYTES,
9 CRYPTO_SIGN_SECRETKEYBYTES
10};
11
12use crate::{error::NcryptfError as Error, util::randombytes_buf, VERSION_2_HEADER};
13
14pub struct Request {
16 secret_key: Vec<u8>,
17 signature_secret_key: Vec<u8>,
18 nonce: Option<Vec<u8>>,
19 message: Option<Vec<u8>>,
20}
21
22impl Request {
23 pub fn encrypt(&mut self, data: String, public_key: Vec<u8>) -> Result<Vec<u8>, Error> {
25 match self.encrypt_with_nonce(data, public_key, None, Some(2)) {
26 Ok(result) => {
27 self.message = Some(result.clone());
28 return Ok(result);
29 }
30 Err(error) => return Err(error),
31 };
32 }
33
34 pub fn get_message(&self) -> Option<Vec<u8>> {
36 return self.message.clone();
37 }
38
39 pub fn encrypt_with_nonce(
41 &mut self,
42 data: String,
43 public_key: Vec<u8>,
44 nonce: Option<Vec<u8>>,
45 version: Option<i8>,
46 ) -> Result<Vec<u8>, Error> {
47 let n = match nonce {
48 Some(n) => n,
49 None => randombytes_buf(CRYPTO_BOX_NONCEBYTES as usize),
50 };
51
52 self.nonce = Some(n.clone());
53
54 if public_key.len() != (CRYPTO_BOX_PUBLICKEYBYTES as usize) {
55 return Err(Error::InvalidArgument(format!(
56 "Public key should be {} bytes",
57 CRYPTO_BOX_PUBLICKEYBYTES
58 )));
59 }
60
61 if n.clone().len() != (CRYPTO_BOX_NONCEBYTES as usize) {
62 return Err(Error::InvalidArgument(format!(
63 "Nonce should be {} bytes",
64 CRYPTO_BOX_NONCEBYTES
65 )));
66 }
67
68 match version {
69 Some(2) => {
70 let h = VERSION_2_HEADER;
72 let header = hex::decode(h.to_string()).unwrap();
73 let mut body = match self.encrypt_body(data.clone(), public_key, n.clone()) {
74 Ok(body) => body,
75 Err(error) => return Err(error),
76 };
77
78 let csk: [u8; CRYPTO_BOX_SECRETKEYBYTES as usize] =
80 self.secret_key.clone().try_into().unwrap();
81 let mut ipk = [0u8; CRYPTO_BOX_PUBLICKEYBYTES as usize];
82 crypto_core::crypto_scalarmult_base(&mut ipk, &csk);
83
84 let ssk: [u8; CRYPTO_SIGN_SECRETKEYBYTES as usize] =
86 self.signature_secret_key.clone().try_into().unwrap();
87 let keypair: SigningKeyPair<[u8; CRYPTO_SIGN_PUBLICKEYBYTES as usize], [u8; CRYPTO_SIGN_SECRETKEYBYTES as usize]> = SigningKeyPair::from_secret_key(ssk);
88 let isk = keypair.public_key;
89
90 let mut signature = match self.sign(data.clone()) {
92 Ok(signature) => signature,
93 Err(error) => return Err(error),
94 };
95
96 let mut payload: Vec<u8> = Vec::<u8>::new();
97 payload.append(&mut header.clone());
98 payload.append(&mut n.clone());
99 payload.append(&mut ipk.to_vec());
100 payload.append(&mut body);
101 payload.append(&mut isk.to_vec());
102 payload.append(&mut signature);
103
104 let s: &[u8; CRYPTO_BOX_NONCEBYTES as usize] = &n.clone().try_into().unwrap();
105 let input = payload.clone();
106
107 let hash: [u8; 64] = GenericHash::hash(&input, Some(s))
108 .map_err(|_| Error::EncryptError)?;
109
110 payload.append(&mut hash.to_vec());
111 return Ok(payload);
112 }
113 _ => {
114 return self.encrypt_body(data.clone(), public_key, n.clone());
115 }
116 }
117 }
118
119 fn encrypt_body(
121 &self,
122 data: String,
123 public_key: Vec<u8>,
124 nonce: Vec<u8>,
125 ) -> Result<Vec<u8>, Error> {
126 let message = data.into_bytes();
127 let sk: [u8; CRYPTO_BOX_SECRETKEYBYTES as usize] =
128 self.secret_key.clone().try_into().unwrap();
129 let pk: [u8; CRYPTO_BOX_PUBLICKEYBYTES as usize] = public_key.clone().try_into().unwrap();
130 let n: [u8; CRYPTO_BOX_NONCEBYTES as usize] = nonce.clone().try_into().unwrap();
131
132 let mut ciphertext = vec![0u8; message.len() + CRYPTO_BOX_MACBYTES as usize];
133 crypto_box::crypto_box_easy(
134 &mut ciphertext,
135 &message,
136 &n,
137 &pk,
138 &sk,
139 ).map_err(|_| Error::EncryptError)?;
140
141 return Ok(ciphertext);
142 }
143
144 pub fn get_nonce(&self) -> Option<Vec<u8>> {
146 return self.nonce.clone();
147 }
148
149 pub fn sign(&self, data: String) -> Result<Vec<u8>, Error> {
151 let key: [u8; CRYPTO_SIGN_SECRETKEYBYTES as usize] =
152 self.signature_secret_key.clone().try_into().unwrap();
153
154 let mut signature = [0u8; CRYPTO_SIGN_BYTES as usize];
155 crypto_sign::crypto_sign_detached(
156 &mut signature,
157 data.as_bytes(),
158 &key,
159 ).map_err(|_| Error::EncryptError)?;
160
161 return Ok(signature.to_vec());
162 }
163
164 pub fn from(secret_key: Vec<u8>, signature_secret_key: Vec<u8>) -> Result<Self, Error> {
166 if secret_key.len() != (CRYPTO_BOX_SECRETKEYBYTES as usize) {
167 return Err(Error::InvalidArgument(format!(
168 "Secret key should be {} bytes",
169 CRYPTO_BOX_SECRETKEYBYTES
170 )));
171 }
172 if signature_secret_key.len() != (CRYPTO_SIGN_SECRETKEYBYTES as usize) {
173 return Err(Error::InvalidArgument(format!(
174 "Signature key should be {} bytes",
175 CRYPTO_SIGN_SECRETKEYBYTES
176 )));
177 }
178
179 return Ok(Request {
180 secret_key,
181 signature_secret_key,
182 nonce: None,
183 message: None,
184 });
185 }
186}