14个版本 (4个重大变更)
0.4.0 | 2024年6月20日 |
---|---|
0.3.0 | 2024年5月10日 |
0.2.3 | 2024年3月27日 |
0.1.2 | 2023年12月11日 |
0.0.0 | 2022年4月12日 |
第119位 加密学
每月下载量421
用于 6 crates
520KB
3K SLoC
通用椭圆曲线加密
该库提供了一组简单的抽象,可提升在Rust中进行椭圆曲线算术的操作体验。目标是保持简单、通用和安全的。这对于实现MPC、零知识协议或其他椭圆加密算法的开发者来说非常方便。
generic-ec
是 no_std
且与Web Assembly兼容。
概述
Crate提供了三个基本操作:椭圆曲线上的点 Point<E>
,整数模群阶 Scalar<E>
,以及携带某些敏感值(例如密钥)的秘密标量 SecretScalar<E>
。《E》代表椭圆曲线的选择,可以是任何 支持的曲线,例如 Point<Secp256k1>
是secp256k1曲线上的椭圆点。
公开API
公开的API有限:椭圆点算术(点加、取负、标量乘法),标量算术(加法、乘法、模素数群阶逆),以及编码/解码为字节表示。
通过 FromHash
和其他特性,某些曲线提供了将散列转换为曲线、将散列转换为标量的基本操作,以及访问点的仿射坐标。
安全性与保证
该库通过强制执行以下检查来减轻一系列攻击(例如小群攻击):
- 标量
Scalar<E>
必须是曲线素数阶的整数 - 椭圆点
Point<E>
必须在曲线上
即椭圆点保证满足《E》的方程 Point<E>
是无挠点的
椭圆点应无小群分量。这消除了任何小群攻击。
如果点或标量不符合上述要求,则无法构建(在安全的Rust中),因为这些检查总是强制执行的。例如,如果您正在反序列化表示无效点的字节数组,反序列化将导致错误。
SecretScalar<E>
有时您的标量代表某些敏感值,例如密钥,并且您希望将其保持更安全。`SecretScalar<E>`是`Scalar<E>`的现场替换,通过在堆上存储标量值并在丢弃时擦除它来强制执行额外的安全性。其优点是它在被丢弃后不会在内存转储中留下任何痕迹(这不是常规`Scalar<E>`保证的)。
但请注意,我们无法控制操作系统,如果您的内存不足,操作系统可能会将包含敏感值的RAM页面加载到交换磁盘(即您的硬盘/固态硬盘)上。或者它可能做其他任何复杂的事情。我们避免编写不安全或特定于操作系统的代码,以减轻这个问题。
无穷远点
应注意的是,无穷远点(或单位点)是一个有效的`Point<E>`。您可以通过调用`Point::<E>::zero()来构建它,例如`Point::<Secp256k1>::zero()`是secp256k1曲线的无穷远点。
如果您正在实施的协议要求点/标量不为零,您可能需要通过调用`.is_zero()`方法或使用NonZero<T>
(《NonZero<Point<E>>`或`NonZero<Scalar<E>>`)来强制执行此检查。
使用`NonZero<T>`提供了某些编译时保证。例如,在模群阶的非零标量下将非零点在素数群中相乘,在数学上保证输出该素群中的非零点。因此,将`NonZero<Point<E>>`在`NonZero<Scalar<E>>`上相乘返回`NonZero<Point<E>>`。
支持的曲线
Crate 提供以下椭圆曲线的原生支持
曲线 | 特性 | 后端 |
---|---|---|
secp256k1 | curve-secp256k1 |
RustCrypto/k256 |
secp256r1 | curve-secp256r1 |
RustCrypto/p256 |
stark-curve | curve-stark |
Dfns/stark |
Ed25519 | curve-ed25519 |
curve25519-dalek |
为了使用这些支持的曲线之一,您需要启用相应的特性。例如,如果您想使用 secp256k1 曲线,请将以下内容添加到 Cargo.toml 中
[dependency]
generic-ec = { version = "...", features = ["curve-secp256k1"] }
现在您可以在该曲线上生成一个点
use generic_ec::{Point, Scalar, curves::Secp256k1};
let random_point: Point<Secp256k1> = Point::generator() * Scalar::random(&mut rng);
添加对其他曲线的支持
添加新的曲线就像实现 Curve
trait 一样简单!如果您缺少某些曲线支持,或者您不满意现有的实现,您可以定义自己的 Curve
trait 实现并享受使用相同的便捷原语 Point<YOUR_EC>
,Scalar<YOUR_EC>
以及等等。
特性
curve-{name}
启用指定的曲线支持。请参阅 支持的曲线列表。all-curves
启用所有支持的曲线serde
启用点/标量(反)序列化支持。(默认启用)std
启用对标准库的支持(默认启用)
示例
随机标量/点生成
use generic_ec::{Point, Scalar, curves::Secp256k1};
// Generates random non-zero scalar
let random_scalar = Scalar::<Secp256k1>::random(&mut rng);
// Produces a point that's result of generator multiplied at the random scalar
let point = Point::generator() * &random_scalar;
Diffie-Hellman 密钥交换
use generic_ec::{Point, SecretScalar, curves::Secp256k1};
let alice_sk = SecretScalar::<Secp256k1>::random(&mut rng);
let alice_pk = Point::generator() * &alice_sk;
let bob_sk = SecretScalar::<Secp256k1>::random(&mut rng);
let bob_pk = Point::generator() * &bob_sk;
let shared_secret_learned_by_alice = bob_pk * &alice_sk;
let shared_secret_learned_by_bob = alice_pk * &bob_sk;
assert_eq!(shared_secret_learned_by_alice, shared_secret_learned_by_bob);
通用的曲线选择
您可以使函数简单地泛化曲线选择
use generic_ec::{Point, Scalar, Curve};
use rand::RngCore;
fn some_generic_computation<E: Curve>(rng: &mut impl RngCore, point: Point<E>) -> Point<E> {
let blinding = Point::<E>::generator() * Scalar::random(rng);
let e = &point + &blinding;
// ... some computation
}
// You can run this function with any supported curve:
use generic_ec::curves::{Secp256k1, Secp256r1};
let point1 = Point::<Secp256k1>::generator().to_point();
let _ = some_generic_computation(&mut rng, point1);
let point2 = Point::<Secp256r1>::generator().to_point();
let _ = some_generic_computation(&mut rng, point2);
// ...
许可
该软件包根据您的选择受 MIT 或 Apache-2.0 许可。
依赖关系
~2–4MB
~89K SLoC