Skip to content

Commit

Permalink
describing privacy leak
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jul 5, 2024
1 parent 357dfb5 commit 581f525
Showing 1 changed file with 19 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ impl OwnedNote for TokenNote {
* deduce what n is. This is the discrete log problem.
*
* However we can still perform addition/subtraction on points! That is why we generate those two points, which are:
* incomplete_fee_payer_point := (fee_payer_npk + randomness) * G
* incomplete_user_point := (user_npk + funded_amount + randomness) * G
* incomplete_fee_payer_point := (fee_payer_npk + fee_payer_randomness) * G
* incomplete_user_point := (user_npk + funded_amount + user_randomness) * G
*
* where `funded_amount` is the total amount in tokens that the sponsored user initially supplied, from which the transaction fee will be subtracted.
*
Expand All @@ -168,19 +168,31 @@ impl OwnedNote for TokenNote {
* Then we arrive at the final points via addition/subtraction of that transaction fee point:
*
* fee_payer_point := incomplete_fee_payer_point + fee_point
* = (fee_payer_npk + randomness) * G + transaction_fee * G
* = (fee_payer_npk + randomness + transaction_fee) * G
* = (fee_payer_npk + fee_payer_randomness) * G + transaction_fee * G
* = (fee_payer_npk + fee_payer_randomness + transaction_fee) * G
*
* user_point := incomplete_user_point - fee_point
* = (user_npk + funded_amount + randomness) * G - transaction_fee * G
* = (user_npk + randomness + (funded_amount - transaction_fee)) * G
* = (user_npk + funded_amount + user_randomness) * G - transaction_fee * G
* = (user_npk + user_randomness + (funded_amount - transaction_fee)) * G
*
* When we return the x-coordinate of those points, it identically matches the note_content_hash of (and therefore *is*) notes like:
* {
* amount: (funded_amount - transaction_fee),
* npk_m_hash: user_npk,
* randomness: randomness
* randomness: user_randomness
* }
*
* Why do we need different randomness for the user and the fee payer notes?
* --> This is because if the randomness values were the same we could fingerprint the user by doing the following:
* 1) randomness_influence = incomplete_fee_payer_point - G * fee_payer_npk =
* = (fee_payer_npk + randomness) * G - G * fee_payer_npk = randomness * G
* 2) user_fingerprint = incomplete_user_point - G * funded_amount - randomness_influence =
* = (user_npk + funded_amount + randomness) * G - funded_amount * G - randomness * G =
* = user_npk * G
* 3) Then the second time the user would use this fee paying contract we would recover the same fingerprint and
* link that the 2 transactions were made by the same user. Given that it's expected that only a limited set
* of fee paying contracts will be used and they will be known searching for fingerprints by trying different
* fee payer npk values of these known contracts is a feasible attack.
*/
impl PrivatelyRefundable for TokenNote {
fn generate_refund_points(fee_payer_npk_m_hash: Field, user_npk_m_hash: Field, funded_amount: Field, user_randomness: Field, fee_payer_randomness: Field) -> (EmbeddedCurvePoint, EmbeddedCurvePoint) {
Expand Down

0 comments on commit 581f525

Please sign in to comment.