pull/808/head
flydolpin 2 weeks ago
parent 09159905b0
commit 4416641d86

@ -0,0 +1 @@
/target

@ -0,0 +1,12 @@
[package]
name = "bitcoin_replay"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sha2 = "0.10.8"
num-bigint = "0.4.0"
num-traits = "0.2.14"
leveldb = "0.8.6"

@ -0,0 +1,75 @@
use std::time::{SystemTime, UNIX_EPOCH};
use sha2::{Sha256, Digest};
use crate::{utils, proofofwork::ProofOfWork};
pub struct Block {
//创建区块的时间戳
pub time_stamp: i64,
//存储区块的信息
pub data: Vec<u8>,
//上一区块的hash
pub pre_block_hash: Vec<u8>,
//当前区块的hash
pub hash :Vec<u8>,
//挖矿目标值
pub nonce: u32,
}
impl Block {
pub(crate) fn new_genesis_block() -> Block {
let pre_block_hash = vec![];
Block::new_block_chain("Genesis Block", pre_block_hash)
}
pub fn new_block_chain(data :&str, pre_block_hash: Vec<u8>) ->Block {
let mut block = Block {
time_stamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64,
data: data.as_bytes().to_vec(),
pre_block_hash,
hash: Vec::new(),
nonce: 0,
};
//block.set_hash();
//使用pow方法生成区块的hash值
let pow = ProofOfWork::new(&block);
let (nonce, hash) = pow.run();
block.nonce = nonce;
block.hash = hash;
block
}
//设置区块的hash值使用当前的时间戳 上一个区块的hash值以及区块交易数据来进行创建
pub fn set_hash(&mut self) {
//concat change from "hello" "world" to "helloworld"
let headers: Vec<u8> = vec![&self.time_stamp.to_le_bytes() as &[u8],
&self.data,
&self.pre_block_hash
].concat();
let mut hasher :Sha256 =Sha256::new();
hasher.update(headers);
self.hash = hasher.finalize().to_vec();
}
pub fn print_content(&self) {
println!("Timestamp:{}",self.time_stamp);
println!("Data:{}", String::from_utf8_lossy(&self.data));
println!("Previous Block Hash:{}", utils::hex_string(&self.pre_block_hash));
println!("Hash:{}",utils::hex_string(&self.hash));
}
}
//change byte code to hex string

@ -0,0 +1,27 @@
use crate::block::{Block, self};
pub struct Blockchain {
pub blocks: Vec<Block>,
}
impl Blockchain {
pub(crate) fn new() -> Blockchain {
let genesis_block = Block::new_genesis_block();
Blockchain { blocks: vec![genesis_block] }
}
pub fn add_block(&mut self, data: &str) {
let pre_block :&Block = self.blocks.last().unwrap().clone();
let pre_block_hash = pre_block.hash.clone();
let new_block = Block::new_block_chain(data, pre_block_hash);
self.blocks.push(new_block)
}
pub fn print_block(&self) {
for block in self.blocks.iter() {
block.print_content();
println!("----------------");
}
}
}

@ -0,0 +1,50 @@
use std::{env, process::Command};
use crate::blockchain::Blockchain;
pub struct CLI {
bc: Blockchain,
}
impl CLI {
pub fn new(bc :Blockchain) -> Self {
CLI {bc}
}
pub fn run(&mut self) {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
self.print_usage();
return;
}
let command = &args[1];
match command.as_str() {
"addblock" => {
if args.len() !=3 {
println!("Usage :addblock <DATA>");
} else {
self.add_block(&args[2]);
}
},
"printchain" => {
self.bc.print_block();
},
_ => {
self.print_usage();
},
}
}
fn print_usage(&self) {
println!("Usage:");
println!(" addblock <DATA> -add a block to the blcokchain");
println!(" printchain - print all the blocks of the blockchain");
}
fn add_block(&mut self, data: &str) {
self.bc.add_block(data);
println!("Sucess!");
}
}

@ -0,0 +1,26 @@
mod block;
mod blockchain;
mod proofofwork;
mod utils;
mod cli;
use crate::blockchain::Blockchain;
use cli::CLI;
use proofofwork::ProofOfWork;
fn main() {
let mut blockchain = Blockchain::new();
//blockchain.add_block("Send 1 BTC to Alice");
//blockchain.add_block("Send 2 BTC to Bob");
//blockchain.print_block();
/*for block in blockchain.blocks.iter() {
let pow = ProofOfWork::new(block);
println!("Pow: {}", pow.validate());
println!();
}*/
let mut cli = CLI::new(blockchain);
cli.run();
}

@ -0,0 +1,90 @@
use std::hash;
use crate::block::{Block, self};
use num_bigint::BigUint;
use sha2::{Sha256,Digest};
use crate::utils;
//difficulty level
const TARGET_BITS: u16 =3;
const MAT_NONCE: u32 = u32::MAX;
pub struct ProofOfWork<'a> {
block: &'a Block,
// pow hash should less than target value
target: BigUint,
}
impl <'a> ProofOfWork<'a> {
pub fn new(block :&'a Block) -> Self {
//0000....1 使用target来控制挖矿的复杂度
let mut target = BigUint::from(1_u32);
target = target<<(256-TARGET_BITS);
ProofOfWork { block, target }
}
fn prepare_data(&self, nonce: u32) -> Vec<u8> {
let data =vec![
&self.block.pre_block_hash,
&self.block.data,
&self.block.time_stamp.to_le_bytes() as &[u8],
&TARGET_BITS.to_le_bytes(),
&nonce.to_le_bytes(),
].concat();
data
}
pub fn run(&self) -> (u32, Vec<u8>) {
let mut nonce :u32 = 0;
let mut hash :Vec<u8> =Vec::new();
let mut hasher =Sha256::new();
println!("Mining the block containing {}", utils::hex_string(&self.block.data));
while nonce < MAT_NONCE {
hash.clear();
let data = self.prepare_data(nonce);
hasher.update(data);
hash = hasher.finalize_reset().to_vec();
let hash_int = BigUint::from_bytes_be(&hash);
if hash_int < self.target {
break;
} else {
nonce += 1;
}
}
println!();
(nonce, hash)
}
pub fn validate(&self) -> bool {
let data = self.prepare_data(self.block.nonce);
let mut hasher = Sha256::new();
hasher.update(data);
let hash = hasher.finalize().to_vec();
let hash_int = BigUint::from_bytes_be(&hash);
hash_int < self.target
}
}
#[cfg(test)]
mod tests {
use num_bigint::BigUint;
#[test]
fn test() {
let mut target = BigUint::from(1_u32);
target = target << (256-3);
println!("target value result {}", target.bits());
}
}

