├── .circleci └── config.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches ├── membership_bp.rs ├── membership_bp_60.rs ├── membership_class.rs ├── membership_hash.rs ├── membership_prime.rs ├── membership_prime_60.rs ├── modeq.rs ├── nonmembership_bp.rs ├── nonmembership_hash.rs ├── nonmembership_prime.rs ├── root.rs ├── rsa.rs └── snark_range.rs └── src ├── channels.rs ├── commitments ├── integer.rs ├── mod.rs └── pedersen.rs ├── lib.rs ├── parameters.rs ├── protocols ├── coprime │ ├── channel.rs │ ├── mod.rs │ └── transcript.rs ├── hash_to_prime │ ├── bp.rs │ ├── channel.rs │ ├── mod.rs │ ├── snark_hash.rs │ ├── snark_range.rs │ └── transcript.rs ├── membership │ ├── channel.rs │ ├── mod.rs │ └── transcript.rs ├── mod.rs ├── modeq │ ├── channel.rs │ ├── mod.rs │ └── transcript.rs ├── nonmembership │ ├── channel.rs │ ├── mod.rs │ └── transcript.rs └── root │ ├── channel.rs │ ├── mod.rs │ └── transcript.rs ├── transcript.rs └── utils ├── curve.rs └── mod.rs /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/rust:1.42.0 6 | steps: 7 | - add_ssh_keys: 8 | fingerprints: 9 | - "98:25:7d:11:f9:5c:62:91:0b:f0:10:e1:93:35:30:65" 10 | - checkout 11 | - run: cargo test --release 12 | - run: rustup install nightly-2020-04-22 13 | - run: rustup component add clippy 14 | - run: rustup component add clippy --toolchain nightly-2020-04-22 15 | - run: cargo +nightly-2020-04-22 test --no-default-features --features dalek 16 | - run: cargo fmt --all -- --check 17 | - run: cargo clippy --release --all-targets -- -D warnings 18 | - run: cargo +nightly-2020-04-22 clippy --release --all-targets --no-default-features --features dalek -- -D warnings 19 | - run: cargo install --force cargo-audit 20 | - run: cargo audit 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | .idea 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cpsnarks-set" 3 | version = "0.1.0" 4 | authors = ["Kobi Gurkan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | accumulator = { git = "https://github.com/kobigurk/cpsnarks-set-accumulator" } 9 | quick-error = "1.2.3" 10 | rug = "1.7.0" 11 | ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves" } 12 | merlin = "2.0.0" 13 | rand = { version = "0.7" } 14 | ark-ff = { git = "https://github.com/arkworks-rs/algebra" } 15 | ark-ec = { git = "https://github.com/arkworks-rs/algebra" } 16 | ark-serialize = { git = "https://github.com/arkworks-rs/algebra" } 17 | ark-relations = { git = "https://github.com/arkworks-rs/snark" } 18 | ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } 19 | ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives", branch = "main", features = [ "r1cs" ] } 20 | legogro16 = { git = "https://github.com/kobigurk/legogro16" } 21 | curve25519-dalek = { version = "3", optional = true, features = ["serde", "simd_backend"] } 22 | bulletproofs = { git = "https://github.com/dalek-cryptography/bulletproofs", branch = "develop", optional = true, features = ["yoloproofs"] } 23 | digest = "0.8.1" 24 | blake2 = ">= 0.8.1" 25 | cfg-if = "0.1" 26 | 27 | [features] 28 | dalek = ["curve25519-dalek", "bulletproofs"] 29 | arkworks = [] 30 | class = [] 31 | default = ["arkworks"] 32 | 33 | [dev-dependencies] 34 | criterion = "0.3" 35 | 36 | [lib] 37 | bench = false 38 | 39 | [[bench]] 40 | name = "root" 41 | harness = false 42 | required-features = ["arkworks"] 43 | 44 | [[bench]] 45 | name = "modeq" 46 | harness = false 47 | required-features = ["arkworks"] 48 | 49 | [[bench]] 50 | name = "rsa" 51 | harness = false 52 | required-features = ["arkworks"] 53 | 54 | [[bench]] 55 | name = "membership_prime" 56 | harness = false 57 | required-features = ["arkworks"] 58 | 59 | [[bench]] 60 | name = "nonmembership_prime" 61 | harness = false 62 | required-features = ["arkworks"] 63 | 64 | [[bench]] 65 | name = "membership_hash" 66 | harness = false 67 | required-features = ["arkworks"] 68 | 69 | [[bench]] 70 | name = "membership_class" 71 | harness = false 72 | required-features = ["arkworks", "class"] 73 | 74 | [[bench]] 75 | name = "membership_bp" 76 | harness = false 77 | required-features = ["dalek"] 78 | 79 | [[bench]] 80 | name = "snark_range" 81 | harness = false 82 | required-features = ["arkworks"] 83 | 84 | [[bench]] 85 | name = "membership_prime_60" 86 | harness = false 87 | required-features = ["arkworks"] 88 | 89 | [[bench]] 90 | name = "membership_bp_60" 91 | harness = false 92 | required-features = ["dalek"] 93 | 94 | [[bench]] 95 | name = "nonmembership_hash" 96 | harness = false 97 | required-features = ["arkworks"] 98 | 99 | [[bench]] 100 | name = "nonmembership_bp" 101 | harness = false 102 | required-features = ["dalek"] 103 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CPSNARKs-Set 2 | ------------ 3 | 4 | ## Overview 5 | 6 | **The library is not ready for production use!** 7 | 8 | Implements various RSA-based protocols from the [Zero-Knowledge Proofs for Set Membership: 9 | Efficient, Succinct, Modular](https://eprint.iacr.org/2019/1255.pdf) paper. 10 | 11 | It implements the following protocols: 12 | 13 | * [CPMemRSA](src/protocols/membership) - RSA-based set membership. 14 | * [CPNonMemRSA](src/protocols/nonmembership) - RSA-based set non-membership. 15 | 16 | The protocols are composed out of the following subprotocols: 17 | 18 | * [root](src/protocols/root) - shows a committed element exists in an accumulator. 19 | * [coprime](src/protocols/coprime) - shows a committed element does not exist in an accumulator. 20 | * [modeq](src/protocols/modeq) - shows an integer commitment and a Pedersen commitment contain the same value. 21 | * [hash\_to\_prime](src/protocols/hash_to_prime) - a number of protocols that perform a range proof or hash-to-prime and output a commitment: 22 | * [snark\_range](src/protocols/hash_to_prime/snark_range.rs) - LegoGroth16-based range proof. 23 | * [snark\_hash](src/protocols/hash_to_prime/bp.rs) - Bulletproofs-based range proof. 24 | * [bp](src/protocols/hash_to_prime/snark_hash.rs) - LegoGroth16-based hash-to-prime proof. 25 | 26 | ## Usage 27 | 28 | ### Tests 29 | 30 | The following commands assume you have a recent stable Rust toolchain installed, e.g. 1.42.0. The Bulletproofs implementation also requires a nightly toolchain. 31 | 32 | To run the tests for membership and non-membership protocols on BLS12-381, run `cargo test --release`. 33 | 34 | To run the tests for membership and non-membership protocols on Ristretto, run `cargo +nigthly test --release --no-default-features --features dalek`. 35 | 36 | ### Benchmarks 37 | 38 | The library contains a number of benchmarks: 39 | 40 | #### Set membership 41 | 42 | * [membership\_prime](benches/membership_prime.rs) - benchmarks RSA-based set membership when the elements are prime with a LegoGroth16 range proof. 43 | * [membership\_prime\_60](benches/membership_prime_60.rs) - benchmarks RSA-based set membership when the elements are prime and are also small (around 60 bits) with a LegoGroth16 range proof. 44 | * [membership\_bp](benches/membership_bp.rs) - benchmarks RSA-based set membership when the elements are prime with a Bulletproofs range proof. 45 | * [membership\_bp\_60](benches/membership_bp_60.rs) - benchmarks RSA-based set membership when the elements are prime and are also small (around 60 bits) with a Bulletproofs range proof. 46 | * [membership\_hash](benches/membership_hash.rs) - benchmarks RSA-based set membership when the elements are not prime and a Blake2s-based hash-to-prime is performed. 47 | * [membership\_class](benches/membership_class.rs) - benchmarks class groups-based set membership when the elements are prime with a LegoGroth16 range proof. This is slow and experimental and the paper doesn't prove its security. 48 | 49 | 50 | #### Set non-membership 51 | * [nonmembership\_prime](benches/nonmembership_prime.rs) - benchmarks RSA-based set non-membership when the elements are prime with a LegoGroth16 range proof. 52 | * [nonmembership\_bp](benches/nonmembership_bp.rs) - benchmarks RSA-based set non-membership when the elements are prime with a Bulletproofs range proof. 53 | * [nonmembership\_hash](benches/nonmembership_hash.rs) - benchmarks RSA-based set non-membership when the elements are not prime and a Blake2s-based hash-to-prime is performed. 54 | 55 | To run benchmarks for the protocols with SNARKs use `cargo bench` and for the protocols with Bulletproofs use `cargo bench --no-default-features --features dalek`. 56 | 57 | ## Libraries 58 | 59 | We've implemented [LegoGroth16](https://github.com/kobigurk/legogro16) on top of [Zexe library](https://github.com/scipr-lab/zexe). 60 | 61 | We've modified the Cambrian Tech's accumulator library. The modified version is [available here](https://github.com/kobigurk/cpsnarks-set-accumulator). 62 | 63 | We've modifies librustzcash to get benchmarks for Merkle tree-based membership proofs. The modified version is [available here](https://github.com/kobigurk/cpsnarks-librustzcash). To run the benchmarks use `cargo run --release --example merkle_sha` for SHA256-based trees and `cargo run --release --example merkle_pedersen` for Pedersen hash-based trees. 64 | 65 | ## License 66 | 67 | This code is licensed under either of the following licenses, at your discretion. 68 | 69 | * [Apache License Version 2.0](LICENSE-APACHE) 70 | * [MIT License](LICENSE-MIT) 71 | 72 | Unless you explicitly state otherwise, any contribution that you submit to this library shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions. 73 | 74 | ## Reference paper 75 | 76 | [Zero-Knowledge Proofs for Set Membership: Efficient, Succinct, Modular](https://eprint.iacr.org/2019/1255.pdf) 77 | 78 | [Daniel Benarroch](https://github.com/daniben31), [Matteo Campanelli](https://www.github.com/matteocam), [Dario Fiore](https://github.com/dariofiore), [Kobi Gurkan](https://github.com/kobigurk), [Dimitris Kolonelos](https://software.imdea.org/people/dimitris.kolonelos/index.html). 79 | 80 | 81 | -------------------------------------------------------------------------------- /benches/membership_bp.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use cpsnarks_set::{ 4 | commitments::Commitment, 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::{bp::Protocol as HPProtocol, CRSSize}, 8 | membership::{ 9 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 10 | Protocol, Statement, Witness, 11 | }, 12 | }, 13 | }; 14 | use criterion::{criterion_group, criterion_main, Criterion}; 15 | use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; 16 | use merlin::Transcript; 17 | use rand::thread_rng; 18 | use rug::rand::RandState; 19 | use rug::Integer; 20 | use std::cell::RefCell; 21 | 22 | const LARGE_PRIMES: [u64; 3] = [ 23 | 12_702_637_924_034_044_211, 24 | 378_373_571_372_703_133, 25 | 8_640_171_141_336_142_787, 26 | ]; 27 | 28 | pub fn criterion_benchmark(c: &mut Criterion) { 29 | let params = Parameters::from_curve::().unwrap().0; 30 | println!("params: {}", params); 31 | let mut rng1 = RandState::new(); 32 | rng1.seed(&Integer::from(13)); 33 | let mut rng2 = thread_rng(); 34 | 35 | let mut crs = cpsnarks_set::protocols::membership::Protocol::< 36 | Rsa2048, 37 | RistrettoPoint, 38 | HPProtocol, 39 | >::setup(¶ms, &mut rng1, &mut rng2) 40 | .unwrap() 41 | .crs; 42 | println!( 43 | "crs size: {:?}", 44 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 45 | ); 46 | let protocol = Protocol::::from_crs(&crs); 47 | 48 | let value = Integer::from(Integer::u_pow_u( 49 | 2, 50 | (crs.parameters.hash_to_prime_bits) as u32, 51 | )) - &Integer::from(129); 52 | let randomness = Integer::from(5); 53 | let commitment = protocol 54 | .crs 55 | .crs_modeq 56 | .pedersen_commitment_parameters 57 | .commit(&value, &randomness) 58 | .unwrap(); 59 | 60 | let accum = 61 | accumulator::Accumulator::::empty(); 62 | let accum = accum.add( 63 | &LARGE_PRIMES 64 | .iter() 65 | .skip(1) 66 | .map(|p| Integer::from(*p)) 67 | .collect::>(), 68 | ); 69 | 70 | let accum = accum.add_with_proof(&[value.clone()]); 71 | let acc = accum.0.value; 72 | let w = accum.1.witness.0.value; 73 | assert_eq!(Rsa2048::exp(&w, &value), acc); 74 | 75 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 76 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = Some(proof_transcript.clone()); 77 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 78 | let statement = Statement { 79 | c_e_q: commitment, 80 | c_p: acc.clone(), 81 | }; 82 | protocol 83 | .prove( 84 | &mut verifier_channel, 85 | &mut rng1, 86 | &mut rng2, 87 | &statement, 88 | &Witness { 89 | e: value.clone(), 90 | r_q: randomness.clone(), 91 | w: w.clone(), 92 | }, 93 | ) 94 | .unwrap(); 95 | let proof = verifier_channel.proof().unwrap(); 96 | println!( 97 | "proof size: {}", 98 | proof.proof_hash_to_prime.serialized_size() 99 | ); 100 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 101 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 102 | Some(verification_transcript.clone()); 103 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 104 | protocol.verify(&mut prover_channel, &statement).unwrap(); 105 | 106 | c.bench_function("membership_bp protocol proving", |b| { 107 | b.iter(|| { 108 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 109 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 110 | Some(proof_transcript.clone()); 111 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 112 | let statement = Statement { 113 | c_e_q: commitment, 114 | c_p: acc.clone(), 115 | }; 116 | protocol 117 | .prove( 118 | &mut verifier_channel, 119 | &mut rng1, 120 | &mut rng2, 121 | &statement, 122 | &Witness { 123 | e: value.clone(), 124 | r_q: randomness.clone(), 125 | w: w.clone(), 126 | }, 127 | ) 128 | .unwrap(); 129 | }) 130 | }); 131 | c.bench_function("membership_bp protocol verification", |b| { 132 | b.iter(|| { 133 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 134 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 135 | Some(verification_transcript.clone()); 136 | let mut prover_channel = 137 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 138 | protocol.verify(&mut prover_channel, &statement).unwrap(); 139 | }) 140 | }); 141 | } 142 | 143 | criterion_group!(benches, criterion_benchmark); 144 | criterion_main!(benches); 145 | -------------------------------------------------------------------------------- /benches/membership_bp_60.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use cpsnarks_set::{ 4 | commitments::Commitment, 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::{bp::Protocol as HPProtocol, CRSSize}, 8 | membership::{ 9 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 10 | Protocol, Statement, Witness, 11 | }, 12 | }, 13 | }; 14 | use criterion::{criterion_group, criterion_main, Criterion}; 15 | use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; 16 | use merlin::Transcript; 17 | use rand::thread_rng; 18 | use rug::rand::RandState; 19 | use rug::Integer; 20 | use std::cell::RefCell; 21 | 22 | const LARGE_PRIMES: [u64; 3] = [ 23 | 12_702_637_924_034_044_211, 24 | 378_373_571_372_703_133, 25 | 8_640_171_141_336_142_787, 26 | ]; 27 | 28 | pub fn criterion_benchmark(c: &mut Criterion) { 29 | let params = Parameters::from_curve_and_small_prime_size::(60, 70) 30 | .unwrap() 31 | .0; 32 | println!("params: {}", params); 33 | let mut rng1 = RandState::new(); 34 | rng1.seed(&Integer::from(13)); 35 | let mut rng2 = thread_rng(); 36 | 37 | let mut crs = cpsnarks_set::protocols::membership::Protocol::< 38 | Rsa2048, 39 | RistrettoPoint, 40 | HPProtocol, 41 | >::setup(¶ms, &mut rng1, &mut rng2) 42 | .unwrap() 43 | .crs; 44 | println!( 45 | "crs size: {:?}", 46 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 47 | ); 48 | let protocol = Protocol::::from_crs(&crs); 49 | 50 | let value = Integer::from(Integer::u_pow_u( 51 | 2, 52 | (crs.parameters.hash_to_prime_bits) as u32, 53 | )) - &Integer::from(129); 54 | let randomness = Integer::from(5); 55 | let commitment = protocol 56 | .crs 57 | .crs_modeq 58 | .pedersen_commitment_parameters 59 | .commit(&value, &randomness) 60 | .unwrap(); 61 | 62 | let accum = 63 | accumulator::Accumulator::::empty(); 64 | let accum = accum.add( 65 | &LARGE_PRIMES 66 | .iter() 67 | .skip(1) 68 | .map(|p| Integer::from(*p)) 69 | .collect::>(), 70 | ); 71 | 72 | let accum = accum.add_with_proof(&[value.clone()]); 73 | let acc = accum.0.value; 74 | let w = accum.1.witness.0.value; 75 | assert_eq!(Rsa2048::exp(&w, &value), acc); 76 | 77 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 78 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = Some(proof_transcript.clone()); 79 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 80 | let statement = Statement { 81 | c_e_q: commitment, 82 | c_p: acc.clone(), 83 | }; 84 | protocol 85 | .prove( 86 | &mut verifier_channel, 87 | &mut rng1, 88 | &mut rng2, 89 | &statement, 90 | &Witness { 91 | e: value.clone(), 92 | r_q: randomness.clone(), 93 | w: w.clone(), 94 | }, 95 | ) 96 | .unwrap(); 97 | let proof = verifier_channel.proof().unwrap(); 98 | println!( 99 | "proof size: {}", 100 | proof.proof_hash_to_prime.serialized_size() 101 | ); 102 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 103 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 104 | Some(verification_transcript.clone()); 105 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 106 | protocol.verify(&mut prover_channel, &statement).unwrap(); 107 | 108 | c.bench_function("membership_bp_60 protocol proving", |b| { 109 | b.iter(|| { 110 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 111 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 112 | Some(proof_transcript.clone()); 113 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 114 | let statement = Statement { 115 | c_e_q: commitment, 116 | c_p: acc.clone(), 117 | }; 118 | protocol 119 | .prove( 120 | &mut verifier_channel, 121 | &mut rng1, 122 | &mut rng2, 123 | &statement, 124 | &Witness { 125 | e: value.clone(), 126 | r_q: randomness.clone(), 127 | w: w.clone(), 128 | }, 129 | ) 130 | .unwrap(); 131 | }) 132 | }); 133 | c.bench_function("membership_bp_60 protocol verification", |b| { 134 | b.iter(|| { 135 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 136 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 137 | Some(verification_transcript.clone()); 138 | let mut prover_channel = 139 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 140 | protocol.verify(&mut prover_channel, &statement).unwrap(); 141 | }) 142 | }); 143 | } 144 | 145 | criterion_group!(benches, criterion_benchmark); 146 | criterion_main!(benches); 147 | -------------------------------------------------------------------------------- /benches/membership_class.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::ClassGroup; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::snark_range::Protocol as HPProtocol, 12 | membership::{ 13 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 14 | Protocol, Statement, Witness, 15 | }, 16 | }, 17 | }; 18 | use criterion::{criterion_group, criterion_main, Criterion}; 19 | use merlin::Transcript; 20 | use rand::thread_rng; 21 | use rug::rand::RandState; 22 | use rug::Integer; 23 | use std::cell::RefCell; 24 | 25 | const LARGE_PRIMES: [u64; 3] = [ 26 | 12_702_637_924_034_044_211, 27 | 378_373_571_372_703_133, 28 | 8_640_171_141_336_142_787, 29 | ]; 30 | 31 | pub fn criterion_benchmark(c: &mut Criterion) { 32 | let params = Parameters::from_curve::().unwrap().0; 33 | println!("params: {}", params); 34 | let mut rng1 = RandState::new(); 35 | rng1.seed(&Integer::from(13)); 36 | let mut rng2 = thread_rng(); 37 | 38 | let crs = cpsnarks_set::protocols::membership::Protocol::< 39 | ClassGroup, 40 | G1Projective, 41 | HPProtocol, 42 | >::setup(¶ms, &mut rng1, &mut rng2) 43 | .unwrap() 44 | .crs; 45 | let protocol = Protocol::>::from_crs(&crs); 46 | 47 | let value = Integer::from(Integer::u_pow_u( 48 | 2, 49 | (crs.parameters.hash_to_prime_bits) as u32, 50 | )) - &Integer::from(245); 51 | let randomness = 52 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 53 | let commitment = protocol 54 | .crs 55 | .crs_modeq 56 | .pedersen_commitment_parameters 57 | .commit(&value, &randomness) 58 | .unwrap(); 59 | 60 | let accum = 61 | accumulator::Accumulator::::empty(); 62 | let accum = accum.add( 63 | &LARGE_PRIMES 64 | .iter() 65 | .skip(1) 66 | .map(|p| Integer::from(*p)) 67 | .collect::>(), 68 | ); 69 | 70 | let accum = accum.add_with_proof(&[value.clone()]); 71 | let acc = accum.0.value; 72 | let w = accum.1.witness.0.value; 73 | assert_eq!(ClassGroup::exp(&w, &value), acc); 74 | 75 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 76 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 77 | let statement = Statement { 78 | c_e_q: commitment, 79 | c_p: acc.clone(), 80 | }; 81 | protocol 82 | .prove( 83 | &mut verifier_channel, 84 | &mut rng1, 85 | &mut rng2, 86 | &statement, 87 | &Witness { 88 | e: value.clone(), 89 | r_q: randomness.clone(), 90 | w: w.clone(), 91 | }, 92 | ) 93 | .unwrap(); 94 | let proof = verifier_channel.proof().unwrap(); 95 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 96 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 97 | protocol.verify(&mut prover_channel, &statement).unwrap(); 98 | 99 | c.bench_function("membership_class protocol proving", |b| { 100 | b.iter(|| { 101 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 102 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 103 | let statement = Statement { 104 | c_e_q: commitment, 105 | c_p: acc.clone(), 106 | }; 107 | protocol 108 | .prove( 109 | &mut verifier_channel, 110 | &mut rng1, 111 | &mut rng2, 112 | &statement, 113 | &Witness { 114 | e: value.clone(), 115 | r_q: randomness.clone(), 116 | w: w.clone(), 117 | }, 118 | ) 119 | .unwrap(); 120 | }) 121 | }); 122 | 123 | c.bench_function("membership_class protocol verification", |b| { 124 | b.iter(|| { 125 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 126 | let mut prover_channel = 127 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 128 | protocol.verify(&mut prover_channel, &statement).unwrap(); 129 | }) 130 | }); 131 | } 132 | 133 | criterion_group!(benches, criterion_benchmark); 134 | criterion_main!(benches); 135 | -------------------------------------------------------------------------------- /benches/membership_hash.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::{ 12 | snark_hash::{HashToPrimeHashParameters, Protocol as HPProtocol}, 13 | CRSSize, 14 | }, 15 | membership::{ 16 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 17 | Protocol, Statement, Witness, 18 | }, 19 | }, 20 | }; 21 | use criterion::{criterion_group, criterion_main, Criterion}; 22 | use merlin::Transcript; 23 | use rand::thread_rng; 24 | use rug::rand::RandState; 25 | use rug::Integer; 26 | use std::cell::RefCell; 27 | 28 | const LARGE_PRIMES: [u64; 3] = [ 29 | 12_702_637_924_034_044_211, 30 | 378_373_571_372_703_133, 31 | 8_640_171_141_336_142_787, 32 | ]; 33 | 34 | struct TestHashToPrimeParameters {} 35 | impl HashToPrimeHashParameters for TestHashToPrimeParameters { 36 | const MESSAGE_SIZE: u16 = 254; 37 | } 38 | 39 | pub fn criterion_benchmark(c: &mut Criterion) { 40 | let params = Parameters::from_curve::().unwrap().0; 41 | println!("params: {}", params); 42 | let mut rng1 = RandState::new(); 43 | rng1.seed(&Integer::from(13)); 44 | let mut rng2 = thread_rng(); 45 | 46 | let crs = cpsnarks_set::protocols::membership::Protocol::< 47 | Rsa2048, 48 | G1Projective, 49 | HPProtocol, 50 | >::setup(¶ms, &mut rng1, &mut rng2) 51 | .unwrap() 52 | .crs; 53 | println!( 54 | "crs size: {:?}", 55 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 56 | ); 57 | let protocol = Protocol::< 58 | Rsa2048, 59 | G1Projective, 60 | HPProtocol, 61 | >::from_crs(&crs); 62 | drop(crs); 63 | 64 | let value = Integer::from(Integer::u_pow_u( 65 | 2, 66 | (protocol.crs.parameters.hash_to_prime_bits) as u32, 67 | )) 68 | .random_below(&mut rng1); 69 | let (hashed_value, _) = protocol.hash_to_prime(&value).unwrap(); 70 | let randomness = 71 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 72 | let commitment = protocol 73 | .crs 74 | .crs_modeq 75 | .pedersen_commitment_parameters 76 | .commit(&hashed_value, &randomness) 77 | .unwrap(); 78 | 79 | let accum = 80 | accumulator::Accumulator::::empty(); 81 | let accum = accum.add( 82 | &LARGE_PRIMES 83 | .iter() 84 | .skip(1) 85 | .map(|p| Integer::from(*p)) 86 | .collect::>(), 87 | ); 88 | 89 | let accum = accum.add_with_proof(&[hashed_value.clone()]); 90 | let acc = accum.0.value; 91 | let w = accum.1.witness.0.value; 92 | assert_eq!(Rsa2048::exp(&w, &hashed_value), acc); 93 | 94 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 95 | let mut verifier_channel = TranscriptVerifierChannel::new(&protocol.crs, &proof_transcript); 96 | let statement = Statement { 97 | c_e_q: commitment, 98 | c_p: acc.clone(), 99 | }; 100 | protocol 101 | .prove( 102 | &mut verifier_channel, 103 | &mut rng1, 104 | &mut rng2, 105 | &statement, 106 | &Witness { 107 | e: value.clone(), 108 | r_q: randomness.clone(), 109 | w: w.clone(), 110 | }, 111 | ) 112 | .unwrap(); 113 | let proof = verifier_channel.proof().unwrap(); 114 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 115 | let mut prover_channel = 116 | TranscriptProverChannel::new(&protocol.crs, &verification_transcript, &proof); 117 | protocol.verify(&mut prover_channel, &statement).unwrap(); 118 | 119 | c.bench_function("membership_hash protocol proving", |b| { 120 | b.iter(|| { 121 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 122 | let mut verifier_channel = 123 | TranscriptVerifierChannel::new(&protocol.crs, &proof_transcript); 124 | let statement = Statement { 125 | c_e_q: commitment, 126 | c_p: acc.clone(), 127 | }; 128 | protocol 129 | .prove( 130 | &mut verifier_channel, 131 | &mut rng1, 132 | &mut rng2, 133 | &statement, 134 | &Witness { 135 | e: value.clone(), 136 | r_q: randomness.clone(), 137 | w: w.clone(), 138 | }, 139 | ) 140 | .unwrap(); 141 | }) 142 | }); 143 | 144 | c.bench_function("membership_hash protocol verification", |b| { 145 | b.iter(|| { 146 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 147 | let mut prover_channel = 148 | TranscriptProverChannel::new(&protocol.crs, &verification_transcript, &proof); 149 | protocol.verify(&mut prover_channel, &statement).unwrap(); 150 | }) 151 | }); 152 | } 153 | 154 | criterion_group!(benches, criterion_benchmark); 155 | criterion_main!(benches); 156 | -------------------------------------------------------------------------------- /benches/membership_prime.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::{snark_range::Protocol as HPProtocol, CRSSize}, 12 | membership::{ 13 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 14 | Protocol, Statement, Witness, 15 | }, 16 | }, 17 | }; 18 | use criterion::{criterion_group, criterion_main, Criterion}; 19 | use merlin::Transcript; 20 | use rand::thread_rng; 21 | use rug::rand::RandState; 22 | use rug::Integer; 23 | use std::cell::RefCell; 24 | 25 | const LARGE_PRIMES: [u64; 3] = [ 26 | 12_702_637_924_034_044_211, 27 | 378_373_571_372_703_133, 28 | 8_640_171_141_336_142_787, 29 | ]; 30 | 31 | pub fn criterion_benchmark(c: &mut Criterion) { 32 | let params = Parameters::from_curve::().unwrap().0; 33 | println!("params: {}", params); 34 | let mut rng1 = RandState::new(); 35 | rng1.seed(&Integer::from(13)); 36 | let mut rng2 = thread_rng(); 37 | 38 | let crs = cpsnarks_set::protocols::membership::Protocol::< 39 | Rsa2048, 40 | G1Projective, 41 | HPProtocol, 42 | >::setup(¶ms, &mut rng1, &mut rng2) 43 | .unwrap() 44 | .crs; 45 | println!( 46 | "crs size: {:?}", 47 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 48 | ); 49 | let protocol = Protocol::>::from_crs(&crs); 50 | 51 | let value = Integer::from(Integer::u_pow_u( 52 | 2, 53 | (crs.parameters.hash_to_prime_bits) as u32, 54 | )) - &Integer::from(245); 55 | let randomness = 56 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 57 | let commitment = protocol 58 | .crs 59 | .crs_modeq 60 | .pedersen_commitment_parameters 61 | .commit(&value, &randomness) 62 | .unwrap(); 63 | 64 | let accum = 65 | accumulator::Accumulator::::empty(); 66 | let accum = accum.add( 67 | &LARGE_PRIMES 68 | .iter() 69 | .skip(1) 70 | .map(|p| Integer::from(*p)) 71 | .collect::>(), 72 | ); 73 | 74 | let accum = accum.add_with_proof(&[value.clone()]); 75 | let acc = accum.0.value; 76 | let w = accum.1.witness.0.value; 77 | assert_eq!(Rsa2048::exp(&w, &value), acc); 78 | 79 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 80 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 81 | let statement = Statement { 82 | c_e_q: commitment, 83 | c_p: acc.clone(), 84 | }; 85 | protocol 86 | .prove( 87 | &mut verifier_channel, 88 | &mut rng1, 89 | &mut rng2, 90 | &statement, 91 | &Witness { 92 | e: value.clone(), 93 | r_q: randomness.clone(), 94 | w: w.clone(), 95 | }, 96 | ) 97 | .unwrap(); 98 | let proof = verifier_channel.proof().unwrap(); 99 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 100 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 101 | protocol.verify(&mut prover_channel, &statement).unwrap(); 102 | 103 | c.bench_function("membership_prime protocol proving", |b| { 104 | b.iter(|| { 105 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 106 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 107 | let statement = Statement { 108 | c_e_q: commitment, 109 | c_p: acc.clone(), 110 | }; 111 | protocol 112 | .prove( 113 | &mut verifier_channel, 114 | &mut rng1, 115 | &mut rng2, 116 | &statement, 117 | &Witness { 118 | e: value.clone(), 119 | r_q: randomness.clone(), 120 | w: w.clone(), 121 | }, 122 | ) 123 | .unwrap(); 124 | }) 125 | }); 126 | 127 | c.bench_function("membership_prime protocol verification", |b| { 128 | b.iter(|| { 129 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 130 | let mut prover_channel = 131 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 132 | 133 | let statement = Statement { 134 | c_e_q: commitment, 135 | c_p: acc.clone(), 136 | }; 137 | protocol.verify(&mut prover_channel, &statement).unwrap(); 138 | }) 139 | }); 140 | } 141 | 142 | criterion_group!(benches, criterion_benchmark); 143 | criterion_main!(benches); 144 | -------------------------------------------------------------------------------- /benches/membership_prime_60.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::{snark_range::Protocol as HPProtocol, CRSSize}, 12 | membership::{ 13 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 14 | Protocol, Statement, Witness, 15 | }, 16 | }, 17 | }; 18 | use criterion::{criterion_group, criterion_main, Criterion}; 19 | use merlin::Transcript; 20 | use rand::thread_rng; 21 | use rug::rand::RandState; 22 | use rug::Integer; 23 | use std::cell::RefCell; 24 | 25 | const LARGE_PRIMES: [u64; 3] = [ 26 | 12_702_637_924_034_044_211, 27 | 378_373_571_372_703_133, 28 | 8_640_171_141_336_142_787, 29 | ]; 30 | 31 | pub fn criterion_benchmark(c: &mut Criterion) { 32 | let params = Parameters::from_curve_and_small_prime_size::(50, 70) 33 | .unwrap() 34 | .0; 35 | println!("params: {}", params); 36 | let mut rng1 = RandState::new(); 37 | rng1.seed(&Integer::from(13)); 38 | let mut rng2 = thread_rng(); 39 | 40 | let crs = cpsnarks_set::protocols::membership::Protocol::< 41 | Rsa2048, 42 | G1Projective, 43 | HPProtocol, 44 | >::setup(¶ms, &mut rng1, &mut rng2) 45 | .unwrap() 46 | .crs; 47 | println!( 48 | "crs size: {:?}", 49 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 50 | ); 51 | let protocol = Protocol::>::from_crs(&crs); 52 | 53 | let value = Integer::from(Integer::u_pow_u( 54 | 2, 55 | (crs.parameters.hash_to_prime_bits) as u32, 56 | )) - &Integer::from(245); 57 | let randomness = 58 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 59 | let commitment = protocol 60 | .crs 61 | .crs_modeq 62 | .pedersen_commitment_parameters 63 | .commit(&value, &randomness) 64 | .unwrap(); 65 | 66 | let accum = 67 | accumulator::Accumulator::::empty(); 68 | let accum = accum.add( 69 | &LARGE_PRIMES 70 | .iter() 71 | .skip(1) 72 | .map(|p| Integer::from(*p)) 73 | .collect::>(), 74 | ); 75 | 76 | let accum = accum.add_with_proof(&[value.clone()]); 77 | let acc = accum.0.value; 78 | let w = accum.1.witness.0.value; 79 | assert_eq!(Rsa2048::exp(&w, &value), acc); 80 | 81 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 82 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 83 | let statement = Statement { 84 | c_e_q: commitment, 85 | c_p: acc.clone(), 86 | }; 87 | protocol 88 | .prove( 89 | &mut verifier_channel, 90 | &mut rng1, 91 | &mut rng2, 92 | &statement, 93 | &Witness { 94 | e: value.clone(), 95 | r_q: randomness.clone(), 96 | w: w.clone(), 97 | }, 98 | ) 99 | .unwrap(); 100 | let proof = verifier_channel.proof().unwrap(); 101 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 102 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 103 | protocol.verify(&mut prover_channel, &statement).unwrap(); 104 | 105 | c.bench_function("membership_prime_60 protocol proving", |b| { 106 | b.iter(|| { 107 | let proof_transcript = RefCell::new(Transcript::new(b"membership")); 108 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 109 | let statement = Statement { 110 | c_e_q: commitment, 111 | c_p: acc.clone(), 112 | }; 113 | protocol 114 | .prove( 115 | &mut verifier_channel, 116 | &mut rng1, 117 | &mut rng2, 118 | &statement, 119 | &Witness { 120 | e: value.clone(), 121 | r_q: randomness.clone(), 122 | w: w.clone(), 123 | }, 124 | ) 125 | .unwrap(); 126 | }) 127 | }); 128 | 129 | c.bench_function("membership_prime_60 protocol verification", |b| { 130 | b.iter(|| { 131 | let verification_transcript = RefCell::new(Transcript::new(b"membership")); 132 | let mut prover_channel = 133 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 134 | protocol.verify(&mut prover_channel, &statement).unwrap(); 135 | }) 136 | }); 137 | } 138 | 139 | criterion_group!(benches, criterion_benchmark); 140 | criterion_main!(benches); 141 | -------------------------------------------------------------------------------- /benches/modeq.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use algebra::bls12_381::{Bls12_381, G1Projective}; 3 | use cpsnarks_set::commitments::Commitment; 4 | use cpsnarks_set::{ 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::snark_range::Protocol as HPProtocol, 8 | modeq::{ 9 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 10 | Protocol, Statement, Witness, 11 | }, 12 | }, 13 | }; 14 | use criterion::{criterion_group, criterion_main, Criterion}; 15 | use merlin::Transcript; 16 | use rand::thread_rng; 17 | use rug::rand::RandState; 18 | use rug::Integer; 19 | use std::cell::RefCell; 20 | 21 | pub fn criterion_benchmark(c: &mut Criterion) { 22 | let params = Parameters::from_security_level(128).unwrap(); 23 | let mut rng1 = RandState::new(); 24 | rng1.seed(&Integer::from(13)); 25 | let mut rng2 = thread_rng(); 26 | 27 | let crs = cpsnarks_set::protocols::membership::Protocol::< 28 | Rsa2048, 29 | G1Projective, 30 | HPProtocol, 31 | >::setup(¶ms, &mut rng1, &mut rng2) 32 | .unwrap() 33 | .crs 34 | .crs_modeq; 35 | let protocol = Protocol::::from_crs(&crs); 36 | 37 | let value1 = Integer::from(2); 38 | let randomness1 = Integer::from(5); 39 | let randomness2 = Integer::from(9); 40 | let commitment1 = protocol 41 | .crs 42 | .integer_commitment_parameters 43 | .commit(&value1, &randomness1) 44 | .unwrap(); 45 | let commitment2 = protocol 46 | .crs 47 | .pedersen_commitment_parameters 48 | .commit(&value1, &randomness2) 49 | .unwrap(); 50 | 51 | let proof_transcript = RefCell::new(Transcript::new(b"modeq")); 52 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 53 | let statement = Statement { 54 | c_e: commitment1.clone(), 55 | c_e_q: commitment2, 56 | }; 57 | protocol 58 | .prove( 59 | &mut verifier_channel, 60 | &mut rng1, 61 | &mut rng2, 62 | &statement, 63 | &Witness { 64 | e: value1.clone(), 65 | r: randomness1.clone(), 66 | r_q: randomness2.clone(), 67 | }, 68 | ) 69 | .unwrap(); 70 | 71 | let verification_transcript = RefCell::new(Transcript::new(b"modeq")); 72 | let mut prover_channel = TranscriptProverChannel::new( 73 | &crs, 74 | &verification_transcript, 75 | &verifier_channel.proof().unwrap(), 76 | ); 77 | protocol.verify(&mut prover_channel, &statement).unwrap(); 78 | 79 | c.bench_function("modeq protocol", move |b| { 80 | b.iter(|| { 81 | let proof_transcript = RefCell::new(Transcript::new(b"modeq")); 82 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 83 | let statement = Statement { 84 | c_e: commitment1.clone(), 85 | c_e_q: commitment2, 86 | }; 87 | protocol 88 | .prove( 89 | &mut verifier_channel, 90 | &mut rng1, 91 | &mut rng2, 92 | &statement, 93 | &Witness { 94 | e: value1.clone(), 95 | r: randomness1.clone(), 96 | r_q: randomness2.clone(), 97 | }, 98 | ) 99 | .unwrap(); 100 | }) 101 | }); 102 | } 103 | 104 | criterion_group!(benches, criterion_benchmark); 105 | criterion_main!(benches); 106 | -------------------------------------------------------------------------------- /benches/nonmembership_bp.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use cpsnarks_set::{ 4 | commitments::Commitment, 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::{bp::Protocol as HPProtocol, CRSSize}, 8 | nonmembership::{ 9 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 10 | Protocol, Statement, Witness, 11 | }, 12 | }, 13 | }; 14 | use criterion::{criterion_group, criterion_main, Criterion}; 15 | use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; 16 | use merlin::Transcript; 17 | use rand::thread_rng; 18 | use rug::rand::RandState; 19 | use rug::Integer; 20 | use std::cell::RefCell; 21 | 22 | const LARGE_PRIMES: [u64; 3] = [ 23 | 12_702_637_924_034_044_211, 24 | 378_373_571_372_703_133, 25 | 8_640_171_141_336_142_787, 26 | ]; 27 | 28 | pub fn criterion_benchmark(c: &mut Criterion) { 29 | let params = Parameters::from_curve::().unwrap().0; 30 | println!("params: {}", params); 31 | let mut rng1 = RandState::new(); 32 | rng1.seed(&Integer::from(13)); 33 | let mut rng2 = thread_rng(); 34 | 35 | let mut crs = cpsnarks_set::protocols::nonmembership::Protocol::< 36 | Rsa2048, 37 | RistrettoPoint, 38 | HPProtocol, 39 | >::setup(¶ms, &mut rng1, &mut rng2) 40 | .unwrap() 41 | .crs; 42 | println!( 43 | "crs size: {:?}", 44 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 45 | ); 46 | let protocol = Protocol::::from_crs(&crs); 47 | 48 | let value = Integer::from(Integer::u_pow_u( 49 | 2, 50 | (crs.parameters.hash_to_prime_bits) as u32, 51 | )) - &Integer::from(129); 52 | let randomness = Integer::from(5); 53 | let commitment = protocol 54 | .crs 55 | .crs_modeq 56 | .pedersen_commitment_parameters 57 | .commit(&value, &randomness) 58 | .unwrap(); 59 | 60 | let accum = 61 | accumulator::Accumulator::::empty(); 62 | let acc_set = LARGE_PRIMES 63 | .iter() 64 | .skip(1) 65 | .map(|p| Integer::from(*p)) 66 | .collect::>(); 67 | let accum = accum.add(&acc_set); 68 | 69 | let non_mem_proof = accum 70 | .prove_nonmembership(&acc_set, &[value.clone()]) 71 | .unwrap(); 72 | 73 | let acc = accum.value; 74 | let d = non_mem_proof.d.clone(); 75 | let b = non_mem_proof.b; 76 | assert_eq!( 77 | Rsa2048::op(&Rsa2048::exp(&d, &value), &Rsa2048::exp(&acc, &b)), 78 | protocol.crs.crs_coprime.integer_commitment_parameters.g 79 | ); 80 | 81 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 82 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = Some(proof_transcript.clone()); 83 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 84 | let statement = Statement { 85 | c_e_q: commitment, 86 | c_p: acc.clone(), 87 | }; 88 | protocol 89 | .prove( 90 | &mut verifier_channel, 91 | &mut rng1, 92 | &mut rng2, 93 | &statement, 94 | &Witness { 95 | e: value.clone(), 96 | r_q: randomness.clone(), 97 | d: d.clone(), 98 | b: b.clone(), 99 | }, 100 | ) 101 | .unwrap(); 102 | let proof = verifier_channel.proof().unwrap(); 103 | println!( 104 | "proof size: {}", 105 | proof.proof_hash_to_prime.serialized_size() 106 | ); 107 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 108 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 109 | Some(verification_transcript.clone()); 110 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 111 | protocol.verify(&mut prover_channel, &statement).unwrap(); 112 | 113 | c.bench_function("nonmembership_bp protocol proving", |be| { 114 | be.iter(|| { 115 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 116 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 117 | Some(proof_transcript.clone()); 118 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 119 | let statement = Statement { 120 | c_e_q: commitment, 121 | c_p: acc.clone(), 122 | }; 123 | protocol 124 | .prove( 125 | &mut verifier_channel, 126 | &mut rng1, 127 | &mut rng2, 128 | &statement, 129 | &Witness { 130 | e: value.clone(), 131 | r_q: randomness.clone(), 132 | d: d.clone(), 133 | b: b.clone(), 134 | }, 135 | ) 136 | .unwrap(); 137 | }) 138 | }); 139 | c.bench_function("nonmembership_bp protocol verification", |be| { 140 | be.iter(|| { 141 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 142 | crs.crs_hash_to_prime.hash_to_prime_parameters.transcript = 143 | Some(verification_transcript.clone()); 144 | let mut prover_channel = 145 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 146 | protocol.verify(&mut prover_channel, &statement).unwrap(); 147 | }) 148 | }); 149 | } 150 | 151 | criterion_group!(benches, criterion_benchmark); 152 | criterion_main!(benches); 153 | -------------------------------------------------------------------------------- /benches/nonmembership_hash.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::{ 12 | snark_hash::{HashToPrimeHashParameters, Protocol as HPProtocol}, 13 | CRSSize, 14 | }, 15 | nonmembership::{ 16 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 17 | Protocol, Statement, Witness, 18 | }, 19 | }, 20 | }; 21 | use criterion::{criterion_group, criterion_main, Criterion}; 22 | use merlin::Transcript; 23 | use rand::thread_rng; 24 | use rug::rand::RandState; 25 | use rug::Integer; 26 | use std::cell::RefCell; 27 | 28 | const LARGE_PRIMES: [u64; 3] = [ 29 | 12_702_637_924_034_044_211, 30 | 378_373_571_372_703_133, 31 | 8_640_171_141_336_142_787, 32 | ]; 33 | 34 | struct TestHashToPrimeParameters {} 35 | impl HashToPrimeHashParameters for TestHashToPrimeParameters { 36 | const MESSAGE_SIZE: u16 = 254; 37 | } 38 | 39 | pub fn criterion_benchmark(c: &mut Criterion) { 40 | let params = Parameters::from_curve::().unwrap().0; 41 | println!("params: {}", params); 42 | let mut rng1 = RandState::new(); 43 | rng1.seed(&Integer::from(13)); 44 | let mut rng2 = thread_rng(); 45 | 46 | let crs = cpsnarks_set::protocols::nonmembership::Protocol::< 47 | Rsa2048, 48 | G1Projective, 49 | HPProtocol, 50 | >::setup(¶ms, &mut rng1, &mut rng2) 51 | .unwrap() 52 | .crs; 53 | println!( 54 | "crs size: {:?}", 55 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 56 | ); 57 | let protocol = Protocol::< 58 | Rsa2048, 59 | G1Projective, 60 | HPProtocol, 61 | >::from_crs(&crs); 62 | 63 | let value = Integer::from(Integer::u_pow_u( 64 | 2, 65 | (crs.parameters.hash_to_prime_bits) as u32, 66 | )) 67 | .random_below(&mut rng1); 68 | let (hashed_value, _) = protocol.hash_to_prime(&value).unwrap(); 69 | let randomness = 70 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 71 | let commitment = protocol 72 | .crs 73 | .crs_modeq 74 | .pedersen_commitment_parameters 75 | .commit(&hashed_value, &randomness) 76 | .unwrap(); 77 | 78 | let accum = 79 | accumulator::Accumulator::::empty(); 80 | let acc_set = LARGE_PRIMES 81 | .iter() 82 | .skip(1) 83 | .map(|p| Integer::from(*p)) 84 | .collect::>(); 85 | let accum = accum.add(&acc_set); 86 | 87 | let non_mem_proof = accum 88 | .prove_nonmembership(&acc_set, &[hashed_value.clone()]) 89 | .unwrap(); 90 | 91 | let acc = accum.value; 92 | let d = non_mem_proof.d.clone(); 93 | let b = non_mem_proof.b; 94 | assert_eq!( 95 | Rsa2048::op(&Rsa2048::exp(&d, &hashed_value), &Rsa2048::exp(&acc, &b)), 96 | protocol.crs.crs_coprime.integer_commitment_parameters.g 97 | ); 98 | 99 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 100 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 101 | let statement = Statement { 102 | c_e_q: commitment, 103 | c_p: acc.clone(), 104 | }; 105 | protocol 106 | .prove( 107 | &mut verifier_channel, 108 | &mut rng1, 109 | &mut rng2, 110 | &statement, 111 | &Witness { 112 | e: value.clone(), 113 | r_q: randomness.clone(), 114 | d: d.clone(), 115 | b: b.clone(), 116 | }, 117 | ) 118 | .unwrap(); 119 | let proof = verifier_channel.proof().unwrap(); 120 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 121 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 122 | protocol.verify(&mut prover_channel, &statement).unwrap(); 123 | 124 | c.bench_function("nonmembership_hash protocol proving", |be| { 125 | be.iter(|| { 126 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 127 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 128 | let statement = Statement { 129 | c_e_q: commitment, 130 | c_p: acc.clone(), 131 | }; 132 | protocol 133 | .prove( 134 | &mut verifier_channel, 135 | &mut rng1, 136 | &mut rng2, 137 | &statement, 138 | &Witness { 139 | e: value.clone(), 140 | r_q: randomness.clone(), 141 | d: d.clone(), 142 | b: b.clone(), 143 | }, 144 | ) 145 | .unwrap(); 146 | }) 147 | }); 148 | c.bench_function("nonmembership_hash protocol verification", |be| { 149 | be.iter(|| { 150 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 151 | let mut prover_channel = 152 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 153 | protocol.verify(&mut prover_channel, &statement).unwrap(); 154 | }) 155 | }); 156 | } 157 | 158 | criterion_group!(benches, criterion_benchmark); 159 | criterion_main!(benches); 160 | -------------------------------------------------------------------------------- /benches/nonmembership_prime.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use accumulator::{group::Group, AccumulatorWithoutHashToPrime}; 3 | use algebra::{ 4 | bls12_381::{Bls12_381, Fr, G1Projective}, 5 | PrimeField, 6 | }; 7 | use cpsnarks_set::{ 8 | commitments::Commitment, 9 | parameters::Parameters, 10 | protocols::{ 11 | hash_to_prime::{snark_range::Protocol as HPProtocol, CRSSize}, 12 | nonmembership::{ 13 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 14 | Protocol, Statement, Witness, 15 | }, 16 | }, 17 | }; 18 | use criterion::{criterion_group, criterion_main, Criterion}; 19 | use merlin::Transcript; 20 | use rand::thread_rng; 21 | use rug::rand::RandState; 22 | use rug::Integer; 23 | use std::cell::RefCell; 24 | 25 | const LARGE_PRIMES: [u64; 3] = [ 26 | 12_702_637_924_034_044_211, 27 | 378_373_571_372_703_133, 28 | 8_640_171_141_336_142_787, 29 | ]; 30 | 31 | pub fn criterion_benchmark(c: &mut Criterion) { 32 | let params = Parameters::from_curve::().unwrap().0; 33 | println!("params: {}", params); 34 | let mut rng1 = RandState::new(); 35 | rng1.seed(&Integer::from(13)); 36 | let mut rng2 = thread_rng(); 37 | 38 | let crs = cpsnarks_set::protocols::nonmembership::Protocol::< 39 | Rsa2048, 40 | G1Projective, 41 | HPProtocol, 42 | >::setup(¶ms, &mut rng1, &mut rng2) 43 | .unwrap() 44 | .crs; 45 | println!( 46 | "crs size: {:?}", 47 | crs.crs_hash_to_prime.hash_to_prime_parameters.crs_size() 48 | ); 49 | let protocol = Protocol::>::from_crs(&crs); 50 | 51 | let value = Integer::from(Integer::u_pow_u( 52 | 2, 53 | (crs.parameters.hash_to_prime_bits) as u32, 54 | )) - &Integer::from(245); 55 | let randomness = 56 | Integer::from(Integer::u_pow_u(2, Fr::size_in_bits() as u32)).random_below(&mut rng1); 57 | let commitment = protocol 58 | .crs 59 | .crs_modeq 60 | .pedersen_commitment_parameters 61 | .commit(&value, &randomness) 62 | .unwrap(); 63 | 64 | let accum = 65 | accumulator::Accumulator::::empty(); 66 | let acc_set = LARGE_PRIMES 67 | .iter() 68 | .skip(1) 69 | .map(|p| Integer::from(*p)) 70 | .collect::>(); 71 | let accum = accum.add(&acc_set); 72 | 73 | let non_mem_proof = accum 74 | .prove_nonmembership(&acc_set, &[value.clone()]) 75 | .unwrap(); 76 | 77 | let acc = accum.value; 78 | let d = non_mem_proof.d.clone(); 79 | let b = non_mem_proof.b; 80 | assert_eq!( 81 | Rsa2048::op(&Rsa2048::exp(&d, &value), &Rsa2048::exp(&acc, &b)), 82 | protocol.crs.crs_coprime.integer_commitment_parameters.g 83 | ); 84 | 85 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 86 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 87 | let statement = Statement { 88 | c_e_q: commitment, 89 | c_p: acc.clone(), 90 | }; 91 | protocol 92 | .prove( 93 | &mut verifier_channel, 94 | &mut rng1, 95 | &mut rng2, 96 | &statement, 97 | &Witness { 98 | e: value.clone(), 99 | r_q: randomness.clone(), 100 | d: d.clone(), 101 | b: b.clone(), 102 | }, 103 | ) 104 | .unwrap(); 105 | let proof = verifier_channel.proof().unwrap(); 106 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 107 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 108 | protocol.verify(&mut prover_channel, &statement).unwrap(); 109 | 110 | c.bench_function("nonmembership_prime protocol proving", |be| { 111 | be.iter(|| { 112 | let proof_transcript = RefCell::new(Transcript::new(b"nonmembership")); 113 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 114 | let statement = Statement { 115 | c_e_q: commitment, 116 | c_p: acc.clone(), 117 | }; 118 | protocol 119 | .prove( 120 | &mut verifier_channel, 121 | &mut rng1, 122 | &mut rng2, 123 | &statement, 124 | &Witness { 125 | e: value.clone(), 126 | r_q: randomness.clone(), 127 | d: d.clone(), 128 | b: b.clone(), 129 | }, 130 | ) 131 | .unwrap(); 132 | }) 133 | }); 134 | c.bench_function("nonmembership_prime protocol verification", |be| { 135 | be.iter(|| { 136 | let verification_transcript = RefCell::new(Transcript::new(b"nonmembership")); 137 | let mut prover_channel = 138 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 139 | protocol.verify(&mut prover_channel, &statement).unwrap(); 140 | }) 141 | }); 142 | } 143 | 144 | criterion_group!(benches, criterion_benchmark); 145 | criterion_main!(benches); 146 | -------------------------------------------------------------------------------- /benches/root.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::{Group, Rsa2048}; 2 | use accumulator::AccumulatorWithoutHashToPrime; 3 | use algebra::bls12_381::{Bls12_381, G1Projective}; 4 | use cpsnarks_set::commitments::Commitment; 5 | use cpsnarks_set::{ 6 | parameters::Parameters, 7 | protocols::{ 8 | hash_to_prime::snark_range::Protocol as HPProtocol, 9 | root::{ 10 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 11 | Protocol, Statement, Witness, 12 | }, 13 | }, 14 | }; 15 | use criterion::{criterion_group, criterion_main, Criterion}; 16 | use merlin::Transcript; 17 | use rand::thread_rng; 18 | use rug::rand::RandState; 19 | use rug::Integer; 20 | use std::cell::RefCell; 21 | 22 | const LARGE_PRIMES: [u64; 3] = [ 23 | 12_702_637_924_034_044_211, 24 | 378_373_571_372_703_133, 25 | 8_640_171_141_336_142_787, 26 | ]; 27 | 28 | pub fn criterion_benchmark(c: &mut Criterion) { 29 | let params = Parameters::from_security_level(128).unwrap(); 30 | let mut rng1 = RandState::new(); 31 | rng1.seed(&Integer::from(13)); 32 | let mut rng2 = thread_rng(); 33 | 34 | let crs = cpsnarks_set::protocols::membership::Protocol::< 35 | Rsa2048, 36 | G1Projective, 37 | HPProtocol, 38 | >::setup(¶ms, &mut rng1, &mut rng2) 39 | .unwrap() 40 | .crs 41 | .crs_root; 42 | let protocol = Protocol::::from_crs(&crs); 43 | 44 | // prime from https://primes.utm.edu/lists/2small/200bit.html 45 | let value = (Integer::from(1) << 256) - 189; 46 | let randomness = Integer::from(5); 47 | let commitment = protocol 48 | .crs 49 | .integer_commitment_parameters 50 | .commit(&value, &randomness) 51 | .unwrap(); 52 | 53 | let accum = 54 | accumulator::Accumulator::::empty(); 55 | let accum = accum.add( 56 | &LARGE_PRIMES 57 | .iter() 58 | .map(|p| Integer::from(*p)) 59 | .collect::>(), 60 | ); 61 | 62 | let accum = accum.add_with_proof(&[value.clone()]); 63 | let acc = accum.0.value; 64 | let w = accum.1.witness.0.value; 65 | assert_eq!(Rsa2048::exp(&w, &value), acc); 66 | 67 | let proof_transcript = RefCell::new(Transcript::new(b"root")); 68 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 69 | let statement = Statement { 70 | c_e: commitment.clone(), 71 | acc: acc.clone(), 72 | }; 73 | protocol 74 | .prove( 75 | &mut verifier_channel, 76 | &mut rng1, 77 | &statement, 78 | &Witness { 79 | e: value.clone(), 80 | r: randomness.clone(), 81 | w: w.clone(), 82 | }, 83 | ) 84 | .unwrap(); 85 | 86 | let verification_transcript = RefCell::new(Transcript::new(b"root")); 87 | let mut prover_channel = TranscriptProverChannel::new( 88 | &crs, 89 | &verification_transcript, 90 | &verifier_channel.proof().unwrap(), 91 | ); 92 | protocol.verify(&mut prover_channel, &statement).unwrap(); 93 | 94 | c.bench_function("root protocol", move |b| { 95 | b.iter(|| { 96 | let proof_transcript = RefCell::new(Transcript::new(b"root")); 97 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 98 | let statement = Statement { 99 | c_e: commitment.clone(), 100 | acc: acc.clone(), 101 | }; 102 | protocol 103 | .prove( 104 | &mut verifier_channel, 105 | &mut rng1, 106 | &statement, 107 | &Witness { 108 | e: value.clone(), 109 | r: randomness.clone(), 110 | w: w.clone(), 111 | }, 112 | ) 113 | .unwrap(); 114 | }) 115 | }); 116 | } 117 | 118 | criterion_group!(benches, criterion_benchmark); 119 | criterion_main!(benches); 120 | -------------------------------------------------------------------------------- /benches/rsa.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::{ElemFrom, Group, Rsa2048, UnknownOrderGroup}; 2 | use cpsnarks_set::parameters::Parameters; 3 | use rug::rand::RandState; 4 | use rug::Integer; 5 | 6 | use cpsnarks_set::utils::{random_between, random_symmetric_range}; 7 | use criterion::{criterion_group, criterion_main, Criterion}; 8 | 9 | pub fn criterion_benchmark(c: &mut Criterion) { 10 | let params = Parameters::from_security_level(128).unwrap(); 11 | let mut rng1 = RandState::new(); 12 | rng1.seed(&Integer::from(13)); 13 | 14 | c.bench_function("RSA exponentiation", move |b| { 15 | b.iter(|| { 16 | let e = Rsa2048::elem(&random_between( 17 | &mut rng1, 18 | &Integer::from(0), 19 | &Rsa2048::order_upper_bound(), 20 | )); 21 | let r_range: Integer = Rsa2048::order_upper_bound() / 2 22 | * Integer::from(Integer::u_pow_u( 23 | 2, 24 | (params.security_zk + params.security_soundness) as u32, 25 | )); 26 | let r = random_symmetric_range(&mut rng1, &r_range); 27 | Rsa2048::exp(&e, &r); 28 | }) 29 | }); 30 | } 31 | 32 | criterion_group!(benches, criterion_benchmark); 33 | criterion_main!(benches); 34 | -------------------------------------------------------------------------------- /benches/snark_range.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::Rsa2048; 2 | use algebra::bls12_381::{Bls12_381, G1Projective}; 3 | use cpsnarks_set::commitments::Commitment; 4 | use cpsnarks_set::{ 5 | parameters::Parameters, 6 | protocols::hash_to_prime::{ 7 | snark_range::Protocol, 8 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 9 | HashToPrimeProtocol, Statement, Witness, 10 | }, 11 | }; 12 | use criterion::{criterion_group, criterion_main, Criterion}; 13 | use merlin::Transcript; 14 | use rand::thread_rng; 15 | use rug::rand::RandState; 16 | use rug::Integer; 17 | use std::cell::RefCell; 18 | 19 | pub fn criterion_benchmark(c: &mut Criterion) { 20 | let params = Parameters::from_security_level(128).unwrap(); 21 | let mut rng1 = RandState::new(); 22 | rng1.seed(&Integer::from(13)); 23 | let mut rng2 = thread_rng(); 24 | 25 | let crs = cpsnarks_set::protocols::membership::Protocol::< 26 | Rsa2048, 27 | G1Projective, 28 | Protocol, 29 | >::setup(¶ms, &mut rng1, &mut rng2) 30 | .unwrap() 31 | .crs 32 | .crs_hash_to_prime; 33 | let protocol = Protocol::::from_crs(&crs); 34 | 35 | let value = Integer::from(Integer::u_pow_u( 36 | 2, 37 | (crs.parameters.hash_to_prime_bits) as u32, 38 | )) - &Integer::from(245); 39 | let randomness = Integer::from(9); 40 | let commitment = protocol 41 | .crs 42 | .pedersen_commitment_parameters 43 | .commit(&value, &randomness) 44 | .unwrap(); 45 | 46 | let proof_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 47 | let statement = Statement { c_e_q: commitment }; 48 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 49 | protocol 50 | .prove( 51 | &mut verifier_channel, 52 | &mut rng2, 53 | &statement, 54 | &Witness { 55 | e: value.clone(), 56 | r_q: randomness.clone(), 57 | }, 58 | ) 59 | .unwrap(); 60 | 61 | let proof = verifier_channel.proof().unwrap(); 62 | 63 | let verification_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 64 | let mut prover_channel = TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 65 | protocol.verify(&mut prover_channel, &statement).unwrap(); 66 | 67 | c.bench_function("snark_range protocol", move |b| { 68 | b.iter(|| { 69 | let proof_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 70 | let statement = Statement { c_e_q: commitment }; 71 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 72 | protocol 73 | .prove( 74 | &mut verifier_channel, 75 | &mut rng2, 76 | &statement, 77 | &Witness { 78 | e: value.clone(), 79 | r_q: randomness.clone(), 80 | }, 81 | ) 82 | .unwrap(); 83 | }) 84 | }); 85 | } 86 | 87 | criterion_group!(benches, criterion_benchmark); 88 | criterion_main!(benches); 89 | -------------------------------------------------------------------------------- /src/channels.rs: -------------------------------------------------------------------------------- 1 | //! Channels provide a way for protocol to act as interactive protocol. 2 | //! 3 | //! Each protocol defines the messages the prover and verifiers send, such that 4 | //! the prover receives a verifier channel and the prover receives a verifier 5 | //! channel. 6 | use crate::utils::curve::CurveError; 7 | use std::cell::{BorrowError, BorrowMutError}; 8 | 9 | quick_error! { 10 | #[derive(Debug)] 11 | pub enum ChannelError { 12 | CouldNotSend {} 13 | CouldNotBorrow(e: BorrowError) { 14 | from() 15 | } 16 | CouldNotBorrowMut(e: BorrowMutError) { 17 | from() 18 | } 19 | CurveError(e: CurveError) { 20 | from() 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/commitments/integer.rs: -------------------------------------------------------------------------------- 1 | //! Integer commitment over groups of unknown order. 2 | 3 | use crate::{ 4 | commitments::{Commitment, CommitmentError}, 5 | utils::ConvertibleUnknownOrderGroup, 6 | }; 7 | use rug::rand::MutRandState; 8 | use rug::Integer; 9 | 10 | #[derive(Clone)] 11 | pub struct IntegerCommitment { 12 | pub g: G::Elem, 13 | pub h: G::Elem, 14 | } 15 | 16 | impl IntegerCommitment { 17 | pub fn setup(rng: &mut R) -> IntegerCommitment { 18 | let upper_bound = G::order_upper_bound(); 19 | let g = G::unknown_order_elem(); 20 | let h = G::exp(&g, &upper_bound.random_below(rng)); 21 | IntegerCommitment { g, h } 22 | } 23 | 24 | pub fn new(g: &G::Elem, h: &G::Elem) -> IntegerCommitment { 25 | IntegerCommitment { 26 | g: g.clone(), 27 | h: h.clone(), 28 | } 29 | } 30 | } 31 | 32 | impl Commitment for IntegerCommitment { 33 | type Instance = G::Elem; 34 | 35 | fn commit( 36 | &self, 37 | value: &Integer, 38 | randomness: &Integer, 39 | ) -> Result { 40 | Ok(G::op(&G::exp(&self.g, value), &G::exp(&self.h, randomness))) 41 | } 42 | 43 | fn open( 44 | &self, 45 | commitment: &Self::Instance, 46 | value: &Integer, 47 | randomness: &Integer, 48 | ) -> Result<(), CommitmentError> { 49 | let expected = G::op(&G::exp(&self.g, value), &G::exp(&self.h, randomness)); 50 | if expected == *commitment { 51 | Ok(()) 52 | } else { 53 | Err(CommitmentError::WrongOpening) 54 | } 55 | } 56 | } 57 | 58 | #[cfg(test)] 59 | mod test { 60 | use super::IntegerCommitment; 61 | use crate::commitments::Commitment; 62 | use accumulator::group::Rsa2048; 63 | use rug::rand::RandState; 64 | use rug::Integer; 65 | 66 | #[test] 67 | fn test_simple_commitment() { 68 | let mut rng = RandState::new(); 69 | rng.seed(&Integer::from(13)); 70 | 71 | let value = Integer::from(2); 72 | let randomness = Integer::from(5); 73 | let integer = IntegerCommitment::::setup(&mut rng); 74 | let commitment = integer.commit(&value, &randomness).unwrap(); 75 | integer.open(&commitment, &value, &randomness).unwrap(); 76 | let wrong_value = Integer::from(5); 77 | integer 78 | .open(&commitment, &wrong_value, &randomness) 79 | .unwrap_err(); 80 | let wrong_randomness = Integer::from(7); 81 | integer 82 | .open(&commitment, &value, &wrong_randomness) 83 | .unwrap_err(); 84 | integer 85 | .open(&commitment, &wrong_value, &wrong_randomness) 86 | .unwrap_err(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/commitments/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements integer and Pedersen commitments. 2 | 3 | use rug::Integer; 4 | 5 | pub mod integer; 6 | pub mod pedersen; 7 | 8 | quick_error! { 9 | #[derive(Debug)] 10 | pub enum CommitmentError { 11 | WrongOpening {} 12 | IntegerTooBig {} 13 | ConversionError(err: std::io::Error) { 14 | from() 15 | } 16 | } 17 | } 18 | 19 | pub trait Commitment { 20 | type Instance; 21 | 22 | fn commit( 23 | &self, 24 | value: &Integer, 25 | randomness: &Integer, 26 | ) -> Result; 27 | fn open( 28 | &self, 29 | commitment: &Self::Instance, 30 | value: &Integer, 31 | randomness: &Integer, 32 | ) -> Result<(), CommitmentError>; 33 | } 34 | -------------------------------------------------------------------------------- /src/commitments/pedersen.rs: -------------------------------------------------------------------------------- 1 | //! Pedersen commitment over elliptic curves. 2 | 3 | use crate::commitments::{Commitment, CommitmentError}; 4 | use crate::utils::{curve::CurvePointProjective, integer_to_bigint}; 5 | use rand::{CryptoRng, RngCore}; 6 | use rug::Integer; 7 | 8 | #[derive(Clone)] 9 | pub struct PedersenCommitment { 10 | pub g: P, 11 | pub h: P, 12 | } 13 | 14 | impl PedersenCommitment

