diff --git a/CASHFUSION.md b/CASHFUSION.md
index d8ad0e0..b93fb88 100644
--- a/CASHFUSION.md
+++ b/CASHFUSION.md
@@ -17,7 +17,7 @@ This scheme takes a "sharding" approach whereby each player gives each other pla
There are a few "moving parts" needed to implement the solution:
1. Covert announcements of inputs
-2. Salted hashes of inputs
+2. Commitment scheme
3. Random ordering of players
4. Sharding grid
5. Ephemeral encryption keys
@@ -33,9 +33,38 @@ The layered encryption method used in CashShuffle (but repeated for multiple inp
Each player will also have a single transaction output (no change output here) that is announced to the server at the beginning of the process.
-## Salted Hashes of Inputs
+## Commitment Scheme
+
+Within CashFusion, the commitment scheme must allow each player to prove they submitted 10 unique inputs which are part of the total set of inputs submitted by all the players for the joined transaction. Each player is expected to reveal each input to a separate verifying party.
+
+This is a challenging requirement in of itself. For example, if the commitment was simply a hash value, then it could be trivially broken with a dictionary attack, since the data set is small (100 inputs). Using salted hashes prevents this attack, but opens a new attack vector in which a player commits the same input more than once. (The salts prevent what is commited from being necessarily unique, and the non-uniqueness would be undectable since the information about each input is revealed to different parties.)
+
+An additional requirement is that players need to commit to a certain order for their inputs. In other words, Alice needs to identity which is her "first" input, her "second" input etc, and commit to it early in the process so that collusion attacks are prevented. For example, if Bob colludes with Alice and knows ahead of time which input of Alice he will validate, he can spoof that commitment.
+
+Our goals can be met as follows:
+
+The commitment for each input X is based on a set of 2 secret numbers A, and B, such that X ⊕ A ⊕ B = 0. (A can be chosen first as a random number, and B calculated as X ⊕ A.) A is encrypted with public key k ("commitment key"), which a unique ephemeral key. The resulting ciphertext (A') is announced along with, and at the same time that the input itself is coveretly announced. B is announced separately as part of a list, which we can call the B list.
+
+The B list consists of 10 random numbers B1... ...B10 where each element represents a unique B value. Unlike the A component, no actual inputs are included here. The list is simply a set of 10 random numbers, which by itself reveals zero knowledge. This list also serves the secondary functioning of commiting to an input order (the first item in the list is part of the commitment for the "first" input, the second item for the second input, and so on.)
+
+To reveal an input, the player simply sends X ,A, and k to the verifier.
+
+For example, imagine Bob is responsible for verifying Alice's first input. (We will discuss later how this came to be in the sharding grid section).
+
+Recall that the A number that was announced along with the actual input is encrypted as A', and since the input was covertly announced, it has no linkage to any other input. No one knows it belongs to Alice, let alone that it is her "first" input.
+
+Alice gives the key k to Bob, and now Bob can check that A' = Ek(A), and also that X ⊕ A ⊕ B = 0.
+
+Can Alice cheat by submitting the same input to both Bob and Carol? No, because the input itself is attached to a commitment that can only be decrypted to a single value, and that won't work with 2 different values in the B list.
+
+Or, more formally: if X is the input Alice wishes to double submit, we have:
+
+ X ⊕ A1 ⊕ B1 = 0
+
+ X ⊕ A2 ⊕ B2 = 0
+
+But, since B1 ≠ B2 (the values in the B list must all be unique), then A1 ≠ A2. Therefore, A' = Ek(A1) → A' ≠ Ek(A2).
-Each player will create a set of salted hashes of their transaction inputs, with a separate secret salt value for each input. Once the hashes are computed, they can be ordered, ascending numerically, which provides an immutable ordered list that will be broadcast to the other players. The ordered list provides a distinct position for each input (e.g. Alice's "first" input and "second" input, etc). Note this must be done prior to setting up the sharding grid so that players can't change the order after the fact.
## Random Ordering of Players
@@ -53,9 +82,9 @@ With the full set of 11 players and 10 inputs, the sharding grid appears as foll
## Ephemeral Encryption Keys
-Each input involved in the transaction needs an additional (ephemeral) encryption key, used for the purposes of validation.
+Each input involved in the transaction requires an ephemeral encryption key, used for secure communication to the validating party.
-Each player creates a set of keypairs (one for each input they are responsible for validating), and then shares the public keys with the group. Separately, each player also creates a set of encrypted proofs (one for each of their own inputs) by encrypting the input along with its secret salt (refer to section on salted hashes), using the public key of the validating player.
+Each player creates a set of keypairs (one for each input they are responsible for validating), and then shares the public keys with the group. Separately, each player also creates a set of encrypted proofs (one for each of their own inputs) by encrypting the input along with its secret value and commitment key, using the communication public key of the validating player.
The public ephemeral keys, along with the encrypted proofs, are sent to all players so that blame can be accurately assigned and witnessed by all.
@@ -86,17 +115,17 @@ Message 1B (from server): ( `<“POOL READY”>......`
+Message 2 (from client): `...`
If any player fails to send a correctly formatted Message 2, then blame is assigned to that player and the round aborts.
-## Phase 3. Announce Ordering
+## Phase 3. Share Commitments and Keys
-Once the server has received message 2 from all players, it creates a random order for the players and sends message 3, announcing all payloads for all players, where each payload contains the information sent in Message 2.
+Once the server has received message 2 from all players, it sends message 3, announcing all payloads for all players, where each payload contains the information sent in Message 2.
Message 3 (from server): `...`
@@ -106,9 +135,11 @@ The Blame Pubkey is included in the payload, which helps to identify each player
Once message 3 has been received, each client should covertly announce their inputs (using TOR), and only the POOL_ID, sending 10 different instances (one for each input) of the following message:
-Message 4 (from client): ``
+Message 4 (from client): ``
-Note that only the pool session is required to post this information because it is covert; however only those who registered on the pool should have this unique id for the session. Also note these are the actual transaction inputs, not hashes.
+(The encrypted "A value" is described previously in the commitment scheme.)
+
+Note that only the pool session is required to post this information because it is covert; however only those who registered on the pool should have this unique id for the session.
The transaction will use the sighash type ALL|ANYONECANPAY, which reduces the interaction required between players. Specifically, this allows users to sign the inputs ahead of time without knowing ahead of time all the inputs that will be part of the transaction. This setup automatically handles the case of users not signing inputs.
@@ -116,53 +147,69 @@ Fee inputs are part of the transaction using the same sighash type and are inclu
## Phase 5. Sharing the Inputs
-Once all the signatures are collected, they can be rebroadcast to all players.
+Clients should announce all inputs to the server within a specified time window (for example 15 seconds), after which the server closes the announcement window, and proceeds to rebroadcast all the inputs to all players.
+
+Rebroadcasting all inputs together (rather than one at a time as each comes in) helps prevent timing timing attacks since only the server would know the times. The input announcements should have stagerred delays to mitigate timing attacks from the server itself. Also, this approach prevents Bob from maliciously re-submitting Alice's input with his own (incorrect) commitment "A" value. In the case where Alice resubmits her own input (or Bob resubmits Alice's transaction from a prior round with a now-bogus signature), the server should include all the inputs and let the blame phases handle the problem.
Message 5 (from server) `...`
+(Input here means serialized input plus the encrypted A value).
+
The client should check all signatures (this should be fast due to libsecp256k1) before broadcasting the transaction. Note that it is possible to have extra bogus inputs (invalid or missing signatures) but those can be just discarded. The transaction will still work if it has enough valid inputs, and should be executed if valid. Thus, the client code needs to loop through the set and determine if it can assemble the transaction.
-In addition, we should be explicity checking for n inputs of standard size rather than allowing the edge case of some less-than-standard-size inputs getting it and being offset by fees to make a transaction valid, because this will make it unclear who to blame.
+## Phase 6. Invoke Blame Process
-If the client finds any problems, we need to assign blame and continue to phase 6.
+If the client finds any problems ih phase 5, we need to invoke the blame portion of the protocol.
-## Phase 6. Send Proofs
+Message 6 (from server) ``
-Each player will create 10 “proofs”. Each proof shall consist of a serialized input that is encrypted by the appropriate player’s key, based on the sharding grid.
+This is just a junction that tells the server to continue with blame phases.
-Message 6 (from client): `...`
+## Phase 7. Announce Ordering
-## Phase 7. Share and Validate Proofs
+Once the server knows we're in the blame portion, it creates a random order for the players.
+
+Message 7 (from server): `...`
+
+The Blame Pubkey is included in the payload, which helps to identify each player, while the ordering of the message itself refelects the ordering of the players.
+
+## Phase 8. Send Proofs
+
+Each player will create 10 “proofs”. Each proof shall consist of the X ,A, and k values (described in the commitment scheme), where X is the signed serialized input, A is a secret number, and k is the public "commitment key". The entire proof is encrypted by the verifying player’s key, based on the sharding grid.
+
+Message 8 (from client): `...`
+
+## Phase 9. Share and Validate Proofs
Then the server sends to all:
-Message 7 (from server): `.........`
+Message 9 (from server): `.........`
-After reciving Message 7, the client will extract the proofs that it is responsible for, and checks each one. Also, very important: the client should also check for any ordering inconsistencies. If the client finds any issues with either the ordering or the transaction inputs, it assigns blame.
+After reciving Message 9, the client will extract the proofs that it is responsible for, and checks each one. If the client finds any issues with either the transaction inputs, it assigns blame.
-## Phase 8. Assign Blame
+## Phase 10. Assign Blame
First the client notifies the server:
-Message 8A (from client): ``
+Message 10A (from client): ``
Then the server notifies all clients with a similar message:
-Message 8B (from server) ``
+Message 10B (from server) ``
If the server receives several instance of Message 10A, it should only pick one input to be blamed (for example the lowest one by lexicographical order)
-## Phase 9. Refute Blame
+## Phase 11. Refute Blame
If Alice blames Bob, but Bob is innocent, Bob can refute the blame, while counter-blaming the accuser (Alice). He does that by sharing his ephemeral private key.
-Message 9A (from client): ``
+Message 11A (from client): ``
The server can then rebroadcast the same message
-Message 9B (from server): ``
+Message 11B (from server): ``
-## Phase 10: Process Blame
+## Phase 12: Process Blame
After determing who is to blame, the client and server should terminate the round.