之前的系列博客有:
本博客,主要针对该论文算法的实现(基于bls12-381 curve),https://github.com/algorand/pointproofs,进行相应的梳理。
Cargo.toml
:Cargo配置文件。
benches
:benchmark文件夹。
- basic.rs
:提供basic benchmarks,数据记录在benchmark.md
文件。
- bench_aggregation.rs
:bench the cost for cross commitments aggregation和batch verification。
- bench_mul.rs
:bench the cost of sum of product vs doing it serialized。
- extra.rs
:extra benchmarks using parameters with pre-computation。
- old_data.md
:在MacOS 3.1GHz Intel Core i5的测试数据,最新的测试数据见benchmark.md
。
- benchmark_extra.md
:AWS Intel® Xeon® CPU E5-2686 v4 @ 2.30 GHz服务器,分别对 n = 1024 n=1024 n=1024, n = 32768 n=32768 n=32768,以及proof in G1,proof in G2进行了bench。同时指出,new commitment和new proof的主要开销在sum of n product,对有无precompute进行了性能对比,当 n < 1024 n<1024 n<1024时,有precomputation的性能提升明显。
src
:Pointproofs算法Rust语言实现。
- bin
:内含bin执行文件。
- pairings
:pairings模块,此处为Pointproofs核心功能模块。详见第3节分析。
- test
:test测试模块。
- lib.rs
:对外暴露pairings模块,支持test测试模块。
c_test
:Pointproofs算法对应C语言接口测试。
- pointproofs_c.h
:通过Makefile
内脚本自动生成。cbindgen --config cbindgen.toml --crate pointproofs --output c_test/pointproofs_c.h
- test.c
:对封装的C语言接口的测试代码。make test
build.rs
:采用Build script方式调用cbindgen
crate来生成相应的C语言header文件pointproofs.h
,默认在target/debug或target/release目录下。(language: cbindgen::Language::C
)
Makefile, cbindgen.toml
:使用make方式调用cbindgen
命令工具(cargo install cargo install –force cbindgen
安装)来生成相应的C语言header文件pointproofs_c.h
,在c_test/目录下。(在cbindgen.toml
中配置了language = "C"
)
crs.param
:即common reference string。可调用https://github.com/algorand/pointproofs-paramgen
来生成。
SPEC.md
:函数接口说明。
benchmark.md
:取 n = 1024 n=1024 n=1024,proofs in G1,AWS Intel® Xeon® CPU E5-2686 v4 @ 2.30 GHz服务器上的bench性能数据。
Pointproofs核心算法实现在src/pairings/
目录下:
github.com/algorand/ff-zeroize
是从github.com/zkcrypto/ff
fork来的。
ff
是用pure Rust写的finite field库,里面没有任何的unsafe{}
代码,提供了finite field内各种运算Traits和utilities。包含的traits有:Field
, PrimeField
, PrimeFieldRepr
, SqrtField
。
调用方式为:
[dependencies]
ff-zeroize = { version = "0.6.3", features = ["derive"]}
Fr
会执行 Field
和PrimeField
,若支持SqrtField
也会执行SqrtField
。同时会自动执行FrRepr
并derives PrimeFieldRepr
for it。#[macro_use]
extern crate ff;
#[derive(PrimeField)]
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
#[PrimeFieldGenerator = "7"]
pub struct Fr(FrRepr);
https://github.com/iqlusioninc/crates/tree/develop/zeroize
zeroized:提供a portable approach to securely zeroing memory using techniques which guarantee they won’t be “optimized away” by the compiler。用于保证:
zeroize
主要API就是Zeroize
trait。
调用方式为:
zeroize_derive
feature,将自动call zeroized()
on all members of a struct or tuple struct。[dependencies]
zeroize = { version = "1.1", features = ["zeroize_derive"]}
use zeroize::Zeroize;
// This struct will be zeroized on drop
#[derive(Zeroize)]
#[zeroize(drop)]
struct MyStruct([u8; 32]);
use zeroize::Zeroize;
// This struct will *NOT* be zeroized on drop
#[derive(Copy, Clone, Zeroize)]
struct MyStruct([u8; 32]);
https://github.com/algorand/pairing-plus
代码库中仅对BLS12-381曲线做了实现。(可参考博客 bls12 curve生成器,可生成ZCash sapling版本中所使用的BLS12-381曲线)
BLS12-381的表达为:
E : y 2 = x 3 + 4 E: y^2 = x^3 + 4 E:y2=x3+4
F q = 0 x 1 a 0111 e a 397 f e 69 a 4 b 1 b a 7 b 6434 b a c d 764774 b 84 f 38512 b f 6730 d 2 a 0 f 6 b 0 f 6241 e a b f f f e b 153 f f f f b 9 f e f f f f f f f f a a a b F_q= 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab Fq=0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
F r = 0 x 73 e d a 753299 d 7 d 483339 d 80809 a 1 d 80553 b d a 402 f f f e 5 b f e f f f f f f f f 00000001 F_r=0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 Fr=0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001【为E.order()
的最大素数因子】
取的generator为:
x 1 = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 x_1=3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 x1=3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
g 1 = ( x 1 , y 1 ) g_1=(x_1,y_1) g1=(x1,y1)【g_1.order()
即为Fr
】
cd pointproofs/src/bin
cargo run
调试信息有:
zouyudi alpha_power:Fr(0x0000000000000000000000000000000000000000000000000000000000000001)
zouyudi g1_power:G1Affine { x: Fq(0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb), y: Fq(0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1), infinity: false }
zouyudi alpha_power:Fr(0x03530f615aa764a263544084485bf91a014712497bc9ba54f11114c3b3e45f08)
zouyudi g1_power:G1Affine { x: Fq(0x06b73e205fc1403b0ea47f87cd9d1752814bfcfa43f37e64e5a4267e7947890678319eebaa659bfbbb07f0b885924ac6), y: Fq(0x00956a7c3cbbfea2a46544aba6dd27989a2c8dcd6c9bed54416c158c0c3c74cbdd045171d85527226a9c854523499467), infinity: false }
zouyudi alpha_power:Fr(0x201474474cc90c279328d8f6cd5e085a575e15e60a1503b7889c2c54b53ae52f)
zouyudi g1_power:G1Affine { x: Fq(0x02102361767f5aa63ca59d03f9985352223962a9bf72a1aaf540cdb1ef89a822c7a9ab5d77cb378112c9bb0519150d89), y: Fq(0x1895ec61d5a8386f61e698c52f19991a3df095fc806fde62912822510e29688ad14a332fb3866e416b2cae3b063112cc), infinity: false }
zouyudi alpha_power:Fr(0x434e2571e93e582a486fd726085cb3dcb9674bd28d56eb5aaab07d1faab07c4c)
zouyudi g1_power:G1Affine { x: Fq(0x121addc500baa3418225e0679869bb03c15492f69f126fa0b410736e60efebc31930070069ee03ad66f89c8345ae5a95), y: Fq(0x00ec4f34faec47049ed87f265ffd4316b5fb056de39ef5eb251ce30e2361438f6c6d0487e28dedaaccbb04bba698306d), infinity: false }
zouyudi alpha_power:Fr(0x0033efb58b5d261aa71244c3388763afde5aec58d477011b9efac221370f3476)
zouyudi g1_power:G1Affine { x: Fq(0x1496012438bf82884c09ba192a60b7c6026a0f1cf10d6f3af28faf48817ccc766cb5ae8331f22745bcd4505eef44a86d), y: Fq(0x040e549bea1b95fc2879f26d3d519dea281629c7e9ec9cc3a2cb437b5102a2cb8c1ca0d9e6e5c2be05a2447f02fb957c), infinity: false }
zouyudi alpha_power:Fr(0x420473cf58dc43ee3c4eb7b0958cb16c05d730a6cec0a6b23533c12dc21e2e06)
zouyudi g1_power:G1Affine { x: Fq(0x0c7b76fd7878fa81257eed5366755d2694061444e91906f946d7547684c11de46af885c181f58e399cff2071fc572a2c), y: Fq(0x19c31696549ead61867ec7ae15c4fd3f7872a21247323e04bd6e777c6a066b875d66a700a454532b0cf7b52f2319a6f9), infinity: false }
zouyudi alpha_power:Fr(0x4b6041ce28f6a592ddbfa94ce392874bbe643d576ebf0f41136bc7c3d072d00a)
zouyudi g1_power:G1Affine { x: Fq(0x06ce08ab6142da0ee7b4f56cc6aa00ee12c56aca1c74e592a27366549d6f10a762f7600244635208de0aba94f7dc1eb8), y: Fq(0x176e53894df072b1c6af745cc069d289bd2e72116f155add8a651e92ab3bb248f64e5cbefd5489c2966392775697bd18), infinity: false }
zouyudi alpha_power:Fr(0x44fba9a63d9240738c0820c346a135345881bb851ef41aaf56e138a209099188)
zouyudi g1_power:G1Affine { x: Fq(0x03249e85f796004385721a8fb3954e8741590ad96ed8eda61c513b7ca9e569d9c4ca1455b7cf41691f460da9cbc5a1fa), y: Fq(0x0b09d3086c7e953c36fae391bae607d44f3068c80e8fd52bbd95819de3687186592cd8adabc95b6617c6af5c0854d1cd), infinity: false }
zouyudi alpha_power:Fr(0x312e7f4ce42b19172a6ca49a002068e275b22bc07a6c2159cfe267b140ff6616)
zouyudi g1_power:G1Affine { x: Fq(0x1118ea263e2942f5fb4ac0143d348c6f48d9b17c7b9c460992b50e3aad892eb4f89a23d3d05b2bcd00c781f66a2447a9), y: Fq(0x144308cf3622b856d7cefc62641baa01432fd426a354e601b8f09606a432f2bd6c26e5a6fb9b96aa31ddeae154f7123f), infinity: false }
zouyudi alpha_power:Fr(0x398edca2cc10069a98cfe724d0e4d268a7c159d767cf769ffce05e12d2d27818)
zouyudi g1_power:G1Affine { x: Fq(0x133e87a933c86c9ce06916e90439740d5f5d078bbe6af04a02eaf739bddb9af014daa212751bae28b31bda7e026f5ac7), y: Fq(0x0635dfb810a2ed0531a68e5e3c040342fd37ce201a53f588c8ca29ce23f2c354f2d58da4d56da8d308885e29aa3b58e8), infinity: false }
zouyudi alpha_power:Fr(0x34f012ea3f06227bb1631c9c96ce71f1bb9d1347b7b82392f07406a6fa0bb327)
zouyudi g1_power:G1Affine { x: Fq(0x10926badcea4c03842de90394a0912911b0dffc24e7ed4348c34dbff11bb0cc8e342bccf139f860b01cdfbf00409d691), y: Fq(0x002df711e8de4dfbb0a35025663047a24542a33ae35c97872adaa4a710088496c2ec049ad53c86b440c562ccaf982b68), infinity: false }
zouyudi alpha_power:Fr(0x68fedeffa6be5dd066539d1f88ee82e7547190222b491dbea0715780e1c44897)
zouyudi g1_power:G1Affine { x: Fq(0x12c0b2d0b58ebb4128104c6edd8a88b7968650da3a1bad968e7f32aeaad3165496928b72e5ccbba101ce1a981c2ba61c), y: Fq(0x01bdbf4ccee5ecd53b8eccfc5cae1f17aac62aeffb05d3e4e940a58ac32157f1189b41f18a19488fac260cb4168e7015), infinity: false }
zouyudi alpha_power:Fr(0x6e9941d817e53229828be6fe7feceadd360302744a597cd0b79ca2b6f3312125)
zouyudi g1_power:G1Affine { x: Fq(0x04dc13a65c4eeff8a29e0644ebae1c80a638a282a1222b8b2233a5a36983f785e600b8d911b11979a938f7f4dae691a6), y: Fq(0x1530b5c7a11a1da31685c6ad7b1dd9ab7e20333d0f3f53b840e0f1662888a0bd434c99f747ffbd7182fe14c9a4caec0a), infinity: false }
zouyudi alpha_power:Fr(0x57094e27fcf86b77398edccc4c01451af179c2bb0b3ec82a9df92d2caa3cc015)
zouyudi g1_power:G1Affine { x: Fq(0x08ac8bd7f7537d834b6169cf2e8cfa9b82c5de32648bb73603dbae5990928f2e3b6ac96029c9578ae0d150c81a8ff838), y: Fq(0x11110702c85d06e5bf49bf99f205efc4711054e0eb53f5765631e51f9028c3786f6d6529477d129ac5d849d7a81304eb), infinity: false }
zouyudi alpha_power:Fr(0x003c2abeb3b07662e5f74a425480ec30bcbcf72f0d807fd88c80bdf8055808f2)
zouyudi g1_power:G1Affine { x: Fq(0x151a8c4cc8cd1c3982e21fd9e0414f29631c7317b633c4d4536eb9f229dc8c47b48b52485b4ba58f7b5fb81887112afb), y: Fq(0x0f44c48426172d9400bdf6b5e77324ab87cc6d8838b76bba887efef1ee38ef3c8348f253b378b75e4f3f771045c1d438), infinity: false }
zouyudi alpha_power:Fr(0x29e17af9825f9f1be10e3686c2a7eed52fff948971c9f00dea6e639cb9232b92)
zouyudi g1_power:G1Affine { x: Fq(0x19d2276f826a3b8a4c9d7f2e1437f0e33c840695e6145e2c7fbc6f68058314c913df46bc4e241b02deed383d0506eb07), y: Fq(0x116178fac0d354255f0ab171dc820941714030dbb8c909ac10b357a66215910918e649248eff18465b7a90f186b2a659), infinity: false }
Commiting to the following 16 strings
this is message number 0
this is message number 1
this is message number 2
this is message number 3
this is message number 4
this is message number 5
this is message number 6
this is message number 7
this is message number 8
this is message number 9
this is message number 10
this is message number 11
this is message number 12
this is message number 13
this is message number 14
this is message number 15
Commitment: [00, aa, c4, 32, 35, 05, c1, cc, 60, b0, 9f, 4a, 6d, 08, 05, 73, 1a, 59, de, 52, cd, 18, 4d, bf, 90, 51,93, 22, 7b, 6b, 9a, 90, 87, 07, f7, 70, a8, 54, 76, e4, d1, 2c, 69, 78, c5, 87, 3a, 9b, 23]
Old Proof 0: [00, 8a, 8b, bc, 7f, c6, b1, d5, f2, 75, ce, 08, f8, 8a, 50, 04, 7b, 5d, 14, 5e, 73, b1, d0, f7, e2, db,74, ee, 42, c9, 4e, 4c, 91, 62, 70, ca, 45, 13, 89, 2d, 84, 96, 34, c0, 5a, 2f, cb, 9f, 09]
Old Proof 1: [00, a5, e7, 5a, 2f, ce, 8f, 63, 31, 20, 05, 72, 9e, 3d, a3, b5, cf, a3, 6a, f3, 3b, 1d, bd, a2, 29, ef,3c, 88, 11, 51, ba, 60, 61, 24, b6, 39, ac, 69, 66, 7d, 5d, 8b, da, f3, 63, ad, 46, d0, 81]
Old Proof 2: [00, 80, 1e, 2a, d1, 1e, 19, 4b, f3, 3a, 02, 20, fd, e7, 3e, 41, 44, bc, 86, 2d, f2, 22, f6, df, 30, 5b,a2, e9, 93, b6, 78, 01, c9, 77, 96, e0, d3, 2c, 45, a6, 8c, ac, df, d6, 99, 14, ca, a8, 40]
Old Proof 3: [00, b7, 9a, 92, 73, 2a, ae, c9, cb, e3, 3b, 2f, d2, ba, a4, 9c, a5, cb, 69, 45, f2, 48, 0f, d5, ef, f6,0f, fb, 65, 48, ef, 8d, 1f, 4a, 91, 1d, 7f, 9f, 21, 24, f4, 41, f8, 54, b6, 79, 21, 11, ab]
Old Proof 4: [00, 8a, 10, bc, 95, 03, b9, 59, d7, 02, 67, 19, a5, 5c, 6a, 1f, 34, 82, 66, 70, 7c, 21, b3, 4c, df, 1a,fc, 0c, f9, e1, 18, 05, bd, c7, 1a, 4a, e5, c1, 6c, 5f, b9, 0f, da, cc, f8, 5b, 11, cc, 79]
Old Proof 5: [00, 8d, 11, dc, 45, ad, df, ad, 2f, 21, 70, 0d, 49, e8, 62, f0, 2a, 06, ee, 1f, 29, c7, d2, 42, 9f, ab,5e, 88, 78, 9e, 92, fa, f6, 88, 81, cb, 6a, 30, 3b, 21, 3b, 1a, a9, 60, 1a, 66, 4d, c0, 6b]
Old Proof 6: [00, 92, 60, 8b, 1a, d5, e9, 1a, 0a, 07, 0b, 4e, db, b1, 29, ca, 24, 63, c1, 93, 52, 71, 2a, dd, 68, 36,55, e9, 46, e4, 82, 06, f8, 5f, fe, 2e, 22, 91, f4, 89, 77, 60, 41, 69, 41, a5, 95, 8f, c2]
Old Proof 7: [00, ab, d6, 1d, e1, 99, 68, 6e, e5, 16, ea, a7, 92, 2e, 0e, 61, 7e, ef, ce, 06, 46, bf, 37, 80, 6b, bd,7f, 11, 4a, f5, 72, 71, b5, f4, 11, 6b, db, 7d, 85, 49, 57, a4, 68, 14, 75, 7e, e7, 0d, ec]
Old Proof 8: [00, 88, 04, 65, 88, b9, e5, 42, b5, 38, 46, da, b6, f3, 0b, 1d, e5, 69, 05, 93, 0b, 3d, e6, 27, 66, f9,91, df, a3, e4, f6, cf, 4e, 01, 4f, 28, cb, ff, 96, b1, 2a, 5a, 48, 89, 67, cd, ec, ae, 1b]
Old Proof 9: [00, b0, 7a, e2, 18, 26, ca, 6a, 26, a7, 37, 49, 9a, 0e, f9, b6, 92, 49, 18, e6, fe, dc, 90, 9f, 12, 62,60, 5e, e4, a3, 14, 26, 9c, 2f, 6f, 86, 61, 64, b0, 1a, c6, d2, 8f, d0, 2d, 47, 37, 1a, 4c]
Old Proof 10: [00, 92, ef, 66, a2, 38, e5, 1b, 95, 94, f9, 31, b4, 1d, b7, 11, 19, 85, 9c, b6, f6, ea, d7, e9, 09, 55, cb, 99, f7, 18, 61, 84, a2, a3, f0, 41, bf, 1f, 08, 86, c8, 6d, 9d, 8e, 4e, 45, 28, 9b, c0]
Old Proof 11: [00, 88, 4d, d5, 79, 6a, ca, 2d, 2b, f7, 85, 68, 03, 32, 58, f6, 97, cc, d0, 59, f4, a3, 2d, 1c, eb, 4c, 5c, a4, 63, 39, 5d, 37, b3, 24, b0, ad, a6, 99, f4, 72, bc, a7, 37, 1e, 3e, 60, ea, 09, ac]
Old Proof 12: [00, b7, 38, 05, 51, aa, a7, 6b, 42, 5a, 1b, 2e, 2c, 4c, 44, 71, b5, e5, 20, 13, 1f, 8a, a2, 64, ef, 8b, d0, 1d, b8, d7, e0, 12, e4, 00, b7, 4f, 6e, 62, db, b2, 9b, e0, d0, 7a, ff, 99, 95, c5, 13]
Old Proof 13: [00, 99, 38, 00, ce, 30, ef, 2c, ba, b2, 62, e1, 64, 49, 87, e5, 25, c5, ae, e3, 7b, 10, 27, 79, 7f, cf, 38, fa, 5c, db, 73, 43, da, 6e, cd, 38, 5a, 6c, 96, 2f, 4b, af, 86, 68, ff, c2, 6e, 4e, f2]
Old Proof 14: [00, 80, b1, 57, 6b, 75, 34, b4, 8e, 99, 89, c3, f1, e8, 2e, 94, b1, 50, 2b, 6a, 4f, 74, 81, 2a, ee, 1a, c9, 9d, fb, cf, 8e, e3, ec, 45, 30, 96, 56, d5, cb, eb, f1, 01, b0, d6, 9e, 55, b2, 56, e6]
Old Proof 15: [00, 98, 3d, 1c, ac, bd, 2f, fe, 9c, 51, 36, 82, 1c, 59, 25, 2f, f3, 71, 10, 1c, f6, ac, 85, 03, 24, 1e, 21, 55, 7c, e8, 54, 40, cf, d9, 8d, 98, 5c, 1f, 01, 56, 83, a2, 36, 67, 3a, 1e, e1, 7c, c9]
Updating string 8 to "this is new message number 8"
New Proof 0: [00, 84, 73, 04, 01, 7a, 39, 2d, fd, 18, e6, 1b, 0e, c0, f0, 09, 41, bc, 5a, 6b, 97, 27, 65, 8b, 30, 0a,26, bb, d4, 09, ef, ce, fb, 81, 71, 0b, bd, eb, 38, 6f, af, 69, 33, 48, 90, 33, 58, 57, 6e]
New Proof 1: [00, ae, ca, df, 0d, f7, 27, 62, fe, ff, 41, 41, c1, 13, 86, f6, 89, 0d, 75, 48, 85, b7, d9, 41, f0, 9b,12, a2, 70, 17, f0, e6, 1f, c5, 7e, 06, f7, c3, 50, c7, c1, c2, 18, 3d, b2, 9d, 8a, ed, 1c]
New Proof 2: [00, b1, 84, 98, e5, f2, 7e, 73, 3d, 58, ed, fc, 04, fc, 7e, 0a, 45, cd, 80, c6, 99, e0, 14, a6, d2, 17,3d, c3, 07, 4a, 6c, 53, 34, bc, 4d, 80, 64, d9, f3, 46, 12, f4, 50, 90, 83, 36, 8e, bc, 2c]
New Proof 3: [00, 86, 49, b1, 70, 4c, f2, c1, e1, 21, 7f, de, e5, 52, a0, 8a, 6c, 95, 18, 53, 44, 35, b8, 2a, 9e, f1,36, ec, a3, db, b0, 16, 05, 90, db, e7, 13, 96, 4a, 21, 09, 1b, f4, 5c, f7, 3f, 67, 82, ed]
New Proof 4: [00, a5, 91, 54, c0, 3e, 1d, 09, 57, ba, b1, 41, d7, ff, 37, f4, 09, 5c, 17, eb, 29, 00, a8, a7, 12, fd,99, d8, d7, 7a, 50, f9, a0, 0e, 9d, cb, 7e, ae, c1, 89, 88, d3, bf, 1d, 28, aa, d6, cf, 62]
New Proof 5: [00, 96, 0c, 8e, 70, ae, e6, bc, 22, f3, fd, 02, 2f, 02, 00, fa, ae, 3d, 42, 9f, 3a, 22, b6, 44, c7, 29,03, a9, bc, 48, 5e, b8, cd, a4, 2d, b0, d2, f7, 2e, 2f, b2, 1f, d0, d6, 63, ba, aa, 6e, 29]
New Proof 6: [00, a2, c5, ec, 5d, b1, 93, 12, 97, 69, fa, c1, 30, 19, da, 5f, 9e, 92, 9a, 0c, 8e, 41, 6e, f4, 3a, f2,ce, c4, fc, 3e, ff, 4b, 55, 3b, 3d, 3e, 6f, 27, 9f, 80, 6f, 0f, f4, d7, 38, c9, 4e, 67, 19]
New Proof 7: [00, 93, 10, 2d, 0b, 72, 38, 58, 50, 8a, d0, c9, 6a, fb, f7, 5e, ef, 14, 51, 86, ce, 7a, a5, 57, 48, 5a,47, 89, 08, 5a, a1, f4, 36, 60, cf, 7d, 27, bb, 20, 33, 33, b0, 9d, 43, 12, 04, bf, a4, 2b]
New Proof 8: [00, 88, 04, 65, 88, b9, e5, 42, b5, 38, 46, da, b6, f3, 0b, 1d, e5, 69, 05, 93, 0b, 3d, e6, 27, 66, f9,91, df, a3, e4, f6, cf, 4e, 01, 4f, 28, cb, ff, 96, b1, 2a, 5a, 48, 89, 67, cd, ec, ae, 1b]
New Proof 9: [00, 80, fe, 01, 3a, 7f, 58, f8, 6f, 7a, 3f, f8, e3, b8, f4, fe, 6c, 4c, 7e, e0, 45, 98, 45, 65, 10, bd,d3, a6, c4, 99, b9, 6e, 8e, de, f1, 86, 94, 28, ce, f0, 38, 30, 5c, 25, f5, 90, 38, 08, 5f]
New Proof 10: [00, 8a, 1c, fa, 02, 03, e1, aa, 1e, 96, 52, 5b, df, 1d, 40, b6, 37, 1f, 55, 6a, 22, 0e, bd, 64, ad, de, b2, bc, b0, 83, 41, a4, 3d, 1a, 71, e9, d7, 57, cf, ac, 26, 98, 96, d5, aa, 72, 01, e0, c2]
New Proof 11: [00, 92, ea, a8, c2, 33, ff, 53, f1, 2f, de, eb, 91, b8, a2, bc, 9f, 66, b0, 39, a9, d9, 5b, 63, 1f, 73, 49, 59, b9, 7d, 0b, 86, 33, 77, 0c, 5a, e2, 0e, 8a, 0f, ba, ee, 62, f8, 5c, 4d, 58, 62, 6a]
New Proof 12: [00, b3, d8, 50, 3f, f6, 65, 84, 0f, e6, 92, 2e, b4, 75, 79, ca, bf, 63, d1, 57, a6, 03, 59, bd, f5, a2, e7, 9e, 13, d0, 1e, 2b, d5, e7, 43, ca, 27, 45, ae, cd, f6, 16, d1, f4, 6f, 46, 7b, 9a, 6f]
New Proof 13: [00, 8b, 18, 66, e4, 31, e7, 82, 53, 20, 1e, a8, 6f, 5b, 45, 60, 11, ee, 7c, b8, 24, 7a, c9, c7, 6f, 73, 8e, 72, 0f, c3, 95, e5, a1, 95, 01, 12, 29, 21, 72, c7, c3, 58, 65, a6, c3, 49, c6, 07, 2d]
New Proof 14: [00, 84, bd, 3a, 13, c6, 9c, 21, db, 1e, e3, 40, 9b, 1e, 63, c9, cc, 2b, ec, 51, 4b, 10, ca, 20, c1, e2, f9, 17, cc, d7, 0d, ad, 0e, 73, a8, 46, eb, 37, 48, 40, ff, b2, bc, 27, 0c, ea, 42, 95, 83]
New Proof 15: [00, b7, c7, 54, 7f, 17, 8e, e9, 90, ba, 32, 9b, 2b, 0b, f6, 03, 5b, d0, 44, c1, 64, 55, 41, 16, b7, 74, 9f, ea, 06, 8d, 59, e7, 2e, a0, 69, dc, eb, 4f, fe, 42, 2a, c7, 77, d2, b1, 83, 00, ce, 4a]
Ni hao, Algorand
对应的Sage脚本验证为:
sage: 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffe
....: b153ffffb9feffffffffaaab
4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
sage: 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: r=0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
sage: primitive_root(r)
7
sage: q=0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabff
....: feb153ffffb9feffffffffaaab
sage: E=EllipticCurve(GF(q),[0,4])
sage: E
Elliptic Curve defined by y^2 = x^3 + 4 over Finite Field of size 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
sage: E.order()
4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129030796414117214202539
sage:
sage: x1=36854167537133870167810883151830777579616207957825464098945783786886075
....: 92378376318836054947676345821548104185464507
sage: y1=13395065449444764730204713799419212215849338759383496204265437364165114
....: 23956333506472724655353366534992391756441569
sage: g1=E(x1,y1)
sage: g1
(3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 : 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 : 1)
sage: g1.order()
52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: r==E.order()
False
sage: r
52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: n=E.order()
sage: n
4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129030796414117214202539
sage: n/r
76329603384216526031706109802092473003
sage: factor(n)
3 * 11^2 * 10177^2 * 859267^2 * 52437899^2 * 52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: alpha=0x03530f615aa764a263544084485bf91a014712497bc9ba54f11114c3b3e45f08
sage: alpha
1503693002983401415113014640808306074223599471496430042206067283810050137864
sage: alpha*g1
(1033654949785203021207026044129189331069127518790367648505266630501389934793504305044295310538037400252804790110918 : 89832893542883859029728348878945587183573275246553105705168502974169963454784039491043776459113083475851957867623 : 1)
sage: 0x06b73e205fc1403b0ea47f87cd9d1752814bfcfa43f37e64e5a4267e7947890678319eeb
....: aa659bfbbb07f0b885924ac6
1033654949785203021207026044129189331069127518790367648505266630501389934793504305044295310538037400252804790110918
sage: 0x00956a7c3cbbfea2a46544aba6dd27989a2c8dcd6c9bed54416c158c0c3c74cbdd045171
....: d85527226a9c854523499467
89832893542883859029728348878945587183573275246553105705168502974169963454784039491043776459113083475851957867623
sage: alpha^2*g1
(317530896942699193401993928133193212893828000826560927504886177222118619833512039417536313380970329724770472758665 : 3784076042772903410141691002998593408675975121295218085246014556053129360108039689761174879948682644693003357197004 : 1)
sage: 0x02102361767f5aa63ca59d03f9985352223962a9bf72a1aaf540cdb1ef89a822c7a9ab5d
....: 77cb378112c9bb0519150d89
317530896942699193401993928133193212893828000826560927504886177222118619833512039417536313380970329724770472758665
sage: 0x1895ec61d5a8386f61e698c52f19991a3df095fc806fde62912822510e29688ad14a332f
....: b3866e416b2cae3b063112cc
3784076042772903410141691002998593408675975121295218085246014556053129360108039689761174879948682644693003357197004
sage: alpha^2
2261092647221239657091752652260266674954220400406356578851084432298038859086196117355910565756002857385403067247496885268714372239001032877485406482496
sage: n
4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129030796414117214202539
sage: r
52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: n*g1
(0 : 1 : 0)
sage: r*g1
(0 : 1 : 0)
sage: factor(r-1)
2^32 * 3 * 11 * 19 * 10177 * 125527 * 859267 * 906349^2 * 2508409 * 2529403 * 52437899 * 254760293^2
sage: 2^32
4294967296
sage: 2^16
65536
sage: r
52435875175126190479447740508185965837690552500527637822603658699938581184513
sage: power_mod(alpha,1,r)*g1
(1033654949785203021207026044129189331069127518790367648505266630501389934793504305044295310538037400252804790110918 : 89832893542883859029728348878945587183573275246553105705168502974169963454784039491043776459113083475851957867623 : 1)
sage: power_mod(alpha,65536,r)*g1
(2929581191141486328429440551007643252814074518455193727550712002326468324879784506948162616659764036885075131959131 : 1833309532402667846915061345496965443062083588117682951357230429927267422538646169998646858646199052204360375863032 : 1)
sage: power_mod(alpha,65537,r)*g1
(853565093434707070897210410773523905749086743143914719869029110470270375947122945706367973698433903895259486740180 : 3713832379110814907791946740505740797159596171420901812951617661121822875856088494720913309256289030430931653551227 : 1)
sage:
除param模块和pointproofs_groups模块外,其它模块均只对crate内public。有如下结构体定义:
/// Structure for porver parameters.
#[derive(Clone, Debug)]
pub struct ProverParams {
pub(crate) ciphersuite: Ciphersuite,
pub(crate) n: usize,
generators: Vec,
pp_len: usize,
precomp: Vec,
}
/// Structure for verifier parameters.
#[derive(Clone, Debug)]
pub struct VerifierParams {
pub(crate) ciphersuite: Ciphersuite,
pub(crate) n: usize,
generators: Vec,
pp_len: usize,
precomp: Vec,
gt_elt: Fq12,
}
/// Structure to hold a commitment.
#[derive(Clone, Debug, PartialEq)]
pub struct Commitment {
pub(crate) ciphersuite: Ciphersuite,
pub(crate) commit: PointproofsG1,
}
/// Structure to hold a proof.
#[derive(Clone, Debug, PartialEq)]
pub struct Proof {
pub(crate) ciphersuite: Ciphersuite,
pub(crate) proof: PointproofsG1,
}
err.rs
中主要定义的是一系列错误码,用于Pointproofs crate内部使用。pub(crate)
表示该变量在本crate内public可见,但对除本crate外的其它crates中均不可见。
//! this file is part of the pointproofs.
//! It defines a list of error messages.
pub(crate) const ERR_SEED_TOO_SHORT: &str = "The seed length is too short";
pub(crate) const ERR_CIPHERSUITE: &str = "Invalid ciphersuite ID";
pub(crate) const ERR_COMPRESS: &str = "Only support compress=true mode";
pub(crate) const ERR_INVALID_VALUE: &str = "Invalid number of values";
pub(crate) const ERR_INVALID_INDEX: &str = "Invalid index";
pub(crate) const ERR_DUPLICATED_INDEX: &str = "Duplicated index";
pub(crate) const ERR_INDEX_PROOF_NOT_MATCH: &str = "Length of index and proof sets do not match";
pub(crate) const ERR_X_COM_SIZE: &str =
"Invalid sizes for commit, proof, or values for cross commit";
pub(crate) const ERR_MAX_N: &str = "N is too large";
pub(crate) const ERR_PARAM: &str = "The input parameter is not correct";
pub(crate) const ERR_INDEX_VALUE_NOT_MATCH: &str = "Length of index and value sets do not match";
hash_to_field_pointproofs.rs
中,定义了一系列hash_to_*
函数。其中的hash_to_field_*
函数执行效率要高于https://github.com/algorand/pairing-plus
中的bls::hash_to_field
函数。详细的接口说明可参见SPEC.md
。
主要的接口函数有:
hash_to_field_pointproofs
:用于将输入的string通过SHA512后转换为非零的field element。// hash_to_field_pointproofs use SHA 512 to hash a blob into a non-zero field element
pub fn hash_to_field_pointproofs>(input: Blob) -> Fr
该函数具体的实现步骤为:
a.hash input
into 64 bytes array data
b.convert data
into a 512 bits integer a = os2ip(data)
c.t = a mod r
where r
is the group order
d.if t == 0
return 1, else return t
hash_to_tj_fr
:计算的是AggregateAcross
中的 t j ’ = H ’ ( j , { C j , S j , m ⃗ j [ S j ] } j ∈ [ l ] ) t_j’=H’(j,\{C_j,S_j,\vec{m}_j[S_j]\}_{j\in[l]}) tj’=H’(j,{Cj,Sj,mj[Sj]}j∈[l])。pub(crate) fn hash_to_tj_fr>(
commits: &[Commitment],
set: &[Vec],
value_sub_vector: &[Vec],
n: usize,
) -> Result, String>
基本的思路为:当aggregate的commitment数为1时(即 ∣ l ∣ = 1 |l|=1 ∣l∣=1时),设置 t j ’ = 1 t_j’=1 tj’=1。
Input: a list of k commitments
Input: a list of k * x indices, for which we need to generate t_j
Input: Value: a list of k * x messages that is committed to
Output: a list of k field elements
Error: ciphersuite id not supported
Error: lengths do no match
Steps:
a.tmp = {C | S | m[S]} for i \in [0 .. commit.len-1]
b.digest = SHA512(tmp)
c.for 0 <= i < commits.len(), res[i] = hash_to_field_pointproofs(i, digest)
注意:this procedure is a bit different from the paper, where no intermediate digest is generated. We pre-hash the data into a digest to improve efficiency.
hash_to_ti_fr
:计算的是AggregateAcross
中的 t j , i = H ( i , C j , S j , m ⃗ j [ S j ] ) t_{j,i}=H(i,C_j,S_j,\vec{m}_j[S_j]) tj,i=H(i,Cj,Sj,mj[Sj])或者same-commitment aggregte中的 t i = H ( i , C , S , m ⃗ [ S ] ) t_i=H(i,C,S,\vec{m}[S]) ti=H(i,C,S,m[S])。pub(crate) fn hash_to_ti_fr>(
commit: &Commitment,
set: &[usize],
value_sub_vector: &[Blob],
n: usize,
) -> Result, String>
总体的思路为:当aggregate后open的总位置数为1(即 ∣ S ∣ = 1 |S|=1 ∣S∣=1)时,设置 t i = 1 t_i=1 ti=1或 t j , i = 1 t_{j,i}=1 tj,i=1。
Input: the commitment
Input: a list of indices, for which we need to generate t_i
Input: Value: the messages that is committed to
Output: a list of field elements
Error: ciphersuite id not supported
Error: lengths do no match
Steps:
a.digest = SHA512(C | S | m[S])
b.for 0 <= i < set.len(), res[i] = hash_to_field_pointproofs(i, digest)
注意:this procedure is a bit different from the paper, where no intermediate digest is generated. We pre-hash the data into a digest to improve efficiency.
param.rs
中,pub函数有:
check_ciphersuite
:目前仅支持csid=0u8
。const VALID_CIPHERSUITE: [u8; 1] = [0u8];
/// Ciphersuite ID is a wrapper of u8.
pub type Ciphersuite = u8;
/// Checks if csid is supported. Currently only support csid = 0.
pub fn check_ciphersuite(csid: Ciphersuite) -> bool {
VALID_CIPHERSUITE.contains(&csid)
}
paramgen_from_seed
:根据seed和csid生成public parameters——Prove key和Verify key。(该函数仅在测试环境下调用。实际生产部署时,应使用单独的https://github.com/algorand/pointproofs-paramgen
crate 来生成Prove key和Verify key,以保证public parameters的安全性。)
1)要求seed长度不低于32,否则报错ERR_SEED_TOO_SHORT
。
2)会check_ciphersuite
,否则报错ERR_CIPHERSUITE
。
3) 0 < n < = 65536 0ERR_MAX_N
。
4)将seed通过hash_to_field_pointproofs
映射为 α \alpha α值。
5)计算Prove key: g 1 α , ⋯ , g 1 α N , g 1 α N + 2 , ⋯ , g 1 α 2 N g_1^{\alpha},\cdots,g_1^{\alpha^N},g_1^{\alpha^{N+2}},\cdots,g_1^{\alpha^{2N}} g1α,⋯,g1αN,g1αN+2,⋯,g1α2N;计算Verify key: g 2 α , ⋯ , g 2 α N ; g T α N + 1 g_2^{\alpha},\cdots,g_2^{\alpha^N};g_T^{\alpha^{N+1}} g2α,⋯,g2αN;gTαN+1
precomp_256
:预计算,对于Prove和Verify都有,当 n < = 1024 n<=1024 n<=1024时,可明显提升性能。
/// pre-process the public parameters with precomputation value set to 256
pub fn precomp_256(&mut self) {
let twice_n = self.generators.len();
self.precomp = vec![PointproofsG1Affine::zero(); 256 * twice_n];
for i in 0..twice_n {
self.generators[i].precomp_256(&mut self.precomp[i * 256..(i + 1) * 256]);
}
self.pp_len = self.n * 512;
}
// pre[i] becomes (\sum_{b such that bth bit of i is 1} 2^{32i}) * self for i in 0..25
fn precomp_256(&self, pre: &mut [Self]) {
// TODO: check if pre has the right length?
// TODO: possible optimization: convert 256 points into affine jointly by doing a single inversion, rather than separately
// In fact, this function gets called multiple times, and the conversions to affine could be cheaper if done together
pre[0] = Self::zero();
let mut piece_length = 1;
let mut power_of_2_times_self = self.into_projective(); // power_of_2_times_self = 2^{32*piece_length} * self
while piece_length <= 128 {
// operate in pieces of length 1, 2, 4, 8, 16, 32, 64, 128
pre[piece_length] = power_of_2_times_self.into_affine();
for i in 1..piece_length {
pre[i + piece_length] = pre[i];
let mut temp = pre[i].into_projective();
temp.add_assign_mixed(&pre[piece_length]);
pre[i + piece_length] = temp.into_affine();
}
if piece_length < 128 {
for _ in 0..32 {
power_of_2_times_self.double();
}
}
piece_length *= 2;
}
}
new
:对vector $\vec{m}$
生成commitment $C$
,基本思路为:
将$\vec{m}$
中的每一个值都通过hash_to_field_repr_pointproofs
经Sha512再映射为scalar field值,计算 C = ∏ i = 1 n p p [ i ] m i C=\prod_{i=1}^{n}pp[i]^{m_i} C=∏i=1npp[i]mi(通过pp_sum_of_prod_helper
计算)。
update
:更新单个位置的commitment。
pub fn update>(
&mut self,
prover_params: &ProverParams,
changed_index: usize,
value_before: Blob,
value_after: Blob,
) -> Result<(), String>
Input: self, a Commitment
Input: a ProverParam
Input: the index to be updated
Input: the original value
Input: the value updated to
Output: mutate self to the updated commit
Error: ciphersuite is not supported
Error: self.ciphersuite does not match prover_params.ciphersuite
Error: index out of range
Steps:
a.hash value_before into old_scalar
b.hash value_after into new_scalar
c.commit = commit * prover_params,generators[changed_index]^(new_scalar-old_scalar)
batch_update
:更新多个位置的commitment。pub fn batch_update>(
&mut self,
prover_params: &ProverParams,
changed_index: &[usize],
value_before: &[Blob],
value_after: &[Blob],
) -> Result<(), String>
Input: self, a Commitment
Input: a ProverParam
Input: a list of indices to be updated
Input: a list of original values
Input: a list of values updated to
Output: mutate self to the updated commit
Error: ciphersuite is not supported
Error: self.ciphersuite does not match prover_params.ciphersuite
Error: index out of range
Error: # of changed_index, value_before or value_after do not match
Steps:
a.for i in indices
b.hash value_before[i]s into old_scalar[i]
c.hash value_after[i]s into new_scalar[i]
d.commit = commit * \prod prover_params.generators[i]^(new_scalar[i]-old_scalar[i]) for i in indices
pp_sum_of_prod_helper
:用于计算 C = ∏ i = 1 n p p [ i ] m i C=\prod_{i=1}^{n}pp[i]^{m_i} C=∏i=1npp[i]mi。/// This helper computes the sum of product:
/// \sum_{i=start}^{end-1}
/// param.generator[i]^scarlar_u64[i]
/// It tries to use pre-computed data when possible.
/// It assumes end - start = n; and the lengths matches.
/// It doesnot perform any sanity checks of those conditions.
pub(crate) fn pp_sum_of_prod_helper(
prover_params: &ProverParams,
scalars_u64: &[&[u64; 4]],
start: usize,
end: usize,
) -> PointproofsG1 {
// the second condition `n <= 1024` comes from benchmarking
// pre-computation is faster only when the #basis is <1024
if prover_params.precomp.len() == 512 * prover_params.n && prover_params.n <= 1024 {
PointproofsG1Affine::sum_of_products_precomp_256(
&prover_params.generators[start..end],
&scalars_u64,
&prover_params.precomp[start * 256..end * 256],
)
} else {
PointproofsG1Affine::sum_of_products(&prover_params.generators[start..end], &scalars_u64)
}
}
sum_of_products
中使用了pippenger算法。
sum_of_products_precomp_256
中使用了public parameter中precompute的信息。(// pre[i] becomes (\sum_{b such that bth bit of i is 1} 2^{32i}) * self for i in 0…25)
fn sum_of_products(points: &[Self], scalars: &[&[u64; 4]]) -> $projective {
// TODO: figure out what to do if the lengths of the two input slices don't match
// For now, take the minimum
let num_components = if points.len() < scalars.len() {
points.len()
} else {
scalars.len()
};
Self::sum_of_products_pippinger(
points,
scalars,
Self::find_pippinger_window(num_components),
)
}
// Expects pre[j*256+i] = (\sum_{b such that bth bit of i is 1} 2^{32i}) * self[j] for i in 0..256 and for each j
// pre can be obtained by calling precomp_256
fn sum_of_products_precomp_256(
points: &[Self],
scalars: &[&[u64; 4]],
pre: &[Self],
) -> $projective {
// TODO: we may decide we should clear memory, such as the old self
// and the precomp array.
// For now, none of the other functions do that, either.
// TODO: figure out what to do if the lengths of the two input slices don't match
// For now, take the minimum
let mut res = Self::Projective::zero();
let num_components = if points.len() < scalars.len() {
points.len()
} else {
scalars.len()
};
// Interleaved window technique: deal with each of the 8 32-bit chunks words of each scalar in parallel
// TODO: understand how this large table will affect performance due to caching
for i in (0..32).rev() {
res.double();
for j in 0..num_components {
let mut byte = (scalars[j][3] >> (i + 25)) & 128;
byte |= ((scalars[j][3] >> i) << 6) & 64; // can't shift by i-6 because it can be negative
byte |= (scalars[j][2] >> (i + 27)) & 32;
byte |= ((scalars[j][2] >> i) << 4) & 16;
byte |= (scalars[j][1] >> (i + 29)) & 8;
byte |= ((scalars[j][1] >> i) << 2) & 4;
byte |= (scalars[j][0] >> (i + 31)) & 2;
byte |= (scalars[j][0] >> i) & 1;
res.add_assign_mixed(&pre[(j << 8) + byte as usize]);
}
}
res
}
}
serialize
和deserialize
用于对Commitment/Proof/ProverParams/VerifierParams进行序列化和反序列化。会调用pairing-plus
crate中的serdes.rs内相关接口。fn serialize(&self, writer: &mut W, compressed: bool) -> Result<()>
Input: a Commitment
Input: a writable buffer
Input: a flag whether to compress the group point or not; must be true
Output: none
Error: compression is false
Error: ciphersuite is not supported
Error: serialization fails
Steps: convert | ciphersuite | commit | to bytes
fn deserialize(reader: &mut R, compressed: bool) -> Result
Input: a readeble buffer
Input: a flag whether the group elements are expected to be compressed or not; must be true
Output: a Commitment
Error: compression is false
Error: ciphersuite is not supported
Error: encoded buffer has a different compressness than specified
Error: deserialization fails
Steps: convert bytes to | ciphersuite | commit |
主要定义了部分类型的重命名。
new
:生成单个位置index的proof。/// generate a new proof
pub fn new>(
prover_params: &ProverParams,
values: &[Blob],
index: usize,
) -> Result
Input: a ProverParams
Input: a list of values to commit
Input: the index for which the proof is generated
Output: a new proof
Error: ciphersuite is not supported
Error: index out of range
Error: values.length does not match n
Steps:
a.hash the values into scarlars
b.proof = \prod prover_params.generators[n - index + i]^scalar[i] for i in range(n) except index (in implementation we implement it as for i in range(n) without exception, since the corresponding generator was already set to 0)
verify
:验证单个位置的proof。/// Verify the proof
pub fn verify>(
&self,
verifier_params: &VerifierParams,
com: &Commitment,
value: Blob,
index: usize,
) -> bool
Input: self, the proof to be verified
Input: a VerifierParams
Input: the commitment
Input: the value that proof is generated
Input: index of the value in the value vector
Output: if the proof is valid w.r.t. commit/values/index or not
Steps:
a.Compute t = hash_to_field_pointproofs(value)
b.return e(com^{1/t}, veririer_params.generators[n-index-1]) * e(proof^{-1/t}, generator_of_g2) == gt_elt
update
:更新单个位置的proof。/// For updating your proof when someone else's value changes
/// Not for updating your own proof when your value changes -- because then the proof does not change!
pub fn update>(
&mut self,
prover_params: &ProverParams,
proof_index: usize,
changed_index: usize,
value_before: Blob,
value_after: Blob,
) -> Result<(), String>
Input: self, the proof to be updated
Input: a ProverParams
Input: proof_index, the index for which the proof is generated
Input: changed_index, the index for which the proof will be updated
Output: mutate self to a new proof
Error: ciphersuite is not supported
Error: index out of range
Note: This function is used for updating your proof when someone else’s value changes. It is not for updating your own proof when your value changes – because then the proof does not change!
Steps:
a.hash value_before into old_scalar
b.hash value_after into new_scalar
c.proof = proof * prover_params.generators[changed_index + n - proof_index]^(new_scalar-old_scalar)
batch_new
:同时生成多个位置的proof,不再逐个生成。/// generate a list of new proofs
pub fn batch_new>(
prover_params: &ProverParams,
values: &[Blob],
indices: &[usize],
) -> Result, String>
Input: a ProverParam
Input: a list of values to commit
Input: a list of indices for which the proofs are generated
Output: a list of proofs, each corresponding to an index
Error: ciphersuite is not supported
Error: index out of range
Error: values.length does not match n
Error: indices.length = 0 or indices.length > n
Steps:
a.hash the values into scarlars
b.for j in 0…indices.len():
b.a.proof[j] = \prod prover_params[n - indices[j] + i]^scalar[i] for i in range(n) except index
(in implementation we implement it as for i in range(n) without exception, since the corresponding generator was already set to 1)
c_api.rs
中实现的是rust接口函数的C语言封装。