{ 15 | pub fn setup(rng: &mut R) -> PedersenCommitment

{ 16 | PedersenCommitment { 17 | g: P::rand(rng), 18 | h: P::rand(rng), 19 | } 20 | } 21 | 22 | pub fn new(g: &P, h: &P) -> PedersenCommitment

{ 23 | PedersenCommitment { 24 | g: g.clone(), 25 | h: h.clone(), 26 | } 27 | } 28 | } 29 | impl Commitment for PedersenCommitment

{ 30 | type Instance = P; 31 | 32 | fn commit( 33 | &self, 34 | value: &Integer, 35 | randomness: &Integer, 36 | ) -> Result { 37 | let v = integer_to_bigint::

(value); 38 | let r = integer_to_bigint::

(randomness); 39 | Ok(self.g.mul(&v).add(&self.h.mul(&r))) 40 | } 41 | 42 | fn open( 43 | &self, 44 | commitment: &Self::Instance, 45 | value: &Integer, 46 | randomness: &Integer, 47 | ) -> Result<(), CommitmentError> { 48 | let expected = self 49 | .g 50 | .mul(&integer_to_bigint::

(value)) 51 | .add(&self.h.mul(&integer_to_bigint::

(randomness))); 52 | if expected == *commitment { 53 | Ok(()) 54 | } else { 55 | Err(CommitmentError::WrongOpening) 56 | } 57 | } 58 | } 59 | 60 | #[cfg(all(test, feature = "arkworks"))] 61 | mod test { 62 | use super::PedersenCommitment; 63 | use crate::commitments::Commitment; 64 | use ark_bls12_381::G1Projective; 65 | use rand::thread_rng; 66 | use rug::Integer; 67 | 68 | #[test] 69 | fn test_simple_commitment() { 70 | let mut rng = thread_rng(); 71 | 72 | let value = Integer::from(2); 73 | let randomness = Integer::from(5); 74 | let pedersen = PedersenCommitment::::setup(&mut rng); 75 | let commitment = pedersen.commit(&value, &randomness).unwrap(); 76 | pedersen.open(&commitment, &value, &randomness).unwrap(); 77 | let wrong_value = Integer::from(5); 78 | pedersen 79 | .open(&commitment, &wrong_value, &randomness) 80 | .unwrap_err(); 81 | let wrong_randomness = Integer::from(7); 82 | pedersen 83 | .open(&commitment, &value, &wrong_randomness) 84 | .unwrap_err(); 85 | pedersen 86 | .open(&commitment, &wrong_value, &wrong_randomness) 87 | .unwrap_err(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This library implements the protocols from [Zero-Knowledge Proofs for Set 2 | //! Membership: Efficient, Succinct, 3 | //! Modular](https://eprint.iacr.org/2019/1255). 4 | //! 5 | //! `CPMemRSA`, `CPMemRSAPrm`, `CPNonMemRSA`, `CPNonMemRSAPrm`, with RSA and 6 | //! class groups available as groups of unknown order to be used for the root 7 | //! protocol, RSA available for the coprime protocol and LegoGroth16 and 8 | //! Bulletproofs available for the hash-to-prime and range proof protocols. The 9 | //! hash-to-prime uses Blake2s. 10 | //! 11 | //! The library is designed in a modular fashion - each subprotocol (root, 12 | //! coprime, modeq and hash_to_prime) implements generic prove and verify 13 | //! functions, a channel for the interactive proof abstraction and a transcript 14 | //! for the non-interactive proof instantiation. The hash-to-prime protocols 15 | //! also define a setup function. 16 | //! 17 | //! The higher level protocols (membership, nonmembership) define setup, prove 18 | //! and verify functions and compose the subprotocols into end-to-end protocols 19 | //! ready to use. 20 | 21 | #[macro_use] 22 | extern crate quick_error; 23 | 24 | pub mod channels; 25 | pub mod commitments; 26 | pub mod parameters; 27 | pub mod protocols; 28 | pub mod transcript; 29 | pub mod utils; 30 | -------------------------------------------------------------------------------- /src/parameters.rs: -------------------------------------------------------------------------------- 1 | //! Derives secure parameters given a desired security level or curve parameters. 2 | 3 | use crate::utils::curve::Field; 4 | use std::fmt; 5 | #[derive(Clone, Debug)] 6 | pub struct Parameters { 7 | /// Desired security level. It's an upper bound rather than the final 8 | /// security level. 9 | pub security_level: u16, 10 | /// Zero-knowledge security. 11 | pub security_zk: u16, 12 | /// Soundness security. 13 | pub security_soundness: u16, 14 | /// Size of the elements in the set, as a result of the hash-to-prime or 15 | /// just size in case of prime elements. 16 | pub hash_to_prime_bits: u16, // μ 17 | /// Size of the field the element are taken from. 18 | pub field_size_bits: u16, // ν 19 | } 20 | 21 | impl fmt::Display for Parameters { 22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 23 | write!(f, "Parameters(𝜆={} (security level), 𝜆_s={} (soundness security), 𝜆_z={} (zero-knowledge security), μ={} (hash-to-prime/range bits), ν={} (field size bits)", 24 | self.security_level, 25 | self.security_zk, 26 | self.security_soundness, 27 | self.hash_to_prime_bits, 28 | self.field_size_bits, 29 | ) 30 | } 31 | } 32 | 33 | quick_error! { 34 | #[derive(Debug)] 35 | pub enum ParametersError { 36 | InvalidParameters {} 37 | } 38 | } 39 | 40 | impl Parameters { 41 | /// Derive parameters for a desired security level. 42 | pub fn from_security_level(security_level: u16) -> Result { 43 | let parameters = Parameters { 44 | security_level, 45 | security_zk: security_level - 3, 46 | security_soundness: security_level - 2, 47 | field_size_bits: 2 * security_level, 48 | hash_to_prime_bits: 2 * security_level - 2, 49 | }; 50 | 51 | parameters.is_valid()?; 52 | Ok(parameters) 53 | } 54 | 55 | /// Derive parameters based on a curve. 56 | pub fn from_curve() -> Result<(Parameters, u16), ParametersError> { 57 | let field_size_bits = P::size_in_bits() as u16; 58 | let security_level = field_size_bits / 2; 59 | let parameters = Parameters { 60 | security_level, 61 | security_zk: security_level - 3, 62 | security_soundness: security_level - 2, 63 | field_size_bits, 64 | hash_to_prime_bits: 2 * security_level - 2, 65 | }; 66 | 67 | parameters.is_valid()?; 68 | Ok((parameters, security_level)) 69 | } 70 | 71 | /// Derive parameters based on a curve and desired small prime bit size. 72 | /// Based on section 4.5 of the paper. 73 | pub fn from_curve_and_small_prime_size( 74 | prime_bits_min: u16, 75 | prime_bits_max: u16, 76 | ) -> Result<(Parameters, u16), ParametersError> { 77 | let field_size_bits = P::size_in_bits() as u16; 78 | let security_level = field_size_bits / 2; 79 | let derived = (|| { 80 | for c in 0..security_level { 81 | let security_soundness_zk = ((2 * security_level - 2 - c) - 2) / 2; 82 | for i in prime_bits_min..=prime_bits_max { 83 | if i <= 2 * security_level - 2 - c && (2 * security_level - 2 - c) % i >= i - c 84 | { 85 | return Some((i, security_soundness_zk)); 86 | } 87 | } 88 | } 89 | 90 | None 91 | })(); 92 | let (prime_bits, security_soundness_zk) = 93 | derived.ok_or(ParametersError::InvalidParameters)?; 94 | 95 | let parameters = Parameters { 96 | security_level, 97 | security_zk: security_soundness_zk, 98 | security_soundness: security_soundness_zk, 99 | field_size_bits, 100 | hash_to_prime_bits: prime_bits, 101 | }; 102 | 103 | parameters.is_valid()?; 104 | Ok((parameters, security_level)) 105 | } 106 | 107 | /// Check the parameters are valid according to section 4.5 of 108 | /// the paper. 109 | pub fn is_valid(&self) -> Result<(), ParametersError> { 110 | let d = 1 + (self.security_zk + self.security_soundness + 2) / self.hash_to_prime_bits; 111 | if d * self.hash_to_prime_bits + 2 <= self.field_size_bits { 112 | Ok(()) 113 | } else { 114 | Err(ParametersError::InvalidParameters) 115 | } 116 | } 117 | } 118 | 119 | #[cfg(test)] 120 | mod test { 121 | use super::Parameters; 122 | 123 | #[test] 124 | fn test_valid_for_128() { 125 | let params = Parameters::from_security_level(128).unwrap(); 126 | params.is_valid().unwrap(); 127 | } 128 | 129 | #[cfg(all(test, feature = "arkworks"))] 130 | #[test] 131 | fn test_valid_for_some_fields() { 132 | let params_with_security_level = Parameters::from_curve::().unwrap(); 133 | println!( 134 | "security level: {}, params: {:#?}", 135 | params_with_security_level.1, params_with_security_level.0 136 | ); 137 | params_with_security_level.0.is_valid().unwrap(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/protocols/coprime/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::coprime::{Message1, Message2, Message3}, 4 | utils::ConvertibleUnknownOrderGroup, 5 | }; 6 | use rug::Integer; 7 | 8 | pub trait CoprimeVerifierChannel { 9 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError>; 10 | fn send_message2(&mut self, message: &Message2) -> Result<(), ChannelError>; 11 | fn send_message3(&mut self, message: &Message3) -> Result<(), ChannelError>; 12 | fn receive_challenge(&mut self) -> Result; 13 | } 14 | 15 | pub trait CoprimeProverChannel { 16 | fn receive_message1(&mut self) -> Result, ChannelError>; 17 | fn receive_message2(&mut self) -> Result, ChannelError>; 18 | fn receive_message3(&mut self) -> Result; 19 | fn generate_and_send_challenge(&mut self) -> Result; 20 | } 21 | -------------------------------------------------------------------------------- /src/protocols/coprime/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::coprime::{ 4 | channel::{CoprimeProverChannel, CoprimeVerifierChannel}, 5 | CRSCoprime, Message1, Message2, Message3, Proof, 6 | }, 7 | transcript::{TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolInteger}, 8 | utils::ConvertibleUnknownOrderGroup, 9 | }; 10 | use merlin::Transcript; 11 | use rug::Integer; 12 | use std::cell::RefCell; 13 | 14 | pub trait TranscriptProtocolCoprime: 15 | TranscriptProtocolInteger + TranscriptProtocolChallenge 16 | { 17 | fn coprime_domain_sep(&mut self); 18 | } 19 | 20 | impl TranscriptProtocolCoprime for Transcript { 21 | fn coprime_domain_sep(&mut self) { 22 | self.append_message(b"dom-sep", b"coprime"); 23 | } 24 | } 25 | 26 | pub struct TranscriptVerifierChannel< 27 | 'a, 28 | G: ConvertibleUnknownOrderGroup, 29 | T: TranscriptProtocolCoprime, 30 | > { 31 | crs: CRSCoprime, 32 | transcript: &'a RefCell, 33 | message1: Option>, 34 | message2: Option>, 35 | message3: Option, 36 | } 37 | 38 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolCoprime> 39 | TranscriptVerifierChannel<'a, G, T> 40 | { 41 | pub fn new( 42 | crs: &CRSCoprime, 43 | transcript: &'a RefCell, 44 | ) -> TranscriptVerifierChannel<'a, G, T> { 45 | TranscriptVerifierChannel { 46 | crs: crs.clone(), 47 | transcript, 48 | message1: None, 49 | message2: None, 50 | message3: None, 51 | } 52 | } 53 | 54 | pub fn proof(&self) -> Result, TranscriptChannelError> { 55 | if self.message1.is_some() && self.message2.is_some() && self.message3.is_some() { 56 | Ok(Proof { 57 | message1: self.message1.as_ref().unwrap().clone(), 58 | message2: self.message2.as_ref().unwrap().clone(), 59 | message3: self.message3.as_ref().unwrap().clone(), 60 | }) 61 | } else { 62 | Err(TranscriptChannelError::Incomplete) 63 | } 64 | } 65 | } 66 | 67 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolCoprime> CoprimeVerifierChannel 68 | for TranscriptVerifierChannel<'a, G, T> 69 | { 70 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError> { 71 | let mut transcript = self.transcript.try_borrow_mut()?; 72 | transcript.coprime_domain_sep(); 73 | transcript.append_integer_point(b"c_a", &message.c_a); 74 | transcript.append_integer_point(b"c_r_a", &message.c_r_a); 75 | transcript.append_integer_point(b"c_b_cap", &message.c_b_cap); 76 | transcript.append_integer_point(b"c_rho_b_cap", &message.c_rho_b_cap); 77 | self.message1 = Some(message.clone()); 78 | Ok(()) 79 | } 80 | fn send_message2(&mut self, message: &Message2) -> Result<(), ChannelError> { 81 | let mut transcript = self.transcript.try_borrow_mut()?; 82 | transcript.coprime_domain_sep(); 83 | transcript.append_integer_point(b"alpha2", &message.alpha2); 84 | transcript.append_integer_point(b"alpha3", &message.alpha3); 85 | transcript.append_integer_point(b"alpha4", &message.alpha4); 86 | transcript.append_integer_point(b"alpha5", &message.alpha5); 87 | transcript.append_integer_point(b"alpha6", &message.alpha6); 88 | transcript.append_integer_point(b"alpha7", &message.alpha7); 89 | self.message2 = Some(message.clone()); 90 | Ok(()) 91 | } 92 | fn send_message3(&mut self, message: &Message3) -> Result<(), ChannelError> { 93 | self.message3 = Some(message.clone()); 94 | Ok(()) 95 | } 96 | fn receive_challenge(&mut self) -> Result { 97 | let mut transcript = self.transcript.try_borrow_mut()?; 98 | transcript.coprime_domain_sep(); 99 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 100 | } 101 | } 102 | 103 | pub struct TranscriptProverChannel< 104 | 'a, 105 | G: ConvertibleUnknownOrderGroup, 106 | T: TranscriptProtocolCoprime, 107 | > { 108 | crs: CRSCoprime, 109 | transcript: &'a RefCell, 110 | proof: Proof, 111 | } 112 | 113 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolCoprime> 114 | TranscriptProverChannel<'a, G, T> 115 | { 116 | pub fn new( 117 | crs: &CRSCoprime, 118 | transcript: &'a RefCell, 119 | proof: &Proof, 120 | ) -> TranscriptProverChannel<'a, G, T> { 121 | TranscriptProverChannel { 122 | crs: crs.clone(), 123 | transcript, 124 | proof: proof.clone(), 125 | } 126 | } 127 | } 128 | 129 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolCoprime> CoprimeProverChannel 130 | for TranscriptProverChannel<'a, G, T> 131 | { 132 | fn receive_message1(&mut self) -> Result, ChannelError> { 133 | let mut transcript = self.transcript.try_borrow_mut()?; 134 | transcript.coprime_domain_sep(); 135 | transcript.append_integer_point(b"c_a", &self.proof.message1.c_a); 136 | transcript.append_integer_point(b"c_r_a", &self.proof.message1.c_r_a); 137 | transcript.append_integer_point(b"c_b_cap", &self.proof.message1.c_b_cap); 138 | transcript.append_integer_point(b"c_rho_b_cap", &self.proof.message1.c_rho_b_cap); 139 | Ok(self.proof.message1.clone()) 140 | } 141 | fn receive_message2(&mut self) -> Result, ChannelError> { 142 | let mut transcript = self.transcript.try_borrow_mut()?; 143 | transcript.coprime_domain_sep(); 144 | transcript.append_integer_point(b"alpha2", &self.proof.message2.alpha2); 145 | transcript.append_integer_point(b"alpha3", &self.proof.message2.alpha3); 146 | transcript.append_integer_point(b"alpha4", &self.proof.message2.alpha4); 147 | transcript.append_integer_point(b"alpha5", &self.proof.message2.alpha5); 148 | transcript.append_integer_point(b"alpha6", &self.proof.message2.alpha6); 149 | transcript.append_integer_point(b"alpha7", &self.proof.message2.alpha7); 150 | 151 | Ok(self.proof.message2.clone()) 152 | } 153 | fn receive_message3(&mut self) -> Result { 154 | Ok(self.proof.message3.clone()) 155 | } 156 | fn generate_and_send_challenge(&mut self) -> Result { 157 | let mut transcript = self.transcript.try_borrow_mut()?; 158 | transcript.coprime_domain_sep(); 159 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/protocols/hash_to_prime/bp.rs: -------------------------------------------------------------------------------- 1 | //! Bulletproofs-based range proof. 2 | 3 | use crate::{ 4 | commitments::pedersen::PedersenCommitment, 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::{ 8 | channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}, 9 | CRSHashToPrime, CRSSize, HashToPrimeError, HashToPrimeProtocol, Statement, Witness, 10 | }, 11 | ProofError, SetupError, VerificationError, 12 | }, 13 | utils::{curve::Field, integer_to_bigint_mod_q, log2}, 14 | }; 15 | use bulletproofs::{ 16 | r1cs::{ConstraintSystem, LinearCombination, Prover, R1CSError, R1CSProof, Verifier}, 17 | BulletproofGens, PedersenGens, 18 | }; 19 | use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar, traits::Identity}; 20 | use merlin::Transcript; 21 | use rand::Rng; 22 | use rug::Integer; 23 | use std::cell::RefCell; 24 | 25 | pub fn range_proof( 26 | cs: &mut CS, 27 | mut v: LinearCombination, 28 | v_assignment: Option, 29 | required_bit_size: usize, 30 | ) -> Result<(), R1CSError> { 31 | let mut exp_2 = Scalar::one(); 32 | let bits = v_assignment.map(|q| q.to_bits().into_iter().rev().collect::>()); 33 | for i in 0..required_bit_size { 34 | // Create low-level variables and add them to constraints 35 | let (a, b, o) = cs.allocate_multiplier(bits.as_ref().and_then(|bits| { 36 | let bit = if bits[i] { 1 as u64 } else { 0 }; 37 | Some(((1 - bit).into(), bit.into())) 38 | }))?; 39 | 40 | // Enforce a * b = 0, so one of (a,b) is zero 41 | cs.constrain(o.into()); 42 | 43 | // Enforce that a = 1 - b, so they both are 1 or 0. 44 | cs.constrain(a + (b - 1u64)); 45 | 46 | // if this is the highest order bit, ensure it's set 47 | if i == required_bit_size - 1 { 48 | cs.constrain(b - 1u64); 49 | } 50 | 51 | // Add `-b_i*2^i` to the linear combination 52 | // in order to form the following constraint by the end of the loop: 53 | // v = Sum(b_i * 2^i, i = 0..n-1) 54 | v = v - b * exp_2; 55 | 56 | exp_2 = exp_2 + exp_2; 57 | } 58 | 59 | // Enforce that v = Sum(b_i * 2^i, i = 0..n-1) 60 | //cs.constrain(v); 61 | 62 | Ok(()) 63 | } 64 | 65 | pub struct Protocol { 66 | pub crs: CRSHashToPrime, 67 | } 68 | 69 | #[derive(Clone)] 70 | pub struct BPParameters { 71 | pub bulletproof_gens: BulletproofGens, 72 | pub transcript: Option>, 73 | } 74 | 75 | impl<'a> BPParameters { 76 | pub fn set_transcript(&mut self, transcript: &RefCell) { 77 | self.transcript = Some(transcript.clone()); 78 | } 79 | } 80 | 81 | impl CRSSize for BPParameters { 82 | fn crs_size(&self) -> (usize, usize) { 83 | let mut vk_accum = 0; 84 | let ristretto_point_size = RistrettoPoint::identity().compress().as_bytes().len(); 85 | for _ in 0..self.bulletproof_gens.gens_capacity { 86 | vk_accum += ristretto_point_size; 87 | } 88 | (vk_accum, 0) 89 | } 90 | } 91 | 92 | impl HashToPrimeProtocol for Protocol { 93 | type Proof = R1CSProof; 94 | type Parameters = BPParameters; 95 | 96 | fn from_crs(crs: &CRSHashToPrime) -> Protocol { 97 | Protocol { 98 | crs: (*crs).clone(), 99 | } 100 | } 101 | 102 | fn setup( 103 | _: &mut R, 104 | _: &PedersenCommitment, 105 | parameters: &Parameters, 106 | ) -> Result { 107 | let rounded_hash_to_prime_bits = 1 << log2(parameters.hash_to_prime_bits as usize); 108 | Ok(BPParameters { 109 | bulletproof_gens: BulletproofGens::new(rounded_hash_to_prime_bits, 1), 110 | transcript: None, 111 | }) 112 | } 113 | 114 | fn prove>( 115 | &self, 116 | verifier_channel: &mut C, 117 | _: &mut R, 118 | _: &Statement, 119 | witness: &Witness, 120 | ) -> Result<(), ProofError> { 121 | let pedersen_gens = PedersenGens { 122 | B: self.crs.pedersen_commitment_parameters.g, 123 | B_blinding: self.crs.pedersen_commitment_parameters.h, 124 | }; 125 | 126 | let (proof, _) = { 127 | let default_transcript = RefCell::new(Transcript::new(b"bp_range_proof")); 128 | let prover_transcript = if self.crs.hash_to_prime_parameters.transcript.is_some() { 129 | self.crs 130 | .hash_to_prime_parameters 131 | .transcript 132 | .as_ref() 133 | .unwrap() 134 | } else { 135 | &default_transcript 136 | }; 137 | 138 | let mut prover_transcript = prover_transcript 139 | .try_borrow_mut() 140 | .map_err(|_| ProofError::CouldNotCreateProof)?; 141 | 142 | let mut prover = Prover::new(&pedersen_gens, &mut *prover_transcript); 143 | 144 | let value = integer_to_bigint_mod_q::(&witness.e)?; 145 | let randomness = integer_to_bigint_mod_q::(&witness.r_q)?; 146 | let (com, var) = prover.commit(value, randomness); 147 | if range_proof( 148 | &mut prover, 149 | var.into(), 150 | Some(value), 151 | self.crs.parameters.hash_to_prime_bits as usize, 152 | ) 153 | .is_err() 154 | { 155 | return Err(ProofError::CouldNotCreateProof); 156 | } 157 | 158 | let proof = prover.prove(&self.crs.hash_to_prime_parameters.bulletproof_gens)?; 159 | 160 | (proof, com) 161 | }; 162 | 163 | verifier_channel.send_proof(&proof)?; 164 | 165 | Ok(()) 166 | } 167 | 168 | fn verify>( 169 | &self, 170 | prover_channel: &mut C, 171 | statement: &Statement, 172 | ) -> Result<(), VerificationError> { 173 | let pedersen_gens = PedersenGens { 174 | B: self.crs.pedersen_commitment_parameters.g, 175 | B_blinding: self.crs.pedersen_commitment_parameters.h, 176 | }; 177 | 178 | let default_transcript = RefCell::new(Transcript::new(b"bp_range_proof")); 179 | let verifier_transcript = if self.crs.hash_to_prime_parameters.transcript.is_some() { 180 | self.crs 181 | .hash_to_prime_parameters 182 | .transcript 183 | .as_ref() 184 | .unwrap() 185 | } else { 186 | &default_transcript 187 | }; 188 | 189 | let mut verifier_transcript = verifier_transcript 190 | .try_borrow_mut() 191 | .map_err(|_| VerificationError::VerificationFailed)?; 192 | let mut verifier = Verifier::new(&mut *verifier_transcript); 193 | 194 | let var = verifier.commit(statement.c_e_q.compress()); 195 | 196 | if range_proof( 197 | &mut verifier, 198 | var.into(), 199 | None, 200 | self.crs.parameters.hash_to_prime_bits as usize, 201 | ) 202 | .is_err() 203 | { 204 | return Err(VerificationError::VerificationFailed); 205 | } 206 | 207 | let proof = prover_channel.receive_proof()?; 208 | Ok(verifier.verify( 209 | &proof, 210 | &pedersen_gens, 211 | &self.crs.hash_to_prime_parameters.bulletproof_gens, 212 | )?) 213 | } 214 | 215 | fn hash_to_prime(&self, e: &Integer) -> Result<(Integer, u64), HashToPrimeError> { 216 | Ok((e.clone(), 0)) 217 | } 218 | } 219 | 220 | #[cfg(test)] 221 | mod tests { 222 | use super::{Protocol, Statement, Witness}; 223 | use crate::{ 224 | commitments::Commitment, 225 | parameters::Parameters, 226 | protocols::hash_to_prime::{ 227 | bp::Protocol as HPProtocol, 228 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 229 | HashToPrimeProtocol, 230 | }, 231 | }; 232 | use accumulator::group::Rsa2048; 233 | use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; 234 | use merlin::Transcript; 235 | use rand::thread_rng; 236 | use rug::rand::RandState; 237 | use rug::Integer; 238 | use std::cell::RefCell; 239 | 240 | #[test] 241 | fn test_proof() { 242 | let params = Parameters::from_curve::().unwrap().0; 243 | let mut rng1 = RandState::new(); 244 | rng1.seed(&Integer::from(13)); 245 | let mut rng2 = thread_rng(); 246 | 247 | let crs = 248 | crate::protocols::membership::Protocol::::setup( 249 | ¶ms, &mut rng1, &mut rng2, 250 | ) 251 | .unwrap() 252 | .crs 253 | .crs_hash_to_prime; 254 | let protocol = Protocol::from_crs(&crs); 255 | 256 | let value = Integer::from(Integer::u_pow_u( 257 | 2, 258 | (crs.parameters.hash_to_prime_bits) as u32, 259 | )) - &Integer::from(129); 260 | let randomness = Integer::from(9); 261 | let commitment = protocol 262 | .crs 263 | .pedersen_commitment_parameters 264 | .commit(&value, &randomness) 265 | .unwrap(); 266 | 267 | let proof_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 268 | let statement = Statement { c_e_q: commitment }; 269 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 270 | protocol 271 | .prove( 272 | &mut verifier_channel, 273 | &mut rng2, 274 | &statement, 275 | &Witness { 276 | e: value, 277 | r_q: randomness, 278 | }, 279 | ) 280 | .unwrap(); 281 | 282 | let proof = verifier_channel.proof().unwrap(); 283 | 284 | let verification_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 285 | let mut prover_channel = 286 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 287 | protocol.verify(&mut prover_channel, &statement).unwrap(); 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/protocols/hash_to_prime/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, protocols::hash_to_prime::HashToPrimeProtocol, 3 | utils::curve::CurvePointProjective, 4 | }; 5 | pub trait HashToPrimeVerifierChannel> { 6 | fn send_proof(&mut self, proof: &HP::Proof) -> Result<(), ChannelError>; 7 | } 8 | 9 | pub trait HashToPrimeProverChannel> { 10 | fn receive_proof(&mut self) -> Result; 11 | } 12 | -------------------------------------------------------------------------------- /src/protocols/hash_to_prime/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements an abstract hash-to-prime protocol, which can also be just a range proof. 2 | use crate::{ 3 | commitments::{pedersen::PedersenCommitment, Commitment}, 4 | parameters::Parameters, 5 | protocols::{ProofError, SetupError, VerificationError}, 6 | utils::curve::CurvePointProjective, 7 | }; 8 | use channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}; 9 | use rand::{CryptoRng, RngCore}; 10 | use rug::Integer; 11 | 12 | pub mod channel; 13 | pub mod transcript; 14 | 15 | cfg_if::cfg_if! { 16 | if #[cfg(feature = "arkworks")] { 17 | pub mod snark_hash; 18 | pub mod snark_range; 19 | 20 | use ark_ec::{PairingEngine, AffineCurve}; 21 | use ark_serialize::CanonicalSerialize; 22 | 23 | impl CRSSize for legogro16::ProvingKey:: { 24 | fn crs_size(&self) -> (usize, usize) { 25 | let g1_serialized_size = E::G1Affine::prime_subgroup_generator().serialized_size(); 26 | let g2_serialized_size = E::G2Affine::prime_subgroup_generator().serialized_size(); 27 | 28 | let mut vk_accum = 0; 29 | // Groth16 vk 30 | vk_accum += self.vk.alpha_g1.serialized_size(); 31 | vk_accum += self.vk.beta_g2.serialized_size(); 32 | vk_accum += self.vk.gamma_g2.serialized_size(); 33 | vk_accum += self.vk.delta_g2.serialized_size(); 34 | for g in &self.vk.gamma_abc_g1 { 35 | vk_accum += g.serialized_size(); 36 | } 37 | vk_accum += self.vk.eta_gamma_inv_g1.serialized_size(); 38 | 39 | // link 40 | vk_accum += 8; // l 41 | vk_accum += 8; // t 42 | vk_accum += g1_serialized_size; 43 | vk_accum += g2_serialized_size; 44 | 45 | for b in &self.vk.link_bases { 46 | vk_accum += b.serialized_size(); 47 | } 48 | vk_accum += g2_serialized_size; 49 | for b in &self.vk.link_vk.c { 50 | vk_accum += b.serialized_size(); 51 | } 52 | 53 | let mut pk_accum = 0; 54 | pk_accum += self.beta_g1.serialized_size(); 55 | pk_accum += self.delta_g1.serialized_size(); 56 | pk_accum += self.eta_delta_inv_g1.serialized_size(); 57 | for g in &self.a_query { 58 | pk_accum += g.serialized_size(); 59 | } 60 | for g in &self.b_g1_query { 61 | pk_accum += g.serialized_size(); 62 | } 63 | for g in &self.b_g2_query { 64 | pk_accum += g.serialized_size(); 65 | } 66 | for g in &self.h_query { 67 | pk_accum += g.serialized_size(); 68 | } 69 | for g in &self.l_query { 70 | pk_accum += g.serialized_size(); 71 | } 72 | for g in &self.link_ek.p { 73 | pk_accum += g.serialized_size(); 74 | } 75 | 76 | (vk_accum, pk_accum) 77 | } 78 | } 79 | } 80 | } 81 | 82 | cfg_if::cfg_if! { 83 | if #[cfg(feature = "dalek")] { 84 | pub mod bp; 85 | } 86 | } 87 | 88 | pub trait CRSSize { 89 | fn crs_size(&self) -> (usize, usize); 90 | } 91 | 92 | pub trait HashToPrimeProtocol { 93 | type Proof: Clone; 94 | type Parameters: Clone; 95 | 96 | fn from_crs(crs: &CRSHashToPrime) -> Self 97 | where 98 | Self: Sized; 99 | 100 | fn setup( 101 | rng: &mut R, 102 | pedersen_commitment_parameters: &PedersenCommitment

