#elliptic-curve #no-alloc

无std generic-ec

通用椭圆曲线加密

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加密学

Download history 116/week @ 2024-04-21 79/week @ 2024-04-28 248/week @ 2024-05-05 170/week @ 2024-05-12 196/week @ 2024-05-19 78/week @ 2024-05-26 235/week @ 2024-06-02 295/week @ 2024-06-09 337/week @ 2024-06-16 59/week @ 2024-06-23 20/week @ 2024-06-30 117/week @ 2024-07-07 98/week @ 2024-07-14 106/week @ 2024-07-21 123/week @ 2024-07-28 91/week @ 2024-08-04

每月下载量421
用于 6 crates

MIT/Apache

520KB
3K SLoC

License Docs Crates io

通用椭圆曲线加密

该库提供了一组简单的抽象,可提升在Rust中进行椭圆曲线算术的操作体验。目标是保持简单、通用和安全的。这对于实现MPC、零知识协议或其他椭圆加密算法的开发者来说非常方便。

generic-ecno_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