@ -0,0 +1,9 @@
use std::fmt::Write;
pub fn hex_string(vec: &Vec<u8>) -> String {
let mut s = String::new();
for byte in vec {
write!(&mut s, "{:02x}", byte).expect("Unable to write");
}
s
}

407
redis/.gitignore vendored

@ -0,0 +1,407 @@
__pycache__/
.venv/
.env
image/
audio/
video/
artifacts_three
dataframe/
.ruff_cache
target/
Cargo.lock
.pytest_cache
static/generated
runs
Financial-Analysis-Agent_state.json
experimental
ffn_alternatives
artifacts_five
encryption
errors
chroma
agent_workspace
.pt
Accounting Assistant_state.json
Unit Testing Agent_state.json
sec_agent
Devin_state.json
poetry.lock
hire_researchers
agent_workspace
json_logs
Medical Image Diagnostic Agent_state.json
flight agent_state.json
D_state.json
artifacts_six
artifacts_seven
swarms/__pycache__
artifacts_once
transcript_generator.json
venv
.DS_Store
Cargo.lock
.DS_STORE
artifacts_logs
Cargo.lock
Medical Treatment Recommendation Agent_state.json
swarms/agents/.DS_Store
artifacts_two
logs
T_state.json
_build
conversation.txt
t1_state.json
stderr_log.txt
t2_state.json
.vscode
.DS_STORE
# Byte-compiled / optimized / DLL files
Transcript Generator_state.json
__pycache__/
*.py[cod]
*$py.class
.grit
swarm-worker-01_state.json
error.txt
Devin Worker 2_state.json
# C extensions
*.so
.ruff_cache
errors.txt
Autonomous-Agent-XYZ1B_state.json
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
.DS_Store
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.vscode/settings.json
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.vscode/settings.json
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data

@ -0,0 +1,16 @@
[package]
name = "redis"
version = "0.1.0"
edition = "2021"
[[example]]
name = "hello-redis"
path = "examples/hello-redis.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1", features = ["full"] }
mini-redis = "0.4"
bytes = "1"

@ -0,0 +1,17 @@
use mini_redis::{client, Result};
#[tokio::main]
async fn main() -> Result<()> {
// 建立与mini-redis服务器的连接
let mut client = client::connect("127.0.0.1:6379").await?;
// 设置 key: "hello" 和 值: "world"
client.set("hello", "world".into()).await?;
// 获取"key=hello"的值
let result = client.get("hello").await?;
println!("从服务器端获取到结果={:?}", result);
Ok(())
}

@ -0,0 +1,81 @@
use tokio::sync::mpsc;
use bytes::Bytes;
use mini_redis::client;
use tokio::sync::oneshot;
/// 管理任务可以使用该发送端将命令执行的结果传回给发出命令的任务
type Responder<T> = oneshot::Sender<mini_redis::Result<T>>;
#[derive(Debug)]
enum Command {
Get {
key: String,
resp: Responder<Option<Bytes>>,
},
Set {
key: String,
val: Bytes,
resp: Responder<()>,
}
}
#[tokio::main]
async fn main() {
// 创建一个新通道,缓冲队列长度是 32
let (tx, mut rx) = mpsc::channel(32);
let tx2 = tx.clone();
// 将消息通道接收者 rx 的所有权转移到管理任务中
let manager = tokio::spawn(async move {
// Establish a connection to the server
// 建立到 redis 服务器的连接
let mut client = client::connect("127.0.0.1:6379").await.unwrap();
// 开始接收消息
while let Some(cmd) = rx.recv().await {
match cmd {
Command::Get { key, resp } => {
let res = client.get(&key).await;
// 忽略错误
let _ = resp.send(res);
}
Command::Set { key, val, resp } => {
let res = client.set(&key, val).await;
// 忽略错误
let _ = resp.send(res);
}
}
}
});
//执行Get和Set发送命令
let t1 = tokio::spawn(async move {
let (resp_tx, resp_rx) = oneshot::channel();
let cmd = Command::Get { key: "hello".to_string(), resp: resp_tx };
tx.send(cmd).await.unwrap();
let res = resp_rx.await;
println!("GOT = {:#?}",res);
});
let t2 = tokio::spawn(async move {
let (resp_tx, resp_rx) = oneshot::channel();
let cmd = Command::Set {
key: "foo".to_string(),
val: "bar".into(),
resp: resp_tx,
};
tx2.send(cmd).await.unwrap();
let res = resp_rx.await;
println!("GOT = {:#?}",res);
});
t1.await.unwrap();
t2.await.unwrap();
manager.await.unwrap();
}

