diff --git a/README.md b/README.md
index 08bfaed..361d3c3 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
# MWixnet
-MW CoinSwap Server
+This is an implementation of @tromp's [CoinSwap Proposal](https://forum.grin.mw/t/mimblewimble-coinswap-proposal/8322) with some slight modifications.
-## APIs
-### swap
-The server configured to be the entry server (node 1) exposes a JSON-RPC `swap` API for use by GRIN wallets.
+A set of n CoinSwap servers (nodei with i=1...n) are agreed upon in advance. They each have a known public key.
+
+### SWAP API
+The first CoinSwap server (n1) provides the `swap` API, publicly available for use by GRIN wallets.
**jsonrpc:** `2.0`
**method:** `swap`
@@ -18,4 +19,28 @@ The server configured to be the entry server (node 1) exposes a JSON-RPC `swap`
"pubkey": "020dd38a220280f14515f6901a3a366cb7b87630814e4b68b3189a32df964961e5"
}
}]
-```
\ No newline at end of file
+```
+
+### Data Provisioning
+#### Inputs
+* Cin: UTXO commitment to swap
+* xin: Blinding factor of Cin
+* K1...n: The public keys of all n servers
+
+#### Procedure
+
+ - Choose random xi for each node ni and create a Payload (Pi) for each containing xi
+ - Build a rangeproof for Cn=Cin+(Σx1...n)*G and include it in payload Pn
+ - Choose random initial ephemeral keypair (r1, R1)
+ - Derive remaining ephemeral keypairs such that ri+1=ri*Sha256(Ri||si) where si=ECDH(Ri, Ki)
+ - For each node ni, use ChaCha20 stream cipher with key=HmacSha256("MWIXNET"||si) and nonce "NONCE1234567" to encrypt payloads Pi...n
+
+
+### Input Validation
+
+* Node n1 verifies that Cin is in the current UTXO set
+* Node n1 verifies the commitment signature is valid for Cin, proving ownership of the input
+
+----
+
+`Output derivation`, `Output validation`, `Kernel derivation`, and `Aggregation` steps remain unchanged from the [original design](https://forum.grin.mw/t/mimblewimble-coinswap-proposal/8322)
\ No newline at end of file
diff --git a/src/onion.rs b/src/onion.rs
index 8c603ed..8c49e85 100644
--- a/src/onion.rs
+++ b/src/onion.rs
@@ -93,7 +93,7 @@ fn calc_blinding_factor(shared_secret: &SharedSecret, ephemeral_pubkey: &PublicK
}
fn new_stream_cipher(shared_secret: &SharedSecret) -> Result {
- let mut mu_hmac = HmacSha256::new_from_slice(b"PAYLOAD")?;
+ let mut mu_hmac = HmacSha256::new_from_slice(b"MWIXNET")?;
mu_hmac.update(&shared_secret[0..32]);
let mukey = mu_hmac.finalize().into_bytes();
diff --git a/src/server.rs b/src/server.rs
index d5a6be4..8e402e6 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -163,6 +163,8 @@ mod tests {
Ok(response_str)
}
+ /// Single hop to demonstrate request validation and onion unwrapping.
+ /// UTXO creation and bulletproof generation reserved for milestones 2 & 3.
#[test]
fn swap_lifecycle() -> Result<(), Box> {
let server_key = secp::insecure_rand_secret()?;