java.lang.Object
com.southernstorm.noise.crypto.x25519.Curve25519

public final class Curve25519extends Object
Implementation of the Curve25519 elliptic curve algorithm. This implementation is based on that from arduinolibs: https://github.com/rweather/arduinolibs Differences in this version are due to using 26-bit limbs for the representation instead of the 8/16/32-bit limbs in the original. References: http://cr.yp.to/ecdh.html, RFC 7748
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final ThreadLocal<Curve25519>
    Per-thread scratch state for eval(byte[], int, byte[], byte[]).
    private final int[]
    Sum x_2 plus z_2, a ladder intermediate.
    private final int[]
    A squared, a ladder intermediate.
    private final int[]
    Difference x_2 minus z_2, a ladder intermediate.
    private final int[]
    B squared, a ladder intermediate.
    private final int[]
    Sum x_3 plus z_3, a ladder intermediate.
    private final int[]
    C times B, a ladder intermediate.
    private final int[]
    Difference x_3 minus z_3, a ladder intermediate.
    private final int[]
    D times A, a ladder intermediate.
    private final int[]
    Difference AA minus BB, a ladder intermediate.
    private static final int
    Limbs of a field element, ten 26 bit words modulo 2^255 - 19.
    private static final int
    Limbs holding a doubled width value.
    private final long[]
    Wide temporary for the field arithmetic.
    private final int[]
    Narrow temporary for the field arithmetic.
    private final int[]
    The x coordinate of the input point.
    private final int[]
    The x coordinate of the accumulator point.
    private final int[]
    The x coordinate of the difference point.
    private final int[]
    The z coordinate of the accumulator point.
    private final int[]
    The z coordinate of the difference point.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Constructs the temporary state holder for Curve25519 evaluation.
  • Method Summary

    Modifier and Type
    Method
    Description
    private void
    add(int[] result, int[] x, int[] y)
    Adds two numbers modulo 2^255 - 19.
    private static void
    cswap(int select, int[] x, int[] y)
    Conditional swap of two values.
    private void
    Destroy all sensitive data in this object.
    static void
    eval(byte[] result, int offset, byte[] privateKey, byte[] publicKey)
    Evaluates the Curve25519 curve.
    private void
    evalCurve(byte[] s)
    Evaluates the curve for every bit in a secret key.
    private void
    mul(int[] result, int[] x, int[] y)
    Multiplies two numbers modulo 2^255 - 19.
    private void
    mulA24(int[] result, int[] x)
    Multiplies a number by the a24 constant, modulo 2^255 - 19.
    private void
    pow250(int[] result, int[] x)
    Raise x to the power of (2^250 - 1).
    private void
    recip(int[] result, int[] x)
    Computes the reciprocal of a number modulo 2^255 - 19.
    private void
    reduce(int[] result, int[] x, int size)
    Reduce a number modulo 2^255 - 19.
    private void
    reduceQuick(int[] x)
    Reduces a number modulo 2^255 - 19 where it is known that the number can be reduced with only 1 trial subtraction.
    private void
    square(int[] result, int[] x)
    Squares a number modulo 2^255 - 19.
    private static void
    sub(int[] result, int[] x, int[] y)
    Subtracts two numbers modulo 2^255 - 19.

    Methods inherited from class Object

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

    • NUM_LIMBS_255BIT

      private static final int NUM_LIMBS_255BIT
      Limbs of a field element, ten 26 bit words modulo 2^255 - 19.
      See Also:
    • NUM_LIMBS_510BIT

      private static final int NUM_LIMBS_510BIT
      Limbs holding a doubled width value.
      See Also:
    • _SCRATCH

      private static final ThreadLocal<Curve25519> _SCRATCH
      Per-thread scratch state for eval(byte[], int, byte[], byte[]).

      The evaluation is a few microseconds of arithmetic over roughly 1 KB of limb arrays; allocating those 16 arrays on every call put that cost on the GC (LS2 derives a key per client tunnel, SSU2/NTCP2 do it per handshake, ECIES ratchets do it per turn).

      A Curve25519 is reachable only through the private constructor and the static eval(), and eval() never reenters itself - every instance method it calls is private leaf arithmetic. One instance per thread is therefore sufficient.

      Security: the instance handed out here is always fully zeroed, both on creation and on release (destroy() runs in a finally on every path out of eval()), and eval() clears it again before use - so a pooled instance never carries private key material forward, exactly as a freshly allocated one did not.

    • x_1

      private final int[] x_1
      The x coordinate of the input point.
    • x_2

      private final int[] x_2
      The x coordinate of the accumulator point.
    • x_3

      private final int[] x_3
      The x coordinate of the difference point.
    • z_2

      private final int[] z_2
      The z coordinate of the accumulator point.
    • z_3

      private final int[] z_3
      The z coordinate of the difference point.
    • A

      private final int[] A
      Sum x_2 plus z_2, a ladder intermediate.
    • B

      private final int[] B
      Difference x_2 minus z_2, a ladder intermediate.
    • C

      private final int[] C
      Sum x_3 plus z_3, a ladder intermediate.
    • D

      private final int[] D
      Difference x_3 minus z_3, a ladder intermediate.
    • E

      private final int[] E
      Difference AA minus BB, a ladder intermediate.
    • AA

      private final int[] AA
      A squared, a ladder intermediate.
    • BB

      private final int[] BB
      B squared, a ladder intermediate.
    • DA

      private final int[] DA
      D times A, a ladder intermediate.
    • CB

      private final int[] CB
      C times B, a ladder intermediate.
    • t1

      private final long[] t1
      Wide temporary for the field arithmetic.
    • t2

      private final int[] t2
      Narrow temporary for the field arithmetic.
  • Constructor Details

    • Curve25519

      private Curve25519()
      Constructs the temporary state holder for Curve25519 evaluation.
  • Method Details

    • destroy

      private void destroy()
      Destroy all sensitive data in this object. Also used to reset the per-thread scratch instance before each evaluation.
    • reduceQuick

      private void reduceQuick(int[] x)
      Reduces a number modulo 2^255 - 19 where it is known that the number can be reduced with only 1 trial subtraction.
      Parameters:
      x - The number to reduce, and the result.
    • reduce

      private void reduce(int[] result, int[] x, int size)
      Reduce a number modulo 2^255 - 19.
      Parameters:
      result - receives the reduced value
      x - The value to be reduced. This array will be modified during the reduction.
      size - The number of limbs in the high order half of x.
    • mul

      private void mul(int[] result, int[] x, int[] y)
      Multiplies two numbers modulo 2^255 - 19.
      Parameters:
      result - receives the product
      x - The first number to multiply.
      y - The second number to multiply.
    • square

      private void square(int[] result, int[] x)
      Squares a number modulo 2^255 - 19.
      Parameters:
      result - receives the square
      x - The number to square.
    • mulA24

      private void mulA24(int[] result, int[] x)
      Multiplies a number by the a24 constant, modulo 2^255 - 19.
      Parameters:
      result - receives the product
      x - The number to multiply by a24.
    • add

      private void add(int[] result, int[] x, int[] y)
      Adds two numbers modulo 2^255 - 19.
      Parameters:
      result - receives the sum
      x - The first number to add.
      y - The second number to add.
    • sub

      private static void sub(int[] result, int[] x, int[] y)
      Subtracts two numbers modulo 2^255 - 19.
      Parameters:
      result - receives the difference
      x - The first number to subtract.
      y - The second number to subtract.
    • cswap

      private static void cswap(int select, int[] x, int[] y)
      Conditional swap of two values.
      Parameters:
      select - Set to 1 to swap, 0 to leave as-is.
      x - The first value.
      y - The second value.
    • pow250

      private void pow250(int[] result, int[] x)
      Raise x to the power of (2^250 - 1).
      Parameters:
      result - The result. Must not overlap with x.
      x - The base, as ten 26-bit limbs of a value modulo 2^255 - 19.
    • recip

      private void recip(int[] result, int[] x)
      Computes the reciprocal of a number modulo 2^255 - 19.
      Parameters:
      result - The result. Must not overlap with x.
      x - The value to invert, as ten 26-bit limbs of a number modulo 2^255 - 19; must be non-zero.
    • evalCurve

      private void evalCurve(byte[] s)
      Evaluates the curve for every bit in a secret key.
      Parameters:
      s - The 32-byte secret key.
    • eval

      public static void eval(byte[] result, int offset, byte[] privateKey, byte[] publicKey)
      Evaluates the Curve25519 curve.
      Parameters:
      result - Buffer to place the result of the evaluation into.
      offset - Offset into the result buffer.
      privateKey - The private key to use in the evaluation.
      publicKey - The public key to use in the evaluation, or null MUST have MSB high bit cleared, i.e. publicKey[31] & 0x80 == 0 if the base point of the curve should be used.
      Throws:
      IllegalArgumentException - on low-order input see RFC 7748