, 103 | parameters: &Parameters, 104 | ) -> Result; 105 | 106 | fn prove>( 107 | &self, 108 | verifier_channel: &mut C, 109 | rng: &mut R, 110 | _: &Statement

, 111 | witness: &Witness, 112 | ) -> Result<(), ProofError> 113 | where 114 | Self: Sized; 115 | fn verify>( 116 | &self, 117 | prover_channel: &mut C, 118 | statement: &Statement

, 119 | ) -> Result<(), VerificationError> 120 | where 121 | Self: Sized; 122 | fn hash_to_prime(&self, e: &Integer) -> Result<(Integer, u64), HashToPrimeError>; 123 | } 124 | 125 | pub struct CRSHashToPrime> { 126 | pub parameters: Parameters, 127 | pub pedersen_commitment_parameters: PedersenCommitment

, 128 | pub hash_to_prime_parameters: HP::Parameters, 129 | } 130 | 131 | impl> Clone for CRSHashToPrime { 132 | fn clone(&self) -> Self { 133 | Self { 134 | parameters: self.parameters.clone(), 135 | pedersen_commitment_parameters: self.pedersen_commitment_parameters.clone(), 136 | hash_to_prime_parameters: self.hash_to_prime_parameters.clone(), 137 | } 138 | } 139 | } 140 | 141 | pub struct Statement { 142 | pub c_e_q: as Commitment>::Instance, 143 | } 144 | 145 | pub struct Witness { 146 | pub e: Integer, 147 | pub r_q: Integer, 148 | } 149 | 150 | quick_error! { 151 | #[derive(Debug)] 152 | pub enum HashToPrimeError { 153 | CouldNotFindIndex {} 154 | ValueTooBig {} 155 | IntegerError(num: Integer) { 156 | from() 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/protocols/hash_to_prime/snark_range.rs: -------------------------------------------------------------------------------- 1 | //! LegoGroth16-based range proof. 2 | 3 | use crate::{ 4 | commitments::pedersen::PedersenCommitment, 5 | parameters::Parameters, 6 | protocols::{ 7 | hash_to_prime::{ 8 | channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}, 9 | CRSHashToPrime, HashToPrimeError, HashToPrimeProtocol, Statement, Witness, 10 | }, 11 | ProofError, SetupError, VerificationError, 12 | }, 13 | utils::integer_to_bigint_mod_q, 14 | }; 15 | use ark_ff::{PrimeField, UniformRand}; 16 | use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; 17 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; 18 | use ark_r1cs_std::{ 19 | alloc::{AllocVar, AllocationMode}, bits::ToBitsGadget, boolean::Boolean, eq::EqGadget, fields::fp::FpVar, 20 | Assignment, 21 | }; 22 | use rand::Rng; 23 | use rug::Integer; 24 | use std::ops::Sub; 25 | 26 | pub struct HashToPrimeCircuit { 27 | required_bit_size: u16, 28 | value: Option, 29 | } 30 | 31 | impl ConstraintSynthesizer for HashToPrimeCircuit { 32 | fn generate_constraints( 33 | self, 34 | cs: ConstraintSystemRef, 35 | ) -> Result<(), SynthesisError> { 36 | let f = FpVar::new_variable(ark_relations::ns!(cs, "alloc value"), || self.value.get(), AllocationMode::Input)?; 37 | // big-endian bits 38 | let bits = f.to_non_unique_bits_be()?; 39 | let modulus_bits = E::Fr::size_in_bits(); 40 | let bits_to_skip = modulus_bits - self.required_bit_size as usize; 41 | for b in bits[..bits_to_skip].iter() { 42 | b.enforce_equal( 43 | &Boolean::constant(false), 44 | )?; 45 | } 46 | bits[bits_to_skip].enforce_equal( 47 | &Boolean::constant(true), 48 | )?; 49 | 50 | Ok(()) 51 | } 52 | } 53 | 54 | pub struct Protocol { 55 | pub crs: CRSHashToPrime, 56 | } 57 | 58 | impl HashToPrimeProtocol for Protocol { 59 | type Proof = legogro16::Proof; 60 | type Parameters = legogro16::ProvingKey; 61 | 62 | fn from_crs(crs: &CRSHashToPrime) -> Protocol { 63 | Protocol { 64 | crs: (*crs).clone(), 65 | } 66 | } 67 | 68 | fn setup( 69 | rng: &mut R, 70 | pedersen_commitment_parameters: &PedersenCommitment, 71 | parameters: &Parameters, 72 | ) -> Result { 73 | let c = HashToPrimeCircuit:: { 74 | required_bit_size: parameters.hash_to_prime_bits, 75 | value: None, 76 | }; 77 | let base_one = E::G1Projective::rand(rng); 78 | let pedersen_bases = vec![ 79 | base_one, 80 | pedersen_commitment_parameters.g, 81 | pedersen_commitment_parameters.h, 82 | ]; 83 | Ok(legogro16::generate_random_parameters( 84 | c, 85 | &pedersen_bases 86 | .into_iter() 87 | .map(|p| p.into_affine()) 88 | .collect::>(), 89 | rng, 90 | )?) 91 | } 92 | 93 | fn prove>( 94 | &self, 95 | verifier_channel: &mut C, 96 | rng: &mut R, 97 | _: &Statement, 98 | witness: &Witness, 99 | ) -> Result<(), ProofError> { 100 | let c = HashToPrimeCircuit:: { 101 | required_bit_size: self.crs.parameters.hash_to_prime_bits, 102 | value: Some(integer_to_bigint_mod_q::( 103 | &witness.e.clone(), 104 | )?), 105 | }; 106 | let v = E::Fr::rand(rng); 107 | let link_v = integer_to_bigint_mod_q::(&witness.r_q.clone())?; 108 | let proof = legogro16::create_random_proof::( 109 | c, 110 | v, 111 | link_v, 112 | &self.crs.hash_to_prime_parameters, 113 | rng, 114 | )?; 115 | verifier_channel.send_proof(&proof)?; 116 | Ok(()) 117 | } 118 | 119 | fn verify>( 120 | &self, 121 | prover_channel: &mut C, 122 | statement: &Statement, 123 | ) -> Result<(), VerificationError> { 124 | let proof = prover_channel.receive_proof()?; 125 | let pvk = legogro16::prepare_verifying_key(&self.crs.hash_to_prime_parameters.vk); 126 | if !legogro16::verify_proof(&pvk, &proof)? { 127 | return Err(VerificationError::VerificationFailed); 128 | } 129 | let proof_link_d_without_one = proof 130 | .link_d 131 | .into_projective() 132 | .sub(&self.crs.hash_to_prime_parameters.vk.link_bases[0].into_projective()); 133 | if statement.c_e_q != proof_link_d_without_one { 134 | return Err(VerificationError::VerificationFailed); 135 | } 136 | 137 | Ok(()) 138 | } 139 | 140 | fn hash_to_prime(&self, e: &Integer) -> Result<(Integer, u64), HashToPrimeError> { 141 | Ok((e.clone(), 0)) 142 | } 143 | } 144 | 145 | #[cfg(test)] 146 | mod test { 147 | use super::{HashToPrimeCircuit, Protocol, Statement, Witness}; 148 | use crate::{ 149 | commitments::Commitment, 150 | parameters::Parameters, 151 | protocols::hash_to_prime::{ 152 | snark_range::Protocol as HPProtocol, 153 | transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 154 | HashToPrimeProtocol, 155 | }, 156 | utils::integer_to_bigint_mod_q, 157 | }; 158 | use accumulator::group::Rsa2048; 159 | use ark_bls12_381::{Bls12_381, Fr, G1Projective}; 160 | use merlin::Transcript; 161 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; 162 | use rand::thread_rng; 163 | use rug::rand::RandState; 164 | use rug::Integer; 165 | use std::cell::RefCell; 166 | 167 | #[test] 168 | fn test_circuit() { 169 | let cs = ConstraintSystem::::new_ref(); 170 | let c = HashToPrimeCircuit:: { 171 | required_bit_size: 4, 172 | value: Some(integer_to_bigint_mod_q::(&Integer::from(12)).unwrap()), 173 | }; 174 | c.generate_constraints(cs.clone()).unwrap(); 175 | println!("num constraints: {}", cs.num_constraints()); 176 | if !cs.is_satisfied().unwrap() { 177 | panic!(format!( 178 | "not satisfied: {:?}", 179 | cs.which_is_unsatisfied().unwrap() 180 | )); 181 | } 182 | } 183 | 184 | #[test] 185 | fn test_proof() { 186 | let params = Parameters::from_security_level(128).unwrap(); 187 | let mut rng1 = RandState::new(); 188 | rng1.seed(&Integer::from(13)); 189 | let mut rng2 = thread_rng(); 190 | 191 | let crs = crate::protocols::membership::Protocol::< 192 | Rsa2048, 193 | G1Projective, 194 | HPProtocol, 195 | >::setup(¶ms, &mut rng1, &mut rng2) 196 | .unwrap() 197 | .crs 198 | .crs_hash_to_prime; 199 | let protocol = Protocol::::from_crs(&crs); 200 | 201 | let value = Integer::from(Integer::u_pow_u( 202 | 2, 203 | (crs.parameters.hash_to_prime_bits) as u32, 204 | )) - &Integer::from(245); 205 | let randomness = Integer::from(9); 206 | let commitment = protocol 207 | .crs 208 | .pedersen_commitment_parameters 209 | .commit(&value, &randomness) 210 | .unwrap(); 211 | 212 | let proof_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 213 | let statement = Statement { c_e_q: commitment }; 214 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 215 | protocol 216 | .prove( 217 | &mut verifier_channel, 218 | &mut rng2, 219 | &statement, 220 | &Witness { 221 | e: value, 222 | r_q: randomness, 223 | }, 224 | ) 225 | .unwrap(); 226 | 227 | let proof = verifier_channel.proof().unwrap(); 228 | 229 | let verification_transcript = RefCell::new(Transcript::new(b"hash_to_prime")); 230 | let mut prover_channel = 231 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 232 | protocol.verify(&mut prover_channel, &statement).unwrap(); 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/protocols/hash_to_prime/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::hash_to_prime::{ 4 | channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}, 5 | CRSHashToPrime, HashToPrimeProtocol, 6 | }, 7 | transcript::{TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolCurve}, 8 | utils::curve::CurvePointProjective, 9 | }; 10 | use merlin::Transcript; 11 | use std::cell::RefCell; 12 | 13 | pub trait TranscriptProtocolHashToPrime: 14 | TranscriptProtocolCurve

+ TranscriptProtocolChallenge 15 | { 16 | fn hash_to_prime_domain_sep(&mut self); 17 | } 18 | 19 | impl TranscriptProtocolHashToPrime

for Transcript { 20 | fn hash_to_prime_domain_sep(&mut self) { 21 | self.append_message(b"dom-sep", b"hash_to_prime"); 22 | } 23 | } 24 | 25 | pub struct TranscriptVerifierChannel< 26 | 'a, 27 | P: CurvePointProjective, 28 | HP: HashToPrimeProtocol

, 29 | T: TranscriptProtocolHashToPrime

, 30 | > { 31 | proof: Option, 32 | crs_type: std::marker::PhantomData>, 33 | transcript_type: std::marker::PhantomData<&'a RefCell>, 34 | } 35 | 36 | impl< 37 | 'a, 38 | P: CurvePointProjective, 39 | HP: HashToPrimeProtocol

, 40 | T: TranscriptProtocolHashToPrime

, 41 | > TranscriptVerifierChannel<'a, P, HP, T> 42 | { 43 | pub fn new( 44 | _: &CRSHashToPrime, 45 | _: &'a RefCell, 46 | ) -> TranscriptVerifierChannel<'a, P, HP, T> { 47 | TranscriptVerifierChannel { 48 | proof: None, 49 | crs_type: std::marker::PhantomData, 50 | transcript_type: std::marker::PhantomData, 51 | } 52 | } 53 | 54 | pub fn proof(&self) -> Result { 55 | if self.proof.is_some() { 56 | Ok(self.proof.as_ref().unwrap().clone()) 57 | } else { 58 | Err(TranscriptChannelError::Incomplete) 59 | } 60 | } 61 | } 62 | 63 | impl< 64 | 'a, 65 | P: CurvePointProjective, 66 | HP: HashToPrimeProtocol

, 67 | T: TranscriptProtocolHashToPrime

, 68 | > HashToPrimeVerifierChannel for TranscriptVerifierChannel<'a, P, HP, T> 69 | { 70 | fn send_proof(&mut self, proof: &HP::Proof) -> Result<(), ChannelError> { 71 | self.proof = Some(proof.clone()); 72 | Ok(()) 73 | } 74 | } 75 | 76 | pub struct TranscriptProverChannel< 77 | 'a, 78 | P: CurvePointProjective, 79 | HP: HashToPrimeProtocol

, 80 | T: TranscriptProtocolHashToPrime

, 81 | > { 82 | proof: HP::Proof, 83 | crs_type: std::marker::PhantomData>, 84 | transcript_type: std::marker::PhantomData<&'a RefCell>, 85 | } 86 | 87 | impl< 88 | 'a, 89 | P: CurvePointProjective, 90 | HP: HashToPrimeProtocol

, 91 | T: TranscriptProtocolHashToPrime

, 92 | > TranscriptProverChannel<'a, P, HP, T> 93 | { 94 | pub fn new( 95 | _: &CRSHashToPrime, 96 | _: &'a RefCell, 97 | proof: &HP::Proof, 98 | ) -> TranscriptProverChannel<'a, P, HP, T> { 99 | TranscriptProverChannel { 100 | proof: proof.clone(), 101 | crs_type: std::marker::PhantomData, 102 | transcript_type: std::marker::PhantomData, 103 | } 104 | } 105 | } 106 | 107 | impl< 108 | 'a, 109 | P: CurvePointProjective, 110 | HP: HashToPrimeProtocol

, 111 | T: TranscriptProtocolHashToPrime

, 112 | > HashToPrimeProverChannel for TranscriptProverChannel<'a, P, HP, T> 113 | { 114 | fn receive_proof(&mut self) -> Result { 115 | Ok(self.proof.clone()) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/protocols/membership/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | commitments::{integer::IntegerCommitment, Commitment}, 4 | utils::ConvertibleUnknownOrderGroup, 5 | }; 6 | 7 | pub trait MembershipVerifierChannel { 8 | fn send_c_e( 9 | &mut self, 10 | c_e: & as Commitment>::Instance, 11 | ) -> Result<(), ChannelError>; 12 | } 13 | 14 | pub trait MembershipProverChannel { 15 | fn receive_c_e( 16 | &mut self, 17 | ) -> Result< as Commitment>::Instance, ChannelError>; 18 | } 19 | -------------------------------------------------------------------------------- /src/protocols/membership/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | commitments::{integer::IntegerCommitment, Commitment}, 4 | protocols::{ 5 | hash_to_prime::{ 6 | channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}, 7 | transcript::{ 8 | TranscriptProtocolHashToPrime, 9 | TranscriptProverChannel as HashToPrimeTranscriptProverChannel, 10 | TranscriptVerifierChannel as HashToPrimeTranscriptVerifierChannel, 11 | }, 12 | HashToPrimeProtocol, 13 | }, 14 | membership::{ 15 | channel::{MembershipProverChannel, MembershipVerifierChannel}, 16 | Proof, CRS, 17 | }, 18 | modeq::{ 19 | channel::{ModEqProverChannel, ModEqVerifierChannel}, 20 | transcript::{ 21 | TranscriptProtocolModEq, TranscriptProverChannel as ModEqTranscriptProverChannel, 22 | TranscriptVerifierChannel as ModEqTranscriptVerifierChannel, 23 | }, 24 | }, 25 | root::{ 26 | channel::{RootProverChannel, RootVerifierChannel}, 27 | transcript::{ 28 | TranscriptProtocolRoot, TranscriptProverChannel as RootTranscriptProverChannel, 29 | TranscriptVerifierChannel as RootTranscriptVerifierChannel, 30 | }, 31 | }, 32 | }, 33 | transcript::{TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolInteger}, 34 | utils::{curve::CurvePointProjective, ConvertibleUnknownOrderGroup}, 35 | }; 36 | use merlin::Transcript; 37 | use rug::Integer; 38 | use std::cell::RefCell; 39 | 40 | pub trait TranscriptProtocolMembership: 41 | TranscriptProtocolInteger + TranscriptProtocolChallenge 42 | { 43 | fn membership_domain_sep(&mut self); 44 | } 45 | 46 | impl TranscriptProtocolMembership for Transcript { 47 | fn membership_domain_sep(&mut self) { 48 | self.append_message(b"dom-sep", b"membership"); 49 | } 50 | } 51 | pub struct TranscriptVerifierChannel< 52 | 'a, 53 | G: ConvertibleUnknownOrderGroup, 54 | P: CurvePointProjective, 55 | HP: HashToPrimeProtocol

, 56 | T: TranscriptProtocolMembership 57 | + TranscriptProtocolRoot 58 | + TranscriptProtocolModEq 59 | + TranscriptProtocolHashToPrime

, 60 | > { 61 | transcript: &'a RefCell, 62 | c_e: Option< as Commitment>::Instance>, 63 | root_transcript_verifier_channel: RootTranscriptVerifierChannel<'a, G, T>, 64 | modeq_transcript_verifier_channel: ModEqTranscriptVerifierChannel<'a, G, P, T>, 65 | hash_to_prime_transcript_verifier_channel: HashToPrimeTranscriptVerifierChannel<'a, P, HP, T>, 66 | } 67 | 68 | impl< 69 | 'a, 70 | G: ConvertibleUnknownOrderGroup, 71 | P: CurvePointProjective, 72 | HP: HashToPrimeProtocol

, 73 | T: TranscriptProtocolMembership 74 | + TranscriptProtocolRoot 75 | + TranscriptProtocolModEq 76 | + TranscriptProtocolHashToPrime

, 77 | > TranscriptVerifierChannel<'a, G, P, HP, T> 78 | { 79 | pub fn new( 80 | crs: &CRS, 81 | transcript: &'a RefCell, 82 | ) -> TranscriptVerifierChannel<'a, G, P, HP, T> { 83 | TranscriptVerifierChannel { 84 | transcript, 85 | c_e: None, 86 | root_transcript_verifier_channel: RootTranscriptVerifierChannel::new( 87 | &crs.crs_root, 88 | transcript, 89 | ), 90 | modeq_transcript_verifier_channel: ModEqTranscriptVerifierChannel::new( 91 | &crs.crs_modeq, 92 | transcript, 93 | ), 94 | hash_to_prime_transcript_verifier_channel: HashToPrimeTranscriptVerifierChannel::new( 95 | &crs.crs_hash_to_prime, 96 | transcript, 97 | ), 98 | } 99 | } 100 | 101 | pub fn proof(&self) -> Result, TranscriptChannelError> { 102 | let proof_root = self.root_transcript_verifier_channel.proof()?; 103 | let proof_modeq = self.modeq_transcript_verifier_channel.proof()?; 104 | let proof_hash_to_prime = self.hash_to_prime_transcript_verifier_channel.proof()?; 105 | if self.c_e.is_some() { 106 | Ok(Proof { 107 | c_e: self.c_e.as_ref().unwrap().clone(), 108 | proof_root, 109 | proof_modeq, 110 | proof_hash_to_prime, 111 | }) 112 | } else { 113 | Err(TranscriptChannelError::Incomplete) 114 | } 115 | } 116 | } 117 | 118 | impl< 119 | 'a, 120 | G: ConvertibleUnknownOrderGroup, 121 | P: CurvePointProjective, 122 | HP: HashToPrimeProtocol

