Rust下P-384签名验证速度偏慢,有哪些优化提速技巧?
使用p384 crate优化ECDSA签名验证性能的技巧
问题背景
我正在用p384 crate对网站API请求做签名验证,测试代码如下:
use p384::elliptic_curve::rand_core; use p384::ecdsa::{signature::Signer, Signature, SigningKey}; use rand_core::OsRng; use std::time::Instant; // 签名流程 let signing_key = SigningKey::random(&mut OsRng); // 可通过::to_bytes()序列化 let message = b"ECDSA proves knowledge of a secret number in the context of a single message"; let signature: Signature = signing_key.sign(message); // 验证流程 use p384::ecdsa::{signature::Verifier, VerifyingKey}; let verifying_key = VerifyingKey::from(&signing_key); let now = Instant::now(); match verifying_key.verify(message, &signature) { Ok(_) => { println!("Verification passed!"); }, Err(e) => { println!("Verification failed: {:?}",e); }, } println!("Verification time: {:.2?}", now.elapsed());
运行输出:
Verification passed! Verification time: 29.41ms
这个验证步骤给每个网络请求增加了约30ms耗时,原本5ms加载完成的网站现在需要35-40ms。测试环境是搭载3GHz 6核Intel Core i5的Mac mini,系统为macOS 13.4.1。想知道有没有优化、缓存或其他提速技巧。
优化方案
1. 复用验证密钥实例
VerifyingKey是线程安全且可复用的,无需每次请求都重新从SigningKey生成。如果验证密钥是固定值(比如服务端公钥),直接在程序初始化阶段创建一次实例,后续所有请求复用该实例,避免重复的密钥转换开销。
2. 启用硬件加速特性
p384 crate支持通过特性开关调用CPU硬件加速指令,大幅提升验证速度。修改Cargo.toml中的依赖配置:
p384 = { version = "0.12", features = ["ecdsa", "ring", "std"] }
其中ring后端会自动利用CPU的AES-NI、SHA硬件加速指令,降低ECDSA验证的计算耗时。
3. 并行批量处理验证请求
如果存在多个待验证的API请求,可利用多核心并行处理摊薄总耗时。比如借助rayon crate实现并行验证:
use rayon::prelude::*; // 假设存在一批消息和对应的签名 let verify_tasks: Vec<_> = messages.iter().zip(signatures.iter()).collect(); verify_tasks.par_iter().for_each(|(msg, sig)| { match verifying_key.verify(msg, sig) { Ok(_) => println!("Verification passed"), Err(e) => println!("Verification failed: {:?}", e), } });
4. 缓存重复请求的验证结果
对于重复请求(比如命中本地缓存的资源请求),直接缓存之前的验证结果,无需重复执行签名验证逻辑,减少不必要的计算。
5. 跳过重复哈希计算
ECDSA验证默认会对消息做SHA-384哈希,如果消息的哈希值已经预先计算完成,可使用verify_prehashed方法跳过重复哈希步骤:
use p384::ecdsa::signature::PrehashSignature; // 预先计算消息的SHA-384哈希 let msg_hash = sha2::Sha384::digest(message); match verifying_key.verify_prehashed(&msg_hash, &signature) { Ok(_) => println!("Verification passed!"), Err(e) => println!("Verification failed: {:?}", e), }
内容的提问来源于stack exchange,提问作者sudoExclamationExclamation
相关产品推荐
相关产品推荐