@ -0,0 +1,78 @@
use tokio::net::{TcpListener, TcpStream};
use mini_redis::{Connection, Frame};
use bytes::Bytes;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
type Db = Arc<Mutex<HashMap<String, Bytes>>>; //防止嵌套太长阅读困难
type ShardedDb = Arc<Vec<Mutex<HashMap<String, Vec<u8>>>>>;
#[tokio::main]
async fn main() {
// Bind the listener to the address
// 监听指定地址,等待 TCP 连接进来
let listener = TcpListener::bind("127.0.0.1:6379").await.unwrap();
let db = Arc::new(Mutex::new(HashMap::new()));
loop {
// 第二个被忽略的项中包含有新连接的 `IP` 和端口信息
let (socket, _) = listener.accept().await.unwrap();
let db = db.clone();
println!("Accepted");
// 为每一条连接都生成一个新的任务,
// `socket` 的所有权将被移动到新的任务中,并在那里进行处理
tokio::spawn(async move {
process(socket, db).await;
});
}
}
// 创建一个分片数据库每个分片都是一个HashMap使得高并发情况下无需竞争一个锁
fn new_sharded_db(num_shards: usize) -> ShardedDb {
let mut db = Vec::with_capacity(num_shards);
for _ in 0..num_shards {
db.push(Mutex::new(HashMap::new()));
}
Arc::new(db)
}
//处理链接函数
async fn process(socket: TcpStream, db: Db) {
use mini_redis::Command::{self, Get, Set};
// `Connection` 对于 redis 的读写进行了抽象封装因此我们读到的是一个一个数据帧frame(数据帧 = redis命令 + 数据),而不是字节流
// `Connection` 是在 mini-redis 中定义
let mut connection = Connection::new(socket);
//通过Set存值 通过Get取值
while let Some(frame) = connection.read_frame().await.unwrap() {
let response = match Command::from_frame(frame).unwrap() {
Set(cmd) => {
//获取db并上锁执行插入命令
let mut db = db.lock().unwrap();
db.insert(cmd.key().to_string(), cmd.value().clone());
Frame::Simple("OK".to_string())
}
Get(cmd) => {
//获取db并上锁执行读取命令
let db = db.lock().unwrap();
if let Some(value) = db.get(cmd.key()) {
Frame::Bulk(value.clone())
} else {
Frame::Null
}
}
cmd => panic!("unimplemented: {:?}", cmd),
};
//返回response给客户端
connection.write_frame(&response).await.unwrap();
}
}

@ -0,0 +1,18 @@
param (
[scriptblock]$Command
)
# 获取开始时间
$startTime = Get-Date
# 执行命令
& $Command
# 获取结束时间
$endTime = Get-Date
# 计算执行时间
$elapsedTime = $endTime - $startTime
# 将执行时间输出为毫秒
Write-Host "命令执行时间: $($elapsedTime.TotalMilliseconds) 毫秒"

@ -0,0 +1,25 @@
{
"inputs": [
{
"name": "r",
"public": false,
"type": "field"
},
{
"name": "g",
"public": true,
"type": "field"
},
{
"name": "expect_commit",
"public": true,
"type": "field"
}
],
"output": {
"type": "tuple",
"components": {
"elements": []
}
}
}

@ -0,0 +1 @@
/target

@ -0,0 +1,26 @@
[package]
name = "mimc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
#ark
ark-ff = "0.3.0"
ark-ec = "0.3.0"
ark-bn254 = "0.3.0"
ark-serialize = "0.3.0"
sha2 = "0.9.8"
bls12_381 = "0.8"
rand = "0.8"
rand_core = "0.6.4"
ff = "0.13.0"
#代理重加密库
recrypt = "0.13.1"
#大整数处理
num-bigint = "0.4.4"

@ -0,0 +1,110 @@
use ark_bn254::{Fr, G1Projective, G2Projective, Bn254};
use ark_ec::{PairingEngine, ProjectiveCurve};
use ark_ff::{Field, UniformRand, PrimeField};
use rand_core::OsRng;
use sha2::{Digest, Sha256};
use std::time::Instant;
//使用bn254来实现了基于bls的盲签名算法 验证使用了paring来进行验证
// 生成密钥对
fn generate_keys() -> (Fr, G1Projective) {
let private_key = Fr::rand(&mut OsRng);
let public_key = G1Projective::prime_subgroup_generator().mul(private_key.into_repr());
(private_key, public_key)
}
// 对消息进行盲化
fn blind_message(message: &[u8], blind_factor: &Fr) -> G2Projective {
let hash = Sha256::digest(message);
let mut wide_hash = [0_u8; 64];
wide_hash[..32].copy_from_slice(&hash);
let hash_scalar = Fr::from_be_bytes_mod_order(&wide_hash);
G2Projective::prime_subgroup_generator().mul(hash_scalar.into_repr()).mul(blind_factor.into_repr())
}
// 签名盲化消息
fn sign_blinded_message(private_key: &Fr, blinded_message: &G2Projective) -> G2Projective {
blinded_message.mul(private_key.into_repr())
}
// 去盲化签名
fn unblind_signature(blinded_signature: &G2Projective, blind_factor: &Fr) -> G2Projective {
let blind_factor_inv = blind_factor.inverse().unwrap(); //计算盲化因子的逆
blinded_signature.mul(blind_factor_inv.into_repr()) //返回一个去盲化的签名
}
// 验证签名
fn verify_signature(public_key: &G1Projective, message: &[u8], signature: &G2Projective) -> bool {
let hash = Sha256::digest(message);
let mut wide_hash = [0_u8; 64];
wide_hash[..32].copy_from_slice(&hash);
let hash_scalar = Fr::from_be_bytes_mod_order(&wide_hash);
let g1 = G1Projective::prime_subgroup_generator();
let starttime = Instant::now();
let sig_g1_pairing = Bn254::pairing(g1.into_affine(), signature.into_affine());
let duration = starttime.elapsed();
let elapsed_ms = duration.as_secs_f64() *1000.0;
println!("Test paring: {} ms", elapsed_ms);
let hash_pk_pairing = Bn254::pairing(public_key.into_affine(), (G2Projective::prime_subgroup_generator().mul(hash_scalar.into_repr())).into_affine());
// let hash_pk_pairing = Bn254::pairing(public_key.into_affine(), (G2Projective::prime_subgroup_generator()).into_affine()).cyclotomic_exp(hash_scalar.into_repr());
sig_g1_pairing == hash_pk_pairing
}
//验证聚合签名
// fn verify_bls_signature(public_key: &[G1Projective], message: &[u8], signature: &G2Projective) -> bool {
// let hash = Sha256::digest(message);
// let mut wide_hash = [0_u8; 64];
// wide_hash[..32].copy_from_slice(&hash);
// let mut key: G1Projective = Default::default();
// //计算公钥和
// for i in public_key.iter() {
// key += i;
// }
// let hash_scalar = Fr::from_be_bytes_mod_order(&wide_hash);
// let g1 = G1Projective::prime_subgroup_generator();
// let sig_g1_pairing = Bn254::pairing(g1.into_affine(), signature.into_affine());
// let hash_pk_pairing = Bn254::pairing(key.into_affine(), (G2Projective::prime_subgroup_generator().mul(hash_scalar.into_repr())).into_affine());
// sig_g1_pairing == hash_pk_pairing
// }
pub fn run() -> Result<(), Box<dyn std::error::Error>> {
// ...
let (private_key, public_key) = generate_keys();
let message = b"Hello, Blind BLSBLSBLSBLSBLSBLS!";
let blind_factor = Fr::rand(&mut OsRng);
println!("明文:{:?}\n 盲化因子:{}",message,blind_factor);
let starttime = Instant::now();
let blinded_message = blind_message(message, &blind_factor);
let blinded_signature = sign_blinded_message(&private_key, &blinded_message);
let signature = unblind_signature(&blinded_signature, &blind_factor);
let duration = starttime.elapsed();
let elapsed_ms = duration.as_secs_f64() *1000.0;
println!("Sign time: {} ms", elapsed_ms);
let starttime = Instant::now();
let is_valid = verify_signature(&public_key, message, &signature);
let duration = starttime.elapsed();
let elapsed_ms = duration.as_secs_f64() *1000.0;
println!("Verify time: {} ms", elapsed_ms);
println!("Signature is valid: {}", is_valid);
Ok(())
}