, 123 | T: TranscriptProtocolMembership 124 | + TranscriptProtocolRoot 125 | + TranscriptProtocolModEq 126 | + TranscriptProtocolHashToPrime

, 127 | > RootVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 128 | { 129 | fn send_message1( 130 | &mut self, 131 | message: &crate::protocols::root::Message1, 132 | ) -> Result<(), ChannelError> { 133 | self.root_transcript_verifier_channel.send_message1(message) 134 | } 135 | fn send_message2( 136 | &mut self, 137 | message: &crate::protocols::root::Message2, 138 | ) -> Result<(), ChannelError> { 139 | self.root_transcript_verifier_channel.send_message2(message) 140 | } 141 | fn send_message3( 142 | &mut self, 143 | message: &crate::protocols::root::Message3, 144 | ) -> Result<(), ChannelError> { 145 | self.root_transcript_verifier_channel.send_message3(message) 146 | } 147 | fn receive_challenge(&mut self) -> Result { 148 | self.root_transcript_verifier_channel.receive_challenge() 149 | } 150 | } 151 | 152 | impl< 153 | 'a, 154 | G: ConvertibleUnknownOrderGroup, 155 | P: CurvePointProjective, 156 | HP: HashToPrimeProtocol

, 157 | T: TranscriptProtocolMembership 158 | + TranscriptProtocolRoot 159 | + TranscriptProtocolModEq 160 | + TranscriptProtocolHashToPrime

