From 8483d600a161543ce470346ce2466fe29c257dfd Mon Sep 17 00:00:00 2001 From: 0xturboblitz Date: Sun, 12 May 2024 12:43:04 +0900 Subject: [PATCH] selecting zkey_path, witness_calculator and dat_file_name outside of native modules --- .../java/com/awesomeproject/ProverModule.kt | 32 ++++++++++---- ...passport_dat.dat => proof_of_passport.dat} | Bin app/ios/Prover.m | 6 ++- app/ios/Prover.swift | 39 +++++++++++++----- app/scripts/build_android_module.sh | 2 +- app/src/utils/prover.ts | 13 +++++- 6 files changed, 70 insertions(+), 22 deletions(-) rename app/android/app/src/main/res/raw/{proof_of_passport_dat.dat => proof_of_passport.dat} (100%) diff --git a/app/android/app/src/main/java/com/awesomeproject/ProverModule.kt b/app/android/app/src/main/java/com/awesomeproject/ProverModule.kt index 0ded80ab0..1915ef7dd 100644 --- a/app/android/app/src/main/java/com/awesomeproject/ProverModule.kt +++ b/app/android/app/src/main/java/com/awesomeproject/ProverModule.kt @@ -22,14 +22,16 @@ import com.proofofpassport.R class ProverModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { private val TAG = "ProverModule" - lateinit var res: GenerateProofResult override fun getName(): String { return "Prover" } @ReactMethod - fun runProveAction(inputs: ReadableMap, promise: Promise) { + fun runProveAction(zkey_path: String, witness_calculator: String, dat_file_name: String, inputs: ReadableMap, promise: Promise) { + Log.e(TAG, "zkey_path in provePassport kotlin: " + zkey_path) + Log.e(TAG, "witness_calculator in provePassport kotlin: " + witness_calculator) + Log.e(TAG, "dat_file_name in provePassport kotlin: " + dat_file_name) Log.e(TAG, "inputs in provePassport kotlin: " + inputs.toString()) val formattedInputs = mutableMapOf( @@ -71,11 +73,24 @@ class ProverModule(reactContext: ReactApplicationContext) : ReactContextBaseJava val jsonInputs = gson.toJson(formattedInputs).toByteArray() val zkpTools = ZKPTools(reactApplicationContext) + + val witnessCalcFunction = when (witness_calculator) { + "proof_of_passport" -> zkpTools::witnesscalc_proof_of_passport + // "another_calculator" -> zkpTools::witnesscalc_another_calculator + else -> throw IllegalArgumentException("Invalid witness calculator name") + } + // Get the resource ID dynamically + val resId = reactApplicationContext.resources.getIdentifier(dat_file_name, "raw", reactApplicationContext.packageName) + if (resId == 0) { + throw IllegalArgumentException("Invalid dat file name") + } + val zkp: ZkProof = ZKPUseCase(reactApplicationContext).generateZKP( - R.raw.proof_of_passport_dat, // datID as Int + zkey_path, + resId, jsonInputs, - zkpTools::witnesscalc_proof_of_passport + witnessCalcFunction ) Log.e("ZKP", gson.toJson(zkp)) @@ -163,7 +178,10 @@ class ZKPTools(val context: Context) { class ZKPUseCase(val context: Context) { fun generateZKP( - datFile: Int, inputs: ByteArray, proofFunction: ( + zkey_path: String, + datId: Int, + inputs: ByteArray, + proofFunction: ( circuitBuffer: ByteArray, circuitSize: Long, jsonBuffer: ByteArray, @@ -175,7 +193,7 @@ class ZKPUseCase(val context: Context) { ) -> Int ): ZkProof { val zkpTool = ZKPTools(context) - val datFile = zkpTool.openRawResourceAsByteArray(datFile) + val datFile = zkpTool.openRawResourceAsByteArray(datId) val msg = ByteArray(256) @@ -218,7 +236,7 @@ class ZKPUseCase(val context: Context) { val witnessData = byteArr.copyOfRange(0, witnessLen[0].toInt()) val verification = zkpTool.groth16_prover_zkey_file( - "/data/user/0/com.proofofpassport/files/proof_of_passport.zkey", + zkey_path, witnessData, witnessLen[0], proofData, diff --git a/app/android/app/src/main/res/raw/proof_of_passport_dat.dat b/app/android/app/src/main/res/raw/proof_of_passport.dat similarity index 100% rename from app/android/app/src/main/res/raw/proof_of_passport_dat.dat rename to app/android/app/src/main/res/raw/proof_of_passport.dat diff --git a/app/ios/Prover.m b/app/ios/Prover.m index 7def067eb..87bae0919 100644 --- a/app/ios/Prover.m +++ b/app/ios/Prover.m @@ -10,10 +10,12 @@ @interface RCT_EXTERN_MODULE(Prover, NSObject) -RCT_EXTERN_METHOD(runProveAction:(NSDictionary *)inputs +RCT_EXTERN_METHOD(runProveAction:(NSString *)zkey_path + witness_calculator:(NSString *)witness_calculator + dat_file_name:(NSString *)dat_file_name + inputs:(NSDictionary *)inputs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) - + (BOOL) requiresMainQueueSetup { return YES; } diff --git a/app/ios/Prover.swift b/app/ios/Prover.swift index 03a3c0817..ccfee59f4 100644 --- a/app/ios/Prover.swift +++ b/app/ios/Prover.swift @@ -35,16 +35,20 @@ struct Proof: Codable { @objc(Prover) class Prover: NSObject { @objc(runProveAction:resolve:reject:) - func runProveAction(_ inputs: [String: [String]], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + func runProveAction(_ zkey_path: String, witness_calculator: String, dat_file_name: String, inputs: [String: [String]], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { let inputsJson = try! JSONEncoder().encode(inputs) print("inputs size: \(inputsJson.count) bytes") print("inputs data: \(String(data: inputsJson, encoding: .utf8) ?? "")") - let wtns = try! calcWtns(inputsJson: inputsJson) + let wtns = try! calcWtns( + witness_calculator: witness_calculator, + dat_file_name: dat_file_name, + inputsJson: inputsJson + ) print("wtns size: \(wtns.count) bytes") - let (proofRaw, pubSignalsRaw) = try groth16prove(wtns: wtns) + let (proofRaw, pubSignalsRaw) = try groth16prove(zkey_path: zkey_path, wtns: wtns) let proof = try JSONDecoder().decode(Proof.self, from: proofRaw) let pubSignals = try JSONDecoder().decode([String].self, from: pubSignalsRaw) @@ -68,12 +72,12 @@ class Prover: NSObject { } } -public func calcWtns(inputsJson: Data) throws -> Data { - let dat = NSDataAsset(name: "proof_of_passport.dat")!.data +public func calcWtns(witness_calculator: String, dat_file_name: String, inputsJson: Data) throws -> Data { + let dat = NSDataAsset(name: dat_file_name + ".dat")!.data return try _calcWtns(dat: dat, jsonData: inputsJson) } -private func _calcWtns(dat: Data, jsonData: Data) throws -> Data { +private func _calcWtns(witness_calculator: String, dat: Data, jsonData: Data) throws -> Data { let datSize = UInt(dat.count) let jsonDataSize = UInt(jsonData.count) @@ -85,7 +89,9 @@ private func _calcWtns(dat: Data, jsonData: Data) throws -> Data { let wtnsBuffer = UnsafeMutablePointer.allocate(capacity: (100 * 1024 * 1024)) let errorBuffer = UnsafeMutablePointer.allocate(capacity: Int(errorSize)) - let result = witnesscalc_proof_of_passport( + let witnessFunction = selectWitnessFunction(named: witness_calculator) + + let result = witnessFunction( (dat as NSData).bytes, datSize, (jsonData as NSData).bytes, jsonDataSize, wtnsBuffer, wtnsSize, @@ -105,11 +111,22 @@ private func _calcWtns(dat: Data, jsonData: Data) throws -> Data { return Data(bytes: wtnsBuffer, count: Int(wtnsSize.pointee)) } -public func groth16prove(wtns: Data) throws -> (proof: Data, publicInputs: Data) { - let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - let zkeyURL = documentsPath.appendingPathComponent("proof_of_passport.zkey") +private func selectWitnessFunction(named witness_calculator: String) -> (UnsafeRawPointer?, UInt, UnsafeRawPointer?, UInt, UnsafeMutablePointer?, UnsafeMutablePointer?, UnsafeMutablePointer?, UInt) -> Int32 { + switch witness_calculator { + case "proof_of_passport": + return witnesscalc_proof_of_passport + // case "another_calculator": + // return witnesscalc_another_calculator + default: + fatalError("Invalid witness calculator name") + } +} + +public func groth16prove(zkey_path: String, wtns: Data) throws -> (proof: Data, publicInputs: Data) { + // let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + // let zkeyURL = documentsPath.appendingPathComponent("proof_of_passport.zkey") - guard let zkeyData = try? Data(contentsOf: zkeyURL) else { + guard let zkeyData = try? Data(contentsOf: zkey_path) else { throw NSError(domain: "YourErrorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to load zkey file."]) } diff --git a/app/scripts/build_android_module.sh b/app/scripts/build_android_module.sh index 3e64a4120..83e2ff3c2 100755 --- a/app/scripts/build_android_module.sh +++ b/app/scripts/build_android_module.sh @@ -28,4 +28,4 @@ cd witnesscalc make android cd .. -cp ../circuits/build/proof_of_passport_cpp/proof_of_passport.dat android/app/src/main/res/raw/proof_of_passport_dat.dat +cp ../circuits/build/proof_of_passport_cpp/proof_of_passport.dat android/app/src/main/res/raw/proof_of_passport.dat diff --git a/app/src/utils/prover.ts b/app/src/utils/prover.ts index 5185be8b0..584963571 100644 --- a/app/src/utils/prover.ts +++ b/app/src/utils/prover.ts @@ -4,6 +4,7 @@ import { generateCircuitInputs } from '../../../common/src/utils/generateInputs' import { Steps } from './utils'; import { PassportData, Proof } from '../../../common/src/utils/types'; import * as amplitude from '@amplitude/analytics-react-native'; +import RNFS from 'react-native-fs'; interface ProverProps { passportData: PassportData | null; @@ -86,8 +87,18 @@ const generateProof = async ( console.log('launching generateProof function'); console.log('inputs in App.tsx', inputs); + const zkey_path = RNFS.DocumentDirectoryPath + '/proof_of_passport.zkey' + // "/data/user/0/com.proofofpassport/files/proof_of_passport.zkey" on android + const witness_calculator = "proof_of_passport" + const dat_file_name = "proof_of_passport" + const startTime = Date.now(); - const response = await NativeModules.Prover.runProveAction(inputs); + const response = await NativeModules.Prover.runProveAction( + zkey_path, + witness_calculator, + dat_file_name, + inputs + ); const endTime = Date.now(); console.log('time spent:', endTime - startTime); console.log('proof response:', response);