#elliptic-curve #pairing

无需std ark-ec

椭圆曲线和配对的库

14次发布

0.5.0-alpha.02024年6月20日
0.4.2 2023年3月18日
0.4.1 2023年2月21日
0.4.0-alpha.72022年12月29日
0.2.0 2021年3月24日

#10 in 密码学

Download history 91034/week @ 2024-04-30 90673/week @ 2024-05-07 97032/week @ 2024-05-14 93000/week @ 2024-05-21 104183/week @ 2024-05-28 97790/week @ 2024-06-04 104499/week @ 2024-06-11 96206/week @ 2024-06-18 103830/week @ 2024-06-25 93229/week @ 2024-07-02 94208/week @ 2024-07-09 108310/week @ 2024-07-16 116096/week @ 2024-07-23 110739/week @ 2024-07-30 134247/week @ 2024-08-06 126797/week @ 2024-08-13

507,084 monthly downloads
用于 1,886 个crate (152直接)

MIT/Apache

1MB
18K SLoC

ark-ec

ark-ec 定义了用于处理不同类型的加法群的特性和算法,重点关注由椭圆曲线产生的群。它还提供了各种椭圆曲线模型(包括BLS12曲线家族等流行的配对友好曲线族)的这些特性的具体实例化。可以使用这些曲线模型找到特定曲线的实现,见 arkworks-rs/curves

用法

Group 特性

许多密码协议使用素数阶群作为核心构建块。 PrimeGroup 特性是表示这种阿贝尔素数阶群元素的抽象。它提供了对群元素执行常见操作的方法

use ark_ec::{AdditiveGroup, PrimeGroup};
use ark_ff::{PrimeField, Field};
// We'll use the BLS12-381 G1 curve for this example.
// This group has a prime order `r`, and is associated with a prime field `Fr`.
use ark_test_curves::bls12_381::{G1Projective as G, Fr as ScalarField};
use ark_std::{Zero, UniformRand, ops::Mul};

let mut rng = ark_std::test_rng();
// Let's sample uniformly random group elements:
let a = G::rand(&mut rng);
let b = G::rand(&mut rng);

// We can add elements, ...
let c = a + b;
// ... subtract them, ...
let d = a - b;
// ... and double them.
assert_eq!(c + d, a.double());
// We can also negate elements, ...
let e = -a;
// ... and check that negation satisfies the basic group law
assert_eq!(e + a, G::zero());

// We can also multiply group elements by elements of the corresponding scalar field
// (an act known as *scalar multiplication*)
let scalar = ScalarField::rand(&mut rng);
let e = c.mul(scalar);
let f = e.mul(scalar.inverse().unwrap());
assert_eq!(f, c);

标量乘法

虽然《PrimeGroup》特性已经产生了标量乘法例程,但在许多情况下,可以通过利用群结构来更有效地执行标量乘法。为了实现这种专业化,ark-ec提供了《ScalarMul》和《VariableBaseMSM》特性。后一特性计算标量向量《s》和群元素向量《g》之间的“内积”。也就是说,它计算《s.iter().zip(g).map(|(s, g)| g * s).sum()

use ark_ec::{PrimeGroup, VariableBaseMSM};
use ark_ff::{PrimeField, Field};
// We'll use the BLS12-381 G1 curve for this example.
// This group has a prime order `r`, and is associated with a prime field `Fr`.
use ark_test_curves::bls12_381::{G1Projective as G, G1Affine as GAffine, Fr as ScalarField};
use ark_std::{Zero,  UniformRand};

let mut rng = ark_std::test_rng();
// Let's sample uniformly random group elements:
let a = GAffine::rand(&mut rng);
let b = GAffine::rand(&mut rng);

let s1 = ScalarField::rand(&mut rng);
let s2 = ScalarField::rand(&mut rng);

// Note that we're using the `GAffine` type here, as opposed to `G`.
// This is because MSMs are more efficient when the group elements are in affine form. (See below for why.)
//
// The `VariableBaseMSM` trait allows specializing the input group element representation to allow
// for more efficient implementations.
let r = G::msm(&[a, b], &[s1, s2]).unwrap();
assert_eq!(r, a * s1 + b * s2);

