1use std::error::Error as StdError;
2use std::os::unix::fs::PermissionsExt;
3use std::fs::{set_permissions, File};
4use std::io::{self, Write};
5use rpassword::read_password;
6use zeroize::Zeroize;
7
8#[cfg(feature = "aes")]
9mod aes256ctr;
10mod api;
11mod fips202;
12mod ntt;
13mod packing;
14mod params;
15mod poly;
16mod polyvec;
17mod randombytes;
18mod reduce;
19mod rounding;
20mod sign;
21mod symmetric;
22mod aesrest;
23
24pub use params::*;
25pub use api::*;
26pub use aesrest::*;
27
28#[allow(unused)]
34pub fn keygen(key_path: &str, pub_path: &str) -> Result<(), Box<dyn StdError>> {
35 let keys = Keypair::generate();
36 let _ = File::create(key_path)
37 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create key file {}: {}", key_path, e)))?;
38 set_permissions(&key_path, PermissionsExt::from_mode(0o600))
39 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to set permissions on {}: {}", key_path, e)))?;
40 let mut puboutput = File::create(pub_path)
41 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create public key file {}: {}", pub_path, e)))?;
42 puboutput.write_all(&keys.public)
43 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to write public key: {}", e)))?;
44 std::io::stdout().flush().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to flush stdout: {}", e)))?;
45 eprintln!("Enter key password then press enter (will not be displayed):");
47 let mut password = read_password().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to read password: {}", e)))?;
48 let mut keymaterial = aesrest::derive_key(password.as_bytes(), 32);
49 aesrest::encrypt_key(keys.expose_secret().to_vec(), key_path, &keymaterial)
50 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to encrypt key file: {}", e)))?;
51 keymaterial.zeroize();
52 password.zeroize();
53 Ok(())
54}
55
56#[cfg(test)]
57mod tests {
58 #[test]
59 fn datetest() {
60 use chrono::prelude::*;
61 assert_eq!(Utc::now().to_string().is_empty(), false);
62 let dt_nano = NaiveDate::from_ymd_opt(2014, 11, 28).unwrap().and_hms_nano_opt(12, 0, 9, 1).unwrap().and_local_timezone(Utc).unwrap();
63 assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z");
64 }
65
66 #[test]
67 fn encrypttest() {
68 use crate::Keypair;
69 use crate::aesrest;
70 use std::os::unix::fs::PermissionsExt;
71 use std::fs::{set_permissions, File};
72 use std::io::{self, Write};
73 use zeroize::Zeroize;
74
75 let keys = Keypair::generate();
76 let key_path = "/tmp/wormsign_test.key";
77 let pub_path = "/tmp/wormsign_test.pub";
78 let _ = File::create(key_path).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create key file {}: {}", key_path, e)));
79 let _ = set_permissions(&key_path, PermissionsExt::from_mode(0o600)).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to set permissions on {}: {}", key_path, e)));
80 let mut puboutput = File::create(pub_path).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create public key file {}: {}", pub_path, e))).expect("failed to create public key");
81 let _ = puboutput.write_all(&keys.public).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to write public key: {}", e)));
82 let _ = std::io::stdout().flush().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to flush stdout: {}", e)));
83 let password = "000000999999888888777777666666555555";
84 let mut keymaterial = aesrest::derive_key(password.as_bytes(), 32);
85 let results = aesrest::encrypt_key(keys.expose_secret().to_vec(), key_path, &keymaterial).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to encrypt key file: {}", e)));
86 keymaterial.zeroize();
87 assert!(results.is_ok());
88 }
89
90 #[test]
91 fn decrypttest() {
92 use crate::Keypair;
93 use crate::aesrest;
94 use std::os::unix::fs::PermissionsExt;
95 use std::fs::{set_permissions, File};
96 use std::io::{self, Write};
97 use zeroize::Zeroize;
98
99 let keys = Keypair::generate();
100 let key_path = "/tmp/wormsign_test.key";
101 let pub_path = "/tmp/wormsign_test.pub";
102 let _ = File::create(key_path).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create key file {}: {}", key_path, e)));
103 let _ = set_permissions(&key_path, PermissionsExt::from_mode(0o600)).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to set permissions on {}: {}", key_path, e)));
104 let mut puboutput = File::create(pub_path).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to create public key file {}: {}", pub_path, e))).expect("failed to create public key");
105 let _ = puboutput.write_all(&keys.public).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to write public key: {}", e)));
106 let _ = std::io::stdout().flush().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to flush stdout: {}", e)));
107 let password = "000000999999888888777777666666555555";
108 let mut keymaterial = aesrest::derive_key(password.as_bytes(), 32);
109 let _ = aesrest::encrypt_key(keys.expose_secret().to_vec(), key_path, &keymaterial).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to encrypt key file: {}", e)));
110 let results = aesrest::decrypt_key(key_path, &keymaterial);
111 keymaterial.zeroize();
112 assert!(results.is_ok());
113 }
114
115 #[test]
116 fn dilithiumtest() {
117 use crate::verify;
118 use crate::Keypair;
119
120 let keys = Keypair::generate();
121 let msg = [0u8; 32];
122 let sig = keys.sign(&msg);
123 let sig_verify = verify(&sig, &msg, &keys.public);
124 assert!(sig_verify.is_ok());
125 }
126}