diff --git a/fhevm-engine/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json b/fhevm-engine/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json new file mode 100644 index 00000000..d62bdaf0 --- /dev/null +++ b/fhevm-engine/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT sks_key\n FROM tenants\n WHERE tenant_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "sks_key", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085" +} diff --git a/fhevm-engine/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json b/fhevm-engine/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json new file mode 100644 index 00000000..46c65d99 --- /dev/null +++ b/fhevm-engine/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT tenant_id, chain_id, verifying_contract_address, pks_key, sks_key\n FROM tenants\n WHERE tenant_id = ANY($1::INT[])\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "tenant_id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "chain_id", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "verifying_contract_address", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "pks_key", + "type_info": "Bytea" + }, + { + "ordinal": 4, + "name": "sks_key", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int4Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653" +} diff --git a/fhevm-engine/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json b/fhevm-engine/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json new file mode 100644 index 00000000..71964737 --- /dev/null +++ b/fhevm-engine/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json @@ -0,0 +1,18 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO ciphertexts(tenant_id, handle, ciphertext, ciphertext_version, ciphertext_type)\n VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (tenant_id, handle, ciphertext_version) DO NOTHING\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4", + "Bytea", + "Bytea", + "Int2", + "Int2" + ] + }, + "nullable": [] + }, + "hash": "db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77" +} diff --git a/fhevm-engine/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json b/fhevm-engine/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json new file mode 100644 index 00000000..c550bd0c --- /dev/null +++ b/fhevm-engine/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT tenant_id, output_handle, dependencies, fhe_operation, is_scalar\n FROM computations c\n WHERE is_completed = false\n AND is_error = false\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(c.dependencies) WITH ORDINALITY AS elems(v, dep_index)\n WHERE (c.tenant_id, elems.v) NOT IN ( SELECT tenant_id, handle FROM ciphertexts )\n -- don't select scalar operands\n AND (\n NOT c.is_scalar\n OR c.is_scalar AND NOT elems.dep_index = 2\n )\n -- ignore fhe random operations, all inputs are scalars\n AND NOT c.fhe_operation = ANY(ARRAY[26, 27])\n )\n LIMIT $1\n FOR UPDATE SKIP LOCKED\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "tenant_id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "output_handle", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "dependencies", + "type_info": "ByteaArray" + }, + { + "ordinal": 3, + "name": "fhe_operation", + "type_info": "Int2" + }, + { + "ordinal": 4, + "name": "is_scalar", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31" +} diff --git a/fhevm-engine/Cargo.lock b/fhevm-engine/Cargo.lock index d1bf90b9..399b1c4a 100644 --- a/fhevm-engine/Cargo.lock +++ b/fhevm-engine/Cargo.lock @@ -1964,6 +1964,8 @@ dependencies = [ "bigdecimal", "bincode", "hex", + "rand", + "rand_chacha", "sha3", "strum", "tfhe", diff --git a/fhevm-engine/Cargo.toml b/fhevm-engine/Cargo.toml index bbebd54f..5a674ab2 100644 --- a/fhevm-engine/Cargo.toml +++ b/fhevm-engine/Cargo.toml @@ -13,4 +13,10 @@ anyhow = "1.0.86" daggy = "0.8.0" [profile.dev.package.tfhe] -overflow-checks = false \ No newline at end of file +overflow-checks = false + +# for testing in release mode due to too big +# binary inside mac +[profile.release] +opt-level = "z" +lto = true \ No newline at end of file diff --git a/fhevm-engine/coprocessor/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json b/fhevm-engine/coprocessor/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json new file mode 100644 index 00000000..d62bdaf0 --- /dev/null +++ b/fhevm-engine/coprocessor/.sqlx/query-4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT sks_key\n FROM tenants\n WHERE tenant_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "sks_key", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "4b48296e5ecf0a6e6a50aefdaa83f6ae667cb0b284ec64ddfbd68da697573085" +} diff --git a/fhevm-engine/coprocessor/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json b/fhevm-engine/coprocessor/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json new file mode 100644 index 00000000..46c65d99 --- /dev/null +++ b/fhevm-engine/coprocessor/.sqlx/query-b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT tenant_id, chain_id, verifying_contract_address, pks_key, sks_key\n FROM tenants\n WHERE tenant_id = ANY($1::INT[])\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "tenant_id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "chain_id", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "verifying_contract_address", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "pks_key", + "type_info": "Bytea" + }, + { + "ordinal": 4, + "name": "sks_key", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int4Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "b3c087db688b8b51227d7ed02f53e5361d4454a700260d10b3c7eed6f5cd6653" +} diff --git a/fhevm-engine/coprocessor/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json b/fhevm-engine/coprocessor/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json new file mode 100644 index 00000000..71964737 --- /dev/null +++ b/fhevm-engine/coprocessor/.sqlx/query-db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77.json @@ -0,0 +1,18 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO ciphertexts(tenant_id, handle, ciphertext, ciphertext_version, ciphertext_type)\n VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (tenant_id, handle, ciphertext_version) DO NOTHING\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4", + "Bytea", + "Bytea", + "Int2", + "Int2" + ] + }, + "nullable": [] + }, + "hash": "db0e921f5b61687985de3df888422087f047078cdb7adb1320c5ec276dc99c77" +} diff --git a/fhevm-engine/coprocessor/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json b/fhevm-engine/coprocessor/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json new file mode 100644 index 00000000..c550bd0c --- /dev/null +++ b/fhevm-engine/coprocessor/.sqlx/query-f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT tenant_id, output_handle, dependencies, fhe_operation, is_scalar\n FROM computations c\n WHERE is_completed = false\n AND is_error = false\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(c.dependencies) WITH ORDINALITY AS elems(v, dep_index)\n WHERE (c.tenant_id, elems.v) NOT IN ( SELECT tenant_id, handle FROM ciphertexts )\n -- don't select scalar operands\n AND (\n NOT c.is_scalar\n OR c.is_scalar AND NOT elems.dep_index = 2\n )\n -- ignore fhe random operations, all inputs are scalars\n AND NOT c.fhe_operation = ANY(ARRAY[26, 27])\n )\n LIMIT $1\n FOR UPDATE SKIP LOCKED\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "tenant_id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "output_handle", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "dependencies", + "type_info": "ByteaArray" + }, + { + "ordinal": 3, + "name": "fhe_operation", + "type_info": "Int2" + }, + { + "ordinal": 4, + "name": "is_scalar", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "f4c7f18af089735e942488b1c643064fd0ea38f3b1e908344002701ab6ce5f31" +} diff --git a/fhevm-engine/coprocessor/Makefile b/fhevm-engine/coprocessor/Makefile index e9511433..09d1ab1d 100644 --- a/fhevm-engine/coprocessor/Makefile +++ b/fhevm-engine/coprocessor/Makefile @@ -19,6 +19,11 @@ recreate_db: $(MAKE) cleanup $(MAKE) init_db +.PHONY: docker_compose_setup +docker_compose_setup: + $(MAKE) init_db + DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/coprocessor cargo test setup_test_user -- --nocapture --ignored + .PHONY: clean_run clean_run: $(MAKE) recreate_db diff --git a/fhevm-engine/coprocessor/docker-compose.yml b/fhevm-engine/coprocessor/docker-compose.yml index 78ebb2b2..c80c9453 100644 --- a/fhevm-engine/coprocessor/docker-compose.yml +++ b/fhevm-engine/coprocessor/docker-compose.yml @@ -16,10 +16,20 @@ services: - DATABASE_URL=postgresql://postgres:postgres@db:5432/coprocessor ports: - '50051:50051' + volumes: + - ${PWD}/coprocessor.key:/usr/share/coprocessor.key command: - --run-bg-worker - --run-server - --server-addr=0.0.0.0:50051 + - --coprocessor-key=/usr/share/coprocessor.key + geth: + image: custom-devnet:v1 + environment: + - FHEVM_COPROCESSOR_API_KEY=a1503fb6-d79b-4e9e-826d-44cf262f3e05 + - FHEVM_COPROCESSOR_URL=coproc:50051 + ports: + - '8545:8545' volumes: db: driver: local diff --git a/fhevm-engine/coprocessor/migrations/20240723111257_coprocessor.sql b/fhevm-engine/coprocessor/migrations/20240723111257_coprocessor.sql deleted file mode 100644 index 0ba14271..00000000 --- a/fhevm-engine/coprocessor/migrations/20240723111257_coprocessor.sql +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:68bf6fb0ef64b629a0ff622c7c5ef900118d32fe77baa9e34c8660bc43cce641 -size 530459546 diff --git a/fhevm-engine/coprocessor/migrations/gen-keys.sh b/fhevm-engine/coprocessor/migrations/gen-keys.sh deleted file mode 100755 index dd1f28d7..00000000 --- a/fhevm-engine/coprocessor/migrations/gen-keys.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -echo " -INSERT INTO tenants(tenant_api_key, chain_id, verifying_contract_address, pks_key, sks_key, cks_key) -VALUES ( - 'a1503fb6-d79b-4e9e-826d-44cf262f3e05', - 12345, - '0x6819e3aDc437fAf9D533490eD3a7552493fCE3B1', - decode('$(cat ../../fhevm-keys/pks | xxd -p | tr -d '\n')','hex'), - decode('$(cat ../../fhevm-keys/sks | xxd -p | tr -d '\n')','hex'), - decode('$(cat ../../fhevm-keys/cks | xxd -p | tr -d '\n')','hex') -) -" > 20240723111257_coprocessor.sql diff --git a/fhevm-engine/coprocessor/src/db_queries.rs b/fhevm-engine/coprocessor/src/db_queries.rs index 9d8b96cb..464c532a 100644 --- a/fhevm-engine/coprocessor/src/db_queries.rs +++ b/fhevm-engine/coprocessor/src/db_queries.rs @@ -101,9 +101,13 @@ pub struct FetchTenantKeyResult { } /// Returns chain id and verifying contract address for EIP712 signature and tfhe server key -pub async fn fetch_tenant_server_key<'a, T>(tenant_id: i32, pool: T, tenant_key_cache: &std::sync::Arc>>) --> Result> -where T: sqlx::PgExecutor<'a> + Copy +pub async fn fetch_tenant_server_key<'a, T>( + tenant_id: i32, + pool: T, + tenant_key_cache: &std::sync::Arc>>, +) -> Result> +where + T: sqlx::PgExecutor<'a> + Copy, { // try getting from cache until it succeeds with populating cache loop { @@ -122,9 +126,12 @@ where T: sqlx::PgExecutor<'a> + Copy } } -pub async fn query_tenant_keys<'a, T>(tenants_to_query: Vec, conn: T) --> Result, Box> -where T: sqlx::PgExecutor<'a> +pub async fn query_tenant_keys<'a, T>( + tenants_to_query: Vec, + conn: T, +) -> Result, Box> +where + T: sqlx::PgExecutor<'a>, { let mut res = Vec::with_capacity(tenants_to_query.len()); let keys = query!( @@ -145,7 +152,8 @@ where T: sqlx::PgExecutor<'a> .expect("We can't deserialize our own validated pks key"); res.push(TfheTenantKeys { tenant_id: key.tenant_id, - sks, pks, + sks, + pks, chain_id: key.chain_id, verifying_contract_address: key.verifying_contract_address, }); @@ -154,9 +162,13 @@ where T: sqlx::PgExecutor<'a> Ok(res) } -pub async fn populate_cache_with_tenant_keys<'a, T>(tenants_to_query: Vec, conn: T, tenant_key_cache: &std::sync::Arc>>) --> Result<(), Box> -where T: sqlx::PgExecutor<'a> +pub async fn populate_cache_with_tenant_keys<'a, T>( + tenants_to_query: Vec, + conn: T, + tenant_key_cache: &std::sync::Arc>>, +) -> Result<(), Box> +where + T: sqlx::PgExecutor<'a>, { if !tenants_to_query.is_empty() { let keys = query_tenant_keys(tenants_to_query, conn).await?; @@ -174,4 +186,4 @@ where T: sqlx::PgExecutor<'a> } Ok(()) -} \ No newline at end of file +} diff --git a/fhevm-engine/coprocessor/src/server.rs b/fhevm-engine/coprocessor/src/server.rs index 0b2b3df0..ff6d989b 100644 --- a/fhevm-engine/coprocessor/src/server.rs +++ b/fhevm-engine/coprocessor/src/server.rs @@ -1,20 +1,26 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::num::NonZeroUsize; use std::str::FromStr; -use crate::db_queries::{check_if_api_key_is_valid, check_if_ciphertexts_exist_in_db, fetch_tenant_server_key}; +use crate::db_queries::{ + check_if_api_key_is_valid, check_if_ciphertexts_exist_in_db, fetch_tenant_server_key, +}; use crate::server::coprocessor::GenericResponse; +use crate::types::{CoprocessorError, TfheTenantKeys}; +use crate::utils::sort_computations_by_dependencies; use alloy::signers::local::PrivateKeySigner; use alloy::signers::SignerSync; use alloy::sol_types::SolStruct; -use bigdecimal::num_bigint::BigUint; -use fhevm_engine_common::tfhe_ops::{check_fhe_operand_types, current_ciphertext_version, debug_trivial_encrypt_be_bytes, deserialize_fhe_ciphertext, try_expand_ciphertext_list}; -use fhevm_engine_common::types::{FhevmError, SupportedFheCiphertexts}; -use sha3::{Digest, Keccak256}; -use crate::types::{CoprocessorError, TfheTenantKeys}; -use crate::utils::sort_computations_by_dependencies; use coprocessor::async_computation_input::Input; -use coprocessor::{DebugDecryptResponse, DebugDecryptResponseSingle, InputCiphertextResponse, InputCiphertextResponseHandle, InputUploadBatch, InputUploadResponse}; +use coprocessor::{ + InputCiphertextResponse, InputCiphertextResponseHandle, InputUploadBatch, InputUploadResponse, +}; +use fhevm_engine_common::tfhe_ops::{ + check_fhe_operand_types, current_ciphertext_version, trivial_encrypt_be_bytes, + try_expand_ciphertext_list, validate_fhe_type, +}; +use fhevm_engine_common::types::{FhevmError, SupportedFheCiphertexts, SupportedFheOperations}; +use sha3::{Digest, Keccak256}; use sqlx::{query, Acquire}; use tonic::transport::Server; @@ -42,9 +48,7 @@ pub async fn run_server( .expect("Can't parse server address"); let db_url = crate::utils::db_url(&args); - let coprocessor_key_file = - tokio::fs::read_to_string(&args.coprocessor_private_key) - .await?; + let coprocessor_key_file = tokio::fs::read_to_string(&args.coprocessor_private_key).await?; let signer = PrivateKeySigner::from_str(coprocessor_key_file.trim())?; println!("Coprocessor signer address: {}", signer.address()); @@ -60,7 +64,12 @@ pub async fn run_server( NonZeroUsize::new(args.tenant_key_cache_size as usize).unwrap(), ))); - let service = CoprocessorService { pool, args, tenant_key_cache, signer }; + let service = CoprocessorService { + pool, + args, + tenant_key_cache, + signer, + }; Server::builder() .add_service( @@ -126,7 +135,7 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ } let mut response = InputUploadResponse { - upload_responses: Vec::with_capacity(req.input_ciphertexts.len()) + upload_responses: Vec::with_capacity(req.input_ciphertexts.len()), }; if req.input_ciphertexts.is_empty() { return Ok(tonic::Response::new(response)); @@ -135,19 +144,19 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ let fetch_key_response = { fetch_tenant_server_key(tenant_id, &self.pool, &self.tenant_key_cache) .await - .map_err(|e| { - tonic::Status::from_error(e) - })? + .map_err(|e| tonic::Status::from_error(e))? }; let chain_id = fetch_key_response.chain_id; let server_key = fetch_key_response.server_key; let verifying_contract_address = fetch_key_response.verifying_contract_address; - let verifying_contract_address = alloy::primitives::Address::from_str(&verifying_contract_address) - .map_err(|e| { - tonic::Status::from_error(Box::new(CoprocessorError::CannotParseTenantEthereumAddress { - bad_address: verifying_contract_address.clone(), - parsing_error: e.to_string(), - })) + let verifying_contract_address = + alloy::primitives::Address::from_str(&verifying_contract_address).map_err(|e| { + tonic::Status::from_error(Box::new( + CoprocessorError::CannotParseTenantEthereumAddress { + bad_address: verifying_contract_address.clone(), + parsing_error: e.to_string(), + }, + )) })?; let eip_712_domain = alloy::sol_types::eip712_domain! { @@ -165,20 +174,22 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ let mut caller_addresses = Vec::with_capacity(req.input_ciphertexts.len()); for ci in &req.input_ciphertexts { // parse addresses - contract_addresses.push(alloy::primitives::Address::from_str(&ci.contract_address) - .map_err(|e| { + contract_addresses.push( + alloy::primitives::Address::from_str(&ci.contract_address).map_err(|e| { CoprocessorError::CannotParseEthereumAddress { bad_address: ci.contract_address.clone(), parsing_error: e.to_string(), } - })?); - caller_addresses.push(alloy::primitives::Address::from_str(&ci.caller_address) - .map_err(|e| { + })?, + ); + caller_addresses.push( + alloy::primitives::Address::from_str(&ci.caller_address).map_err(|e| { CoprocessorError::CannotParseEthereumAddress { bad_address: ci.contract_address.clone(), parsing_error: e.to_string(), } - })?); + })?, + ); } for (idx, ci) in req.input_ciphertexts.iter().enumerate() { @@ -200,44 +211,66 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ let mut results: BTreeMap> = BTreeMap::new(); while let Some(output) = tfhe_work_set.join_next().await { - let (cts, idx) = output.map_err(|e| { - let err: Box<(dyn std::error::Error + Sync + Send)> = Box::new(e); - tonic::Status::from_error(err) - })?.map_err(|e| { - tonic::Status::from_error(e.0) - })?; + let (cts, idx) = output + .map_err(|e| { + let err: Box<(dyn std::error::Error + Sync + Send)> = Box::new(e); + tonic::Status::from_error(err) + })? + .map_err(|e| tonic::Status::from_error(e.0))?; if cts.len() > self.args.maximum_handles_per_input as usize { - return Err(tonic::Status::from_error( - Box::new(CoprocessorError::CompactInputCiphertextHasMoreCiphertextThanLimitAllows { + return Err(tonic::Status::from_error(Box::new( + CoprocessorError::CompactInputCiphertextHasMoreCiphertextThanLimitAllows { input_blob_index: idx, input_ciphertexts_in_blob: cts.len(), - input_maximum_ciphertexts_allowed: self.args.maximum_handles_per_input as usize, - }) - )); + input_maximum_ciphertexts_allowed: self.args.maximum_handles_per_input + as usize, + }, + ))); } - assert!(results.insert(idx, cts).is_none(), "fresh map, we passed vector ordered by indexes before"); + assert!( + results.insert(idx, cts).is_none(), + "fresh map, we passed vector ordered by indexes before" + ); } - assert_eq!(results.len(), req.input_ciphertexts.len(), "We should have all the ciphertexts now"); + assert_eq!( + results.len(), + req.input_ciphertexts.len(), + "We should have all the ciphertexts now" + ); - let mut trx = self.pool.begin().await.map_err(Into::::into)?; + let mut trx = self + .pool + .begin() + .await + .map_err(Into::::into)?; for (idx, input_blob) in req.input_ciphertexts.iter().enumerate() { let mut state = Keccak256::new(); state.update(&input_blob.input_payload); let blob_hash = state.finalize().to_vec(); assert_eq!(blob_hash.len(), 32, "should be 32 bytes"); - let corresponding_unpacked = results.get(&idx).expect("we should have all results computed now"); + let corresponding_unpacked = results + .get(&idx) + .expect("we should have all results computed now"); // save blob for audits and historical reference - let _ = sqlx::query!(" + let _ = sqlx::query!( + " INSERT INTO input_blobs(tenant_id, blob_hash, blob_data, blob_ciphertext_count) VALUES($1, $2, $3, $4) ON CONFLICT (tenant_id, blob_hash) DO NOTHING - ", tenant_id, &blob_hash, &input_blob.input_payload, corresponding_unpacked.len() as i32) - .execute(trx.as_mut()).await.map_err(Into::::into)?; + ", + tenant_id, + &blob_hash, + &input_blob.input_payload, + corresponding_unpacked.len() as i32 + ) + .execute(trx.as_mut()) + .await + .map_err(Into::::into)?; let mut ct_verification = CiphertextVerification { contractAddress: contract_addresses[idx], @@ -267,7 +300,8 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ handle[30] = serialized_type as u8; handle[31] = ciphertext_version as u8; - let _ = sqlx::query!(" + let _ = sqlx::query!( + " INSERT INTO ciphertexts( tenant_id, handle, @@ -279,10 +313,22 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ ) VALUES($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (tenant_id, handle, ciphertext_version) DO NOTHING - ", tenant_id, &handle, &serialized_ct, ciphertext_version, serialized_type, &blob_hash, ct_idx as i32) - .execute(trx.as_mut()).await.map_err(Into::::into)?; + ", + tenant_id, + &handle, + &serialized_ct, + ciphertext_version, + serialized_type, + &blob_hash, + ct_idx as i32 + ) + .execute(trx.as_mut()) + .await + .map_err(Into::::into)?; - ct_verification.handlesList.push(alloy::primitives::U256::from_be_slice(&handle)); + ct_verification + .handlesList + .push(alloy::primitives::U256::from_be_slice(&handle)); ct_resp.input_handles.push(InputCiphertextResponseHandle { handle: handle.to_vec(), ciphertext_type: serialized_type as i32, @@ -290,10 +336,11 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ } let signing_hash = ct_verification.eip712_signing_hash(&eip_712_domain); - let eip_712_signature = self.signer.sign_hash_sync(&signing_hash) - .map_err(|e| { - CoprocessorError::Eip712SigningFailure { error: e.to_string() } - })?; + let eip_712_signature = self.signer.sign_hash_sync(&signing_hash).map_err(|e| { + CoprocessorError::Eip712SigningFailure { + error: e.to_string(), + } + })?; ct_resp.eip712_signature = eip_712_signature.as_bytes().to_vec(); @@ -344,6 +391,10 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ let mut this_comp_inputs: Vec> = Vec::with_capacity(comp.inputs.len()); let mut is_scalar_op_vec: Vec = Vec::with_capacity(comp.inputs.len()); for (idx, ih) in comp.inputs.iter().enumerate() { + let fhe_op: SupportedFheOperations = comp + .operation + .try_into() + .map_err(|e| CoprocessorError::FhevmError(e))?; if let Some(input) = &ih.input { match input { Input::InputHandle(ih) => { @@ -359,7 +410,7 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ handle_types.push(-1); this_comp_inputs.push(sc.clone()); is_scalar_op_vec.push(true); - assert!(idx == 1, "we should have checked earlier that only second operand can be scalar"); + assert!(idx == 1 || fhe_op.is_random(), "we should have checked earlier that only second operand can be scalar"); } } } @@ -372,7 +423,8 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ &handle_types, &this_comp_inputs, &is_scalar_op_vec, - ).map_err(|e| CoprocessorError::FhevmError(e))?; + ) + .map_err(|e| CoprocessorError::FhevmError(e))?; computations_inputs.push(this_comp_inputs); are_comps_scalar.push(is_computation_scalar); @@ -393,10 +445,9 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ let output_type = ct_types .get(&comp.output_handle) .expect("we should have collected all output result types by now with check_fhe_operand_types"); - let fhe_operation: i16 = comp - .operation - .try_into() - .map_err(|_| CoprocessorError::FhevmError(FhevmError::UnknownFheOperation(comp.operation)))?; + let fhe_operation: i16 = comp.operation.try_into().map_err(|_| { + CoprocessorError::FhevmError(FhevmError::UnknownFheOperation(comp.operation)) + })?; let res = query!( " INSERT INTO computations( @@ -417,7 +468,10 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ fhe_operation, are_comps_scalar[idx], output_type - ).execute(trx.as_mut()).await.map_err(Into::::into)?; + ) + .execute(trx.as_mut()) + .await + .map_err(Into::::into)?; if res.rows_affected() > 0 { new_work_available = true; } @@ -439,17 +493,24 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ return Err(tonic::Status::unimplemented("not implemented")); } - // debug functions below, should be removed in production - async fn debug_encrypt_ciphertext( + async fn trivial_encrypt_ciphertexts( &self, - request: tonic::Request, + request: tonic::Request, ) -> std::result::Result, tonic::Status> { let tenant_id = check_if_api_key_is_valid(&request, &self.pool).await?; let req = request.get_ref(); + let mut unique_handles: BTreeSet<&[u8]> = BTreeSet::new(); + for val in &req.values { + validate_fhe_type(val.output_type).map_err(|e| CoprocessorError::FhevmError(e))?; + if !unique_handles.insert(&val.handle) { + return Err(CoprocessorError::DuplicateOutputHandleInBatch(format!("0x{}", hex::encode(&val.handle))).into()); + } + } + let mut public_key = sqlx::query!( " - SELECT sks_key, cks_key + SELECT sks_key FROM tenants WHERE tenant_id = $1 ", @@ -462,25 +523,15 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ assert_eq!(public_key.len(), 1); let public_key = public_key.pop().unwrap(); - - // for checking if decryption equals to trivial encryption value - let client_key: tfhe::ClientKey = bincode::deserialize(&public_key.cks_key.unwrap()).unwrap(); - let cloned = req.values.clone(); let out_cts = tokio::task::spawn_blocking(move || { let server_key: tfhe::ServerKey = bincode::deserialize(&public_key.sks_key).unwrap(); tfhe::set_server_key(server_key); - // single threaded implementation as this is debug function and it is simple to implement + // single threaded implementation, we can optimize later let mut res: Vec<(Vec, i16, Vec)> = Vec::with_capacity(cloned.len()); for v in cloned { - let the_num = BigUint::from_bytes_be(&v.be_value).to_string(); - let ct = debug_trivial_encrypt_be_bytes(v.output_type as i16, &v.be_value); - let decr = ct.decrypt(&client_key); - let fhe_bool_type = 0; - if v.output_type != fhe_bool_type { - assert_eq!(the_num, decr, "Trivial encryption must preserve the original value"); - } + let ct = trivial_encrypt_be_bytes(v.output_type as i16, &v.be_value); let (ct_type, ct_bytes) = ct.serialize(); res.push((v.handle, ct_type, ct_bytes)); } @@ -501,6 +552,7 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ sqlx::query!(" INSERT INTO ciphertexts(tenant_id, handle, ciphertext, ciphertext_version, ciphertext_type) VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (tenant_id, handle, ciphertext_version) DO NOTHING ", tenant_id, handle, db_bytes, current_ciphertext_version(), db_type as i16 ) @@ -511,122 +563,4 @@ impl coprocessor::fhevm_coprocessor_server::FhevmCoprocessor for CoprocessorServ return Ok(tonic::Response::new(GenericResponse { response_code: 0 })); } - - async fn debug_decrypt_ciphertext( - &self, - request: tonic::Request, - ) -> std::result::Result, tonic::Status> - { - let tenant_id = check_if_api_key_is_valid(&request, &self.pool).await?; - let req = request.get_ref(); - - let mut priv_key = sqlx::query!( - " - SELECT cks_key - FROM tenants - WHERE tenant_id = $1 - ", - tenant_id - ) - .fetch_all(&self.pool) - .await - .map_err(Into::::into)?; - - if priv_key.is_empty() || priv_key[0].cks_key.is_none() { - return Err(tonic::Status::not_found("tenant private key not found")); - } - - let mut ct_indexes: BTreeMap<&[u8], usize> = BTreeMap::new(); - for (idx, h) in req.handles.iter().enumerate() { - ct_indexes.insert(h.as_slice(), idx); - } - - assert_eq!(priv_key.len(), 1); - - let cts = sqlx::query!( - " - SELECT ciphertext, ciphertext_type, handle - FROM ciphertexts - WHERE tenant_id = $1 - AND handle = ANY($2::BYTEA[]) - AND ciphertext_version = $3 - ", - tenant_id, - &req.handles, - current_ciphertext_version() - ) - .fetch_all(&self.pool) - .await - .map_err(Into::::into)?; - - if cts.is_empty() { - return Err(tonic::Status::not_found("ciphertext not found")); - } - - let priv_key = priv_key.pop().unwrap().cks_key.unwrap(); - - let mut values = tokio::task::spawn_blocking(move || { - let client_key: tfhe::ClientKey = bincode::deserialize(&priv_key).unwrap(); - - let mut decrypted: Vec<(Vec, DebugDecryptResponseSingle)> = Vec::with_capacity(cts.len()); - for ct in cts { - let deserialized = - deserialize_fhe_ciphertext(ct.ciphertext_type, &ct.ciphertext) - .unwrap(); - decrypted.push((ct.handle, DebugDecryptResponseSingle { - output_type: ct.ciphertext_type as i32, - value: deserialized.decrypt(&client_key), - })); - } - - decrypted - }) - .await - .unwrap(); - - values.sort_by_key(|(h, _)| { - ct_indexes.get(h.as_slice()).unwrap() - }); - - let values = values.into_iter().map(|i| i.1).collect::>(); - - return Ok(tonic::Response::new(DebugDecryptResponse { values })); - } - - async fn upload_ciphertexts( - &self, - request: tonic::Request, - ) -> std::result::Result, tonic::Status> { - let tenant_id = check_if_api_key_is_valid(&request, &self.pool).await?; - - let req = request.get_ref(); - - // TODO: check if ciphertext deserializes into type correctly - // TODO: check for duplicate handles in the input - // TODO: check if ciphertext doesn't exist already - // TODO: if ciphertexts exists check that it is equal to the one being uploaded - - let mut trx = self - .pool - .begin() - .await - .map_err(Into::::into)?; - for i_ct in &req.input_ciphertexts { - let ciphertext_type: i16 = i_ct - .ciphertext_type - .try_into() - .map_err(|_e| CoprocessorError::FhevmError(FhevmError::UnknownFheType(i_ct.ciphertext_type)))?; - let _ = sqlx::query!(" - INSERT INTO ciphertexts(tenant_id, handle, ciphertext, ciphertext_version, ciphertext_type) - VALUES($1, $2, $3, $4, $5) - ON CONFLICT (tenant_id, handle, ciphertext_version) DO NOTHING - ", tenant_id, i_ct.ciphertext_handle, i_ct.ciphertext_bytes, current_ciphertext_version(), ciphertext_type) - .execute(trx.as_mut()).await.map_err(Into::::into)?; - } - - trx.commit().await.map_err(Into::::into)?; - - return Ok(tonic::Response::new(GenericResponse { response_code: 0 })); - } - } diff --git a/fhevm-engine/coprocessor/src/tests/errors.rs b/fhevm-engine/coprocessor/src/tests/errors.rs index 13e7d35c..a2086e1d 100644 --- a/fhevm-engine/coprocessor/src/tests/errors.rs +++ b/fhevm-engine/coprocessor/src/tests/errors.rs @@ -1,7 +1,21 @@ use std::str::FromStr; +use crate::{ + db_queries::query_tenant_keys, + server::{ + common::FheOperation, + coprocessor::{ + async_computation_input::Input, fhevm_coprocessor_client::FhevmCoprocessorClient, + AsyncComputation, AsyncComputationInput, AsyncComputeRequest, InputToUpload, + InputUploadBatch, + }, + }, + tests::{ + inputs::{test_random_caller_address, test_random_contract_address}, + utils::{default_api_key, default_tenant_id, setup_test_app}, + }, +}; use tonic::metadata::MetadataValue; -use crate::{db_queries::query_tenant_keys, server::{common::FheOperation, coprocessor::{async_computation_input::Input, fhevm_coprocessor_client::FhevmCoprocessorClient, AsyncComputation, AsyncComputationInput, AsyncComputeRequest, InputToUpload, InputUploadBatch}}, tests::{inputs::{test_random_caller_address, test_random_contract_address}, utils::{default_api_key, default_tenant_id, setup_test_app}}}; #[tokio::test] async fn test_coprocessor_input_errors() -> Result<(), Box> { @@ -13,13 +27,16 @@ async fn test_coprocessor_input_errors() -> Result<(), Box = e; - e - })?; + let keys = query_tenant_keys(vec![default_tenant_id()], &pool) + .await + .map_err(|e| { + let e: Box = e; + e + })?; let keys = &keys[0]; - { // too many uploads at once + { + // too many uploads at once let mut builder = tfhe::CompactCiphertextListBuilder::new(&keys.pks); let the_list = builder .push(false) @@ -42,9 +59,7 @@ async fn test_coprocessor_input_errors() -> Result<(), Box Result<(), Box { - assert!(e.to_string().contains("More than maximum input blobs uploaded, maximum allowed: 10, uploaded: 12")); + assert!(e.to_string().contains( + "More than maximum input blobs uploaded, maximum allowed: 10, uploaded: 12" + )); } Ok(_) => { panic!("Should not have succeeded") @@ -60,7 +77,8 @@ async fn test_coprocessor_input_errors() -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box { eprintln!("error: {e}"); - assert!(e.to_string().contains("Input blob contains too many ciphertexts")); + assert!(e + .to_string() + .contains("Input blob contains too many ciphertexts")); } Ok(_) => { panic!("Should not have succeeded") @@ -136,13 +153,12 @@ async fn test_coprocessor_input_errors() -> Result<(), Box Result<(), Box Result<(), Box { - assert!(e.to_string().contains("API key unknown/invalid/not provided")); + assert!(e + .to_string() + .contains("API key unknown/invalid/not provided")); } Ok(_) => { panic!("Should not have succeeded") @@ -180,7 +199,8 @@ async fn test_coprocessor_api_key_errors() -> Result<(), Box Result<(), Box { - assert!(e.to_string().contains("API key unknown/invalid/not provided")); + assert!(e + .to_string() + .contains("API key unknown/invalid/not provided")); } Ok(_) => { panic!("Should not have succeeded") @@ -201,7 +223,8 @@ async fn test_coprocessor_api_key_errors() -> Result<(), Box Result<(), Box { - assert!(e.to_string().contains("API key unknown/invalid/not provided")); + assert!(e + .to_string() + .contains("API key unknown/invalid/not provided")); } Ok(_) => { panic!("Should not have succeeded") @@ -236,10 +261,12 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box = e; - e - })?; + let keys = query_tenant_keys(vec![default_tenant_id()], &pool) + .await + .map_err(|e| { + let e: Box = e; + e + })?; let keys = &keys[0]; let mut handle_counter = 0; @@ -249,7 +276,8 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("has circular dependency and is uncomputable")); + assert!(e + .to_string() + .contains("has circular dependency and is uncomputable")); } } } - { // test invalid binary op between uncast types + { + // test invalid binary op between uncast types let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheAdd.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_u8.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(test_u16.handle.clone())), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheAdd.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::InputHandle(test_u8.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(test_u16.handle.clone())), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -383,27 +411,28 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: FheOperationDoesntHaveUniformTypesAsInput")); + assert!(e + .to_string() + .contains("fhevm error: FheOperationDoesntHaveUniformTypesAsInput")); } } } - { // empty ciphertext handle + { + // empty ciphertext handle let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheAdd.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_u32.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(vec![])), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheAdd.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::InputHandle(test_u32.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(vec![])), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -422,22 +451,21 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("Found ciphertext handle longer than 64 bytes")); + assert!(e + .to_string() + .contains("Found ciphertext handle longer than 64 bytes")); } } } - { // computation too many inputs + { + // computation too many inputs let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheAdd.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_u64.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(test_u64.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(test_u64.handle.clone())), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheAdd.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::InputHandle(test_u64.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(test_u64.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(test_u64.handle.clone())), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -488,27 +517,28 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: UnexpectedOperandCountForFheOperation")); + assert!(e + .to_string() + .contains("fhevm error: UnexpectedOperandCountForFheOperation")); } } } - { // scalar operand on the left + { + // scalar operand on the left let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheAdd.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::Scalar(vec![123])), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(test_u64.handle.clone())), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheAdd.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::Scalar(vec![123])), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(test_u64.handle.clone())), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -522,27 +552,28 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: FheOperationOnlySecondOperandCanBeScalar")); + assert!(e + .to_string() + .contains("fhevm error: FheOperationOnlySecondOperandCanBeScalar")); } } } - { // scalar division by zero + { + // scalar division by zero let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheDiv.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_u64.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::Scalar(vec![0])), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheDiv.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::InputHandle(test_u64.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::Scalar(vec![0])), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -556,27 +587,28 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: FheOperationScalarDivisionByZero")); + assert!(e + .to_string() + .contains("fhevm error: FheOperationScalarDivisionByZero")); } } } - { // binary boolean inputs + { + // binary boolean inputs let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheAdd.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_bool.handle.clone())), - }, - AsyncComputationInput { - input: Some(Input::InputHandle(test_bool.handle.clone())), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheAdd.into(), + output_handle: output_handle_a.clone(), + inputs: vec![ + AsyncComputationInput { + input: Some(Input::InputHandle(test_bool.handle.clone())), + }, + AsyncComputationInput { + input: Some(Input::InputHandle(test_bool.handle.clone())), + }, + ], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -590,24 +622,23 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: OperationDoesntSupportBooleanInputs")); + assert!(e + .to_string() + .contains("fhevm error: OperationDoesntSupportBooleanInputs")); } } } - { // unary boolean inputs + { + // unary boolean inputs let output_handle_a = next_handle(); - let async_computations = vec![ - AsyncComputation { - operation: FheOperation::FheNeg.into(), - output_handle: output_handle_a.clone(), - inputs: vec![ - AsyncComputationInput { - input: Some(Input::InputHandle(test_bool.handle.clone())), - }, - ], - }, - ]; + let async_computations = vec![AsyncComputation { + operation: FheOperation::FheNeg.into(), + output_handle: output_handle_a.clone(), + inputs: vec![AsyncComputationInput { + input: Some(Input::InputHandle(test_bool.handle.clone())), + }], + }]; let mut input_request = tonic::Request::new(AsyncComputeRequest { computations: async_computations, }); @@ -621,10 +652,12 @@ async fn test_coprocessor_computation_errors() -> Result<(), Box { eprintln!("error: {}", e); - assert!(e.to_string().contains("fhevm error: OperationDoesntSupportBooleanInputs")); + assert!(e + .to_string() + .contains("fhevm error: OperationDoesntSupportBooleanInputs")); } } } Ok(()) -} \ No newline at end of file +} diff --git a/fhevm-engine/coprocessor/src/tests/inputs.rs b/fhevm-engine/coprocessor/src/tests/inputs.rs index 3b2894a1..269bf34c 100644 --- a/fhevm-engine/coprocessor/src/tests/inputs.rs +++ b/fhevm-engine/coprocessor/src/tests/inputs.rs @@ -3,7 +3,13 @@ use std::str::FromStr; use tfhe::integer::{bigint::StaticUnsignedBigInt, U256}; use tonic::metadata::MetadataValue; -use crate::{db_queries::query_tenant_keys, server::coprocessor::{fhevm_coprocessor_client::FhevmCoprocessorClient, DebugDecryptRequest, InputToUpload, InputUploadBatch}, tests::utils::{default_api_key, default_tenant_id, setup_test_app}}; +use crate::{ + db_queries::query_tenant_keys, + server::coprocessor::{ + fhevm_coprocessor_client::FhevmCoprocessorClient, InputToUpload, InputUploadBatch, + }, + tests::utils::{decrypt_ciphertexts, default_api_key, default_tenant_id, setup_test_app}, +}; pub fn test_random_caller_address() -> String { let _private_key = "bd2400c676871534a682ca1c5e4cd647ec9c3e122f188c6e3f54e6900d586c7b"; @@ -25,10 +31,12 @@ async fn test_fhe_inputs() -> Result<(), Box> { .connect(app.db_url()) .await?; - let keys = query_tenant_keys(vec![default_tenant_id()], &pool).await.map_err(|e| { - let e: Box = e; - e - })?; + let keys = query_tenant_keys(vec![default_tenant_id()], &pool) + .await + .map_err(|e| { + let e: Box = e; + e + })?; let keys = &keys[0]; let mut builder = tfhe::CompactCiphertextListBuilder::new(&keys.pks); @@ -50,14 +58,12 @@ async fn test_fhe_inputs() -> Result<(), Box> { println!("Encrypting inputs..."); let mut input_request = tonic::Request::new(InputUploadBatch { - input_ciphertexts: vec![ - InputToUpload { - input_payload: serialized, - signature: Vec::new(), - caller_address: test_random_caller_address(), - contract_address: test_random_contract_address(), - } - ] + input_ciphertexts: vec![InputToUpload { + input_payload: serialized, + signature: Vec::new(), + caller_address: test_random_caller_address(), + contract_address: test_random_contract_address(), + }], }); input_request.metadata_mut().append( "authorization", @@ -76,37 +82,29 @@ async fn test_fhe_inputs() -> Result<(), Box> { decr_handles.push(handle.handle.clone()); } - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: decr_handles, - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; - let resp = resp.get_ref(); - assert_eq!(resp.values.len(), 10); - - assert_eq!(resp.values[0].output_type, 0); - assert_eq!(resp.values[0].value, "false"); - assert_eq!(resp.values[1].output_type, 2); - assert_eq!(resp.values[1].value, "1"); - assert_eq!(resp.values[2].output_type, 3); - assert_eq!(resp.values[2].value, "2"); - assert_eq!(resp.values[3].output_type, 4); - assert_eq!(resp.values[3].value, "3"); - assert_eq!(resp.values[4].output_type, 5); - assert_eq!(resp.values[4].value, "4"); - assert_eq!(resp.values[5].output_type, 6); - assert_eq!(resp.values[5].value, "5"); - assert_eq!(resp.values[6].output_type, 8); - assert_eq!(resp.values[6].value, "7"); - assert_eq!(resp.values[7].output_type, 9); - assert_eq!(resp.values[7].value, "8"); - assert_eq!(resp.values[8].output_type, 10); - assert_eq!(resp.values[8].value, "9"); - assert_eq!(resp.values[9].output_type, 11); - assert_eq!(resp.values[9].value, "10"); + let resp = decrypt_ciphertexts(&pool, 1, decr_handles).await?; + assert_eq!(resp.len(), 10); + + assert_eq!(resp[0].output_type, 0); + assert_eq!(resp[0].value, "false"); + assert_eq!(resp[1].output_type, 2); + assert_eq!(resp[1].value, "1"); + assert_eq!(resp[2].output_type, 3); + assert_eq!(resp[2].value, "2"); + assert_eq!(resp[3].output_type, 4); + assert_eq!(resp[3].value, "3"); + assert_eq!(resp[4].output_type, 5); + assert_eq!(resp[4].value, "4"); + assert_eq!(resp[5].output_type, 6); + assert_eq!(resp[5].value, "5"); + assert_eq!(resp[6].output_type, 8); + assert_eq!(resp[6].value, "7"); + assert_eq!(resp[7].output_type, 9); + assert_eq!(resp[7].value, "8"); + assert_eq!(resp[8].output_type, 10); + assert_eq!(resp[8].value, "9"); + assert_eq!(resp[9].output_type, 11); + assert_eq!(resp[9].value, "10"); Ok(()) } @@ -126,10 +124,12 @@ async fn custom_insert_inputs() -> Result<(), Box> { .connect(&db_url) .await?; - let keys = query_tenant_keys(vec![default_tenant_id()], &pool).await.map_err(|e| { - let e: Box = e; - e - })?; + let keys = query_tenant_keys(vec![default_tenant_id()], &pool) + .await + .map_err(|e| { + let e: Box = e; + e + })?; let keys = &keys[0]; let mut builder = tfhe::CompactCiphertextListBuilder::new(&keys.pks); @@ -146,14 +146,12 @@ async fn custom_insert_inputs() -> Result<(), Box> { println!("Encrypting inputs..."); let mut input_request = tonic::Request::new(InputUploadBatch { - input_ciphertexts: vec![ - InputToUpload { - input_payload: serialized, - signature: Vec::new(), - caller_address: test_random_caller_address(), - contract_address: test_random_contract_address(), - } - ] + input_ciphertexts: vec![InputToUpload { + input_payload: serialized, + signature: Vec::new(), + caller_address: test_random_caller_address(), + contract_address: test_random_contract_address(), + }], }); input_request.metadata_mut().append( "authorization", @@ -172,32 +170,3 @@ async fn custom_insert_inputs() -> Result<(), Box> { Ok(()) } - -#[ignore] -#[tokio::test] -// custom function to decrypt the ciphertext from grpc -// ct_to_decrypt should be changed to your environment -async fn custom_decrypt_ct() -> Result<(), Box> { - let grpc_url = "http://127.0.0.1:50051"; - let api_key_header = format!("bearer {}", default_api_key()); - let ct_to_decrypt = "5bcaeef7d5bee3b5dffff3dfbfafcfb73cf57ddbbff73f777ffdfe677ebc0500"; - - let mut client = FhevmCoprocessorClient::connect(grpc_url).await?; - println!("Encrypting inputs..."); - let mut input_request = tonic::Request::new(DebugDecryptRequest { - handles: vec![ - hex::decode(ct_to_decrypt).unwrap() - ] - }); - input_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - - let uploaded = client.debug_decrypt_ciphertext(input_request).await?; - let response = uploaded.get_ref(); - - println!("{:#?}", response); - - Ok(()) -} \ No newline at end of file diff --git a/fhevm-engine/coprocessor/src/tests/mod.rs b/fhevm-engine/coprocessor/src/tests/mod.rs index 64a6ea10..cec35550 100644 --- a/fhevm-engine/coprocessor/src/tests/mod.rs +++ b/fhevm-engine/coprocessor/src/tests/mod.rs @@ -4,11 +4,11 @@ use crate::server::common::FheOperation; use crate::server::coprocessor::async_computation_input::Input; use crate::server::coprocessor::fhevm_coprocessor_client::FhevmCoprocessorClient; use crate::server::coprocessor::{ - AsyncComputation, AsyncComputationInput, AsyncComputeRequest, DebugDecryptRequest, - DebugEncryptRequest, DebugEncryptRequestSingle, + AsyncComputation, AsyncComputationInput, AsyncComputeRequest, TrivialEncryptBatch, + TrivialEncryptRequestSingle, }; use tonic::metadata::MetadataValue; -use utils::{default_api_key, random_handle, wait_until_all_ciphertexts_computed}; +use utils::{default_api_key, decrypt_ciphertexts, random_handle, wait_until_all_ciphertexts_computed}; mod errors; mod inputs; @@ -18,6 +18,10 @@ mod utils; #[tokio::test] async fn test_smoke() -> Result<(), Box> { let app = utils::setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; @@ -31,14 +35,14 @@ async fn test_smoke() -> Result<(), Box> { // encrypt two ciphertexts { - let mut encrypt_request = tonic::Request::new(DebugEncryptRequest { + let mut encrypt_request = tonic::Request::new(TrivialEncryptBatch { values: vec![ - DebugEncryptRequestSingle { + TrivialEncryptRequestSingle { handle: h1.to_vec(), be_value: vec![123], output_type: ct_type, }, - DebugEncryptRequestSingle { + TrivialEncryptRequestSingle { handle: h2.to_vec(), be_value: vec![124], output_type: ct_type, @@ -49,7 +53,7 @@ async fn test_smoke() -> Result<(), Box> { "authorization", MetadataValue::from_str(&api_key_header).unwrap(), ); - let resp = client.debug_encrypt_ciphertext(encrypt_request).await?; + let resp = client.trivial_encrypt_ciphertexts(encrypt_request).await?; println!("encryption request: {:?}", resp); } @@ -96,23 +100,58 @@ async fn test_smoke() -> Result<(), Box> { // decrypt values { - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: vec![h4.to_vec(), h3.to_vec()], - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; + let decrypt_request = vec![h4.to_vec(), h3.to_vec()]; + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; println!("decrypt request: {:?}", resp); - assert_eq!(resp.get_ref().values.len(), 2); + assert_eq!(resp.len(), 2); // first value - assert_eq!(resp.get_ref().values[0].value, "247"); - assert_eq!(resp.get_ref().values[0].output_type, ct_type); + assert_eq!(resp[0].value, "247"); + assert_eq!(resp[0].output_type, ct_type as i16); // second value - assert_eq!(resp.get_ref().values[1].value, "263"); - assert_eq!(resp.get_ref().values[1].output_type, ct_type); + assert_eq!(resp[1].value, "263"); + assert_eq!(resp[1].output_type, ct_type as i16); } Ok(()) } + +#[tokio::test] +#[ignore] +// custom test to run against local instance for decrypting custom ciphertexts +async fn test_custom_function() -> Result<(), Box> { + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect("postgresql://postgres:postgres@127.0.0.1:5432/coprocessor") + .await?; + + let res = utils::decrypt_ciphertexts(&pool, 1, vec![ + hex::decode("de2c33227b24ca797f7ad88495648446c70612c17f416d27513c77f2d0810200").unwrap(), + hex::decode("51d1d882d1e5ce54f15523558edd2746766c14cd5177faeb659418c57cec0200").unwrap(), + hex::decode("e3935354c48514fdfb0cbd965ad506d8865a2c88efffffca94dc9e0cecec0300").unwrap(), + hex::decode("3eed1ad1d1aa030b3bb3d3587ece4661a56945affcdee6bbdc02e28779380200").unwrap(), + hex::decode("55fe0c4283fbad83dc6fab91c3f85c098ada7a70ca8089e3076043efc9c60200").unwrap(), + hex::decode("3b42e61e197b88c083b4a2ab4b0ec542775e2282bebcc574e45d09f9779a0200").unwrap(), + hex::decode("9718b490a41e20fecaa90a7ab75e74de0c4105213ac3e5d8b5368ab813160200").unwrap(), + hex::decode("164c6d678ddf95f12bfa6b0fee7fd8b12e6221bd0c587640ae61dfc624f20200").unwrap(), + hex::decode("52a01af58c3d2b8ed1d04cd846706c1d214b72e079bd0930827628cb69180200").unwrap(), + hex::decode("d8d493764d46b62187b6a42917d58e297922d9ebab0dee306324e8c78a130200").unwrap(), + ]).await.unwrap(); + + println!("{:#?}", res); + + Ok(()) +} + +#[tokio::test] +#[ignore] +/// setup test data with keys +async fn setup_test_user() -> Result<(), Box> { + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(&std::env::var("DATABASE_URL").expect("expected to get db url")) + .await?; + + utils::setup_test_user(&pool).await?; + + Ok(()) +} diff --git a/fhevm-engine/coprocessor/src/tests/operators.rs b/fhevm-engine/coprocessor/src/tests/operators.rs index 3ffc9dac..31d764c4 100644 --- a/fhevm-engine/coprocessor/src/tests/operators.rs +++ b/fhevm-engine/coprocessor/src/tests/operators.rs @@ -1,10 +1,11 @@ use crate::server::common::FheOperation; use crate::server::coprocessor::fhevm_coprocessor_client::FhevmCoprocessorClient; use crate::server::coprocessor::{ - AsyncComputation, AsyncComputeRequest, DebugDecryptRequest, DebugEncryptRequest, - DebugEncryptRequestSingle, + AsyncComputation, AsyncComputeRequest, TrivialEncryptBatch, TrivialEncryptRequestSingle, +}; +use crate::tests::utils::{ + decrypt_ciphertexts, random_handle, wait_until_all_ciphertexts_computed, }; -use crate::tests::utils::{random_handle, wait_until_all_ciphertexts_computed}; use crate::{ server::coprocessor::{async_computation_input::Input, AsyncComputationInput}, tests::utils::{default_api_key, setup_test_app}, @@ -41,7 +42,7 @@ fn supported_bits() -> &'static [i32] { &[8, 16, 32, 64, 128, 160, 256, 512, 1024, 2048] } -fn supported_types() -> &'static [i32] { +pub fn supported_types() -> &'static [i32] { &[ 0, // bool // 1, TODO: add 4 bit support @@ -78,6 +79,10 @@ fn supported_bits_to_bit_type_in_db(inp: i32) -> i32 { async fn test_fhe_binary_operands() -> Result<(), Box> { let ops = generate_binary_test_cases(); let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; let mut handle_counter: u64 = random_handle(); @@ -113,14 +118,14 @@ async fn test_fhe_binary_operands() -> Result<(), Box> { op.lhs.to_string(), op.rhs.to_string() ); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: lhs_handle.clone(), be_value: lhs_bytes, output_type: op.input_types, }); if !op.is_scalar { let (_, rhs_bytes) = op.rhs.to_bytes_be(); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: rhs_handle.clone(), be_value: rhs_bytes, output_type: op.input_types, @@ -151,14 +156,14 @@ async fn test_fhe_binary_operands() -> Result<(), Box> { } println!("Encrypting inputs..."); - let mut encrypt_request = tonic::Request::new(DebugEncryptRequest { + let mut encrypt_request = tonic::Request::new(TrivialEncryptBatch { values: enc_request_payload, }); encrypt_request.metadata_mut().append( "authorization", MetadataValue::from_str(&api_key_header).unwrap(), ); - let _resp = client.debug_encrypt_ciphertext(encrypt_request).await?; + let _resp = client.trivial_encrypt_ciphertexts(encrypt_request).await?; println!("Scheduling computations..."); let mut compute_request = tonic::Request::new(AsyncComputeRequest { @@ -174,26 +179,20 @@ async fn test_fhe_binary_operands() -> Result<(), Box> { wait_until_all_ciphertexts_computed(&app).await?; - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: output_handles.clone(), - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; assert_eq!( - resp.get_ref().values.len(), + resp.len(), output_handles.len(), "Outputs length doesn't match" ); for (idx, op) in ops.iter().enumerate() { - let decr_response = &resp.get_ref().values[idx]; + let decr_response = &resp[idx]; println!("Checking computation for binary test bits:{} op:{} is_scalar:{} lhs:{} rhs:{} output:{}", op.bits, op.operand, op.is_scalar, op.lhs.to_string(), op.rhs.to_string(), op.expected_output.to_string()); assert_eq!( - decr_response.output_type, op.expected_output_type, + decr_response.output_type, op.expected_output_type as i16, "operand types not equal" ); let value_to_compare = match decr_response.value.as_str() { @@ -216,6 +215,10 @@ async fn test_fhe_binary_operands() -> Result<(), Box> { async fn test_fhe_unary_operands() -> Result<(), Box> { let ops = generate_unary_test_cases(); let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; let mut handle_counter: u64 = random_handle(); @@ -243,7 +246,7 @@ async fn test_fhe_unary_operands() -> Result<(), Box> { op.operand, op.inp.to_string() ); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: input_handle.clone(), be_value: inp_bytes, output_type: op.operand_types, @@ -266,14 +269,14 @@ async fn test_fhe_unary_operands() -> Result<(), Box> { } println!("Encrypting inputs..."); - let mut encrypt_request = tonic::Request::new(DebugEncryptRequest { + let mut encrypt_request = tonic::Request::new(TrivialEncryptBatch { values: enc_request_payload, }); encrypt_request.metadata_mut().append( "authorization", MetadataValue::from_str(&api_key_header).unwrap(), ); - let _resp = client.debug_encrypt_ciphertext(encrypt_request).await?; + let _resp = client.trivial_encrypt_ciphertexts(encrypt_request).await?; println!("Scheduling computations..."); let mut compute_request = tonic::Request::new(AsyncComputeRequest { @@ -289,22 +292,16 @@ async fn test_fhe_unary_operands() -> Result<(), Box> { wait_until_all_ciphertexts_computed(&app).await?; - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: output_handles.clone(), - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; assert_eq!( - resp.get_ref().values.len(), + resp.len(), output_handles.len(), "Outputs length doesn't match" ); for (idx, op) in ops.iter().enumerate() { - let decr_response = &resp.get_ref().values[idx]; + let decr_response = &resp[idx]; println!( "Checking computation for binary test bits:{} op:{} input:{} output:{}", op.bits, @@ -313,7 +310,7 @@ async fn test_fhe_unary_operands() -> Result<(), Box> { op.expected_output.to_string() ); assert_eq!( - decr_response.output_type, op.operand_types, + decr_response.output_type, op.operand_types as i16, "operand types not equal" ); assert_eq!( @@ -329,6 +326,10 @@ async fn test_fhe_unary_operands() -> Result<(), Box> { #[tokio::test] async fn test_fhe_casts() -> Result<(), Box> { let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; let mut handle_counter = random_handle(); @@ -368,7 +369,7 @@ async fn test_fhe_casts() -> Result<(), Box> { println!( "Encrypting inputs for cast test type from:{type_from} type to:{type_to} input:{input} output:{output}", ); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: input_handle.clone(), be_value: inp_bytes, output_type: *type_from, @@ -401,14 +402,14 @@ async fn test_fhe_casts() -> Result<(), Box> { } println!("Encrypting inputs..."); - let mut encrypt_request = tonic::Request::new(DebugEncryptRequest { + let mut encrypt_request = tonic::Request::new(TrivialEncryptBatch { values: enc_request_payload, }); encrypt_request.metadata_mut().append( "authorization", MetadataValue::from_str(&api_key_header).unwrap(), ); - let _resp = client.debug_encrypt_ciphertext(encrypt_request).await?; + let _resp = client.trivial_encrypt_ciphertexts(encrypt_request).await?; println!("Scheduling computations..."); let mut compute_request = tonic::Request::new(AsyncComputeRequest { @@ -424,22 +425,16 @@ async fn test_fhe_casts() -> Result<(), Box> { wait_until_all_ciphertexts_computed(&app).await?; - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: output_handles.clone(), - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; assert_eq!( - resp.get_ref().values.len(), + resp.len(), output_handles.len(), "Outputs length doesn't match" ); for (idx, co) in cast_outputs.iter().enumerate() { - let decr_response = &resp.get_ref().values[idx]; + let decr_response = &resp[idx]; println!( "Checking computation for cast test from:{} to:{} input:{} output:{}", co.type_from, co.type_to, co.input, co.expected_result, @@ -449,7 +444,7 @@ async fn test_fhe_casts() -> Result<(), Box> { decr_response.output_type, decr_response.value ); assert_eq!( - decr_response.output_type, co.type_to, + decr_response.output_type, co.type_to as i16, "operand types not equal" ); assert_eq!( @@ -464,6 +459,10 @@ async fn test_fhe_casts() -> Result<(), Box> { #[tokio::test] async fn test_fhe_if_then_else() -> Result<(), Box> { let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; let mut handle_counter = random_handle(); @@ -491,12 +490,12 @@ async fn test_fhe_if_then_else() -> Result<(), Box> { let fhe_bool_type = 0; let false_handle = next_handle(); let true_handle = next_handle(); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: false_handle.clone(), be_value: BigInt::from(0).to_bytes_be().1, output_type: fhe_bool_type, }); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: true_handle.clone(), be_value: BigInt::from(1).to_bytes_be().1, output_type: fhe_bool_type, @@ -508,12 +507,12 @@ async fn test_fhe_if_then_else() -> Result<(), Box> { let right_handle = next_handle(); let is_input_bool = *input_types == fhe_bool_type; let (left_input, right_input) = if is_input_bool { (0, 1) } else { (7, 12) }; - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: left_handle.clone(), be_value: BigInt::from(left_input).to_bytes_be().1, output_type: *input_types, }); - enc_request_payload.push(DebugEncryptRequestSingle { + enc_request_payload.push(TrivialEncryptRequestSingle { handle: right_handle.clone(), be_value: BigInt::from(right_input).to_bytes_be().1, output_type: *input_types, @@ -558,14 +557,14 @@ async fn test_fhe_if_then_else() -> Result<(), Box> { } println!("Encrypting inputs..."); - let mut encrypt_request = tonic::Request::new(DebugEncryptRequest { + let mut encrypt_request = tonic::Request::new(TrivialEncryptBatch { values: enc_request_payload, }); encrypt_request.metadata_mut().append( "authorization", MetadataValue::from_str(&api_key_header).unwrap(), ); - let _resp = client.debug_encrypt_ciphertext(encrypt_request).await?; + let _resp = client.trivial_encrypt_ciphertexts(encrypt_request).await?; println!("Scheduling computations..."); let mut compute_request = tonic::Request::new(AsyncComputeRequest { @@ -581,22 +580,16 @@ async fn test_fhe_if_then_else() -> Result<(), Box> { wait_until_all_ciphertexts_computed(&app).await?; - let mut decrypt_request = tonic::Request::new(DebugDecryptRequest { - handles: output_handles.clone(), - }); - decrypt_request.metadata_mut().append( - "authorization", - MetadataValue::from_str(&api_key_header).unwrap(), - ); - let resp = client.debug_decrypt_ciphertext(decrypt_request).await?; + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; assert_eq!( - resp.get_ref().values.len(), + resp.len(), output_handles.len(), "Outputs length doesn't match" ); for (idx, co) in if_then_else_outputs.iter().enumerate() { - let decr_response = &resp.get_ref().values[idx]; + let decr_response = &resp[idx]; println!( "Checking if then else computation for test type:{} control:{} lhs:{} rhs:{} output:{}", co.input_type, co.input_bool, co.left_input, co.right_input, co.expected_result, @@ -606,7 +599,7 @@ async fn test_fhe_if_then_else() -> Result<(), Box> { decr_response.output_type, decr_response.value ); assert_eq!( - decr_response.output_type, co.input_type, + decr_response.output_type, co.input_type as i16, "operand types not equal" ); assert_eq!( diff --git a/fhevm-engine/coprocessor/src/tests/random.rs b/fhevm-engine/coprocessor/src/tests/random.rs new file mode 100644 index 00000000..eda019c2 --- /dev/null +++ b/fhevm-engine/coprocessor/src/tests/random.rs @@ -0,0 +1,247 @@ +use std::str::FromStr; + +use bigdecimal::num_bigint::BigInt; +use tonic::metadata::MetadataValue; + +use crate::{ + server::{ + common::FheOperation, + coprocessor::{ + async_computation_input::Input, fhevm_coprocessor_client::FhevmCoprocessorClient, + AsyncComputation, AsyncComputationInput, AsyncComputeRequest, + }, + }, + tests::utils::{ + decrypt_ciphertexts, default_api_key, random_handle_start, setup_test_app, + wait_until_all_ciphertexts_computed, DecryptionResult, + }, +}; + +use super::operators::supported_types; + +#[tokio::test] +async fn test_fhe_random_basic() -> Result<(), Box> { + let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; + let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; + + let mut handle_counter = random_handle_start(); + let mut next_handle = || { + let out: u64 = handle_counter; + handle_counter += 1; + out.to_be_bytes().to_vec() + }; + + let api_key_header = format!("bearer {}", default_api_key()); + + let mut async_computations = Vec::new(); + let mut output_handles = Vec::new(); + // second batch + let mut repeated_output_handles = Vec::new(); + let mut other_seed_output_handles = Vec::new(); + + let random_test_types = supported_types(); + + let deterministic_seed = 123u8; + for the_type in random_test_types { + let output_handle = next_handle(); + output_handles.push(output_handle.clone()); + + async_computations.push(AsyncComputation { + operation: FheOperation::FheRand.into(), + output_handle, + inputs: vec![ + AsyncComputationInput { + input: Some(Input::Scalar(vec![deterministic_seed])), + }, + AsyncComputationInput { + input: Some(Input::Scalar(vec![*the_type as u8])), + }, + ], + }); + } + + for the_type in random_test_types { + let output_handle = next_handle(); + repeated_output_handles.push(output_handle.clone()); + + async_computations.push(AsyncComputation { + operation: FheOperation::FheRand.into(), + output_handle, + inputs: vec![ + AsyncComputationInput { + input: Some(Input::Scalar(vec![deterministic_seed])), + }, + AsyncComputationInput { + input: Some(Input::Scalar(vec![*the_type as u8])), + }, + ], + }); + } + + let deterministic_seed = 124u8; + for the_type in random_test_types { + let output_handle = next_handle(); + other_seed_output_handles.push(output_handle.clone()); + + async_computations.push(AsyncComputation { + operation: FheOperation::FheRand.into(), + output_handle, + inputs: vec![ + AsyncComputationInput { + input: Some(Input::Scalar(vec![deterministic_seed])), + }, + AsyncComputationInput { + input: Some(Input::Scalar(vec![*the_type as u8])), + }, + ], + }); + } + println!("Scheduling computations..."); + let mut compute_request = tonic::Request::new(AsyncComputeRequest { + computations: async_computations, + }); + compute_request.metadata_mut().append( + "authorization", + MetadataValue::from_str(&api_key_header).unwrap(), + ); + let _resp = client.async_compute(compute_request).await?; + println!("Computations scheduled, waiting upon completion..."); + + wait_until_all_ciphertexts_computed(&app).await?; + + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; + let expected: Vec = vec![ + DecryptionResult { value: "true".to_string(), output_type: 0 }, + DecryptionResult { value: "191".to_string(), output_type: 2 }, + DecryptionResult { value: "31935".to_string(), output_type: 3 }, + DecryptionResult { value: "50166975".to_string(), output_type: 4 }, + DecryptionResult { value: "1340532071352597695".to_string(), output_type: 5 }, + DecryptionResult { value: "124020002486967631373104553377985821887".to_string(), output_type: 6 }, + DecryptionResult { value: "1460743068773264656276930615123138630088589671615".to_string(), output_type: 7 }, + DecryptionResult { value: "9073722870604321437325343932192605854447491367692274273821339035224667684031".to_string(), output_type: 8 }, + DecryptionResult { value: "305206023014776799985230721993414106811955216557006729499329334660464767143319849635649940645070409986179511078348380864394886287375691494634900011449535".to_string(), output_type: 9 }, + DecryptionResult { value: "47107745454094956047032061683228950257813886136471742519491594819930746822037387709806363956594057633886089295195718013393612776278364590927545759803018868145037996301653648244673256559634442220254150128066779099210193723099178032989466601285160252652521543788771151245736124664154459945466742327296640515263".to_string(), output_type: 10 }, + DecryptionResult { value: "15993832479142254582179552051978985171942987041581078316307196452126031943098588175022265343465618290530692834276986750976786634669778707390871076641509515302233954805902327473616311936122148439292611965911683385306561778692974324402831129553488123365277966756540494010076336201015765082225027076061721793429534417162741021200774038978621182013568300885057697263422825507901057344782449000322153843538116752641484000884044992485272920464597070056681924136192427539146031607003264945583126338515417165811516149183380031917969225191063070817311680151162289712932918856949044454757316587442727824006976546517520450682047".to_string(), output_type: 11 } + ]; + + println!("results: {:#?}", resp); + + assert_eq!(expected, resp); + + let resp_repeated = decrypt_ciphertexts(&pool, 1, repeated_output_handles).await?; + assert_eq!( + resp, resp_repeated, + "randomness generation is not deterministic" + ); + + let resp_repeated = decrypt_ciphertexts(&pool, 1, other_seed_output_handles).await?; + assert_ne!(resp, resp_repeated, "seed has change, so must the values"); + + Ok(()) +} + +fn to_be_bytes(input: &str) -> Vec { + let num = BigInt::from_str(input).unwrap(); + let (_, bytes_be) = num.to_bytes_be(); + bytes_be +} + +#[tokio::test] +async fn test_fhe_random_bounded() -> Result<(), Box> { + let app = setup_test_app().await?; + let pool = sqlx::postgres::PgPoolOptions::new() + .max_connections(2) + .connect(app.db_url()) + .await?; + let mut client = FhevmCoprocessorClient::connect(app.app_url().to_string()).await?; + + let mut handle_counter = random_handle_start(); + let mut next_handle = || { + let out: u64 = handle_counter; + handle_counter += 1; + out.to_be_bytes().to_vec() + }; + + let api_key_header = format!("bearer {}", default_api_key()); + + let mut async_computations = Vec::new(); + let mut output_handles = Vec::new(); + + let deterministic_seed = 123u8; + let bounds = [ + "8", + "128", + "16384", + "1073741824", + "4611686018427387904", + "85070591730234615865843651857942052864", + "365375409332725729550921208179070754913983135744", + "28948022309329048855892746252171976963317496166410141009864396001978282409984", + ]; + let results = [ + "true", + "127", + "15551", + "50166975", + "1340532071352597695", + "38949410756733015507260901520043769023", + "364616840775087467624166990585926365346640264383", + "9073722870604321437325343932192605854447491367692274273821339035224667684031", + ]; + + for (idx, the_type) in supported_types().iter().enumerate() { + if *the_type > 8 { + // don't support bounded numbers larger than 256 scalar type + break; + } + + let output_handle = next_handle(); + output_handles.push(output_handle.clone()); + + async_computations.push(AsyncComputation { + operation: FheOperation::FheRandBounded.into(), + output_handle, + inputs: vec![ + AsyncComputationInput { + input: Some(Input::Scalar(vec![deterministic_seed])), + }, + AsyncComputationInput { + input: Some(Input::Scalar(to_be_bytes(bounds[idx]))), + }, + AsyncComputationInput { + input: Some(Input::Scalar(vec![*the_type as u8])), + }, + ], + }); + } + + println!("Scheduling computations..."); + let mut compute_request = tonic::Request::new(AsyncComputeRequest { + computations: async_computations, + }); + compute_request.metadata_mut().append( + "authorization", + MetadataValue::from_str(&api_key_header).unwrap(), + ); + let _resp = client.async_compute(compute_request).await?; + println!("Computations scheduled, waiting upon completion..."); + + wait_until_all_ciphertexts_computed(&app).await?; + + let decrypt_request = output_handles.clone(); + let resp = decrypt_ciphertexts(&pool, 1, decrypt_request).await?; + assert_eq!(resp.len(), bounds.len()); + + println!("response: {:#?}", resp); + for idx in 0..bounds.len() { + assert_eq!(resp[idx].output_type, supported_types()[idx] as i16); + assert_eq!(resp[idx].value, results[idx]); + } + + Ok(()) +} diff --git a/fhevm-engine/coprocessor/src/tests/utils.rs b/fhevm-engine/coprocessor/src/tests/utils.rs index c98194f4..b02d8489 100644 --- a/fhevm-engine/coprocessor/src/tests/utils.rs +++ b/fhevm-engine/coprocessor/src/tests/utils.rs @@ -1,5 +1,7 @@ use crate::cli::Args; -use rand::Rng; +use fhevm_engine_common::tfhe_ops::{current_ciphertext_version, deserialize_fhe_ciphertext}; +use rand::{Rng, RngCore}; +use std::collections::BTreeMap; use std::sync::atomic::{AtomicU16, Ordering}; use testcontainers::{core::WaitFor, runners::AsyncRunner, GenericImage, ImageExt}; use tokio::sync::watch::Receiver; @@ -56,7 +58,7 @@ pub async fn setup_test_app() -> Result const LOCAL_DB_URL: &str = "postgresql://postgres:postgres@127.0.0.1:5432/coprocessor"; -async fn setup_test_app_existing_localhost() -> Result> { +pub async fn setup_test_app_existing_localhost() -> Result> { Ok(TestInstance { _container: None, app_close_channel: None, @@ -147,7 +149,8 @@ async fn setup_test_app_custom_docker() -> Result Result<(), Box> { + let sks = tokio::fs::read("../fhevm-keys/sks").await.expect("can't read sks key"); + let pks = tokio::fs::read("../fhevm-keys/pks").await.expect("can't read pks key"); + let cks = tokio::fs::read("../fhevm-keys/cks").await.expect("can't read cks key"); + sqlx::query!( + " + INSERT INTO tenants(tenant_api_key, tenant_id, chain_id, verifying_contract_address, pks_key, sks_key, cks_key) + VALUES ( + 'a1503fb6-d79b-4e9e-826d-44cf262f3e05', + 1, + 12345, + '0x6819e3aDc437fAf9D533490eD3a7552493fCE3B1', + $1, + $2, + $3 + ) + ", + &pks, + &sks, + &cks, + ) + .execute(pool) + .await?; + + Ok(()) +} + +pub async fn decrypt_ciphertexts( + pool: &sqlx::PgPool, + tenant_id: i32, + input: Vec>, +) -> Result, Box> { + let mut priv_key = sqlx::query!( + " + SELECT cks_key + FROM tenants + WHERE tenant_id = $1 + ", + tenant_id + ) + .fetch_all(pool) + .await?; + + if priv_key.is_empty() || priv_key[0].cks_key.is_none() { + panic!("tenant private key not found"); + } + + let mut ct_indexes: BTreeMap<&[u8], usize> = BTreeMap::new(); + for (idx, h) in input.iter().enumerate() { + ct_indexes.insert(h.as_slice(), idx); + } + + assert_eq!(priv_key.len(), 1); + + let cts = sqlx::query!( + " + SELECT ciphertext, ciphertext_type, handle + FROM ciphertexts + WHERE tenant_id = $1 + AND handle = ANY($2::BYTEA[]) + AND ciphertext_version = $3 + ", + tenant_id, + &input, + current_ciphertext_version() + ) + .fetch_all(pool) + .await?; + + if cts.is_empty() { + panic!("ciphertext not found"); + } + + let priv_key = priv_key.pop().unwrap().cks_key.unwrap(); + + let mut values = tokio::task::spawn_blocking(move || { + let client_key: tfhe::ClientKey = bincode::deserialize(&priv_key).unwrap(); + + let mut decrypted: Vec<(Vec, DecryptionResult)> = Vec::with_capacity(cts.len()); + for ct in cts { + let deserialized = + deserialize_fhe_ciphertext(ct.ciphertext_type, &ct.ciphertext).unwrap(); + decrypted.push(( + ct.handle, + DecryptionResult { + output_type: ct.ciphertext_type, + value: deserialized.decrypt(&client_key), + }, + )); + } + + decrypted + }) + .await + .unwrap(); + + values.sort_by_key(|(h, _)| ct_indexes.get(h.as_slice()).unwrap()); + + let values = values.into_iter().map(|i| i.1).collect::>(); + Ok(values) +} diff --git a/fhevm-engine/coprocessor/src/tfhe_worker.rs b/fhevm-engine/coprocessor/src/tfhe_worker.rs index e13dba54..5cc01efc 100644 --- a/fhevm-engine/coprocessor/src/tfhe_worker.rs +++ b/fhevm-engine/coprocessor/src/tfhe_worker.rs @@ -1,8 +1,9 @@ -use fhevm_engine_common::tfhe_ops::{ - current_ciphertext_version, deserialize_fhe_ciphertext, perform_fhe_operation, -}; use crate::{db_queries::populate_cache_with_tenant_keys, types::TfheTenantKeys}; use fhevm_engine_common::types::SupportedFheCiphertexts; +use fhevm_engine_common::{ + tfhe_ops::{current_ciphertext_version, deserialize_fhe_ciphertext, perform_fhe_operation}, + types::SupportedFheOperations, +}; use sqlx::{postgres::PgListener, query, Acquire}; use std::{ cell::Cell, @@ -71,7 +72,12 @@ async fn tfhe_worker_cycle( FROM unnest(c.dependencies) WITH ORDINALITY AS elems(v, dep_index) WHERE (c.tenant_id, elems.v) NOT IN ( SELECT tenant_id, handle FROM ciphertexts ) -- don't select scalar operands - AND ( NOT c.is_scalar OR c.is_scalar AND NOT elems.dep_index = 2 ) + AND ( + NOT c.is_scalar + OR c.is_scalar AND NOT elems.dep_index = 2 + ) + -- ignore fhe random operations, all inputs are scalars + AND NOT c.fhe_operation = ANY(ARRAY[26, 27]) ) LIMIT $1 FOR UPDATE SKIP LOCKED @@ -142,17 +148,21 @@ async fn tfhe_worker_cycle( // process every tenant by tenant id because we must switch keys for each tenant for w in the_work { let tenant_key_cache = tenant_key_cache.clone(); + let fhe_op: SupportedFheOperations = w + .fhe_operation + .try_into() + .expect("only valid fhe ops must have been put in db"); let mut work_ciphertexts: Vec<(i16, Vec)> = Vec::with_capacity(w.dependencies.len()); for (idx, dh) in w.dependencies.iter().enumerate() { - let is_operand_scalar = w.is_scalar && idx == 1; + let is_operand_scalar = w.is_scalar && idx == 1 || fhe_op.is_random(); if is_operand_scalar { work_ciphertexts.push((-1, dh.clone())); } else { - let ct_map_val = ciphertext_map - .get(&(w.tenant_id, &dh)) - .expect("Me must get ciphertext here"); + let ct_map_val = ciphertext_map.get(&(w.tenant_id, &dh)).expect( + "must get ciphertext here, we should have selected all dependencies", + ); work_ciphertexts .push((ct_map_val.ciphertext_type, ct_map_val.ciphertext.clone())); } @@ -166,19 +176,21 @@ async fn tfhe_worker_cycle( } // set thread tenant key - if w.tenant_id != TFHE_TENANT_ID.get() { + { let mut rk = tenant_key_cache.blocking_write(); let keys = rk .get(&w.tenant_id) .expect("Can't get tenant key from cache"); - tfhe::set_server_key(keys.sks.clone()); - TFHE_TENANT_ID.set(w.tenant_id); + if w.tenant_id != TFHE_TENANT_ID.get() { + tfhe::set_server_key(keys.sks.clone()); + TFHE_TENANT_ID.set(w.tenant_id); + } } let mut deserialized_cts: Vec = Vec::with_capacity(work_ciphertexts.len()); for (idx, (ct_type, ct_bytes)) in work_ciphertexts.iter().enumerate() { - let is_operand_scalar = w.is_scalar && idx == 1; + let is_operand_scalar = w.is_scalar && idx == 1 || fhe_op.is_random(); if is_operand_scalar { let mut the_int = tfhe::integer::U256::default(); assert!( @@ -196,20 +208,23 @@ async fn tfhe_worker_cycle( deserialized_cts.push(SupportedFheCiphertexts::Scalar(the_int)); } else { deserialized_cts.push( - deserialize_fhe_ciphertext(*ct_type, ct_bytes.as_slice()) - .map_err(|e| { - let err: Box = Box::new(e); + deserialize_fhe_ciphertext(*ct_type, ct_bytes.as_slice()).map_err( + |e| { + let err: Box = + Box::new(e); (err, w.tenant_id, w.output_handle.clone()) - })?, + }, + )?, ); } } - let res = perform_fhe_operation(w.fhe_operation, &deserialized_cts) - .map_err(|e| { - let err: Box = Box::new(e); - (err, w.tenant_id, w.output_handle.clone()) - })?; + let res = + perform_fhe_operation(w.fhe_operation, &deserialized_cts) + .map_err(|e| { + let err: Box = Box::new(e); + (err, w.tenant_id, w.output_handle.clone()) + })?; let (db_type, db_bytes) = res.serialize(); Ok((w, db_type, db_bytes)) diff --git a/fhevm-engine/coprocessor/src/types.rs b/fhevm-engine/coprocessor/src/types.rs index 7470e3ec..0f483998 100644 --- a/fhevm-engine/coprocessor/src/types.rs +++ b/fhevm-engine/coprocessor/src/types.rs @@ -61,12 +61,22 @@ impl std::fmt::Display for CoprocessorError { write!(f, "Duplicate output handle in ciphertext batch: {}", op) } Self::DuplicateResultHandleInInputsUploaded { hex_handle } => { - write!(f, "Duplicate result handle in inputs detected: {hex_handle}") + write!( + f, + "Duplicate result handle in inputs detected: {hex_handle}" + ) } - Self::MoreThanMaximumCompactInputCiphertextsUploaded { input_count, maximum_allowed } => { + Self::MoreThanMaximumCompactInputCiphertextsUploaded { + input_count, + maximum_allowed, + } => { write!(f, "More than maximum input blobs uploaded, maximum allowed: {maximum_allowed}, uploaded: {input_count}") } - Self::CompactInputCiphertextHasMoreCiphertextThanLimitAllows { input_blob_index, input_ciphertexts_in_blob, input_maximum_ciphertexts_allowed } => { + Self::CompactInputCiphertextHasMoreCiphertextThanLimitAllows { + input_blob_index, + input_ciphertexts_in_blob, + input_maximum_ciphertexts_allowed, + } => { write!(f, "Input blob contains too many ciphertexts, input blob index: {input_blob_index}, ciphertexts in blob: {input_ciphertexts_in_blob}, maximum ciphertexts in blob allowed: {input_maximum_ciphertexts_allowed}") } Self::CiphertextHandleLongerThan64Bytes => { @@ -88,28 +98,28 @@ impl std::fmt::Display for CoprocessorError { handle ) } - Self::CannotParseTenantEthereumAddress { bad_address, parsing_error } => { + Self::CannotParseTenantEthereumAddress { + bad_address, + parsing_error, + } => { write!( f, "Cannot parse tenant ethereum verifying contract address: {}, error: {}", - bad_address, - parsing_error, + bad_address, parsing_error, ) } - Self::CannotParseEthereumAddress { bad_address, parsing_error } => { + Self::CannotParseEthereumAddress { + bad_address, + parsing_error, + } => { write!( f, "Cannot parse ethereum address: {}, error: {}", - bad_address, - parsing_error, + bad_address, parsing_error, ) } Self::Eip712SigningFailure { error } => { - write!( - f, - "Error when signing EIP712 hash: {}", - error, - ) + write!(f, "Error when signing EIP712 hash: {}", error,) } Self::CiphertextComputationDependencyLoopDetected { uncomputable_output_handle, @@ -161,4 +171,4 @@ pub struct TfheTenantKeys { // maybe we'll need this #[allow(dead_code)] pub pks: tfhe::CompactPublicKey, -} +} \ No newline at end of file diff --git a/fhevm-engine/coprocessor/src/utils.rs b/fhevm-engine/coprocessor/src/utils.rs index 4cfaff49..9fff2311 100644 --- a/fhevm-engine/coprocessor/src/utils.rs +++ b/fhevm-engine/coprocessor/src/utils.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeSet, HashMap, HashSet}; -use fhevm_engine_common::types::FhevmError; +use fhevm_engine_common::types::{FhevmError, SupportedFheOperations}; #[cfg(test)] use crate::server::coprocessor::AsyncComputationInput; @@ -46,6 +46,10 @@ pub fn sort_computations_by_dependencies<'a>( for (idx, comp) in input.iter().enumerate() { let mut this_deps = Vec::with_capacity(comp.inputs.len()); let mut this_scalar_operands = Vec::with_capacity(comp.inputs.len()); + let fhe_op: SupportedFheOperations = comp + .operation + .try_into() + .map_err(|e| CoprocessorError::FhevmError(e))?; for (dep_idx, ih) in comp.inputs.iter().enumerate() { let mut is_scalar_operand = false; if let Some(ih_input) = &ih.input { @@ -70,13 +74,13 @@ pub fn sort_computations_by_dependencies<'a>( } Input::Scalar(sc_bytes) => { check_valid_ciphertext_handle(&sc_bytes)?; - if dep_idx != 1 { + if dep_idx != 1 && !fhe_op.is_random() { // TODO: remove wrapping after refactor return Err(CoprocessorError::FhevmError( FhevmError::FheOperationOnlySecondOperandCanBeScalar { scalar_input_index: dep_idx, only_allowed_scalar_input_index: 1, - } + }, )); } is_scalar_operand = true; @@ -145,7 +149,10 @@ pub fn sort_computations_by_dependencies<'a>( "0x{}", hex::encode(&first_uncomputable_handle) ), - uncomputable_handle_dependency: format!("0x{}", hex::encode(first_uncomputable_handle_dependency)), + uncomputable_handle_dependency: format!( + "0x{}", + hex::encode(first_uncomputable_handle_dependency) + ), }, ); } diff --git a/fhevm-engine/fhevm-engine-common/Cargo.toml b/fhevm-engine/fhevm-engine-common/Cargo.toml index 8665ca64..858e65d2 100644 --- a/fhevm-engine/fhevm-engine-common/Cargo.toml +++ b/fhevm-engine/fhevm-engine-common/Cargo.toml @@ -15,6 +15,8 @@ strum = { version = "0.26", features = ["derive"] } bincode = "1.3.3" hex = "0.4" bigdecimal = "0.4.5" +rand_chacha = "0.3.1" +rand = "0.8.5" [[bin]] name = "generate-keys" diff --git a/fhevm-engine/fhevm-engine-common/src/tfhe_ops.rs b/fhevm-engine/fhevm-engine-common/src/tfhe_ops.rs index c7e644f2..c45bd1b1 100644 --- a/fhevm-engine/fhevm-engine-common/src/tfhe_ops.rs +++ b/fhevm-engine/fhevm-engine-common/src/tfhe_ops.rs @@ -2,7 +2,7 @@ use crate::types::{is_ebytes_type, FheOperationType, FhevmError, SupportedFheCip use tfhe::{ integer::{bigint::StaticUnsignedBigInt, U256}, prelude::{ CastInto, FheEq, FheMax, FheMin, FheOrd, FheTryTrivialEncrypt, IfThenElse, RotateLeft, RotateRight - }, FheBool, FheUint1024, FheUint128, FheUint16, FheUint160, FheUint2048, FheUint256, FheUint32, FheUint512, FheUint64, FheUint8 + }, FheBool, FheUint1024, FheUint128, FheUint16, FheUint160, FheUint2048, FheUint256, FheUint32, FheUint512, FheUint64, FheUint8, Seed }; pub fn deserialize_fhe_ciphertext( @@ -72,7 +72,7 @@ pub fn deserialize_fhe_ciphertext( } /// Function assumes encryption key already set -pub fn debug_trivial_encrypt_be_bytes( +pub fn trivial_encrypt_be_bytes( output_type: i16, input_bytes: &[u8], ) -> SupportedFheCiphertexts { @@ -86,7 +86,12 @@ pub fn debug_trivial_encrypt_be_bytes( 3 => { let mut padded: [u8; 2] = [0; 2]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let res = u16::from_be_bytes(padded); @@ -95,7 +100,12 @@ pub fn debug_trivial_encrypt_be_bytes( 4 => { let mut padded: [u8; 4] = [0; 4]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let res: u32 = u32::from_be_bytes(padded); @@ -104,7 +114,12 @@ pub fn debug_trivial_encrypt_be_bytes( 5 => { let mut padded: [u8; 8] = [0; 8]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let res: u64 = u64::from_be_bytes(padded); @@ -113,7 +128,12 @@ pub fn debug_trivial_encrypt_be_bytes( 6 => { let mut padded: [u8; 16] = [0; 16]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let res: u128 = u128::from_be_bytes(padded); @@ -123,7 +143,12 @@ pub fn debug_trivial_encrypt_be_bytes( 7 => { let mut padded: [u8; 32] = [0; 32]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let mut be: U256 = U256::ZERO; @@ -135,7 +160,12 @@ pub fn debug_trivial_encrypt_be_bytes( 8 => { let mut padded: [u8; 32] = [0; 32]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let mut be: U256 = U256::ZERO; @@ -146,7 +176,12 @@ pub fn debug_trivial_encrypt_be_bytes( 9 => { let mut padded: [u8; 64] = [0; 64]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let mut be: StaticUnsignedBigInt<8> = StaticUnsignedBigInt::<8>::ZERO; @@ -157,7 +192,12 @@ pub fn debug_trivial_encrypt_be_bytes( 10 => { let mut padded: [u8; 128] = [0; 128]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let mut be: StaticUnsignedBigInt<16> = StaticUnsignedBigInt::<16>::ZERO; @@ -168,7 +208,12 @@ pub fn debug_trivial_encrypt_be_bytes( 11 => { let mut padded: [u8; 256] = [0; 256]; let padded_len = padded.len(); - let copy_from = padded_len - input_bytes.len(); + let copy_from = + if padded_len >= input_bytes.len() { + padded_len - input_bytes.len() + } else { + 0 + }; let len = padded.len().min(input_bytes.len()); padded[copy_from..padded_len].copy_from_slice(&input_bytes[0..len]); let mut be: StaticUnsignedBigInt<32> = StaticUnsignedBigInt::<32>::ZERO; @@ -314,9 +359,9 @@ pub fn check_fhe_operand_types( input_handles: &[Vec], is_input_handle_scalar: &[bool], ) -> Result { - assert_eq!(input_handles.len(), is_input_handle_scalar.len()); - let fhe_op: SupportedFheOperations = fhe_operation.try_into()?; + + assert_eq!(input_handles.len(), is_input_handle_scalar.len()); // TODO: figure out typing system with constants let fhe_bool_type = 0; @@ -328,37 +373,41 @@ pub fn check_fhe_operand_types( let is_scalar = scalar_operands.len() > 0; - if scalar_operands.len() > 1 { - return Err(FhevmError::FheOperationOnlyOneOperandCanBeScalar { - fhe_operation, - fhe_operation_name: format!("{:?}", fhe_op), - scalar_operand_count: scalar_operands.len(), - max_scalar_operands: 1, - }); - } - - if is_scalar { - assert_eq!( - scalar_operands.len(), - 1, - "We checked already that not more than 1 scalar operand can be present" - ); - - if !does_fhe_operation_support_scalar(&fhe_op) { - return Err(FhevmError::FheOperationDoesntSupportScalar { + // do this check for only random ops because + // all random ops inputs are scalar + if !fhe_op.is_random() { + if scalar_operands.len() > 1 { + return Err(FhevmError::FheOperationOnlyOneOperandCanBeScalar { fhe_operation, fhe_operation_name: format!("{:?}", fhe_op), - scalar_requested: is_scalar, - scalar_supported: false, + scalar_operand_count: scalar_operands.len(), + max_scalar_operands: 1, }); } - let scalar_input_index = scalar_operands[0].0; - if scalar_input_index != 1 { - return Err(FhevmError::FheOperationOnlySecondOperandCanBeScalar { - scalar_input_index, - only_allowed_scalar_input_index: 1, - }); + if is_scalar { + assert_eq!( + scalar_operands.len(), + 1, + "We checked already that not more than 1 scalar operand can be present" + ); + + if !does_fhe_operation_support_scalar(&fhe_op) { + return Err(FhevmError::FheOperationDoesntSupportScalar { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + scalar_requested: is_scalar, + scalar_supported: false, + }); + } + + let scalar_input_index = scalar_operands[0].0; + if scalar_input_index != 1 { + return Err(FhevmError::FheOperationOnlySecondOperandCanBeScalar { + scalar_input_index, + only_allowed_scalar_input_index: 1, + }); + } } } @@ -549,6 +598,97 @@ pub fn check_fhe_operand_types( } } } + SupportedFheOperations::FheRand => { + // counter and output type + let expected_operands = 2; + if input_types.len() != expected_operands { + return Err(FhevmError::UnexpectedOperandCountForFheOperation { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + expected_operands, + got_operands: input_types.len(), + }); + } + + let scalar_operands = is_input_handle_scalar.iter().filter(|i| **i).count(); + if scalar_operands < expected_operands { + return Err( + FhevmError::RandOperationInputsMustAllBeScalar { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + scalar_operand_count: scalar_operands, + expected_scalar_operand_count: expected_operands, + }, + ); + } + + let rand_type = &input_handles[1]; + if rand_type.len() != 1 { + return Err( + FhevmError::UnexpectedRandOperandSizeForOutputType { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + expected_operand_bytes: 1, + got_bytes: rand_type.len(), + }, + ); + } + + validate_fhe_type(rand_type[0] as i32)?; + + Ok(rand_type[0] as i16) + } + SupportedFheOperations::FheRandBounded => { + // counter, bound and output type + let expected_operands = 3; + if input_types.len() != expected_operands { + return Err(FhevmError::UnexpectedOperandCountForFheOperation { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + expected_operands, + got_operands: input_types.len(), + }); + } + + let scalar_operands = is_input_handle_scalar.iter().filter(|i| **i).count(); + if scalar_operands < expected_operands { + return Err( + FhevmError::RandOperationInputsMustAllBeScalar { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + scalar_operand_count: scalar_operands, + expected_scalar_operand_count: expected_operands, + }, + ); + } + + let upper_bound = &input_handles[1]; + if upper_bound.is_empty() && upper_bound.iter().all(|i| *i == 0) { + return Err( + FhevmError::RandOperationUpperBoundCannotBeZero { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + upper_bound_value: format!("0x{}", hex::encode(upper_bound)), + }, + ); + } + + let rand_type = &input_handles[2]; + if rand_type.len() != 1 { + return Err( + FhevmError::UnexpectedRandOperandSizeForOutputType { + fhe_operation, + fhe_operation_name: format!("{:?}", fhe_op), + expected_operand_bytes: 1, + got_bytes: rand_type.len(), + }, + ); + } + + validate_fhe_type(rand_type[0] as i32)?; + + Ok(rand_type[0] as i16) + } other => { panic!("Unexpected branch: {:?}", other) } @@ -604,6 +744,7 @@ fn trim_to_160bit(inp: &U256) -> U256 { pub fn perform_fhe_operation( fhe_operation_int: i16, input_operands: &[SupportedFheCiphertexts], + // for deterministc randomness functions ) -> Result { let fhe_operation: SupportedFheOperations = fhe_operation_int.try_into()?; match fhe_operation { @@ -2617,8 +2758,104 @@ pub fn perform_fhe_operation( panic!("unknown cast pair") } }, - SupportedFheOperations::FheRand => todo!("Implement FheRand"), - SupportedFheOperations::FheRandBounded => todo!("Implement FheRandBounded"), + SupportedFheOperations::FheRand => { + let SupportedFheCiphertexts::Scalar(rand_counter) = &input_operands[0] else { + panic!("we should have checked we have only scalar operands here") + }; + let SupportedFheCiphertexts::Scalar(to_type) = &input_operands[1] else { + panic!("we should have checked we have only scalar operands here") + }; + let (rand_counter, _) = rand_counter.to_low_high_u128(); + let (to_type, _) = to_type.to_low_high_u128(); + Ok(generate_random_number(to_type as i16, rand_counter, None)) + }, + SupportedFheOperations::FheRandBounded => { + let SupportedFheCiphertexts::Scalar(rand_counter) = &input_operands[0] else { + panic!("we should have checked we have only scalar operands here") + }; + let SupportedFheCiphertexts::Scalar(upper_bound) = &input_operands[1] else { + panic!("we should have checked we have only scalar operands here") + }; + let SupportedFheCiphertexts::Scalar(to_type) = &input_operands[2] else { + panic!("we should have checked we have only scalar operands here") + }; + let (rand_counter, _) = rand_counter.to_low_high_u128(); + let (to_type, _) = to_type.to_low_high_u128(); + Ok(generate_random_number(to_type as i16, rand_counter, Some(*upper_bound))) + }, SupportedFheOperations::FheGetInputCiphertext => todo!("Implement FheGetInputCiphertext"), } } + +pub fn generate_random_number(the_type: i16, seed: u128, upper_bound: Option) -> SupportedFheCiphertexts { + let subtract_from = 255; + match the_type { + 0 => { + let num = FheUint8::generate_oblivious_pseudo_random(Seed(seed), 1); + SupportedFheCiphertexts::FheBool(num.gt(0)) + }, + 2 => { + let bit_count = 8; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint8(FheUint8::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 3 => { + let bit_count = 16; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint16(FheUint16::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 4 => { + let bit_count = 32; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint32(FheUint32::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 5 => { + let bit_count = 64; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint64(FheUint64::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 6 => { + let bit_count = 128; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint128(FheUint128::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 7 => { + let bit_count = 160; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint160(FheUint160::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 8 => { + let bit_count = 256; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheUint256(FheUint256::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 9 => { + let bit_count = 512; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheBytes64(FheUint512::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 10 => { + let bit_count = 1024; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheBytes128(FheUint1024::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + 11 => { + let bit_count = 2048; + let random_bits = upper_bound.map(|i| subtract_from - i.leading_zeros()) + .unwrap_or(bit_count).min(bit_count) as u64; + SupportedFheCiphertexts::FheBytes256(FheUint2048::generate_oblivious_pseudo_random(Seed(seed), random_bits)) + }, + other => { + panic!("unknown type to trim to: {other}") + } + } +} \ No newline at end of file diff --git a/fhevm-engine/fhevm-engine-common/src/types.rs b/fhevm-engine/fhevm-engine-common/src/types.rs index b201dbf0..28ed2b47 100644 --- a/fhevm-engine/fhevm-engine-common/src/types.rs +++ b/fhevm-engine/fhevm-engine-common/src/types.rs @@ -81,6 +81,23 @@ pub enum FhevmError { expected_scalar_operand_bytes: usize, got_bytes: usize, }, + UnexpectedRandOperandSizeForOutputType { + fhe_operation: i32, + fhe_operation_name: String, + expected_operand_bytes: usize, + got_bytes: usize, + }, + RandOperationUpperBoundCannotBeZero { + fhe_operation: i32, + fhe_operation_name: String, + upper_bound_value: String, + }, + RandOperationInputsMustAllBeScalar { + fhe_operation: i32, + fhe_operation_name: String, + scalar_operand_count: usize, + expected_scalar_operand_count: usize, + }, BadInputs, MissingTfheRsData, InvalidHandle, @@ -202,6 +219,29 @@ impl std::fmt::Display for FhevmError { } => { write!(f, "only one operand can be scalar, fhe operation: {fhe_operation}, fhe operation name: {fhe_operation_name}, second operand count: {scalar_operand_count}, max scalar operands: {max_scalar_operands}") } + Self::UnexpectedRandOperandSizeForOutputType { + fhe_operation, + fhe_operation_name, + expected_operand_bytes, + got_bytes, + } => { + write!(f, "operation must have only one byte for output operand type {fhe_operation} ({fhe_operation_name}) expects bytes {}, received: {}", expected_operand_bytes, got_bytes) + } + Self::RandOperationUpperBoundCannotBeZero { + fhe_operation, + fhe_operation_name, + upper_bound_value, + } => { + write!(f, "rand bounded operation cannot receive zero as upper bound {fhe_operation} ({fhe_operation_name}) received: {}", upper_bound_value) + }, + Self::RandOperationInputsMustAllBeScalar { + fhe_operation, + fhe_operation_name, + scalar_operand_count, + expected_scalar_operand_count, + } => { + write!(f, "operation must have all operands as scalar {fhe_operation} ({fhe_operation_name}) expected scalar operands {}, received: {}", expected_scalar_operand_count, scalar_operand_count) + } Self::BadInputs => { write!(f, "Bad inputs") } @@ -421,6 +461,12 @@ impl SupportedFheCiphertexts { 9 => Ok(SupportedFheCiphertexts::FheBytes64( list.get(0)?.ok_or(FhevmError::MissingTfheRsData)?, )), + 10 => Ok(SupportedFheCiphertexts::FheBytes128( + list.get(0)?.ok_or(FhevmError::MissingTfheRsData)?, + )), + 11 => Ok(SupportedFheCiphertexts::FheBytes128( + list.get(0)?.ok_or(FhevmError::MissingTfheRsData)?, + )), _ => Err(FhevmError::UnknownFheType(ct_type as i32).into()), } } @@ -491,6 +537,14 @@ impl SupportedFheOperations { } } + pub fn is_random(&self) -> bool { + match self { + SupportedFheOperations::FheRand + | SupportedFheOperations::FheRandBounded => true, + _ => false, + } + } + pub fn supports_bool_inputs(&self) -> bool { match self { SupportedFheOperations::FheEq diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/api.go b/fhevm-engine/fhevm-go-coproc/fhevm/api.go index d30f29aa..fbecb222 100644 --- a/fhevm-engine/fhevm-go-coproc/fhevm/api.go +++ b/fhevm-engine/fhevm-go-coproc/fhevm/api.go @@ -8,13 +8,10 @@ import ( "errors" "fmt" "os" - "strings" "sync" "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - ethCrypto "github.com/ethereum/go-ethereum/crypto" _ "github.com/mattn/go-sqlite3" "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -32,6 +29,7 @@ const ( FheUint64 FheUintType = 5 FheUint128 FheUintType = 6 FheUint160 FheUintType = 7 + FheUint256 FheUintType = 8 FheUserBytes FheUintType = 255 ) @@ -112,8 +110,12 @@ type CoprocessorApi interface { type SegmentId int +type ExtraData struct { + RandomCounter common.Hash +} + type CoprocessorSession interface { - Execute(input []byte, output []byte) error + Execute(input []byte, ed ExtraData, output []byte) error ContractAddress() common.Address NextSegment() SegmentId InvalidateSinceSegment(id SegmentId) SegmentId @@ -127,9 +129,8 @@ type ComputationStore interface { } type ApiImpl struct { - store *SqliteCiphertextStore - address common.Address - coprocessorKey *ecdsa.PrivateKey + store *SqliteComputationStore + address common.Address } type SessionImpl struct { @@ -161,7 +162,7 @@ type SessionComputationStore struct { segmentCount int } -type SqliteCiphertextStore struct { +type SqliteComputationStore struct { dbMutex sync.Mutex dbConn *sql.DB coprocessorUrl string @@ -181,9 +182,8 @@ type ciphertextSegment struct { func (coprocApi *ApiImpl) CreateSession() CoprocessorSession { return &SessionImpl{ - address: coprocApi.address, - coprocessorKey: coprocApi.coprocessorKey, - isCommitted: false, + address: coprocApi.address, + isCommitted: false, sessionStore: &SessionComputationStore{ isCommitted: false, inserts: make([]ComputationToInsert, 0), @@ -212,7 +212,7 @@ func (sessionApi *SessionImpl) Commit() error { return nil } -func (sessionApi *SessionImpl) Execute(data []byte, output []byte) error { +func (sessionApi *SessionImpl) Execute(data []byte, ed ExtraData, output []byte) error { if len(data) < 4 { return fmt.Errorf("input data must be at least 4 bytes for signature, got %d", len(data)) } @@ -226,7 +226,7 @@ func (sessionApi *SessionImpl) Execute(data []byte, output []byte) error { if len(output) >= 32 { // where to get output handle from? outputHandle := output[0:32] - return method.runFunction(sessionApi, callData, outputHandle) + return method.runFunction(sessionApi, callData, ed, outputHandle) } else { return errors.New("no output data provided") } @@ -278,7 +278,7 @@ func (dbApi *SessionComputationStore) InsertComputation(computation ComputationT func (dbApi *SessionComputationStore) Commit() error { if dbApi.isCommitted { - return errors.New("session ciphertext store already committed") + return errors.New("session computation store already committed") } dbApi.isCommitted = true @@ -290,7 +290,7 @@ func (dbApi *SessionComputationStore) Commit() error { } } - fmt.Printf("Inserting %d ciphertexts into database\n", len(finalInserts)) + fmt.Printf("Inserting %d computations into database\n", len(finalInserts)) err := dbApi.underlyingCiphertextStore.InsertComputationBatch(finalInserts) if err != nil { @@ -325,7 +325,7 @@ func computationToAsyncComputation(computation ComputationToInsert) AsyncComputa } } -func (dbApi *SqliteCiphertextStore) InsertComputation(computation ComputationToInsert) error { +func (dbApi *SqliteComputationStore) InsertComputation(computation ComputationToInsert) error { dbApi.dbMutex.Lock() defer dbApi.dbMutex.Unlock() @@ -345,7 +345,7 @@ func (dbApi *SqliteCiphertextStore) InsertComputation(computation ComputationToI return nil } -func (dbApi *SqliteCiphertextStore) InsertComputationBatch(computations []ComputationToInsert) error { +func (dbApi *SqliteComputationStore) InsertComputationBatch(computations []ComputationToInsert) error { dbApi.dbMutex.Lock() defer dbApi.dbMutex.Unlock() @@ -382,11 +382,6 @@ func InitCoprocessor() (CoprocessorApi, error) { } fhevmContractAddress := common.HexToAddress(contractAddr) - keyFile, hasKey := os.LookupEnv("FHEVM_COPROCESSOR_PRIVATE_KEY_FILE") - if !hasKey { - return nil, errors.New("FHEVM_CIPHERTEXTS_DB is set but FHEVM_COPROCESSOR_PRIVATE_KEY_FILE is not set") - } - coprocUrl, hasUrl := os.LookupEnv("FHEVM_COPROCESSOR_URL") if !hasUrl { return nil, errors.New("FHEVM_COPROCESSOR_URL is not configured") @@ -402,49 +397,9 @@ func InitCoprocessor() (CoprocessorApi, error) { return nil, err } - keyBytes, err := os.ReadFile(keyFile) - if err != nil { - if !os.IsNotExist(err) { - return nil, err - } - // key file doesn't exist, generate - fmt.Printf("Key file not found in %s, generating and saving\n", keyFile) - privKey, err := ethCrypto.GenerateKey() - if err != nil { - return nil, err - } - keyBytes = []byte(hexutil.Encode(ethCrypto.FromECDSA(privKey))) - err = os.WriteFile(keyFile, keyBytes, 0o600) - if err != nil { - return nil, err - } - fmt.Printf("Generated and saved ECDSA private key in %s\n", keyFile) - } - - privKeyString := strings.TrimSpace(string(keyBytes)) - privKeyBytes, err := hexutil.Decode(privKeyString) - if err != nil { - return nil, err - } - - privKey, err := ethCrypto.ToECDSA(privKeyBytes) - if err != nil { - return nil, err - } - - pubKey := privKey.Public() - publicKeyECDSA, ok := pubKey.(*ecdsa.PublicKey) - if !ok { - return nil, errors.New("can't get ethereum public key from private") - } - - pubKeyAddr := ethCrypto.PubkeyToAddress(*publicKeyECDSA) - fmt.Printf("Public coprocessor eth address: %s\n", pubKeyAddr) - apiImpl := ApiImpl{ - store: ciphertextDb, - address: fhevmContractAddress, - coprocessorKey: privKey, + store: ciphertextDb, + address: fhevmContractAddress, } // background job to submit computations to coprocessor @@ -482,45 +437,53 @@ func scheduleCoprocessorFlushes(impl *ApiImpl) { }() } -func flushWorkItemsToCoprocessor(store *SqliteCiphertextStore) (int, error) { +func queryCurrentComputeRequests(store *SqliteComputationStore) (*AsyncComputeRequest, [][]byte, error) { var asyncCompReq *AsyncComputeRequest handlesToMarkDone := make([][]byte, 0) - { - store.dbMutex.Lock() - defer store.dbMutex.Unlock() - // query all ciphertexts - response, err := store.dbConn.Query("SELECT output_handle, payload FROM computations WHERE is_sent = 0 LIMIT 700") + store.dbMutex.Lock() + defer store.dbMutex.Unlock() + + // query all ciphertexts + response, err := store.dbConn.Query("SELECT output_handle, payload FROM computations WHERE is_sent = 0 LIMIT 700") + if err != nil { + return nil, handlesToMarkDone, err + } + + requests := make([]*AsyncComputation, 0, 16) + for response.Next() { + var outputHandle, payload []byte + err = response.Scan(&outputHandle, &payload) if err != nil { - return 0, err + return nil, handlesToMarkDone, err + } + var ac AsyncComputation + err = proto.Unmarshal(payload, &ac) + if err != nil { + return nil, handlesToMarkDone, err } - requests := make([]*AsyncComputation, 0, 16) - for response.Next() { - var outputHandle, payload []byte - err = response.Scan(&outputHandle, &payload) - if err != nil { - return 0, err - } - var ac AsyncComputation - err = proto.Unmarshal(payload, &ac) - if err != nil { - return 0, err - } + requests = append(requests, &ac) + handlesToMarkDone = append(handlesToMarkDone, outputHandle) + } - requests = append(requests, &ac) - handlesToMarkDone = append(handlesToMarkDone, outputHandle) - } + if response.Err() != nil { + return nil, handlesToMarkDone, err + } - if response.Err() != nil { - return 0, err + if len(requests) > 0 { + asyncCompReq = &AsyncComputeRequest{ + Computations: requests, } + } - if len(requests) > 0 { - asyncCompReq = &AsyncComputeRequest{ - Computations: requests, - } - } + return asyncCompReq, handlesToMarkDone, nil +} + +func flushWorkItemsToCoprocessor(store *SqliteComputationStore) (int, error) { + asyncCompReq, handlesToMarkDone, err := queryCurrentComputeRequests(store) + if err != nil { + return 0, err } if asyncCompReq != nil { @@ -562,7 +525,7 @@ func flushWorkItemsToCoprocessor(store *SqliteCiphertextStore) (int, error) { return 0, nil } -func CreateSqliteCiphertextStore(dbPath string, ctx context.Context, coprocUrl, coprocApiKey string) (*SqliteCiphertextStore, error) { +func CreateSqliteCiphertextStore(dbPath string, ctx context.Context, coprocUrl, coprocApiKey string) (*SqliteComputationStore, error) { dbConn, err := sql.Open("sqlite3", dbPath) if err != nil { return nil, err @@ -573,7 +536,7 @@ func CreateSqliteCiphertextStore(dbPath string, ctx context.Context, coprocUrl, return nil, err } - return &SqliteCiphertextStore{ + return &SqliteComputationStore{ dbConn: dbConn, dbMutex: sync.Mutex{}, coprocessorUrl: coprocUrl, diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/common.pb.go b/fhevm-engine/fhevm-go-coproc/fhevm/common.pb.go index 80971e17..c2ee8c95 100644 --- a/fhevm-engine/fhevm-go-coproc/fhevm/common.pb.go +++ b/fhevm-engine/fhevm-go-coproc/fhevm/common.pb.go @@ -23,32 +23,33 @@ const ( type FheOperation int32 const ( - FheOperation_FHE_ADD FheOperation = 0 - FheOperation_FHE_SUB FheOperation = 1 - FheOperation_FHE_MUL FheOperation = 2 - FheOperation_FHE_DIV FheOperation = 3 - FheOperation_FHE_REM FheOperation = 4 - FheOperation_FHE_BIT_AND FheOperation = 5 - FheOperation_FHE_BIT_OR FheOperation = 6 - FheOperation_FHE_BIT_XOR FheOperation = 7 - FheOperation_FHE_SHL FheOperation = 8 - FheOperation_FHE_SHR FheOperation = 9 - FheOperation_FHE_ROTL FheOperation = 10 - FheOperation_FHE_ROTR FheOperation = 11 - FheOperation_FHE_EQ FheOperation = 12 - FheOperation_FHE_NE FheOperation = 13 - FheOperation_FHE_GE FheOperation = 14 - FheOperation_FHE_GT FheOperation = 15 - FheOperation_FHE_LE FheOperation = 16 - FheOperation_FHE_LT FheOperation = 17 - FheOperation_FHE_MIN FheOperation = 18 - FheOperation_FHE_MAX FheOperation = 19 - FheOperation_FHE_NEG FheOperation = 20 - FheOperation_FHE_NOT FheOperation = 21 - FheOperation_FHE_CAST FheOperation = 23 - FheOperation_FHE_IF_THEN_ELSE FheOperation = 25 - FheOperation_FHE_RAND FheOperation = 26 - FheOperation_FHE_RAND_BOUNDED FheOperation = 27 + FheOperation_FHE_ADD FheOperation = 0 + FheOperation_FHE_SUB FheOperation = 1 + FheOperation_FHE_MUL FheOperation = 2 + FheOperation_FHE_DIV FheOperation = 3 + FheOperation_FHE_REM FheOperation = 4 + FheOperation_FHE_BIT_AND FheOperation = 5 + FheOperation_FHE_BIT_OR FheOperation = 6 + FheOperation_FHE_BIT_XOR FheOperation = 7 + FheOperation_FHE_SHL FheOperation = 8 + FheOperation_FHE_SHR FheOperation = 9 + FheOperation_FHE_ROTL FheOperation = 10 + FheOperation_FHE_ROTR FheOperation = 11 + FheOperation_FHE_EQ FheOperation = 12 + FheOperation_FHE_NE FheOperation = 13 + FheOperation_FHE_GE FheOperation = 14 + FheOperation_FHE_GT FheOperation = 15 + FheOperation_FHE_LE FheOperation = 16 + FheOperation_FHE_LT FheOperation = 17 + FheOperation_FHE_MIN FheOperation = 18 + FheOperation_FHE_MAX FheOperation = 19 + FheOperation_FHE_NEG FheOperation = 20 + FheOperation_FHE_NOT FheOperation = 21 + FheOperation_FHE_CAST FheOperation = 23 + FheOperation_FHE_IF_THEN_ELSE FheOperation = 25 + FheOperation_FHE_RAND FheOperation = 26 + FheOperation_FHE_RAND_BOUNDED FheOperation = 27 + FheOperation_FHE_GET_CIPHERTEXT FheOperation = 32 ) // Enum value maps for FheOperation. @@ -80,34 +81,36 @@ var ( 25: "FHE_IF_THEN_ELSE", 26: "FHE_RAND", 27: "FHE_RAND_BOUNDED", + 32: "FHE_GET_CIPHERTEXT", } FheOperation_value = map[string]int32{ - "FHE_ADD": 0, - "FHE_SUB": 1, - "FHE_MUL": 2, - "FHE_DIV": 3, - "FHE_REM": 4, - "FHE_BIT_AND": 5, - "FHE_BIT_OR": 6, - "FHE_BIT_XOR": 7, - "FHE_SHL": 8, - "FHE_SHR": 9, - "FHE_ROTL": 10, - "FHE_ROTR": 11, - "FHE_EQ": 12, - "FHE_NE": 13, - "FHE_GE": 14, - "FHE_GT": 15, - "FHE_LE": 16, - "FHE_LT": 17, - "FHE_MIN": 18, - "FHE_MAX": 19, - "FHE_NEG": 20, - "FHE_NOT": 21, - "FHE_CAST": 23, - "FHE_IF_THEN_ELSE": 25, - "FHE_RAND": 26, - "FHE_RAND_BOUNDED": 27, + "FHE_ADD": 0, + "FHE_SUB": 1, + "FHE_MUL": 2, + "FHE_DIV": 3, + "FHE_REM": 4, + "FHE_BIT_AND": 5, + "FHE_BIT_OR": 6, + "FHE_BIT_XOR": 7, + "FHE_SHL": 8, + "FHE_SHR": 9, + "FHE_ROTL": 10, + "FHE_ROTR": 11, + "FHE_EQ": 12, + "FHE_NE": 13, + "FHE_GE": 14, + "FHE_GT": 15, + "FHE_LE": 16, + "FHE_LT": 17, + "FHE_MIN": 18, + "FHE_MAX": 19, + "FHE_NEG": 20, + "FHE_NOT": 21, + "FHE_CAST": 23, + "FHE_IF_THEN_ELSE": 25, + "FHE_RAND": 26, + "FHE_RAND_BOUNDED": 27, + "FHE_GET_CIPHERTEXT": 32, } ) @@ -142,7 +145,7 @@ var File_common_proto protoreflect.FileDescriptor var file_common_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, - 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2a, 0xfb, 0x02, 0x0a, + 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2a, 0x93, 0x03, 0x0a, 0x0c, 0x46, 0x68, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x48, 0x45, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x48, 0x45, 0x5f, 0x53, 0x55, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x48, 0x45, 0x5f, 0x4d, @@ -166,11 +169,12 @@ var file_common_proto_rawDesc = []byte{ 0x12, 0x14, 0x0a, 0x10, 0x46, 0x48, 0x45, 0x5f, 0x49, 0x46, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x45, 0x4c, 0x53, 0x45, 0x10, 0x19, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x48, 0x45, 0x5f, 0x52, 0x41, 0x4e, 0x44, 0x10, 0x1a, 0x12, 0x14, 0x0a, 0x10, 0x46, 0x48, 0x45, 0x5f, 0x52, 0x41, 0x4e, 0x44, - 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x1b, 0x42, 0x2d, 0x0a, 0x13, 0x69, 0x6f, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x42, 0x0b, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x01, - 0x5a, 0x07, 0x2e, 0x2f, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x48, + 0x45, 0x5f, 0x47, 0x45, 0x54, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, + 0x10, 0x20, 0x42, 0x2d, 0x0a, 0x13, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x68, + 0x65, 0x76, 0x6d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x0b, 0x46, 0x68, 0x65, 0x76, 0x6d, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x01, 0x5a, 0x07, 0x2e, 0x2f, 0x66, 0x68, 0x65, 0x76, + 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor.pb.go b/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor.pb.go index 1d61d21c..a913d199 100644 --- a/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor.pb.go +++ b/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor.pb.go @@ -20,16 +20,16 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type DebugEncryptRequest struct { +type TrivialEncryptBatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*DebugEncryptRequestSingle `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + Values []*TrivialEncryptRequestSingle `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` } -func (x *DebugEncryptRequest) Reset() { - *x = DebugEncryptRequest{} +func (x *TrivialEncryptBatch) Reset() { + *x = TrivialEncryptBatch{} if protoimpl.UnsafeEnabled { mi := &file_coprocessor_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -37,13 +37,13 @@ func (x *DebugEncryptRequest) Reset() { } } -func (x *DebugEncryptRequest) String() string { +func (x *TrivialEncryptBatch) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DebugEncryptRequest) ProtoMessage() {} +func (*TrivialEncryptBatch) ProtoMessage() {} -func (x *DebugEncryptRequest) ProtoReflect() protoreflect.Message { +func (x *TrivialEncryptBatch) ProtoReflect() protoreflect.Message { mi := &file_coprocessor_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -55,30 +55,30 @@ func (x *DebugEncryptRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DebugEncryptRequest.ProtoReflect.Descriptor instead. -func (*DebugEncryptRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use TrivialEncryptBatch.ProtoReflect.Descriptor instead. +func (*TrivialEncryptBatch) Descriptor() ([]byte, []int) { return file_coprocessor_proto_rawDescGZIP(), []int{0} } -func (x *DebugEncryptRequest) GetValues() []*DebugEncryptRequestSingle { +func (x *TrivialEncryptBatch) GetValues() []*TrivialEncryptRequestSingle { if x != nil { return x.Values } return nil } -type DebugEncryptRequestSingle struct { +type TrivialEncryptRequestSingle struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Handle []byte `protobuf:"bytes,1,opt,name=handle,proto3" json:"handle,omitempty"` - LeValue []byte `protobuf:"bytes,2,opt,name=le_value,json=leValue,proto3" json:"le_value,omitempty"` + BeValue []byte `protobuf:"bytes,2,opt,name=be_value,json=beValue,proto3" json:"be_value,omitempty"` OutputType int32 `protobuf:"varint,3,opt,name=output_type,json=outputType,proto3" json:"output_type,omitempty"` } -func (x *DebugEncryptRequestSingle) Reset() { - *x = DebugEncryptRequestSingle{} +func (x *TrivialEncryptRequestSingle) Reset() { + *x = TrivialEncryptRequestSingle{} if protoimpl.UnsafeEnabled { mi := &file_coprocessor_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -86,13 +86,13 @@ func (x *DebugEncryptRequestSingle) Reset() { } } -func (x *DebugEncryptRequestSingle) String() string { +func (x *TrivialEncryptRequestSingle) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DebugEncryptRequestSingle) ProtoMessage() {} +func (*TrivialEncryptRequestSingle) ProtoMessage() {} -func (x *DebugEncryptRequestSingle) ProtoReflect() protoreflect.Message { +func (x *TrivialEncryptRequestSingle) ProtoReflect() protoreflect.Message { mi := &file_coprocessor_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -104,181 +104,32 @@ func (x *DebugEncryptRequestSingle) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DebugEncryptRequestSingle.ProtoReflect.Descriptor instead. -func (*DebugEncryptRequestSingle) Descriptor() ([]byte, []int) { +// Deprecated: Use TrivialEncryptRequestSingle.ProtoReflect.Descriptor instead. +func (*TrivialEncryptRequestSingle) Descriptor() ([]byte, []int) { return file_coprocessor_proto_rawDescGZIP(), []int{1} } -func (x *DebugEncryptRequestSingle) GetHandle() []byte { +func (x *TrivialEncryptRequestSingle) GetHandle() []byte { if x != nil { return x.Handle } return nil } -func (x *DebugEncryptRequestSingle) GetLeValue() []byte { +func (x *TrivialEncryptRequestSingle) GetBeValue() []byte { if x != nil { - return x.LeValue + return x.BeValue } return nil } -func (x *DebugEncryptRequestSingle) GetOutputType() int32 { +func (x *TrivialEncryptRequestSingle) GetOutputType() int32 { if x != nil { return x.OutputType } return 0 } -type DebugDecryptRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Handles [][]byte `protobuf:"bytes,1,rep,name=handles,proto3" json:"handles,omitempty"` -} - -func (x *DebugDecryptRequest) Reset() { - *x = DebugDecryptRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DebugDecryptRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DebugDecryptRequest) ProtoMessage() {} - -func (x *DebugDecryptRequest) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DebugDecryptRequest.ProtoReflect.Descriptor instead. -func (*DebugDecryptRequest) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{2} -} - -func (x *DebugDecryptRequest) GetHandles() [][]byte { - if x != nil { - return x.Handles - } - return nil -} - -type DebugDecryptResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Values []*DebugDecryptResponseSingle `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` -} - -func (x *DebugDecryptResponse) Reset() { - *x = DebugDecryptResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DebugDecryptResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DebugDecryptResponse) ProtoMessage() {} - -func (x *DebugDecryptResponse) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DebugDecryptResponse.ProtoReflect.Descriptor instead. -func (*DebugDecryptResponse) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{3} -} - -func (x *DebugDecryptResponse) GetValues() []*DebugDecryptResponseSingle { - if x != nil { - return x.Values - } - return nil -} - -type DebugDecryptResponseSingle struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - OutputType int32 `protobuf:"varint,1,opt,name=output_type,json=outputType,proto3" json:"output_type,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *DebugDecryptResponseSingle) Reset() { - *x = DebugDecryptResponseSingle{} - if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DebugDecryptResponseSingle) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DebugDecryptResponseSingle) ProtoMessage() {} - -func (x *DebugDecryptResponseSingle) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DebugDecryptResponseSingle.ProtoReflect.Descriptor instead. -func (*DebugDecryptResponseSingle) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{4} -} - -func (x *DebugDecryptResponseSingle) GetOutputType() int32 { - if x != nil { - return x.OutputType - } - return 0 -} - -func (x *DebugDecryptResponseSingle) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - type AsyncComputation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -292,7 +143,7 @@ type AsyncComputation struct { func (x *AsyncComputation) Reset() { *x = AsyncComputation{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[5] + mi := &file_coprocessor_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -305,7 +156,7 @@ func (x *AsyncComputation) String() string { func (*AsyncComputation) ProtoMessage() {} func (x *AsyncComputation) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[5] + mi := &file_coprocessor_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -318,7 +169,7 @@ func (x *AsyncComputation) ProtoReflect() protoreflect.Message { // Deprecated: Use AsyncComputation.ProtoReflect.Descriptor instead. func (*AsyncComputation) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{5} + return file_coprocessor_proto_rawDescGZIP(), []int{2} } func (x *AsyncComputation) GetOperation() FheOperation { @@ -357,7 +208,7 @@ type AsyncComputationInput struct { func (x *AsyncComputationInput) Reset() { *x = AsyncComputationInput{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[6] + mi := &file_coprocessor_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -370,7 +221,7 @@ func (x *AsyncComputationInput) String() string { func (*AsyncComputationInput) ProtoMessage() {} func (x *AsyncComputationInput) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[6] + mi := &file_coprocessor_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -383,7 +234,7 @@ func (x *AsyncComputationInput) ProtoReflect() protoreflect.Message { // Deprecated: Use AsyncComputationInput.ProtoReflect.Descriptor instead. func (*AsyncComputationInput) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{6} + return file_coprocessor_proto_rawDescGZIP(), []int{3} } func (m *AsyncComputationInput) GetInput() isAsyncComputationInput_Input { @@ -423,82 +274,21 @@ func (*AsyncComputationInput_InputHandle) isAsyncComputationInput_Input() {} func (*AsyncComputationInput_Scalar) isAsyncComputationInput_Input() {} -type CiphertextToUpload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CiphertextType int32 `protobuf:"varint,1,opt,name=ciphertext_type,json=ciphertextType,proto3" json:"ciphertext_type,omitempty"` - CiphertextHandle []byte `protobuf:"bytes,2,opt,name=ciphertext_handle,json=ciphertextHandle,proto3" json:"ciphertext_handle,omitempty"` - CiphertextBytes []byte `protobuf:"bytes,3,opt,name=ciphertext_bytes,json=ciphertextBytes,proto3" json:"ciphertext_bytes,omitempty"` -} - -func (x *CiphertextToUpload) Reset() { - *x = CiphertextToUpload{} - if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CiphertextToUpload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CiphertextToUpload) ProtoMessage() {} - -func (x *CiphertextToUpload) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CiphertextToUpload.ProtoReflect.Descriptor instead. -func (*CiphertextToUpload) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{7} -} - -func (x *CiphertextToUpload) GetCiphertextType() int32 { - if x != nil { - return x.CiphertextType - } - return 0 -} - -func (x *CiphertextToUpload) GetCiphertextHandle() []byte { - if x != nil { - return x.CiphertextHandle - } - return nil -} - -func (x *CiphertextToUpload) GetCiphertextBytes() []byte { - if x != nil { - return x.CiphertextBytes - } - return nil -} - type InputToUpload struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - InputPayload []byte `protobuf:"bytes,1,opt,name=input_payload,json=inputPayload,proto3" json:"input_payload,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + InputPayload []byte `protobuf:"bytes,1,opt,name=input_payload,json=inputPayload,proto3" json:"input_payload,omitempty"` + ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + CallerAddress string `protobuf:"bytes,3,opt,name=caller_address,json=callerAddress,proto3" json:"caller_address,omitempty"` + Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"` } func (x *InputToUpload) Reset() { *x = InputToUpload{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[8] + mi := &file_coprocessor_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -511,7 +301,7 @@ func (x *InputToUpload) String() string { func (*InputToUpload) ProtoMessage() {} func (x *InputToUpload) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[8] + mi := &file_coprocessor_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -524,7 +314,7 @@ func (x *InputToUpload) ProtoReflect() protoreflect.Message { // Deprecated: Use InputToUpload.ProtoReflect.Descriptor instead. func (*InputToUpload) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{8} + return file_coprocessor_proto_rawDescGZIP(), []int{4} } func (x *InputToUpload) GetInputPayload() []byte { @@ -534,6 +324,20 @@ func (x *InputToUpload) GetInputPayload() []byte { return nil } +func (x *InputToUpload) GetContractAddress() string { + if x != nil { + return x.ContractAddress + } + return "" +} + +func (x *InputToUpload) GetCallerAddress() string { + if x != nil { + return x.CallerAddress + } + return "" +} + func (x *InputToUpload) GetSignature() []byte { if x != nil { return x.Signature @@ -553,7 +357,7 @@ type InputCiphertextResponseHandle struct { func (x *InputCiphertextResponseHandle) Reset() { *x = InputCiphertextResponseHandle{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[9] + mi := &file_coprocessor_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -566,7 +370,7 @@ func (x *InputCiphertextResponseHandle) String() string { func (*InputCiphertextResponseHandle) ProtoMessage() {} func (x *InputCiphertextResponseHandle) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[9] + mi := &file_coprocessor_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -579,7 +383,7 @@ func (x *InputCiphertextResponseHandle) ProtoReflect() protoreflect.Message { // Deprecated: Use InputCiphertextResponseHandle.ProtoReflect.Descriptor instead. func (*InputCiphertextResponseHandle) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{9} + return file_coprocessor_proto_rawDescGZIP(), []int{5} } func (x *InputCiphertextResponseHandle) GetHandle() []byte { @@ -601,13 +405,17 @@ type InputCiphertextResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - InputHandles []*InputCiphertextResponseHandle `protobuf:"bytes,1,rep,name=input_handles,json=inputHandles,proto3" json:"input_handles,omitempty"` + InputHandles []*InputCiphertextResponseHandle `protobuf:"bytes,1,rep,name=input_handles,json=inputHandles,proto3" json:"input_handles,omitempty"` + Eip712ContractAddress string `protobuf:"bytes,2,opt,name=eip712ContractAddress,proto3" json:"eip712ContractAddress,omitempty"` + Eip712CallerAddress string `protobuf:"bytes,3,opt,name=eip712CallerAddress,proto3" json:"eip712CallerAddress,omitempty"` + Eip712SignerAddress string `protobuf:"bytes,4,opt,name=eip712SignerAddress,proto3" json:"eip712SignerAddress,omitempty"` + Eip712Signature []byte `protobuf:"bytes,5,opt,name=eip712Signature,proto3" json:"eip712Signature,omitempty"` } func (x *InputCiphertextResponse) Reset() { *x = InputCiphertextResponse{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[10] + mi := &file_coprocessor_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -620,7 +428,7 @@ func (x *InputCiphertextResponse) String() string { func (*InputCiphertextResponse) ProtoMessage() {} func (x *InputCiphertextResponse) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[10] + mi := &file_coprocessor_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -633,7 +441,7 @@ func (x *InputCiphertextResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InputCiphertextResponse.ProtoReflect.Descriptor instead. func (*InputCiphertextResponse) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{10} + return file_coprocessor_proto_rawDescGZIP(), []int{6} } func (x *InputCiphertextResponse) GetInputHandles() []*InputCiphertextResponseHandle { @@ -643,6 +451,34 @@ func (x *InputCiphertextResponse) GetInputHandles() []*InputCiphertextResponseHa return nil } +func (x *InputCiphertextResponse) GetEip712ContractAddress() string { + if x != nil { + return x.Eip712ContractAddress + } + return "" +} + +func (x *InputCiphertextResponse) GetEip712CallerAddress() string { + if x != nil { + return x.Eip712CallerAddress + } + return "" +} + +func (x *InputCiphertextResponse) GetEip712SignerAddress() string { + if x != nil { + return x.Eip712SignerAddress + } + return "" +} + +func (x *InputCiphertextResponse) GetEip712Signature() []byte { + if x != nil { + return x.Eip712Signature + } + return nil +} + type InputUploadResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -654,7 +490,7 @@ type InputUploadResponse struct { func (x *InputUploadResponse) Reset() { *x = InputUploadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[11] + mi := &file_coprocessor_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -667,7 +503,7 @@ func (x *InputUploadResponse) String() string { func (*InputUploadResponse) ProtoMessage() {} func (x *InputUploadResponse) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[11] + mi := &file_coprocessor_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -680,7 +516,7 @@ func (x *InputUploadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InputUploadResponse.ProtoReflect.Descriptor instead. func (*InputUploadResponse) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{11} + return file_coprocessor_proto_rawDescGZIP(), []int{7} } func (x *InputUploadResponse) GetUploadResponses() []*InputCiphertextResponse { @@ -702,7 +538,7 @@ type AsyncComputeRequest struct { func (x *AsyncComputeRequest) Reset() { *x = AsyncComputeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[12] + mi := &file_coprocessor_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -715,7 +551,7 @@ func (x *AsyncComputeRequest) String() string { func (*AsyncComputeRequest) ProtoMessage() {} func (x *AsyncComputeRequest) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[12] + mi := &file_coprocessor_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -728,7 +564,7 @@ func (x *AsyncComputeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AsyncComputeRequest.ProtoReflect.Descriptor instead. func (*AsyncComputeRequest) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{12} + return file_coprocessor_proto_rawDescGZIP(), []int{8} } func (x *AsyncComputeRequest) GetComputations() []*AsyncComputation { @@ -738,53 +574,6 @@ func (x *AsyncComputeRequest) GetComputations() []*AsyncComputation { return nil } -type CiphertextUploadBatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - InputCiphertexts []*CiphertextToUpload `protobuf:"bytes,1,rep,name=input_ciphertexts,json=inputCiphertexts,proto3" json:"input_ciphertexts,omitempty"` -} - -func (x *CiphertextUploadBatch) Reset() { - *x = CiphertextUploadBatch{} - if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CiphertextUploadBatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CiphertextUploadBatch) ProtoMessage() {} - -func (x *CiphertextUploadBatch) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CiphertextUploadBatch.ProtoReflect.Descriptor instead. -func (*CiphertextUploadBatch) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{13} -} - -func (x *CiphertextUploadBatch) GetInputCiphertexts() []*CiphertextToUpload { - if x != nil { - return x.InputCiphertexts - } - return nil -} - type InputUploadBatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -796,7 +585,7 @@ type InputUploadBatch struct { func (x *InputUploadBatch) Reset() { *x = InputUploadBatch{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[14] + mi := &file_coprocessor_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -809,7 +598,7 @@ func (x *InputUploadBatch) String() string { func (*InputUploadBatch) ProtoMessage() {} func (x *InputUploadBatch) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[14] + mi := &file_coprocessor_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -822,7 +611,7 @@ func (x *InputUploadBatch) ProtoReflect() protoreflect.Message { // Deprecated: Use InputUploadBatch.ProtoReflect.Descriptor instead. func (*InputUploadBatch) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{14} + return file_coprocessor_proto_rawDescGZIP(), []int{9} } func (x *InputUploadBatch) GetInputCiphertexts() []*InputToUpload { @@ -843,7 +632,7 @@ type WaitBatch struct { func (x *WaitBatch) Reset() { *x = WaitBatch{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[15] + mi := &file_coprocessor_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -856,7 +645,7 @@ func (x *WaitBatch) String() string { func (*WaitBatch) ProtoMessage() {} func (x *WaitBatch) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[15] + mi := &file_coprocessor_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -869,7 +658,7 @@ func (x *WaitBatch) ProtoReflect() protoreflect.Message { // Deprecated: Use WaitBatch.ProtoReflect.Descriptor instead. func (*WaitBatch) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{15} + return file_coprocessor_proto_rawDescGZIP(), []int{10} } func (x *WaitBatch) GetCiphertextHandles() []string { @@ -890,7 +679,7 @@ type GenericResponse struct { func (x *GenericResponse) Reset() { *x = GenericResponse{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[16] + mi := &file_coprocessor_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -903,7 +692,7 @@ func (x *GenericResponse) String() string { func (*GenericResponse) ProtoMessage() {} func (x *GenericResponse) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[16] + mi := &file_coprocessor_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -916,7 +705,7 @@ func (x *GenericResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GenericResponse.ProtoReflect.Descriptor instead. func (*GenericResponse) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{16} + return file_coprocessor_proto_rawDescGZIP(), []int{11} } func (x *GenericResponse) GetResponseCode() int32 { @@ -937,7 +726,7 @@ type FhevmResponses struct { func (x *FhevmResponses) Reset() { *x = FhevmResponses{} if protoimpl.UnsafeEnabled { - mi := &file_coprocessor_proto_msgTypes[17] + mi := &file_coprocessor_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -950,7 +739,7 @@ func (x *FhevmResponses) String() string { func (*FhevmResponses) ProtoMessage() {} func (x *FhevmResponses) ProtoReflect() protoreflect.Message { - mi := &file_coprocessor_proto_msgTypes[17] + mi := &file_coprocessor_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -963,7 +752,7 @@ func (x *FhevmResponses) ProtoReflect() protoreflect.Message { // Deprecated: Use FhevmResponses.ProtoReflect.Descriptor instead. func (*FhevmResponses) Descriptor() ([]byte, []int) { - return file_coprocessor_proto_rawDescGZIP(), []int{17} + return file_coprocessor_proto_rawDescGZIP(), []int{12} } func (x *FhevmResponses) GetCiphertextHandles() []string { @@ -979,159 +768,134 @@ var file_coprocessor_proto_rawDesc = []byte{ 0x0a, 0x11, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5b, 0x0a, 0x13, 0x44, 0x65, 0x62, 0x75, 0x67, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x06, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x66, 0x68, - 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x22, 0x6f, 0x0a, 0x19, 0x44, 0x65, 0x62, 0x75, 0x67, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x2f, 0x0a, 0x13, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x61, 0x6e, - 0x64, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x68, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x66, 0x68, - 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, - 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x22, 0x53, 0x0a, 0x1a, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x79, 0x6e, - 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1a, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, - 0x68, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x66, 0x68, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x13, 0x54, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x46, 0x0a, 0x06, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, + 0x54, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x22, 0x71, 0x0a, 0x1b, 0x54, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x65, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x79, 0x6e, 0x63, + 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, + 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x68, + 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x66, 0x68, 0x65, + 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x41, + 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x22, 0x5f, 0x0a, 0x15, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x22, 0x5f, 0x0a, - 0x15, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0b, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x73, - 0x63, 0x61, 0x6c, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x73, - 0x63, 0x61, 0x6c, 0x61, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x95, - 0x01, 0x0a, 0x12, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, - 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, - 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, - 0x0a, 0x11, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x61, 0x6e, - 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x69, 0x70, 0x68, 0x65, - 0x72, 0x74, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x52, 0x0a, 0x0d, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, - 0x6f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x60, 0x0a, 0x1d, 0x49, 0x6e, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0b, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x73, 0x63, + 0x61, 0x6c, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, + 0x61, 0x6c, 0x61, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0xa4, 0x01, + 0x0a, 0x0d, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x22, 0x60, 0x0a, 0x1d, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, + 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0xb4, 0x02, 0x0a, 0x17, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x55, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x66, 0x68, 0x65, 0x76, + 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x6e, - 0x64, 0x6c, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x69, - 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x70, 0x0a, 0x17, - 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x65, 0x69, 0x70, + 0x37, 0x31, 0x32, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x65, 0x69, 0x70, 0x37, 0x31, 0x32, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x30, 0x0a, 0x13, 0x65, 0x69, 0x70, 0x37, 0x31, 0x32, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x69, + 0x70, 0x37, 0x31, 0x32, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x30, 0x0a, 0x13, 0x65, 0x69, 0x70, 0x37, 0x31, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, + 0x65, 0x69, 0x70, 0x37, 0x31, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x69, 0x70, 0x37, 0x31, 0x32, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x69, + 0x70, 0x37, 0x31, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x6c, 0x0a, + 0x13, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, - 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x6c, - 0x0a, 0x13, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, - 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0f, 0x75, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x13, - 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x68, 0x65, 0x76, + 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x13, 0x41, + 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, + 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x79, + 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x63, + 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x61, 0x0a, 0x10, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x4d, 0x0a, 0x11, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x68, 0x65, + 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x10, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x3a, + 0x0a, 0x09, 0x57, 0x61, 0x69, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2d, 0x0a, 0x12, 0x63, + 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x0f, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, + 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, + 0x65, 0x22, 0x3f, 0x0a, 0x0e, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x11, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x73, 0x32, 0x9b, 0x03, 0x0a, 0x10, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x43, 0x6f, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x5c, 0x0a, 0x0c, 0x41, 0x73, 0x79, 0x6e, 0x63, + 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, + 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x79, 0x6e, + 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x10, 0x57, 0x61, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x41, 0x73, - 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, - 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6b, 0x0a, 0x15, - 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x52, 0x0a, 0x11, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x54, - 0x6f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x43, 0x69, - 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x61, 0x0a, 0x10, 0x49, 0x6e, 0x70, - 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x4d, 0x0a, - 0x11, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, - 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, - 0x75, 0x74, 0x54, 0x6f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x10, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x3a, 0x0a, 0x09, - 0x57, 0x61, 0x69, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x0f, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x22, - 0x3f, 0x0a, 0x0e, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x5f, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, - 0x32, 0xea, 0x04, 0x0a, 0x10, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x43, 0x6f, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x5c, 0x0a, 0x0c, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, - 0x72, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, - 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x1a, 0x22, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x10, 0x57, 0x61, 0x69, 0x74, - 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x66, - 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, - 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x66, 0x68, 0x65, 0x76, - 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, - 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x26, - 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x16, 0x44, 0x65, 0x62, 0x75, - 0x67, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, - 0x78, 0x74, 0x12, 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x66, 0x68, 0x65, - 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x16, 0x44, 0x65, 0x62, 0x75, 0x67, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x12, - 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x6f, 0x72, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, - 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x37, 0x0a, - 0x18, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x63, 0x6f, - 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x42, 0x10, 0x46, 0x68, 0x65, 0x76, 0x6d, - 0x43, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x50, 0x01, 0x5a, 0x07, 0x2e, - 0x2f, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x46, 0x68, 0x65, 0x76, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x73, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, + 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x26, 0x2e, 0x66, 0x68, + 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x19, 0x54, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x12, 0x26, 0x2e, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x22, 0x2e, 0x66, 0x68, 0x65, + 0x76, 0x6d, 0x2e, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x37, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x66, 0x68, 0x65, 0x76, + 0x6d, 0x63, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x42, 0x10, 0x46, 0x68, + 0x65, 0x76, 0x6d, 0x43, 0x6f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x50, 0x01, + 0x5a, 0x07, 0x2e, 0x2f, 0x66, 0x68, 0x65, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1146,55 +910,44 @@ func file_coprocessor_proto_rawDescGZIP() []byte { return file_coprocessor_proto_rawDescData } -var file_coprocessor_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_coprocessor_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_coprocessor_proto_goTypes = []any{ - (*DebugEncryptRequest)(nil), // 0: fhevm.coprocessor.DebugEncryptRequest - (*DebugEncryptRequestSingle)(nil), // 1: fhevm.coprocessor.DebugEncryptRequestSingle - (*DebugDecryptRequest)(nil), // 2: fhevm.coprocessor.DebugDecryptRequest - (*DebugDecryptResponse)(nil), // 3: fhevm.coprocessor.DebugDecryptResponse - (*DebugDecryptResponseSingle)(nil), // 4: fhevm.coprocessor.DebugDecryptResponseSingle - (*AsyncComputation)(nil), // 5: fhevm.coprocessor.AsyncComputation - (*AsyncComputationInput)(nil), // 6: fhevm.coprocessor.AsyncComputationInput - (*CiphertextToUpload)(nil), // 7: fhevm.coprocessor.CiphertextToUpload - (*InputToUpload)(nil), // 8: fhevm.coprocessor.InputToUpload - (*InputCiphertextResponseHandle)(nil), // 9: fhevm.coprocessor.InputCiphertextResponseHandle - (*InputCiphertextResponse)(nil), // 10: fhevm.coprocessor.InputCiphertextResponse - (*InputUploadResponse)(nil), // 11: fhevm.coprocessor.InputUploadResponse - (*AsyncComputeRequest)(nil), // 12: fhevm.coprocessor.AsyncComputeRequest - (*CiphertextUploadBatch)(nil), // 13: fhevm.coprocessor.CiphertextUploadBatch - (*InputUploadBatch)(nil), // 14: fhevm.coprocessor.InputUploadBatch - (*WaitBatch)(nil), // 15: fhevm.coprocessor.WaitBatch - (*GenericResponse)(nil), // 16: fhevm.coprocessor.GenericResponse - (*FhevmResponses)(nil), // 17: fhevm.coprocessor.FhevmResponses - (FheOperation)(0), // 18: fhevm.common.FheOperation + (*TrivialEncryptBatch)(nil), // 0: fhevm.coprocessor.TrivialEncryptBatch + (*TrivialEncryptRequestSingle)(nil), // 1: fhevm.coprocessor.TrivialEncryptRequestSingle + (*AsyncComputation)(nil), // 2: fhevm.coprocessor.AsyncComputation + (*AsyncComputationInput)(nil), // 3: fhevm.coprocessor.AsyncComputationInput + (*InputToUpload)(nil), // 4: fhevm.coprocessor.InputToUpload + (*InputCiphertextResponseHandle)(nil), // 5: fhevm.coprocessor.InputCiphertextResponseHandle + (*InputCiphertextResponse)(nil), // 6: fhevm.coprocessor.InputCiphertextResponse + (*InputUploadResponse)(nil), // 7: fhevm.coprocessor.InputUploadResponse + (*AsyncComputeRequest)(nil), // 8: fhevm.coprocessor.AsyncComputeRequest + (*InputUploadBatch)(nil), // 9: fhevm.coprocessor.InputUploadBatch + (*WaitBatch)(nil), // 10: fhevm.coprocessor.WaitBatch + (*GenericResponse)(nil), // 11: fhevm.coprocessor.GenericResponse + (*FhevmResponses)(nil), // 12: fhevm.coprocessor.FhevmResponses + (FheOperation)(0), // 13: fhevm.common.FheOperation } var file_coprocessor_proto_depIdxs = []int32{ - 1, // 0: fhevm.coprocessor.DebugEncryptRequest.values:type_name -> fhevm.coprocessor.DebugEncryptRequestSingle - 4, // 1: fhevm.coprocessor.DebugDecryptResponse.values:type_name -> fhevm.coprocessor.DebugDecryptResponseSingle - 18, // 2: fhevm.coprocessor.AsyncComputation.operation:type_name -> fhevm.common.FheOperation - 6, // 3: fhevm.coprocessor.AsyncComputation.inputs:type_name -> fhevm.coprocessor.AsyncComputationInput - 9, // 4: fhevm.coprocessor.InputCiphertextResponse.input_handles:type_name -> fhevm.coprocessor.InputCiphertextResponseHandle - 10, // 5: fhevm.coprocessor.InputUploadResponse.upload_responses:type_name -> fhevm.coprocessor.InputCiphertextResponse - 5, // 6: fhevm.coprocessor.AsyncComputeRequest.computations:type_name -> fhevm.coprocessor.AsyncComputation - 7, // 7: fhevm.coprocessor.CiphertextUploadBatch.input_ciphertexts:type_name -> fhevm.coprocessor.CiphertextToUpload - 8, // 8: fhevm.coprocessor.InputUploadBatch.input_ciphertexts:type_name -> fhevm.coprocessor.InputToUpload - 12, // 9: fhevm.coprocessor.FhevmCoprocessor.AsyncCompute:input_type -> fhevm.coprocessor.AsyncComputeRequest - 13, // 10: fhevm.coprocessor.FhevmCoprocessor.UploadCiphertexts:input_type -> fhevm.coprocessor.CiphertextUploadBatch - 12, // 11: fhevm.coprocessor.FhevmCoprocessor.WaitComputations:input_type -> fhevm.coprocessor.AsyncComputeRequest - 14, // 12: fhevm.coprocessor.FhevmCoprocessor.UploadInputs:input_type -> fhevm.coprocessor.InputUploadBatch - 2, // 13: fhevm.coprocessor.FhevmCoprocessor.DebugDecryptCiphertext:input_type -> fhevm.coprocessor.DebugDecryptRequest - 0, // 14: fhevm.coprocessor.FhevmCoprocessor.DebugEncryptCiphertext:input_type -> fhevm.coprocessor.DebugEncryptRequest - 16, // 15: fhevm.coprocessor.FhevmCoprocessor.AsyncCompute:output_type -> fhevm.coprocessor.GenericResponse - 16, // 16: fhevm.coprocessor.FhevmCoprocessor.UploadCiphertexts:output_type -> fhevm.coprocessor.GenericResponse - 17, // 17: fhevm.coprocessor.FhevmCoprocessor.WaitComputations:output_type -> fhevm.coprocessor.FhevmResponses - 11, // 18: fhevm.coprocessor.FhevmCoprocessor.UploadInputs:output_type -> fhevm.coprocessor.InputUploadResponse - 3, // 19: fhevm.coprocessor.FhevmCoprocessor.DebugDecryptCiphertext:output_type -> fhevm.coprocessor.DebugDecryptResponse - 16, // 20: fhevm.coprocessor.FhevmCoprocessor.DebugEncryptCiphertext:output_type -> fhevm.coprocessor.GenericResponse - 15, // [15:21] is the sub-list for method output_type - 9, // [9:15] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 1, // 0: fhevm.coprocessor.TrivialEncryptBatch.values:type_name -> fhevm.coprocessor.TrivialEncryptRequestSingle + 13, // 1: fhevm.coprocessor.AsyncComputation.operation:type_name -> fhevm.common.FheOperation + 3, // 2: fhevm.coprocessor.AsyncComputation.inputs:type_name -> fhevm.coprocessor.AsyncComputationInput + 5, // 3: fhevm.coprocessor.InputCiphertextResponse.input_handles:type_name -> fhevm.coprocessor.InputCiphertextResponseHandle + 6, // 4: fhevm.coprocessor.InputUploadResponse.upload_responses:type_name -> fhevm.coprocessor.InputCiphertextResponse + 2, // 5: fhevm.coprocessor.AsyncComputeRequest.computations:type_name -> fhevm.coprocessor.AsyncComputation + 4, // 6: fhevm.coprocessor.InputUploadBatch.input_ciphertexts:type_name -> fhevm.coprocessor.InputToUpload + 8, // 7: fhevm.coprocessor.FhevmCoprocessor.AsyncCompute:input_type -> fhevm.coprocessor.AsyncComputeRequest + 8, // 8: fhevm.coprocessor.FhevmCoprocessor.WaitComputations:input_type -> fhevm.coprocessor.AsyncComputeRequest + 9, // 9: fhevm.coprocessor.FhevmCoprocessor.UploadInputs:input_type -> fhevm.coprocessor.InputUploadBatch + 0, // 10: fhevm.coprocessor.FhevmCoprocessor.TrivialEncryptCiphertexts:input_type -> fhevm.coprocessor.TrivialEncryptBatch + 11, // 11: fhevm.coprocessor.FhevmCoprocessor.AsyncCompute:output_type -> fhevm.coprocessor.GenericResponse + 12, // 12: fhevm.coprocessor.FhevmCoprocessor.WaitComputations:output_type -> fhevm.coprocessor.FhevmResponses + 7, // 13: fhevm.coprocessor.FhevmCoprocessor.UploadInputs:output_type -> fhevm.coprocessor.InputUploadResponse + 11, // 14: fhevm.coprocessor.FhevmCoprocessor.TrivialEncryptCiphertexts:output_type -> fhevm.coprocessor.GenericResponse + 11, // [11:15] is the sub-list for method output_type + 7, // [7:11] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_coprocessor_proto_init() } @@ -1205,7 +958,7 @@ func file_coprocessor_proto_init() { file_common_proto_init() if !protoimpl.UnsafeEnabled { file_coprocessor_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*DebugEncryptRequest); i { + switch v := v.(*TrivialEncryptBatch); i { case 0: return &v.state case 1: @@ -1217,7 +970,7 @@ func file_coprocessor_proto_init() { } } file_coprocessor_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*DebugEncryptRequestSingle); i { + switch v := v.(*TrivialEncryptRequestSingle); i { case 0: return &v.state case 1: @@ -1229,42 +982,6 @@ func file_coprocessor_proto_init() { } } file_coprocessor_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*DebugDecryptRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_coprocessor_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*DebugDecryptResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_coprocessor_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*DebugDecryptResponseSingle); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_coprocessor_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*AsyncComputation); i { case 0: return &v.state @@ -1276,7 +993,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[6].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*AsyncComputationInput); i { case 0: return &v.state @@ -1288,19 +1005,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*CiphertextToUpload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_coprocessor_proto_msgTypes[8].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*InputToUpload); i { case 0: return &v.state @@ -1312,7 +1017,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[9].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*InputCiphertextResponseHandle); i { case 0: return &v.state @@ -1324,7 +1029,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[10].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*InputCiphertextResponse); i { case 0: return &v.state @@ -1336,7 +1041,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[11].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*InputUploadResponse); i { case 0: return &v.state @@ -1348,7 +1053,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[12].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*AsyncComputeRequest); i { case 0: return &v.state @@ -1360,19 +1065,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*CiphertextUploadBatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_coprocessor_proto_msgTypes[14].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*InputUploadBatch); i { case 0: return &v.state @@ -1384,7 +1077,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[15].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*WaitBatch); i { case 0: return &v.state @@ -1396,7 +1089,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[16].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[11].Exporter = func(v any, i int) any { switch v := v.(*GenericResponse); i { case 0: return &v.state @@ -1408,7 +1101,7 @@ func file_coprocessor_proto_init() { return nil } } - file_coprocessor_proto_msgTypes[17].Exporter = func(v any, i int) any { + file_coprocessor_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*FhevmResponses); i { case 0: return &v.state @@ -1421,7 +1114,7 @@ func file_coprocessor_proto_init() { } } } - file_coprocessor_proto_msgTypes[6].OneofWrappers = []any{ + file_coprocessor_proto_msgTypes[3].OneofWrappers = []any{ (*AsyncComputationInput_InputHandle)(nil), (*AsyncComputationInput_Scalar)(nil), } @@ -1431,7 +1124,7 @@ func file_coprocessor_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_coprocessor_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor_grpc.pb.go b/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor_grpc.pb.go new file mode 100644 index 00000000..2d3bfc07 --- /dev/null +++ b/fhevm-engine/fhevm-go-coproc/fhevm/coprocessor_grpc.pb.go @@ -0,0 +1,235 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 +// source: coprocessor.proto + +package fhevm + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + FhevmCoprocessor_AsyncCompute_FullMethodName = "/fhevm.coprocessor.FhevmCoprocessor/AsyncCompute" + FhevmCoprocessor_WaitComputations_FullMethodName = "/fhevm.coprocessor.FhevmCoprocessor/WaitComputations" + FhevmCoprocessor_UploadInputs_FullMethodName = "/fhevm.coprocessor.FhevmCoprocessor/UploadInputs" + FhevmCoprocessor_TrivialEncryptCiphertexts_FullMethodName = "/fhevm.coprocessor.FhevmCoprocessor/TrivialEncryptCiphertexts" +) + +// FhevmCoprocessorClient is the client API for FhevmCoprocessor service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type FhevmCoprocessorClient interface { + AsyncCompute(ctx context.Context, in *AsyncComputeRequest, opts ...grpc.CallOption) (*GenericResponse, error) + WaitComputations(ctx context.Context, in *AsyncComputeRequest, opts ...grpc.CallOption) (*FhevmResponses, error) + UploadInputs(ctx context.Context, in *InputUploadBatch, opts ...grpc.CallOption) (*InputUploadResponse, error) + TrivialEncryptCiphertexts(ctx context.Context, in *TrivialEncryptBatch, opts ...grpc.CallOption) (*GenericResponse, error) +} + +type fhevmCoprocessorClient struct { + cc grpc.ClientConnInterface +} + +func NewFhevmCoprocessorClient(cc grpc.ClientConnInterface) FhevmCoprocessorClient { + return &fhevmCoprocessorClient{cc} +} + +func (c *fhevmCoprocessorClient) AsyncCompute(ctx context.Context, in *AsyncComputeRequest, opts ...grpc.CallOption) (*GenericResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GenericResponse) + err := c.cc.Invoke(ctx, FhevmCoprocessor_AsyncCompute_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fhevmCoprocessorClient) WaitComputations(ctx context.Context, in *AsyncComputeRequest, opts ...grpc.CallOption) (*FhevmResponses, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FhevmResponses) + err := c.cc.Invoke(ctx, FhevmCoprocessor_WaitComputations_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fhevmCoprocessorClient) UploadInputs(ctx context.Context, in *InputUploadBatch, opts ...grpc.CallOption) (*InputUploadResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InputUploadResponse) + err := c.cc.Invoke(ctx, FhevmCoprocessor_UploadInputs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *fhevmCoprocessorClient) TrivialEncryptCiphertexts(ctx context.Context, in *TrivialEncryptBatch, opts ...grpc.CallOption) (*GenericResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GenericResponse) + err := c.cc.Invoke(ctx, FhevmCoprocessor_TrivialEncryptCiphertexts_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// FhevmCoprocessorServer is the server API for FhevmCoprocessor service. +// All implementations must embed UnimplementedFhevmCoprocessorServer +// for forward compatibility. +type FhevmCoprocessorServer interface { + AsyncCompute(context.Context, *AsyncComputeRequest) (*GenericResponse, error) + WaitComputations(context.Context, *AsyncComputeRequest) (*FhevmResponses, error) + UploadInputs(context.Context, *InputUploadBatch) (*InputUploadResponse, error) + TrivialEncryptCiphertexts(context.Context, *TrivialEncryptBatch) (*GenericResponse, error) + mustEmbedUnimplementedFhevmCoprocessorServer() +} + +// UnimplementedFhevmCoprocessorServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedFhevmCoprocessorServer struct{} + +func (UnimplementedFhevmCoprocessorServer) AsyncCompute(context.Context, *AsyncComputeRequest) (*GenericResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AsyncCompute not implemented") +} +func (UnimplementedFhevmCoprocessorServer) WaitComputations(context.Context, *AsyncComputeRequest) (*FhevmResponses, error) { + return nil, status.Errorf(codes.Unimplemented, "method WaitComputations not implemented") +} +func (UnimplementedFhevmCoprocessorServer) UploadInputs(context.Context, *InputUploadBatch) (*InputUploadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadInputs not implemented") +} +func (UnimplementedFhevmCoprocessorServer) TrivialEncryptCiphertexts(context.Context, *TrivialEncryptBatch) (*GenericResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TrivialEncryptCiphertexts not implemented") +} +func (UnimplementedFhevmCoprocessorServer) mustEmbedUnimplementedFhevmCoprocessorServer() {} +func (UnimplementedFhevmCoprocessorServer) testEmbeddedByValue() {} + +// UnsafeFhevmCoprocessorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to FhevmCoprocessorServer will +// result in compilation errors. +type UnsafeFhevmCoprocessorServer interface { + mustEmbedUnimplementedFhevmCoprocessorServer() +} + +func RegisterFhevmCoprocessorServer(s grpc.ServiceRegistrar, srv FhevmCoprocessorServer) { + // If the following call pancis, it indicates UnimplementedFhevmCoprocessorServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&FhevmCoprocessor_ServiceDesc, srv) +} + +func _FhevmCoprocessor_AsyncCompute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AsyncComputeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FhevmCoprocessorServer).AsyncCompute(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FhevmCoprocessor_AsyncCompute_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FhevmCoprocessorServer).AsyncCompute(ctx, req.(*AsyncComputeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FhevmCoprocessor_WaitComputations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AsyncComputeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FhevmCoprocessorServer).WaitComputations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FhevmCoprocessor_WaitComputations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FhevmCoprocessorServer).WaitComputations(ctx, req.(*AsyncComputeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FhevmCoprocessor_UploadInputs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InputUploadBatch) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FhevmCoprocessorServer).UploadInputs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FhevmCoprocessor_UploadInputs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FhevmCoprocessorServer).UploadInputs(ctx, req.(*InputUploadBatch)) + } + return interceptor(ctx, in, info, handler) +} + +func _FhevmCoprocessor_TrivialEncryptCiphertexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TrivialEncryptBatch) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FhevmCoprocessorServer).TrivialEncryptCiphertexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FhevmCoprocessor_TrivialEncryptCiphertexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FhevmCoprocessorServer).TrivialEncryptCiphertexts(ctx, req.(*TrivialEncryptBatch)) + } + return interceptor(ctx, in, info, handler) +} + +// FhevmCoprocessor_ServiceDesc is the grpc.ServiceDesc for FhevmCoprocessor service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var FhevmCoprocessor_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "fhevm.coprocessor.FhevmCoprocessor", + HandlerType: (*FhevmCoprocessorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AsyncCompute", + Handler: _FhevmCoprocessor_AsyncCompute_Handler, + }, + { + MethodName: "WaitComputations", + Handler: _FhevmCoprocessor_WaitComputations_Handler, + }, + { + MethodName: "UploadInputs", + Handler: _FhevmCoprocessor_UploadInputs_Handler, + }, + { + MethodName: "TrivialEncryptCiphertexts", + Handler: _FhevmCoprocessor_TrivialEncryptCiphertexts_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "coprocessor.proto", +} diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/fhelib.go b/fhevm-engine/fhevm-go-coproc/fhevm/fhelib.go index 236223b1..45084c3f 100644 --- a/fhevm-engine/fhevm-go-coproc/fhevm/fhelib.go +++ b/fhevm-engine/fhevm-go-coproc/fhevm/fhelib.go @@ -12,7 +12,7 @@ type FheLibMethod struct { Name string // types of the arguments that the fhelib function take. format is "(type1,type2...)" (e.g "(uint256,bytes1)") ArgTypes string - runFunction func(sess CoprocessorSession, input []byte, outputHandle []byte) error + runFunction func(sess CoprocessorSession, input []byte, ed ExtraData, outputHandle []byte) error ScalarSupport bool NonScalarDisabled bool } diff --git a/fhevm-engine/fhevm-go-coproc/fhevm/fhelib_ops.go b/fhevm-engine/fhevm-go-coproc/fhevm/fhelib_ops.go index c9ed5099..d7ea39a2 100644 --- a/fhevm-engine/fhevm-go-coproc/fhevm/fhelib_ops.go +++ b/fhevm-engine/fhevm-go-coproc/fhevm/fhelib_ops.go @@ -10,7 +10,7 @@ func handleType(handle []byte) FheUintType { return FheUintType(handle[30]) } -func fheAddRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheAddRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -80,7 +80,7 @@ func fheAddRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheSubRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheSubRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -150,7 +150,7 @@ func fheSubRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheMulRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheMulRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -220,7 +220,7 @@ func fheMulRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheRemRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheRemRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -289,7 +289,7 @@ func fheRemRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheBitAndRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheBitAndRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -333,7 +333,7 @@ func fheBitAndRun(sess CoprocessorSession, unslicedInput []byte, outputHandle [] } } -func fheBitOrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheBitOrRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -377,7 +377,7 @@ func fheBitOrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []b } } -func fheBitXorRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheBitXorRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -421,7 +421,7 @@ func fheBitXorRun(sess CoprocessorSession, unslicedInput []byte, outputHandle [] } } -func fheShlRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheShlRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -489,7 +489,7 @@ func fheShlRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheShrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheShrRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -557,7 +557,7 @@ func fheShrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheRotlRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheRotlRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -625,7 +625,7 @@ func fheRotlRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []by } } -func fheRotrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheRotrRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -693,7 +693,7 @@ func fheRotrRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []by } } -func fheEqRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheEqRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -761,7 +761,7 @@ func fheEqRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheNeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheNeRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -829,7 +829,7 @@ func fheNeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheGeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheGeRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -897,7 +897,7 @@ func fheGeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheGtRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheGtRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -965,7 +965,7 @@ func fheGtRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheLeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheLeRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1033,7 +1033,7 @@ func fheLeRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheLtRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheLtRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1101,7 +1101,7 @@ func fheLtRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte } } -func fheMinRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheMinRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1169,7 +1169,7 @@ func fheMinRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheMaxRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheMaxRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 65 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1237,7 +1237,7 @@ func fheMaxRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt } } -func fheNegRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheNegRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 32 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1267,7 +1267,7 @@ func fheNegRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt return nil } -func fheNotRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheNotRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 32 { return fmt.Errorf("expected at least 65 bytes as input, got %d", len(unslicedInput)) } @@ -1297,7 +1297,7 @@ func fheNotRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byt return nil } -func fheIfThenElseRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheIfThenElseRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 96 { return fmt.Errorf("expected at least 96 bytes as input, got %d", len(unslicedInput)) } @@ -1341,7 +1341,7 @@ func fheIfThenElseRun(sess CoprocessorSession, unslicedInput []byte, outputHandl return nil } -func castRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func castRun(sess CoprocessorSession, unslicedInput []byte, _ ExtraData, outputHandle []byte) error { if len(unslicedInput) < 33 { return fmt.Errorf("expected at least 33 bytes as input, got %d", len(unslicedInput)) } @@ -1382,7 +1382,7 @@ func castRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) return nil } -func fheRandRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheRandRun(sess CoprocessorSession, unslicedInput []byte, ed ExtraData, outputHandle []byte) error { if len(unslicedInput) < 1 { return fmt.Errorf("expected at least 1 bytes as input, got %d", len(unslicedInput)) } @@ -1397,7 +1397,12 @@ func fheRandRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []by OutputHandle: outputHandle, Operands: []ComputationOperand{ { - Handle: outputHandle, + Handle: ed.RandomCounter[:], + FheUintType: FheUint256, + IsScalar: true, + }, + { + Handle: []byte{resultTypeByte}, FheUintType: FheUint8, IsScalar: true, }, @@ -1410,7 +1415,7 @@ func fheRandRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []by return nil } -func fheRandBoundedRun(sess CoprocessorSession, unslicedInput []byte, outputHandle []byte) error { +func fheRandBoundedRun(sess CoprocessorSession, unslicedInput []byte, ed ExtraData, outputHandle []byte) error { if len(unslicedInput) < 33 { return fmt.Errorf("expected at least 1 bytes as input, got %d", len(unslicedInput)) } @@ -1427,13 +1432,18 @@ func fheRandBoundedRun(sess CoprocessorSession, unslicedInput []byte, outputHand Operation: FheRandBounded, OutputHandle: outputHandle, Operands: []ComputationOperand{ + { + Handle: ed.RandomCounter[:], + FheUintType: FheUint256, + IsScalar: true, + }, { Handle: unslicedInput[0:32], - FheUintType: FheUint32, + FheUintType: FheUint256, IsScalar: true, }, { - Handle: outputHandle, + Handle: []byte{resultTypeByte}, FheUintType: FheUint8, IsScalar: true, }, diff --git a/proto/coprocessor.proto b/proto/coprocessor.proto index 40c84262..34bda54f 100644 --- a/proto/coprocessor.proto +++ b/proto/coprocessor.proto @@ -11,38 +11,21 @@ import "common.proto"; service FhevmCoprocessor { rpc AsyncCompute (AsyncComputeRequest) returns (GenericResponse) {} - rpc UploadCiphertexts (CiphertextUploadBatch) returns (GenericResponse) {} rpc WaitComputations (AsyncComputeRequest) returns (FhevmResponses) {} rpc UploadInputs (InputUploadBatch) returns (InputUploadResponse) {} - // for debugging, should be removed in prod - rpc DebugDecryptCiphertext (DebugDecryptRequest) returns (DebugDecryptResponse) {} - // for debugging, should be removed in prod - rpc DebugEncryptCiphertext (DebugEncryptRequest) returns (GenericResponse) {} + rpc TrivialEncryptCiphertexts (TrivialEncryptBatch) returns (GenericResponse) {} } -message DebugEncryptRequest { - repeated DebugEncryptRequestSingle values = 1; +message TrivialEncryptBatch { + repeated TrivialEncryptRequestSingle values = 1; } -message DebugEncryptRequestSingle { +message TrivialEncryptRequestSingle { bytes handle = 1; bytes be_value = 2; int32 output_type = 3; } -message DebugDecryptRequest { - repeated bytes handles = 1; -} - -message DebugDecryptResponse { - repeated DebugDecryptResponseSingle values = 1; -} - -message DebugDecryptResponseSingle { - int32 output_type = 1; - string value = 2; -} - message AsyncComputation { fhevm.common.FheOperation operation = 1; bytes output_handle = 3; @@ -56,12 +39,6 @@ message AsyncComputationInput { } } -message CiphertextToUpload { - int32 ciphertext_type = 1; - bytes ciphertext_handle = 2; - bytes ciphertext_bytes = 3; -} - message InputToUpload { bytes input_payload = 1; string contract_address = 2; @@ -91,10 +68,6 @@ message AsyncComputeRequest { repeated AsyncComputation computations = 1; } -message CiphertextUploadBatch { - repeated CiphertextToUpload input_ciphertexts = 1; -} - message InputUploadBatch { repeated InputToUpload input_ciphertexts = 1; }