Skip to content

Commit

Permalink
Overflow Risk Mitigation in Merkle Sum Trees Using keccak256 (#289)
Browse files Browse the repository at this point in the history
* feat: use hashed username for mitigating attack vector

* fix: backend test
  • Loading branch information
sifnoc authored Apr 18, 2024
1 parent 332d309 commit 5237346
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
2 changes: 1 addition & 1 deletion backend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ mod test {
liability_commitment_logs[0],
LiabilitiesCommitmentSubmittedFilter {
timestamp: U256::from(1),
mst_root: "0x18d6ab953235a811edffa4cead74ea045e7cd2085771a2269d59dca054c955b1"
mst_root: "0x177bf452ad139f067a64fe09fdc30aae46144d60abfa2ad9f0c70928e29a26d1"
.parse()
.unwrap(),
root_balances: vec![U256::from(556862), U256::from(556862)],
Expand Down
12 changes: 6 additions & 6 deletions zk_prover/src/circuits/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,17 +339,17 @@ mod test {
cell_values: vec![
(
((Any::advice(), 0).into(), 0).into(),
"0xe113acd03b98f0bab0ef6f577245d5d008cbcc19ef2dab3608aa4f37f72a407"
"0x167505f45c4ef4a0b051c30e881d2e8f881f26f5edb231396198a2cc1712f5ad"
.to_string()
),
(
((Any::advice(), 0).into(), 1).into(),
"0x17ef9d8ee0e2c8470814651413b71009a607a020214f749687384a7b7a7eb67a"
"0x2c688f624d2bca741a1c2ad1ad2880721fbfd1613bbc5fe3d2ba66eb672e3aab"
.to_string()
),
(
((Any::advice(), 1).into(), 0).into(),
"0x17ef9d8ee0e2c8470814651413b71009a607a020214f749687384a7b7a7eb67a"
"0x2c688f624d2bca741a1c2ad1ad2880721fbfd1613bbc5fe3d2ba66eb672e3aab"
.to_string()
),
(((Any::advice(), 2).into(), 0).into(), "0x2".to_string()),
Expand All @@ -364,17 +364,17 @@ mod test {
cell_values: vec![
(
((Any::advice(), 0).into(), 0).into(),
"0xe113acd03b98f0bab0ef6f577245d5d008cbcc19ef2dab3608aa4f37f72a407"
"0x167505f45c4ef4a0b051c30e881d2e8f881f26f5edb231396198a2cc1712f5ad"
.to_string()
),
(
((Any::advice(), 1).into(), 0).into(),
"0x17ef9d8ee0e2c8470814651413b71009a607a020214f749687384a7b7a7eb67a"
"0x2c688f624d2bca741a1c2ad1ad2880721fbfd1613bbc5fe3d2ba66eb672e3aab"
.to_string()
),
(
((Any::advice(), 1).into(), 1).into(),
"0xe113acd03b98f0bab0ef6f577245d5d008cbcc19ef2dab3608aa4f37f72a407"
"0x167505f45c4ef4a0b051c30e881d2e8f881f26f5edb231396198a2cc1712f5ad"
.to_string()
),
(((Any::advice(), 2).into(), 0).into(), "0x2".to_string()),
Expand Down
20 changes: 13 additions & 7 deletions zk_prover/src/merkle_sum_tree/entry.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
use crate::merkle_sum_tree::utils::big_intify_username;
use crate::merkle_sum_tree::Node;
use ethers::utils::keccak256;
use num_bigint::BigUint;

/// An entry in the Merkle Sum Tree from the database of the CEX.
/// It contains the username and the balances of the user.
#[derive(Clone, Debug, std::cmp::PartialEq)]
pub struct Entry<const N_CURRENCIES: usize> {
username_as_big_uint: BigUint,
hashed_username: BigUint,
balances: [BigUint; N_CURRENCIES],
username: String,
}

impl<const N_CURRENCIES: usize> Entry<N_CURRENCIES> {
pub fn new(username: String, balances: [BigUint; N_CURRENCIES]) -> Result<Self, &'static str> {
// Security Assumptions:
// Using `keccak256` for `hashed_username` ensures high collision resistance,
// appropriate for the assumed userbase of $2^{30}$.
// The `hashed_username` utilizes the full 256 bits produced by `keccak256`,
// but is adjusted to the field size through the Poseidon hash function's modulo operation.
let hashed_username: BigUint = BigUint::from_bytes_be(&keccak256(username.as_bytes()));
Ok(Entry {
username_as_big_uint: big_intify_username(&username),
hashed_username,
balances,
username,
})
Expand All @@ -25,7 +31,7 @@ impl<const N_CURRENCIES: usize> Entry<N_CURRENCIES> {
let empty_balances: [BigUint; N_CURRENCIES] = std::array::from_fn(|_| BigUint::from(0u32));

Entry {
username_as_big_uint: BigUint::from(0u32),
hashed_username: BigUint::from(0u32),
balances: empty_balances,
username: "0".to_string(),
}
Expand All @@ -35,7 +41,7 @@ impl<const N_CURRENCIES: usize> Entry<N_CURRENCIES> {
where
[usize; N_CURRENCIES + 1]: Sized,
{
Node::leaf(&self.username_as_big_uint, &self.balances)
Node::leaf(&self.hashed_username, &self.balances)
}

/// Stores the new balance values
Expand All @@ -49,15 +55,15 @@ impl<const N_CURRENCIES: usize> Entry<N_CURRENCIES> {
[usize; N_CURRENCIES + 1]: Sized,
{
self.balances = updated_balances.clone();
Node::leaf(&self.username_as_big_uint, updated_balances)
Node::leaf(&self.hashed_username, updated_balances)
}

pub fn balances(&self) -> &[BigUint; N_CURRENCIES] {
&self.balances
}

pub fn username_as_big_uint(&self) -> &BigUint {
&self.username_as_big_uint
&self.hashed_username
}

pub fn username(&self) -> &str {
Expand Down

0 comments on commit 5237346

Please sign in to comment.