, 161 | > ModEqVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 162 | { 163 | fn send_message1( 164 | &mut self, 165 | message: &crate::protocols::modeq::Message1, 166 | ) -> Result<(), ChannelError> { 167 | self.modeq_transcript_verifier_channel 168 | .send_message1(message) 169 | } 170 | fn send_message2( 171 | &mut self, 172 | message: &crate::protocols::modeq::Message2

, 173 | ) -> Result<(), ChannelError> { 174 | self.modeq_transcript_verifier_channel 175 | .send_message2(message) 176 | } 177 | fn receive_challenge(&mut self) -> Result { 178 | self.modeq_transcript_verifier_channel.receive_challenge() 179 | } 180 | } 181 | 182 | impl< 183 | 'a, 184 | G: ConvertibleUnknownOrderGroup, 185 | P: CurvePointProjective, 186 | HP: HashToPrimeProtocol

, 187 | T: TranscriptProtocolMembership 188 | + TranscriptProtocolRoot 189 | + TranscriptProtocolModEq 190 | + TranscriptProtocolHashToPrime

, 191 | > HashToPrimeVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 192 | { 193 | fn send_proof(&mut self, proof: &HP::Proof) -> Result<(), ChannelError> { 194 | self.hash_to_prime_transcript_verifier_channel 195 | .send_proof(proof) 196 | } 197 | } 198 | 199 | pub struct TranscriptProverChannel< 200 | 'a, 201 | G: ConvertibleUnknownOrderGroup, 202 | P: CurvePointProjective, 203 | HP: HashToPrimeProtocol

, 204 | T: TranscriptProtocolMembership 205 | + TranscriptProtocolRoot 206 | + TranscriptProtocolModEq 207 | + TranscriptProtocolHashToPrime

