java.lang.Object
net.i2p.crypto.SessionKeyManager
net.i2p.router.crypto.ratchet.MuxedSKM

public class MuxedSKMextends SessionKeyManager
Multiplexed session key manager combining ElGamal and ECIES key management.
  • Field Details

    • _elg

      private final TransientSessionKeyManager _elg
      The ElGamal session keys.
    • _ec

      private final RatchetSKM _ec
      The ratcheted ECIES session keys.
    • _elgCounter

      private final AtomicInteger _elgCounter
      Counts the ElGamal keys handed out.
    • _ecCounter

      private final AtomicInteger _ecCounter
      Counts the ratcheted keys handed out.
    • ELG_SLOW_FACTOR

      static final int ELG_SLOW_FACTOR
      How much slower the ElGamal slow decrypt is than the ratchet one, so its success count is divided by this much before the two are compared.
      See Also:
    • RESTART_COUNTERS

      static final int RESTART_COUNTERS
      Size of the sampling window. Once both counters are individually meaningful and their sum passes this, the window rolls over so the ordering tracks recent traffic instead of the whole session.
      See Also:
  • Constructor Details

    • MuxedSKM

      public MuxedSKM(TransientSessionKeyManager elg, RatchetSKM ec)
      Combines ElGamal and ECIES SKMs with adaptive decrypt ordering.
      Parameters:
      elg - the ElGamal key manager handling legacy transient sessions
      ec - the ratchet key manager handling ECIES-X25519 sessions
  • Method Details

    • getElgSKM

      public TransientSessionKeyManager getElgSKM()
      Return the ElGamal key manager that handles legacy transient sessions.
      Returns:
      the ElGamal session key manager this instance multiplexes
    • getECSKM

      public RatchetSKM getECSKM()
      Return the ratchet key manager that handles ECIES-X25519 sessions.
      Returns:
      the ratchet session key manager this instance multiplexes
    • preferRatchet

      boolean preferRatchet()
      Should we try the Ratchet slow decrypt before ElG slow decrypt? Adaptive test based on previous mix of traffic for this SKM, as reported by reportDecryptResult().
      Returns:
      true if the ratchet slow decrypt should be tried before the ElGamal one
    • needsRestart

      static boolean needsRestart(int ec, int elg)
      Whether the sampling window is full and both counters should start over, so the ordering tracks recent traffic rather than the whole session. Both counters have to be individually meaningful, or a one-sided flood would reset a window that still says something about the other path.
      Parameters:
      ec - successful ratchet decrypts in the current window
      elg - successful ElGamal decrypts in the current window
      Returns:
      true if the window has run its course
    • preferRatchet

      static boolean preferRatchet(int ec, int elg)
      The ordering the current window favours, with the ElGamal count discounted because the ratchet slow decrypt is the cheaper of the two to try first.
      Parameters:
      ec - successful ratchet decrypts in the current window
      elg - successful ElGamal decrypts in the current window
      Returns:
      true if the ratchet slow decrypt should go first
    • rollOver

      static boolean rollOver(AtomicInteger counter, int expected)
      Reset one counter to start a fresh window, only if nothing was recorded since the value the decision was taken on. A plain set(0) would discard any success logged between that read and the reset, which is how the counters used to lose counts under concurrent decrypts.
      Parameters:
      counter - the counter to roll over
      expected - the value read when the decision was taken
      Returns:
      true if the counter was reset, false if it moved in the meantime
    • reportDecryptResult

      void reportDecryptResult(boolean isRatchet, boolean success)
      Report the result of a slow decrypt attempt.
      Parameters:
      isRatchet - true for EC, false for ElG
      success - true for successful decrypt
    • getCurrentKey

      public SessionKey getCurrentKey(PublicKey target)
      ElG only.
      Overrides:
      getCurrentKey in class SessionKeyManager
      Parameters:
      target - the destination whose current session key is wanted
      Returns:
      the current key
    • getCurrentOrNewKey

      public SessionKey getCurrentOrNewKey(PublicKey target)
      ElG only.
      Overrides:
      getCurrentOrNewKey in class SessionKeyManager
      Parameters:
      target - the destination to start or continue a session with
      Returns:
      the current or new key
    • createSession

      public void createSession(PublicKey target, SessionKey key)
      ElG only.
      Overrides:
      createSession in class SessionKeyManager
      Parameters:
      target - the destination the session is established with
      key - the session key to associate, whose expiry metrics start at this call
    • createSession

      public SessionKey createSession(PublicKey target)
      ElG only.
      Overrides:
      createSession in class SessionKeyManager
      Parameters:
      target - the destination to establish a freshly generated session with
      Returns:
      the session key
    • consumeNextAvailableTag

      public SessionTag consumeNextAvailableTag(PublicKey target, SessionKey key)
      ElG only.
      Overrides:
      consumeNextAvailableTag in class SessionKeyManager
      Parameters:
      target - the destination the tag was sent to
      key - the session key whose use the tag identifies
      Returns:
      the next available tag, or null
    • consumeNextAvailableTag

      public RatchetEntry consumeNextAvailableTag(PublicKey target)
      EC only.
      Parameters:
      target - the destination to take an available session tag from
      Returns:
      the oldest unconsumed tag, or null if the target is not an ECIES-X25519 key
    • getTagsToSend

      public int getTagsToSend()
      Not used; tag management is handled by the ratchet protocol.
      Overrides:
      getTagsToSend in class SessionKeyManager
      Returns:
      0, tag management is handled by ratchet protocol
    • getLowThreshold

      public int getLowThreshold()
      Not used; thresholds are not used for ratchet sessions.
      Overrides:
      getLowThreshold in class SessionKeyManager
      Returns:
      0, threshold not used for ratchet sessions
    • shouldSendTags

      public boolean shouldSendTags(PublicKey target, SessionKey key)
      ElG only.
      Overrides:
      shouldSendTags in class SessionKeyManager
      Parameters:
      target - the destination whose tags are being considered
      key - the session key
      Returns:
      whether send tags
    • shouldSendTags

      public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold)
      ElG only.
      Overrides:
      shouldSendTags in class SessionKeyManager
      Parameters:
      target - the destination whose tags are being considered
      key - the session key
      lowThreshold - the low threshold
      Returns:
      whether send tags
    • getAvailableTags

      public int getAvailableTags(PublicKey target, SessionKey key)
      Delegates to the appropriate key manager by encryption type.
      Overrides:
      getAvailableTags in class SessionKeyManager
      Parameters:
      target - the destination the tags were sent to
      key - the session key those tags were issued under
      Returns:
      the available tags
    • getAvailableTimeLeft

      public long getAvailableTimeLeft(PublicKey target, SessionKey key)
      Delegates to the appropriate key manager by encryption type.
      Overrides:
      getAvailableTimeLeft in class SessionKeyManager
      Parameters:
      target - the destination the tags were sent to
      key - the session key those tags were issued under
      Returns:
      the available time left
    • tagsDelivered

      public TagSetHandle tagsDelivered(PublicKey target, SessionKey key, Set<SessionTag> sessionTags)
      ElG only.
      Overrides:
      tagsDelivered in class SessionKeyManager
      Parameters:
      target - the destination that acknowledged the tags
      key - the session key the acknowledged tags were issued under
      sessionTags - modifiable; NOT copied
      Returns:
      the tag set handle
    • tagsReceived

      public void tagsReceived(SessionKey key, Set<SessionTag> sessionTags)
      ElG only.
      Overrides:
      tagsReceived in class SessionKeyManager
      Parameters:
      key - the session key the tags were received for
      sessionTags - modifiable; NOT copied
    • tagsReceived

      public void tagsReceived(SessionKey key, Set<SessionTag> sessionTags, long expire)
      ElG only.
      Overrides:
      tagsReceived in class SessionKeyManager
      Parameters:
      key - the session key the tags were received for
      sessionTags - modifiable; NOT copied
      expire - time from now
    • tagsReceived

      public void tagsReceived(SessionKey key, RatchetSessionTag tag, long expire)
      EC only One time session.
      Parameters:
      key - the session the tag was received on
      tag - the one-time tag received
      expire - time from now
    • consumeTag

      public SessionKey consumeTag(SessionTag tag)
      Tries ElGamal tag lookup first, falls back to ratchet lookup.
      Overrides:
      consumeTag in class SessionKeyManager
      Parameters:
      tag - the session tag whose delivered key is consumed
      Returns:
      the session key, or null
    • shutdown

      public void shutdown()
      Shuts down both ElGamal and ECIES key managers.
      Overrides:
      shutdown in class SessionKeyManager
    • renderStatusHTML

      public void renderStatusHTML(Writer out) throws IOException
      Renders debug status for both key managers.
      Overrides:
      renderStatusHTML in class SessionKeyManager
      Parameters:
      out - the writer to render to
      Throws:
      IOException - if an I/O error occurs
    • getDebugStats

      public long[] getDebugStats()
      Sums the debug stats of both key managers, null if neither tracks them.
      Overrides:
      getDebugStats in class SessionKeyManager
      Returns:
      the stats, or null
    • failTags

      public void failTags(PublicKey target, SessionKey key, TagSetHandle ts)
      ElG only.
      Overrides:
      failTags in class SessionKeyManager
      Parameters:
      target - the destination whose tags are being considered
      key - the session key
      ts - the tag set handle
    • tagsAcked

      public void tagsAcked(PublicKey target, SessionKey key, TagSetHandle ts)
      ElG only.
      Overrides:
      tagsAcked in class SessionKeyManager
      Parameters:
      target - the destination whose tags are being considered
      key - the session key
      ts - the tag set handle