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
      在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光伏三相并网逆变器的控制策略与性能分析(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

24、Flink 的table api与sql之Catalogs(java api操作分区与函数、表)-4

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

基于Java的师生交流答疑管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

攻防世界web篇-Training-WWW-Robots

直接点击给出的地址&#xff0c;然后会转到另一个网页界面&#xff0c;在这个界面&#xff0c;已经给出了提示&#xff0c;robots.txt 在浏览器中&#xff0c;直接在地址的后面加上robots.txt&#xff0c;会进到下面这个界面 因为对php语言一窍不通&#xff0c;所以这里纯粹就…

【数据结构】队列(C语言实现)

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 队列 1. 队列的概念及结构…

搜维尔科技:Varjo-探讨汽车工业使用虚拟现实/XR的可能性

新的 奇亚EV9 被定位为起亚有史以来最豪华的车型。在一次活动中,起亚通过向芬兰媒体、利益相关者和经销商网络推出新的汽车车型(起亚EV9&#xff0c;EV9是一款高度超过5米的全电动车,拥有100千瓦的电池、快速充电能力、2500公斤的拖曳能力和7公斤的座位--这在市场上是一个独特的…

常见问题-找不到vcruntime140.dll无法继续执行代码解决方案

本文将介绍五种不同的解决方案&#xff0c;帮助大家解决这个问题。 首先&#xff0c;我们需要了解为什么会出现找不到vcruntime140.dll的情况。这种情况通常是由于以下几个原因导致的&#xff1a; 1. 系统环境变量设置不正确&#xff1a;系统环境变量中可能没有包含vcruntime…

jvm的jshell,学生的工具

jshell 在我眼里&#xff0c;只能作为学校教学的一个玩具&#xff0c;事实上官方也做了解释&#xff0c;以下是官方的解释&#xff1a; 在学习编程语言时&#xff0c;即时反馈很重要&#xff0c;并且 它的 API。学校引用远离Java的首要原因 教学语言是其他语言有一个“REPL”…

轻量级导出 Excel 标准格式

一般业务系统中都有导出到 Excel 功能&#xff0c;其实质就是把数据库里面一条条记录转换到 Excel 文件上。Java 常用的第三方类库有 Apache POI 和阿里巴巴开源的 EasyExcel 等。另外也有通过 Web 模板技术渲染 Excel 文件导出&#xff0c;这实质是 MVC 模式的延伸&#xff0c…

nfs+rpcbind实现服务器之间的文件共享

NFS简介 NFS服务及Network File System&#xff0c;用于在网络上共享存储&#xff0c;分为2,3,4三个版本&#xff0c;最新为4.1版本。NFS基于RPC协议&#xff0c;RPC为Remote Procedure Call的简写。 应用场景&#xff1a;用于A,B,C三台机器上需要保证被访问到的文件是一样…

2023阿里云双十一到底有没有活动?去年就没有

2023阿里云双十一到底有没有活动&#xff1f;根据以往经验&#xff0c;阿里云双11是一次大型促销活动&#xff0c;但是去年好像就没有&#xff0c;印象里去年阿里云没推出双十一活动&#xff0c;因为阿里云一直都活动&#xff0c;没有单独推出双11优惠&#xff0c;阿里云百科给…

发现一不错的编程助手 Amazon CodeWhisperer

Amazon CodeWhisperer 是一款 AI 编程助手&#xff0c;旨在为开发人员提供智能化的编程辅助工具。作为一款基于人工智能的编程助手&#xff0c;CodeWhisperer 的目标是提高开发人员的生产效率、降低开发成本&#xff0c;并提供高质量的编程解决方案。 1.安装过程参考官网 htt…

驱动实现LED点灯

demo.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include "head.h" //定义三个指针指向映射后的虚拟内存 unsigned int *vir_moder; unsigned …

YOLOv8改进实战 | 更换主干网络Backbone(四)之轻量化模型MobileNetV3

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…

【Qt之布局】QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout介绍及使用

在Qt中&#xff0c;布局管理器&#xff08;Layout&#xff09;用于管理窗口中的控件的位置和大小&#xff0c;以适应不同大小的窗口。 常用的布局管理器包括QVBoxLayout、QHBoxLayout、QGridLayout和QFormLayout。 先放张布局UI&#xff1a; 1. QVBoxLayout&#xff08;垂直布…

百分点科技受邀参加“一带一路”国际合作高峰论坛

10月17-18日&#xff0c;第三届“一带一路”国际合作高峰论坛在北京成功举行。作为新一代信息技术出海企业代表&#xff0c;百分点科技董事长兼CEO苏萌受邀出席高峰论坛开场活动——“一带一路”企业家大会&#xff0c;与来自82个国家和地区的企业或机构、有关国际组织、经济机…

【IBIS 模型与仿真 - IBISWriter and Write_IBIS】

本文将介绍如何从用户设计中编写自定义IBIS模型。 本文是 SelectIO 解决方案中心&#xff08;Xilinx 答复 50924&#xff09;的设计助手部分&#xff08;Xilinx 答复 50926&#xff09;的一部分。 原文链接&#xff1a;https://support.xilinx.com/s/article/50957?languagee…

2022年亚太杯APMCM数学建模大赛E题有多少核弹可以摧毁地球求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 E题 有多少核弹可以摧毁地球 原题再现 1945年8月6日&#xff0c;第二次世界大战即将结束。为了尽快结束战争&#xff0c;美国在日本广岛投下了下一颗名为“小男孩”的原子弹。这样一颗原子弹在广岛炸死了20万人&#xff0c;广岛的所有建筑物都…

VueRouter 源码解析

重要函数思维导图 路由注册 在开始之前&#xff0c;推荐大家 clone 一份源码对照着看。因为篇幅较长&#xff0c;函数间的跳转也很多。 使用路由之前&#xff0c;需要调用 Vue.use(VueRouter)&#xff0c;这是因为让插件可以使用 Vue export function initUse(Vue: GlobalAP…

EDUSRC--简单打穿某985之旅

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…