, 208 | > { 209 | transcript: &'a RefCell, 210 | root_transcript_prover_channel: RootTranscriptProverChannel<'a, G, T>, 211 | modeq_transcript_prover_channel: ModEqTranscriptProverChannel<'a, G, P, T>, 212 | hash_to_prime_transcript_prover_channel: HashToPrimeTranscriptProverChannel<'a, P, HP, T>, 213 | proof: Proof, 214 | } 215 | 216 | impl< 217 | 'a, 218 | G: ConvertibleUnknownOrderGroup, 219 | P: CurvePointProjective, 220 | HP: HashToPrimeProtocol

, 221 | T: TranscriptProtocolMembership 222 | + TranscriptProtocolRoot 223 | + TranscriptProtocolModEq 224 | + TranscriptProtocolHashToPrime

, 225 | > RootProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 226 | { 227 | fn receive_message1(&mut self) -> Result, ChannelError> { 228 | self.root_transcript_prover_channel.receive_message1() 229 | } 230 | fn receive_message2(&mut self) -> Result, ChannelError> { 231 | self.root_transcript_prover_channel.receive_message2() 232 | } 233 | fn receive_message3(&mut self) -> Result { 234 | self.root_transcript_prover_channel.receive_message3() 235 | } 236 | fn generate_and_send_challenge(&mut self) -> Result { 237 | self.root_transcript_prover_channel 238 | .generate_and_send_challenge() 239 | } 240 | } 241 | 242 | impl< 243 | 'a, 244 | G: ConvertibleUnknownOrderGroup, 245 | P: CurvePointProjective, 246 | HP: HashToPrimeProtocol

, 247 | T: TranscriptProtocolMembership 248 | + TranscriptProtocolRoot 249 | + TranscriptProtocolModEq 250 | + TranscriptProtocolHashToPrime

, 251 | > ModEqProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 252 | { 253 | fn receive_message1( 254 | &mut self, 255 | ) -> Result, ChannelError> { 256 | self.modeq_transcript_prover_channel.receive_message1() 257 | } 258 | fn receive_message2(&mut self) -> Result, ChannelError> { 259 | self.modeq_transcript_prover_channel.receive_message2() 260 | } 261 | fn generate_and_send_challenge(&mut self) -> Result { 262 | self.modeq_transcript_prover_channel 263 | .generate_and_send_challenge() 264 | } 265 | } 266 | 267 | impl< 268 | 'a, 269 | G: ConvertibleUnknownOrderGroup, 270 | P: CurvePointProjective, 271 | HP: HashToPrimeProtocol

, 272 | T: TranscriptProtocolMembership 273 | + TranscriptProtocolRoot 274 | + TranscriptProtocolModEq 275 | + TranscriptProtocolHashToPrime

, 276 | > HashToPrimeProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 277 | { 278 | fn receive_proof(&mut self) -> Result { 279 | self.hash_to_prime_transcript_prover_channel.receive_proof() 280 | } 281 | } 282 | 283 | impl< 284 | 'a, 285 | G: ConvertibleUnknownOrderGroup, 286 | P: CurvePointProjective, 287 | HP: HashToPrimeProtocol

, 288 | T: TranscriptProtocolMembership 289 | + TranscriptProtocolRoot 290 | + TranscriptProtocolModEq 291 | + TranscriptProtocolHashToPrime

, 292 | > MembershipVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 293 | { 294 | fn send_c_e( 295 | &mut self, 296 | c_e: & as Commitment>::Instance, 297 | ) -> Result<(), ChannelError> { 298 | let mut transcript = self.transcript.try_borrow_mut()?; 299 | transcript.membership_domain_sep(); 300 | transcript.append_integer_point(b"c_e", c_e); 301 | self.c_e = Some(c_e.clone()); 302 | Ok(()) 303 | } 304 | } 305 | 306 | impl< 307 | 'a, 308 | G: ConvertibleUnknownOrderGroup, 309 | P: CurvePointProjective, 310 | HP: HashToPrimeProtocol

, 311 | T: TranscriptProtocolMembership 312 | + TranscriptProtocolRoot 313 | + TranscriptProtocolModEq 314 | + TranscriptProtocolHashToPrime

, 315 | > MembershipProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 316 | { 317 | fn receive_c_e( 318 | &mut self, 319 | ) -> Result< as Commitment>::Instance, ChannelError> { 320 | let mut transcript = self.transcript.try_borrow_mut()?; 321 | transcript.membership_domain_sep(); 322 | transcript.append_integer_point(b"c_e", &self.proof.c_e); 323 | Ok(self.proof.c_e.clone()) 324 | } 325 | } 326 | 327 | impl< 328 | 'a, 329 | G: ConvertibleUnknownOrderGroup, 330 | P: CurvePointProjective, 331 | HP: HashToPrimeProtocol

, 332 | T: TranscriptProtocolMembership 333 | + TranscriptProtocolRoot 334 | + TranscriptProtocolModEq 335 | + TranscriptProtocolHashToPrime

, 336 | > TranscriptProverChannel<'a, G, P, HP, T> 337 | { 338 | pub fn new( 339 | crs: &CRS, 340 | transcript: &'a RefCell, 341 | proof: &Proof, 342 | ) -> TranscriptProverChannel<'a, G, P, HP, T> { 343 | TranscriptProverChannel { 344 | transcript, 345 | root_transcript_prover_channel: RootTranscriptProverChannel::new( 346 | &crs.crs_root, 347 | transcript, 348 | &proof.proof_root, 349 | ), 350 | modeq_transcript_prover_channel: ModEqTranscriptProverChannel::new( 351 | &crs.crs_modeq, 352 | transcript, 353 | &proof.proof_modeq, 354 | ), 355 | hash_to_prime_transcript_prover_channel: HashToPrimeTranscriptProverChannel::new( 356 | &crs.crs_hash_to_prime, 357 | transcript, 358 | &proof.proof_hash_to_prime, 359 | ), 360 | proof: proof.clone(), 361 | } 362 | } 363 | } 364 | -------------------------------------------------------------------------------- /src/protocols/mod.rs: -------------------------------------------------------------------------------- 1 | //! All the protocol implementations. 2 | 3 | use crate::{ 4 | channels::ChannelError, commitments::CommitmentError, 5 | protocols::hash_to_prime::HashToPrimeError, 6 | }; 7 | use ark_relations::r1cs::SynthesisError; 8 | use rug::Integer; 9 | 10 | pub mod coprime; 11 | pub mod hash_to_prime; 12 | pub mod membership; 13 | pub mod modeq; 14 | pub mod nonmembership; 15 | pub mod root; 16 | 17 | quick_error! { 18 | #[derive(Debug)] 19 | pub enum CRSError { 20 | InvalidParameters {} 21 | } 22 | } 23 | 24 | quick_error! { 25 | #[derive(Debug)] 26 | pub enum SetupError { 27 | CouldNotPerformSetup {} 28 | SNARKError(err: SynthesisError) { 29 | from() 30 | } 31 | } 32 | } 33 | 34 | #[cfg(feature = "dalek")] 35 | type R1CSError = bulletproofs::r1cs::R1CSError; 36 | 37 | #[cfg(feature = "arkworks")] 38 | quick_error! { 39 | #[derive(Debug)] 40 | pub enum DummyBPError {} 41 | } 42 | #[cfg(feature = "arkworks")] 43 | type R1CSError = DummyBPError; 44 | 45 | quick_error! { 46 | #[derive(Debug)] 47 | pub enum ProofError { 48 | CouldNotCreateProof {} 49 | CommitmentError(err: CommitmentError) { 50 | from() 51 | } 52 | IntegerError(err: Integer) { 53 | from() 54 | } 55 | SNARKError(err: SynthesisError) { 56 | from() 57 | } 58 | VerifierChannelError(err: ChannelError) { 59 | from() 60 | } 61 | PrimeError(err: HashToPrimeError) { 62 | from() 63 | } 64 | BPError(err: R1CSError) { 65 | from() 66 | } 67 | CRSInitError(err: CRSError) { 68 | from() 69 | } 70 | } 71 | } 72 | 73 | quick_error! { 74 | #[derive(Debug)] 75 | pub enum VerificationError { 76 | VerificationFailed {} 77 | CommitmentError(err: CommitmentError) { 78 | from() 79 | } 80 | IntegerError(err: Integer) { 81 | from() 82 | } 83 | SNARKError(err: SynthesisError) { 84 | from() 85 | } 86 | ProverChannelError(err: ChannelError) { 87 | from() 88 | } 89 | BPError(err: R1CSError) { 90 | from() 91 | } 92 | CRSInitError(err: CRSError) { 93 | from() 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/protocols/modeq/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::modeq::{Message1, Message2}, 4 | utils::{curve::CurvePointProjective, ConvertibleUnknownOrderGroup}, 5 | }; 6 | use rug::Integer; 7 | 8 | pub trait ModEqVerifierChannel { 9 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError>; 10 | fn send_message2(&mut self, message: &Message2

) -> Result<(), ChannelError>; 11 | fn receive_challenge(&mut self) -> Result; 12 | } 13 | 14 | pub trait ModEqProverChannel { 15 | fn receive_message1(&mut self) -> Result, ChannelError>; 16 | fn receive_message2(&mut self) -> Result, ChannelError>; 17 | fn generate_and_send_challenge(&mut self) -> Result; 18 | } 19 | -------------------------------------------------------------------------------- /src/protocols/modeq/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements ModEq. 2 | use crate::commitments::{integer::IntegerCommitment, pedersen::PedersenCommitment, Commitment}; 3 | use crate::{ 4 | parameters::Parameters, 5 | protocols::{ProofError, VerificationError}, 6 | utils::{ 7 | bigint_to_integer, 8 | curve::{CurvePointProjective, Field}, 9 | integer_mod_q, integer_to_bigint_mod_q, random_symmetric_range, 10 | ConvertibleUnknownOrderGroup, 11 | }, 12 | }; 13 | use channel::{ModEqProverChannel, ModEqVerifierChannel}; 14 | use rand::{CryptoRng, RngCore}; 15 | use rug::{rand::MutRandState, Integer}; 16 | 17 | pub mod channel; 18 | pub mod transcript; 19 | 20 | #[derive(Clone)] 21 | pub struct CRSModEq { 22 | // G contains the information about Z^*_N 23 | pub parameters: Parameters, 24 | pub integer_commitment_parameters: IntegerCommitment, // G, H 25 | pub pedersen_commitment_parameters: PedersenCommitment

, // g, h 26 | } 27 | 28 | pub struct Statement { 29 | pub c_e: as Commitment>::Instance, 30 | pub c_e_q: as Commitment>::Instance, 31 | } 32 | 33 | pub struct Witness { 34 | pub e: Integer, 35 | pub r: Integer, 36 | pub r_q: Integer, 37 | } 38 | 39 | #[derive(Clone)] 40 | pub struct Message1 { 41 | pub alpha1: as Commitment>::Instance, 42 | pub alpha2: as Commitment>::Instance, 43 | } 44 | 45 | #[derive(Clone)] 46 | pub struct Message2 { 47 | pub s_e: Integer, 48 | pub s_r: Integer, 49 | pub s_r_q: P::ScalarField, 50 | } 51 | 52 | #[derive(Clone)] 53 | pub struct Proof { 54 | pub message1: Message1, 55 | pub message2: Message2

, 56 | } 57 | 58 | pub struct Protocol { 59 | pub crs: CRSModEq, 60 | } 61 | 62 | impl Protocol { 63 | pub fn from_crs(crs: &CRSModEq) -> Protocol { 64 | Protocol { crs: crs.clone() } 65 | } 66 | 67 | pub fn prove>( 68 | &self, 69 | verifier_channel: &mut C, 70 | rng1: &mut R1, 71 | rng2: &mut R2, 72 | _: &Statement, 73 | witness: &Witness, 74 | ) -> Result<(), ProofError> { 75 | let r_e_range = Integer::from(Integer::u_pow_u( 76 | 2, 77 | (self.crs.parameters.security_zk 78 | + self.crs.parameters.security_soundness 79 | + self.crs.parameters.hash_to_prime_bits) as u32, 80 | )); 81 | let r_e = random_symmetric_range(rng1, &r_e_range); 82 | let r_r_range: Integer = G::order_upper_bound() / 2 83 | * Integer::from(Integer::u_pow_u( 84 | 2, 85 | (self.crs.parameters.security_zk + self.crs.parameters.security_soundness) as u32, 86 | )); 87 | let r_r = random_symmetric_range(rng1, &r_r_range); 88 | assert!(self.crs.parameters.field_size_bits as usize >= P::ScalarField::size_in_bits()); 89 | let r_r_q_field = P::ScalarField::rand(rng2); 90 | let r_r_q = bigint_to_integer::

(&r_r_q_field); 91 | 92 | let alpha1 = self.crs.integer_commitment_parameters.commit(&r_e, &r_r)?; 93 | let alpha2 = self 94 | .crs 95 | .pedersen_commitment_parameters 96 | .commit(&integer_mod_q::

(&r_e)?, &r_r_q)?; 97 | 98 | let message1 = Message1:: { alpha1, alpha2 }; 99 | verifier_channel.send_message1(&message1)?; 100 | 101 | let c = verifier_channel.receive_challenge()?; 102 | let r_q = integer_to_bigint_mod_q::

(&witness.r_q.clone())?; 103 | let s_e = r_e - c.clone() * witness.e.clone(); 104 | let s_r = r_r - c.clone() * witness.r.clone(); 105 | let c_big = integer_to_bigint_mod_q::

(&c)?; 106 | let s_r_q = r_r_q_field.sub(&(r_q.mul(&c_big))); 107 | 108 | let message2 = Message2::

{ s_e, s_r, s_r_q }; 109 | verifier_channel.send_message2(&message2)?; 110 | 111 | Ok(()) 112 | } 113 | 114 | pub fn verify>( 115 | &self, 116 | prover_channel: &mut C, 117 | statement: &Statement, 118 | ) -> Result<(), VerificationError> { 119 | let message1 = prover_channel.receive_message1()?; 120 | let c = prover_channel.generate_and_send_challenge()?; 121 | let message2 = prover_channel.receive_message2()?; 122 | 123 | let commitment2 = self 124 | .crs 125 | .integer_commitment_parameters 126 | .commit(&message2.s_e, &message2.s_r)?; 127 | let commitment2_extra = G::exp(&statement.c_e, &c); 128 | let expected_alpha1 = G::op(&commitment2, &commitment2_extra); 129 | 130 | let s_e_mod_q = integer_mod_q::

(&message2.s_e)?; 131 | let s_r_q_int = bigint_to_integer::

(&message2.s_r_q); 132 | let commitment1 = self 133 | .crs 134 | .pedersen_commitment_parameters 135 | .commit(&s_e_mod_q, &s_r_q_int)?; 136 | let c_big = integer_to_bigint_mod_q::

(&c)?; 137 | let commitment1_extra = statement.c_e_q.mul(&c_big); 138 | let expected_alpha2 = commitment1.add(&commitment1_extra); 139 | 140 | if expected_alpha1 == message1.alpha1 && expected_alpha2 == message1.alpha2 { 141 | Ok(()) 142 | } else { 143 | Err(VerificationError::VerificationFailed) 144 | } 145 | } 146 | } 147 | 148 | #[cfg(all(test, feature = "arkworks"))] 149 | mod test { 150 | use super::{Protocol, Statement, Witness}; 151 | use crate::{ 152 | commitments::Commitment, 153 | parameters::Parameters, 154 | protocols::{ 155 | hash_to_prime::snark_range::Protocol as HPProtocol, 156 | modeq::transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 157 | }, 158 | }; 159 | use accumulator::group::Rsa2048; 160 | use ark_bls12_381::{Bls12_381, G1Projective}; 161 | use merlin::Transcript; 162 | use rand::thread_rng; 163 | use rug::rand::RandState; 164 | use rug::Integer; 165 | use std::cell::RefCell; 166 | 167 | #[test] 168 | fn test_proof() { 169 | let params = Parameters::from_security_level(128).unwrap(); 170 | let mut rng1 = RandState::new(); 171 | rng1.seed(&Integer::from(13)); 172 | let mut rng2 = thread_rng(); 173 | 174 | let crs = crate::protocols::membership::Protocol::< 175 | Rsa2048, 176 | G1Projective, 177 | HPProtocol, 178 | >::setup(¶ms, &mut rng1, &mut rng2) 179 | .unwrap() 180 | .crs 181 | .crs_modeq; 182 | let protocol = Protocol::::from_crs(&crs); 183 | 184 | let value1 = Integer::from(2); 185 | let randomness1 = Integer::from(5); 186 | let randomness2 = Integer::from(9); 187 | let commitment1 = protocol 188 | .crs 189 | .integer_commitment_parameters 190 | .commit(&value1, &randomness1) 191 | .unwrap(); 192 | let commitment2 = protocol 193 | .crs 194 | .pedersen_commitment_parameters 195 | .commit(&value1, &randomness2) 196 | .unwrap(); 197 | 198 | let proof_transcript = RefCell::new(Transcript::new(b"modeq")); 199 | let statement = Statement { 200 | c_e: commitment1, 201 | c_e_q: commitment2, 202 | }; 203 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 204 | protocol 205 | .prove( 206 | &mut verifier_channel, 207 | &mut rng1, 208 | &mut rng2, 209 | &statement, 210 | &Witness { 211 | e: value1, 212 | r: randomness1, 213 | r_q: randomness2, 214 | }, 215 | ) 216 | .unwrap(); 217 | 218 | let proof = verifier_channel.proof().unwrap(); 219 | 220 | let verification_transcript = RefCell::new(Transcript::new(b"modeq")); 221 | let mut prover_channel = 222 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 223 | protocol.verify(&mut prover_channel, &statement).unwrap(); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/protocols/modeq/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::modeq::{ 4 | channel::{ModEqProverChannel, ModEqVerifierChannel}, 5 | CRSModEq, Message1, Message2, Proof, 6 | }, 7 | transcript::{ 8 | TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolCurve, 9 | TranscriptProtocolInteger, 10 | }, 11 | utils::{curve::CurvePointProjective, ConvertibleUnknownOrderGroup}, 12 | }; 13 | use merlin::Transcript; 14 | use rug::Integer; 15 | use std::cell::RefCell; 16 | 17 | pub trait TranscriptProtocolModEq: 18 | TranscriptProtocolInteger + TranscriptProtocolCurve

+ TranscriptProtocolChallenge 19 | { 20 | fn modeq_domain_sep(&mut self); 21 | } 22 | 23 | impl TranscriptProtocolModEq 24 | for Transcript 25 | { 26 | fn modeq_domain_sep(&mut self) { 27 | self.append_message(b"dom-sep", b"modeq"); 28 | } 29 | } 30 | pub struct TranscriptVerifierChannel< 31 | 'a, 32 | G: ConvertibleUnknownOrderGroup, 33 | P: CurvePointProjective, 34 | T: TranscriptProtocolModEq, 35 | > { 36 | crs: CRSModEq, 37 | transcript: &'a RefCell, 38 | message1: Option>, 39 | message2: Option>, 40 | } 41 | 42 | impl< 43 | 'a, 44 | G: ConvertibleUnknownOrderGroup, 45 | P: CurvePointProjective, 46 | T: TranscriptProtocolModEq, 47 | > TranscriptVerifierChannel<'a, G, P, T> 48 | { 49 | pub fn new( 50 | crs: &CRSModEq, 51 | transcript: &'a RefCell, 52 | ) -> TranscriptVerifierChannel<'a, G, P, T> { 53 | TranscriptVerifierChannel { 54 | crs: crs.clone(), 55 | transcript, 56 | message1: None, 57 | message2: None, 58 | } 59 | } 60 | 61 | pub fn proof(&self) -> Result, TranscriptChannelError> { 62 | if self.message1.is_some() && self.message2.is_some() { 63 | Ok(Proof { 64 | message1: self.message1.as_ref().unwrap().clone(), 65 | message2: self.message2.as_ref().unwrap().clone(), 66 | }) 67 | } else { 68 | Err(TranscriptChannelError::Incomplete) 69 | } 70 | } 71 | } 72 | 73 | impl< 74 | 'a, 75 | G: ConvertibleUnknownOrderGroup, 76 | P: CurvePointProjective, 77 | T: TranscriptProtocolModEq, 78 | > ModEqVerifierChannel for TranscriptVerifierChannel<'a, G, P, T> 79 | { 80 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError> { 81 | let mut transcript = self.transcript.try_borrow_mut()?; 82 | transcript.modeq_domain_sep(); 83 | transcript.append_integer_point(b"alpha1", &message.alpha1); 84 | transcript.append_curve_point(b"alpha2", &message.alpha2)?; 85 | self.message1 = Some(message.clone()); 86 | Ok(()) 87 | } 88 | fn send_message2(&mut self, message: &Message2

) -> Result<(), ChannelError> { 89 | self.message2 = Some(message.clone()); 90 | Ok(()) 91 | } 92 | fn receive_challenge(&mut self) -> Result { 93 | let mut transcript = self.transcript.try_borrow_mut()?; 94 | transcript.modeq_domain_sep(); 95 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 96 | } 97 | } 98 | 99 | pub struct TranscriptProverChannel< 100 | 'a, 101 | G: ConvertibleUnknownOrderGroup, 102 | P: CurvePointProjective, 103 | T: TranscriptProtocolModEq, 104 | > { 105 | crs: CRSModEq, 106 | transcript: &'a RefCell, 107 | proof: Proof, 108 | } 109 | 110 | impl< 111 | 'a, 112 | G: ConvertibleUnknownOrderGroup, 113 | P: CurvePointProjective, 114 | T: TranscriptProtocolModEq, 115 | > TranscriptProverChannel<'a, G, P, T> 116 | { 117 | pub fn new( 118 | crs: &CRSModEq, 119 | transcript: &'a RefCell, 120 | proof: &Proof, 121 | ) -> TranscriptProverChannel<'a, G, P, T> { 122 | TranscriptProverChannel { 123 | crs: crs.clone(), 124 | transcript, 125 | proof: proof.clone(), 126 | } 127 | } 128 | } 129 | 130 | impl< 131 | 'a, 132 | G: ConvertibleUnknownOrderGroup, 133 | P: CurvePointProjective, 134 | T: TranscriptProtocolModEq, 135 | > ModEqProverChannel for TranscriptProverChannel<'a, G, P, T> 136 | { 137 | fn receive_message1(&mut self) -> Result, ChannelError> { 138 | let mut transcript = self.transcript.try_borrow_mut()?; 139 | transcript.modeq_domain_sep(); 140 | transcript.append_integer_point(b"alpha1", &self.proof.message1.alpha1); 141 | transcript.append_curve_point(b"alpha2", &self.proof.message1.alpha2)?; 142 | Ok(self.proof.message1.clone()) 143 | } 144 | fn receive_message2(&mut self) -> Result, ChannelError> { 145 | Ok(self.proof.message2.clone()) 146 | } 147 | fn generate_and_send_challenge(&mut self) -> Result { 148 | let mut transcript = self.transcript.try_borrow_mut()?; 149 | transcript.modeq_domain_sep(); 150 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/protocols/nonmembership/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | commitments::{integer::IntegerCommitment, Commitment}, 4 | utils::ConvertibleUnknownOrderGroup, 5 | }; 6 | 7 | pub trait NonMembershipVerifierChannel { 8 | fn send_c_e( 9 | &mut self, 10 | c_e: & as Commitment>::Instance, 11 | ) -> Result<(), ChannelError>; 12 | } 13 | 14 | pub trait NonMembershipProverChannel { 15 | fn receive_c_e( 16 | &mut self, 17 | ) -> Result< as Commitment>::Instance, ChannelError>; 18 | } 19 | -------------------------------------------------------------------------------- /src/protocols/nonmembership/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | commitments::{integer::IntegerCommitment, Commitment}, 4 | protocols::{ 5 | coprime::{ 6 | channel::{CoprimeProverChannel, CoprimeVerifierChannel}, 7 | transcript::{ 8 | TranscriptProtocolCoprime, 9 | TranscriptProverChannel as CoprimeTranscriptProverChannel, 10 | TranscriptVerifierChannel as CoprimeTranscriptVerifierChannel, 11 | }, 12 | }, 13 | hash_to_prime::HashToPrimeProtocol, 14 | hash_to_prime::{ 15 | channel::{HashToPrimeProverChannel, HashToPrimeVerifierChannel}, 16 | transcript::{ 17 | TranscriptProtocolHashToPrime, 18 | TranscriptProverChannel as HashToPrimeTranscriptProverChannel, 19 | TranscriptVerifierChannel as HashToPrimeTranscriptVerifierChannel, 20 | }, 21 | }, 22 | modeq::{ 23 | channel::{ModEqProverChannel, ModEqVerifierChannel}, 24 | transcript::{ 25 | TranscriptProtocolModEq, TranscriptProverChannel as ModEqTranscriptProverChannel, 26 | TranscriptVerifierChannel as ModEqTranscriptVerifierChannel, 27 | }, 28 | }, 29 | nonmembership::{ 30 | channel::{NonMembershipProverChannel, NonMembershipVerifierChannel}, 31 | Proof, CRS, 32 | }, 33 | }, 34 | transcript::{TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolInteger}, 35 | utils::{curve::CurvePointProjective, ConvertibleUnknownOrderGroup}, 36 | }; 37 | use merlin::Transcript; 38 | use rug::Integer; 39 | use std::cell::RefCell; 40 | 41 | pub trait TranscriptProtocolNonMembership: 42 | TranscriptProtocolInteger + TranscriptProtocolChallenge 43 | { 44 | fn nonmembership_domain_sep(&mut self); 45 | } 46 | 47 | impl TranscriptProtocolNonMembership for Transcript { 48 | fn nonmembership_domain_sep(&mut self) { 49 | self.append_message(b"dom-sep", b"nonmembership"); 50 | } 51 | } 52 | pub struct TranscriptVerifierChannel< 53 | 'a, 54 | G: ConvertibleUnknownOrderGroup, 55 | P: CurvePointProjective, 56 | HP: HashToPrimeProtocol

, 57 | T: TranscriptProtocolNonMembership 58 | + TranscriptProtocolCoprime 59 | + TranscriptProtocolModEq 60 | + TranscriptProtocolHashToPrime

, 61 | > { 62 | transcript: &'a RefCell, 63 | c_e: Option< as Commitment>::Instance>, 64 | coprime_transcript_verifier_channel: CoprimeTranscriptVerifierChannel<'a, G, T>, 65 | modeq_transcript_verifier_channel: ModEqTranscriptVerifierChannel<'a, G, P, T>, 66 | hash_to_prime_transcript_verifier_channel: HashToPrimeTranscriptVerifierChannel<'a, P, HP, T>, 67 | } 68 | 69 | impl< 70 | 'a, 71 | G: ConvertibleUnknownOrderGroup, 72 | P: CurvePointProjective, 73 | HP: HashToPrimeProtocol

, 74 | T: TranscriptProtocolNonMembership 75 | + TranscriptProtocolCoprime 76 | + TranscriptProtocolModEq 77 | + TranscriptProtocolHashToPrime

, 78 | > TranscriptVerifierChannel<'a, G, P, HP, T> 79 | { 80 | pub fn new( 81 | crs: &CRS, 82 | transcript: &'a RefCell, 83 | ) -> TranscriptVerifierChannel<'a, G, P, HP, T> { 84 | TranscriptVerifierChannel { 85 | transcript, 86 | c_e: None, 87 | coprime_transcript_verifier_channel: CoprimeTranscriptVerifierChannel::new( 88 | &crs.crs_coprime, 89 | transcript, 90 | ), 91 | modeq_transcript_verifier_channel: ModEqTranscriptVerifierChannel::new( 92 | &crs.crs_modeq, 93 | transcript, 94 | ), 95 | hash_to_prime_transcript_verifier_channel: HashToPrimeTranscriptVerifierChannel::new( 96 | &crs.crs_hash_to_prime, 97 | transcript, 98 | ), 99 | } 100 | } 101 | 102 | pub fn proof(&self) -> Result, TranscriptChannelError> { 103 | let proof_coprime = self.coprime_transcript_verifier_channel.proof()?; 104 | let proof_modeq = self.modeq_transcript_verifier_channel.proof()?; 105 | let proof_hash_to_prime = self.hash_to_prime_transcript_verifier_channel.proof()?; 106 | if self.c_e.is_some() { 107 | Ok(Proof { 108 | c_e: self.c_e.as_ref().unwrap().clone(), 109 | proof_coprime, 110 | proof_modeq, 111 | proof_hash_to_prime, 112 | }) 113 | } else { 114 | Err(TranscriptChannelError::Incomplete) 115 | } 116 | } 117 | } 118 | 119 | impl< 120 | 'a, 121 | G: ConvertibleUnknownOrderGroup, 122 | P: CurvePointProjective, 123 | HP: HashToPrimeProtocol

