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日

#8 in 密码学

Download history 156708/week @ 2024-05-03 161658/week @ 2024-05-10 148082/week @ 2024-05-17 166570/week @ 2024-05-24 166595/week @ 2024-05-31 156026/week @ 2024-06-07 167248/week @ 2024-06-14 185747/week @ 2024-06-21 151921/week @ 2024-06-28 160606/week @ 2024-07-05 181457/week @ 2024-07-12 197274/week @ 2024-07-19 190424/week @ 2024-07-26 208223/week @ 2024-08-02 231857/week @ 2024-08-09 192587/week @ 2024-08-16

858,438每月下载量
用于2,098个crate(204个直接使用)

MIT/Apache

340KB
7.5K SLoC

ark-ff

此crate定义了有限域特性和遵循这些特性的有用抽象模型。一些流行椭圆曲线的特定有限域的实现可以在arkworks-rs/curves下找到,具体位置为arkworks-rs/curves/<你最喜欢的曲线>/src/fields/

此crate包含两种类型的特性和配置

  • Field特性:这些定义了操作域元素(如加法、乘法、逆元、平方根等)的接口。
  • Config配置:指定定义域的参数。对于扩展域,它还提供了执行域操作所需的功能,例如用于构建域的(立方或二次)非剩余数(NONRESIDUE)。

可用的域特性包括

  • AdditiveGroup - 有关与Scalar关联类型相关的“标量乘法”操作的加法群的接口。这适用于素域、域扩展和密码学中使用的椭圆曲线群。
  • Field - 通用有限域的接口。
  • FftField - 提供执行字段元素上高效FFT的方法。
  • PrimeField - 具有素数 p 个元素的域,也称为 Fp

实现的模式包括

上述两种模型作为直接构建扩展域 Fp^m(即 m 等于 2 或 3)或创建扩展塔以达到更高的 m 的抽象。后者通过迭代应用扩展来实现,例如在二次扩展域上应用三次扩展。

  • Fp2 - 直接在素数域上的二次扩展,即 BaseField == BasePrimeField
  • Fp3 - 直接在素数域上的三次扩展,即 BaseField == BasePrimeField
  • Fp6_2over3 - 扩展塔:在三次扩展域上的二次扩展,即 BaseField = Fp3,但 BasePrimeField = Fp
  • Fp6_3over2 - 扩展塔,与上述类似,但塔的顺序相反:它是在二次扩展域上的三次扩展,即 BaseField = Fp2,但 BasePrimeField = Fp。默认情况下,只有后者作为 Fp6 导出。
  • Fp12_2over3over2 - 扩展塔:在 Fp6_3over2 上的二次扩展,即 BaseField = Fp6

用法

在处理有限域时有两个重要的特质:FieldPrimeField。让我们通过示例来探讨这些。

加法群

AdditiveGroup 特质提供了一个具有关联标量乘法操作的加法群的通用接口。实现此特质的类型支持常见的群操作,如加法、减法、取反以及通过 Scalar 关联类型进行标量乘法。

use ark_ff::AdditiveGroup;
// We'll use a field associated with the BLS12-381 pairing-friendly
// group for this example.
use ark_test_curves::bls12_381::Fq2 as F;
// `ark-std` is a utility crate that enables `arkworks` libraries
// to easily support `std` and `no_std` workloads, and also re-exports
// useful crates that should be common across the entire ecosystem, such as `rand`.
use ark_std::{One, UniformRand};

let mut rng = ark_std::test_rng();
// Let's sample uniformly random field elements:
let a = F::rand(&mut rng);
let b = F::rand(&mut rng);
let c = <F as AdditiveGroup>::Scalar::rand(&mut rng);

// We can add...
let c = a + b;
// ... subtract ...
let d = a - b;
// ... double elements ...
assert_eq!(c + d, a.double());
// ... negate them ...
assert_ne!(d, -d);

// ... and multiply them by scalars:
let e = d * c;

《Field》特质为任何有限域提供了一个通用接口。实现《Field》特质的数据类型支持常见的域操作,如加法、减法、乘法和逆元,并且还必须实现《AdditiveGroup》特质。

use ark_ff::{AdditiveGroup, Field};
// We'll use a field associated with the BLS12-381 pairing-friendly
// group for this example.
use ark_test_curves::bls12_381::Fq2 as F;
// `ark-std` is a utility crate that enables `arkworks` libraries
// to easily support `std` and `no_std` workloads, and also re-exports
// useful crates that should be common across the entire ecosystem, such as `rand`.
use ark_std::{One, UniformRand};

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

// We can perform all the operations from the `AdditiveGroup` trait:
// We can add...
let c = a + b;
// ... subtract ...
let d = a - b;
// ... double elements ...
assert_eq!(c + d, a.double());

// ... multiply ...
let e = c * d;
// ... square elements ...
assert_eq!(e, a.square() - b.square());

// ... and compute inverses ...
assert_eq!(a.inverse().unwrap() * a, F::one()); // have to unwrap, as `a` could be zero.

在某些情况下,计算域元素的平方根很有用(例如:用于椭圆曲线元素的点压缩)。为此,用户可以为他们的域类型实现与《sqrt》相关的方法。这种方法已经为素数域实现(见下文),并且也适用于二次扩展域。

可以使用以下方式使用与《sqrt》相关的方法

use ark_ff::Field;
// As before, we'll use a field associated with the BLS12-381 pairing-friendly
// group for this example.
use ark_test_curves::bls12_381::Fq2 as F;
use ark_std::{One, UniformRand};

let mut rng = ark_std::test_rng();
let a = F::rand(&mut rng);

// We can check if a field element is a square by computing its Legendre symbol...
if a.legendre().is_qr() {
    // ... and if it is, we can compute its square root.
    let b = a.sqrt().unwrap();
    assert_eq!(b.square(), a);
} else {
    // Otherwise, we can check that the square root is `None`.
    assert_eq!(a.sqrt(), None);
}

素数域

如果域的阶为素数,则用户可以选择为它实现《PrimeField》特质。这提供了以下额外的API访问权限

use ark_ff::{Field, PrimeField, FpConfig, BigInteger, Zero};
// Now we'll use the prime field underlying the BLS12-381 G1 curve.
use ark_test_curves::bls12_381::Fq as F;
use ark_std::{One, UniformRand};

let mut rng = ark_std::test_rng();
let a = F::rand(&mut rng);
// We can access the prime modulus associated with `F`:
let modulus = <F as PrimeField>::MODULUS;
assert_eq!(a.pow(&modulus), a);

// We can convert field elements to integers in the range [0, MODULUS - 1]:
let one: num_bigint::BigUint = F::one().into();
assert_eq!(one, num_bigint::BigUint::one());

// We can construct field elements from an arbitrary sequence of bytes:
let n = F::from_le_bytes_mod_order(&modulus.to_bytes_le());
assert_eq!(n, F::zero());

依赖项

约2.5-3.5MB
约71K SLoC