Skip to content

Commit

Permalink
Merge pull request #14 from zkemail/dimidumo/publicKeyHash_wasm
Browse files Browse the repository at this point in the history
feat: add public_key_hash wasm bindings
  • Loading branch information
DimiDumo authored Dec 11, 2024
2 parents e0c1e8d + c1423fc commit cf873f9
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"wasm:postbuild": "node build.js",
"build": "npm run wasm:build && npm run wasm:postbuild"
},
"version": "0.4.52",
"version": "0.4.55",
"devDependencies": {
"@types/bun": "latest",
"prettier": "^3.3.3"
Expand Down
47 changes: 47 additions & 0 deletions src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use crate::{
AccountSalt, CircuitInputWithDecomposedRegexesAndExternalInputsParams, DecomposedRegex,
ExternalInput, PaddedEmailAddr, ParsedEmail,
};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures::future_to_promise;

#[wasm_bindgen]
#[allow(non_snake_case)]
Expand Down Expand Up @@ -264,3 +266,48 @@ pub async fn sha256Pad(data: JsValue, max_sha_bytes: usize) -> Promise {
}
}
}

#[wasm_bindgen]
#[allow(non_snake_case)]
#[cfg(target_arch = "wasm32")]
/// Computes the Poseidon hash of a public key.
///
/// # Arguments
///
/// * `public_key_n` - A `Uint8Array` containing the public key in little endian format.
///
/// # Returns
///
/// A `Promise` that resolves with the hexadecimal string representation of the hash,
/// or rejects with an error message.
pub async fn publicKeyHash(public_key_n: JsValue) -> Promise {
use crate::{field_to_hex, public_key_hash};
console_error_panic_hook::set_once();

// We'll wrap the logic in a future so we can use `Promise` and `await`.
let future = async move {
// Convert JsValue (Uint8Array) to Vec<u8>
let mut key_bytes: Vec<u8> = from_value(public_key_n)
.map_err(|e| JsValue::from_str(&format!("Failed to convert input: {}", e)))?;

// Reverse the bytes for little-endian format
key_bytes.reverse();

// Compute the hash
let hash = public_key_hash(&key_bytes)
.map_err(|e| JsValue::from_str(&format!("Failed to compute hash: {}", e)))?;

// Convert hash field to hex string
let hex_hash = field_to_hex(&hash);
to_value(&hex_hash)
.map_err(|e| JsValue::from_str(&format!("Failed to serialize result: {}", e)))
};

// Convert the future into a JS Promise
future_to_promise(async move {
match future.await {
Ok(js_value) => Ok(js_value),
Err(e) => Err(e),
}
})
}
23 changes: 23 additions & 0 deletions ts_tests/public_key_hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { expect, test, describe, it } from "bun:test";
import { publicKeyHash, init } from "../pkg";

const publicKeyHex =
"cfb0520e4ad78c4adb0deb5e605162b6469349fc1fde9269b88d596ed9f3735c00c592317c982320874b987bcc38e8556ac544bdee169b66ae8fe639828ff5afb4f199017e3d8e675a077f21cd9e5c526c1866476e7ba74cd7bb16a1c3d93bc7bb1d576aedb4307c6b948d5b8c29f79307788d7a8ebf84585bf53994827c23a5";

// Convert hex string to Uint8Array (no reversal needed)
function hexToBytes(hex) {
return new Uint8Array(hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
}

const publicKeyBytes = hexToBytes(publicKeyHex);

// The expected hash result from the Rust test
const expectedHash = "0x181ab950d973ee53838532ecb1b8b11528f6ea7ab08e2868fb3218464052f953";

describe("publicKeyHash", async () => {
await init();
it("should correctly hash the public key", async () => {
const result = await publicKeyHash(publicKeyBytes);
expect(result).toBe(expectedHash);
});
});

0 comments on commit cf873f9

Please sign in to comment.