@ -0,0 +1,58 @@
mod blind;
mod pre;
mod pedersen;
// mod non_blind;
// 引入所需的库
use ark_bn254::{Bn254, Fr, G1Projective,G1Affine};
use ark_ff::{BigInteger256, FftField, Field, PrimeField, UniformRand};
use ark_serialize::CanonicalSerialize;
use rand_core::OsRng;
use sha2::{Sha256, Digest};
use ark_ec::{ProjectiveCurve, AffineCurve};
use std::time::{Instant, Duration};
use pedersen::*;
fn main() {
let starttime = Instant::now();
//2跳的代理重加密
// let _ =pre::run();
let _ =blind::run();
let duration =starttime.elapsed();
let elapsed_ms = duration.as_millis();
println!("Total time: {} ms\n", elapsed_ms);
let k = Fr::rand(&mut OsRng);
let starttime = Instant::now();
let test_exp = Fr::multiplicative_generator().pow(k.into_repr());
let duration =starttime.elapsed();
let elapsed_us = duration.as_secs_f64() *1000.0*1000.0;
println!("test_exp time: {} us\n", elapsed_us);
let starttime = Instant::now();
let test_mul = test_exp*k;
let duration =starttime.elapsed();
let elapsed_us = duration.as_secs_f64() *1000.0*1000.0;
println!("test_mul: {} us\n", elapsed_us);
let message: &[u8] =b"aasdiahsduoashdzxkhcvijashdasdas";
let starttime = Instant::now();
let hash = Sha256::digest(message);
let mut wide_hash = [0_u8; 64];
wide_hash[..32].copy_from_slice(&hash);
let duration =starttime.elapsed();
let elapsed_ms = duration.as_secs_f64() *1000.0*1000.0;
println!("test_h: {} us\n", elapsed_ms);
//println!("Result of g * h(r): {:#?}", result);
}

@ -0,0 +1,79 @@
//use bls12_381::*;
//use ff::*;
use rand_core::OsRng;
use ark_bn254::{Bn254, Fr, g1, G1Affine, G1Projective, FrParameters};
use ark_ec::{ ProjectiveCurve, AffineCurve};
use ark_ff::{UniformRand, Fp256};
use ark_ff::{Field, PrimeField,BigInteger256};
use ark_serialize::*;
use num_bigint::BigUint;
// 基于bls12-381仿射映射的pedersen承诺
/*fn pedersen_commit(value: Scalar, blinding_factor: Scalar) -> G1Affine {
//生成曲线上的基点
let G = G1Affine::generator();
let H = G1Affine::generator();
(G * value + H * blinding_factor).into()
}*/
//基于bn254仿射映射的pedersen承诺
fn pedersen_commit(value: Fr, blinding_factor: Fr) -> G1Affine {
// Generator points in affine coordinates
let g_affine = G1Affine::prime_subgroup_generator();
let h_affine = G1Affine::from(G1Projective::rand(&mut OsRng));
println!("g的值{:?}", g_affine);
println!("h的值{:?}",h_affine);
// Compute the Pedersen commitment
(g_affine.mul(value) + h_affine.mul(blinding_factor)).into()
}
pub(crate) fn run() -> Result<(), Box<dyn std::error::Error>> {
//生成随机数
let blind = Fr::new(10.into());
//承诺的消息
let message: Fp256<FrParameters> = Fr::new(3.into());
//计算perdersen承诺
let commitment = pedersen_commit(message, blind);
println!("承诺的消息是{:#?}\n 选择的随机值是{:#?}\npedersen承诺为:{:#?}",message,blind,commitment);
let x = commitment.x;
let y = commitment.y;
let mut commit_compressed_bytes = Vec::new();
let mut message_bytes = Vec::new();
//字节化Fp256变为十六进制
commitment.serialize(&mut commit_compressed_bytes).unwrap();
message.serialize(&mut message_bytes).unwrap();
// 将字节转换为十进制
let messgage_dem = BigUint::from_bytes_be(&message_bytes);
// 打印十进制坐标
println!("commit_compressed_bytes is: {:?}", commit_compressed_bytes);
println!("The length of commit_compressed_bytes is : {}",commit_compressed_bytes.len() );
println!("message_bytes is: {:?}", message_bytes);
println!("message转换为uint256后的值:{:#?}", messgage_dem);
Ok(())
}

