Announcing ICPP - A protocol for P2P privacy-enabled transactions on the Internet Computer

Just wanted to share with the community the following (and I don’t know why I was always suspecting something of sorts would happen). To get the record straight:

  • Today I was informed by a separate channel that someone within the ICP community (by the name Brandon Cox) is seemingly accusing me of “stealing” his idea.
  • Let me start by saying I have never met this individual, or his associates, didn’t knew of his existence, his work or whatnot until now. Zero.
  • It hardly qualifies as stealing what you have absolutely no idea is taking place. That does not mean people that are completely unconnected, professionally or personally, may be working on similar topics at any given time.

For proper visibility, here is the paper it was alleged I “stole” from Native Stack Privacy (NSP): A Comprehensive Framework for Privacy Across All Layers

Let me be firm in saying this is totally baseless and absurd.

The paper by Cox taxonomizes desirable privacy properties, or “6 principles”, asserting that ICP can host full-stack private apps. The “reference implementation” is an E2E encrypted chat using standard cryptography. Besides that it provides no novel cryptographic constructions, no formal security definitions, and no proofs.

By contrast, ICPP offers:

  • A novel key agreement protocol (RDMPF, NP-hard from rank deficiency)
  • Formal assumptions (cRDMPF, dRDMPF)
  • Security proofs (IND-CPA, authorization soundness, and so on)
  • Dual-intermediary architecture with certified destruction
  • Functional Encryption layer
  • Randomized chunking for ledger decorrelation
  • Live implementation

The only “overlap” is that both run on ICP (assuming their protocol is live; I can only say ICPP is live).

Claiming that someone stole the idea that “privacy should be native to all layers” is like claiming ownership, say, of “security in depth”. It’s a design philosophy, not an invention. ICPP implements novel cryptography to achieve specific properties that NSP doesn’t even attempt to formalize.

(NB: for some strange reason it reminds me of an exchange I had in the early hours of the morning in this very thread… because the pattern rhymes: assertions without substance, refusal to engage formally, inability to specify when challenged.)

If anything, the NSP paper’s comparison table (pp. 6-7) would place ICPP in a category NSP doesn’t address: cryptographic content protection with formal security guarantees.

To wrap up: the technical overlap is zero. Only common denominator is that we both build on ICP and care about privacy.

Points 1 to 5 still stay valid after your response, nothing has changed.
You didn’t mention anything about 1-3 in two threads and ~50 posts until I brought it up and explained how things work. Some of the knowledge around that is not even documented and chatGPT definitely doesn’t know about it. People with 4y in the eco will find something they didn’t know in these points. You’ve been around for months. Then you pointed out the whitepaper didn’t include a lot of implementation angles…

Then you included some of the privacy related issues I pointed out in the whitepaper, but much more obfuscated and later said:

I’ve made an overview of the whole protocol analysis with 5 points.
Your response was:

This conversation stops making any sense here, looks like chatGPT generated text where you asked it to sound like a professor and argue, but it’s getting the basics wrong, so I will not really participate and waste my time after this post. Your attempts to obfuscate, conceal and deny concerns me.


I will demonstrate point 5.

Your response:

Here is the setup:
Alice ICPP address: ny5ow-blfbl-tayay-ggwzd-5zafp-gbf47-lhgv2-3bt5a-6vqoo-iecii-yqe
28946f739b8b799c09a8041607ee47beb0bf9a87a2c5d419013c5821bcbd973a

Bob ICPP address: eourg-yfyhl-pre7b-jftsn-ol2ze-igwcb-dfhfs-d2tw4-d3q5r-3nski-lae
0f7e049c3d64e6b9db817c8a1e2ce927a8d2b71a32465abd74e7150332070cc7

I’ve sent 1ICP from Alice to Bob using ICPP.

Separate issue I have with the service fee!!!

