Skip to content

Antiflood Tokens #246

@sanity

Description

@sanity

Overview

Antiflood tokens increase the cost of abusive behavior like spam and denial of service attacks within Locutus.

To create antiflood tokens, the user must give up something of value to obtain a token generator. A public/private keypair that meets some cryptographically provable criteria - such as a signed certificate of donation to Freenet. This generator releases new tokens at regular time intervals that depend on the token tier. The lowest tier, 30-second tokens, are released every 30 seconds. Higher tiers release less frequently: 1 minute, 10 minutes, 30 minutes, 1 hour, 2 hours, 4 hours, 12 hours, or 1 day.

Other systems can require that a token of some minimum tier be issued as a condition of some action like adding a message to an inbox. In the event of bad behavior by the generator owner, the recipient can create a complaint, which will be visible to anyone interacting with the generator.
Initially, this will be a centralized solution. The user must make a cryptographically blinded donation to Freenet to obtain a token generator. In the future, we will provide a decentralized on-network way to create new token generators. We're still at the ideation stage with that, but it will not be based on proof-of-work.

Token Generator

Creating a Token Generator

  1. The user creates generator_key_pair and blinds generatorPublicKey to get blind(generator_public_key) before sending it to https://freenet.org/donations
  2. Freenet's donation system selected a donation_key_pair based on the donation amount
  3. Donation system signs blind(generator_public_key) with donation_private_key to produce signed(donation_public_key, blind(generator_public_key))
  4. signed(donation_public_key, blind(generator_public_key)) is sent back to the user
  5. The user unblinds it to obtain signed(donation_public_key, generator_public_key), this is the initialization certificate and can be used to prove that the generator has been initialized with a donation

Token Generator Contract

The Token Generator Contract keeps track of tokens that have been assigned

Contract State

The token contract state is a set of token assignments organized by tier (frequency of token release), and then the time the token is released.

The contract verifies that the release times for a tier match the tier. For example, a 15:30 UTC release time isn't permitted for hour_1 tier, but 15:00 UTC is permitted.

Note: Conflicting assignments for the same time slot are not permitted and indicate that the generator is broken or malicious.

struct TokenContractParameters {
    generator_public_key : PublicKey,
    current_date_utc : Date,
}

struct TokenContractState {
   /// A list of issued tokens
   tokens_by_tier : HashMap<Tier, HashMap<DateTime, TokenAssignment>>,
}

struct TokenAssignment {
   tier : Tier,

   issue_time : DateTime,

   /// The assignment, the recipient decides whether this assignment
   /// is valid based on this field. This will often be a PublicKey.
   assigned_to: [u8],

   /// `(tier, issue_time, assigned_to)` must be signed 
   /// by `generator_public_key`
   signature: Signature,
}

enum Tier {
  minute_1, minute_10, minute_30, hour_1, 
  hour_2, hour_4, hour_12, day_1
}

Requirements

For the TokenAssignment to be valid only one TokenAssignment must exist for a given issue_time and tier

Token assignment and verification

For example, consider a contract representing a message inbox, where senders must spend a token to add a message to the inbox. The inbox decides what tier of token is required, this should be made known to senders.

struct InboxContractState {
  messages : Vec<InboxMessage>,
}

struct InboxMessage {
  message: String,

  assignment: TokenAssignment,

  /// `(message, assignment)` signed by generator's public key
  signature: Signature,
}
  1. The sender creates an InboxMessage including a valid TokenAssignment
  2. The sender attempts to modify the inbox to add the new message
  3. The InboxContract verifies that the tier is high enough and the assignment signature matches
  4. The InboxContract verifies that the assignment is valid by checking the relevant TokenContractState, ignoring it if it isn't

Complaints

Generator Complaint Contract

A contract that maintains a list of valid complaints for a generator - complaints can be created by a token recepient. Tokens from a generator with an excessive number of complaints may be rejected. The recepient is responsible for adding complaints to this contract.

   struct GeneratorComplaintsParameters {
       generator_public_key: PublicKey,
   }
   
   struct GeneratorComplaintsState { 
      complaints : HashMap<DateTime, HashMap<Tier, Complaint>>,
   }
   
   struct Complaint {
    /// A valid assignment is required for a complaint
    assignment: TokenAssignment,

    /// Reason for the complaint
    reason: String,

    /// `(assignment, reason)` must be signed by the token
    /// recipient to be a valid complaint
    recepient_signature : Signature,
}

Enhancements

  • We should randomize the daily changeover time for current_date_utc based on the generator_public_key to avoid a synchronized network change at 0:00 UTC.

  • assigned_tofield inTokenAssignmentis redundant in anInboxMessagebecause we already know theassigned_to here. We should avoid wasting these bytes.

  • Token recipients can specify a maximum token age, preventing passive accumulation of a large number of tokens over time

  • A duplicate token assignment is evidence of malicious behavior by the generator owner and will disable the token generator

Conclusion

We've now described a mechanism for generating scarce tokens that can be spent to gain access to potentially floodable resources like a message inbox.

Metadata

Metadata

Assignees

Labels

E-hardExperience needed to fix/implement: Hard / a lotP-mediumMedium priorityT-featureType: New functionality request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions