Off-The-Record messaging encryption written in pure Java
Clone or download
Pull request Compare This branch is 1450 commits ahead, 3 commits behind redsolution:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

NOTE: This version of otr4j is in active development for the adoption of the OTRv4 specification that is being developed at this moment.

The repository for otr4j OTRv4 development is



Status: In active development
Current work should be considered at most prototype-quality and guaranteed insecure. The development follows the master branch of OTRv4, but may lag behind in areas that currently lack development focus.

Development stages:

Note: temporary dependency on see bottom of

  • ✔ Minimal working encryption (Interactive DAKE, message encryption/decryption, self-serving)
    a.k.a. "at least the bugs are symmetric in nature :-)"
  • ✔ Socialist Millionaire's Protocol for OTRv4.
  • ✔ Migrate OTRv4 DAKE state machine into OTRv4 Message state machine.
  • ⌛ Migrate Ed448-Goldilocks implementation to Bouncy Castle.
    • ✔ EdDSA long-term keypair
    • ECDH keypair
      Requires additions to the BouncyCastle API, as certain necessary operations are not currently supplied.
    • Verify if implementation is still concise and simple, given recent modifications to Point and Scalar internals.
  • Support for skipped messages, keeping track of skipped message keys.
  • OTRv4 maintenance tasks:
    • clean up old (abandoned) message fragments
    • clean up old sessions and reveal memorized MACs
  • Full implementation of "OTRv3-compatible" + "OTRv4 Interactive" use-case (including all FIXMEs)
  • ... (OTRv4 Non-interactive, ...)
  • Clean up remaining TODOs
  • Review the many logging statements and verify if log levels are reasonable.


  • General Off-the-record operation:
    • ☑ Maintain mixed OTRv2, OTRv3, OTRv4 sessions.
    • ☑ Persistent instance tags
    • ☑ 'Interactive DAKE' implemented as Message states i.s.o. AKE states.
    • ☐ OTRv4 extension to OTR error messages
    • ☐ OTRv4 operating modes (OTRv3-compatible, OTRv4-standalone, OTRv4-interactive-only).
    • ☐ Queueing of messages while not in ENCRYPTED_MESSAGES state.
    • ☐ Publishing of generated ClientProfile payloads through callback to OtrEngineHost
  • Cryptographic primitives:
    • Edd448-Goldilocks elliptic curve (temporary solution)
      • ☑ Temporary working solution
      • ⌛ Migrate to BouncyCastle 1.60.
    • 3072-bit Diffie-Hellman parameters
      • ☑ Temporary working solution
      • ☐ Verify if current solution is acceptable, otherwise migrate to JCA/BC
    • ☑ XSalsa20 symmetric cipher
    • ☑ SHAKE-256
    • ☑ Ring signatures
  • Key Exchange:
    • ☑ Interactive DAKE
    • ☐ Non-interactive DAKE
  • Key Management:
    • Double Ratchet:
      • ☑ Generate next message keys (in-order messages)
      • ☑ Generate future message keys (skip over missing messages)
      • ☐ Store and recall skipped message keys (out-of-order messages)
    • Shared secrets management:
      • ☑ Ephemeral DH with 3072-bit parameters
      • ☑ Ephemeral ECDH based on Ed448-Goldilocks
      • ☑ Key rotation
    • ☑ Calculate Encryption, MAC and Extra Symmetric Key keys
    • ☑ Revealing used MAC keys
    • ☐ Periodic clean-up of "old" skipped message keys
    • ☐ Session expiration (and revealing remaining MAC keys)
  • Message encryption/decryption:
    • ☑ In-order messages
    • ☑ In-order messages with some messages missing
    • ☐ Out-of-order messages
  • Fragmentation and re-assembly:
    • ☑ Fragmentation
    • ☑ Re-assembling fragmented messages
  • Socialist Millionaire's Protocol:
    • ☑ OTRv2/OTRv3
    • ☑ OTRv4
  • Client and PreKey Profiles:
    • ☑ Client Profile support
    • ☐ PreKey profile support
  • Extra Symmetric Key support:
    • ☑ OTRv3
    • OTRv4
      • ☐ Base "Extra Symmetric Key" available for use.
      • ☐ Derived keys according to OTRv4 prescribed derivation
  • API support:
    • ☐ verify if API still fully suitable for clients to adopt.
    • ☐ ability to import/export EdDSA key pairs, such that ClientProfiles can be persisted/restored.
    • OtrKeyManager was removed. Evaluate whether this is a problem for adopters. (I prefer to leave it out or put it in its own repository.)
  • Misc
    • ☑ Set flag IGNORE_UNREADABLE also for OTRv3 DISCONNECT and all SMP messages.
      Although not explicitly document that this is necessary, it should not break any existing applications. This makes implementations of OTRv3 and OTRv4 more similar and promotes better behavior in general, being: the other party is not needlessly warned for (lost) messages that do not contain valuable content, i.e. they are part of the OTR process, but do not contain user content themselves.
    • ☐ Ability to define own, customized-per-network phi (shared session state) implementer addition for the t value calculation.
      Under consideration as part of the OTRv4 client implementation recommendations.


  • Constant-time implementations:
    • ☑ MAC key comparison
    • ☑ Point and Scalar equality
    • ☐ Scalar value comparison
    • ☐ Ring signatures implemented fully constant-time.
  • Cleaning up data:
    • ☑ Clearing byte-arrays containing sensitive material after use.
    • ☐ Clean up remaining message keys instances when transitioning away from encrypted message states.
    • ☐ Investigate effectiveness of clearing byte-arrays right before potential GC. (Maybe they are optimized away by JVM?)
  • Verify OTR-protocol obligations of other party:
    • ☑ Verify that revealed MAC keys are present when expected. (I.e. is list of revealed MAC keys larger than 0 bytes?)
  • In-memory representation of points and scalar values as byte-arrays:
    Note that we specifically refer to how the data is represented in memory. Operations require temporary conversion back and forth into an intermediate type.
    • ☑ Points kept as byte-arrays.
    • ☑ Scalar values kept as byte-arrays.
  • Mathematical operations act on byte-array representations directly:
    See also BearSSL big integer operations
    • ☐ Scalar arithmetic operations
    • ☐ Point arithmetic operations
  • Robustness
    • ☑ otr4j does not handle Error-type exceptions.
      If critical situations occur, for instance OutOfMemoryError, then all bets are off.
    • ☑ otr4j protects itself against RuntimeExceptions caused by callbacks into the host application. Any occurrence of a RuntimeException is considered a bug on the host application side, and is caught and logged by otr4j.
  • Stability
    • ☐ Profile library in execution.
    • ☐ Measure memory usage changes under long-term use/heavy load.
  • OTRv3 - catching up:
    • ☐ In-memory representation for OTRv3.
    • ☐ Arithmetical operations on byte-arrays for OTRv2 and/or OTRv3 logic.


  • ☑ Encapsulate cryptographic material such that design facilitates appropriate use and maintenance.
  • ☑ States, such as Message states, isolated as to prevent mistakes in mixing up variables and state management for different states.
  • ☑ Strategically placed assertions to discover mistakes such as uninitialized/cleared byte-arrays.
  • Tool support:
    • ☑ JSR-305 annotations for static analysis
    • ☑ Introduce compiler warnings failure at build-time
    • ☑ Introduce pmd analysis at build-time.
    • ☑ Introduce SpotBugs analysis at build-time
    • ☑ Introduce checkstyle at build-time to guard formatting/style
    • ☑ Introduce checkstyle ImportControl module to guard the design structure
    • ☐ Introduce Animal sniffer build plug-in to verify that we do not break backwards-compatibility, once released.
    • ☐ spotbugs-annotations to support managing clean-up of cryptographic key material
    • ☐ Experiment with features of Checker Framework.
  • ⌛ Issue: some tests fail on a rare occasion due to the assert checks that are embedded in the code. These tests should be updated to assume successful execution if input would trigger the assertion.
  • ☐ Significant amount of unit tests to accompany the library. (Currently: 1100+)
  • ☐ Interoperability testing with other OTRv4 implementations.

Architectural considerations

Architectural constraints that are taken into consideration for the design.

  1. Correctness of protocol implementation.
  2. Encapsulation of cryptographic material to prevent mistakes, misuse, excessive exposure.
  3. Design that prevents or makes obvious programming errors.
  4. Simplicity: restricted implementation with only as much complexity and abstraction as needed.


otr4j is an implementation of the OTR (Off The Record) protocol in Java. Its development started during the GSoC '09 where the goal was to add support for OTR in jitsi. It currently supports OTRv2 and OTRv3. Additionally, there is support for fragmenting outgoing messages.

Support for OTRv1 is removed, as is recommended by the OTR team.

Using otr4j

Note: otr4j with OTRv4 support is not backwards-compatible with older releases. Although the API has not changed significantly, some restructuring has been performed and the interfaces extended to be able to support client requirements of OTRv4.

TODO: describe adoption information

Contributing / Help needed

Please open an issue to discuss contributions early. As OTRv4 is still in draft and work on otr4j is active, things might change quickly.

  • Helping with implementation work:
    • see the Functional/Operational/Developmental action points above.
    • look for FIXME/TODO in the code. (there are plenty to find)
  • Peer-reviewing (for correctness, security and improvements in general)
  • Integration into chat clients
    • adoption
    • feedback on the API from the usage perspective

Build support and code style

The code is built using maven. The build configuration fails on compiler warnings and performs several types of static analysis. Checkstyle verifies the coding style and the same checkstyle configuration file can be used to configure your IDE. Although this does not catch all potential issues, I hope it will serve to provide early feedback for code contributions.

In addition to syntactic correctness checking, we enforce javadoc for anything that is part of the public API: public and protected classes methods and fields. The rationale for this is that the user of otr4j should expect reasonable information on the logic its able to call. Although some javadoc may still be limited in usefulness, we should aim to use it to clarify everything the user should know in using otr4j.

Setting up your IDE: IntelliJ IDEA

  1. Load the otr4j pom.xml file as a maven module.
  2. Load codecheck/checkstyle.xml as the code style in IntelliJ (you will need to have the Checkstyle plug-in installed)
  3. ... (I'm not sure if anything else is needed, but I'll update when I find out.)


  • otr4j supports message lengths up to 2^31.
    Message sizes in OTR are defined as 4-byte unsigned. Due to Java's signed integer types, this implementation currently uses a signed integer. Therefore, the highest bit of the message length is interpreted as sign bit. Lengths over 2^31 are unsupported.
  • Message are not queued up.
    Messages will be rejected while the connection is being established. Once the secure connection is established, message can again be sent.

Dependency on joldilocks

Due to initial lack of support for Ed448-Goldilocks, a very basic, limited Java library was written to support Ed448-Goldilocks. This library is by no means production-ready, does not provide any of the operational requirements necessary for security purposes and is not even guaranteed to be functionally correct. It did however enable further implementation of otr4j. We aim to completely migrate away from joldilocks for otr4j. At most, we may keep it as a second opinion in unit testing code. joldilocks needs Java 9 to compile so this dependency also raises our minimum required Java version for otr4j.