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

- 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后启动时遇到的问题,看了好几个博客方案无效,搞了半小时才找到正解,在此次进行记录。 在此假设你已经修改了对应目录的权限,比如配置的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日,为深入贯彻国家网络强国战略思想,宣传国家网络安全顶层设计,落实《网络安全法》《数据安全法》等法律法规。由大学生网络安全尖锋训练营主办,龙芯中科技术股份有限公司承办,山石网科通信技术股份有限公…...
代码随想录算法训练营第五十八天| 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的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 1 的个数(也被称为汉明重量)。 提示: 请注意,在某些语言(如 Java)中…...
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私人健身与教练预约管理系统
大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…...
测试Android webview 加载本地html
最近开发一个需要未联网功能的App, 不熟悉使用Java原生开发界面,于是想使用本地H5做界面,本文测试了使用本地html加载远程数据。直接上代码: MainActivity.java package com.alex.webviewlocal;import androidx.appcompat.app.AppCompatAct…...
ubuntu安装pgsql
ubuntu安装postgresSQL 官网地址: 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获取每一个冰川的中心位置经纬度坐标:要素转点和要素折点转点的区别
问题概述:下图是天山地区的冰川的分布,我们可以看到每一条冰川是一个面要素,要求得到每一个冰川(面要素)的中心经纬度坐标。 1.采用要素转点功能 选择工具箱的【数据管理工具】-【要素】-【要素转点】。完成之后再采用…...
数据结构中的七大排序(Java实现)
目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 一、直接插入排序 思想: 定义i下标之前的元素全部已经有序,遍历一遍要排序的数组,把i下标前的元素全部进行排序࿰…...
深度学习基础算法
算法 1.K近邻算法 机器学习--K-近邻算法(KNN)_k近邻-CSDN博客 2. 数据库样本: CIFAR-10 CIFAR-10数据集(介绍、下载读取、可视化显示、另存为图片)_cifar10数据集-CSDN博客...
LuatOS-SOC接口文档(air780E)-- ir - 红外遥控
ir.sendNEC(pin, addr, cmd, repeat, disablePWM)# 发送NEC数据 参数 传入值类型 解释 int 使用的GPIO引脚编号 int 用户码(大于0xff则采用Extended NEC模式) int 数据码 int 可选,引导码发送次数(110ms一次࿰…...
Java虚拟机常见面试题总结
梳理Java虚拟机相关的面试题,主要参考《深入理解Java虚拟机 JVM高级特性与最佳实践》(第2版, 周志明 著)一书,其余部分整合网络相关内容。注意,关于Java并发编程的面试题因为内容较多,单独整理。Java基础相关的面试题可以参考Java…...
NVIDIA NCCL 源码学习(十一)- ring allreduce
之前的章节里我们看到了nccl send/recv通信的过程,本节我们以ring allreduce为例看下集合通信的过程。整体执行流程和send/recv很像,所以对于相似的流程只做简单介绍,主要介绍ring allreduce自己特有内容。 单机 搜索ring 在nccl初始化的过…...
前端--性能优化【上篇】--网络优化与页面渲染优化
一、网络优化 1、DNS预解析 link标签的rel属性设置dns-prefetch,提前获取域名对应的IP地址 2、CDN(网络分发系统) 用户与服务器的物理距离对响应时间也有影响。 内容分发网络(CDN)是一组分散在不同地理位置的 web…...
git 删除分支
目录 1,查看分支2,删除本地分支3,删除远程分支 1,查看分支 # 查看本地分支 git branch# 查看远程分支 git branch -r# 查看所有分支 git branch -a2,删除本地分支 # -d 是 --delete 的简写,会在删除前检查…...
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. 不…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
五、jmeter脚本参数化
目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...
