You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 02:10:34