pub struct RsaPrivateKey {
pub public: RsaPublicKey,
/* private fields */
}Fields§
§public: RsaPublicKeyImplementations§
Source§impl RsaPrivateKey
impl RsaPrivateKey
Sourcepub fn new(n: &[u8], e: &[u8], d: &[u8]) -> Option<RsaPrivateKey>
pub fn new(n: &[u8], e: &[u8], d: &[u8]) -> Option<RsaPrivateKey>
Builds a private key from big-endian n, e, d.
Sourcepub fn set_crt(
&mut self,
p: &[u8],
q: &[u8],
dp: &[u8],
dq: &[u8],
qinv: &[u8],
) -> bool
pub fn set_crt( &mut self, p: &[u8], q: &[u8], dp: &[u8], dq: &[u8], qinv: &[u8], ) -> bool
Adds the CRT parameters (big-endian p, q, d mod (p-1), d mod (q-1), q^-1 mod p); returns false (and keeps the plain exponentiation) when they do not match the key.
Sourcepub fn pkcs1_der(&self) -> Option<&[u8]>
pub fn pkcs1_der(&self) -> Option<&[u8]>
The PKCS#1 RSAPrivateKey encoding this key was parsed from (keys built with
RsaPrivateKey::new lack the CRT parameters and have none).
pub fn sign_pkcs1(&self, hash: HashAlg, digest: &[u8]) -> Option<Vec<u8>>
Sourcepub fn sign_pss(&self, hash: HashAlg, digest: &[u8]) -> Option<Vec<u8>>
pub fn sign_pss(&self, hash: HashAlg, digest: &[u8]) -> Option<Vec<u8>>
RSASSA-PSS signature with salt length = hash length (as TLS 1.3 requires).
Examples found in repository?
examples/bench_tls.rs (line 148)
63fn main() {
64 let openssl = std::env::args().any(|a| a == "--openssl");
65 let d = Duration::from_millis(if std::env::args().any(|a| a == "--quick") { 300 } else { 1500 });
66 println!("simoom-tls benchmarks (single thread), hardware AES: {}, CLMUL: {}, SHA-NI: {}", simoom_sys::arch::has_aes(), simoom_sys::arch::has_clmul(), simoom_sys::arch::has_sha256());
67 println!();
68 println!("{:<34} {:>12} {:>12}", "AEAD seal (encrypt + tag)", "16384 B", "1400 B");
69 let aad = [0u8; 13];
70 let mut buf = vec![0x5au8; 16384];
71 let gcm128 = AesGcm::new(&[1u8; 16]);
72 let gcm256 = AesGcm::new(&[1u8; 32]);
73 let gcm128s = AesGcm::new_soft(&[1u8; 16]);
74 let chacha = ChaCha20Poly1305::new(&[2u8; 32]);
75 let mut seq = 0u64;
76 let mut nonce = || {
77 seq += 1;
78 let mut n = [0u8; 12];
79 n[4..].copy_from_slice(&seq.to_be_bytes());
80 n
81 };
82 let f1 = |n: &[u8; 12], b: &mut [u8]| gcm128.seal(n, &aad, b);
83 let f2 = |n: &[u8; 12], b: &mut [u8]| gcm256.seal(n, &aad, b);
84 let f3 = |n: &[u8; 12], b: &mut [u8]| gcm128s.seal(n, &aad, b);
85 let f4 = |n: &[u8; 12], b: &mut [u8]| chacha.seal(n, &aad, b);
86 let algs: [(&str, &dyn Fn(&[u8; 12], &mut [u8]) -> [u8; 16]); 4] =
87 [("AES-128-GCM", &f1), ("AES-256-GCM", &f2), ("AES-128-GCM (portable, bitsliced)", &f3), ("ChaCha20-Poly1305", &f4)];
88 for (name, f) in algs {
89 let size_d = if name.contains("portable") { d / 3 } else { d };
90 let a = rate(size_d, || {
91 black_box(f(&nonce(), &mut buf));
92 });
93 let b = rate(size_d, || {
94 black_box(f(&nonce(), &mut buf[..1400]));
95 });
96 println!("{:<34} {:>9.2} GB/s {:>7.2} GB/s", name, gbps(a, 16384), gbps(b, 1400));
97 }
98 let mut tag = [0u8; 16];
99 let n12 = [0u8; 12];
100 tag.copy_from_slice(&gcm128.seal(&n12, &aad, &mut buf));
101 let o = rate(d, || {
102 // open fails (buffer changed) but does the full work: GHASH, CTR, tag compare
103 black_box(gcm128.open(&n12, &aad, &mut buf, &tag));
104 });
105 println!("{:<34} {:>9.2} GB/s", "AES-128-GCM open", gbps(o, 16384));
106
107 println!();
108 println!("{:<34} {:>12}", "Primitive", "ops/s");
109 let sk = [7u8; 32];
110 let pk = x25519::x25519_base(&[9u8; 32]);
111 println!("{:<34} {:>12.0}", "X25519 key generation (table)", rate(d, || {
112 black_box(x25519::x25519_base(black_box(&sk)));
113 }));
114 println!("{:<34} {:>12.0}", "X25519 shared secret (ladder)", rate(d, || {
115 black_box(x25519::x25519(black_box(&sk), &pk));
116 }));
117 let d256 = p256::generate_private();
118 let q256 = p256::public_key(&p256::generate_private()).unwrap();
119 let h = [3u8; 32];
120 println!("{:<34} {:>12.0}", "P-256 key generation", rate(d, || {
121 black_box(p256::public_key(black_box(&d256)));
122 }));
123 println!("{:<34} {:>12.0}", "P-256 ECDH", rate(d, || {
124 black_box(p256::ecdh(black_box(&d256), &q256));
125 }));
126 let (r, s) = p256::sign(&d256, &h, simoom_tls::crypto::sha2::HashAlg::Sha256).unwrap();
127 let pub256 = p256::public_key(&d256).unwrap();
128 println!("{:<34} {:>12.0}", "ECDSA P-256 sign", rate(d, || {
129 black_box(p256::sign(black_box(&d256), &h, simoom_tls::crypto::sha2::HashAlg::Sha256));
130 }));
131 println!("{:<34} {:>12.0}", "ECDSA P-256 verify", rate(d, || {
132 black_box(p256::verify(&pub256, &h, &r, &s));
133 }));
134 let seed = [5u8; 32];
135 let edpub = simoom_tls::crypto::ed25519::public_key(&seed);
136 // as the server signs: the key's public half is known (OpenSSL keeps it in the key too)
137 println!("{:<34} {:>12.0}", "Ed25519 sign", rate(d, || {
138 black_box(simoom_tls::crypto::ed25519::sign_with_public(&seed, &edpub, b"message"));
139 }));
140 let edsig = simoom_tls::crypto::ed25519::sign(&seed, b"message");
141 println!("{:<34} {:>12.0}", "Ed25519 verify", rate(d, || {
142 black_box(simoom_tls::crypto::ed25519::verify(&edpub, b"message", &edsig));
143 }));
144 let rsa = PrivateKey::from_pem(include_bytes!("../testdata/rsa2048.pkcs1.pem")).unwrap();
145 if let PrivateKey::Rsa(k) = &rsa {
146 let dg = [1u8; 32];
147 println!("{:<34} {:>12.0}", "RSA-2048 PSS sign", rate(d, || {
148 black_box(k.sign_pss(simoom_tls::crypto::sha2::HashAlg::Sha256, &dg));
149 }));
150 let sig = k.sign_pss(simoom_tls::crypto::sha2::HashAlg::Sha256, &dg).unwrap();
151 println!("{:<34} {:>12.0}", "RSA-2048 PSS verify", rate(d, || {
152 black_box(k.public.verify_pss(simoom_tls::crypto::sha2::HashAlg::Sha256, &dg, &sig, Some(32)));
153 }));
154 }
155
156 // handshakes
157 let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
158 let mut roots = RootStore::empty();
159 roots.add_der(&ss.cert_der).unwrap();
160 let mut scfg = ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap());
161 scfg.groups = vec![NamedGroup::X25519];
162 let scfg = Arc::new(scfg);
163 let mut cfull = ClientConfig::new(roots.clone());
164 cfull.sessions = None;
165 cfull.groups = vec![NamedGroup::X25519];
166 let cfull = Arc::new(cfull);
167 let mut cres = ClientConfig::new(roots);
168 cres.groups = vec![NamedGroup::X25519];
169 let cres = Arc::new(cres);
170
171 println!();
172 println!("{:<44} {:>12}", "TLS 1.3 handshake (X25519, ECDSA P-256 cert)", "per second");
173 let full = rate(d, || {
174 let mut c = ClientConnection::new(cfull.clone(), "localhost").unwrap();
175 let mut s = ServerConnection::new(scfg.clone());
176 pump(&mut c, &mut s);
177 assert!(!s.is_handshaking());
178 });
179 println!("{:<44} {:>12.0}", "full, client + server", full);
180 // server side only: replay a fresh ClientHello per iteration and time the server's work
181 let mut server_time = Duration::ZERO;
182 let mut n = 0u32;
183 let t0 = Instant::now();
184 while t0.elapsed() < d {
185 let mut c = ClientConnection::new(cfull.clone(), "localhost").unwrap();
186 let mut s = ServerConnection::new(scfg.clone());
187 let ch = c.tls_output().to_vec();
188 c.consume_tls_output(ch.len());
189 let t = Instant::now();
190 s.read_tls(&ch);
191 s.process_new_packets().unwrap();
192 server_time += t.elapsed();
193 let flight = s.tls_output().to_vec();
194 s.consume_tls_output(flight.len());
195 c.read_tls(&flight);
196 c.process_new_packets().unwrap();
197 let fin = c.tls_output().to_vec();
198 let t = Instant::now();
199 s.read_tls(&fin);
200 s.process_new_packets().unwrap();
201 server_time += t.elapsed();
202 n += 1;
203 }
204 println!("{:<44} {:>12.0}", "full, server side only", n as f64 / server_time.as_secs_f64());
205 // resumption: prime the cache, then each connection uses one ticket and stores a new one
206 let mut c = ClientConnection::new(cres.clone(), "localhost").unwrap();
207 let mut s = ServerConnection::new(scfg.clone());
208 pump(&mut c, &mut s);
209 let resumed = rate(d, || {
210 let mut c = ClientConnection::new(cres.clone(), "localhost").unwrap();
211 let mut s = ServerConnection::new(scfg.clone());
212 pump(&mut c, &mut s);
213 assert!(c.is_resumed());
214 });
215 println!("{:<44} {:>12.0}", "PSK-DHE resumption, client + server", resumed);
216
217 if openssl {
218 println!();
219 println!("openssl speed (same machine, single thread):");
220 for args in [
221 &["speed", "-seconds", "2", "-bytes", "16384", "-evp", "aes-128-gcm"][..],
222 &["speed", "-seconds", "2", "-bytes", "1400", "-evp", "aes-128-gcm"][..],
223 &["speed", "-seconds", "2", "-bytes", "16384", "-evp", "chacha20-poly1305"][..],
224 &["speed", "-seconds", "2", "-bytes", "1400", "-evp", "chacha20-poly1305"][..],
225 &["speed", "-seconds", "2", "ecdhx25519", "ecdhp256", "ecdsap256", "ed25519", "rsa2048"][..],
226 ] {
227 match std::process::Command::new("openssl").args(args).output() {
228 Ok(o) => {
229 let out = String::from_utf8_lossy(&o.stdout);
230 for line in out.lines().filter(|l| {
231 l.starts_with("AES-128-GCM") || l.starts_with("ChaCha20-Poly1305") || l.contains(" sign ") || l.contains("op/s") || l.starts_with("rsa") || l.contains("ecdh") || l.contains("ecdsa") || l.contains("Ed25519") || l.contains("type")
232 }) {
233 println!(" {line}");
234 }
235 }
236 Err(e) => println!(" openssl not available: {e}"),
237 }
238 }
239 }
240}pub fn sign_pss_with_salt( &self, hash: HashAlg, digest: &[u8], salt: &[u8], ) -> Option<Vec<u8>>
Trait Implementations§
Source§impl Clone for RsaPrivateKey
impl Clone for RsaPrivateKey
Auto Trait Implementations§
impl Forget for RsaPrivateKey
impl Freeze for RsaPrivateKey
impl Move for RsaPrivateKey
impl RefUnwindSafe for RsaPrivateKey
impl Send for RsaPrivateKey
impl Sync for RsaPrivateKey
impl Unpin for RsaPrivateKey
impl UnsafeUnpin for RsaPrivateKey
impl UnwindSafe for RsaPrivateKey
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more