diff --git a/Cargo.lock b/Cargo.lock index 1fda751..5f4b878 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,9 +264,9 @@ dependencies = [ [[package]] name = "bbs_plus" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7732b652fb5bca8357fbc012250ede183c658853972c83b7f14a6a405b5c8165" +checksum = "39faa539f5a9aefb0efc1f5012fd465182defa60e88f8bc56eb4d644ef340966" dependencies = [ "ark-ec", "ark-ff", @@ -322,9 +322,9 @@ dependencies = [ [[package]] name = "bulletproofs_plus_plus" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd367088019d22fd0911a9d9dd9cd1c713dca62082b73c0afa08a1dd9e7ec58f" +checksum = "c1d15f776236606996f878c540b03a2b2f6d32ff8cad2fe4ebce15dbea77265d" dependencies = [ "ark-ec", "ark-ff", @@ -405,9 +405,9 @@ dependencies = [ [[package]] name = "coconut-crypto" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f59a6ad48b4d447024dbea1c799d31af5f31d1f3d68a480b1c52ead079b151f" +checksum = "21584c60aa405b5b8ec79363748aa98a649b238d03dd44b55433af2cb24027a1" dependencies = [ "ark-ec", "ark-ff", @@ -1042,9 +1042,9 @@ dependencies = [ [[package]] name = "oblivious_transfer_protocols" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "367abb69dd82ab63e92b506489b5957c4c3c22e46dbc932e2a96a63bca171265" +checksum = "0a5954f01eaa12b19a1741020043013c50628ff0f505033f3ea0eae213b970d3" dependencies = [ "aes", "ark-ec", @@ -1142,9 +1142,9 @@ dependencies = [ [[package]] name = "proof_system" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63297d193f837dbffdf5eb1f3bde1f78b407beade67d4edfcea49f13c98836d1" +checksum = "f9f53f630b32defa43111c49fb0f21f9226f7132b3c410d9751c2ae88798ddbf" dependencies = [ "ark-ec", "ark-ff", @@ -1376,9 +1376,9 @@ dependencies = [ [[package]] name = "schnorr_pok" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d5f6e808bf4777e34e68bfa375bf339a867951de33cd72c5c968c8a4737a398" +checksum = "7f9b4e8026287a0230c025f130a32639fdfe736705472bd8d6d54f090f499ee7" dependencies = [ "ark-ec", "ark-ff", @@ -1411,9 +1411,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "secret_sharing_and_dkg" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19bcfb276a1876e43ee0f8aca0cc9fd784ce71214ae1b050ef1ec201b15d46a" +checksum = "ecb12997cec1e7c22dd9a151857d857c384d04484d4065c24eb703625dceccb4" dependencies = [ "ark-ec", "ark-ff", @@ -1533,9 +1533,9 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smc_range_proof" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5153509b97386dc1edc8157eb79fab1ff48fdd6a45159537759ac30ca6b8e03a" +checksum = "10ff148b032e71c7b6f1883f51159701fd2a77b180c4938220270e4cbfc2cf02" dependencies = [ "ark-ec", "ark-ff", @@ -1702,9 +1702,9 @@ checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" [[package]] name = "vb_accumulator" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ce7d2b133d461a3f7658aa7d8639f510b7ec258fc12bab844faf5640e38617" +checksum = "a04b84bd377235c759245e6a4f933a395da87e5d700c2209d0e768e71f74bcf9" dependencies = [ "ark-ec", "ark-ff", diff --git a/Cargo.toml b/Cargo.toml index 8ed4a12..b4538d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,19 +25,18 @@ wasm-bindgen = "= 0.2.86" dlmalloc = { version = "0.2.4", features = ["global"], optional = true } serde_with = { version = "1.10.0", default-features = false, features = ["macros"] } -bbs_plus = { version = "0.17.0", default-features = false } -vb_accumulator = { version = "0.18.0", default-features = false } -schnorr_pok = { version = "0.15.0", default-features = false } -proof_system = { version = "0.23.0", default-features = false } -coconut-crypto = { version = "0.6.0", default-features = false } +bbs_plus = { version = "0.18.0", default-features = false } +vb_accumulator = { version = "0.19.0", default-features = false } +schnorr_pok = { version = "0.16.0", default-features = false } +proof_system = { version = "0.24.0", default-features = false } +coconut-crypto = { version = "0.7.0", default-features = false } dock_crypto_utils = { version = "0.16.0", default-features = false } saver = { version = "0.14.0", default-features = false } legogroth16 = { version = "0.11.0", default-features = false, features = ["circom", "wasmer-js"] } -secret_sharing_and_dkg = { version = "0.8.0", default-features = false } -oblivious_transfer_protocols = { version = "0.4.0", default-features = false} -bulletproofs_plus_plus = { version = "0.1.0", default-features = false} -smc_range_proof = { version = "0.1.0", default-features = false} - +secret_sharing_and_dkg = { version = "0.9.0", default-features = false } +oblivious_transfer_protocols = { version = "0.5.0", default-features = false} +bulletproofs_plus_plus = { version = "0.2.0", default-features = false} +smc_range_proof = { version = "0.2.0", default-features = false} ark-ec = { version = "^0.4.0", default-features = false } ark-ff = { version = "^0.4.0", default-features = false } diff --git a/package.json b/package.json index e88a1f7..228c890 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/crypto-wasm", - "version": "0.22.0", + "version": "0.23.0", "author": "Dock.io", "license": "Apache-2.0", "private": false, diff --git a/src/common.rs b/src/common.rs index 3dddcb7..17609fb 100644 --- a/src/common.rs +++ b/src/common.rs @@ -11,6 +11,7 @@ use ark_ec::{CurveGroup, VariableBaseMSM}; use ark_serialize::CanonicalSerialize; use blake2::Blake2b512; use serde::{Deserialize, Serialize}; +use zeroize::Zeroize; use wasm_bindgen::prelude::*; @@ -145,6 +146,36 @@ pub fn pedersen_commitment_g2( g2_affine_to_uint8_array(&comm) } +#[wasm_bindgen(js_name = generatePedersenCommKeyG1)] +pub fn generate_pedersen_comm_key_g1( + label: Vec, + return_uncompressed: bool +) -> Result { + set_panic_hook(); + let comm_key = schnorr_pok::inequality::CommitmentKey::::new::(&label); + Ok(if return_uncompressed { + obj_to_uint8array_uncompressed!(&comm_key, "CommitmentKey") + } else { + obj_to_uint8array!(&comm_key, false, "CommitmentKey") + }) +} + +#[wasm_bindgen(js_name = decompressPedersenCommKeyG1)] +pub fn decompress_pedersen_comm_key_g1( + comm_key: js_sys::Uint8Array +) -> Result { + let comm_key = obj_from_uint8array!( + schnorr_pok::inequality::CommitmentKey::, + comm_key, + false, + "CommitmentKey" + ); + Ok(obj_to_uint8array_uncompressed!( + &comm_key, + "SmcParamsAndCommitmentKeyAndSecretKey" + )) +} + fn fr_uin8_array_from_bytes_hash(bytes: &[u8]) -> js_sys::Uint8Array { let f = dock_crypto_utils::hashing_utils::field_elem_from_try_and_incr::(bytes); fr_to_uint8_array(&f).unwrap() diff --git a/src/composite_proof_system/mod.rs b/src/composite_proof_system/mod.rs index 6f1358b..12cb094 100644 --- a/src/composite_proof_system/mod.rs +++ b/src/composite_proof_system/mod.rs @@ -348,6 +348,14 @@ pub fn generate_bound_check_smc_with_kv_witness(message: Uint8Array) -> Result Result { + set_panic_hook(); + let message = fr_from_uint8_array(message, true)?; + let witness = Witness::PublicInequality(message); + serde_wasm_bindgen::to_value(&witness).map_err(JsValue::from) +} + pub fn parse_statements_meta_statements_and_setup_params( statements: js_sys::Array, meta_statements: js_sys::Array, diff --git a/src/composite_proof_system/setup_params.rs b/src/composite_proof_system/setup_params.rs index 025062d..3096de3 100644 --- a/src/composite_proof_system/setup_params.rs +++ b/src/composite_proof_system/setup_params.rs @@ -420,3 +420,22 @@ pub fn generate_setup_param_for_smc_params_and_sk( params ))) } + +#[wasm_bindgen(js_name = generateSetupParamForCommitmentKey)] +pub fn generate_setup_param_for_commitment_key( + comm_key: js_sys::Uint8Array, + uncompressed: bool, +) -> Result { + set_panic_hook(); + let comm_key = if uncompressed { + obj_from_uint8array_uncompressed!(schnorr_pok::inequality::CommitmentKey, comm_key, "CommitmentKey") + } else { + obj_from_uint8array!(schnorr_pok::inequality::CommitmentKey, comm_key, false, "CommitmentKey") + }; + Ok(obj_to_uint8array_uncompressed!(&SetupParams::< + Bls12_381, + G1Affine, + >::CommitmentKey( + comm_key + ))) +} \ No newline at end of file diff --git a/src/composite_proof_system/statements/mod.rs b/src/composite_proof_system/statements/mod.rs index 6f8f2af..009451e 100644 --- a/src/composite_proof_system/statements/mod.rs +++ b/src/composite_proof_system/statements/mod.rs @@ -1,7 +1,4 @@ -use crate::utils::{ - g1_affine_from_uint8_array, g2_affine_from_uint8_array, js_array_to_g1_affine_vec, - js_array_to_g2_affine_vec, set_panic_hook, -}; +use crate::utils::{fr_from_uint8_array, g1_affine_from_uint8_array, g2_affine_from_uint8_array, js_array_to_g1_affine_vec, js_array_to_g2_affine_vec, set_panic_hook}; use ark_bls12_381::Bls12_381; use ark_ec::pairing::Pairing; use js_sys::Uint8Array; @@ -9,8 +6,10 @@ use proof_system::{ meta_statement::{EqualWitnesses, MetaStatement}, prelude, }; +use crate::G1Affine; use std::collections::BTreeSet; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; +use zeroize::Zeroize; // All `Statement`s are returned in their uncompressed form as they are generated by the same party using // them unlike signature params, public keys, proofs, etc @@ -20,6 +19,8 @@ pub(crate) type PedCommG1Stmt = pub(crate) type PedCommG2Stmt = prelude::ped_comm::PedersenCommitment<::G2Affine>; +pub(crate) type InequalityG1Stmt = prelude::inequality::PublicInequality<::G1Affine>; + #[wasm_bindgen(js_name = generatePedersenCommitmentG1Statement)] pub fn generate_pedersen_commitment_g1_statement( commitment_key: js_sys::Array, @@ -70,6 +71,36 @@ pub fn generate_pedersen_commitment_g2_statement_from_param_refs( Ok(obj_to_uint8array_uncompressed!(&statement, "PedCommG2Stmt")) } +#[wasm_bindgen(js_name = generatePublicInequalityG1Statement)] +pub fn generate_public_inequality_g1_statement( + inequal_to: Uint8Array, + commitment_key: Uint8Array, + uncompressed_key: bool, +) -> Result { + set_panic_hook(); + let commitment_key = if uncompressed_key { + obj_from_uint8array_uncompressed!(schnorr_pok::inequality::CommitmentKey, commitment_key, "CommitmentKey") + } else { + obj_from_uint8array!(schnorr_pok::inequality::CommitmentKey, commitment_key, false, "CommitmentKey") + }; + let inequal_to = fr_from_uint8_array(inequal_to, false)?; + let statement = + InequalityG1Stmt::new_statement_from_params::(inequal_to, commitment_key); + Ok(obj_to_uint8array_uncompressed!(&statement, "InequalityG1Stmt")) +} + +#[wasm_bindgen(js_name = generatePublicInequalityG1StatementFromParamRefs)] +pub fn generate_public_inequality_g1_statement_from_param_refs( + inequal_to: Uint8Array, + commitment_key: usize, +) -> Result { + set_panic_hook(); + let inequal_to = fr_from_uint8_array(inequal_to, false)?; + let statement = + InequalityG1Stmt::new_statement_from_params_ref::(inequal_to, commitment_key); + Ok(obj_to_uint8array_uncompressed!(&statement, "InequalityG1Stmt")) +} + #[wasm_bindgen(js_name = generateWitnessEqualityMetaStatement)] pub fn generate_witness_equality_meta_statement(equality: js_sys::Set) -> Result { set_panic_hook(); diff --git a/src/js/composite_proof_system_wasm.js b/src/js/composite_proof_system_wasm.js index 877beb4..2822db5 100644 --- a/src/js/composite_proof_system_wasm.js +++ b/src/js/composite_proof_system_wasm.js @@ -172,6 +172,16 @@ module.exports.generateBoundCheckSmcWithKVVerifierStatementFromParamRefs = (min, return wasm.generateBoundCheckSmcWithKVVerifierStatementFromParamRefs(min, max, params); }; +module.exports.generatePublicInequalityG1Statement = (inequalTo, commKey, uncompressedKey) => { + requireWasmInitialized(); + return wasm.generatePublicInequalityG1Statement(inequalTo, commKey, uncompressedKey); +}; + +module.exports.generatePublicInequalityG1StatementFromParamRefs = (inequalTo, commKey) => { + requireWasmInitialized(); + return wasm.generatePublicInequalityG1StatementFromParamRefs(inequalTo, commKey); +}; + module.exports.generateWitnessEqualityMetaStatement = (equalities) => { requireWasmInitialized(); return wasm.generateWitnessEqualityMetaStatement(equalities); @@ -237,6 +247,11 @@ module.exports.generateBoundCheckSmcWithKVWitness = (message) => { return wasm.generateBoundCheckSmcWithKVWitness(message); }; +module.exports.generatePublicInequalityWitness = (message) => { + requireWasmInitialized(); + return wasm.generatePublicInequalityWitness(message); +}; + module.exports.generateProofSpecG1 = (statements, metaStatements, setupParams, context) => { requireWasmInitialized(); return wasm.generateProofSpecG1(statements, metaStatements, setupParams, context); diff --git a/src/js/setup_params_wasm.js b/src/js/setup_params_wasm.js index b175673..2f5cf1b 100644 --- a/src/js/setup_params_wasm.js +++ b/src/js/setup_params_wasm.js @@ -120,4 +120,9 @@ module.exports.generateSetupParamForSmcParams = (params, uncompressed) => { module.exports.generateSetupParamForSmcParamsAndSk = (params, uncompressed) => { requireWasmInitialized(); return wasm.generateSetupParamForSmcParamsAndSk(params, uncompressed); +}; + +module.exports.generateSetupParamForCommitmentKey = (commKey, uncompressed) => { + requireWasmInitialized(); + return wasm.generateSetupParamForCommitmentKey(commKey, uncompressed); }; \ No newline at end of file diff --git a/src/js/type_declarations/composite_proof_system.d.ts b/src/js/type_declarations/composite_proof_system.d.ts index f912c86..369e7e6 100644 --- a/src/js/type_declarations/composite_proof_system.d.ts +++ b/src/js/type_declarations/composite_proof_system.d.ts @@ -227,6 +227,17 @@ export function generateBoundCheckSmcWithKVVerifierStatementFromParamRefs( params: number, ): Uint8Array; +export function generatePublicInequalityG1Statement( + inequalTo: Uint8Array, + commKey: Uint8Array, + uncompressedKey: boolean +): Uint8Array; + +export function generatePublicInequalityG1StatementFromParamRefs( + inequalTo: Uint8Array, + commKey: number, +): Uint8Array; + export function generateWitnessEqualityMetaStatement( equalities: Set<[number, number]>, ): Uint8Array; @@ -288,6 +299,10 @@ export function generateBoundCheckSmcWithKVWitness( message: Uint8Array ): Uint8Array; +export function generatePublicInequalityWitness( + message: Uint8Array +): Uint8Array; + export function generateProofSpecG1( statements: Uint8Array[], metaStatements: Uint8Array[], diff --git a/src/js/type_declarations/setup_params.d.ts b/src/js/type_declarations/setup_params.d.ts index dac5d53..27dc47a 100644 --- a/src/js/type_declarations/setup_params.d.ts +++ b/src/js/type_declarations/setup_params.d.ts @@ -104,4 +104,9 @@ export function generateSetupParamForSmcParams( export function generateSetupParamForSmcParamsAndSk( params: Uint8Array, uncompressed: boolean +): Uint8Array; + +export function generateSetupParamForCommitmentKey( + commKey: Uint8Array, + uncompressed: boolean ): Uint8Array; \ No newline at end of file diff --git a/src/js/type_declarations/util.d.ts b/src/js/type_declarations/util.d.ts index 0bfb539..848bb05 100644 --- a/src/js/type_declarations/util.d.ts +++ b/src/js/type_declarations/util.d.ts @@ -41,3 +41,12 @@ export function pedersenCommitmentG2( bases: Uint8Array[], messages: Uint8Array[], ): Uint8Array; + +export function generatePedersenCommKeyG1( + label: Uint8Array, + returnUncompressed: boolean, +): Uint8Array; + +export function decompressPedersenCommKeyG1( + commKey: Uint8Array +): Uint8Array; diff --git a/src/js/util_wasm.js b/src/js/util_wasm.js index 81158a7..ddd1581 100644 --- a/src/js/util_wasm.js +++ b/src/js/util_wasm.js @@ -59,3 +59,13 @@ module.exports.pedersenCommitmentG2 = (bases, messages) => { requireWasmInitialized(); return wasm.pedersenCommitmentG2(bases, messages); }; + +module.exports.generatePedersenCommKeyG1 = (label, returnUncompressed) => { + requireWasmInitialized(); + return wasm.generatePedersenCommKeyG1(label, returnUncompressed); +}; + +module.exports.decompressPedersenCommKeyG1 = (commKey) => { + requireWasmInitialized(); + return wasm.decompressPedersenCommKeyG1(commKey); +}; \ No newline at end of file diff --git a/tests/js/proofSystem.spec.ts b/tests/js/proofSystem.spec.ts index 84ab93f..b97e4f5 100644 --- a/tests/js/proofSystem.spec.ts +++ b/tests/js/proofSystem.spec.ts @@ -78,7 +78,8 @@ import { bbsSign, generatePoKBBSSignatureWitness, generateSetupParamForBBSSignatureParameters, - generatePoKBBSSignatureStatementFromParamRefs, + generatePoKBBSSignatureStatementFromParamRefs, generatePublicInequalityG1Statement, + generatePedersenCommKeyG1, generatePublicInequalityWitness } from "../../lib"; import { BbsSigParams, PSSigParams } from "../../lib/types"; @@ -442,6 +443,7 @@ describe("Proving knowledge of signatures and accumulator membership and non-mem let uniAccumulator = getUniversalAccum(initialElements, sk, params, 100); const nonMemPrk = generateNonMembershipProvingKey(); + const memPrk = accumulatorDeriveMembershipProvingKeyFromNonMembershipKey( nonMemPrk ); @@ -1161,11 +1163,130 @@ describe("Reusing setup params of BBS, BBS+ and accumulator", () => { expect(res.verified).toBe(true); } - it("generate and verify a proof of knowledge with BBS+ and accumulator using setup parameters", () => { + it("generate and verify a proof of knowledge with BBS+ signature and accumulator using setup parameters", () => { check(bbsPlusSignG1, generateSetupParamForBBSPlusSignatureParametersG1, generateSetupParamForBBSPlusPublicKeyG2, generatePoKBBSPlusSignatureStatementFromParamRefs, generatePoKBBSPlusSignatureWitness) }); - it("generate and verify a proof of knowledge with BBS and accumulator using setup parameters", () => { + it("generate and verify a proof of knowledge with BBS signature and accumulator using setup parameters", () => { check(bbsSign, generateSetupParamForBBSSignatureParameters, generateSetupParamForBBSPlusPublicKeyG2, generatePoKBBSSignatureStatementFromParamRefs, generatePoKBBSSignatureWitness) }); }); + +describe("Proving knowledge of signature and inequality of a signed message with a public value", () => { + const check = ( + setup, + sign, + buildStatement, + buildWitness, + ) => { + let [sigParams, sk, pk, messages] = setup( + 5, + "Message", + true + ); + + let comm_key = generatePedersenCommKeyG1(stringToBytes('test'), true); + const sig = sign(messages, sk, sigParams, false); + + const revealedIndices = new Set(); + revealedIndices.add(0); + + const [revealedMsgs, unrevealedMsgs] = getRevealedUnrevealed( + messages, + revealedIndices + ); + + const inequalMsgIdx = 1; + const inequalTo = generateRandomFieldElement(); + expect(messages[inequalMsgIdx]).not.toEqual(inequalTo); + + const statement1 = buildStatement( + sigParams, + pk, + revealedMsgs, + false + ); + const statement2 = generatePublicInequalityG1Statement(inequalTo, comm_key, true); + + const metaStatements: Uint8Array[] = []; + + const set = new Set<[number, number]>(); + set.add([0, inequalMsgIdx]); + set.add([1, 0]); + metaStatements.push(generateWitnessEqualityMetaStatement(set)); + + const statements: Uint8Array[] = []; + statements.push(statement1); + statements.push(statement2); + + const context = stringToBytes("test-context"); + const proofSpec = generateProofSpecG1( + statements, + metaStatements, + [], + context + ); + + expect(isProofSpecG1Valid(proofSpec)).toEqual(true); + + const witness1 = buildWitness( + sig, + unrevealedMsgs, + false + ); + const witness2 = generatePublicInequalityWitness(messages[inequalMsgIdx]); + + const witnesses: Uint8Array[] = []; + witnesses.push(witness1); + witnesses.push(witness2); + + const nonce = stringToBytes("test-nonce"); + + const proof = generateCompositeProofG1(proofSpec, witnesses, nonce); + const res = verifyCompositeProofG1(proof, proofSpec, nonce); + expect(res.verified).toBe(true); + }; + + beforeAll(async () => { + await initializeWasm(); + }); + + it("when BBS signatures", () => { + check( + setupBBS, + bbsSign, + generatePoKBBSSignatureStatement, + generatePoKBBSSignatureWitness, + ); + check( + setupBBS, + bbsSign, + generatePoKBBSSignatureStatement, + generatePoKBBSSignatureWitness, + ); + }); + + it("when BBS+ signatures", () => { + check( + setupBBSPlus, + bbsPlusSignG1, + generatePoKBBSPlusSignatureStatement, + generatePoKBBSPlusSignatureWitness, + ); + check( + setupBBSPlus, + bbsPlusSignG1, + generatePoKBBSPlusSignatureStatement, + generatePoKBBSPlusSignatureWitness, + ); + }); + + it("when PS signatures", () => { + check( + setupPS, + psSign, + generatePoKPSSignatureStatement, + generatePoKPSSignatureWitness, + ); + }); +}); \ No newline at end of file