, 124 | T: TranscriptProtocolNonMembership 125 | + TranscriptProtocolCoprime 126 | + TranscriptProtocolModEq 127 | + TranscriptProtocolHashToPrime

, 128 | > CoprimeVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 129 | { 130 | fn send_message1( 131 | &mut self, 132 | message: &crate::protocols::coprime::Message1, 133 | ) -> Result<(), ChannelError> { 134 | self.coprime_transcript_verifier_channel 135 | .send_message1(message) 136 | } 137 | fn send_message2( 138 | &mut self, 139 | message: &crate::protocols::coprime::Message2, 140 | ) -> Result<(), ChannelError> { 141 | self.coprime_transcript_verifier_channel 142 | .send_message2(message) 143 | } 144 | fn send_message3( 145 | &mut self, 146 | message: &crate::protocols::coprime::Message3, 147 | ) -> Result<(), ChannelError> { 148 | self.coprime_transcript_verifier_channel 149 | .send_message3(message) 150 | } 151 | fn receive_challenge(&mut self) -> Result { 152 | self.coprime_transcript_verifier_channel.receive_challenge() 153 | } 154 | } 155 | 156 | impl< 157 | 'a, 158 | G: ConvertibleUnknownOrderGroup, 159 | P: CurvePointProjective, 160 | HP: HashToPrimeProtocol

, 161 | T: TranscriptProtocolNonMembership 162 | + TranscriptProtocolCoprime 163 | + TranscriptProtocolModEq 164 | + TranscriptProtocolHashToPrime

, 165 | > ModEqVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 166 | { 167 | fn send_message1( 168 | &mut self, 169 | message: &crate::protocols::modeq::Message1, 170 | ) -> Result<(), ChannelError> { 171 | self.modeq_transcript_verifier_channel 172 | .send_message1(message) 173 | } 174 | fn send_message2( 175 | &mut self, 176 | message: &crate::protocols::modeq::Message2

, 177 | ) -> Result<(), ChannelError> { 178 | self.modeq_transcript_verifier_channel 179 | .send_message2(message) 180 | } 181 | fn receive_challenge(&mut self) -> Result { 182 | self.modeq_transcript_verifier_channel.receive_challenge() 183 | } 184 | } 185 | 186 | impl< 187 | 'a, 188 | G: ConvertibleUnknownOrderGroup, 189 | P: CurvePointProjective, 190 | HP: HashToPrimeProtocol

, 191 | T: TranscriptProtocolNonMembership 192 | + TranscriptProtocolCoprime 193 | + TranscriptProtocolModEq 194 | + TranscriptProtocolHashToPrime

, 195 | > HashToPrimeVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 196 | { 197 | fn send_proof(&mut self, proof: &HP::Proof) -> Result<(), ChannelError> { 198 | self.hash_to_prime_transcript_verifier_channel 199 | .send_proof(proof) 200 | } 201 | } 202 | 203 | pub struct TranscriptProverChannel< 204 | 'a, 205 | G: ConvertibleUnknownOrderGroup, 206 | P: CurvePointProjective, 207 | HP: HashToPrimeProtocol

, 208 | T: TranscriptProtocolNonMembership 209 | + TranscriptProtocolCoprime 210 | + TranscriptProtocolModEq 211 | + TranscriptProtocolHashToPrime

, 212 | > { 213 | transcript: &'a RefCell, 214 | coprime_transcript_prover_channel: CoprimeTranscriptProverChannel<'a, G, T>, 215 | modeq_transcript_prover_channel: ModEqTranscriptProverChannel<'a, G, P, T>, 216 | hash_to_prime_transcript_prover_channel: HashToPrimeTranscriptProverChannel<'a, P, HP, T>, 217 | proof: Proof, 218 | } 219 | 220 | impl< 221 | 'a, 222 | G: ConvertibleUnknownOrderGroup, 223 | P: CurvePointProjective, 224 | HP: HashToPrimeProtocol

, 225 | T: TranscriptProtocolNonMembership 226 | + TranscriptProtocolCoprime 227 | + TranscriptProtocolModEq 228 | + TranscriptProtocolHashToPrime

, 229 | > CoprimeProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 230 | { 231 | fn receive_message1(&mut self) -> Result, ChannelError> { 232 | self.coprime_transcript_prover_channel.receive_message1() 233 | } 234 | fn receive_message2(&mut self) -> Result, ChannelError> { 235 | self.coprime_transcript_prover_channel.receive_message2() 236 | } 237 | fn receive_message3(&mut self) -> Result { 238 | self.coprime_transcript_prover_channel.receive_message3() 239 | } 240 | fn generate_and_send_challenge(&mut self) -> Result { 241 | self.coprime_transcript_prover_channel 242 | .generate_and_send_challenge() 243 | } 244 | } 245 | 246 | impl< 247 | 'a, 248 | G: ConvertibleUnknownOrderGroup, 249 | P: CurvePointProjective, 250 | HP: HashToPrimeProtocol

, 251 | T: TranscriptProtocolNonMembership 252 | + TranscriptProtocolCoprime 253 | + TranscriptProtocolModEq 254 | + TranscriptProtocolHashToPrime

, 255 | > ModEqProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 256 | { 257 | fn receive_message1( 258 | &mut self, 259 | ) -> Result, ChannelError> { 260 | self.modeq_transcript_prover_channel.receive_message1() 261 | } 262 | fn receive_message2(&mut self) -> Result, ChannelError> { 263 | self.modeq_transcript_prover_channel.receive_message2() 264 | } 265 | fn generate_and_send_challenge(&mut self) -> Result { 266 | self.modeq_transcript_prover_channel 267 | .generate_and_send_challenge() 268 | } 269 | } 270 | 271 | impl< 272 | 'a, 273 | G: ConvertibleUnknownOrderGroup, 274 | P: CurvePointProjective, 275 | HP: HashToPrimeProtocol

, 276 | T: TranscriptProtocolNonMembership 277 | + TranscriptProtocolCoprime 278 | + TranscriptProtocolModEq 279 | + TranscriptProtocolHashToPrime

, 280 | > HashToPrimeProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 281 | { 282 | fn receive_proof(&mut self) -> Result { 283 | self.hash_to_prime_transcript_prover_channel.receive_proof() 284 | } 285 | } 286 | 287 | impl< 288 | 'a, 289 | G: ConvertibleUnknownOrderGroup, 290 | P: CurvePointProjective, 291 | HP: HashToPrimeProtocol

, 292 | T: TranscriptProtocolNonMembership 293 | + TranscriptProtocolCoprime 294 | + TranscriptProtocolModEq 295 | + TranscriptProtocolHashToPrime

, 296 | > NonMembershipVerifierChannel for TranscriptVerifierChannel<'a, G, P, HP, T> 297 | { 298 | fn send_c_e( 299 | &mut self, 300 | c_e: & as Commitment>::Instance, 301 | ) -> Result<(), ChannelError> { 302 | let mut transcript = self.transcript.try_borrow_mut()?; 303 | transcript.nonmembership_domain_sep(); 304 | transcript.append_integer_point(b"c_e", c_e); 305 | self.c_e = Some(c_e.clone()); 306 | Ok(()) 307 | } 308 | } 309 | 310 | impl< 311 | 'a, 312 | G: ConvertibleUnknownOrderGroup, 313 | P: CurvePointProjective, 314 | HP: HashToPrimeProtocol

, 315 | T: TranscriptProtocolNonMembership 316 | + TranscriptProtocolCoprime 317 | + TranscriptProtocolModEq 318 | + TranscriptProtocolHashToPrime

, 319 | > NonMembershipProverChannel for TranscriptProverChannel<'a, G, P, HP, T> 320 | { 321 | fn receive_c_e( 322 | &mut self, 323 | ) -> Result< as Commitment>::Instance, ChannelError> { 324 | let mut transcript = self.transcript.try_borrow_mut()?; 325 | transcript.nonmembership_domain_sep(); 326 | transcript.append_integer_point(b"c_e", &self.proof.c_e); 327 | Ok(self.proof.c_e.clone()) 328 | } 329 | } 330 | 331 | impl< 332 | 'a, 333 | G: ConvertibleUnknownOrderGroup, 334 | P: CurvePointProjective, 335 | HP: HashToPrimeProtocol

, 336 | T: TranscriptProtocolNonMembership 337 | + TranscriptProtocolCoprime 338 | + TranscriptProtocolModEq 339 | + TranscriptProtocolHashToPrime

