当前位置: 首页 > news >正文

ZKP3.2 Programming ZKPs (Arkworks Zokrates)

ZKP学习笔记

ZK-Learning MOOC课程笔记

Lecture 3: Programming ZKPs (Guest Lecturers: Pratyush Mishra and Alex Ozdemir)

3.3 Using a library (+ tutorial)

  • R1CS Libraries
    • A library in a host language (Eg: Rust, OCaml, C++, Go, …)
    • Key type: constraint system
      • Maintains state about R1CS constraints and variables
    • Key operations:
      • create variable
      • create linear combinations of variables
      • add constraint
  • ConstraintSystem Operations
//Variable creation
cs.add_var(p, v) → id//Linear Combination creation
cs.zero()
lc.add(c, id) → lc_
//lc_ := lc + c * id//Adding constraints
cs.constrain(lcA, lcB, lcC)
//Adds a constraint lcA × lcB = lcC
  • Arkworks Tutorial
// main.rs
use ark_ff::PrimeField;
use ark_r1cs_std::{prelude::{Boolean, EqGadget, AllocVar},uint8::UInt8
};
use ark_relations::r1cs::{SynthesisError, ConstraintSystem};
use cmp::CmpGadget;mod cmp;
mod alloc;pub struct Puzzle<const N: usize, ConstraintF: PrimeField>([[UInt8<ConstraintF>; N]; N]);
pub struct Solution<const N: usize, ConstraintF: PrimeField>([[UInt8<ConstraintF>; N]; N]);fn check_rows<const N: usize, ConstraintF: PrimeField>(solution: &Solution<N, ConstraintF>,
) -> Result<(), SynthesisError> {for row in &solution.0 {for (j, cell) in row.iter().enumerate() {for prior_cell in &row[0..j] {cell.is_neq(&prior_cell)?.enforce_equal(&Boolean::TRUE)?;}}}Ok(())
}fn check_puzzle_matches_solution<const N: usize, ConstraintF: PrimeField>(puzzle: &Puzzle<N, ConstraintF>,solution: &Solution<N, ConstraintF>,
) -> Result<(), SynthesisError> {for (p_row, s_row) in puzzle.0.iter().zip(&solution.0) {for (p, s) in p_row.iter().zip(s_row) {// Ensure that the solution `s` is in the range [1, N]s.is_leq(&UInt8::constant(N as u8))?.and(&s.is_geq(&UInt8::constant(1))?)?.enforce_equal(&Boolean::TRUE)?;// Ensure that either the puzzle slot is 0, or that// the slot matches equivalent slot in the solution(p.is_eq(s)?.or(&p.is_eq(&UInt8::constant(0))?)?).enforce_equal(&Boolean::TRUE)?;}}Ok(())
}fn check_helper<const N: usize, ConstraintF: PrimeField>(puzzle: &[[u8; N]; N],solution: &[[u8; N]; N],
) {let cs = ConstraintSystem::<ConstraintF>::new_ref();let puzzle_var = Puzzle::new_input(cs.clone(), || Ok(puzzle)).unwrap();let solution_var = Solution::new_witness(cs.clone(), || Ok(solution)).unwrap();check_puzzle_matches_solution(&puzzle_var, &solution_var).unwrap();check_rows(&solution_var).unwrap();assert!(cs.is_satisfied().unwrap());
}fn main() {use ark_bls12_381::Fq as F;// Check that it accepts a valid solution.let puzzle = [[1, 0],[0, 2],];let solution = [[1, 2],[1, 2],];check_helper::<2, F>(&puzzle, &solution);// Check that it rejects a solution with a repeated number in a row.let puzzle = [[1, 0],[0, 2],];let solution = [[1, 0],[1, 2],];check_helper::<2, F>(&puzzle, &solution);
}// cmp.rs
use ark_ff::PrimeField;
use ark_r1cs_std::{prelude::{Boolean, EqGadget}, R1CSVar, uint8::UInt8, ToBitsGadget};
use ark_relations::r1cs::SynthesisError;pub trait CmpGadget<ConstraintF: PrimeField>: R1CSVar<ConstraintF> + EqGadget<ConstraintF> {#[inline]fn is_geq(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError> {// self >= other => self == other || self > other//               => !(self < other)self.is_lt(other).map(|b| b.not())}#[inline]fn is_leq(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError> {// self <= other => self == other || self < other//               => self == other || other > self//               => self >= otherother.is_geq(self)}#[inline]fn is_gt(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError> {// self > other => !(self == other  || self < other)//              => !(self <= other)self.is_leq(other).map(|b| b.not())}fn is_lt(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError>; 
}impl<ConstraintF: PrimeField> CmpGadget<ConstraintF> for UInt8<ConstraintF> {fn is_lt(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError> {// Determine the variable mode.if self.is_constant() && other.is_constant() {let self_value = self.value().unwrap();let other_value = other.value().unwrap();let result = Boolean::constant(self_value < other_value);Ok(result)} else {let diff_bits = self.xor(other)?.to_bits_be()?.into_iter();let mut result = Boolean::FALSE;let mut a_and_b_equal_so_far = Boolean::TRUE;let a_bits = self.to_bits_be()?;let b_bits = other.to_bits_be()?;for ((a_and_b_are_unequal, a), b) in diff_bits.zip(a_bits).zip(b_bits) {let a_is_lt_b = a.not().and(&b)?;let a_and_b_are_equal = a_and_b_are_unequal.not();result = result.or(&a_is_lt_b.and(&a_and_b_equal_so_far)?)?;a_and_b_equal_so_far = a_and_b_equal_so_far.and(&a_and_b_are_equal)?;}Ok(result)}}
}#[cfg(test)]
mod test {use ark_r1cs_std::{prelude::{AllocationMode, AllocVar, Boolean, EqGadget}, uint8::UInt8};use ark_relations::r1cs::{ConstraintSystem, SynthesisMode};use ark_bls12_381::Fr as Fp;use itertools::Itertools;use crate::cmp::CmpGadget;#[test]fn test_comparison_for_u8() {let modes = [AllocationMode::Constant, AllocationMode::Input, AllocationMode::Witness];for (a, a_mode) in (0..=u8::MAX).cartesian_product(modes) {for (b, b_mode) in (0..=u8::MAX).cartesian_product(modes) {let cs = ConstraintSystem::<Fp>::new_ref();cs.set_mode(SynthesisMode::Prove { construct_matrices: true });let a_var = UInt8::new_variable(cs.clone(), || Ok(a), a_mode).unwrap();let b_var = UInt8::new_variable(cs.clone(), || Ok(b), b_mode).unwrap();if a < b {a_var.is_lt(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();a_var.is_leq(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();a_var.is_gt(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();a_var.is_geq(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();} else if a == b {a_var.is_lt(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();a_var.is_leq(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();a_var.is_gt(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();a_var.is_geq(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();} else {a_var.is_lt(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();a_var.is_leq(&b_var).unwrap().enforce_equal(&Boolean::FALSE).unwrap();a_var.is_gt(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();a_var.is_geq(&b_var).unwrap().enforce_equal(&Boolean::TRUE).unwrap();}assert!(cs.is_satisfied().unwrap(), "a: {a}, b: {b}");}}}
}//alloc.rs
use std::borrow::Borrow;use ark_ff::PrimeField;
use ark_r1cs_std::{prelude::{AllocVar, AllocationMode}, uint8::UInt8};
use ark_relations::r1cs::{Namespace, SynthesisError};use crate::{Puzzle, Solution};impl<const N: usize, F: PrimeField> AllocVar<[[u8; N]; N], F> for Puzzle<N, F> {fn new_variable<T: Borrow<[[u8; N]; N]>>(cs: impl Into<Namespace<F>>,f: impl FnOnce() -> Result<T, SynthesisError>,mode: AllocationMode,) -> Result<Self, SynthesisError> {let cs = cs.into();let row = [(); N].map(|_| UInt8::constant(0));let mut puzzle = Puzzle([(); N].map(|_| row.clone()));let value = f().map_or([[0; N]; N], |f| *f.borrow());for (i, row) in value.into_iter().enumerate() {for (j, cell) in row.into_iter().enumerate() {puzzle.0[i][j] = UInt8::new_variable(cs.clone(), || Ok(cell), mode)?;}}Ok(puzzle)}
} impl<const N: usize, F: PrimeField> AllocVar<[[u8; N]; N], F> for Solution<N, F> {fn new_variable<T: Borrow<[[u8; N]; N]>>(cs: impl Into<Namespace<F>>,f: impl FnOnce() -> Result<T, SynthesisError>,mode: AllocationMode,) -> Result<Self, SynthesisError> {let cs = cs.into();let row = [(); N].map(|_| UInt8::constant(0));let mut solution = Solution([(); N].map(|_| row.clone()));let value = f().map_or([[0; N]; N], |f| *f.borrow());for (i, row) in value.into_iter().enumerate() {for (j, cell) in row.into_iter().enumerate() {solution.0[i][j] = UInt8::new_variable(cs.clone(), || Ok(cell), mode)?;}}Ok(solution)}
}

3.4 Using a compiler (+ tutorial)

  • HDLs & Circuit Libraries
    • Difference: Host language v. custom language
    • Similarities: explicit wire creation (explicitly wire values); explicit constraint creation
  • ZoKrates Tutorial
struct Puzzle<N> {u8[N][N] elems;
}
struct Solution<N> {u8[N][N] elems;
}def check_rows<N>(Solution<N> sol) -> bool {// for each rowfor u32 i in 0..N {// for each columnfor u32 j in 0..N {// Check that the (i, j)-th element is not equal to any of the// the elements preceding it in the same row.for u32 k in 0..j {assert(sol.elems[i][j] != sol.elems[i][k]);}}}return true;
}def check_puzzle_matches_solution<N>(Solution<N> sol, Puzzle<N> puzzle) -> bool {for u32 i in 0..N {for u32 j in 0..N {assert((sol.elems[i][j] > 0) && (sol.elems[i][j] < 10));assert(\(puzzle.elems[i][j] == 0) ||\(puzzle.elems[i][j] == sol.elems[i][j])\);}}return true;
}def main(public Puzzle<2> puzzle, private Solution<2> sol) {assert(check_puzzle_matches_solution(sol, puzzle));assert(check_rows(sol));
}

3.5 An overview of prominent ZKP toolchains

  • Toolchain Type
    在这里插入图片描述

在这里插入图片描述

  • Other toolchains
    在这里插入图片描述

  • Shared Compiler Infrastructure

    • CirC: https://github.com/circify/circ
      在这里插入图片描述

相关文章:

ZKP3.2 Programming ZKPs (Arkworks Zokrates)

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 3: Programming ZKPs (Guest Lecturers: Pratyush Mishra and Alex Ozdemir) 3.3 Using a library ( tutorial) R1CS Libraries A library in a host language (Eg: Rust, OCaml, C, Go, …)Key type: constraint system Mai…...

mysqld: File ‘./binlog.index‘ not found (OS errno 13 - Permission denied) 问题解决

问题背景 Centos7 安装Mysql 8后启动时遇到的问题&#xff0c;看了好几个博客方案无效&#xff0c;搞了半小时才找到正解&#xff0c;在此次进行记录。 在此假设你已经修改了对应目录的权限&#xff0c;比如配置的mysql data目录初始化后已经执行了chown -R mysql:mysql /XXX/…...

Python 环境构建最佳实践:Mamba + Conda + PIP

此前,我们单独介绍过 PIP 和 Conda,在后续的实际应用中,还是遇到了不少 Python 环境构建的问题,特别是在 Windows 系统上,最突出的表现是:虽然PIP的包依赖解析和下载都很快,但在 Windows 上经常会因为缺失底层依赖的程序库(例如某些dll文件)而导致 Python 程序启动时报…...

华为OD 最多团队(100分)【java】A卷+B卷

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…...

2023“龙芯杯”信创攻防赛 | 赛宁网安技术支持

2023年10月19日&#xff0c;为深入贯彻国家网络强国战略思想&#xff0c;宣传国家网络安全顶层设计&#xff0c;落实《网络安全法》《数据安全法》等法律法规。由大学生网络安全尖锋训练营主办&#xff0c;龙芯中科技术股份有限公司承办&#xff0c;山石网科通信技术股份有限公…...

代码随想录算法训练营第五十八天| 583. 两个字符串的删除操作 72. 编辑距离

今日学习的文章链接和视频链接 两个字符串的删除操作 https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html 编辑距离 https://programmercarl.com/0072.%E7%BC%96%E8%BE%91%E8%B7%9D%E7%A6%BB…...

leetcode做题笔记191. 位1的个数

编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为汉明重量&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中…...

Git基本命令和使用

文章目录 1、Git本地库命令1.1、初始化本地库1.2、设置用户签名1.3、查看本地库状态1.4、将工作区的修改添加到暂存区1.5、将暂存区的修改提交到本地库1.6、历史版本1.7、取消commit1.8、取消暂存文件 2、分支操作2.1、查看分支2.2、创建分支2.3、分支合并时产生冲突 3、Gitee远…...

50springboot私人健身与教练预约管理系统

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…...

测试Android webview 加载本地html

最近开发一个需要未联网功能的App, 不熟悉使用Java原生开发界面&#xff0c;于是想使用本地H5做界面&#xff0c;本文测试了使用本地html加载远程数据。直接上代码&#xff1a; MainActivity.java package com.alex.webviewlocal;import androidx.appcompat.app.AppCompatAct…...

ubuntu安装pgsql

ubuntu安装postgresSQL 官网地址&#xff1a; https://www.postgresql.org/download/ 1.安装 # 添加源 sudo sh -c echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list # 安装数字签名 w…...

利用ArcGIS获取每一个冰川的中心位置经纬度坐标:要素转点和要素折点转点的区别

问题概述&#xff1a;下图是天山地区的冰川的分布&#xff0c;我们可以看到每一条冰川是一个面要素&#xff0c;要求得到每一个冰川&#xff08;面要素&#xff09;的中心经纬度坐标。 1.采用要素转点功能 选择工具箱的【数据管理工具】-【要素】-【要素转点】。完成之后再采用…...

数据结构中的七大排序(Java实现)

目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 一、直接插入排序 思想&#xff1a; 定义i下标之前的元素全部已经有序&#xff0c;遍历一遍要排序的数组&#xff0c;把i下标前的元素全部进行排序&#xff0…...

深度学习基础算法

算法 1.K近邻算法 机器学习--K-近邻算法(KNN)_k近邻-CSDN博客 2. 数据库样本: CIFAR-10 CIFAR-10数据集&#xff08;介绍、下载读取、可视化显示、另存为图片&#xff09;_cifar10数据集-CSDN博客...

LuatOS-SOC接口文档(air780E)-- ir - 红外遥控

ir.sendNEC(pin, addr, cmd, repeat, disablePWM)# 发送NEC数据 参数 传入值类型 解释 int 使用的GPIO引脚编号 int 用户码&#xff08;大于0xff则采用Extended NEC模式&#xff09; int 数据码 int 可选&#xff0c;引导码发送次数&#xff08;110ms一次&#xff0…...

Java虚拟机常见面试题总结

梳理Java虚拟机相关的面试题&#xff0c;主要参考《深入理解Java虚拟机 JVM高级特性与最佳实践》(第2版, 周志明 著)一书&#xff0c;其余部分整合网络相关内容。注意&#xff0c;关于Java并发编程的面试题因为内容较多&#xff0c;单独整理。Java基础相关的面试题可以参考Java…...

NVIDIA NCCL 源码学习(十一)- ring allreduce

之前的章节里我们看到了nccl send/recv通信的过程&#xff0c;本节我们以ring allreduce为例看下集合通信的过程。整体执行流程和send/recv很像&#xff0c;所以对于相似的流程只做简单介绍&#xff0c;主要介绍ring allreduce自己特有内容。 单机 搜索ring 在nccl初始化的过…...

前端--性能优化【上篇】--网络优化与页面渲染优化

一、网络优化 1、DNS预解析 link标签的rel属性设置dns-prefetch&#xff0c;提前获取域名对应的IP地址 2、CDN&#xff08;网络分发系统&#xff09; 用户与服务器的物理距离对响应时间也有影响。 内容分发网络&#xff08;CDN&#xff09;是一组分散在不同地理位置的 web…...

git 删除分支

目录 1&#xff0c;查看分支2&#xff0c;删除本地分支3&#xff0c;删除远程分支 1&#xff0c;查看分支 # 查看本地分支 git branch# 查看远程分支 git branch -r# 查看所有分支 git branch -a2&#xff0c;删除本地分支 # -d 是 --delete 的简写&#xff0c;会在删除前检查…...

SQLite Write-ahead Logging

1. 概述2. WAL如何工作 2.1 检验指示(Checkpointing)2.2 并发性(Concurrency)2.3 性能考虑(Performance Considerations)3. 激活并配置WAL模式 3.1 自动checkpoint3.2 应用开始的checkpoint3.3 WAL模式的持久性4. 只读数据库5. 避免过大的WAL文件6. WAL索引的共享内存应用7. 不…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

【Redis】Redis从入门到实战:全面指南

Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...