It says the ICPP service fee is 0.005ICP
But the “canister spawning and operations” is 3.9409 ICP (I supposed creating two canisters, however once that is done, most of the cycles can be reclaimed by ICPP, so the service fee is actually much more, unless you just throw the cycles away - I doubt. You’ve correctly pointed out down there - 394.658%. ~11$ per transfer fees going to ICPP. Your protocol could just use its own cycles, creating two canisters cost 0.65$ x 2, then after deleting the canisters reclaim whatever cycles remain. It would cost the protocol ~1.4$ to do the canister ops. If it charges 2.4$ there is 1$ for the ICPP protocol.

I wanted to find the single pool address the protocol uses and then ask Claude to quickly write me a script that goes over it and links all the different Bob ↔ Alice pairs there are.

  1. It would start with the pool address, easily find all Bobs (the only outgoing tokens) collect addresses,amount,timestamps (B).
    Here is the pool (easily findable once you send a transfer and follow your transaction): IC Explorer - Internet Computer Block Explorer


Every transaction going thru the protocol will move thru this address.

I see Bob’s address there as expected 0f7e049c…32070cc7

  1. Script will go over all the input addresses (These are the router deposit addresses). They are new each time.


A router deposit address.

You can easily see the sum of the chunked transactions is 1 ICP. Alice’s address is also there (A). It will be trivial to match timestamps and amounts of (A) and (B) and establish link between Alice and Bob (even with thousands of transactions).

I would advise @Leadership to NOT promote this project before people had time to review it. After playing out the different scenarios ahead in time there seem to be a few that will not really be desirable long term. And I am not even talking about the privacy issues at all here and the lack of privacy.

Your screenshot from above


It’s great that you are trying to solve the quantum problem, but first learn how to use a ledger browser, second - stop arguing using chatGPT, instead try to understand what you are doing.

But what if Bob send 0.1 ICP out of pool to 10 different addresses within 30 days. You have no idea who actually deposited it as long as you wait and pull out small amounts to many wallets over longer timeframe. If this app really busy, you have no idea who sending what.

BTW infu You look more like borovan who find good project, try to destroy it and than build yourself.

About Dfinity promoting it, i dont see it happening because if someone steals big amount and start laundering it, Dfinity cant have any trace of promoting it. Best way to get funding is from people who move not so clean money, like Russia or North Korea.

Thats what we want to happen!

Not sure why this is controversial I think we all want Mr. Salazar here to have the resources to get this properly audited. Thats all.

Honestly, I don’t see what this changes. Let’s look at what ICP’s dashboard says, not some Claude-generated :laughing: script (it’s you using AI, not me…) of which I have no visibility about.

You provide both Alice’s and Bob’s addresses. Alice’s starts with 2894 and Bob’s with 0f7e from what I can read above.

From either end, I could not place Alice and Bob in the same frame. The ICP’s dashboard graph explorer, which is literally designed to reveal transaction relationships, cannot visually connect sender to receiver even with expanded depth.

Limiting the graph view to a depth of 1 for inbound links to Alice and pushing up to a depth of 8 in the other direction (which is what we’re interested) there is no connection (edge) between Alice and Bob shown. None.

Let’s now do Bob’s side of the equation but reversing the search depth (8 in, 1 out).

Surprise: Alice can neither be found.

So, at 8 levels of depth exploration on either side of the transaction in the relevant directions (outflows for Alice, inflows for Bob; you don’t need a depth of 8… the graph explorer chokes even before that because the is not that deep in either direction) neither of them appear in the same frame.

From Alice’s view:

  • Alice (2894…973a) visible
  • Funds flow to a3a4…9045
  • Chunks go to pool (35bd…0ec4): 0.440044, 0.270027, 0.290029
  • Bob not visible

From Bob’s view:

  • Bob (0f7e…0cc7) visible
  • Receives 1 ICP from pool (35bd…0ec4)
  • Pool fed by a3a4…9045, ea8a…ef0c, and so on
  • Alice not visible

Conclusion: Even at depth 8, the ICP Dashboard graph explorer cannot connect Alice to Bob. The intermediate node a3a4…9045 appears in both views, but the chain doesn’t resolve to show both endpoints simultaneously.

In this respect, your trivial (Claude-generated) script seems to outperform ICP’s own purpose-built chain analysis tooling. There is only one way to check it out: Publish your script or retract.

But the fact remains: you traced your own transaction and concluded correlation is trivial. But the traceability you have “demonstrated” depends on self-knowledge (you know which amounts are yours). What an external attacker has is only ledger data, not an oracle telling him which deposit corresponds to which withdrawal.

Answering which inputs fund which outputs is a combinatorial problem. Even at n=1, an external observer sees one deposit and one withdrawal. They can guess they’re related… but “guessing with n=1” is not “trivial correlation” at scale.

In short, you used your own knowledge (being Alice and Bob at the same time) to trace the path, to then claim that an external observer could do the same. For that, your “script” would need to:

  • Enumerate all deposit-withdrawal pairs
  • Test subset-sum matches for each pair (when n > 1 good luck)
  • Disambiguate when multiple combinations sum correctly

Without the oracle of “I know this is my transaction” the problem explodes. That’s the maths, not me.

Let me add this, before I forget: run this same test using Zcash or Monero technology. Meaning: tracing your own single transaction in a set of 1 with self-knowledge of the amounts. You’ll get the same result.

On the rest, I said what I had to say, not going to waste more time explaining it. Anyone following the thread can evaluate for themselves.

I had the intention of writing a script, but didnt have enough data to make sense, you only have 2 transactions. What you are seeing is called ICP explorer, it’s not mine.

You deleting a canister doesn’t delete ledger transactions. Maybe it only tricks the dashboard.

Why cant we build like this: Alice send 100 ICP to splitter, it splits ICP to 10 shared pools, 10 ICP each. Alice set 20 amounts with what time She want those to move from pool to 20 different wallets. When set time comes transaction from pool triggers and send to 20 Bob addresses. Only problem will be to hide data what is written during Alice writes into app. Protocol itself can use its own funds to rotate and send without fees so that it has better mixing.

Well, I have used the same tool, showing you the results. Explaining them to you.

Let me expand…

If an attacker surveils both Alice and Bob (knows their addresses, watches their transactions: an endpoint compromise) they can correlate regardless of what happens in between.

This is true of:

  • Tor (entry + exit surveillance)
  • Monero (sender + receiver wallet monitoring)
  • Zcash (same)
  • Signal (sender + receiver device compromise)
  • Every privacy system ever built

The protocol protects the path, not the endpoints. If you own both endpoints, you don’t need to break the protocol: you already have the information.

I am not as smart as either of you, but from a common sense perspective I think these things are true:

If I know Alice and Bob and try to link them, that is easier than if I only know one.

As this scales (more people use it) it becomes increasingly more complex to link Alice and Bob.

Here’s what I know for a fact. My tool that can see thousands of transactions simultaneously. But it doesn’t see Mr. Salazar’s.

You replied as I answered this…

Basically: the situation he flags (endpoint compromise) is not in any privacy protocol’s threat model because it’s definitionally outside what transport privacy can provide.

Get what you suggest but IMHO this adds nothing, and it’s actually a regression. Let me explain.

You are basically proposing a trusted mixer with scheduled withdrawals. A (weaker) Tornado Cash version with added steps.

Why? The stored scheduling instructions (Alice’s amounts, timing, destinations) are exactly the attack surface ICPP eliminates by destroying state. Your proposal retains that mapping until execution, and in doing so making it compromisable. Also, “protocol uses its own funds” introduces a trusted operator. This IMHO is a regression, not an improvement.

Im no expert, only Alice input can be traced. No one can trace how many time events She created, what wallets set as output and what amounts. Lets say She split into 31 parts, every month at random date She picked, pool send set amount to set wallet.
By own funds i meant protocol will make so called fake users that use protocol to get better untrackable results. There is still needed many users to have useful result.

Well, I am out. Hope someone else comes around and helps you understand what eludes you. Clicks on your pool address 35bd6b9fa935ba0337fdaa6a988d414ada87a30b2c6cae66f5813b0feb330ec4
And explains how you establish the link between Alice<->Bob.

Thanks for linking the pool. Most revealing. Let me explain why.

For starters, anyone can look at it and see exactly what I described: chunks in from deposit subaccounts, withdrawals out to recipients. No mapping. No correlation data. Just transactions. Establishing Alice-Bob from that data is the subset-sum problem I explained.

You are seeing Alice → deposit_subaccount → chunks → pool and then Pool → Bob. But at n=1 this is trivial, even more so with you being at both ends of the table at the same time. Exactly the same would happen in Monero or Zcash.

Let’s work out the maths, which you seem to ignore. Let’s take n = 50, for sake of argument.

  • We would have 150 deposits (50 transactions in 3 chunks each) and 50 outflows.

  • The first step is to group the 150 chunks into 50 triplets. Which chunks belong together? That’s the problem to solve at this stage. Anything but trivial.

  • But even if the attacker can group by source subaccount (since chunks from the same deposit come from the same subaccount; we’ll assume that’ solved by the attacker in what follows) you still have to match 50 grouped deposits to 50 withdrawals.

  • That’s 50! ~ 3.04 x 10^64. For a perspective, at 10^18 guesses per second (all computing power worldwide is currently at ~10^21 I think, so I’m using 10^18 or 1 EFLOPS as proxy for a Nation-State attack) and given there are about 3.15 x 10^7 seconds in a calendar year, elementary math will show you could make 3.15 x 10^25 guesses a year. Therefore, it would take about 9.65 x 10^38 ~ 10^39 years to enumerate the 50! possibilities from just 50 transactions.

If you think that the age of the universe is estimated, if I’m not wrong, at roughly 1.38 x 10^10 years, you get the picture.

Am I being biased? Possibly. EFLOPS measure FP operations, whereas guessing (as in brute-forcing) are simple repetitive guesses. If a Nation-State directs all its computing power towards that goal, the processing power scales up massively. So let’s use as benchmark 1.1 x 10^21 hashes/second which is what the entire Bitcoin network processes. Makes no difference.

And you’re forgetting a fact: fees mean that deposit gross is not equal to withdrawal net. Alice deposits 4.48 gross, Bob withdraws 1.0 net. There’s no clean sum to match.

Let’s narrow it to n = 20 transactions. You have 2.43 × 10^18 possible mappings. Still not trivial to solve.

Let’s make it now n = 20 per day (protocol operating, not a n = 20 batch) and the fact that transactions are not a one-shot: Alice sends, but Bob has to reclaim, and he can do so up to 3 days later. Not everyone will pull the same day, which means that you need to traverse the whole transaction history.

In a 3-day window and n = 20 but rolling we have (quite obviously) a set of 60 to enumerate, and 60! ~ 8.32 x 10^81. In this scenario, however, an attacker would see a stream of chunks in, withdrawals out. No clean partitions. No “batch” boundaries. And let’s not ignore collisions: many transactions will cluster around common values. Multiple 5 ICP deposits, 10 ICP deposits, whatever. Which one matches which?

With no boundaries, asynchronous timing, amount collisions, and no visibility into claimed vs. pending state? Good luck.

By contrast, what did you solve and claim breaks the protocol? n = 1 or 1! = 1.

What can I say…

@EdSalazar @WebTreeSoftwareSolut @ICdex @COOLLER @MForum @Henn91

Check out - :high_voltage: Personal DAO they might implement this later

Thanks for the heads up..!

To make this debate to rest… because honestly there is nothing much to debate…

The fundamental gist of what this n = 1 exercise demonstrates is that no graph edge directly connects Alice and Bob. In a standard blockchain transaction, the ledger says Alice → Bob. In ICPP, it says Alice → Subaccount A → Router → Subaccount B → Bob. By the time the transaction is finalized, the intervening canisters are blown up. The bridge is burned to the ground.

Does a ledger record exist? Of course. If it didn’t, the ICP wouldn’t be spendable. But there is a massive difference between a record of value and a record of origin. The ledger shows that Bob received native, spendable ICP. The metadata that proves that specific ICP came from Alice lived only in the ephemeral canisters. And those canisters haven’t just been stopped; they’ve been mathematically wiped and deleted. The record remains, it has to. **The linkage is gone.

Ah, but see, I can see it was Alice sending to Bob..!** This is just a common misunderstanding (which I’ve tried at pains to explain) of how privacy sets work.

So, the logical inference that “Alice sent money to the Router, and Bob received money from the Router, and since no one else used the Router today, clearly Bob’s money must be Alice’s” isn’t “breaking the protocol” in any form or shape. It’s mistaking observational inference for a cryptographic break.

In any privacy system (Monero, Zcash, Tor, ICPP) privacy is a statistical property of the crowd, not a magical property of a single transaction.

To provide an analogy: In a building with one occupant, if that person flushes the toilet, you know whose water is moving through the pipes. But as soon as the building is full, that certainty vanishes forever. No leak in the pipes has been found, what was found is that only one person is using the bathroom.

And yet the ledger still does not show the link. It shows that Alice sent to X and Y sent to Bob, but has no record of X and Y being related. As soon Claire enters the system, that “mental trace” (of knowing Alice send ICP to Bob, because you are Alice and Bob at the same time…) immediately loses 50% of its certainty. Push the number even to n = 10 and it becomes much messier. Why?

Baseline mapping (assuming incoming chunks can be grouped together) is 10! ~ 3.6 million.

Let’s now look at the reality. If an attacker sees 30 fragments entering the router and 10 withdrawals leaving, they have to solve a partitioning problem before they can even attempt the mapping (I purposedly obviated this in my previous response because it really didn’t matter, given the examples I was presenting).

The number of ways to partition 30 distinct items into 10 groups of 3 is 30! / ((3!)^10 + 10!) ~ 1.2 x 10^18. But, of course, an attacker would want to map these groups to specific recipients (labeled outputs). In such case the 10! cancels out. The total number of ways to assign 30 fragments to 10 specific people emitting 3 fragments each is 30! / (3!)^10 = 30! / 6! ~ 4.38 x 10^24. That’s the tidy sum of 4 septillion possible mappings.

For a Nation-State throwing 1 EFLOPS it would take roughly 51 days of 100% dedicated capacity computing to exhaust the n = 10 mapping.

That’s for a fixed batch. As soon as you consider 10 daily transactions it just becomes computationally intractable. Even for 10 transactions per day.

Nothing more to add.

Your deposit ids are fresh for every transfer. It’s trivial to sum them up, the canister fees go to another address and get burned for cycles, easy to see. Wrong unless you assume nobody knows your protocol exists and how it works and can’t automatically detect patterns?

Let’s see (How much time it will take you to match deposits with withdrawals? 10^39 years to enumerate?

Deposit Withdraw
132 ICP
47 ICP
388 ICP
215 ICP
79 ICP
301 ICP
164 ICP
23 ICP
276 ICP
96 ICP
340 ICP 164 ICP
61 ICP 47 ICP
372 ICP 96 ICP
12 ICP 301 ICP
249 ICP 23 ICP
181 ICP 388 ICP
74 ICP 79 ICP
333 ICP 215 ICP
143 ICP 276 ICP
6 ICP 132 ICP
262 ICP 340 ICP
88 ICP 61 ICP
309 ICP 372 ICP
203 ICP 12 ICP
157 ICP 249 ICP
38 ICP 181 ICP
400 ICP 74 ICP
67 ICP 333 ICP
291 ICP 143 ICP
118 ICP 6 ICP
52 ICP 262 ICP
227 ICP 88 ICP
191 ICP 309 ICP
18 ICP 203 ICP
356 ICP 157 ICP
298 ICP 38 ICP
131 ICP 400 ICP
84 ICP 67 ICP
241 ICP 291 ICP
172 ICP 118 ICP
33 ICP 52 ICP
266 ICP 227 ICP
92 ICP 191 ICP
312 ICP 18 ICP
204 ICP 356 ICP
159 ICP 298 ICP
41 ICP 131 ICP
399 ICP 84 ICP
68 ICP 241 ICP
274 ICP 172 ICP
33 ICP
266 ICP
92 ICP
312 ICP
204 ICP
159 ICP
41 ICP
399 ICP
68 ICP
274 ICP

It will take 1min. Your calculations assume everyone sends the same amounts and there aren’t easier to detect decoys.
Anyway, I’ll be happy to help you harden your protocol with another batch of things you’ve architectured badly, but you are going to have to apologize first. Seriously, I gave you already a lot of knowhow and pointed out numerous mistakes. You denied that I’ve contributed anything meaningful, then defended your mistakes refusing to accept the facts until I simplified them enough to make them obvious. The next batch has few more points, already compiled - should you choose to accept.

Right…

Your example shows different values in each column. If they’re not the same set, what exactly are you matching? If they are the same set (just shuffled) then you’ve assumed deposit = withdrawal, which isn’t how ICPP works.

If they’re different values, there’s nothing to match. In ICPP Alice deposits, say, 4.48 gross, Bob withdraws 1.0 net. Show me how you match those.

As for apologies: you’ve demanded I retract while providing n=1 tests, alleged scripts you won’t publish, and now synthetic data that doesn’t reflect the protocol.

So IMHO this conversation has exhausted itself: I’ve provided dashboard evidence, combinatorial analysis, and challenged every claim with specifics. You responded with n=1 self-traces, some scripting work (or not, couldn’t care less at this stage) and now a seemingly incoherent table.

I’ll engage with substance. I won’t engage with theater.

And if you believe you can do it better, go build it yourself.

End of.

Not interested in making privacy protocols thanks.

It’s kind of enough for me to see you were expecting your ledger transactions to be deleted because you were deleting your canisters. Your screenshot:

Historically, attempts to dodge the obvious in a forum discussion- hoping there are enough people who don’t understand the technology and will believe what you say- haven’t worked out well.