java.lang.Object
net.i2p.data.RoutingKeyGenerator
net.i2p.data.router.RouterKeyGenerator

public class RouterKeyGeneratorextends RoutingKeyGenerator
Generates routing keys from hashes using date-based modification to prevent Sybil attacks. Transforms input hashes by appending current GMT date (yyyyMMdd format) and computing SHA256. The modification data changes daily at midnight GMT to randomize routing keys consistently.

The transformation takes the original hash, appends the bytes of the current mod data, then returns the SHA256 of that concatenation. This makes Sybil attacks much harder as she needs to essentially take over the whole keyspace.

Note: generateDateBasedModData() should be called after midnight GMT once per day to generate the correct routing keys.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final I2PAppContext
    The app context.
    private byte[]
    The modulus data of the current key.
    private final ThreadLocal<DateFormat>
    The per-thread date format.
    private long
    When the keys last changed.
    private final Log
    The log for the key generator.
    private long
    When the keys change next.
    private byte[]
    The modulus data of the next key.
    private static final String
    Date format of the key modulus.
    private static final java.time.ZoneId
    The time zone of the key dates.
    private static final int
    Length of the formatted key date.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructor that initializes GMT date formatter and generates current routing key modifier data.
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    Update the current modifier data with some bytes derived from the current date (yyyyMMdd in GMT).
    private byte[]
    generateModDataFromCal(java.time.LocalDate day)
    Generate mod data from the given GMT day.
    private static Hash
    getKey(Hash origKey, byte[] modData)
    Generate a modified (yet consistent) hash from the origKey by generating the SHA256 of the targetKey with the specified modData appended to it.
    long
    Time the routing key modifier data was last regenerated.
    byte[]
    The current (today's) mod data.
    byte[]
    Tomorrow's mod data.
    Routing key using tomorrow's modData, not today's.
    private java.time.LocalDate
    Previous midnight (GMT) for the time given.
    Generate a modified (yet consistent) hash from the origKey by generating the SHA256 of the targetKey with the current modData appended to it
    getRoutingKey(Hash origKey, long time)
    Routing key for the specified date, not today's.
    long
    How long until midnight (ms).
    static void
    main(String[] args)
    Command-line entry point: converts routing keys to their -offset and +offset day forms, reading a hash, hostname or destination per argument.

    Methods inherited from class RoutingKeyGenerator

    getInstance
    Modifier and Type
    Method
    Description
    Generator for this context.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • _log

      private final Log _log
      The log for the key generator.
    • _context

      private final I2PAppContext _context
      The app context.
    • _currentModData

      private volatile byte[] _currentModData
      The modulus data of the current key.
    • _nextModData

      private volatile byte[] _nextModData
      The modulus data of the next key.
    • _nextMidnight

      private volatile long _nextMidnight
      When the keys change next.
    • _lastChanged

      private volatile long _lastChanged
      When the keys last changed.
    • GMT

      private static final java.time.ZoneId GMT
      The time zone of the key dates.
    • FORMAT

      private static final String FORMAT
      Date format of the key modulus.
      See Also:
    • LENGTH

      private static final int LENGTH
      Length of the formatted key date.
    • _fmt

      private final ThreadLocal<DateFormat> _fmt
      The per-thread date format.
  • Constructor Details

    • RouterKeyGenerator

      public RouterKeyGenerator(I2PAppContext context)
      Constructor that initializes GMT date formatter and generates current routing key modifier data.
      Parameters:
      context - the application context supplying the log and clock
  • Method Details

    • getModData

      public byte[] getModData()
      The current (today's) mod data. Warning - not a copy, do not corrupt.
      Returns:
      non-null, 8 bytes
    • getNextModData

      public byte[] getNextModData()
      Tomorrow's mod data. Warning - not a copy, do not corrupt. For debugging use only.
      Returns:
      non-null, 8 bytes
    • getLastChanged

      public long getLastChanged()
      Time the routing key modifier data was last regenerated.
      Specified by:
      getLastChanged in class RoutingKeyGenerator
      Returns:
      the last changed
    • getTimeTillMidnight

      public long getTimeTillMidnight()
      How long until midnight (ms).
      Returns:
      could be slightly negative
    • getPreviousMidnight

      private java.time.LocalDate getPreviousMidnight(long now)
      Previous midnight (GMT) for the time given. Caller must synch.
      Parameters:
      now - the time in milliseconds since the epoch
      Returns:
      the previous midnight
    • generateModDataFromCal

      private byte[] generateModDataFromCal(java.time.LocalDate day)
      Generate mod data from the given GMT day. Caller must synch.
      Parameters:
      day - the GMT day to derive the modifier from
      Returns:
      the modifier bytes, the date as ASCII yyyyMMdd
    • generateDateBasedModData

      public boolean generateDateBasedModData()
      Update the current modifier data with some bytes derived from the current date (yyyyMMdd in GMT).
      Returns:
      true if changed
    • getRoutingKey

      public Hash getRoutingKey(Hash origKey)
      Generate a modified (yet consistent) hash from the origKey by generating the SHA256 of the targetKey with the current modData appended to it

      This makes Sybil's job a lot harder, as she needs to essentially take over the whole keyspace.

      Specified by:
      getRoutingKey in class RoutingKeyGenerator
      Parameters:
      origKey - non-null
      Returns:
      the routing key
      Throws:
      IllegalArgumentException - if origKey is null
    • getNextRoutingKey

      public Hash getNextRoutingKey(Hash origKey)
      Routing key using tomorrow's modData, not today's.
      Parameters:
      origKey - the key to be modified into a routing key
      Returns:
      the next routing key
    • getRoutingKey

      public Hash getRoutingKey(Hash origKey, long time)
      Routing key for the specified date, not today's.
      Parameters:
      origKey - the key to be modified into a routing key
      time - epoch milliseconds naming the day to derive the key for
      Returns:
      the routing key
    • getKey

      private static Hash getKey(Hash origKey, byte[] modData)
      Generate a modified (yet consistent) hash from the origKey by generating the SHA256 of the targetKey with the specified modData appended to it.
      Parameters:
      origKey - the original routing key to modify
      modData - the modifier bytes appended before hashing, LENGTH bytes
      Returns:
      the modified hash, computed over origKey followed by the modifier
      Throws:
      IllegalArgumentException - if origKey is null
    • main

      public static void main(String[] args)
      Command-line entry point: converts routing keys to their -offset and +offset day forms, reading a hash, hostname or destination per argument.
      Parameters:
      args - the routing keys to convert, optionally preceded by an offset in days