diff --git a/Cargo.lock b/Cargo.lock index 39ce56f..7afccda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,6 +57,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "ansi_term" version = "0.12.1" @@ -66,6 +72,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "arrayref" version = "0.3.9" @@ -94,7 +106,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -258,6 +270,27 @@ dependencies = [ "rustc-serialize", ] +[[package]] +name = "bulletproofs" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "012e2e5f88332083bd4235d445ae78081c00b2558443821a9ca5adfe1070073d" +dependencies = [ + "byteorder", + "clear_on_drop", + "curve25519-dalek 4.1.3", + "digest 0.10.7", + "group", + "merlin", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "serde_derive", + "sha3 0.10.8", + "subtle", + "thiserror", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -294,7 +327,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9daec6140ab4dcd38c3dd57e580b59a621172a526ac79f1527af760a55afeafd" dependencies = [ - "clap", + "clap 2.34.0", "log", "proc-macro2", "quote", @@ -326,6 +359,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half 2.4.1", +] + [[package]] name = "cipher" version = "0.2.5" @@ -350,6 +410,31 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clap" +version = "4.5.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + [[package]] name = "clear_on_drop" version = "0.2.5" @@ -404,8 +489,8 @@ checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", - "clap", - "criterion-plot", + "clap 2.34.0", + "criterion-plot 0.4.5", "csv", "itertools", "lazy_static 1.5.0", @@ -422,6 +507,32 @@ dependencies = [ "walkdir", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap 4.5.28", + "criterion-plot 0.5.0", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + [[package]] name = "criterion-plot" version = "0.4.5" @@ -432,6 +543,16 @@ dependencies = [ "itertools", ] +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -497,9 +618,9 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array 0.14.7", "subtle", @@ -553,6 +674,36 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "group", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "der" version = "0.7.9" @@ -846,6 +997,12 @@ dependencies = [ "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "foreign-types" version = "0.3.2" @@ -950,6 +1107,16 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -959,6 +1126,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -991,7 +1164,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", "digest 0.9.0", ] @@ -1024,6 +1197,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "is-terminal" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1178,13 +1362,13 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "merlin" -version = "1.3.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ "byteorder", "keccak", - "rand_core 0.4.2", + "rand_core 0.6.4", "zeroize", ] @@ -1730,6 +1914,15 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.40" @@ -1806,6 +1999,12 @@ dependencies = [ "cc", ] +[[package]] +name = "semver" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" + [[package]] name = "serde" version = "1.0.195" @@ -1821,7 +2020,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half", + "half 1.8.3", "serde", ] @@ -1919,6 +2118,16 @@ dependencies = [ "opaque-debug 0.2.3", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1998,9 +2207,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -2058,6 +2267,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -2299,11 +2528,12 @@ name = "wedpr_ffi_c_zkp" version = "1.0.0" dependencies = [ "cbindgen", - "curve25519-dalek 1.2.6", + "curve25519-dalek 4.1.3", "libc", "wedpr_ffi_common 1.1.0", "wedpr_ffi_macros 1.1.0", "wedpr_l_crypto_zkp_discrete_logarithm_proof", + "wedpr_l_crypto_zkp_range_proof", "wedpr_l_crypto_zkp_utils 1.3.0", "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2398,6 +2628,20 @@ dependencies = [ "wedpr_third_party_fisco_bcos_java_sdk", ] +[[package]] +name = "wedpr_ffi_java_zkp" +version = "0.1.0" +dependencies = [ + "curve25519-dalek 4.1.3", + "jni", + "wedpr_ffi_common 1.1.0", + "wedpr_ffi_macros 1.1.0", + "wedpr_l_crypto_zkp_discrete_logarithm_proof", + "wedpr_l_crypto_zkp_range_proof", + "wedpr_l_crypto_zkp_utils 1.3.0", + "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wedpr_ffi_macros" version = "1.1.0" @@ -2408,25 +2652,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25c251c82cdf6abfb141bae92553c4d7e1a60baa005daffe19bb991d573c863b" -[[package]] -name = "wedpr_l_bulletproofs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a40bf29b5f1ee2526389295af5f65b0b273823dc4814782a7d54bfa9c0221e" -dependencies = [ - "byteorder", - "clear_on_drop", - "curve25519-dalek 1.2.6", - "digest 0.8.1", - "failure", - "merlin", - "rand 0.6.5", - "serde", - "serde_derive", - "sha3 0.8.2", - "subtle", -] - [[package]] name = "wedpr_l_common_coder_base64" version = "1.1.0" @@ -2637,7 +2862,7 @@ dependencies = [ name = "wedpr_l_crypto_ot_base_ot" version = "0.2.0" dependencies = [ - "criterion", + "criterion 0.3.6", "curve25519-dalek 1.2.6", "lazy_static 1.5.0", "rand 0.6.5", @@ -2664,7 +2889,7 @@ dependencies = [ name = "wedpr_l_crypto_signature_secp256k1" version = "1.1.0" dependencies = [ - "criterion", + "criterion 0.3.6", "lazy_static 1.5.0", "secp256k1", "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2712,10 +2937,10 @@ dependencies = [ name = "wedpr_l_crypto_zkp_discrete_logarithm_proof" version = "1.3.0" dependencies = [ - "criterion", - "curve25519-dalek 1.2.6", + "criterion 0.5.1", + "curve25519-dalek 4.1.3", "hex", - "rand 0.6.5", + "rand 0.8.5", "wedpr_l_crypto_zkp_utils 1.3.0", "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "wedpr_l_protos 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2726,10 +2951,12 @@ dependencies = [ name = "wedpr_l_crypto_zkp_range_proof" version = "1.2.0" dependencies = [ - "curve25519-dalek 1.2.6", + "bulletproofs", + "criterion 0.5.1", + "curve25519-dalek 4.1.3", + "hex", "merlin", - "wedpr_l_bulletproofs", - "wedpr_l_crypto_zkp_utils 1.2.0", + "wedpr_l_crypto_zkp_utils 1.3.0", "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2754,12 +2981,11 @@ dependencies = [ name = "wedpr_l_crypto_zkp_utils" version = "1.3.0" dependencies = [ - "curve25519-dalek 1.2.6", + "curve25519-dalek 4.1.3", "lazy_static 1.5.0", - "rand 0.6.5", - "rand_core 0.5.1", + "rand 0.8.5", "serde", - "sha3 0.8.2", + "sha3 0.10.8", "wedpr_l_crypto_hash_keccak256 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "wedpr_l_utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3024,3 +3250,16 @@ dependencies = [ "quote", "syn 2.0.87", ] + +[[package]] +name = "zktransfer" +version = "0.1.0" +dependencies = [ + "criterion 0.5.1", + "curve25519-dalek 4.1.3", + "hex", + "wedpr_l_crypto_zkp_discrete_logarithm_proof", + "wedpr_l_crypto_zkp_range_proof", + "wedpr_l_crypto_zkp_utils 1.3.0", + "wedpr_l_macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] diff --git a/Cargo.toml b/Cargo.toml index 942011b..b00fcce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ members = [ "crypto/vrf/curve25519", "crypto/vrf/secp256k1", "crypto/zkp/discrete_logarithm_proof", "crypto/zkp/range_proof", - "crypto/zkp/utils", + "crypto/zkp/utils", "crypto/zkp/zktransfer", "ffi/ffi_c/ffi_c_common", "ffi/ffi_c/ffi_c_crypto", "ffi/ffi_c/ffi_c_crypto_binary", @@ -29,7 +29,7 @@ members = [ "ffi/ffi_common", "ffi/ffi_java/ffi_java_crypto", "ffi/ffi_java/ffi_java_crypto_binary", - "ffi/ffi_java/ffi_java_fisco_bcos_sdk", + "ffi/ffi_java/ffi_java_fisco_bcos_sdk", "ffi/ffi_java/ffi_java_zkp", "ffi/ffi_macros", "protos", "third_party/fisco_bcos", diff --git a/crypto/zkp/discrete_logarithm_proof/Cargo.toml b/crypto/zkp/discrete_logarithm_proof/Cargo.toml index eeaf6e6..c55bb21 100644 --- a/crypto/zkp/discrete_logarithm_proof/Cargo.toml +++ b/crypto/zkp/discrete_logarithm_proof/Cargo.toml @@ -10,15 +10,15 @@ description = "Library of WeDPR shared zkp Function implement discrete logarithm [dependencies] hex = "0.4.2" -curve25519-dalek = { version = "1.0", features = [ "serde" ] } +curve25519-dalek = { version = "4.1", features = [ "serde" ] } wedpr_l_crypto_zkp_utils = {version = "1.3.0", path = "../utils/"} wedpr_l_macros = "1.0.0" wedpr_l_protos = "1.2.0" wedpr_l_utils = "1.1.0" -rand = "0.6" +rand = "0.8.5" [dev-dependencies] -criterion = "0.3" +criterion = "0.5" [[bench]] name = "dlp" diff --git a/crypto/zkp/discrete_logarithm_proof/benches/dlp.rs b/crypto/zkp/discrete_logarithm_proof/benches/dlp.rs index a338995..cbf1ddf 100644 --- a/crypto/zkp/discrete_logarithm_proof/benches/dlp.rs +++ b/crypto/zkp/discrete_logarithm_proof/benches/dlp.rs @@ -168,7 +168,7 @@ fn create_point_mul_helper(c: &mut Criterion) { fn create_point_mul_1_helper(c: &mut Criterion) { let label = format!("create_point_mul_1_helper",); - let scalar_1 = Scalar::one(); + let scalar_1 = Scalar::from(1u8); let value_basepoint = *BASEPOINT_G1; c.bench_function(&label, move |b| b.iter(|| scalar_1 * value_basepoint)); } diff --git a/crypto/zkp/discrete_logarithm_proof/src/lib.rs b/crypto/zkp/discrete_logarithm_proof/src/lib.rs index ef38ef5..f0c51e0 100644 --- a/crypto/zkp/discrete_logarithm_proof/src/lib.rs +++ b/crypto/zkp/discrete_logarithm_proof/src/lib.rs @@ -8,8 +8,7 @@ use curve25519_dalek::{ }; use rand::Rng; use wedpr_l_crypto_zkp_utils::{ - get_random_scalar, hash_to_scalar, point_to_bytes, ArithmeticProof, - BalanceProof, EqualityProof, FormatProof, KnowledgeProof, + get_random_scalar, hash_to_scalar, point_to_bytes, ArithmeticProof, BalanceProof, EqualityProof, FormatProof, KnowledgeProof, ReceiverRelationshipProofFinalPublic, ReceiverRelationshipProofSetupPrivate, ReceiverRelationshipProofSetupPublic, RelationshipProof, SenderRelationshipProofFinalPublic, SenderRelationshipProofSetupPrivate, SenderRelationshipProofSetupPublic, ValueEqualityProof }; use wedpr_l_utils::error::WedprError; @@ -21,6 +20,68 @@ pub fn aggregate_ristretto_point( Ok(point_sum + point_share) } +/// Proves a value with a commitments satisfying an equality relationship, i.e. +/// the value embedded in c_point = c_value * c_basepoint + c_blinding * +/// blinding_basepoint. It returns a proof for the above equality relationship. +pub fn prove_value_equality_relationship_proof( + c_value: u64, + c_blinding: &Scalar, + c_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> ValueEqualityProof { + let blinding_a = get_random_scalar(); + let blinding_b = get_random_scalar(); + let t1 = blinding_a * c_basepoint; + let t2 = blinding_a * c_basepoint + blinding_b * blinding_basepoint; + let c_value_scalar = Scalar::from(c_value); + let c_point = + c_value_scalar * c_basepoint + c_blinding * blinding_basepoint; + let mut hash_vec = Vec::new(); + hash_vec.append(&mut point_to_bytes(&t1)); + hash_vec.append(&mut point_to_bytes(&t2)); + hash_vec.append(&mut point_to_bytes(&c_point)); + hash_vec.append(&mut c_value.to_be_bytes().to_vec()); + hash_vec.append(&mut point_to_bytes(c_basepoint)); + hash_vec.append(&mut point_to_bytes(blinding_basepoint)); + let check = hash_to_scalar(&hash_vec); + let m1 = blinding_a - (check * c_value_scalar); + let m2 = blinding_b - (check * c_blinding); + return ValueEqualityProof { check, m1, m2 }; +} + +/// Verifies a commitment satisfying an equality relationship, i.e. +/// the value embedded in c_point = c_value * c_basepoint + c_blinding * +/// blinding_basepoint. +/// It returns a proof for the above equality relationship. +pub fn verify_value_equality_relationship_proof( + c_value: u64, + c_point: &RistrettoPoint, + proof: &ValueEqualityProof, + c_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> Result { + let c_value_scalar = Scalar::from(c_value); + + let t1 = + c_value_scalar * proof.check * c_basepoint + proof.m1 * c_basepoint; + let t2 = proof.check * c_point + + proof.m1 * c_basepoint + + proof.m2 * blinding_basepoint; + let mut hash_vec = Vec::new(); + hash_vec.append(&mut point_to_bytes(&t1)); + hash_vec.append(&mut point_to_bytes(&t2)); + hash_vec.append(&mut point_to_bytes(&c_point)); + hash_vec.append(&mut c_value.to_be_bytes().to_vec()); + hash_vec.append(&mut point_to_bytes(c_basepoint)); + hash_vec.append(&mut point_to_bytes(blinding_basepoint)); + let check = hash_to_scalar(&hash_vec); + + if check == proof.check { + return Ok(true); + } + Ok(false) +} + /// Proves three commitments satisfying either or equality relationships, i.e. /// the values embedded in c1_point = c1_value * c_basepoint + c1_blinding * /// blinding_basepoint c2_point = c2_value * c_basepoint + c2_blinding * @@ -279,8 +340,8 @@ pub fn verify_knowledge_proof_in_batch( } let mut t1_sum_expected: RistrettoPoint = Default::default(); let mut c1_c_expected: RistrettoPoint = Default::default(); - let mut m1_expected: Scalar = Scalar::zero(); - let mut m2_expected: Scalar = Scalar::zero(); + let mut m1_expected: Scalar = Scalar::from(0u8); + let mut m2_expected: Scalar = Scalar::from(0u8); for i in 0..c_point_list.len() { // 8 bit random scalar @@ -418,8 +479,8 @@ pub fn verify_format_proof_in_batch( let mut t2_sum_expected: RistrettoPoint = Default::default(); let mut c1_c_expected: RistrettoPoint = Default::default(); let mut c2_c_expected: RistrettoPoint = Default::default(); - let mut m1_expected: Scalar = Scalar::zero(); - let mut m2_expected: Scalar = Scalar::zero(); + let mut m1_expected: Scalar = Scalar::from(0u8); + let mut m2_expected: Scalar = Scalar::from(0u8); for i in 0..c1_point_list.len() { // 8 bit random scalar @@ -461,6 +522,249 @@ pub fn verify_format_proof_in_batch( Ok(false) } +pub fn sender_prove_multi_sum_relationship_setup( + input_value: u64, + input_blinding: &Scalar, + value_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> ( + SenderRelationshipProofSetupPrivate, + SenderRelationshipProofSetupPublic, +) { + let blinding_a = get_random_scalar(); + let blinding_b = get_random_scalar(); + let t_commit = + blinding_a * value_basepoint + blinding_b * blinding_basepoint; + let a_commit = blinding_a * value_basepoint; + let commit = Scalar::from(input_value) * value_basepoint + + input_blinding * blinding_basepoint; + return ( + SenderRelationshipProofSetupPrivate { + blinding_a: blinding_a, + blinding_b: blinding_b, + }, + SenderRelationshipProofSetupPublic { + t_commit: t_commit, + a_commit: a_commit, + commitment: commit, + }, + ); +} + +pub fn sender_prove_multi_sum_relationship_final(input_value: u64, input_blinding: &Scalar, proof_secret: &SenderRelationshipProofSetupPrivate, check: &Scalar) -> SenderRelationshipProofFinalPublic { + let m = proof_secret.blinding_a - check * Scalar::from(input_value); + let n = proof_secret.blinding_b - check * input_blinding; + return SenderRelationshipProofFinalPublic { + m: m, + n: n, + }; +} + +pub fn receiver_prove_multi_sum_relationship_setup( + output_value: u64, + output_blinding: &Scalar, + value_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> ( + ReceiverRelationshipProofSetupPrivate, + ReceiverRelationshipProofSetupPublic, +) { + let blinding_f = get_random_scalar(); + let f_commit = blinding_f * blinding_basepoint; + let commit = Scalar::from(output_value) * value_basepoint + + output_blinding * blinding_basepoint; + return ( + ReceiverRelationshipProofSetupPrivate { + f_blinding: blinding_f, + }, + ReceiverRelationshipProofSetupPublic { + f_commit: f_commit, + commitment: commit, + }, + ); +} + +pub fn receiver_prove_multi_sum_relationship_final(output_blinding: &Scalar, proof_secret: &ReceiverRelationshipProofSetupPrivate, check: &Scalar) -> ReceiverRelationshipProofFinalPublic { + let t_commit_share = proof_secret.f_blinding - check * output_blinding; + return ReceiverRelationshipProofFinalPublic { + t_commit_share: t_commit_share, + }; +} + +pub fn coordinator_prove_multi_sum_relationship_setup( + sender_setup_lists: &[SenderRelationshipProofSetupPublic], + receiver_setup_lists: &[ReceiverRelationshipProofSetupPublic], + value_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> Scalar { + let mut hash_vec = Vec::new(); + hash_vec.append(&mut point_to_bytes(value_basepoint)); + hash_vec.append(&mut point_to_bytes(blinding_basepoint)); + let mut a_sum_commit = RistrettoPoint::default(); + let mut f_sum_commit = RistrettoPoint::default(); + for sender_setup in sender_setup_lists.iter() { + a_sum_commit += sender_setup.a_commit; + hash_vec.append(&mut point_to_bytes(&sender_setup.commitment)); + } + for receiver_setup in receiver_setup_lists.iter() { + f_sum_commit += receiver_setup.f_commit; + hash_vec.append(&mut point_to_bytes(&receiver_setup.commitment)); + } + for sender_setup in sender_setup_lists.iter() { + hash_vec.append(&mut point_to_bytes(&sender_setup.t_commit)); + } + let t_commit = a_sum_commit + f_sum_commit; + hash_vec.append(&mut point_to_bytes(&t_commit)); + return hash_to_scalar(&hash_vec); +} + +pub fn coordinator_prove_multi_sum_relationship_final(check: &Scalar, sender_proofs: &[SenderRelationshipProofFinalPublic], receiver_proofs: &[ReceiverRelationshipProofFinalPublic]) -> RelationshipProof { + let mut left_commit = Scalar::from(0u64); + let mut m_list = Vec::new(); + let mut n_list = Vec::new(); + for i in 0..receiver_proofs.len() + { + left_commit += receiver_proofs[i].t_commit_share; + } + + for i in 0..sender_proofs.len() + { + m_list.push(sender_proofs[i].m); + n_list.push(sender_proofs[i].n); + } + + return RelationshipProof { + check: *check, + m_list: m_list, + n_list: n_list, + left_commit: left_commit, + }; +} + +pub fn prove_multi_sum_relationship( + input_value_list: &[u64], + input_blinding_list: &[Scalar], + output_value_list: &[u64], + output_blinding_list: &[Scalar], + value_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> RelationshipProof { + if input_value_list.len() != input_blinding_list.len() + || output_value_list.len() != output_blinding_list.len() + { + return RelationshipProof::default(); + } + let mut hash_vec = Vec::new(); + hash_vec.append(&mut point_to_bytes(value_basepoint)); + hash_vec.append(&mut point_to_bytes(blinding_basepoint)); + + let mut m_list = Vec::new(); + let mut n_list = Vec::new(); + + let mut blinding_a_list = Vec::new(); + let mut blinding_b_list = Vec::new(); + let blinding_f = get_random_scalar(); + + let mut input_t_point_list = Vec::new(); + let mut blinding_a_sum = Scalar::from(0u64); + + // TODO: add commitment for hasher + for i in 0..input_value_list.len() { + let blinding_a_i = get_random_scalar(); + let blinding_b_i = get_random_scalar(); + blinding_a_list.push(blinding_a_i); + blinding_b_list.push(blinding_b_i); + + let point_t_i = + blinding_a_i * value_basepoint + blinding_b_i * blinding_basepoint; + input_t_point_list.push(point_t_i); + blinding_a_sum += blinding_a_i; + let input_commitment_i = Scalar::from(input_value_list[i]) + * value_basepoint + + input_blinding_list[i] * blinding_basepoint; + hash_vec.append(&mut point_to_bytes(&input_commitment_i)); + } + + for i in 0..output_value_list.len() { + let output_commitment_i = Scalar::from(output_value_list[i]) + * value_basepoint + + output_blinding_list[i] * blinding_basepoint; + hash_vec.append(&mut point_to_bytes(&output_commitment_i)); + } + + let t_sum_commit = + blinding_a_sum * value_basepoint + blinding_f * blinding_basepoint; + + for point in input_t_point_list.iter() { + hash_vec.append(&mut point_to_bytes(point)); + } + hash_vec.append(&mut point_to_bytes(&t_sum_commit)); + + let check = hash_to_scalar(&hash_vec); + let mut left_blinding_sum = Scalar::from(0u64); + + for i in 0..input_value_list.len() { + let mi = blinding_a_list[i] - check * Scalar::from(input_value_list[i]); + let ni = blinding_b_list[i] - check * input_blinding_list[i]; + m_list.push(mi); + n_list.push(ni); + } + for i in 0..output_blinding_list.len() { + left_blinding_sum += output_blinding_list[i]; + } + let left_commit = blinding_f - check * left_blinding_sum; + + return RelationshipProof { + check: check, + m_list: m_list, + n_list: n_list, + left_commit: left_commit, + }; +} + +pub fn verify_multi_sum_relationship( + input_commitments: &[RistrettoPoint], + output_commitments: &[RistrettoPoint], + proof: &RelationshipProof, + value_basepoint: &RistrettoPoint, + blinding_basepoint: &RistrettoPoint, +) -> Result { + if proof.m_list.len() != input_commitments.len() + || proof.n_list.len() != input_commitments.len() + { + return Ok(false); + } + + let mut hash_vec = Vec::new(); + hash_vec.append(&mut point_to_bytes(value_basepoint)); + hash_vec.append(&mut point_to_bytes(blinding_basepoint)); + + for point in input_commitments.iter() { + hash_vec.append(&mut point_to_bytes(point)); + } + for point in output_commitments.iter() { + hash_vec.append(&mut point_to_bytes(point)); + } + + let mut m_sum = Scalar::from(0u64); + for i in 0..input_commitments.len() { + m_sum += proof.m_list[i]; + let point_t_i = proof.m_list[i] * value_basepoint + + proof.n_list[i] * blinding_basepoint + + proof.check * input_commitments[i]; + hash_vec.append(&mut point_to_bytes(&point_t_i)); + } + let mut output_sum_commitment = RistrettoPoint::default(); + for point in output_commitments.iter() { + output_sum_commitment += point; + } + let t_sum_commit = m_sum * value_basepoint + + proof.left_commit * blinding_basepoint + + proof.check * output_sum_commitment; + hash_vec.append(&mut point_to_bytes(&t_sum_commit)); + let check = hash_to_scalar(&hash_vec); + return Ok(check == proof.check); +} /// Proves three commitments satisfying a sum relationship, i.e. /// the values embedded in them satisfying c1_value + c2_value = c3_value. /// c3_value is not in the argument list, and will be directly computed from @@ -606,11 +910,11 @@ pub fn verify_sum_relationship_in_batch( let mut c1_c_expected: RistrettoPoint = Default::default(); let mut c2_c_expected: RistrettoPoint = Default::default(); let mut c3_c_expected: RistrettoPoint = Default::default(); - let mut m1_expected: Scalar = Scalar::zero(); - let mut m2_expected: Scalar = Scalar::zero(); - let mut m3_expected: Scalar = Scalar::zero(); - let mut m4_expected: Scalar = Scalar::zero(); - let mut m5_expected: Scalar = Scalar::zero(); + let mut m1_expected: Scalar = Scalar::from(0u8); + let mut m2_expected: Scalar = Scalar::from(0u8); + let mut m3_expected: Scalar = Scalar::from(0u8); + let mut m4_expected: Scalar = Scalar::from(0u8); + let mut m5_expected: Scalar = Scalar::from(0u8); for i in 0..c1_point_list.len() { // 8 bit random scalar let random_scalar = get_random_u8(); @@ -832,12 +1136,12 @@ pub fn verify_product_relationship_in_batch( let mut t3_c1_c_expected: RistrettoPoint = Default::default(); let mut t3_c2_c_expected: RistrettoPoint = Default::default(); let mut t3_c3_c_expected: RistrettoPoint = Default::default(); - let mut m1_expected: Scalar = Scalar::zero(); - let mut m1_m3_expected: Scalar = Scalar::zero(); - let mut m2_expected: Scalar = Scalar::zero(); - let mut m3_expected: Scalar = Scalar::zero(); - let mut m4_expected: Scalar = Scalar::zero(); - let mut m5_expected: Scalar = Scalar::zero(); + let mut m1_expected: Scalar = Scalar::from(0u8); + let mut m1_m3_expected: Scalar = Scalar::from(0u8); + let mut m2_expected: Scalar = Scalar::from(0u8); + let mut m3_expected: Scalar = Scalar::from(0u8); + let mut m4_expected: Scalar = Scalar::from(0u8); + let mut m5_expected: Scalar = Scalar::from(0u8); for i in 0..c1_point_list.len() { // 8 bit random scalar let random_scalar = get_random_u8(); @@ -988,7 +1292,7 @@ pub fn verify_equality_relationship_proof_in_batch( let mut t2_sum_expected: RistrettoPoint = Default::default(); let mut c1_c_expected: RistrettoPoint = Default::default(); let mut c2_c_expected: RistrettoPoint = Default::default(); - let mut m1_expected: Scalar = Scalar::zero(); + let mut m1_expected: Scalar = Scalar::from(0u8); for i in 0..c1_point_list.len() { // 8 bit random scalar let random_scalar = get_random_u8(); @@ -1047,7 +1351,7 @@ pub fn get_random_u8() -> u8 { mod tests { use super::*; use wedpr_l_crypto_zkp_utils::{ - get_random_u32, Serialize, BASEPOINT_G1, BASEPOINT_G2, + get_random_u32, Deserialize, Serialize, BASEPOINT_G1, BASEPOINT_G2 }; use wedpr_l_macros::wedpr_println; @@ -1070,11 +1374,10 @@ mod tests { &[Scalar::from(c2_value), c2_blinding], &[c_basepoint, blinding_basepoint], ); - let c3_point = - RistrettoPoint::multiscalar_mul(&[Scalar::zero(), c3_blinding], &[ - c_basepoint, - blinding_basepoint, - ]); + let c3_point = RistrettoPoint::multiscalar_mul( + &[Scalar::from(0u8), c3_blinding], + &[c_basepoint, blinding_basepoint], + ); let proof = prove_either_equality_relationship_proof( c1_value, @@ -1792,4 +2095,305 @@ mod tests { ); } } + + #[test] + fn test_value_equality_proof() { + let c1_value = 100u64; + let c1_scalar = Scalar::from(c1_value); + let c1_blinding = get_random_scalar(); + let commitment = + c1_scalar * *BASEPOINT_G1 + c1_blinding * *BASEPOINT_G2; + + let proof = prove_value_equality_relationship_proof( + c1_value, + &c1_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + assert_eq!( + true, + verify_value_equality_relationship_proof( + c1_value, + &commitment, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let c2_value = 101u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + + assert_eq!( + false, + verify_value_equality_relationship_proof( + c2_value, + &commitment, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let commitment2 = + c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + let proof2 = prove_value_equality_relationship_proof( + c2_value, + &c2_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + assert_eq!( + true, + verify_value_equality_relationship_proof( + c2_value, + &commitment2, + &proof2, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let result = verify_value_equality_relationship_proof( + c2_value, + &commitment, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ) + .unwrap(); + assert_eq!(false, result); + + wedpr_println!( + "#### verify_value_equality_relationship_proof: print begin" + ); + wedpr_println!( + "#commitment: {:?}", + hex::encode(&point_to_bytes(&commitment)) + ); + wedpr_println!("#proof: {:?}", hex::encode(proof.serialize())); + } + + #[test] + fn test_multi_sum_relationship() { + let input_length = 10; + let output_length = 4; + let mut input_values: Vec = vec![]; + let mut input_blindings: Vec = vec![]; + let mut input_commitments: Vec = vec![]; + let mut output_blindings: Vec = vec![]; + let mut output_values: Vec = vec![]; + let mut output_commitments: Vec = vec![]; + let mut output_commitments_error: Vec = vec![]; + let value_basepoint = *BASEPOINT_G1; + let blinding_basepoint = *BASEPOINT_G2; + + let mut spend_sum = 0; + for i in 0..input_length { + let value = i as u64; + let blinding = get_random_scalar(); + input_values.push(value); + input_blindings.push(blinding); + spend_sum += value; + let scalar_value = Scalar::from(value); + input_commitments.push( + scalar_value * value_basepoint + blinding * blinding_basepoint, + ); + } + for i in 0..output_length - 1 { + let value = i as u64; + let blinding = get_random_scalar(); + output_values.push(value); + output_blindings.push(blinding); + output_commitments.push( + value_basepoint * Scalar::from(value) + + blinding * blinding_basepoint, + ); + output_commitments_error.push( + value_basepoint * Scalar::from(value + 1) + + blinding * blinding_basepoint, + ); + } + let final_unspent = spend_sum - output_values.iter().sum::(); + output_values.push(final_unspent); + output_blindings.push(get_random_scalar()); + output_commitments.push( + value_basepoint * Scalar::from(final_unspent) + + output_blindings[output_length - 1] * blinding_basepoint, + ); + + let proof = prove_multi_sum_relationship( + &input_values, + &input_blindings, + &output_values, + &output_blindings, + &value_basepoint, + &blinding_basepoint, + ); + assert_eq!( + true, + verify_multi_sum_relationship( + &input_commitments, + &output_commitments, + &proof, + &value_basepoint, + &blinding_basepoint + ) + .unwrap() + ); + + // error case + // 1. error input commitment + let mut error_input_commitments = input_commitments.clone(); + error_input_commitments[0] = + error_input_commitments[0] + value_basepoint; + assert_eq!( + false, + verify_multi_sum_relationship( + &error_input_commitments, + &output_commitments, + &proof, + &value_basepoint, + &blinding_basepoint + ) + .unwrap() + ); + + // 2. error output commitment + let mut error_output_commitments = output_commitments.clone(); + error_output_commitments[0] = + error_output_commitments[0] + value_basepoint; + assert_eq!( + false, + verify_multi_sum_relationship( + &input_commitments, + &error_output_commitments, + &proof, + &value_basepoint, + &blinding_basepoint + ) + .unwrap() + ); + + // 3. error proof + let mut error_proof = proof.clone(); + error_proof.check = error_proof.check + Scalar::from(1u8); + assert_eq!( + false, + verify_multi_sum_relationship( + &input_commitments, + &output_commitments, + &error_proof, + &value_basepoint, + &blinding_basepoint + ) + .unwrap() + ); + + // fake error input commitment + error_proof.check = error_proof.check + Scalar::from(1u8); + assert_eq!( + false, + verify_multi_sum_relationship( + &input_commitments, + &output_commitments_error, + &proof, + &value_basepoint, + &blinding_basepoint + ) + .unwrap() + ); + } + + #[test] + fn test_sum_relation_ship_with_round() + { + let input_count = 10; + let output_count = 5; + let mut input_blindings = Vec::new(); + let mut input_private_part = Vec::new(); + let mut input_public_part = Vec::new(); + let mut input_commitments = Vec::new(); + + let mut output_private_part = Vec::new(); + let mut output_public_part = Vec::new(); + let mut output_commitments = Vec::new(); + let mut output_blidings = Vec::new(); + + // 45 + let mut input_value_sum = 0; + for i in 0..input_count + { + let value = i as u64; + input_value_sum += value; + let blinding = get_random_scalar(); + let scalar_value = Scalar::from(value); + input_blindings.push(blinding); + input_commitments.push( + scalar_value * *BASEPOINT_G1 + blinding * *BASEPOINT_G2, + ); + let (private_part, public_part ) = sender_prove_multi_sum_relationship_setup(value, &blinding, &BASEPOINT_G1, &BASEPOINT_G2); + input_private_part.push(private_part); + input_public_part.push(public_part); + } + wedpr_println!("input_value_sum: {:?}", input_value_sum); + // 15 + let mut output_value_sum = 0; + for i in 0..output_count + { + let value = i as u64 + 7; + output_value_sum += value; + let blinding = get_random_scalar(); + output_blidings.push(blinding); + output_commitments.push( + *BASEPOINT_G1 * Scalar::from(value) + + blinding * *BASEPOINT_G2, + ); + let (private_part, public_part ) = receiver_prove_multi_sum_relationship_setup(value, &blinding, &BASEPOINT_G1, &BASEPOINT_G2); + output_private_part.push(private_part); + output_public_part.push(public_part); + } + wedpr_println!("output_value_sum: {:?}", output_value_sum); + assert_eq!(input_value_sum, output_value_sum); + + let check = coordinator_prove_multi_sum_relationship_setup(&input_public_part, &output_public_part, &BASEPOINT_G1, &BASEPOINT_G2); + + let mut sender_public_parts = Vec::new(); + let mut receiver_public_parts = Vec::new(); + for i in 0..input_count + { + let sender_public_part = sender_prove_multi_sum_relationship_final(i as u64, &input_blindings[i], &input_private_part[i], &check); + sender_public_parts.push(sender_public_part); + } + + for i in 0..output_count + { + let receiver_public_part = receiver_prove_multi_sum_relationship_final(&output_blidings[i], &output_private_part[i], &check); + receiver_public_parts.push(receiver_public_part); + } + + let result_proof = coordinator_prove_multi_sum_relationship_final(&check, &sender_public_parts, &receiver_public_parts); + + assert_eq!( + true, + verify_multi_sum_relationship(&input_commitments, &output_commitments, &result_proof, &BASEPOINT_G1, &BASEPOINT_G2) + .unwrap() + ); + + } + + + + #[test] + fn test_commitments_serde() + { + let input_commitments_str = "8ce3d84ec8307c41eaaec84ab705efc966b631eb94be4592a7e3a8aba229af32105e8ea619da94c523b3bf1a73546ee8bf573115f8197f9986ac4b06fa19a270"; + let bytes_commitment = hex::decode(input_commitments_str).unwrap(); + let commitments: Result = wedpr_l_crypto_zkp_utils::Commitments::deserialize(bytes_commitment.as_slice()); + assert_eq!(commitments.is_ok(), true); + } } diff --git a/crypto/zkp/range_proof/Cargo.toml b/crypto/zkp/range_proof/Cargo.toml index f562bb2..ce79c36 100644 --- a/crypto/zkp/range_proof/Cargo.toml +++ b/crypto/zkp/range_proof/Cargo.toml @@ -9,9 +9,18 @@ description = "Library of WeDPR shared zkp Function implement range proof." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bulletproofs = { package = "wedpr_l_bulletproofs", version = "1.0.5" } -curve25519-dalek = { version = "1.0", features = [ "serde" ] } -merlin = "1" -wedpr_l_crypto_zkp_utils = "1.2.0" +bulletproofs = { package = "bulletproofs", version = "5.0" } +curve25519-dalek = { version = "4.1", features = [ "serde" ] } +merlin = "3" +wedpr_l_crypto_zkp_utils = {version = "1.3.0", path = "../utils/"} wedpr_l_macros = "1.0.0" wedpr_l_utils = "1.1.0" + +[dev-dependencies] +criterion = "0.5" +hex = "0.4.2" + + +[[bench]] +name = "proof" +harness = false diff --git a/crypto/zkp/range_proof/benches/proof.rs b/crypto/zkp/range_proof/benches/proof.rs new file mode 100644 index 0000000..bac5b87 --- /dev/null +++ b/crypto/zkp/range_proof/benches/proof.rs @@ -0,0 +1,32 @@ +// Copyright 2021 WeDPR Lab Project Authors. Licensed under Apache-2.0. + +#[macro_use] +extern crate criterion; +use criterion::Criterion; + +use curve25519_dalek::{ + ristretto::RistrettoPoint, scalar::Scalar, traits::MultiscalarMul, +}; +use wedpr_l_crypto_zkp_range_proof::{ + self, prove_value_range, verify_value_range, +}; + +fn create_verify_range_proof_helper(c: &mut Criterion) { + let label = format!("create_verify_range_proof_helper"); + let (proof_c1, c1_point, _) = prove_value_range(32u64); + c.bench_function(&label, move |b| { + b.iter(|| { + assert_eq!(true, verify_value_range(&c1_point, &proof_c1)); + }) + }); +} + +criterion_group! { + name = init_proof_test; + config = Criterion::default().sample_size(10); +targets = +create_verify_range_proof_helper, + +} + +criterion_main!(init_proof_test); diff --git a/crypto/zkp/range_proof/src/lib.rs b/crypto/zkp/range_proof/src/lib.rs index 5533dd1..6ea55c5 100644 --- a/crypto/zkp/range_proof/src/lib.rs +++ b/crypto/zkp/range_proof/src/lib.rs @@ -206,6 +206,10 @@ pub fn verify_value_range_in_batch( #[cfg(test)] mod tests { + use wedpr_l_crypto_zkp_utils::point_to_bytes; + extern crate hex; + + use super::*; #[test] @@ -257,4 +261,30 @@ mod tests { .unwrap_err() ); } + + #[test] + fn test_range_proof_single() { + let blinding_basepoint = *BASEPOINT_G2; + let value = 1; + let blinding = get_random_scalar(); + let (proof, commitment) = + prove_value_range_with_blinding_and_blinding_basepoint( + value, + &blinding, + &blinding_basepoint, + ); + assert_eq!( + true, + verify_value_range_with_blinding_basepoint( + &commitment, + &proof, + &blinding_basepoint, + ) + ); + + wedpr_println!("commitment: {:?}", hex::encode(&point_to_bytes(&commitment))); + wedpr_println!("proof: {:?}", hex::encode(&proof)); + wedpr_println!("blinding_basepoint: {:?}", hex::encode(&point_to_bytes(&blinding_basepoint))); + + } } diff --git a/crypto/zkp/utils/Cargo.toml b/crypto/zkp/utils/Cargo.toml index a559fb4..1b08e65 100644 --- a/crypto/zkp/utils/Cargo.toml +++ b/crypto/zkp/utils/Cargo.toml @@ -10,11 +10,13 @@ description = "Library of WeDPR shared zkp function utils." [dependencies] serde = { version = "1.0", features = ["derive"] } -curve25519-dalek = { version = "1.0", features = [ "serde" ] } +curve25519-dalek = { version = "4.1", features = [ "serde", "digest", "rand_core" ] } lazy_static = "1.4.0" -rand = "0.6" -rand_core = { version = "0.5", features = ["getrandom"] } -sha3 = "0.8" +rand = "0.8.5" +sha3 = "0.10" wedpr_l_crypto_hash_keccak256 = "1.1.0" wedpr_l_macros = "1.0.0" wedpr_l_utils = "1.1.0" + +[patch.crates-io] +zerocopy = { version = "=0.7.35" } diff --git a/crypto/zkp/utils/src/lib.rs b/crypto/zkp/utils/src/lib.rs index a619190..35bd290 100644 --- a/crypto/zkp/utils/src/lib.rs +++ b/crypto/zkp/utils/src/lib.rs @@ -46,6 +46,79 @@ pub trait Deserialize: Sized { fn deserialize(bytes: &[u8]) -> Result; } +#[derive(Default, Debug, Clone)] +pub struct Commitments { + pub commitments: Vec, +} + +impl Serialize for Commitments { + fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + for commitment in &self.commitments { + buf.extend(&(point_to_bytes(commitment))); + } + buf + } +} + +impl Deserialize for Commitments { + fn deserialize(bytes: &[u8]) -> Result { + let mut offset = 0; + let mut commitments = Vec::new(); + while offset < bytes.len() { + let commitment = bytes_to_point(&bytes[offset..offset+RISTRETTO_POINT_SIZE_IN_BYTES])?; + commitments.push(commitment); + offset += RISTRETTO_POINT_SIZE_IN_BYTES; + } + Ok(Commitments { + commitments: commitments, + }) + } +} + +// ZKP data to verify the balance relationship among value commitments. +// For example, given C(x), C(y), C(z), this proof data can be used to +// verify whether x * y =? z. +#[derive(Default, Debug, Clone)] +pub struct ValueEqualityProof { + pub check: Scalar, + pub m1: Scalar, + pub m2: Scalar, +} + +impl Serialize for ValueEqualityProof { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(3 * SCALAR_SIZE_IN_BYTE); + buf.extend(&(scalar_to_bytes(&self.check))); + buf.extend(&(scalar_to_bytes(&self.m1))); + buf.extend(&(scalar_to_bytes(&self.m2))); + buf + } +} + +impl Deserialize for ValueEqualityProof { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 3 * SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + // decode check + let mut offset = 0; + let check = + bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + // decode m1 + offset += SCALAR_SIZE_IN_BYTE; + let m1 = bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + // decode m2 + offset += SCALAR_SIZE_IN_BYTE; + let m2 = bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + Ok(ValueEqualityProof { + check: check, + m1: m1, + m2: m2, + }) + } +} + // ZKP data to verify the balance relationship among value commitments. // For example, given C(x), C(y), C(z), this proof data can be used to // verify whether x * y =? z. @@ -216,6 +289,387 @@ impl Deserialize for FormatProof { } } +#[derive(Default, Debug, Clone)] +pub struct ReceiverRelationshipProofSetupPrivate { + pub f_blinding: Scalar, +} + +impl Serialize for ReceiverRelationshipProofSetupPrivate { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(SCALAR_SIZE_IN_BYTE); + buf.extend(&(scalar_to_bytes(&self.f_blinding))); + buf + } +} + +impl Deserialize for ReceiverRelationshipProofSetupPrivate { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + let f_blinding = bytes_to_scalar(&bytes[0..SCALAR_SIZE_IN_BYTE])?; + Ok(ReceiverRelationshipProofSetupPrivate { + f_blinding: f_blinding, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct ReceiverRelationshipProofSetupPublicList { + pub receiver_setup_list: Vec +} + +impl Serialize for ReceiverRelationshipProofSetupPublicList { + fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + for setup in &self.receiver_setup_list { + buf.extend(&(setup.serialize())); + } + buf + } +} + +impl Deserialize for ReceiverRelationshipProofSetupPublicList { + fn deserialize(bytes: &[u8]) -> Result { + let mut offset = 0; + let mut receiver_setup_list = Vec::new(); + while offset < bytes.len() { + let setup = ReceiverRelationshipProofSetupPublic::deserialize( + &bytes[offset..], + )?; + receiver_setup_list.push(setup); + offset += 2 * RISTRETTO_POINT_SIZE_IN_BYTES; + } + Ok(ReceiverRelationshipProofSetupPublicList { + receiver_setup_list: receiver_setup_list, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct ReceiverRelationshipProofSetupPublic { + pub f_commit: RistrettoPoint, + pub commitment: RistrettoPoint, +} + +impl Serialize for ReceiverRelationshipProofSetupPublic { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(2 * RISTRETTO_POINT_SIZE_IN_BYTES); + buf.extend(&(point_to_bytes(&self.f_commit))); + buf.extend(&(point_to_bytes(&self.commitment))); + buf + } +} + +impl Deserialize for ReceiverRelationshipProofSetupPublic { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 2 * RISTRETTO_POINT_SIZE_IN_BYTES { + return Err(WedprError::ArgumentError); + } + let f_commit = + bytes_to_point(&bytes[0..RISTRETTO_POINT_SIZE_IN_BYTES])?; + let commitment = bytes_to_point( + &bytes[RISTRETTO_POINT_SIZE_IN_BYTES + ..2 * RISTRETTO_POINT_SIZE_IN_BYTES], + )?; + Ok(ReceiverRelationshipProofSetupPublic { + f_commit: f_commit, + commitment: commitment, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct SenderRelationshipProofSetupPrivate { + pub blinding_a: Scalar, + pub blinding_b: Scalar, +} + +impl Serialize for SenderRelationshipProofSetupPrivate { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(2 * SCALAR_SIZE_IN_BYTE); + buf.extend(&(scalar_to_bytes(&self.blinding_a))); + buf.extend(&(scalar_to_bytes(&self.blinding_b))); + buf + } +} + +impl Deserialize for SenderRelationshipProofSetupPrivate { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 2 * SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + let blinding_a = bytes_to_scalar(&bytes[0..SCALAR_SIZE_IN_BYTE])?; + let blinding_b = bytes_to_scalar( + &bytes[SCALAR_SIZE_IN_BYTE..2 * SCALAR_SIZE_IN_BYTE], + )?; + Ok(SenderRelationshipProofSetupPrivate { + blinding_a: blinding_a, + blinding_b: blinding_b, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct SenderRelationshipProofSetupPublicList { + pub sender_setup_list: Vec +} + +impl Serialize for SenderRelationshipProofSetupPublicList { + fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + for setup in &self.sender_setup_list { + buf.extend(&(setup.serialize())); + } + buf + } +} + +impl Deserialize for SenderRelationshipProofSetupPublicList { + fn deserialize(bytes: &[u8]) -> Result { + let mut offset = 0; + let mut sender_setup_list = Vec::new(); + while offset < bytes.len() { + let setup = SenderRelationshipProofSetupPublic::deserialize( + &bytes[offset..], + )?; + sender_setup_list.push(setup); + offset += 3 * RISTRETTO_POINT_SIZE_IN_BYTES; + } + Ok(SenderRelationshipProofSetupPublicList { + sender_setup_list: sender_setup_list, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct SenderRelationshipProofSetupPublic { + pub t_commit: RistrettoPoint, + pub a_commit: RistrettoPoint, + pub commitment: RistrettoPoint, +} + +impl Serialize for SenderRelationshipProofSetupPublic { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(3 * RISTRETTO_POINT_SIZE_IN_BYTES); + buf.extend(&(point_to_bytes(&self.t_commit))); + buf.extend(&(point_to_bytes(&self.a_commit))); + buf.extend(&(point_to_bytes(&self.commitment))); + buf + } +} + +impl Deserialize for SenderRelationshipProofSetupPublic { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 3 * RISTRETTO_POINT_SIZE_IN_BYTES { + return Err(WedprError::ArgumentError); + } + let t_commit = + bytes_to_point(&bytes[0..RISTRETTO_POINT_SIZE_IN_BYTES])?; + let a_commit = bytes_to_point( + &bytes[RISTRETTO_POINT_SIZE_IN_BYTES + ..2 * RISTRETTO_POINT_SIZE_IN_BYTES], + )?; + let commitment = bytes_to_point( + &bytes[2 * RISTRETTO_POINT_SIZE_IN_BYTES + ..3 * RISTRETTO_POINT_SIZE_IN_BYTES], + )?; + Ok(SenderRelationshipProofSetupPublic { + t_commit: t_commit, + a_commit: a_commit, + commitment: commitment, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct SenderRelationshipProofFinalPublicList { + pub sender_final_list: Vec +} + +impl Serialize for SenderRelationshipProofFinalPublicList { + fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + for final_public in &self.sender_final_list { + buf.extend(&(final_public.serialize())); + } + buf + } +} + +impl Deserialize for SenderRelationshipProofFinalPublicList { + fn deserialize(bytes: &[u8]) -> Result { + let mut offset = 0; + let mut sender_final_list = Vec::new(); + while offset < bytes.len() { + let final_public = + SenderRelationshipProofFinalPublic::deserialize(&bytes[offset..])?; + sender_final_list.push(final_public); + offset += 2 * SCALAR_SIZE_IN_BYTE; + } + Ok(SenderRelationshipProofFinalPublicList { + sender_final_list: sender_final_list, + }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct SenderRelationshipProofFinalPublic { + pub m: Scalar, + pub n: Scalar, +} + +impl Serialize for SenderRelationshipProofFinalPublic { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(2 * SCALAR_SIZE_IN_BYTE); + buf.extend(&(scalar_to_bytes(&self.m))); + buf.extend(&(scalar_to_bytes(&self.n))); + buf + } +} + +impl Deserialize for SenderRelationshipProofFinalPublic { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 2 * SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + let m = bytes_to_scalar(&bytes[0..SCALAR_SIZE_IN_BYTE])?; + let n = bytes_to_scalar( + &bytes[SCALAR_SIZE_IN_BYTE..2 * SCALAR_SIZE_IN_BYTE], + )?; + Ok(SenderRelationshipProofFinalPublic { m: m, n: n }) + } +} + +#[derive(Default, Debug, Clone)] +pub struct ReceiverRelationshipProofFinalPublicList { + pub receiver_final_list: Vec +} + +impl Serialize for ReceiverRelationshipProofFinalPublicList { + fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + for final_public in &self.receiver_final_list { + buf.extend(&(final_public.serialize())); + } + buf + } +} + +impl Deserialize for ReceiverRelationshipProofFinalPublicList { + fn deserialize(bytes: &[u8]) -> Result { + let mut offset = 0; + let mut receiver_final_list = Vec::new(); + while offset < bytes.len() { + let final_public = + ReceiverRelationshipProofFinalPublic::deserialize(&bytes[offset..])?; + receiver_final_list.push(final_public); + offset += SCALAR_SIZE_IN_BYTE; + } + Ok(ReceiverRelationshipProofFinalPublicList { + receiver_final_list: receiver_final_list, + }) + } +} + + +#[derive(Default, Debug, Clone)] +pub struct ReceiverRelationshipProofFinalPublic { + pub t_commit_share: Scalar, +} + +impl Serialize for ReceiverRelationshipProofFinalPublic { + fn serialize(&self) -> Vec { + let mut buf = Vec::with_capacity(SCALAR_SIZE_IN_BYTE); + buf.extend(&(scalar_to_bytes(&self.t_commit_share))); + buf + } +} + +impl Deserialize for ReceiverRelationshipProofFinalPublic { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + let t_commit_share = bytes_to_scalar(&bytes[0..SCALAR_SIZE_IN_BYTE])?; + Ok(ReceiverRelationshipProofFinalPublic { + t_commit_share: t_commit_share, + }) + } +} +#[derive(Default, Debug, Clone)] +pub struct RelationshipProof { + pub check: Scalar, + pub left_commit: Scalar, + pub m_list: Vec, + pub n_list: Vec, +} + +impl Serialize for RelationshipProof { + fn serialize(&self) -> Vec { + if self.m_list.len() != self.n_list.len() { + return Vec::new(); + } + let mut buf = Vec::with_capacity( + SCALAR_SIZE_IN_BYTE + + SCALAR_SIZE_IN_BYTE * self.m_list.len() + + SCALAR_SIZE_IN_BYTE * self.n_list.len(), + ); + buf.push(self.m_list.len() as u8); + buf.extend(&(scalar_to_bytes(&self.check))); + buf.extend(&(scalar_to_bytes(&self.left_commit))); + for m in &self.m_list { + buf.extend(&(scalar_to_bytes(m))); + } + for n in &self.n_list { + buf.extend(&(scalar_to_bytes(n))); + } + + buf + } +} + +impl Deserialize for RelationshipProof { + fn deserialize(bytes: &[u8]) -> Result { + if bytes.len() < 3 * SCALAR_SIZE_IN_BYTE { + return Err(WedprError::ArgumentError); + } + let mut offset = 0; + let m_list_len = bytes[offset]; + offset += 1; + // decode check + let check = + bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + offset += SCALAR_SIZE_IN_BYTE; + // decode left_commit + let left_commit = + bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + offset += SCALAR_SIZE_IN_BYTE; + // decode m_list + let mut m_list = Vec::new(); + for _ in 0..m_list_len { + let m = + bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + m_list.push(m); + offset += SCALAR_SIZE_IN_BYTE; + } + // decode n_list + let mut n_list = Vec::new(); + for _ in 0..m_list_len { + let n = + bytes_to_scalar(&bytes[offset..offset + SCALAR_SIZE_IN_BYTE])?; + n_list.push(n); + offset += SCALAR_SIZE_IN_BYTE; + } + Ok(RelationshipProof { + check: check, + left_commit: left_commit, + m_list: m_list, + n_list: n_list, + }) + } +} + #[derive(Default, Debug, Clone)] pub struct ArithmeticProof { pub t1: RistrettoPoint, @@ -379,7 +833,7 @@ fn to_bytes32_slice(barry: &[u8]) -> Result<&[u8; 32], WedprError> { /// Converts a vector to Scalar. pub fn bytes_to_scalar(input: &[u8]) -> Result { let get_num_u8 = to_bytes32_slice(&input)?; - let scalar_num = Scalar::from_bits(*get_num_u8); + let scalar_num = Scalar::from_bytes_mod_order(*get_num_u8); Ok(scalar_num) } @@ -399,8 +853,16 @@ pub fn bytes_to_point(point: &[u8]) -> Result { wedpr_println!("bytes_to_point decode failed"); return Err(WedprError::FormatError); } - let point_value = match CompressedRistretto::from_slice(&point).decompress() - { + let point_value_result = match CompressedRistretto::from_slice(&point) { + Ok(v) => v, + Err(_e) => { + wedpr_println!( + "bytes_to_point decompress CompressedRistretto failed" + ); + return Err(WedprError::FormatError); + }, + }; + let point_value = match point_value_result.decompress() { Some(v) => v, None => { wedpr_println!( diff --git a/crypto/zkp/zktransfer/Cargo.toml b/crypto/zkp/zktransfer/Cargo.toml new file mode 100644 index 0000000..0680d5c --- /dev/null +++ b/crypto/zkp/zktransfer/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "zktransfer" +version = "0.1.0" +edition = "2021" + +[dependencies] +curve25519-dalek = { version = "4.1", features = [ "serde" ] } +wedpr_l_crypto_zkp_utils = {version = "1.3.0", path = "../utils/"} +wedpr_l_crypto_zkp_range_proof = {version = "1.2.0", path = "../range_proof/"} +wedpr_l_crypto_zkp_discrete_logarithm_proof = {version = "1.3.0", path = "../discrete_logarithm_proof/"} +wedpr_l_macros = "1.0.0" +hex = "0.4.2" + +[dev-dependencies] +criterion = "0.5" + +[[bench]] +name = "zktransfer" +harness = false \ No newline at end of file diff --git a/crypto/zkp/zktransfer/benches/zktransfer.rs b/crypto/zkp/zktransfer/benches/zktransfer.rs new file mode 100644 index 0000000..d60a740 --- /dev/null +++ b/crypto/zkp/zktransfer/benches/zktransfer.rs @@ -0,0 +1,269 @@ +// Copyright 2021 WeDPR Lab Project Authors. Licensed under Apache-2.0. + +#[macro_use] +extern crate criterion; +use criterion::Criterion; + +use curve25519_dalek::Scalar; +use wedpr_l_crypto_zkp_discrete_logarithm_proof::{ + prove_knowledge_proof, prove_sum_relationship, + prove_value_equality_relationship_proof, verify_knowledge_proof, + verify_sum_relationship, verify_value_equality_relationship_proof, +}; +use wedpr_l_crypto_zkp_range_proof::{ + prove_value_range_with_blinding, + prove_value_range_with_blinding_and_blinding_basepoint, + verify_value_range_with_blinding_basepoint, +}; +use wedpr_l_crypto_zkp_utils::{ + get_random_scalar, point_to_bytes, Serialize, BASEPOINT_G1, BASEPOINT_G2, +}; + +fn create_mint_helper(c: &mut Criterion) { + let label = format!("create_mint_helper"); + let value = 1; + let c_scalar = Scalar::from(value); + let c_blinding = get_random_scalar(); + let c_commitment = c_scalar * *BASEPOINT_G1 + c_blinding * *BASEPOINT_G2; + let value_proof: wedpr_l_crypto_zkp_utils::ValueEqualityProof = + prove_value_equality_relationship_proof( + value, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + c.bench_function(&label, move |b| { + b.iter(|| { + assert_eq!( + true, + verify_value_equality_relationship_proof( + value, + &c_commitment, + &value_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + }) + }); +} + +fn create_transfer_helper(c: &mut Criterion) { + let label = format!("create_transfer_helper"); + // 1 mint + let value = 1; + let c_scalar = Scalar::from(value); + let c_blinding = get_random_scalar(); + let c_commitment = c_scalar * *BASEPOINT_G1 + c_blinding * *BASEPOINT_G2; + let value_proof: wedpr_l_crypto_zkp_utils::ValueEqualityProof = + prove_value_equality_relationship_proof( + value, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + assert_eq!( + true, + verify_value_equality_relationship_proof( + value, + &c_commitment, + &value_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let c2_value = 1u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + let c2_commitment = c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + + let c3_value = value - c2_value; + let c3_scalar = Scalar::from(c3_value); + let c3_blinding = get_random_scalar(); + let c3_commitment = c3_scalar * *BASEPOINT_G1 + c3_blinding * *BASEPOINT_G2; + + let knowledge_proof = + prove_knowledge_proof(value, &c_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + + let balance_proof = prove_sum_relationship( + c2_value, + c3_value, + &c2_blinding, + &c3_blinding, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + let (rangeproof_c2, expected_commitment2) = + prove_value_range_with_blinding_and_blinding_basepoint( + c2_value, + &c2_blinding, + &BASEPOINT_G2, + ); + let (rangeproof_c3, expected_commitment3) = + prove_value_range_with_blinding_and_blinding_basepoint( + c3_value, + &c3_blinding, + &BASEPOINT_G2, + ); + + c.bench_function(&label, move |b| { + b.iter(|| { + assert_eq!( + true, + verify_knowledge_proof( + &c_commitment, + &knowledge_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + assert_eq!( + true, + verify_value_equality_relationship_proof( + value, + &c_commitment, + &value_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + assert_eq!( + true, + verify_value_range_with_blinding_basepoint( + &c2_commitment, + &rangeproof_c2, + &BASEPOINT_G2 + ) + ); + assert_eq!( + true, + verify_value_range_with_blinding_basepoint( + &c3_commitment, + &rangeproof_c3, + &BASEPOINT_G2 + ) + ); + }) + }); +} + +fn create_withdraw_helper(c: &mut Criterion) { + let label: String = format!("create_withdraw_helper"); + let value = 1; + let c_scalar = Scalar::from(value); + let c_blinding = get_random_scalar(); + let c_commitment = c_scalar * *BASEPOINT_G1 + c_blinding * *BASEPOINT_G2; + let value_proof: wedpr_l_crypto_zkp_utils::ValueEqualityProof = + prove_value_equality_relationship_proof( + value, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + assert_eq!( + true, + verify_value_equality_relationship_proof( + value, + &c_commitment, + &value_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let c2_value = 1u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + let c2_commitment = c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + + let c3_value = value - c2_value; + let c3_scalar = Scalar::from(c3_value); + let c3_blinding = get_random_scalar(); + let c3_commitment = c3_scalar * *BASEPOINT_G1 + c3_blinding * *BASEPOINT_G2; + + let knowledge_proof = + prove_knowledge_proof(value, &c_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + + let balance_proof = prove_sum_relationship( + c2_value, + c3_value, + &c2_blinding, + &c3_blinding, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + let (rangeproof_c2, expected_commitment2) = + prove_value_range_with_blinding_and_blinding_basepoint( + c2_value, + &c2_blinding, + &BASEPOINT_G2, + ); + let (rangeproof_c3, expected_commitment3) = + prove_value_range_with_blinding_and_blinding_basepoint( + c3_value, + &c3_blinding, + &BASEPOINT_G2, + ); + + let knowledge_proof = prove_knowledge_proof( + c3_value, + &c3_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + let value_proof = prove_value_equality_relationship_proof( + c3_value, + &c3_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + c.bench_function(&label, move |b| { + b.iter(|| { + assert_eq!( + true, + verify_knowledge_proof( + &c3_commitment, + &knowledge_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + assert_eq!( + true, + verify_value_equality_relationship_proof( + c3_value, + &c3_commitment, + &value_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + }) + }); +} + +criterion_group! { + name = init_proof_test; + config = Criterion::default().sample_size(10); +targets = +create_mint_helper, +create_transfer_helper, +create_withdraw_helper +} + +criterion_main!(init_proof_test); diff --git a/crypto/zkp/zktransfer/src/main.rs b/crypto/zkp/zktransfer/src/main.rs new file mode 100644 index 0000000..488224e --- /dev/null +++ b/crypto/zkp/zktransfer/src/main.rs @@ -0,0 +1,390 @@ +use std::fs::File; +use std::io::Write; + +use curve25519_dalek::Scalar; +use wedpr_l_crypto_zkp_discrete_logarithm_proof::{prove_knowledge_proof, prove_multi_sum_relationship, prove_sum_relationship, prove_value_equality_relationship_proof, verify_knowledge_proof, verify_multi_sum_relationship, verify_sum_relationship, verify_value_equality_relationship_proof}; +use wedpr_l_crypto_zkp_range_proof::{prove_value_range_with_blinding, prove_value_range_with_blinding_and_blinding_basepoint, verify_value_range_with_blinding_basepoint}; +use wedpr_l_crypto_zkp_utils::{get_random_scalar, point_to_bytes, Serialize, BASEPOINT_G1, BASEPOINT_G2}; +#[macro_use] +extern crate wedpr_l_macros; + +fn main() { + // generate_mint_file(100); + demo(); +} + +fn generate_mint_file(count: u64) { + let mut file_proof = File::create("mint_proof.txt").unwrap(); + let mut file_commitment = File::create("mint_commitment.txt").unwrap(); + let mut file_commitment2 = File::create("transfer_commitment2.txt").unwrap(); + let mut file_commitment3 = File::create("transfer_commitment3.txt").unwrap(); + let mut file_proof_range1 = File::create("transfer_range_proof1.txt").unwrap(); + let mut file_proof_range2 = File::create("transfer_range_proof2.txt").unwrap(); + let mut file_proof_balance = File::create("transfer_balance_proof.txt").unwrap(); + let mut file_proof_knowledge = File::create("transfer_knowledge_proof.txt").unwrap(); + let mut file_commitment_withdraw = File::create("withdraw_commitment.txt").unwrap(); + let mut file_proof_withdraw_knowledge = File::create("withdraw_knowledge_proof.txt").unwrap(); + let mut file_proof_withdraw_value = File::create("withdraw_value_proof.txt").unwrap(); + + for _ in 0..count + { + // 1 mint + let value = 1; + let c_scalar = Scalar::from(value); + let c_blinding = get_random_scalar(); + let c_commitment = c_scalar * *BASEPOINT_G1 + c_blinding * *BASEPOINT_G2; + let value_proof: wedpr_l_crypto_zkp_utils::ValueEqualityProof = prove_value_equality_relationship_proof(value, &c_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(value, &c_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + writeln!(file_commitment, "{}", hex::encode(&point_to_bytes(&c_commitment))); + writeln!(file_proof, "{}", hex::encode(&value_proof.serialize())); + + // 2 transfer + + let c2_value = 1u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + let c2_commitment = c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + + let c3_value = value - c2_value; + let c3_scalar = Scalar::from(c3_value); + let c3_blinding = get_random_scalar(); + let c3_commitment = c3_scalar * *BASEPOINT_G1 + c3_blinding * *BASEPOINT_G2; + + let knowledge_proof = prove_knowledge_proof(value, &c_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + + let balance_proof = prove_sum_relationship( + c2_value, + c3_value, + &c2_blinding, + &c3_blinding, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + assert_eq!( + true, + verify_sum_relationship( + &c2_commitment, + &c3_commitment, + &c_commitment, + &balance_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let (rangeproof_c2, expected_commitment2) = prove_value_range_with_blinding_and_blinding_basepoint(c2_value, &c2_blinding, &BASEPOINT_G2); + let (rangeproof_c3, expected_commitment3) = prove_value_range_with_blinding_and_blinding_basepoint(c3_value, &c3_blinding, &BASEPOINT_G2); + + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c2_commitment, &rangeproof_c2, &BASEPOINT_G2)); + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c3_commitment, &rangeproof_c3, &BASEPOINT_G2)); + assert_eq!(true, c2_commitment == expected_commitment2); + assert_eq!(true, c3_commitment == expected_commitment3); + + writeln!(file_commitment2, "{}", hex::encode(&point_to_bytes(&c2_commitment))); + writeln!(file_commitment3, "{}", hex::encode(&point_to_bytes(&c3_commitment))); + writeln!(file_proof_range1, "{}", hex::encode(rangeproof_c2.clone())); + writeln!(file_proof_range2, "{}", hex::encode(rangeproof_c3.clone())); + writeln!(file_proof_balance, "{}", hex::encode(balance_proof.serialize())); + writeln!(file_proof_knowledge, "{}", hex::encode(knowledge_proof.serialize())); + + // 3 withdraw + let knowledge_proof = prove_knowledge_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c3_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + let value_proof = prove_value_equality_relationship_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(c3_value, &c3_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + writeln!(file_commitment_withdraw, "{}", hex::encode(&point_to_bytes(&c3_commitment))); + writeln!(file_proof_withdraw_knowledge, "{}", hex::encode(knowledge_proof.serialize())); + writeln!(file_proof_withdraw_value, "{}", hex::encode(value_proof.serialize())); + } +} + +fn demo() +{ + // 1. 生成commitment 生成value证明,链上入金 + // value_proof证明commitment钱和value相等 + let c1_value = 100u64; + let c1_scalar = Scalar::from(c1_value); + let c1_blinding = get_random_scalar(); + let c1_commitment = c1_scalar * *BASEPOINT_G1 + c1_blinding * *BASEPOINT_G2; + + let value_proof = prove_value_equality_relationship_proof(c1_value, &c1_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(c1_value, &c1_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + + wedpr_println!( + "#c1_value: {:?}", + c1_value + ); + wedpr_println!( + "#c1_commitment: {:?}", + hex::encode(&point_to_bytes(&c1_commitment)) + ); + wedpr_println!( + "#value_proof: {:?}", + hex::encode(value_proof.serialize()) + ); + + // 2. 生成transfer_proof,链上转账 + // knowledge proof证明拥有所有权 + // balance proof 会计平衡 + // range proof防止作恶 + let knowledge_proof = prove_knowledge_proof(c1_value, &c1_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c1_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "#c1 knowledge_proof: {:?}", + hex::encode(knowledge_proof.serialize()) + ); + + let mut input_value_list = Vec::new(); + let mut input_bliding_list = Vec::new(); + input_value_list.push(c1_value); + input_bliding_list.push(c1_blinding); + + let mut output_value_list = Vec::new(); + let mut output_blinding_list = Vec::new(); + let c2_value = 51u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + let c2_commitment = c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + + let c3_value = c1_value - c2_value; + let c3_scalar = Scalar::from(c3_value); + let c3_blinding = get_random_scalar(); + let c3_commitment = c3_scalar * *BASEPOINT_G1 + c3_blinding * *BASEPOINT_G2; + output_value_list.push(c2_value); + output_value_list.push(c3_value); + output_blinding_list.push(c2_blinding); + output_blinding_list.push(c3_blinding); + + + let balance_proof = prove_multi_sum_relationship( + &input_value_list, + &input_bliding_list, + &output_value_list, + &output_blinding_list, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + let input_commitments = vec![c1_commitment]; + let output_commitments = vec![c2_commitment, c3_commitment]; + + wedpr_println!( + "#c2_value: {:?}", + c2_value + ); + wedpr_println!( + "#c2_commitment: {:?}", + hex::encode(&point_to_bytes(&c2_commitment)) + ); + wedpr_println!( + "#c3_value: {:?}", + c3_value + ); + wedpr_println!( + "#c3_commitment: {:?}", + hex::encode(&point_to_bytes(&c3_commitment)) + ); + wedpr_println!( + "#balance_proof: {:?}", + hex::encode(balance_proof.serialize()) + ); + + assert_eq!( + true, + verify_multi_sum_relationship( + &input_commitments, + &output_commitments, + &balance_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let (rangeproof_c2, expected_commitment2) = prove_value_range_with_blinding_and_blinding_basepoint(c2_value, &c2_blinding, &BASEPOINT_G2); + let (rangeproof_c3, expected_commitment3) = prove_value_range_with_blinding_and_blinding_basepoint(c3_value, &c3_blinding, &BASEPOINT_G2); + + assert_eq!(true, c2_commitment == expected_commitment2); + assert_eq!(true, c3_commitment == expected_commitment3); + + wedpr_println!( + "#rangeproof_c2: {:?}", + hex::encode(rangeproof_c2.clone()) + ); + wedpr_println!( + "#rangeproof_c3: {:?}", + hex::encode(rangeproof_c3.clone()) + ); + + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c2_commitment, &rangeproof_c2, &BASEPOINT_G2)); + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c3_commitment, &rangeproof_c3, &BASEPOINT_G2)); + + // 3. 生成 出金证明 将c3转出 + // knowledge proof证明拥有所有权 + // value_proof证明commitment钱和value相等 + + let knowledge_proof = prove_knowledge_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c3_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "c3 #knowledge_proof: {:?}", + hex::encode(knowledge_proof.serialize()) + ); + + let value_proof = prove_value_equality_relationship_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(c3_value, &c3_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "c3 #value_proof: {:?}", + hex::encode(value_proof.serialize()) + ); + wedpr_println!( + "#c3_commitment: {:?}", + hex::encode(&point_to_bytes(&c3_commitment)) + ); +} + +fn demo2(){ + // 1. 生成commitment 生成value证明,链上入金 + // value_proof证明commitment钱和value相等 + let c1_value = 500u64; + let c1_scalar = Scalar::from(c1_value); + let c1_blinding = get_random_scalar(); + let c1_commitment = c1_scalar * *BASEPOINT_G1 + c1_blinding * *BASEPOINT_G2; + + let value_proof = prove_value_equality_relationship_proof(c1_value, &c1_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(c1_value, &c1_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + + wedpr_println!( + "#c1_value: {:?}", + c1_value + ); + wedpr_println!( + "#c1_commitment: {:?}", + hex::encode(&point_to_bytes(&c1_commitment)) + ); + wedpr_println!( + "#value_proof: {:?}", + hex::encode(value_proof.serialize()) + ); + + // 2. 生成transfer_proof,链上转账 + // knowledge proof证明拥有所有权 + // balance proof 会计平衡 + // range proof防止作恶 + let knowledge_proof = prove_knowledge_proof(c1_value, &c1_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c1_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "#c1 knowledge_proof: {:?}", + hex::encode(knowledge_proof.serialize()) + ); + + let mut input_value_list = Vec::new(); + let mut input_bliding_list = Vec::new(); + input_value_list.push(c1_value); + input_bliding_list.push(c1_blinding); + + let mut output_value_list = Vec::new(); + let mut output_blinding_list = Vec::new(); + let c2_value = 51u64; + let c2_scalar = Scalar::from(c2_value); + let c2_blinding = get_random_scalar(); + let c2_commitment = c2_scalar * *BASEPOINT_G1 + c2_blinding * *BASEPOINT_G2; + + let c3_value = c1_value - c2_value; + let c3_scalar = Scalar::from(c3_value); + let c3_blinding = get_random_scalar(); + let c3_commitment = c3_scalar * *BASEPOINT_G1 + c3_blinding * *BASEPOINT_G2; + output_value_list.push(c2_value); + output_value_list.push(c3_value); + output_blinding_list.push(c2_blinding); + output_blinding_list.push(c3_blinding); + + + let balance_proof = prove_multi_sum_relationship( + &input_value_list, + &input_bliding_list, + &output_value_list, + &output_blinding_list, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + let input_commitments = vec![c1_commitment]; + let output_commitments = vec![c2_commitment, c3_commitment]; + + wedpr_println!( + "#c2_value: {:?}", + c2_value + ); + wedpr_println!( + "#c2_commitment: {:?}", + hex::encode(&point_to_bytes(&c2_commitment)) + ); + wedpr_println!( + "#c3_value: {:?}", + c3_value + ); + wedpr_println!( + "#c3_commitment: {:?}", + hex::encode(&point_to_bytes(&c3_commitment)) + ); + wedpr_println!( + "#balance_proof: {:?}", + hex::encode(balance_proof.serialize()) + ); + + assert_eq!( + true, + verify_multi_sum_relationship( + &input_commitments, + &output_commitments, + &balance_proof, + &BASEPOINT_G1, + &BASEPOINT_G2 + ) + .unwrap() + ); + + let (rangeproof_c2, expected_commitment2) = prove_value_range_with_blinding_and_blinding_basepoint(c2_value, &c2_blinding, &BASEPOINT_G2); + let (rangeproof_c3, expected_commitment3) = prove_value_range_with_blinding_and_blinding_basepoint(c3_value, &c3_blinding, &BASEPOINT_G2); + + assert_eq!(true, c2_commitment == expected_commitment2); + assert_eq!(true, c3_commitment == expected_commitment3); + + wedpr_println!( + "#rangeproof_c2: {:?}", + hex::encode(rangeproof_c2.clone()) + ); + wedpr_println!( + "#rangeproof_c3: {:?}", + hex::encode(rangeproof_c3.clone()) + ); + + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c2_commitment, &rangeproof_c2, &BASEPOINT_G2)); + assert_eq!(true, verify_value_range_with_blinding_basepoint(&c3_commitment, &rangeproof_c3, &BASEPOINT_G2)); + + // 3. 生成 出金证明 将c3转出 + // knowledge proof证明拥有所有权 + // value_proof证明commitment钱和value相等 + + let knowledge_proof = prove_knowledge_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_knowledge_proof(&c3_commitment, &knowledge_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "c3 #knowledge_proof: {:?}", + hex::encode(knowledge_proof.serialize()) + ); + + let value_proof = prove_value_equality_relationship_proof(c3_value, &c3_blinding, &BASEPOINT_G1, &BASEPOINT_G2); + assert_eq!(true, verify_value_equality_relationship_proof(c3_value, &c3_commitment, &value_proof, &BASEPOINT_G1, &BASEPOINT_G2).unwrap()); + wedpr_println!( + "c3 #value_proof: {:?}", + hex::encode(value_proof.serialize()) + ); + wedpr_println!( + "#c3_commitment: {:?}", + hex::encode(&point_to_bytes(&c3_commitment)) + ); +} diff --git a/ffi/ffi_c/ffi_c_zkp/Cargo.toml b/ffi/ffi_c/ffi_c_zkp/Cargo.toml index 0bf0193..e4c3bfe 100644 --- a/ffi/ffi_c/ffi_c_zkp/Cargo.toml +++ b/ffi/ffi_c/ffi_c_zkp/Cargo.toml @@ -6,20 +6,21 @@ edition = "2018" [features] default = ["wedpr_f_zkp_proof"] -wedpr_f_zkp_proof = ["wedpr_l_crypto_zkp_discrete_logarithm_proof"] +wedpr_f_zkp_proof = ["wedpr_l_crypto_zkp_discrete_logarithm_proof", "wedpr_l_crypto_zkp_range_proof"] [lib] name = "ffi_c_zkp" crate-type = [ "cdylib", "staticlib" ] [dependencies] -curve25519-dalek = { version = "1.0", features = [ "serde" ] } +curve25519-dalek = { version = "4.1", features = [ "serde" ] } libc = "0.2.60" wedpr_l_utils = "1.1.0" wedpr_ffi_common = { path = "../../ffi_common" } wedpr_ffi_macros = { path = "../../ffi_macros" } wedpr_l_crypto_zkp_utils = {version = "1.3.0", path = "../../../crypto/zkp/utils/"} wedpr_l_crypto_zkp_discrete_logarithm_proof = { version = "1.3.0", path = "../../../crypto/zkp/discrete_logarithm_proof/", optional = true} +wedpr_l_crypto_zkp_range_proof = { path = "../../../crypto/zkp/range_proof/", optional = true} # This is required to generate C/C++ header files. [build-dependencies] diff --git a/ffi/ffi_c/ffi_c_zkp/src/discrete_logarithm_proof.rs b/ffi/ffi_c/ffi_c_zkp/src/discrete_logarithm_proof.rs index ce749ae..8ca6344 100644 --- a/ffi/ffi_c/ffi_c_zkp/src/discrete_logarithm_proof.rs +++ b/ffi/ffi_c/ffi_c_zkp/src/discrete_logarithm_proof.rs @@ -1,11 +1,17 @@ use crate::utils::{ c_input_buffer_to_point, c_input_buffer_to_scalar, read_c_arithmetic_proof, - read_c_balance_proof, read_c_equality_proof, read_c_format_proof, - read_c_knowledge_proof, write_arithmetic_proof, write_balance_proof, + read_c_balance_proof, read_c_commitments, read_c_equality_proof, + read_c_format_proof, read_c_knowledge_proof, read_c_relationship_proof, + read_c_value_equality_proof, write_arithmetic_proof, write_balance_proof, write_equality_proof, write_format_proof, write_knowledger_proof, + write_value_equality_proof, }; use wedpr_ffi_common::utils::{CInputBuffer, COutputBuffer, FAILURE, SUCCESS}; -use wedpr_l_crypto_zkp_utils::point_to_slice; +use wedpr_l_crypto_zkp_discrete_logarithm_proof::{ + prove_value_equality_relationship_proof, verify_multi_sum_relationship, + verify_value_equality_relationship_proof, +}; +use wedpr_l_crypto_zkp_utils::{point_to_slice, BASEPOINT_G1, BASEPOINT_G2}; use wedpr_ffi_common::utils::c_write_data_to_pointer; @@ -712,3 +718,195 @@ pub unsafe extern "C" fn wedpr_verify_equality_relationship_proof( } return FAILURE; } + +#[no_mangle] +/// C interface for 'wedpr_verify_knowledge_proof_without_basepoint'. +pub unsafe extern "C" fn wedpr_verify_knowledge_proof_without_basepoint( + c_point_data: &CInputBuffer, + proof: &CInputBuffer, +) -> i8 { + // c_point + let c_point_result = c_input_buffer_to_point(c_point_data); + let c_point = match c_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // KnowledgeProof + let knowledge_proof_result = read_c_knowledge_proof(proof); + let knowledge_proof = match knowledge_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // verify_knowledge_proof + let result = verify_knowledge_proof( + &c_point, + &knowledge_proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + let verify_result = match result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + if verify_result { + return SUCCESS; + } + FAILURE +} + +#[no_mangle] +/// C interface for 'wedpr_verify_sum_relationship_without_basepoint'. +pub unsafe extern "C" fn wedpr_verify_sum_relationship_without_basepoint( + c1_point_data: &CInputBuffer, + c2_point_data: &CInputBuffer, + c3_point_data: &CInputBuffer, + proof: &CInputBuffer, +) -> i8 { + // c1_point + let c1_point_result = c_input_buffer_to_point(c1_point_data); + let c1_point = match c1_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // c2_point + let c2_point_result = c_input_buffer_to_point(c2_point_data); + let c2_point = match c2_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // c3_point + let c3_point_result = c_input_buffer_to_point(c3_point_data); + let c3_point = match c3_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // proof + let arithmetic_proof_result = read_c_arithmetic_proof(proof); + let arithmetic_proof = match arithmetic_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + let result = verify_sum_relationship( + &c1_point, + &c2_point, + &c3_point, + &arithmetic_proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + let verify_result = match result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + if verify_result { + return SUCCESS; + } + return FAILURE; +} + +#[no_mangle] +/// C interface for +/// 'wedpr_generate_value_equality_relationship_proof_without_basepoint'. +pub unsafe extern "C" fn wedpr_generate_value_equality_relationship_proof_without_basepoint( + c_value: u64, + c_blinding_data: &CInputBuffer, + generated_proof: &mut COutputBuffer, +) -> i8 { + // c_blinding + let c_blinding_result = c_input_buffer_to_scalar(c_blinding_data); + let c_blinding = match c_blinding_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + + let equality_proof = prove_value_equality_relationship_proof( + c_value, + &c_blinding, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + write_value_equality_proof(&equality_proof, generated_proof); + SUCCESS +} + +#[no_mangle] +/// C interface for +/// 'wedpr_verify_value_equality_relationship_proof_without_basepoint'. +pub unsafe extern "C" fn wedpr_verify_value_equality_relationship_proof_without_basepoint( + c_value: u64, + c_point_data: &CInputBuffer, + proof: &CInputBuffer, +) -> i8 { + // c_point + let c_point_result = c_input_buffer_to_point(c_point_data); + let c_point = match c_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // ValueEqualityProof + let value_equality_proof_result = read_c_value_equality_proof(proof); + let value_equality_proof = match value_equality_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // verify_value_equality_relationship_proof + let result = verify_value_equality_relationship_proof( + c_value, + &c_point, + &value_equality_proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + let verify_result = match result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + if verify_result { + return SUCCESS; + } + return FAILURE; +} + +#[no_mangle] +/// C interface for +/// 'wedpr_verify_multi_sum_relationship_without_basepoint'. +pub unsafe extern "C" fn wedpr_verify_multi_sum_relationship_without_basepoint( + input_point_list_data: &CInputBuffer, + output_point_list_data: &CInputBuffer, + proof: &CInputBuffer, +) -> i8 { + // input_point_list + let input_point_list_result = read_c_commitments(input_point_list_data); + let input_point_list = match input_point_list_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // output_point_list + let output_point_list_result = read_c_commitments(output_point_list_data); + let output_point_list = match output_point_list_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + + // proof + let relationship_proof_result = read_c_relationship_proof(proof); + let relationship_proof = match relationship_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + let result = verify_multi_sum_relationship( + &input_point_list, + &output_point_list, + &relationship_proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + let verify_result = match result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + if verify_result { + return SUCCESS; + } + return FAILURE; +} diff --git a/ffi/ffi_c/ffi_c_zkp/src/lib.rs b/ffi/ffi_c/ffi_c_zkp/src/lib.rs index 575a694..51d273e 100644 --- a/ffi/ffi_c/ffi_c_zkp/src/lib.rs +++ b/ffi/ffi_c/ffi_c_zkp/src/lib.rs @@ -2,5 +2,6 @@ //! compatible architectures (including iOS), with fast binary interfaces. // Copyright 2020 WeDPR Lab Project Authors. Licensed under Apache-2.0. pub mod discrete_logarithm_proof; +pub mod range_proof; pub mod utils; // C/C++ FFI: C-style interfaces will be generated. diff --git a/ffi/ffi_c/ffi_c_zkp/src/range_proof.rs b/ffi/ffi_c/ffi_c_zkp/src/range_proof.rs new file mode 100644 index 0000000..1a15088 --- /dev/null +++ b/ffi/ffi_c/ffi_c_zkp/src/range_proof.rs @@ -0,0 +1,116 @@ +use crate::utils::{ + c_input_buffer_to_point, c_input_buffer_to_scalar, + c_input_buffer_to_vec +}; +use wedpr_ffi_common::utils::{CInputBuffer, COutputBuffer, FAILURE, SUCCESS}; + +use wedpr_ffi_common::utils::c_write_data_to_pointer; + +#[cfg(feature = "wedpr_f_zkp_proof")] +use wedpr_l_crypto_zkp_range_proof::{ + prove_value_range_with_blinding_and_blinding_basepoint, verify_value_range_with_blinding_basepoint +}; +use wedpr_l_crypto_zkp_utils::BASEPOINT_G2; + +#[no_mangle] +/// C interface for 'wedpr_generate_range_proof'. +pub unsafe extern "C" fn wedpr_generate_range_proof( + c_value: u64, + c_blinding: &CInputBuffer, + blinding_basepoint_data: &CInputBuffer, + c_range_proof: &mut COutputBuffer, +) -> i8 { + // c_blinding + let c_blinding_result: Result = c_input_buffer_to_scalar(&c_blinding); + let c_blinding_value = match c_blinding_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // blinding_basepoint + let blinding_basepoint_result = + c_input_buffer_to_point(blinding_basepoint_data); + let blinding_basepoint = match blinding_basepoint_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + let (range_proof, _) = prove_value_range_with_blinding_and_blinding_basepoint( + c_value, + &c_blinding_value, + &blinding_basepoint, + ); + // write balance proof back to c_balance_proof + c_write_data_to_pointer( + &range_proof, + c_range_proof.data, + c_range_proof.len, + ); + SUCCESS +} + +#[no_mangle] +/// C interface for 'wedpr_verify_range_proof'. +pub unsafe extern "C" fn wedpr_verify_range_proof( + commitment_point_data: &CInputBuffer, + proof: &CInputBuffer, + blinding_basepoint_data: &CInputBuffer, +) -> i8 { + // c_point + let c_point_result = c_input_buffer_to_point(commitment_point_data); + let c_point = match c_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // range_proof + let range_proof_result = c_input_buffer_to_vec(proof); + let range_proof = match range_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // blinding_basepoint + let blinding_basepoint_result = + c_input_buffer_to_point(blinding_basepoint_data); + let blinding_basepoint = match blinding_basepoint_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + let result = verify_value_range_with_blinding_basepoint( + &c_point, + &range_proof, + &blinding_basepoint, + ); + if result { + return SUCCESS; + } + FAILURE +} + + +#[no_mangle] +/// C interface for 'wedpr_verify_range_proof_without_basepoint'. +pub unsafe extern "C" fn wedpr_verify_range_proof_without_basepoint( + commitment_point_data: &CInputBuffer, + proof: &CInputBuffer, +) -> i8 { + // c_point + let c_point_result = c_input_buffer_to_point(commitment_point_data); + let c_point = match c_point_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + // range_proof + let range_proof_result = c_input_buffer_to_vec(proof); + let range_proof = match range_proof_result { + Ok(v) => v, + Err(_) => return FAILURE, + }; + + let result = verify_value_range_with_blinding_basepoint( + &c_point, + &range_proof, + &BASEPOINT_G2, + ); + if result { + return SUCCESS; + } + FAILURE +} diff --git a/ffi/ffi_c/ffi_c_zkp/src/utils.rs b/ffi/ffi_c/ffi_c_zkp/src/utils.rs index 15be325..98b0051 100644 --- a/ffi/ffi_c/ffi_c_zkp/src/utils.rs +++ b/ffi/ffi_c/ffi_c_zkp/src/utils.rs @@ -5,12 +5,24 @@ use wedpr_ffi_common::utils::{ }; use wedpr_l_crypto_zkp_utils::{ bytes_to_point, bytes_to_scalar, ArithmeticProof, BalanceProof, - Deserialize, EqualityProof, FormatProof, KnowledgeProof, Serialize, + Deserialize, EqualityProof, FormatProof, KnowledgeProof, RelationshipProof, + Serialize, ValueEqualityProof, }; use wedpr_l_utils::error::WedprError; // From Rust to C/C++. use libc::c_char; + +pub unsafe fn c_input_buffer_to_vec( + input_data: &CInputBuffer, +) -> Result, WedprError> { + let rust_bytes_input = c_read_raw_pointer(&input_data); + // avoid the input c buffer been released + let result = rust_bytes_input.clone(); + std::mem::forget(rust_bytes_input); + Ok(result) +} + pub unsafe fn c_input_buffer_to_point( input_data: &CInputBuffer, ) -> Result { @@ -130,6 +142,43 @@ pub unsafe fn write_arithmetic_proof( ); } +pub unsafe fn write_commitments(commitments: &Vec, c_commitments: &mut COutputBuffer) { + let mut result = Vec::new(); + for commitment in commitments { + result.extend_from_slice(&commitment.compress().to_bytes()); + } + c_write_data_to_pointer(&result, c_commitments.data, c_commitments.len); +} + +pub unsafe fn read_c_commitments( + c_commitments: &CInputBuffer, +) -> Result, WedprError> { + let commitments = c_read_raw_pointer(c_commitments); + let mut result = Vec::new(); + let mut index = 0; + while index < commitments.len() { + let point = bytes_to_point(&commitments[index..index + 32])?; + result.push(point); + index += 32; + } + // avoid the input c buffer been released + std::mem::forget(commitments); + Ok(result) +} + +pub unsafe fn read_c_relationship_proof( + c_relationship_proof: &CInputBuffer, +) -> Result { + let proof = c_read_raw_data_pointer( + c_relationship_proof.data, + c_relationship_proof.len, + ); + let relationship_proof = Deserialize::deserialize(&proof); + // avoid the input c buffer been released + std::mem::forget(proof); + relationship_proof +} + pub unsafe fn read_c_arithmetic_proof( c_arithmetic_proof: &CInputBuffer, ) -> Result { @@ -164,3 +213,27 @@ pub unsafe fn read_c_equality_proof( std::mem::forget(proof); equality_proof } + +pub unsafe fn write_value_equality_proof( + value_equality_proof: &ValueEqualityProof, + c_value_equality_proof: &mut COutputBuffer, +) { + c_write_data_to_pointer( + &value_equality_proof.serialize(), + c_value_equality_proof.data, + c_value_equality_proof.len, + ); +} + +pub unsafe fn read_c_value_equality_proof( + c_value_equality_proof: &CInputBuffer, +) -> Result { + let proof = c_read_raw_data_pointer( + c_value_equality_proof.data, + c_value_equality_proof.len, + ); + let value_equality_proof = Deserialize::deserialize(&proof); + // avoid the input c buffer been released + std::mem::forget(proof); + value_equality_proof +} diff --git a/ffi/ffi_java/ffi_java_zkp/Cargo.toml b/ffi/ffi_java/ffi_java_zkp/Cargo.toml new file mode 100644 index 0000000..f993249 --- /dev/null +++ b/ffi/ffi_java/ffi_java_zkp/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "wedpr_ffi_java_zkp" +version = "0.1.0" +edition = "2021" + +[lib] +name = "ffi_java_zkp" +crate-type = [ "cdylib", "staticlib" ] + +[dependencies] +jni = "0.13.0" +wedpr_ffi_common = { path = "../../ffi_common" } +wedpr_ffi_macros = { path = "../../ffi_macros" } +wedpr_l_crypto_zkp_utils = {version = "1.3.0", path = "../../../crypto/zkp/utils/"} +wedpr_l_crypto_zkp_discrete_logarithm_proof = { version = "1.3.0", path = "../../../crypto/zkp/discrete_logarithm_proof/"} +wedpr_l_crypto_zkp_range_proof = { path = "../../../crypto/zkp/range_proof/"} +wedpr_l_utils = "1.1.0" +curve25519-dalek = { version = "4.1", features = [ "serde" ] } + + + diff --git a/ffi/ffi_java/ffi_java_zkp/NativeInterface.java b/ffi/ffi_java/ffi_java_zkp/NativeInterface.java new file mode 100644 index 0000000..3ceebd2 --- /dev/null +++ b/ffi/ffi_java/ffi_java_zkp/NativeInterface.java @@ -0,0 +1,39 @@ +package com.webank.wedpr.crypto.zkp; + +public class NativeInterface { + static { + String libraryPath = ZkpDemo.class.getResource("/lib/libffi_java_zkp.dylib").getPath(); + System.load(libraryPath); +// System.loadLibrary("ffi_java_zkp"); + } + + public native ZkpResult proveKnowledgeProof(int value, byte[] blinding); + + public native ZkpResult verifyKnowledgeProof(byte[] commitment, byte[] proof); + + public native ZkpResult proveValueEqualityRelationshipProof(int value1, byte[] blinding1); + + public native ZkpResult verifyValueEqualityRelationshipProof(int value1, byte[] commitment1, byte[] proof); + + public native ZkpResult senderProveMultiSumRelationshipSetup(int values, byte[] blindings); + + public native ZkpResult senderProveMultiSumRelationshipFinal(int values, byte[] blindings, byte[] proofSecret, byte[] check); + + public native ZkpResult receiverProveMultiSumRelationshipSetup(int values, byte[] blindings); + + public native ZkpResult receiverProveMultiSumRelationshipFinal(byte[] blindings, byte[] proofSecret, byte[] check); + + public native ZkpResult coordinatorProveMultiSumRelationshipSetup(byte[] senderSetupLists, byte[] receiverSetupLists); + + public native ZkpResult coordinatorProveMultiSumRelationshipFinal(byte[] check, byte[] senderProofs, byte[] receiverProofs); + + public native ZkpResult verifyMultiSumRelationship(byte[] inputCommitments, byte[] outputCommitments, byte[] proof); + + public native ZkpResult proveRangeProof(int value, byte[] blinding); + + public native ZkpResult verifyRangeProof(byte[] commitment, byte[] proof); + + public native ZkpResult computeCommitment(int value, byte[] blinding); + + public native ZkpResult computeViewkey(byte[] blinding); +} diff --git a/ffi/ffi_java/ffi_java_zkp/src/discrete_logarithm_proof.rs b/ffi/ffi_java/ffi_java_zkp/src/discrete_logarithm_proof.rs new file mode 100644 index 0000000..917f22f --- /dev/null +++ b/ffi/ffi_java/ffi_java_zkp/src/discrete_logarithm_proof.rs @@ -0,0 +1,1019 @@ +use curve25519_dalek::Scalar; +use jni::{ + objects::{JClass, JObject, JValue}, + sys::{jint, jobject}, + JNIEnv, +}; + +use jni::sys::jbyteArray; +use wedpr_ffi_common::utils::{ + self, java_bytes_to_jbyte_array, java_jbytes_to_bytes, + java_set_error_field_and_extract_jobject, +}; + +use wedpr_l_crypto_zkp_discrete_logarithm_proof::{ + coordinator_prove_multi_sum_relationship_final, + coordinator_prove_multi_sum_relationship_setup, prove_knowledge_proof, + prove_multi_sum_relationship, prove_value_equality_relationship_proof, + receiver_prove_multi_sum_relationship_final, + receiver_prove_multi_sum_relationship_setup, + sender_prove_multi_sum_relationship_final, + sender_prove_multi_sum_relationship_setup, verify_knowledge_proof, + verify_multi_sum_relationship, verify_value_equality_relationship_proof, +}; +use wedpr_l_crypto_zkp_utils::{ + bytes_to_point, bytes_to_scalar, scalar_to_bytes, Deserialize, + KnowledgeProof, Serialize, BASEPOINT_G1, BASEPOINT_G2, +}; +use wedpr_l_utils::error::WedprError; + +use super::get_result_jobject; + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->proveKnowledgeProof'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_proveKnowledgeProof( + env: JNIEnv, + _class: JClass, + value: jint, + blinding: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + // Convert Java byte array to Rust byte vector + let blinding_bytes = match java_jbytes_to_bytes(&env, blinding) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding conversion failed", + ); + }, + }; + + // Convert bytes to scalar + let blinding_scalar = match bytes_to_scalar(&blinding_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Generate the knowledge proof + let proof = prove_knowledge_proof( + value as u64, + &blinding_scalar, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + // Serialize the proof to bytes + let proof_bytes = proof.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &proof_bytes, + "proof" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->verifyKnowledgeProof'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_verifyKnowledgeProof( + env: JNIEnv, + _class: JClass, + commitment_jbytes: jbyteArray, + proof_jbytes: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte array to Rust byte vector + let commitment_bytes = match java_jbytes_to_bytes(&env, commitment_jbytes) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment conversion failed", + ); + }, + }; + + let commitment = match bytes_to_point(&commitment_bytes) { + Ok(point) => point, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment conversion failed", + ); + }, + }; + + let proof_bytes = match java_jbytes_to_bytes(&env, proof_jbytes) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof conversion failed", + ); + }, + }; + + // Deserialize the proof + let proof = match wedpr_l_crypto_zkp_utils::KnowledgeProof::deserialize( + &proof_bytes, + ) { + Ok(proof) => proof, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof deserialization failed", + ); + }, + }; + + // Verify the proof + let result = match verify_knowledge_proof( + &commitment, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ) { + Ok(result) => result, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof verification failed", + ); + }, + }; + + java_safe_set_boolean_field!(&env, result_jobject, result, "result"); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->proveValueEqualityRelationshipProof'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_proveValueEqualityRelationshipProof( + env: JNIEnv, + _class: JClass, + value1: jint, + blinding1: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let blinding1_bytes = match java_jbytes_to_bytes(&env, blinding1) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding1 conversion failed", + ); + }, + }; + + // Convert bytes to scalars + let blinding1_scalar = match bytes_to_scalar(&blinding1_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding1 scalar conversion failed", + ); + }, + }; + + // Generate the value equality relationship proof + let proof = prove_value_equality_relationship_proof( + value1 as u64, + &blinding1_scalar, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + // Serialize the proof to bytes + let proof_bytes = proof.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &proof_bytes, + "proof" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->verifyValueEqualityRelationshipProof' +/// . +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_verifyValueEqualityRelationshipProof( + env: JNIEnv, + _class: JClass, + value1: jint, + commitment1_jbytes: jbyteArray, + proof_jbytes: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let commitment1_bytes = match java_jbytes_to_bytes(&env, commitment1_jbytes) + { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment1 conversion failed", + ); + }, + }; + + let proof_bytes = match java_jbytes_to_bytes(&env, proof_jbytes) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof conversion failed", + ); + }, + }; + + // Deserialize the commitments and proof + let commitment1 = match bytes_to_point(&commitment1_bytes) { + Ok(point) => point, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment1 deserialization failed", + ); + }, + }; + + let proof = match wedpr_l_crypto_zkp_utils::ValueEqualityProof::deserialize( + &proof_bytes, + ) { + Ok(proof) => proof, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof deserialization failed", + ); + }, + }; + + // Verify the proof + let result = match verify_value_equality_relationship_proof( + value1 as u64, + &commitment1, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ) { + Ok(result) => result, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof verification failed", + ); + }, + }; + + java_safe_set_boolean_field!(&env, result_jobject, result, "result"); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->senderProveMultiSumRelationshipSetup' +/// . +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_senderProveMultiSumRelationshipSetup( + env: JNIEnv, + _class: JClass, + values: jint, + blindings: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let blindings_bytes = match java_jbytes_to_bytes(&env, blindings) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blindings conversion failed", + ); + }, + }; + + // Convert bytes to scalars + let blinding_scalar = match bytes_to_scalar(&blindings_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Generate the setup proof + let (private, public) = sender_prove_multi_sum_relationship_setup( + values as u64, + &blinding_scalar, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + // Serialize the proof to bytes + let private_bytes = private.serialize(); + let public_bytes = public.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &private_bytes, + "privatePart" + ); + java_safe_set_byte_array_field!( + &env, + result_jobject, + &public_bytes, + "publicPart" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->senderProveMultiSumRelationshipFinal' +/// . +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_senderProveMultiSumRelationshipFinal( + env: JNIEnv, + _class: JClass, + values: jint, + blindings: jbyteArray, + proof_secret: jbyteArray, + check: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let blindings_bytes = match java_jbytes_to_bytes(&env, blindings) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blindings conversion failed", + ); + }, + }; + + let proof_secret_bytes = match java_jbytes_to_bytes(&env, proof_secret) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof secret conversion failed", + ); + }, + }; + + let check_bytes = match java_jbytes_to_bytes(&env, check) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check conversion failed", + ); + }, + }; + + // Convert bytes to scalars + let blinding_scalar = match bytes_to_scalar(&blindings_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + let proof_secret_scalar = match wedpr_l_crypto_zkp_utils::SenderRelationshipProofSetupPrivate::deserialize(&proof_secret_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof secret scalar conversion failed", + ); + } + }; + + let check_scalar = match bytes_to_scalar(&check_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check scalar conversion failed", + ); + }, + }; + + // Generate the final proof + let public = sender_prove_multi_sum_relationship_final( + values as u64, + &blinding_scalar, + &proof_secret_scalar, + &check_scalar, + ); + + // Serialize the proof to bytes + let public_bytes = public.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &public_bytes, + "publicPart" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp. +/// NativeInterface->receiverProveMultiSumRelationshipSetup'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_receiverProveMultiSumRelationshipSetup( + env: JNIEnv, + _class: JClass, + values: jint, + blindings: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let blindings_bytes = match java_jbytes_to_bytes(&env, blindings) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blindings conversion failed", + ); + }, + }; + + // Convert bytes to scalars + let blinding_scalar = match bytes_to_scalar(&blindings_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Generate the setup proof + let (private, public) = receiver_prove_multi_sum_relationship_setup( + values as u64, + &blinding_scalar, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + // Serialize the proof to bytes + let private_bytes = private.serialize(); + let public_bytes = public.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &private_bytes, + "privatePart" + ); + java_safe_set_byte_array_field!( + &env, + result_jobject, + &public_bytes, + "publicPart" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp. +/// NativeInterface->receiverProveMultiSumRelationshipFinal'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_receiverProveMultiSumRelationshipFinal( + env: JNIEnv, + _class: JClass, + blindings: jbyteArray, + proof_secret: jbyteArray, + check: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let blindings_bytes = match java_jbytes_to_bytes(&env, blindings) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blindings conversion failed", + ); + }, + }; + + let proof_secret_bytes = match java_jbytes_to_bytes(&env, proof_secret) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof secret conversion failed", + ); + }, + }; + + let check_bytes = match java_jbytes_to_bytes(&env, check) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check conversion failed", + ); + }, + }; + + // Convert bytes to scalars + let blinding_scalar = match bytes_to_scalar(&blindings_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + let proof_secret_scalar = match wedpr_l_crypto_zkp_utils::ReceiverRelationshipProofSetupPrivate::deserialize(&proof_secret_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof secret scalar conversion failed", + ); + } + }; + + let check_scalar = match bytes_to_scalar(&check_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check scalar conversion failed", + ); + }, + }; + + // Generate the final proof + let public = receiver_prove_multi_sum_relationship_final( + &blinding_scalar, + &proof_secret_scalar, + &check_scalar, + ); + + // Serialize the proof to bytes + let public_bytes = public.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &public_bytes, + "publicPart" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp. +/// NativeInterface->coordinatorProveMultiSumRelationshipSetup'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_coordinatorProveMultiSumRelationshipSetup( + env: JNIEnv, + _class: JClass, + sender_setup_lists: jbyteArray, + receiver_setup_lists: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let sender_setup_bytes = + match java_jbytes_to_bytes(&env, sender_setup_lists) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Sender setup lists conversion failed", + ); + }, + }; + + let receiver_setup_bytes = + match java_jbytes_to_bytes(&env, receiver_setup_lists) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Receiver setup lists conversion failed", + ); + }, + }; + + // Deserialize setup lists + let sender_setup = match wedpr_l_crypto_zkp_utils::SenderRelationshipProofSetupPublicList::deserialize(&sender_setup_bytes) { + Ok(setup) => setup, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Sender setup lists deserialization failed", + ); + } + }; + + let receiver_setup = match wedpr_l_crypto_zkp_utils::ReceiverRelationshipProofSetupPublicList::deserialize(&receiver_setup_bytes) { + Ok(setup) => setup, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Receiver setup lists deserialization failed", + ); + } + }; + + // Generate the setup proof + let check = coordinator_prove_multi_sum_relationship_setup( + &sender_setup.sender_setup_list, + &receiver_setup.receiver_setup_list, + &BASEPOINT_G1, + &BASEPOINT_G2, + ); + + // Serialize the proof to bytes + let check_bytes = scalar_to_bytes(&check); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &check_bytes, + "check" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp. +/// NativeInterface->coordinatorProveMultiSumRelationshipFinal'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_coordinatorProveMultiSumRelationshipFinal( + env: JNIEnv, + _class: JClass, + check: jbyteArray, + sender_proofs: jbyteArray, + receiver_proofs: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let check_bytes = match java_jbytes_to_bytes(&env, check) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check conversion failed", + ); + }, + }; + + let sender_proofs_bytes = match java_jbytes_to_bytes(&env, sender_proofs) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Sender proofs conversion failed", + ); + }, + }; + + let receiver_proofs_bytes = + match java_jbytes_to_bytes(&env, receiver_proofs) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Receiver proofs conversion failed", + ); + }, + }; + + // Deserialize proofs + let check_scalar = match bytes_to_scalar(&check_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Check scalar conversion failed", + ); + }, + }; + + let sender_proofs = match wedpr_l_crypto_zkp_utils::SenderRelationshipProofFinalPublicList::deserialize(&sender_proofs_bytes) { + Ok(proofs) => proofs, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Sender proofs deserialization failed", + ); + } + }; + + let receiver_proofs = match wedpr_l_crypto_zkp_utils::ReceiverRelationshipProofFinalPublicList::deserialize(&receiver_proofs_bytes) { + Ok(proofs) => proofs, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Receiver proofs deserialization failed", + ); + } + }; + + // Generate the final proof + let proof = coordinator_prove_multi_sum_relationship_final( + &check_scalar, + &sender_proofs.sender_final_list, + &receiver_proofs.receiver_final_list, + ); + + // Serialize the proof to bytes + let proof_bytes = proof.serialize(); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!( + &env, + result_jobject, + &proof_bytes, + "proof" + ); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->verifyMultiSumRelationship'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_verifyMultiSumRelationship( + env: JNIEnv, + _class: JClass, + input_commitments: jbyteArray, + output_commitments: jbyteArray, + proof: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte arrays to Rust byte vectors + let input_commitments_bytes = + match java_jbytes_to_bytes(&env, input_commitments) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Input commitments conversion failed", + ); + }, + }; + + let output_commitments_bytes = + match java_jbytes_to_bytes(&env, output_commitments) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Output commitments conversion failed", + ); + }, + }; + + let proof_bytes = match java_jbytes_to_bytes(&env, proof) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof conversion failed", + ); + }, + }; + + // Deserialize commitments and proof + let input_commitments = + match wedpr_l_crypto_zkp_utils::Commitments::deserialize( + &input_commitments_bytes, + ) { + Ok(commitments) => commitments, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Input commitments deserialization failed", + ); + }, + }; + + let output_commitments = + match wedpr_l_crypto_zkp_utils::Commitments::deserialize( + &output_commitments_bytes, + ) { + Ok(commitments) => commitments, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Output commitments deserialization failed", + ); + }, + }; + + let proof = match wedpr_l_crypto_zkp_utils::RelationshipProof::deserialize( + &proof_bytes, + ) { + Ok(proof) => proof, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof deserialization failed", + ); + }, + }; + + // Verify the proof + let result = match verify_multi_sum_relationship( + &input_commitments.commitments, + &output_commitments.commitments, + &proof, + &BASEPOINT_G1, + &BASEPOINT_G2, + ) { + Ok(result) => result, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof verification failed", + ); + }, + }; + + java_safe_set_boolean_field!(&env, result_jobject, result, "result"); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->computeCommitment'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_computeCommitment( + env: JNIEnv, + _class: JClass, + value: jint, + blinding: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte array to Rust byte vector + let blinding_bytes = match java_jbytes_to_bytes(&env, blinding) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding conversion failed", + ); + }, + }; + + // Convert bytes to scalar + let blinding_scalar = match bytes_to_scalar(&blinding_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Compute the commitment + let commitment = Scalar::from(value as u64) * *BASEPOINT_G1 + blinding_scalar * *BASEPOINT_G2; + + // Convert Rust byte vector to Java byte array + let commitment_bytes = wedpr_l_crypto_zkp_utils::point_to_bytes(&commitment); + java_safe_set_byte_array_field!(&env, result_jobject, &commitment_bytes, "commitment"); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->computeViewkey'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_computeViewkey( + env: JNIEnv, + _class: JClass, + blinding: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte array to Rust byte vector + let blinding_bytes = match java_jbytes_to_bytes(&env, blinding) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding conversion failed", + ); + }, + }; + + // Convert bytes to scalar + let blinding_scalar = match bytes_to_scalar(&blinding_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Compute the commitment + let viewkey = blinding_scalar * *BASEPOINT_G1; + + // Convert Rust byte vector to Java byte array + let viewkey_bytes = wedpr_l_crypto_zkp_utils::point_to_bytes(&viewkey); + java_safe_set_byte_array_field!(&env, result_jobject, &viewkey_bytes, "viewkey"); + result_jobject.into_inner() +} \ No newline at end of file diff --git a/ffi/ffi_java/ffi_java_zkp/src/lib.rs b/ffi/ffi_java/ffi_java_zkp/src/lib.rs new file mode 100644 index 0000000..9e8afeb --- /dev/null +++ b/ffi/ffi_java/ffi_java_zkp/src/lib.rs @@ -0,0 +1,27 @@ +// Copyright 2020 WeDPR Lab Project Authors. Licensed under Apache-2.0. + +//! Library of FFI of wedpr_third_party_fisco_bcos_java_sdk wrapper functions, +//! targeting Java-compatible architectures (including Android), with fast +//! binary interfaces. + +#![cfg(not(tarpaulin_include))] +extern crate jni; +#[allow(unused_imports)] +#[macro_use] +extern crate wedpr_ffi_macros; +#[allow(unused_imports)] +#[macro_use] + +pub mod discrete_logarithm_proof; +pub mod range_proof; + +const RESULT_JAVA_SDK_CLASS_NAME: &str = + "com/webank/wedpr/crypto/zkp/ZkpResult"; + +use jni::{objects::JObject, JNIEnv}; +use wedpr_ffi_common::utils::java_new_jobject; + +#[allow(dead_code)] +fn get_result_jobject<'a>(_env: &'a JNIEnv) -> JObject<'a> { + java_new_jobject(_env, RESULT_JAVA_SDK_CLASS_NAME) +} diff --git a/ffi/ffi_java/ffi_java_zkp/src/range_proof.rs b/ffi/ffi_java/ffi_java_zkp/src/range_proof.rs new file mode 100644 index 0000000..4dc5ab6 --- /dev/null +++ b/ffi/ffi_java/ffi_java_zkp/src/range_proof.rs @@ -0,0 +1,115 @@ +use jni::{ + objects::{JClass, JObject, JValue}, + sys::{jint, jobject}, + JNIEnv, +}; + +use jni::sys::jbyteArray; +use wedpr_ffi_common::utils::{ + java_bytes_to_jbyte_array, java_jbytes_to_bytes, + java_set_error_field_and_extract_jobject, +}; + +use wedpr_l_crypto_zkp_range_proof::{ + prove_value_range_with_blinding, verify_value_range, +}; +use wedpr_l_crypto_zkp_utils::{bytes_to_point, bytes_to_scalar}; + +use super::get_result_jobject; + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->proveRangeProof'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_proveRangeProof( + env: JNIEnv, + _class: JClass, + value: jint, + blinding: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte array to Rust byte vector + let blinding_bytes = match java_jbytes_to_bytes(&env, blinding) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding conversion failed", + ); + }, + }; + + // Convert bytes to scalar + let blinding_scalar = match bytes_to_scalar(&blinding_bytes) { + Ok(scalar) => scalar, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Blinding scalar conversion failed", + ); + }, + }; + + // Generate the range proof + let (proof, _) = + prove_value_range_with_blinding(value as u64, &blinding_scalar); + + // Convert Rust byte vector to Java byte array + java_safe_set_byte_array_field!(&env, result_jobject, &proof, "proof"); + result_jobject.into_inner() +} + +#[no_mangle] +/// Java interface for +/// 'com.webank.wedpr.zkp.NativeInterface->verifyRangeProof'. +pub extern "system" fn Java_com_webank_wedpr_crypto_zkp_NativeInterface_verifyRangeProof( + env: JNIEnv, + _class: JClass, + commitment: jbyteArray, + proof: jbyteArray, +) -> jobject { + let result_jobject = get_result_jobject(&env); + + // Convert Java byte array to Rust byte vector + let commitment_bytes = match java_jbytes_to_bytes(&env, commitment) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment conversion failed", + ); + }, + }; + + let proof_bytes = match java_jbytes_to_bytes(&env, proof) { + Ok(bytes) => bytes, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Proof conversion failed", + ); + }, + }; + + // Deserialize the commitment and proof + let commitment = match bytes_to_point(&commitment_bytes) { + Ok(point) => point, + Err(_) => { + return java_set_error_field_and_extract_jobject( + &env, + &result_jobject, + "Commitment deserialization failed", + ); + }, + }; + + // Verify the proof + let result = verify_value_range(&commitment, &proof_bytes); + + java_safe_set_boolean_field!(&env, result_jobject, result, "result"); + result_jobject.into_inner() +} diff --git a/third_party/include/WedprDiscreteLogarithmProof.h b/third_party/include/WedprDiscreteLogarithmProof.h index b4bb217..8373dba 100644 --- a/third_party/include/WedprDiscreteLogarithmProof.h +++ b/third_party/include/WedprDiscreteLogarithmProof.h @@ -2,62 +2,62 @@ #ifndef _WEDPR_DISCRETE_LOGARITHM_H_ #define _WEDPR_DISCRETE_LOGARITHM_H_ #include "WedprUtilities.h" +#include extern "C" { /** * C interface for 'wedpr_generate_prove_either_equality_relationship_proof'. */ int8_t wedpr_aggregate_ristretto_point(const CInputBuffer *point_sum, const CInputBuffer *point_share, - COutputBuffer* result); + COutputBuffer *result); /** * C interface for 'wedpr_generate_prove_either_equality_relationship_proof'. */ -int8_t wedpr_generate_prove_either_equality_relationship_proof(uint64_t c1_value, - uint64_t c2_value, - const CInputBuffer *c1_blinding, - const CInputBuffer *c2_blinding, - const CInputBuffer *c3_blinding, - const CInputBuffer *c_basepoint_data, - const CInputBuffer *blinding_basepoint_data, - COutputBuffer *c_balance_proof); +int8_t wedpr_generate_prove_either_equality_relationship_proof( + uint64_t c1_value, uint64_t c2_value, const CInputBuffer *c1_blinding, + const CInputBuffer *c2_blinding, const CInputBuffer *c3_blinding, + const CInputBuffer *c_basepoint_data, + const CInputBuffer *blinding_basepoint_data, + COutputBuffer *c_balance_proof); /** * C interface for 'wedpr_verify_either_equality_relationship_proof'. */ -int8_t wedpr_verify_either_equality_relationship_proof(const CInputBuffer *c1_point_data, - const CInputBuffer *c2_point_data, - const CInputBuffer *c3_point_data, - const CInputBuffer *proof, - const CInputBuffer *c_basepoint_data, - const CInputBuffer *blinding_basepoint_data); +int8_t wedpr_verify_either_equality_relationship_proof( + const CInputBuffer *c1_point_data, const CInputBuffer *c2_point_data, + const CInputBuffer *c3_point_data, const CInputBuffer *proof, + const CInputBuffer *c_basepoint_data, + const CInputBuffer *blinding_basepoint_data); /** * C interface for 'wedpr_generate_prove_knowledge_proof'. */ -int8_t wedpr_generate_prove_knowledge_proof(uint64_t c_value, - const CInputBuffer *c_blinding_data, - const CInputBuffer *c_basepoint_data, - const CInputBuffer *blinding_basepoint_data, - COutputBuffer *generated_proof); +int8_t wedpr_generate_prove_knowledge_proof( + uint64_t c_value, const CInputBuffer *c_blinding_data, + const CInputBuffer *c_basepoint_data, + const CInputBuffer *blinding_basepoint_data, + COutputBuffer *generated_proof); /** * C interface for 'wedpr_verify_knowledge_proof'. */ -int8_t wedpr_verify_knowledge_proof(const CInputBuffer *c_point_data, - const CInputBuffer *proof, - const CInputBuffer *c_basepoint_data, - const CInputBuffer *blinding_basepoint_data); +int8_t +wedpr_verify_knowledge_proof(const CInputBuffer *c_point_data, + const CInputBuffer *proof, + const CInputBuffer *c_basepoint_data, + const CInputBuffer *blinding_basepoint_data); /** * C interface for 'wedpr_generate_prove_format_proof'. */ -int8_t wedpr_generate_prove_format_proof(uint64_t c1_value, - const CInputBuffer *c_blinding_data, - const CInputBuffer *c1_basepoint_data, - const CInputBuffer *c2_basepoint_data, - const CInputBuffer *blinding_basepoint_data, - COutputBuffer *generated_format_proof); +int8_t +wedpr_generate_prove_format_proof(uint64_t c1_value, + const CInputBuffer *c_blinding_data, + const CInputBuffer *c1_basepoint_data, + const CInputBuffer *c2_basepoint_data, + const CInputBuffer *blinding_basepoint_data, + COutputBuffer *generated_format_proof); /** * C interface for 'wedpr_verify_format_proof'. @@ -72,62 +72,81 @@ int8_t wedpr_verify_format_proof(const CInputBuffer *c1_point_data, /** * C interface for 'wedpr_generate_prove_sum_relationship'. */ -int8_t wedpr_generate_prove_sum_relationship(uint64_t c1_value, - uint64_t c2_value, - const CInputBuffer *c1_blinding_data, - const CInputBuffer *c2_blinding_data, - const CInputBuffer *c3_blinding_data, - const CInputBuffer *value_basepoint_data, - const CInputBuffer *blinding_basepoint_data, - COutputBuffer *proof); +int8_t wedpr_generate_prove_sum_relationship( + uint64_t c1_value, uint64_t c2_value, const CInputBuffer *c1_blinding_data, + const CInputBuffer *c2_blinding_data, const CInputBuffer *c3_blinding_data, + const CInputBuffer *value_basepoint_data, + const CInputBuffer *blinding_basepoint_data, COutputBuffer *proof); /** * C interface for 'wedpr_verify_sum_relationship'. */ -int8_t wedpr_verify_sum_relationship(const CInputBuffer *c1_point_data, - const CInputBuffer *c2_point_data, - const CInputBuffer *c3_point_data, - const CInputBuffer *proof, - const CInputBuffer *value_basepoint_data, - const CInputBuffer *blinding_basepoint_data); +int8_t wedpr_verify_sum_relationship( + const CInputBuffer *c1_point_data, const CInputBuffer *c2_point_data, + const CInputBuffer *c3_point_data, const CInputBuffer *proof, + const CInputBuffer *value_basepoint_data, + const CInputBuffer *blinding_basepoint_data); /** * C interface for 'wedpr_generate_prove_product_relationship'. */ -int8_t wedpr_generate_prove_product_relationship(uint64_t c1_value, - uint64_t c2_value, - const CInputBuffer *c1_blinding_data, - const CInputBuffer *c2_blinding_data, - const CInputBuffer *c3_blinding_data, - const CInputBuffer *value_basepoint_data, - const CInputBuffer *blinding_basepoint_data, - COutputBuffer *generated_proof); +int8_t wedpr_generate_prove_product_relationship( + uint64_t c1_value, uint64_t c2_value, const CInputBuffer *c1_blinding_data, + const CInputBuffer *c2_blinding_data, const CInputBuffer *c3_blinding_data, + const CInputBuffer *value_basepoint_data, + const CInputBuffer *blinding_basepoint_data, + COutputBuffer *generated_proof); /** * C interface for 'wedpr_verify_product_relationship'. */ -int8_t wedpr_verify_product_relationship(const CInputBuffer *c1_point_data, - const CInputBuffer *c2_point_data, - const CInputBuffer *c3_point_data, - const CInputBuffer *proof, - const CInputBuffer *value_basepoint_data, - const CInputBuffer *blinding_basepoint_data); +int8_t wedpr_verify_product_relationship( + const CInputBuffer *c1_point_data, const CInputBuffer *c2_point_data, + const CInputBuffer *c3_point_data, const CInputBuffer *proof, + const CInputBuffer *value_basepoint_data, + const CInputBuffer *blinding_basepoint_data); /** * C interface for 'wedpr_generate_prove_equality_relationship_proof'. */ -int8_t wedpr_generate_prove_equality_relationship_proof(const CInputBuffer *c1_value_data, - const CInputBuffer *basepoint1_data, - const CInputBuffer *basepoint2_data, - COutputBuffer *generated_proof); +int8_t wedpr_generate_prove_equality_relationship_proof( + const CInputBuffer *c1_value_data, const CInputBuffer *basepoint1_data, + const CInputBuffer *basepoint2_data, COutputBuffer *generated_proof); /** * C interface for 'wedpr_verify_equality_relationship_proof'. */ -int8_t wedpr_verify_equality_relationship_proof(const CInputBuffer *c1_point_data, - const CInputBuffer *c2_point_data, - const CInputBuffer *proof, - const CInputBuffer *basepoint1_data, - const CInputBuffer *basepoint2_data); +int8_t wedpr_verify_equality_relationship_proof( + const CInputBuffer *c1_point_data, const CInputBuffer *c2_point_data, + const CInputBuffer *proof, const CInputBuffer *basepoint1_data, + const CInputBuffer *basepoint2_data); +/** + * C interface for 'wedpr_verify_knowledge_proof_without_basepoint'. + */ +int8_t +wedpr_verify_knowledge_proof_without_basepoint(const CInputBuffer *c_point_data, + const CInputBuffer *proof); + +/** + * C interface for 'wedpr_verify_sum_relationship_without_basepoint'. + */ +int8_t wedpr_verify_sum_relationship_without_basepoint( + const CInputBuffer *c1_point_data, const CInputBuffer *c2_point_data, + const CInputBuffer *c3_point_data, const CInputBuffer *proof); + +/** + * C interface for + * 'wedpr_verify_value_equality_relationship_proof_without_basepoint'. + */ +int8_t wedpr_verify_value_equality_relationship_proof_without_basepoint( + int64_t c_value, const CInputBuffer *c_point_data, + const CInputBuffer *proof); + +/** + * C interface for 'wedpr_verify_sum_relationship_without_basepoint'. + */ + int8_t wedpr_verify_multi_sum_relationship_without_basepoint( + const CInputBuffer *input_point_data, const CInputBuffer *output_point_data, + const CInputBuffer *proof); } #endif \ No newline at end of file diff --git a/third_party/include/WedprRangeProof.h b/third_party/include/WedprRangeProof.h new file mode 100644 index 0000000..4ed7e59 --- /dev/null +++ b/third_party/include/WedprRangeProof.h @@ -0,0 +1,25 @@ +#ifndef _WEDPR_RANGE_PROOF_H_ +#define _WEDPR_RANGE_PROOF_H_ +#include "WedprUtilities.h" +extern "C" { +/** + * C interface for 'wedpr_generate_range_proof'. + */ +int8_t wedpr_generate_range_proof(uint64_t c_value, + const CInputBuffer *c_blinding, + const CInputBuffer *blinding_basepoint_data, + COutputBuffer *c_range_proof); + +/** + * C interface for 'wedpr_verify_range_proof'. + */ +int8_t wedpr_verify_range_proof(const CInputBuffer *commitment_point_data, + const CInputBuffer *proof, + const CInputBuffer *blinding_basepoint_data); +/** + * C interface for 'wedpr_verify_range_proof_without_basepoint'. + */ +int8_t wedpr_verify_range_proof_without_basepoint( + const CInputBuffer *commitment_point_data, const CInputBuffer *proof); +} +#endif \ No newline at end of file