椭圆曲线群

在有限域上使用椭圆曲线时,有两个特性非常重要:《CurveGroup》和《AffineRepr》。这两个特性表示同一条曲线的元素,但提供不同的底层表示。特别是,曲线点的《CurveGroup》表示通常在算术运算中更有效,但并不提供曲线点的唯一表示。另一方面,《AffineRepr》表示是唯一的,但在大多数算术运算中较慢。让我们探讨如何和使用这些

use ark_ec::{AdditiveGroup, AffineRepr, PrimeGroup, CurveGroup, VariableBaseMSM};
use ark_ff::{PrimeField, Field};
use ark_test_curves::bls12_381::{G1Projective as G, G1Affine as GAffine, Fr as ScalarField};
use ark_std::{Zero, UniformRand};

let mut rng = ark_std::test_rng();
// Let's generate an elliptic curve group element in the `CurveGroup` representation
let a = G::rand(&mut rng);
// We can convert it the `AffineRepr` representation...
let a_aff = a.into_affine();
// ... and check that the two representations are equal.
assert_eq!(a_aff, a);
// We can also convert back to the `CurveGroup` representation:
assert_eq!(a, a_aff.into_group());

// As a general rule, most group operations are slower when elements
// are represented as `AffineRepr`. However, adding an `AffineRepr`
// point to a `CurveGroup` one is usually slightly more efficient than
// adding two `CurveGroup` points.
let d = a + a_aff;
assert_eq!(d, a.double());

// This efficiency also translates into more efficient scalar multiplication routines.
let scalar = ScalarField::rand(&mut rng);
let mul_result = a_aff * scalar;
assert_eq!(a * scalar, mul_result);

// Finally, while not recommended, users can directly construct group elements
// from the x and y coordinates of the curve points. This is useful when implementing algorithms
// like hash-to-curve.
let a_x = a_aff.x;
let a_y = a_aff.y;
let is_at_infinity = a_aff.is_zero();
// This check ensures that `new_a` is indeed in the curve group, and in particular
// is within the prime-order group.
let new_a = GAffine::new(a_x, a_y);
assert_eq!(a_aff, new_a);
assert!(new_a.is_on_curve());
assert!(new_a.is_in_correct_subgroup_assuming_on_curve());

除了上述椭圆曲线群的抽象接口之外,ark-ec还提供了以下常见椭圆曲线模型的具体实例

配对

Pairing是一个定义了配对友好椭圆曲线接口的特性。除了通用接口之外,我们还提供了对流行的配对友好曲线家族的具体实现,例如Barreto-Lynn-ScottBarreto-Naehrig家族。

use ark_ec::{pairing::Pairing, AffineRepr};
use ark_ff::Field;
use ark_std::UniformRand;

use ark_test_curves::bls12_381::{Bls12_381, G1Projective as G1, G2Projective as G2, Fq12 as Fq12};
use ark_test_curves::bls12_381::Fr as ScalarField;

// The pairing engine is parameterized by the scalar field of the curve.
let mut rng = ark_std::test_rng();
let s = ScalarField::rand(&mut rng);
let a = G1::rand(&mut rng);
let b = G2::rand(&mut rng);

// We can compute the pairing of two points on the curve, either monolithically...
let e1 = Bls12_381::pairing(a, b);
// ... or in two steps. First, we compute the Miller loop...
let ml_result = Bls12_381::miller_loop(a, b);
// ... and then the final exponentiation.
let e2 = Bls12_381::final_exponentiation(ml_result).unwrap();
assert_eq!(e1, e2);

哈希到群

ark-ec还提供了将哈希到椭圆曲线群的特征。允许用户将任意字节字符串哈希到椭圆曲线群元素,并允许使用不同的哈希策略的《HashToCurve》特性。

依赖关系

~3–4.5MB
~84K SLoC