, 340 | > TranscriptProverChannel<'a, G, P, HP, T> 341 | { 342 | pub fn new( 343 | crs: &CRS, 344 | transcript: &'a RefCell, 345 | proof: &Proof, 346 | ) -> TranscriptProverChannel<'a, G, P, HP, T> { 347 | TranscriptProverChannel { 348 | transcript, 349 | coprime_transcript_prover_channel: CoprimeTranscriptProverChannel::new( 350 | &crs.crs_coprime, 351 | transcript, 352 | &proof.proof_coprime, 353 | ), 354 | modeq_transcript_prover_channel: ModEqTranscriptProverChannel::new( 355 | &crs.crs_modeq, 356 | transcript, 357 | &proof.proof_modeq, 358 | ), 359 | hash_to_prime_transcript_prover_channel: HashToPrimeTranscriptProverChannel::new( 360 | &crs.crs_hash_to_prime, 361 | transcript, 362 | &proof.proof_hash_to_prime, 363 | ), 364 | proof: proof.clone(), 365 | } 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /src/protocols/root/channel.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::root::{Message1, Message2, Message3}, 4 | utils::ConvertibleUnknownOrderGroup, 5 | }; 6 | use rug::Integer; 7 | 8 | pub trait RootVerifierChannel { 9 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError>; 10 | fn send_message2(&mut self, message: &Message2) -> Result<(), ChannelError>; 11 | fn send_message3(&mut self, message: &Message3) -> Result<(), ChannelError>; 12 | fn receive_challenge(&mut self) -> Result; 13 | } 14 | 15 | pub trait RootProverChannel { 16 | fn receive_message1(&mut self) -> Result, ChannelError>; 17 | fn receive_message2(&mut self) -> Result, ChannelError>; 18 | fn receive_message3(&mut self) -> Result; 19 | fn generate_and_send_challenge(&mut self) -> Result; 20 | } 21 | -------------------------------------------------------------------------------- /src/protocols/root/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements root, to be used in the membership protocol. 2 | use crate::{ 3 | commitments::{integer::IntegerCommitment, Commitment}, 4 | parameters::Parameters, 5 | protocols::{ProofError, VerificationError}, 6 | utils::{random_symmetric_range, ConvertibleUnknownOrderGroup}, 7 | }; 8 | use channel::{RootProverChannel, RootVerifierChannel}; 9 | use rug::rand::MutRandState; 10 | use rug::Integer; 11 | 12 | pub mod channel; 13 | pub mod transcript; 14 | 15 | #[derive(Clone)] 16 | pub struct CRSRoot { 17 | // G contains the information about Z^*_N 18 | pub parameters: Parameters, 19 | pub integer_commitment_parameters: IntegerCommitment, // G, H 20 | } 21 | pub struct Statement { 22 | pub c_e: as Commitment>::Instance, 23 | pub acc: G::Elem, 24 | } 25 | 26 | pub struct Witness { 27 | pub e: Integer, 28 | pub r: Integer, 29 | pub w: G::Elem, 30 | } 31 | 32 | #[derive(Clone)] 33 | pub struct Message1 { 34 | pub c_w: G::Elem, 35 | pub c_r: as Commitment>::Instance, 36 | } 37 | 38 | #[derive(Clone)] 39 | pub struct Message2 { 40 | pub alpha1: as Commitment>::Instance, 41 | pub alpha2: as Commitment>::Instance, 42 | pub alpha3: as Commitment>::Instance, 43 | pub alpha4: G::Elem, 44 | } 45 | 46 | #[derive(Clone)] 47 | pub struct Message3 { 48 | pub s_e: Integer, 49 | pub s_r: Integer, 50 | pub s_r_2: Integer, 51 | pub s_r_3: Integer, 52 | pub s_beta: Integer, 53 | pub s_delta: Integer, 54 | } 55 | 56 | #[derive(Clone)] 57 | pub struct Proof { 58 | pub message1: Message1, 59 | pub message2: Message2, 60 | pub message3: Message3, 61 | } 62 | 63 | pub struct Protocol { 64 | pub crs: CRSRoot, 65 | } 66 | 67 | impl Protocol { 68 | pub fn from_crs(crs: &CRSRoot) -> Protocol { 69 | Protocol { crs: crs.clone() } 70 | } 71 | 72 | pub fn prove>( 73 | &self, 74 | verifier_channel: &mut C, 75 | rng: &mut R, 76 | _: &Statement, 77 | witness: &Witness, 78 | ) -> Result<(), ProofError> { 79 | let r_2 = random_symmetric_range(rng, &(G::order_upper_bound() / Integer::from(2))); 80 | let r_3 = random_symmetric_range(rng, &(G::order_upper_bound() / Integer::from(2))); 81 | let c_w = G::op( 82 | &witness.w, 83 | &G::exp(&self.crs.integer_commitment_parameters.h, &r_2), 84 | ); 85 | let c_r = self.crs.integer_commitment_parameters.commit(&r_2, &r_3)?; 86 | 87 | let message1 = Message1:: { c_w, c_r }; 88 | verifier_channel.send_message1(&message1)?; 89 | 90 | let r_e_range = Integer::from(Integer::u_pow_u( 91 | 2, 92 | (self.crs.parameters.security_zk 93 | + self.crs.parameters.security_soundness 94 | + self.crs.parameters.hash_to_prime_bits) as u32, 95 | )); 96 | let r_e = random_symmetric_range(rng, &r_e_range); 97 | 98 | let r_r_range: Integer = G::order_upper_bound() / 2 99 | * Integer::from(Integer::u_pow_u( 100 | 2, 101 | (self.crs.parameters.security_zk + self.crs.parameters.security_soundness) as u32, 102 | )); 103 | let r_r = random_symmetric_range(rng, &r_r_range); 104 | let r_r_2 = random_symmetric_range(rng, &r_r_range); 105 | let r_r_3 = random_symmetric_range(rng, &r_r_range); 106 | 107 | let r_beta_delta_range: Integer = G::order_upper_bound() / 2 108 | * Integer::from(Integer::u_pow_u( 109 | 2, 110 | (self.crs.parameters.security_zk 111 | + self.crs.parameters.security_soundness 112 | + self.crs.parameters.hash_to_prime_bits) as u32, 113 | )); 114 | let r_beta = random_symmetric_range(rng, &r_beta_delta_range); 115 | let r_delta = random_symmetric_range(rng, &r_beta_delta_range); 116 | 117 | let alpha1 = self.crs.integer_commitment_parameters.commit(&r_e, &r_r)?; 118 | let alpha2 = self 119 | .crs 120 | .integer_commitment_parameters 121 | .commit(&r_r_2, &r_r_3)?; 122 | let integer_commitment_alpha3 = IntegerCommitment::::new( 123 | &message1.c_w, 124 | &G::inv(&self.crs.integer_commitment_parameters.h), 125 | ); 126 | let alpha3 = integer_commitment_alpha3.commit(&r_e, &r_beta)?; 127 | let integer_commitment_alpha4 = IntegerCommitment::::new( 128 | &G::inv(&self.crs.integer_commitment_parameters.h), 129 | &G::inv(&self.crs.integer_commitment_parameters.g), 130 | ); 131 | let alpha4 = G::op( 132 | &G::exp(&message1.c_r, &r_e), 133 | &integer_commitment_alpha4.commit(&r_delta, &r_beta)?, 134 | ); 135 | let message2 = Message2:: { 136 | alpha1, 137 | alpha2, 138 | alpha3, 139 | alpha4, 140 | }; 141 | verifier_channel.send_message2(&message2)?; 142 | 143 | let c = verifier_channel.receive_challenge()?; 144 | let s_e = r_e - c.clone() * witness.e.clone(); 145 | let s_r = r_r - c.clone() * witness.r.clone(); 146 | let s_r_2 = r_r_2 - c.clone() * r_2.clone(); 147 | let s_r_3 = r_r_3 - c.clone() * r_3.clone(); 148 | let s_beta = r_beta - c.clone() * witness.e.clone() * r_2; 149 | let s_delta = r_delta - c * witness.e.clone() * r_3; 150 | let message3 = Message3 { 151 | s_e, 152 | s_r, 153 | s_r_2, 154 | s_r_3, 155 | s_beta, 156 | s_delta, 157 | }; 158 | verifier_channel.send_message3(&message3)?; 159 | 160 | Ok(()) 161 | } 162 | 163 | pub fn verify>( 164 | &self, 165 | prover_channel: &mut C, 166 | statement: &Statement, 167 | ) -> Result<(), VerificationError> { 168 | let message1 = prover_channel.receive_message1()?; 169 | let message2 = prover_channel.receive_message2()?; 170 | let c = prover_channel.generate_and_send_challenge()?; 171 | let message3 = prover_channel.receive_message3()?; 172 | let expected_alpha1 = G::op( 173 | &G::exp(&statement.c_e, &c), 174 | &self 175 | .crs 176 | .integer_commitment_parameters 177 | .commit(&message3.s_e, &message3.s_r)?, 178 | ); 179 | let expected_alpha2 = G::op( 180 | &G::exp(&message1.c_r, &c), 181 | &self 182 | .crs 183 | .integer_commitment_parameters 184 | .commit(&message3.s_r_2, &message3.s_r_3)?, 185 | ); 186 | let integer_commitment_alpha3 = IntegerCommitment::::new( 187 | &message1.c_w, 188 | &G::inv(&self.crs.integer_commitment_parameters.h), 189 | ); 190 | let expected_alpha3 = G::op( 191 | &G::exp(&statement.acc, &c), 192 | &integer_commitment_alpha3.commit(&message3.s_e, &message3.s_beta)?, 193 | ); 194 | let integer_commitment_alpha4 = IntegerCommitment::::new( 195 | &G::inv(&self.crs.integer_commitment_parameters.h), 196 | &G::inv(&self.crs.integer_commitment_parameters.g), 197 | ); 198 | let expected_alpha4 = G::op( 199 | &G::exp(&message1.c_r, &message3.s_e), 200 | &integer_commitment_alpha4.commit(&message3.s_delta, &message3.s_beta)?, 201 | ); 202 | 203 | let s_e_expected_right = Integer::from(Integer::u_pow_u( 204 | 2, 205 | (self.crs.parameters.security_zk 206 | + self.crs.parameters.security_soundness 207 | + self.crs.parameters.hash_to_prime_bits 208 | + 1) as u32, 209 | )); 210 | 211 | let s_e_expected_left: Integer = -s_e_expected_right.clone(); 212 | let is_s_e_in_range = 213 | message3.s_e >= s_e_expected_left && message3.s_e <= s_e_expected_right; 214 | 215 | if expected_alpha1 == message2.alpha1 216 | && expected_alpha2 == message2.alpha2 217 | && expected_alpha3 == message2.alpha3 218 | && expected_alpha4 == message2.alpha4 219 | && is_s_e_in_range 220 | { 221 | Ok(()) 222 | } else { 223 | Err(VerificationError::VerificationFailed) 224 | } 225 | } 226 | } 227 | 228 | #[cfg(all(test, feature = "arkworks"))] 229 | mod test { 230 | use super::{Protocol, Statement, Witness}; 231 | use crate::{ 232 | commitments::Commitment, 233 | parameters::Parameters, 234 | protocols::{ 235 | hash_to_prime::snark_range::Protocol as HPProtocol, 236 | root::transcript::{TranscriptProverChannel, TranscriptVerifierChannel}, 237 | }, 238 | }; 239 | use accumulator::{ 240 | group::{Group, Rsa2048}, 241 | AccumulatorWithoutHashToPrime, 242 | }; 243 | use ark_bls12_381::{Bls12_381, G1Projective}; 244 | use merlin::Transcript; 245 | use rand::thread_rng; 246 | use rug::rand::RandState; 247 | use rug::Integer; 248 | use std::cell::RefCell; 249 | 250 | const LARGE_PRIMES: [u64; 4] = [ 251 | 553_525_575_239_331_913, 252 | 12_702_637_924_034_044_211, 253 | 378_373_571_372_703_133, 254 | 8_640_171_141_336_142_787, 255 | ]; 256 | 257 | #[test] 258 | fn test_proof() { 259 | let params = Parameters::from_security_level(128).unwrap(); 260 | let mut rng1 = RandState::new(); 261 | rng1.seed(&Integer::from(13)); 262 | let mut rng2 = thread_rng(); 263 | 264 | let crs = crate::protocols::membership::Protocol::< 265 | Rsa2048, 266 | G1Projective, 267 | HPProtocol, 268 | >::setup(¶ms, &mut rng1, &mut rng2) 269 | .unwrap() 270 | .crs 271 | .crs_root; 272 | let protocol = Protocol::::from_crs(&crs); 273 | 274 | let value = Integer::from(LARGE_PRIMES[0]); 275 | let randomness = Integer::from(5); 276 | let commitment = protocol 277 | .crs 278 | .integer_commitment_parameters 279 | .commit(&value, &randomness) 280 | .unwrap(); 281 | 282 | let accum = 283 | accumulator::Accumulator::::empty(); 284 | let accum = accum.add( 285 | &LARGE_PRIMES 286 | .iter() 287 | .skip(1) 288 | .map(|p| Integer::from(*p)) 289 | .collect::>(), 290 | ); 291 | 292 | let accum = accum.add_with_proof(&[value.clone()]); 293 | let acc = accum.0.value; 294 | let w = accum.1.witness.0.value; 295 | assert_eq!(Rsa2048::exp(&w, &value), acc); 296 | 297 | let proof_transcript = RefCell::new(Transcript::new(b"root")); 298 | let mut verifier_channel = TranscriptVerifierChannel::new(&crs, &proof_transcript); 299 | let statement = Statement { 300 | c_e: commitment, 301 | acc, 302 | }; 303 | protocol 304 | .prove( 305 | &mut verifier_channel, 306 | &mut rng1, 307 | &statement, 308 | &Witness { 309 | e: value, 310 | r: randomness, 311 | w, 312 | }, 313 | ) 314 | .unwrap(); 315 | 316 | let proof = verifier_channel.proof().unwrap(); 317 | let verification_transcript = RefCell::new(Transcript::new(b"root")); 318 | let mut prover_channel = 319 | TranscriptProverChannel::new(&crs, &verification_transcript, &proof); 320 | protocol.verify(&mut prover_channel, &statement).unwrap(); 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /src/protocols/root/transcript.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | channels::ChannelError, 3 | protocols::root::{ 4 | channel::{RootProverChannel, RootVerifierChannel}, 5 | CRSRoot, Message1, Message2, Message3, Proof, 6 | }, 7 | transcript::{TranscriptChannelError, TranscriptProtocolChallenge, TranscriptProtocolInteger}, 8 | utils::ConvertibleUnknownOrderGroup, 9 | }; 10 | use merlin::Transcript; 11 | use rug::Integer; 12 | use std::cell::RefCell; 13 | 14 | pub trait TranscriptProtocolRoot: 15 | TranscriptProtocolInteger + TranscriptProtocolChallenge 16 | { 17 | fn root_domain_sep(&mut self); 18 | } 19 | 20 | impl TranscriptProtocolRoot for Transcript { 21 | fn root_domain_sep(&mut self) { 22 | self.append_message(b"dom-sep", b"root"); 23 | } 24 | } 25 | 26 | pub struct TranscriptVerifierChannel< 27 | 'a, 28 | G: ConvertibleUnknownOrderGroup, 29 | T: TranscriptProtocolRoot, 30 | > { 31 | crs: CRSRoot, 32 | transcript: &'a RefCell, 33 | message1: Option>, 34 | message2: Option>, 35 | message3: Option, 36 | } 37 | 38 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolRoot> 39 | TranscriptVerifierChannel<'a, G, T> 40 | { 41 | pub fn new( 42 | crs: &CRSRoot, 43 | transcript: &'a RefCell, 44 | ) -> TranscriptVerifierChannel<'a, G, T> { 45 | TranscriptVerifierChannel { 46 | crs: crs.clone(), 47 | transcript, 48 | message1: None, 49 | message2: None, 50 | message3: None, 51 | } 52 | } 53 | 54 | pub fn proof(&self) -> Result, TranscriptChannelError> { 55 | if self.message1.is_some() && self.message2.is_some() && self.message3.is_some() { 56 | Ok(Proof { 57 | message1: self.message1.as_ref().unwrap().clone(), 58 | message2: self.message2.as_ref().unwrap().clone(), 59 | message3: self.message3.as_ref().unwrap().clone(), 60 | }) 61 | } else { 62 | Err(TranscriptChannelError::Incomplete) 63 | } 64 | } 65 | } 66 | 67 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolRoot> RootVerifierChannel 68 | for TranscriptVerifierChannel<'a, G, T> 69 | { 70 | fn send_message1(&mut self, message: &Message1) -> Result<(), ChannelError> { 71 | let mut transcript = self.transcript.try_borrow_mut()?; 72 | transcript.root_domain_sep(); 73 | transcript.append_integer_point(b"c_w", &message.c_w); 74 | transcript.append_integer_point(b"c_r", &message.c_r); 75 | self.message1 = Some(message.clone()); 76 | Ok(()) 77 | } 78 | fn send_message2(&mut self, message: &Message2) -> Result<(), ChannelError> { 79 | let mut transcript = self.transcript.try_borrow_mut()?; 80 | transcript.root_domain_sep(); 81 | transcript.append_integer_point(b"alpha1", &message.alpha1); 82 | transcript.append_integer_point(b"alpha2", &message.alpha2); 83 | transcript.append_integer_point(b"alpha3", &message.alpha3); 84 | transcript.append_integer_point(b"alpha4", &message.alpha4); 85 | self.message2 = Some(message.clone()); 86 | Ok(()) 87 | } 88 | fn send_message3(&mut self, message: &Message3) -> Result<(), ChannelError> { 89 | self.message3 = Some(message.clone()); 90 | Ok(()) 91 | } 92 | fn receive_challenge(&mut self) -> Result { 93 | let mut transcript = self.transcript.try_borrow_mut()?; 94 | transcript.root_domain_sep(); 95 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 96 | } 97 | } 98 | 99 | pub struct TranscriptProverChannel< 100 | 'a, 101 | G: ConvertibleUnknownOrderGroup, 102 | T: TranscriptProtocolRoot, 103 | > { 104 | crs: CRSRoot, 105 | transcript: &'a RefCell, 106 | proof: Proof, 107 | } 108 | 109 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolRoot> 110 | TranscriptProverChannel<'a, G, T> 111 | { 112 | pub fn new( 113 | crs: &CRSRoot, 114 | transcript: &'a RefCell, 115 | proof: &Proof, 116 | ) -> TranscriptProverChannel<'a, G, T> { 117 | TranscriptProverChannel { 118 | crs: crs.clone(), 119 | transcript, 120 | proof: proof.clone(), 121 | } 122 | } 123 | } 124 | 125 | impl<'a, G: ConvertibleUnknownOrderGroup, T: TranscriptProtocolRoot> RootProverChannel 126 | for TranscriptProverChannel<'a, G, T> 127 | { 128 | fn receive_message1(&mut self) -> Result, ChannelError> { 129 | let mut transcript = self.transcript.try_borrow_mut()?; 130 | transcript.root_domain_sep(); 131 | transcript.append_integer_point(b"c_w", &self.proof.message1.c_w); 132 | transcript.append_integer_point(b"c_r", &self.proof.message1.c_r); 133 | Ok(self.proof.message1.clone()) 134 | } 135 | fn receive_message2(&mut self) -> Result, ChannelError> { 136 | let mut transcript = self.transcript.try_borrow_mut()?; 137 | transcript.root_domain_sep(); 138 | transcript.append_integer_point(b"alpha1", &self.proof.message2.alpha1); 139 | transcript.append_integer_point(b"alpha2", &self.proof.message2.alpha2); 140 | transcript.append_integer_point(b"alpha3", &self.proof.message2.alpha3); 141 | transcript.append_integer_point(b"alpha4", &self.proof.message2.alpha4); 142 | 143 | Ok(self.proof.message2.clone()) 144 | } 145 | fn receive_message3(&mut self) -> Result { 146 | Ok(self.proof.message3.clone()) 147 | } 148 | fn generate_and_send_challenge(&mut self) -> Result { 149 | let mut transcript = self.transcript.try_borrow_mut()?; 150 | transcript.root_domain_sep(); 151 | Ok(transcript.challenge_scalar(b"c", self.crs.parameters.security_soundness)) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/transcript.rs: -------------------------------------------------------------------------------- 1 | //! Transcripts transform the interactive protocols into non-interactive using 2 | //! the Merlin transcript. 3 | //! 4 | //! Each protocol defines a transcript that defines a domain separator, how to 5 | //! consume each message in the protocol and how to generate challenge scalars. 6 | use crate::{ 7 | protocols::{ 8 | hash_to_prime::transcript::TranscriptProtocolHashToPrime, 9 | modeq::transcript::TranscriptProtocolModEq, root::transcript::TranscriptProtocolRoot, 10 | }, 11 | utils::{ 12 | bigint_to_bytes, 13 | curve::{CurveError, CurvePointProjective}, 14 | integer_to_bytes, ConvertibleUnknownOrderGroup, 15 | }, 16 | }; 17 | use merlin::Transcript; 18 | use rug::integer::Order; 19 | use rug::Integer; 20 | 21 | quick_error! { 22 | #[derive(Debug)] 23 | pub enum TranscriptChannelError { 24 | Incomplete {} 25 | } 26 | } 27 | 28 | pub trait TranscriptProtocolMembershipPrime< 29 | G: ConvertibleUnknownOrderGroup, 30 | P: CurvePointProjective, 31 | >: 32 | TranscriptProtocolRoot + TranscriptProtocolModEq + TranscriptProtocolHashToPrime

33 | { 34 | } 35 | 36 | pub trait TranscriptProtocolChallenge { 37 | fn challenge_scalar(&mut self, label: &'static [u8], length_in_bits: u16) -> Integer; 38 | } 39 | 40 | pub trait TranscriptProtocolInteger { 41 | fn append_integer_scalar(&mut self, label: &'static [u8], scalar: &Integer); 42 | fn append_integer_point(&mut self, label: &'static [u8], point: &G::Elem); 43 | } 44 | 45 | pub trait TranscriptProtocolCurve { 46 | fn append_curve_scalar(&mut self, label: &'static [u8], scalar: &P::ScalarField); 47 | fn append_curve_point(&mut self, label: &'static [u8], point: &P) -> Result<(), CurveError>; 48 | } 49 | 50 | impl TranscriptProtocolInteger for Transcript { 51 | fn append_integer_scalar(&mut self, label: &'static [u8], scalar: &Integer) { 52 | self.append_message(label, &integer_to_bytes(scalar)); 53 | } 54 | 55 | fn append_integer_point(&mut self, label: &'static [u8], point: &G::Elem) { 56 | self.append_message(label, &G::elem_to_bytes(point)); 57 | } 58 | } 59 | 60 | impl TranscriptProtocolCurve

for Transcript { 61 | fn append_curve_scalar(&mut self, label: &'static [u8], scalar: &P::ScalarField) { 62 | self.append_message(label, &bigint_to_bytes::

(&scalar)); 63 | } 64 | 65 | fn append_curve_point(&mut self, label: &'static [u8], point: &P) -> Result<(), CurveError> { 66 | let bytes = point.to_affine_bytes()?; 67 | self.append_message(label, &bytes); 68 | Ok(()) 69 | } 70 | } 71 | 72 | impl TranscriptProtocolChallenge for Transcript { 73 | fn challenge_scalar(&mut self, label: &'static [u8], length_in_bits: u16) -> Integer { 74 | let mut buf = vec![0u8; (length_in_bits / 8) as usize]; 75 | self.challenge_bytes(label, &mut buf); 76 | Integer::from_digits(&buf[..], Order::MsfBe) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/utils/curve.rs: -------------------------------------------------------------------------------- 1 | //! A simple abstraction for curves and fields, to wrap the Zexe and dalek-cryptography curves. 2 | 3 | use rand::{CryptoRng, RngCore}; 4 | use rug::Integer; 5 | 6 | quick_error! { 7 | #[derive(Debug)] 8 | pub enum CurveError { 9 | CannotWrite {} 10 | } 11 | } 12 | 13 | pub trait Field 14 | where 15 | Self: Clone + Sized, 16 | { 17 | fn modulus() -> Integer; 18 | fn size_in_bits() -> usize; 19 | fn to_bits(&self) -> Vec; 20 | fn from_bits(bits: &[bool]) -> Self; 21 | fn add(&self, other: &Self) -> Self; 22 | fn sub(&self, other: &Self) -> Self; 23 | fn neg(&self) -> Self; 24 | fn mul(&self, other: &Self) -> Self; 25 | fn inverse(&self) -> Option; 26 | fn rand(rng: &mut R) -> Self; 27 | } 28 | 29 | pub trait CurvePointProjective 30 | where 31 | Self: Clone + PartialEq, 32 | { 33 | type ScalarField: Field; 34 | 35 | fn mul(&self, s: &Self::ScalarField) -> Self; 36 | fn add(&self, other: &Self) -> Self; 37 | 38 | fn to_affine_bytes(&self) -> Result, CurveError>; 39 | fn rand(rng: &mut R) -> Self; 40 | } 41 | 42 | #[cfg(feature = "arkworks")] 43 | mod arkworks { 44 | use super::{CurvePointProjective, Field}; 45 | use crate::utils::{bits_big_endian_to_bytes_big_endian, bytes_to_integer, curve::CurveError}; 46 | use ark_ec::ProjectiveCurve; 47 | use ark_ff::{BigInteger, FpParameters, PrimeField}; 48 | use ark_serialize::{CanonicalSerialize, SerializationError}; 49 | 50 | use rand::{CryptoRng, RngCore}; 51 | use rug::Integer; 52 | 53 | impl From for CurveError { 54 | fn from(_: SerializationError) -> Self { 55 | CurveError::CannotWrite 56 | } 57 | } 58 | 59 | impl Field for F { 60 | fn modulus() -> Integer { 61 | let repr = F::Params::MODULUS; 62 | let bits = repr.to_bits_be(); 63 | let bytes = bits_big_endian_to_bytes_big_endian(&bits); 64 | bytes_to_integer(&bytes) 65 | } 66 | fn size_in_bits() -> usize { 67 | F::size_in_bits() 68 | } 69 | fn to_bits(&self) -> Vec { 70 | self.into_repr().to_bits_be() 71 | } 72 | fn from_bits(bits: &[bool]) -> Self { 73 | F::from(F::BigInt::from_bits_be(bits)) 74 | } 75 | fn add(&self, other: &Self) -> Self { 76 | F::add(*self, *other) 77 | } 78 | fn sub(&self, other: &Self) -> Self { 79 | F::sub(*self, *other) 80 | } 81 | fn neg(&self) -> Self { 82 | F::neg(*self) 83 | } 84 | fn mul(&self, other: &Self) -> Self { 85 | F::mul(*self, *other) 86 | } 87 | fn inverse(&self) -> Option { 88 | F::inverse(self) 89 | } 90 | fn rand(rng: &mut R) -> Self { 91 | F::rand(rng) 92 | } 93 | } 94 | 95 | impl CurvePointProjective for P { 96 | type ScalarField = P::ScalarField; 97 | 98 | fn mul(&self, s: &Self::ScalarField) -> Self { 99 | P::mul(*self, s.into_repr()) 100 | } 101 | 102 | fn add(&self, other: &Self) -> Self { 103 | P::add(*self, *other) 104 | } 105 | 106 | fn to_affine_bytes(&self) -> Result, CurveError> { 107 | let affine = self.into_affine(); 108 | let mut bytes = vec![]; 109 | affine.serialize(&mut bytes)?; 110 | Ok(bytes) 111 | } 112 | 113 | fn rand(rng: &mut R) -> Self { 114 | P::rand(rng) 115 | } 116 | } 117 | } 118 | 119 | #[cfg(feature = "dalek")] 120 | mod dalek { 121 | use super::{CurvePointProjective, Field}; 122 | use crate::utils::{ 123 | bigint_to_integer, bits_big_endian_to_bytes_big_endian, 124 | bytes_big_endian_to_bits_big_endian, curve::CurveError, 125 | }; 126 | use curve25519_dalek::{constants::BASEPOINT_ORDER, ristretto::RistrettoPoint, scalar::Scalar}; 127 | use rand::{CryptoRng, RngCore}; 128 | use rug::Integer; 129 | 130 | impl Field for Scalar { 131 | fn modulus() -> Integer { 132 | bigint_to_integer::(&BASEPOINT_ORDER) 133 | } 134 | 135 | fn size_in_bits() -> usize { 136 | 252 137 | } 138 | fn to_bits(&self) -> Vec { 139 | let little_endian_bytes = self.to_bytes(); 140 | let big_endian_bytes = little_endian_bytes 141 | .iter() 142 | .copied() 143 | .rev() 144 | .collect::>(); 145 | bytes_big_endian_to_bits_big_endian(&big_endian_bytes) 146 | } 147 | fn from_bits(bits: &[bool]) -> Self { 148 | let big_endian_bytes = bits_big_endian_to_bytes_big_endian(&bits); 149 | let little_endian_bytes = big_endian_bytes 150 | .to_vec() 151 | .into_iter() 152 | .rev() 153 | .collect::>(); 154 | let little_endian_bytes_length = little_endian_bytes.len(); 155 | let little_endian_bytes_padded = if little_endian_bytes_length < 32 { 156 | [ 157 | little_endian_bytes, 158 | vec![0u8; 32 - little_endian_bytes_length], 159 | ] 160 | .concat() 161 | } else { 162 | little_endian_bytes 163 | }; 164 | let mut little_endian_fixed_bytes = [0u8; 32]; 165 | little_endian_fixed_bytes[..].copy_from_slice(little_endian_bytes_padded.as_ref()); 166 | Scalar::from_bits(little_endian_fixed_bytes) 167 | } 168 | fn add(&self, other: &Self) -> Self { 169 | self + other 170 | } 171 | fn sub(&self, other: &Self) -> Self { 172 | self - other 173 | } 174 | fn neg(&self) -> Self { 175 | -self 176 | } 177 | fn mul(&self, other: &Self) -> Self { 178 | self * other 179 | } 180 | fn inverse(&self) -> Option { 181 | if *self == Scalar::zero() { 182 | None 183 | } else { 184 | Some(self.invert()) 185 | } 186 | } 187 | fn rand(rng: &mut R) -> Self { 188 | Scalar::random(rng) 189 | } 190 | } 191 | 192 | impl CurvePointProjective for RistrettoPoint { 193 | type ScalarField = Scalar; 194 | 195 | fn mul(&self, s: &Self::ScalarField) -> Self { 196 | self * s 197 | } 198 | fn add(&self, other: &Self) -> Self { 199 | self + other 200 | } 201 | 202 | fn to_affine_bytes(&self) -> Result, CurveError> { 203 | Ok(self.compress().to_bytes()[..].to_vec()) 204 | } 205 | fn rand(rng: &mut R) -> Self { 206 | RistrettoPoint::random(rng) 207 | } 208 | } 209 | 210 | #[cfg(test)] 211 | mod test { 212 | use super::Field; 213 | use curve25519_dalek::scalar::Scalar; 214 | #[test] 215 | fn test_to_from_bits() { 216 | let s = Scalar::from(10 as u64); 217 | let bits = ::to_bits(&s); 218 | let s2 = ::from_bits(&bits); 219 | assert_eq!(s, s2); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | use accumulator::group::{ElemToBytes, UnknownOrderGroup}; 2 | use rug::integer::Order; 3 | use rug::rand::MutRandState; 4 | use rug::Integer; 5 | 6 | pub mod curve; 7 | use curve::{CurvePointProjective, Field}; 8 | 9 | pub trait ConvertibleUnknownOrderGroup: UnknownOrderGroup + ElemToBytes {} 10 | impl ConvertibleUnknownOrderGroup for T {} 11 | 12 | pub fn random_between(rng: &mut R, min: &Integer, max: &Integer) -> Integer { 13 | min + Integer::from(max - min).random_below(rng) 14 | } 15 | 16 | pub fn random_symmetric_range(rng: &mut R, max: &Integer) -> Integer { 17 | Integer::from(-max) + Integer::from(2 * max).random_below(rng) 18 | } 19 | 20 | pub fn bytes_big_endian_to_bits_big_endian(bytes: &[u8]) -> Vec { 21 | let mut bits = vec![]; 22 | for b in bytes { 23 | let mut p = 1 << 7; 24 | for _ in 0..8 { 25 | bits.push(b & p == p); 26 | p /= 2; 27 | } 28 | } 29 | bits 30 | } 31 | 32 | pub fn bits_big_endian_to_bytes_big_endian(bits: &[bool]) -> Vec { 33 | let byte_length = (bits.len() + 7) / 8; 34 | let mut bytes = vec![]; 35 | for b in 0..byte_length { 36 | let mut byte = 0 as u8; 37 | for i in 0..8 { 38 | byte |= (bits[8 * b + i] as u8) << (7 - i); 39 | } 40 | bytes.push(byte); 41 | } 42 | bytes 43 | } 44 | 45 | pub fn integer_to_bytes(num: &Integer) -> Vec { 46 | let digits = num.significant_digits::(); 47 | let mut bytes = vec![0u8; digits]; 48 | num.write_digits(&mut bytes, Order::MsfBe); 49 | bytes 50 | } 51 | 52 | pub fn integer_to_bigint(num: &Integer) -> P::ScalarField { 53 | let bytes = integer_to_bytes(num); 54 | let bits = bytes_big_endian_to_bits_big_endian(&bytes); 55 | P::ScalarField::from_bits(&bits) 56 | } 57 | 58 | pub fn integer_mod_q(num: &Integer) -> Result { 59 | let q = P::ScalarField::modulus(); 60 | num.clone().pow_mod(&Integer::from(1), &q) 61 | } 62 | 63 | pub fn integer_to_bigint_mod_q( 64 | num: &Integer, 65 | ) -> Result { 66 | let bytes = integer_to_bytes(&integer_mod_q::

(num)?); 67 | let bits = bytes_big_endian_to_bits_big_endian(&bytes); 68 | Ok(P::ScalarField::from_bits(&bits)) 69 | } 70 | 71 | pub fn bigint_to_bytes(num: &P::ScalarField) -> Vec { 72 | let bits = num.to_bits(); 73 | bits_big_endian_to_bytes_big_endian(&bits) 74 | } 75 | 76 | pub fn bytes_to_integer(bytes: &[u8]) -> Integer { 77 | let mut big = Integer::from(0); 78 | big.assign_digits(bytes, Order::MsfBe); 79 | big 80 | } 81 | 82 | pub fn bigint_to_integer(num: &P::ScalarField) -> Integer { 83 | let bytes = bigint_to_bytes::

(num); 84 | let mut big = Integer::from(0); 85 | big.assign_digits(&bytes, Order::MsfBe); 86 | big 87 | } 88 | 89 | pub fn log2(x: usize) -> u32 { 90 | if x <= 1 { 91 | return 0; 92 | } 93 | 94 | let n = x.leading_zeros(); 95 | core::mem::size_of::() as u32 * 8 - n 96 | } 97 | 98 | #[cfg(all(test, feature = "arkworks"))] 99 | mod test { 100 | use crate::utils::{bigint_to_integer, integer_to_bigint}; 101 | use ark_bls12_381::G1Projective; 102 | use rug::Integer; 103 | 104 | #[test] 105 | fn test_back_and_forth() { 106 | let int = Integer::from(2_493_823); 107 | let big = integer_to_bigint::(&int); 108 | let int2 = bigint_to_integer::(&big); 109 | assert_eq!(int, int2); 110 | } 111 | } 112 | --------------------------------------------------------------------------------