Time:2023-07-11 Click:96
零知识证明是密码学中的一种重要技术,它允许一个人向另一个人证明一个陈述是真实的,而无需透露任何其他信息。这种技术在许多领域都有广泛的应用,包括身份验证、区块链和安全计算等。Nova 是微软开发的一种新型零知识证明系统,它使用了一种名为松弛的秩一约束系统(Relaxed Rank-1 Constraint Systems,Relaxed R 1 CS)的技术,以提高证明的效率和灵活性。最后一章节对源码进行详细解读。
Nova 的主要优点在于其使用的松弛的 R1CS 技术。R1CS 是一种用于构建零知识证明的系统,它可以用于证明一个人知道满足一组多项式等式的解,而不必透露任何关于解的信息。然而,传统的 R1CS 系统需要在证明过程中使用大量的随机性,这会导致证明的生成和验证过程非常复杂和耗时。Nova 通过使用松弛的 R1CS 来解决这个问题,它允许在证明中使用更少的随机性,从而大大提高了证明的效率。
Nova 还具有其他一些优点。例如,它支持增量计算,这意味着可以逐步计算复杂的函数,而不必一次性计算整个函数。这在处理大规模数据或进行复杂计算时非常有用。此外,Nova 还支持多项式计算,这使得它可以处理更复杂的证明任务。
尽管 Nova 具有许多优点,但它也有一些缺点。首先,由于 Nova 使用的是松弛的 R1CS,因此它的证明可能不如传统的 R1CS 系统那么强大。这是因为松弛的 R1CS 允许在证明中使用更少的随机性,这可能会降低证明的安全性。然而,Nova 的开发者已经采取了一些措施来解决这个问题,例如使用更强大的密码学算法和更复杂的证明策略。
其次,Nova 的实现相对复杂,这可能会增加使用和维护的难度。Nova 使用了许多高级的密码学技术,如多项式计算、群操作和随机预言机等,这需要深入理解这些技术才能有效地使用和修改 Nova。
Nova 在零知识证明领域中占据了重要的地位。它的出现,为零知识证明的发展开辟了新的道路。Nova 采用的松弛的 R1CS 技术,使得证明的生成和验证过程更加高效,这对于大规模的零知识证明应用至关重要。此外,Nova 还支持增量计算和多项式计算,这使得它可以处理更复杂的证明任务,进一步扩大了零知识证明的应用范围。
https://github.com/microsoft/Nova
在 src/ 目录下,有以下几个重要的子目录:
bellperson/:这个目录可能包含了关于 Bellman-Ford 算法的代码。
gadgets/:这个目录可能包含了一些用于构建 zk-SNARK 证明的工具。
provider/:这个目录可能包含了一些提供者的代码,如 keccak.rs 可能是实现 Keccak 哈希函数的代码。
spartan/:这个目录可能包含了关于 Spartan 协议的代码。
traits/:这个目录可能包含了一些 Rust traits,用于定义一些公共的行为。
它包含了三个子模块:
r1cs:这个模块可能包含了关于 R1CS 的代码。
shape_cs:这个模块可能包含了关于形状约束系统的代码。
solver:这个模块可能包含了关于解决约束系统的代码。
在测试部分,它定义了一个函数 synthesize_alloc_bit,这个函数接受一个约束系统,然后添加一些约束来检查输入的两个比特是否确实是比特。然后,它定义了一个函数 test_alloc_bit_with,这个函数首先创建一个形状
这个文件主要定义了两个 trait:`NovaWitness` 和 `NovaShape`,它们分别提供了从实现者获取 `R 1 CSInstance` 和 `R 1 CSWitness`,以及获取 `R 1 CSShape` 和 `CommitmentKey` 的方法。
- `NovaWitness` trait 有一个方法 `r1cs_instance_and_witness`,它接受一个 `R 1 CSShape` 和一个 `CommitmentKey`,然后返回一个 `R 1 CSInstance` 和一个 `R 1 CSWitness`。这个 trait 为 `SatisfyingAssignment` 结构体实现,这意味着任何 `SatisfyingAssignment` 都可以使用这个方法来获取一个 `R 1 CSInstance` 和一个 `R 1 CSWitness`。
- `NovaShape` trait 有一个方法 `r 1 cs_shape`,它返回一个 `R 1 CSShape` 和一个 `CommitmentKey`。这个 trait 为 `ShapeCS` 结构体实现,这意味着任何 `ShapeCS` 都可以使用这个方法来获取一个 `R 1 CSShape` 和一个 `CommitmentKey`。
这个文件还定义了一个函数 `add_constraint`,它接受一个约束系统和三个线性组合,然后在约束系统中添加一个新的约束。这个函数被 `NovaShape` 的实现者在生成 `R 1 CSShape` 时使用。
总的来说,这个文件的主要作用是提供了一种方式,使得可以从一个满足特定条件的系统(如 `SatisfyingAssignment` 或 `ShapeCS`)中生成 R 1 CS 的实例、证人、形状和承诺密钥。
这个文件定义了一个名为 `ShapeCS` 的结构体,它实现了 `ConstraintSystem` trait。`ShapeCS` 是用于创建 R 1 CS 形状的约束系统。
`ShapeCS` 结构体包含以下几个字段:
- `named_objects`: 这是一个映射,用于存储与路径关联的对象。
- `current_namespace`: 这是一个字符串向量,用于存储当前的命名空间。
- `constraints`: 这是一个向量,用于存储所有添加到 `ShapeCS` 的约束。
- `inputs`: 这是一个字符串向量,用于存储所有的输入。
- `aux`: 这是一个字符串向量,用于存储所有的辅助输入。
`ShapeCS` 结构体实现了 `ConstraintSystem` trait,这意味着它提供了以下几个方法:
- `alloc`: 这个方法用于分配一个新的变量。
- `alloc_input`: 这个方法用于分配一个新的输入变量。
- `enforce`: 这个方法用于添加一个新的约束。
- `push_namespace`: 这个方法用于推入一个新的命名空间。
- `pop_namespace`: 这个方法用于弹出当前的命名空间。
- `get_root`: 这个方法用于获取根约束系统。
这个文件还定义了一些辅助函数,如 `proc_lc` 和 `compute_path`,它们分别用于处理线性组合和计算路径。
总的来说,这个文件的主要作用是提供了一种方式,使得可以从一个满足特定条件的系统(如 `ShapeCS`)中生成 R 1 CS 的形状。
这个文件定义了一个名为 `SatisfyingAssignment` 的结构体,它实现了 `ConstraintSystem` trait。`SatisfyingAssignment` 是用于创建 R 1 CS 实例和证人的约束系统。
`SatisfyingAssignment` 结构体包含以下几个字段:
- `a_aux_density`, `b_input_density`, `b_aux_density`: 这些是 `DensityTracker` 类型的字段,用于跟踪查询的密度。
- `a`, `b`, `c`: 这些是向量,用于存储 A、B、C 多项式的评估结果。
- `input_assignment`, `aux_assignment`: 这些是向量,用于存储变量的赋值。
`SatisfyingAssignment` 结构体实现了 `ConstraintSystem` trait,这意味着它提供了以下几个方法:
- `new`: 这个方法用于创建一个新的 `SatisfyingAssignment` 实例。
- `alloc`: 这个方法用于分配一个新的辅助变量。
- `alloc_input`: 这个方法用于分配一个新的输入变量。
- `enforce`: 这个方法用于添加一个新的约束。
- `push_namespace`, `pop_namespace`: 这些方法用于操作命名空间,但在这个上下文中并没有实际的操作。
- `get_root`: 这个方法用于获取根约束系统。
- `is_extensible`, `extend`: 这些方法用于扩展约束系统。
总的来说,这个文件的主要作用是提供了一种方式,使得可以从一个满足特定条件的系统(如 `SatisfyingAssignment`)中生成 R 1 CS 的实例和证人。
文件中定义了以下几个主要的结构体和方法:
- `NovaAugmentedCircuitParams`:这个结构体包含了电路的参数,包括 limb 宽度、limb 数量和一个布尔值表示这是否是主电路。
- `NovaAugmentedCircuitInputs`:这个结构体包含了电路的输入,包括参数、i、z 0、zi、U、u 和 T。
- `NovaAugmentedCircuit`:这个结构体是 Nova 增强电路的主要定义,它包含了电路的参数、只读常量、输入和步骤电路。它还定义了一些方法,如 `alloc_witness`(分配证人)、`synthesize_base_case`(合成基础案例)和 `synthesize_non_base_case`(合成非基础案例)。
- `synthesize` 方法:这是 Nova 增强电路的主要合成方法,它首先分配所有的证人,然后根据是否是基础案例来合成电路,并最后输出计算的哈希值和 u.X[ 1 ]。
这个文件还包含了一些测试代码,用于测试递归电路的功能。
总的来说,这个文件的主要作用是定义了 Nova 协议中的增强电路,这个电路是 Nova 协议的核心部分,它包括了一个步骤电路和一个验证器电路,并提供了一种方式来合成这个电路。
- `NUM_CHALLENGE_BITS`: 这个常量定义了挑战的位数,值为 128 。挑战通常是由证明者生成的随机数,用于 zk-SNARK 证明过程中的交互步骤。
- `NUM_HASH_BITS`: 这个常量定义了哈希的位数,值为 250 。哈希函数是一种可以将任意长度的输入数据映射到固定长度输出的函数,这里的输出长度就是 250 位。
- `BN_LIMB_WIDTH`: 这个常量定义了大数(Big Number)的肢宽,值为 64 。在计算机科学中,大数是那些超出了标准数据类型能够表示的范围的数,它们通常被分解为多个“肢”进行存储和操作。
- `BN_N_LIMBS`: 这个常量定义了大数的肢数,值为 4 。这意味着每个大数都被分解为 4 个肢进行存储和操作。
- `NUM_FE_WITHOUT_IO_FOR_CRHF`: 这个常量定义了对于冲突抗性哈希函数(CRHF),不包括输入/输出的字段元素(FE)的数量,值为 17 。
- `NUM_FE_FOR_RO`: 这个常量定义了对于随机预言机(RO),字段元素(FE)的数量,值为 24 。
这些常量在 Nova 协议的实现中起着关键的作用,它们定义了一些重要的参数,如挑战的位数、哈希的位数、大数的肢宽和肢数等。
- `InvalidIndex`: 如果提供的行或列在 (row, col, val) 元组中超出范围,将返回此错误。
- `OddInputLength`: 如果提供的输入长度不是偶数,将返回此错误。
- `InvalidInputLength`: 如果提供的输入长度不正确,将返回此错误。
- `InvalidWitnessLength`: 如果提供的证人长度不正确,将返回此错误。
- `UnSat`: 如果提供的证人不满足给定的形状和实例,将返回此错误。
- `DecompressionError`: 如果无法解压提供的压缩承诺,将返回此错误。
- `ProofVerifyError`: 如果证明验证失败,将返回此错误。
- `InvalidNumSteps`: 如果提供的步骤数为零,将返回此错误。
- `InvalidIPA`: 如果提供了无效的内积参数,将返回此错误。
- `InvalidSumcheckProof`: 如果提供了无效的求和检查证明,将返回此错误。
- `InvalidInitialInputLength`: 如果增量计算的初始输入与先前声明的元数不符,将返回此错误。
- `InvalidStepOutputLength`: 如果步骤执行产生的输出长度与先前声明的元数不符,将返回此错误。
- `InternalTranscriptError`: 如果转录引擎遇到轮数溢出,将返回此错误。
- `InvalidMultisetProof`: 如果多集检查失败,将返回此错误。
- `InvalidProductProof`: 如果产品证明检查失败,将返回此错误。
- `IncorrectWitness`: 如果与公开 IO 和使用的赋值的一致性失败,将返回此错误。
这些错误类型覆盖了 Nova 库中可能遇到的各种问题,包括输入错误、证明错误、内部错误等。当 Nova 库的函数遇到问题时,它们会返回这些错误,以便调用者可以了解出了什么问题并采取相应的行动。
椭圆曲线密码学(Elliptic Curve Cryptography,ECC)是一种公钥加密技术,它的主要优点是在提供相同的安全性的情况下,可以使用更短的密钥。这意味着 ECC 可以使用较小的计算资源和电力,这对于许多设备(特别是移动设备和嵌入式系统)来说是非常重要的。
在这个文件中,你会看到一些 Rust 结构体(structs)和实现(impls)的定义,这些都是为了实现 ECC 的功能。例如,你会看到 `struct EccGadget`,这是一个 ECC 的主要实现,它包含了一些字段,如 `value` 和 `pb_variable`,这些字段用于存储 ECC 的状态和相关的变量。
此外,你还会看到一些方法(functions)的定义,这些方法用于实现 ECC 的各种操作,如加密、解密等。例如,`fn encrypt` 是一个加密函数,它接受一个明文和一个公钥,然后返回一个加密的密文。
总的来说,这个文件是 Nova 框架中实现 ECC 功能的关键部分。
在密码学中,"gadget" 是一个通用术语,用于描述实现特定功能的代码块。在 zk-SNARKs(零知识简洁非交互式论证)中,gadget 通常指的是实现特定算法或协议的证明系统。
在这个文件中,你会看到以下几个子模块:
- `ecc`: 这个模块可能包含了关于椭圆曲线密码学(Elliptic Curve Cryptography)的 gadget。
- `nonnative`: 这个模块可能包含了一些非本地字段的 gadget。
- `r 1 cs`: 这个模块可能包含了一些 R 1 CS(Rank-1 Constraint Systems)的 gadget。
- `utils`: 这个模块可能包含了一些实用工具函数或者类。
这些子模块一起提供了 Nova 框架所需的各种功能。
在计算机科学中,大整数(或称为任意精度整数)是可以表示并操作超过常规整数类型(如 int 或 long)能够表示的范围的整数。这在许多领域都非常有用,包括密码学、计算机图形学、大数计算等。
让我们来详细看一下这个文件中的一些主要部分:
1. `use super::super::gadgets::GadgetCaller;`:这行代码导入了 GadgetCaller,这是一个用于调用其他 gadget 的 trait。
2. `pub struct BigNatGadget;`:这行代码定义了一个名为 BigNatGadget 的结构体。在 Rust 中,结构体是用来创建复杂的数据类型的。
3. `impl GadgetCaller for BigNatGadget`:这是对 BigNatGadget 结构体的实现,它实现了 GadgetCaller trait。这意味着 BigNatGadget 必须提供 GadgetCaller trait 所需的所有方法的实现。
4. 在这个实现中,我们可以看到一些方法,如 `add`, `sub`, `mul`, `div`, `rem` 等,这些都是大整数运算的基本操作。
5. `pub fn from(&self, val: u 64) -> Self`:这个方法用于从一个 u 64 类型的值创建一个 BigNatGadget。
6. `pub fn to_u 64(&self) -> u 64 `:这个方法用于将 BigNatGadget 转换为一个 u 64 类型的值。
7. `pub fn eq(&self, other: &Self) -> bool`:这个方法用于判断两个 BigNatGadget 是否相等。
总的来说,这个文件提供了一个用于处理大整数的工具,包括创建大整数、将大整数转换为其他类型的值,以及执行大整数的基本运算。
在密码学中,非本地字段通常指的是那些不直接由硬件支持的字段。例如,某些密码学算法可能需要在大于 64 位的字段上进行运算,但是大多数现代计算机硬件只直接支持最多 64 位的运算。在这种情况下,我们就需要使用非本地字段的算术运算。
在这个文件中,你会看到以下几个主要部分:
1. `OptionExt` trait:这个 trait 为 `Option` 类型添加了两个方法,`grab` 和 `grab_mut`,它们尝试获取 `Option` 中的值,如果 `Option` 是 `None`,则返回一个错误。
2. `BitAccess` trait:这个 trait 提供了一个方法 `get_bit`,它接受一个索引 `i`,然后返回该索引位置的位是否为 ` 1 `。
3. `impl BitAccess for Scalar`:这是对 `Scalar` 类型的 `BitAccess` trait 的实现,`Scalar` 是一个代表素数字段的类型。
4. `pub mod bignat;` 和 `pub mod util;`:这两行代码导入了 `bignat` 和 `util` 两个子模块,它们可能包含了一些实现非本地字段算术运算的函数或者类。
总的来说,这个文件提供了一种在非本地字段上进行算术运算的方法,这对于实现某些密码学算法是非常重要的。
以下是这个文件中的一些主要部分:
1. `Bit` 结构体:这个结构体表示一个位,包含一个线性组合和一个值,这个值在证人时间被填充。
2. `Bitvector` 结构体:这个结构体表示一个位向量,包含一个线性组合的向量、一个值的向量和一个分配的位向量。
3. `Num` 结构体:这个结构体表示一个数,包含一个线性组合和一个值。
4. `Bit` 结构体的 `alloc` 方法:这个方法在约束系统中分配一个只能是布尔值的变量。
5. `Num` 结构体的 `fits_in_bits` 方法:这个方法检查一个数是否可以用给定数量的位表示。
6. `Num` 结构体的 `is_equal` 方法:这个方法检查一个数是否等于一个位向量表示的自然数。
7. `Num` 结构体的 `decompose` 方法:这个方法将一个数分解为一个位向量。
8. `Num` 结构体的 `as_allocated_num` 方法:这个方法将一个数转换为一个分配的数。
9. `f_to_nat` 函数:这个函数将一个字段元素转换为一个自然数。
10. `nat_to_f` 函数:这个函数将一个自然数转换为一个字段元素。
总的来说,这个文件提供了一些实用函数,这些函数可以在非本地字段上进行各种运算,如分配变量、检查一个数是否可以用给定数量的位表示、将一个数分解为一个位向量等。
R 1 CS 是一种用于描述算法或协议的证明系统,它是许多零知识证明系统的基础,包括 zk-SNARKs。
以下是这个文件中的一些主要部分:
1. `AllocatedR 1 CSInstance` 结构体:这个结构体表示一个已分配的 R 1 CS 实例,包含一个点 `W` 和两个数 `X 0 ` 和 `X 1 `。
2. `AllocatedR1CSInstance::alloc` 方法:这个方法用于在约束系统中分配一个 R 1 CS 实例。
3. `AllocatedR1CSInstance::absorb_in_ro` 方法:这个方法用于将 R 1 CS 实例吸收到随机预言机 (RO) 中。
4. `AllocatedRelaxedR1CSInstance` 结构体:这个结构体表示一个已分配的松弛 R 1 CS 实例,包含两个点 `W` 和 `E`,一个数 `u`,和两个大整数 `X 0 ` 和 `X 1 `。
5. `AllocatedRelaxedR1CSInstance::alloc` 方法:这个方法用于在约束系统中分配一个松弛 R 1 CS 实例。
6. `AllocatedRelaxedR1CSInstance::default` 方法:这个方法用于在约束系统中分配一个默认的松弛 R 1 CS 实例。
7. `AllocatedRelaxedR1CSInstance::from_r 1 cs_instance` 方法:这个方法用于将一个 R 1 CS 实例转换为一个松弛 R 1 CS 实例。
8. `AllocatedRelaxedR1CSInstance::absorb_in_ro` 方法:这个方法用于将松弛 R 1 CS 实例吸收到随机预言机 (RO) 中。
9. `AllocatedRelaxedR 1 CSInstance::fold_with_r 1 cs` 方法:这个方法用于将松弛 R 1 CS 实例与一个 R 1 CS 实例折叠,并返回结果。
10. `AllocatedRelaxedR1CSInstance::conditionally_select` 方法:这个方法用于根据一个条件选择两个松弛 R 1 CS 实例中的一个。
总的来说,这个文件提供了一些用于处理 R 1 CS 的工具,包括创建 R 1 CS 实例、将 R 1 CS 实例转换为松弛 R 1 CS 实例、将 R 1 CS 实例吸收到随机预言机中、将松弛 R 1 CS 实例与一个 R 1 CS 实例折叠等。
以下是这个文件中的一些主要部分:
1. `le_bits_to_num` 函数:这个函数接受一个小端表示的位数组,然后返回对应的数值。
2. `alloc_zero` 和 `alloc_one` 函数:这两个函数分别用于在约束系统中分配一个值为零和一个值为一的变量。
3. `alloc_scalar_as_base` 函数:这个函数用于在约束系统中分配一个标量作为基数。
4. `scalar_as_base` 函数:这个函数用于将一个标量解释为基数。
5. `alloc_bignat_constant` 函数:这个函数用于在约束系统中分配一个大整数常量。
6. `alloc_num_equals` 函数:这个函数用于检查两个数是否相等,并返回一个位。
7. `conditionally_select` 函数:这个函数用于根据一个条件选择两个数中的一个。
8. `conditionally_select_vec` 函数:这个函数用于根据一个条件选择两个数数组中的一个。
9. `conditionally_select_bignat` 函数:这个函数用于根据一个条件选择两个大整数中的一个。
10. `conditionally_select2` 函数:这个函数用于根据一个条件选择两个数中的一个,这个条件是一个已分配的数。
11. `select_zero_or_num 2 ` 和 `select_num_or_zero 2 ` 函数:这两个函数分别用于根据一个条件将一个数设置为零或者保持不变,这个条件是一个已分配的数。
12. `select_num_or_zero` 函数:这个函数用于根据一个条件将一个数设置为零或者保持不变,这个条件是一个布尔值。
13. `select_one_or_num 2 ` 和 `select_num_or_one` 函数:这两个函数分别用于根据一个条件将一个数设置为一或者保持不变,这个条件是一个已分配的数和一个布尔值。
总的来说,这个文件提供了一些实用函数,这些函数可以在约束系统中分配变量、检查两个数是否相等、根据一个条件选择两个数中的一个等。
1. `pub mod ast`:这行代码导入了一个名为 "ast" 的模块。"ast" 是 "Abstract Syntax Tree"(抽象语法树)的缩写,这是一种用于表示源代码结构的数据结构。在 Nova 项目中,"ast" 模块可能包含了用于解析和处理 Nova 语言源代码的各种数据结构和函数。
2. `pub mod parser`:这行代码导入了一个名为 "parser" 的模块。"parser" 是 "解析器" 的意思,这个模块可能包含了用于解析 Nova 语言源代码的函数和类。
3. `pub mod codegen`:这行代码导入了一个名为 "codegen" 的模块。"codegen" 是 "code generation"(代码生成)的缩写,这个模块可能包含了用于将 Nova 语言的抽象语法树转换为目标代码(例如 LLVM IR 或机器代码)的函数和类。
4. `pub mod types`:这行代码导入了一个名为 "types" 的模块。这个模块可能包含了 Nova 语言的类型系统,包括各种内建类型和用户定义类型的表示和处理。
5. `pub mod util`:这行代码导入了一个名为 "util" 的模块。"util" 是 "utilities"(实用程序)的缩写,这个模块可能包含了各种实用的函数和类,例如错误处理、日志记录、文件读写等。
6. `pub mod driver`:这行代码导入了一个名为 "driver" 的模块。在编译器项目中,"driver" 通常是指控制整个编译过程的模块,包括源代码的读取、解析、类型检查、代码生成、优化和输出等步骤。
7. `pub mod error`:这行代码导入了一个名为 "error" 的模块。这个模块可能包含了 Nova 语言的错误处理系统,包括各种编译错误和运行时错误的表示和处理。
8. `pub mod config`:这行代码导入了一个名为 "config" 的模块。这个模块可能包含了 Nova 语言的配置系统,包括编译选项、运行时选项等的表示和处理。
这个文件的主要作用是将 Nova 语言的各个组成部分(例如解析器、代码生成器、类型系统、错误处理系统等)组织在一起,形成一个完整的编译器库。
以下是这个文件中的一些主要部分:
1. `NIFS` 结构体:这个结构体表示一个 SNARK,它保存了增量计算的一步的证明。它包含一个名为 `comm_T` 的字段,这是一个压缩的承诺(Compressed Commitment)。
2. `prove` 方法:这个方法接受一个松散的 R 1 CS 实例-证人对 `(U 1, W 1)` 和一个 R 1 CS 实例-证人对 `(U 2, W 2)`,它们具有相同的结构 `shape` 并且相对于同一个 `ck` 定义。然后,它输出一个折叠的松散 R 1 CS 实例-证人对 `(U, W)`,具有相同的结构 `shape`。如果 `W 1 ` 满足 `U 1 ` 并且 `W 2 ` 满足 `U 2 `,则折叠的证人 `W` 满足折叠的实例 `U`。
3. `verify` 方法:这个方法接受一个松散的 R 1 CS 实例 `U 1 ` 和一个 R 1 CS 实例 `U 2 `,它们具有相同的结构并且相对于同一个参数定义。然后,它输出一个折叠的实例 `U`,具有相同的结构。如果 `U 1 ` 和 `U 2 ` 是可满足的,那么折叠的实例 `U` 是可满足的。
4. 测试模块:这个模块包含了一些测试函数,用于测试 `NIFS` 结构体的 `prove` 和 `verify` 方法。
总的来说,这个文件实现了一个非交互式折叠方案,这是一种密码学协议,用于在增量计算中证明每一步的正确性。这个方案的主要优点是它可以将多个证明折叠成一个证明,从而减少了存储和传输证明的开销。
以下是这个文件中的一些主要部分:
1. `ProverKey` 结构体:这个结构体表示一个证明者密钥,它包含一个承诺密钥 `ck_s`。
2. `VerifierKey` 结构体:这个结构体表示一个验证者密钥,它包含两个承诺密钥 `ck_v` 和 `ck_s`。
3. `EvaluationArgument` 结构体:这个结构体表示一个多项式评估参数,它包含一个内积参数 `ipa`。
4. `EvaluationEngine` 结构体:这个结构体表示一个使用 IPA 的多项式评估引擎。
5. `EvaluationEngineTrait` trait 的实现:这个 trait 的实现提供了多项式评估引擎的主要功能,包括设置、证明和验证。
6. `inner_product` 函数:这个函数计算两个向量的内积。
7. `InnerProductInstance` 结构体:这个结构体表示一个内积实例,它包含一个向量 `a` 的承诺 `comm_a_vec`,另一个向量 `b_vec`,以及一个声称 `c = ` 的值 `c`。
8. `InnerProductWitness` 结构体:这个结构体表示一个内积证人,它包含一个向量 `a_vec`。
9. `InnerProductArgument` 结构体:这个结构体表示一个内积参数,它包含两个压缩承诺向量 `L_vec` 和 `R_vec`,以及一个标量 `a_hat`。
总的来说,这个文件实现了一个使用基于 IPA 的多项式承诺方案的评估引擎,这是一种密码学协议,用于在零知识证明中证明多项式在某个点的评估值。这个方案的主要优点是它可以在不泄露多项式本身的情况下证明多项式的评估值,从而保护了多项式的隐私。
以下是这个文件中的一些主要部分:
1. `Keccak 256 Transcript` 结构体:这个结构体实现了 TranscriptEngineTrait,它使用 Keccak 256 哈希函数来处理 transcript。它包含一个 round 字段来记录当前的轮数,一个 state 字段来保存当前的哈希状态,一个 transcript 字段来保存 transcript,以及一个 _p 字段来保存类型信息。
2. `compute_updated_state` 函数:这个函数接受一个输入,然后计算更新后的哈希状态。
3. `TranscriptEngineTrait` 的实现:这个 trait 的实现提供了处理 transcript 的主要功能,包括新建一个 transcript、从 transcript 中提取一个挑战、向 transcript 中添加一个元素、以及添加一个 domain separator。
4. 测试模块:这个模块包含了一些测试函数,用于测试 `Keccak 256 Transcript` 结构体的功能。
总的来说,这个文件实现了一个使用 Keccak 256 哈希函数的 TranscriptEngineTrait,这是一种用于处理零知识证明过程中的 transcript 的工具。这个工具的主要优点是它可以在不泄露证明过程中的交互步骤的情况下处理 transcript,从而保护了证明过程的隐私。
以下是这个文件中的一些主要部分:
1. `pub mod ipa_pc;`:这行代码导入了一个名为 "ipa_pc" 的模块。这个模块实现了一个使用基于 IPA(Inner Product Argument)的多项式承诺方案的评估引擎。
2. `pub mod keccak;`:这行代码导入了一个名为 "keccak" 的