Skip to content

Commit ddb130b

Browse files
committed
feat: sdk and cli parse input.json to the raw numbers
1 parent c22391e commit ddb130b

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

crates/cli/src/main.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -926,10 +926,17 @@ fn verification_data_from_args(args: &SubmitArgs) -> Result<VerificationData, Su
926926
"--vk",
927927
args.verification_key_file_name.clone(),
928928
)?);
929-
pub_input = Some(read_file_option(
930-
"--public_input",
931-
args.pub_input_file_name.clone(),
932-
)?);
929+
let pub_input_file =
930+
read_file_option("--public_input", args.pub_input_file_name.clone())?;
931+
let pub_inputs: Vec<String> = serde_json::from_slice(&pub_input_file)
932+
.map_err(|e| SubmitError::MissingRequiredParameter(e.to_string()))?;
933+
934+
let decode_inputs = aligned_sdk::common::utils::encode_circom_pub_inputs(&pub_inputs)
935+
.map_err(|_| {
936+
SubmitError::MissingRequiredParameter("Invalid public inputs".into())
937+
})?;
938+
939+
pub_input = Some(decode_inputs);
933940
}
934941
}
935942

crates/sdk/src/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod constants;
22
pub mod errors;
33
pub mod types;
4+
pub mod utils;

crates/sdk/src/common/utils.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use ethers::{abi::ethereum_types::FromDecStrErr, types::U256};
2+
3+
/// Encodes Circom public inputs into a single byte vector.
4+
///
5+
/// Circom normally outputs public inputs as a JSON array of strings, where each
6+
/// entry is actually a big integer represented in decimal. For example:
7+
///
8+
/// ```json
9+
/// { "pubInputs": ["123", "456", "789"] }
10+
/// ```
11+
///
12+
/// For on-chain usage (e.g. in Solidity), working with JSON is inefficient.
13+
/// Instead, we prefer the **raw form**: each input is converted to a 32-byte
14+
/// big-endian encoding of the integer, concatenated together. This makes it
15+
/// simple to compute commitments and verify proofs on-chain, since the contract
16+
/// receives a compact `bytes` array rather than parsing JSON.
17+
///
18+
/// Each input must fit in 32 bytes (i.e. < 2^256).
19+
pub fn encode_circom_pub_inputs(input: &[String]) -> Result<Vec<u8>, FromDecStrErr> {
20+
let mut out = Vec::with_capacity(input.len() * 32);
21+
22+
for s in input {
23+
// parse as decimal (base 10). Use from_str_radix(s, 16) if they're hex.
24+
let n = U256::from_dec_str(s)?;
25+
let mut bytes = [0u8; 32];
26+
n.to_big_endian(&mut bytes);
27+
28+
out.extend_from_slice(&bytes);
29+
}
30+
31+
Ok(out)
32+
}

0 commit comments

Comments
 (0)