SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
Submission Details
Impact: high
Likelihood: high

Total System Collapse: Plaintext Secret Exposure

Author Revealed upon completion

Root + Impact

Description

A Zero-Knowledge proof is only useful if the "witness" (the private input) is difficult to guess.

  1. Hardcoded Hashes: The ALLOWED_TREASURE_HASHES are public. Anyone can see them by looking at the Noir file or the contract deployment data.

  2. Deterministic Hashing: The circuit uses a standard Pedersen hash of a single Field element: pedersen_hash([treasure]).

  3. The Exploit: If the "treasures" are human-readable strings, small numbers, or even 256-bit values that haven't been salted, an attacker can run a dictionary attack or a rainbow table against the 10 public hashes.

// The "Map" is public
global ALLOWED_TREASURE_HASHES: [Field; 10] = [
1505662313093145631275418581390771847921541863527840230091007112166041775502,
// ... an attacker just needs to find what 'x' results in this hash
];
fn main(treasure: Field, treasure_hash: pub Field, recipient: pub Field) {
// @> If I know the treasure, I can generate the proof for ANY recipient.
assert(std::hash::pedersen_hash([treasure]) == treasure_hash);
}

Risk

Likelihood: Critical

  • The hashes are visible in the source code.

  • If the treasure values were generated with low entropy (e.g., "treasure1", "gold_key"), they can be cracked in milliseconds.

Impact: High

  • The "Hunt" is over immediately. One person (or bot) will claim all 10 rewards (100 ETH) before anyone else can even start.

Proof of Concept

Recommended Mitigation

Salting: The treasure should be a combination of a secret AND a unique identifier (like a nullifier) to prevent dictionary attacks.

  • Off-chain Commitment: Don't bake the hashes into the circuit. Instead, store a Merkle Root of the allowed treasure hashes in the Smart Contract. This allows you to add treasures without recompiling the circuit and hides the individual hashes until they are claimed.

  • High Entropy: Ensure the treasure secrets are cryptographically strong (at least 256 bits of randomness).

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!