@ -0,0 +1,64 @@
use recrypt::prelude::*;
use std::time::{Instant, Duration};
//实现了2跳的代理重加密
pub(crate) fn run() -> Result<(),Box<dyn std::error::Error>> {
// 初始化Recrypt
let recrypt = Recrypt::new();
//生成代理商的signing keys
let signing_keypair= recrypt.generate_ed25519_key_pair();
// 生成用户的密钥对
let (private_key_data_owner, public_key_data_owner) = recrypt.generate_key_pair().unwrap();
let (private_key_manage_center, public_key_manage_center) = recrypt.generate_key_pair().unwrap();
let (private_key_data_user, public_key_data_user) = recrypt.generate_key_pair().unwrap();
let plaintext = recrypt::api::Plaintext::new([23_u8;384]);
// 加密数据 其中使用了代理商的公钥
let encrypted_data = recrypt.encrypt(&plaintext, &public_key_data_owner, &signing_keypair).unwrap();
// 生成代理重加密密钥
//从a到b
let re_encryption_key_do_to_mc = recrypt.generate_transform_key(
&private_key_data_owner,
&public_key_manage_center,
&signing_keypair).unwrap();
//从b到c
let re_encryption_key_mc_to_du = recrypt.generate_transform_key(
&private_key_manage_center,
&public_key_data_user,
&signing_keypair).unwrap();
// 重加密流程
let encrypted_data_mc = recrypt.transform(
encrypted_data,
re_encryption_key_do_to_mc,
&signing_keypair).unwrap();
//重加密密文 b to c
let encrypted_data_du = recrypt.transform(
encrypted_data_mc,
re_encryption_key_mc_to_du,
&signing_keypair).unwrap();
// 解密数据
let starttime = Instant::now();
let decrypted_data = recrypt.decrypt(encrypted_data_du, &private_key_data_user).unwrap();
let duration =starttime.elapsed();
let elapsed_ms = duration.as_millis();
println!("解密时间: {} ms\n", elapsed_ms);
assert_eq!(decrypted_data, plaintext);
println!("成功解密数据!");
Ok(())
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,39 @@
import "ecc/edwardsScalarMult" as scalarmul;
import "ecc/edwardsAdd" as add;
import "ecc/babyjubjubParams" as babyJubJubParams;
from "ecc/babyjubjubParams" import BabyJubJubParams;
import "utils/pack/bool/nonStrictUnpack256" as pack256;
def commit(field r, field[2] g, BabyJubJubParams context) -> field[2]{
bool[256] exp_r =pack256(r);
return scalarmul(exp_r,g,context);
}
def main( private field r, field[2] g, field[2] expect_commit) {
BabyJubJubParams context = babyJubJubParams();
field[2] result = commit(r,g,context);
assert(result == expect_commit);
return;
}
/*//计算基于bn254的pedersen承诺
def commit(field v, field r, field[2] g, field[2] h, BabyJubJubParams context) -> field[2]{
bool[256] exp_v =pack256(v);
bool[256] exp_r =pack256(r);
return add(scalarmul(exp_v,g,context),scalarmul(exp_r,h,context),context);
}
def main(private field v, private field r, field[2] g, field[2] h, field[2] expect_commit) {
BabyJubJubParams context = babyJubJubParams();
field[2] result = commit(v,r,g,h,context);
assert(result == expect_commit);
return;
}*/

@ -0,0 +1,43 @@
import "utils/pack/bool/unpack256" as unpack256;
import "utils/casts/field_to_u32" as field_to_u32;
//计算 g^r
//第一步 :将field类型的r转换为bool[256]
//第二步:判断r的每一位上是否等于1 即 bool[i] == 1, 如果等于计算这一位的t=g^EXP[i]的值
//第三步:判断当前bool[i]的区间 即 EXP_PRAMA[i/16]
//第四步:循环左移g^EXP[16]^EXP[i/16]
//最终将 result = result *t,遍历256位将其累积计算 g^r的值
const u32[16] EXP_PRAMA = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
const u32[17] EXP =[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536];
const u32 MAX = 65536;
def commit(field r, field g) -> field {
field mut result = 1;
field mut t = 1;
field mut e = 1;
bool[256] exp_r = unpack256(r);
for u32 i in 0..256 {
for u32 j in 0..EXP_PRAMA[(255-i)/16] {
e = e * g ** MAX;
}
t = if exp_r[i] == true {
e *(g ** (EXP[(255-i)%16]))
} else {
1
};
result = result * t;
e = 1;
}
return result;
}
def main(private field r, field g, field expect_commit) {
field mut res_commit = commit(r,g);
assert(res_commit == expect_commit);
return ;
}

@ -0,0 +1,103 @@
{
"scheme": "marlin",
"curve": "bn128",
"proof": {
"commitments": [
[
[
[
"0x0658c018134937d6b0b43e1fd4011021711df6919357ca764251472131c34e27",
"0x092297510bb1e6db109e03af5080e2877a65959a61b0bf372ad79ae2f0bf11ab"
],
null
],
[
[
"0x0fadef2277c46865730a971335bd1003b7f9443e4da122f1f93ac854dba96216",
"0x0ce45c00c74c81563a8ff15495dd01bdfe79e88b1b50cc5ff3816889c16aaeae"
],
null
],
[
[
"0x01d8e6929c16275a7fe2df9e6c984ed08175b16461d1449c20fdf3e91edb219c",
"0x0366db7238d267193f9bfb3ae51afde8c78c2ce5f35f3c9726f4fc6cb28ba92e"
],
null
],
[
[
"0x29b769509ed692dd31efad63b37dd5eef5941c49e7c6fa7e1780b74dba74a08e",
"0x2685ced3aa6e7893b43307bf043806f3aa41e0551809fe2d9e8e8831be5a6c76"
],
null
]
],
[
[
[
"0x01104e1c107ac38c77552a8505225100e9aed180504bd1fe9708d89bece51743",
"0x290bb6f5344abe78fab99ad2c2c2f00ab3508eea46d10c6243925ba3ae72fd1d"
],
null
],
[
[
"0x2f173b4544ae16fa92368b88612749e8238333f7738775ca8231034e6294e591",
"0x277f3723142ae875e119ebab2aa6c556a40346f8783040bd6df55827bf69d4c2"
],
[
"0x128c618de8e2a0150907ee331dab486970d1e05fa665f04e4b913a0b5a4fe802",
"0x194b0a08e501789131133cada10977e7f45d64ad81f61372069e1c30798f65c7"
]
],
[
[
"0x08fbf99babc3eaf71d906507b8dedfec5ed0c016f888f8d4d08bbddf4952ad64",
"0x2114f2437d8297ebe4e9e278dd7508f675ceb41ff24be3165ff676e569525180"
],
null
]
],
[
[
[
"0x0446996b7e4f75ab653b5144549b23b689773b877c2bf101632e216d5f8b7f8b",
"0x07820207931da78512c34dac6ca328b688f4a59623e1196a9211cfe680e2e4b6"
],
[
"0x246f6548de38abb9e8e79ca4f30aa0e0629d0cfff1cfcd783e214f08e0ba26c3",
"0x24c477bbcf2d2ad91f474838a505497a17ac8dd0be03faea0a794943f9cdbf78"
]
],
[
[
"0x2e54c241f0530d6114d6714c75d2e064c0cde2ea5f14ae3cb77317c41a334db5",
"0x15ed433d2924a4ebded9ae126824558c96fbc8c9ebe0e1b0a3651db7b4740dc9"
],
null
]
]
],
"evaluations": [
"0x2f63878480304d570280256094d861d8380f135731142ffac4f04bd205082735",
"0x0cc484c1d0a694ff97f5f61f38510a3a7e408f9c282c99be228ff04ba6694a95",
"0x2946ce3f31175046ab1da81848d14568c0e81135eab532256504a0e2c503b759",
"0x250c387c40d2a025024130a0cb4de54191c55580cd7a03c06e2937ccb2321257"
],
"pc_lc_opening_1": [
"0x21397cabc15e6d8cbd39eacd0368336856ca1f2b673a141b90858e44a3356ec1",
"0x23dffb245e4fcf943184ad46c7ee33dbbc56b344b76467a24f43de495081a35f"
],
"pc_lc_opening_1_degree": "0x066ee77dd1570c273189df2200e3481b1913a78e83ca62ec18d51299e6d5f29b",
"pc_lc_opening_2": [
"0x1decedd7b86933fda359a1fa96c94c0fa20a985f4cab972f7e2a8d0d21143cbf",
"0x03807bacedb16ea77423c1eb784683738fc71288730e1fa58af969ff61e4619b"
],
"prover_messages_count": 3
},
"inputs": [
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000400"
]
}

Binary file not shown.

@ -0,0 +1,7 @@
import "hashes/mimcSponge/mimcSponge" as mimc;
def main(private field[20] sk, field k) -> field[20]{
return mimc(sk,k);
}

Binary file not shown.

@ -0,0 +1,925 @@
{
"scheme": "marlin",
"curve": "bn128",
"fs_seed": [
77,
65,
82,
76,
73,
78,
45,
50,
48,
49,
57,
3,
140,
0,
0,
0,
0,
0,
0,
3,
140,
0,
0,
0,
0,
0,
0,
240,
40,
1,
0,
0,
0,
0,
0,
36,
65,
174,
169,
215,
167,
118,
201,
71,
162,
166,
14,
75,
128,
83,
61,
41,
115,
216,
92,
220,
12,
231,
65,
122,
118,
89,
240,
184,
15,
246,
35,
200,
96,
254,
117,
215,
98,
39,
32,
155,
190,
116,
11,
163,
101,
134,
243,
235,
168,
18,
209,
106,
197,
167,
34,
18,
50,
22,
123,
149,
29,
18,
15,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
251,
27,
182,
109,
14,
54,
234,
23,
196,
96,
205,
115,
247,
249,
236,
28,
72,
143,
169,
83,
106,
241,
31,
155,
112,
10,
121,
180,
86,
208,
7,
27,
11,
138,
28,
208,
194,
140,
70,
254,
93,
53,
20,
62,
79,
207,
169,
122,
108,
114,
102,
21,
113,
5,
141,
111,
102,
196,
245,
183,
148,
140,
183,
27,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
25,
229,
167,
107,
194,
99,
32,
181,
240,
105,
101,
73,
68,
13,
107,
94,
194,
129,
149,
22,
101,
195,
231,
199,
105,
63,
140,
21,
0,
116,
56,
26,
14,
212,
110,
238,
34,
49,
51,
37,
140,
145,
226,
242,
126,
254,
81,
140,
177,
228,
135,
208,
96,
163,
161,
124,
174,
68,
186,
73,
158,
115,
40,
48,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
77,
27,
222,
197,
45,
226,
195,
127,
32,
112,
44,
95,
75,
86,
187,
217,
30,
222,
106,
205,
87,
241,
25,
27,
24,
196,
93,
184,
174,
216,
44,
12,
50,
250,
94,
171,
194,
101,
252,
159,
209,
24,
226,
137,
2,
118,
46,
113,
251,
216,
152,
199,
236,
14,
156,
233,
100,
81,
198,
145,
166,
172,
6,
32,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
108,
110,
245,
27,
116,
9,
212,
123,
244,
179,
127,
107,
189,
181,
31,
40,
18,
54,
114,
133,
127,
206,
47,
11,
198,
66,
226,
67,
71,
202,
144,
37,
102,
117,
69,
11,
5,
252,
41,
230,
173,
218,
83,
55,
67,
58,
77,
177,
218,
10,
116,
242,
122,
179,
40,
23,
8,
216,
250,
6,
122,
85,
238,
36,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
109,
118,
177,
92,
237,
186,
36,
246,
199,
173,
254,
110,
181,
2,
65,
226,
109,
139,
107,
48,
86,
88,
164,
120,
133,
110,
147,
220,
129,
57,
114,
33,
30,
90,
41,
88,
186,
48,
22,
35,
194,
34,
36,
119,
150,
25,
243,
224,
181,
12,
103,
81,
1,
79,
176,
196,
121,
127,
173,
139,
239,
117,
37,
23,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1
],
"x_root_of_unity": "0x30644e72e131a029048b6e193fd841045cea24f6fd736bec231204708f703636",
"num_public_inputs": 2,
"num_variables": 35843,
"num_constraints": 35843,
"num_non_zero": 76016,
"num_instance_variables": 4,
"index_comms": [
[
[
"0x23f60fb8f059767a41e70cdc5cd873293d53804b0ea6a247c976a7d7a9ae4124",
"0x0f121d957b16321222a7c56ad112a8ebf38665a30b74be9b202762d775fe60c8"
],
null
],
[
[
"0x1b07d056b4790a709b1ff16a53a98f481cecf9f773cd60c417ea360e6db61bfb",
"0x1bb78c94b7f5c4666f8d05711566726c7aa9cf4f3e14355dfe468cc2d01c8a0b"
],
null
],
[
[
"0x1a387400158c3f69c7e7c365169581c25e6b0d44496569f0b52063c26ba7e519",
"0x3028739e49ba44ae7ca1a360d087e4b18c51fe7ef2e2918c25333122ee6ed40e"
],
null
],
[
[
"0x0c2cd8aeb85dc4181b19f157cd6ade1ed9bb564b5f2c70207fc3e22dc5de1b4d",
"0x2006aca691c65164e99c0eecc798d8fb712e760289e218d19ffc65c2ab5efa32"
],
null
],
[
[
"0x2590ca4743e242c60b2fce7f85723612281fb5bd6b7fb3f47bd409741bf56e6c",
"0x24ee557a06fad8081728b37af2740adab14d3a433753daade629fc050b457566"
],
null
],
[
[
"0x21723981dc936e8578a45856306b8b6de24102b56efeadc7f624baed5cb1766d",
"0x172575ef8bad7f79c4b04f0151670cb5e0f31996772422c2231630ba58295a1e"
],
null
]
],
"vk": {
"g": [
"0x0e65d373109746cfd54b31a99dd9fdb77d72c0abf922ecb958cbe00e0d57bb00",
"0x1e0b0cdebe9fbc2332f447344ed7e62da8a5c3f04be7214410c98e6369f16f4f"
],
"gamma_g": [
"0x199813740698413b6ea6af1f40b952476e4bebb2addcd2b64cff50da18ce7de4",
"0x132fb393d487c8cdd4873ba642e5203e508c7f8f97e2d7f50bf64c5288b53286"
],
"h": [
[
"0x2bf91a9634279a7c19cc6a2e71111707f97b2e251226127ff9542b69900c67da",
"0x28ea7f4942444c671b73b50c27e61f7170c6d801f217a5c2f6b1b47db985c7d8"
],
[
"0x04438756644102f2fb8f596ea0e8cc95ae1c3fca581c4a1d3da575ee66e07e4c",
"0x2e07b7e76af87e42c2109e1aef2498d148c0d3a2702010bc29a88979f89af0a5"
]
],
"beta_h": [
[
"0x1308bdb18feed9ba8f7516fbe3123b763f5ef6a50a0d48a9ddcee98e3a61bb12",
"0x0b2688e92fbe14a531ba6b89e93908f7b652e4a94462f51d923cca0e402a3418"
],
[
"0x1ba7185729b15f74af603342efa02db6c81fbaed4f04e3d69c692658770ce950",
"0x1387a4ccc72c409ca4b127e415be9f3e500924c0906e59455529e59b0f76d45f"
]
]
},
"max_degree": 196607,
"supported_degree": 196607,
"degree_bounds_and_shift_powers": [
[
65534,
[
"0x1408cab87d933fe9f65a077da6dd6c94edb32205fc8bd401124bb438d451df9f",
"0x23fac268497bcc86b37f6a6df31cadaaad2f76d37b35af576e472132ac5572ed"
]
],
[
131070,
[
"0x08a102191464d548e1425763ee41cb037e72e71eba411a93799c24aea0da0dc8",
"0x2126eb67e08b3286e124576c3ef5dd4062dd26724c6f8649077a7a8eb1c547c0"
]
]
]
}

@ -0,0 +1,204 @@
// This file is MIT Licensed.
//
// Copyright 2017 Christian Reitwiessner
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
pragma solidity ^0.8.0;
library Pairing {
struct G1Point {
uint X;
uint Y;
}
// Encoding of field elements is: X[0] * z + X[1]
struct G2Point {
uint[2] X;
uint[2] Y;
}
/// @return the generator of G1
function P1() pure internal returns (G1Point memory) {
return G1Point(1, 2);
}
/// @return the generator of G2
function P2() pure internal returns (G2Point memory) {
return G2Point(
[10857046999023057135944570762232829481370756359578518086990519993285655852781,
11559732032986387107991004021392285783925812861821192530917403151452391805634],
[8495653923123431417604973247489272438418190587263600148770280649306958101930,
4082367875863433681332203403145435568316851327593401208105741076214120093531]
);
}
/// @return the negation of p, i.e. p.addition(p.negate()) should be zero.
function negate(G1Point memory p) pure internal returns (G1Point memory) {
// The prime q in the base field F_q for G1
uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
if (p.X == 0 && p.Y == 0)
return G1Point(0, 0);
return G1Point(p.X, q - (p.Y % q));
}
/// @return r the sum of two points of G1
function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {
uint[4] memory input;
input[0] = p1.X;
input[1] = p1.Y;
input[2] = p2.X;
input[3] = p2.Y;
bool success;
assembly {
success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
require(success);
}
/// @return r the product of a point on G1 and a scalar, i.e.
/// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
function scalar_mul(G1Point memory p, uint s) internal view returns (G1Point memory r) {
uint[3] memory input;
input[0] = p.X;
input[1] = p.Y;
input[2] = s;
bool success;
assembly {
success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
require (success);
}
/// @return the result of computing the pairing check
/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
/// return true.
function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {
require(p1.length == p2.length);
uint elements = p1.length;
uint inputSize = elements * 6;
uint[] memory input = new uint[](inputSize);
for (uint i = 0; i < elements; i++)
{
input[i * 6 + 0] = p1[i].X;
input[i * 6 + 1] = p1[i].Y;
input[i * 6 + 2] = p2[i].X[1];
input[i * 6 + 3] = p2[i].X[0];
input[i * 6 + 4] = p2[i].Y[1];
input[i * 6 + 5] = p2[i].Y[0];
}
uint[1] memory out;
bool success;
assembly {
success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
require(success);
return out[0] != 0;
}
/// Convenience method for a pairing check for two pairs.
function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](2);
G2Point[] memory p2 = new G2Point[](2);
p1[0] = a1;
p1[1] = b1;
p2[0] = a2;
p2[1] = b2;
return pairing(p1, p2);
}
/// Convenience method for a pairing check for three pairs.
function pairingProd3(
G1Point memory a1, G2Point memory a2,
G1Point memory b1, G2Point memory b2,
G1Point memory c1, G2Point memory c2
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](3);
G2Point[] memory p2 = new G2Point[](3);
p1[0] = a1;
p1[1] = b1;
p1[2] = c1;
p2[0] = a2;
p2[1] = b2;
p2[2] = c2;
return pairing(p1, p2);
}
/// Convenience method for a pairing check for four pairs.
function pairingProd4(
G1Point memory a1, G2Point memory a2,
G1Point memory b1, G2Point memory b2,
G1Point memory c1, G2Point memory c2,
G1Point memory d1, G2Point memory d2
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](4);
G2Point[] memory p2 = new G2Point[](4);
p1[0] = a1;
p1[1] = b1;
p1[2] = c1;
p1[3] = d1;
p2[0] = a2;
p2[1] = b2;
p2[2] = c2;
p2[3] = d2;
return pairing(p1, p2);
}
}
contract Verifier {
using Pairing for *;
struct VerifyingKey {
Pairing.G1Point alpha;
Pairing.G2Point beta;
Pairing.G2Point gamma;
Pairing.G2Point delta;
Pairing.G1Point[] gamma_abc;
}
struct Proof {
Pairing.G1Point a;
Pairing.G2Point b;
Pairing.G1Point c;
}
function verifyingKey() pure internal returns (VerifyingKey memory vk) {
vk.alpha = Pairing.G1Point(uint256(0x00a7242ae7ca7e5ef5a81e605760b81d8d6a71cf249860e65852c1323e792a71), uint256(0x164d50243f5e37f95ed2b957c4a4dfe414fd8f6aa898bc0f93710c9b08158313));
vk.beta = Pairing.G2Point([uint256(0x1d515bee0f5a36abbdef85abb1a0d9556ac7adf0c3f05c8dcb7f7052c8fa4111), uint256(0x2fecec70065fb42d2bcabaaf7a07876c065f2b2a7321f45af2bd05e2711017c5)], [uint256(0x03ad820d3d456c277165b59ae7e92b68bf8aba72cc103b21f15f674d1fcefe71), uint256(0x14755ea1c773ca76c961a89da6820f7231a7a223a62180504be46f260952c5e4)]);
vk.gamma = Pairing.G2Point([uint256(0x22c55caabfe4bca35998f8dfd2e0bec741112c6f07e6e4c58032848567762108), uint256(0x196b9e6fd26779de7c3759de9e8abb9c4f58f47536221e8bb2c869c94004052a)], [uint256(0x05ab647f6917a1c243f2ea3196020e62a45d2f62663e6b1653ffb773f0ef9a0a), uint256(0x2dd39eb5a9fc0b2142e3bad4cdb10f4e2945514606f3a1b3f3fc84bc7aa91fbd)]);
vk.delta = Pairing.G2Point([uint256(0x24550281da53ae80c038ebad0933a8f2d25ad133f0360fc0166bef40d3ba3455), uint256(0x150443268853b355f88977f45a5e62370064261d884c1a4cf21d008cd967e69e)], [uint256(0x1ed5251501f384f9756aef008e96f56579723bccb2c871bd6d1ada0a131412e4), uint256(0x03b36603369c85be97f823258e29fbb0c1d5a69fabc8db61824269fdbb37c674)]);
vk.gamma_abc = new Pairing.G1Point[](5);
vk.gamma_abc[0] = Pairing.G1Point(uint256(0x20c258442c5cc6b906c8d35db8febc6e559fca588c67677ec84cb21be0eb023c), uint256(0x0f9c763cddc13c4c200d77cf85c0ef8a5f1193da49a2d4f3345deb69a8a2ec79));
vk.gamma_abc[1] = Pairing.G1Point(uint256(0x2c8413372aae79e5b8a74edf027347c299881e50ab8ab251115cf88f4692b55f), uint256(0x2a28a1e90d49420794282eda5f819c46c70436a83fa4d1e1fb3210016cd04d7c));
vk.gamma_abc[2] = Pairing.G1Point(uint256(0x2576013f4113307b89635b23007d7846f9abf2bbaaad93a437abb42cc6bcb78b), uint256(0x0c5dd9262d1959a7e4544d1fccb872490b26abc5ee333b323eaa918665325423));
vk.gamma_abc[3] = Pairing.G1Point(uint256(0x20c7b3b27ced4e4f9001aed3e3efac0db85b4ce37b407f063a3b47e889c7a488), uint256(0x10915c4c39d30e751e038e1aeef91d03d4a4d4edfedc379bab9bb1ff514ac07c));
vk.gamma_abc[4] = Pairing.G1Point(uint256(0x088605cd2e128c5163a7d08a5f4eb5939a7138017a125696cb8f9936f596b540), uint256(0x2cf3e6c96ee411991104842e927cde707a2abbe352f7cf616c102c74745498a6));
}
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
VerifyingKey memory vk = verifyingKey();
require(input.length + 1 == vk.gamma_abc.length);
// Compute the linear combination vk_x
Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
for (uint i = 0; i < input.length; i++) {
require(input[i] < snark_scalar_field);
vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.gamma_abc[i + 1], input[i]));
}
vk_x = Pairing.addition(vk_x, vk.gamma_abc[0]);
if(!Pairing.pairingProd4(
proof.a, proof.b,
Pairing.negate(vk_x), vk.gamma,
Pairing.negate(proof.c), vk.delta,
Pairing.negate(vk.alpha), vk.beta)) return 1;
return 0;
}
function verifyTx(
Proof memory proof, uint[4] memory input
) public view returns (bool r) {
uint[] memory inputValues = new uint[](4);
for(uint i = 0; i < input.length; i++){
inputValues[i] = input[i];
}
if (verify(inputValues, proof) == 0) {
return true;
} else {
return false;
}
}
}

Binary file not shown.
Loading…
Cancel
Save