Class SpeckCipher

java.lang.Object
com.github.tommyettinger.random.cipher.SpeckCipher

public final class SpeckCipher extends Object
An implementation of the Speck Cipher that can encrypt and decrypt using either CBC or CTR modes. Speck is designed to be small and fast when implemented in software. This does not extend javax.crypto.Cipher because that isn't possible in a pure Java library, to my knowledge.
I have very little faith in my implementation's accuracy, and even an accurate implementation would have been specified by The United States of America's NSA, making it inherently untrustworthy. It should be fast, though, and strong enough to keep small-time crooks out of encrypted files. Big-time crooks (nation-states) should be assumed to already have anything they want that was encrypted with this.
This uses a block size of 128 bits and a key size of 256 bits.
The implementation here is based on m2mi's open_speck C code, which is licensed under Apache 2.0. Though the m2mi implementation seems to use some form of PKCS#7 for padding, it encrypts the last block but doesn't decrypt it, so I think it may only work when a full block of padding is written, validated and ignored. That is, if it works at all! I haven't been able to test m2mi's implementation, but this code has been tested some in this repo. This version uses zero-padding instead of PKCS#7, and works even if a partial block is all there is in the plaintext. When encrypting with CBC mode, the ciphertext array may need to be larger than the plaintext array; use newPaddedArray(long[]) or newPaddedArray(byte[]) to get an array of the right size. This isn't required for CTR mode.
  • Method Summary

    Modifier and Type
    Method
    Description
    static void
    decrypt(long[] key, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset)
    A usually-internal decryption step.
    static void
    decrypt(long[] key, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset)
    A usually-internal decryption step.
    static byte[]
    decryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array.
    static long[]
    decryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to decrypt a coded "ciphertext" long array and get back the original "plaintext" long array from before encryptCBC(long, long, long, long, long, long, long[], int, long[], int, int) was called.
    static byte[]
    decryptCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to decrypt a coded "ciphertext" byte array and get back a "plaintext" byte array.
    static byte[]
    decryptCTR(long k1, long k2, long k3, long k4, long nonce, int nonce2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to decrypt a coded "ciphertext" byte array and get back a "plaintext" byte array.
    static long[]
    decryptCTR(long k1, long k2, long k3, long k4, long nonce, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to decrypt a coded "ciphertext" long array and get back a "plaintext" long array.
    static byte[]
    decryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, byte[] ciphertext, int cipherOffset, int textLength)
    Decrypts a coded "ciphertext" byte array and changes it in-place to a "plaintext" byte array.
    static ByteBuffer
    decryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, ByteBuffer ciphertext, int cipherOffset, int textLength)
    Decrypts a coded "ciphertext" ByteBuffer and changes it in-place to a "plaintext" ByteBuffer.
    static void
    encrypt(long[] key, long last0, long last1, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset)
    A usually-internal encryption step.
    static void
    encrypt(long[] key, long last0, long last1, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset)
    A usually-internal encryption step.
    static byte[]
    encryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array.
    static long[]
    encryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" long array and get back a coded "ciphertext" long array.
    static byte[]
    encryptCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array.
    static byte[]
    encryptCTR(long k1, long k2, long k3, long k4, long nonce, int nonce2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array.
    static long[]
    encryptCTR(long k1, long k2, long k3, long k4, long nonce, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
    One of the main ways here to encrypt a "plaintext" long array and get back a coded "ciphertext" long array.
    static byte[]
    encryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, int textLength)
    Encrypts a "plaintext" byte array in-place, making it a coded "ciphertext" byte array.
    static ByteBuffer
    encryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, ByteBuffer plaintext, int plainOffset, int textLength)
    Encrypts a "plaintext" ByteBuffer in-place, making it a coded "ciphertext" ByteBuffer.
    static void
    encryptWithXor(long[] key, long iv0, long iv1, byte[] plaintext, int plainOffset)
    A usually-internal encryption step.
    static void
    encryptWithXor(long[] key, long iv0, long iv1, ByteBuffer plaintext, int plainOffset)
    A usually-internal encryption step.
    static long[]
    expandKey(long k1, long k2, long k3, long k4)
    Given a 256-bit key as four long values, this grows that initial key into a 2176-bit expanded key (a long[34]).
    static byte[]
    newPaddedArray(byte[] data)
    Copies data into a new byte array that will be at least as long as data, padded with zeroes so that it meets a length that is a multiple of 16, if necessary.
    static long[]
    newPaddedArray(long[] data)
    Copies data into a new long array that will be at least as long as data, padded with zeroes so that it meets a length that is a multiple of 2, if necessary.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • newPaddedArray

      public static long[] newPaddedArray(long[] data)
      Copies data into a new long array that will be at least as long as data, padded with zeroes so that it meets a length that is a multiple of 2, if necessary. If data is null, this returns a new long array with length 2.
      This is typically used to ensure the ciphertext array is long enough to hold the data assigned to it. It is only needed for the ciphertext written to by encryptCBC(long, long, long, long, long, long, long[], int, long[], int, int) (CTR doesn't need it).
      Parameters:
      data - a long array to copy, potentially including padding in the copy
      Returns:
      a long array with a length that is a multiple of 2
    • newPaddedArray

      public static byte[] newPaddedArray(byte[] data)
      Copies data into a new byte array that will be at least as long as data, padded with zeroes so that it meets a length that is a multiple of 16, if necessary. If data is null, this returns a new byte array with length 16.
      This is typically used to ensure the ciphertext array is long enough to hold the data assigned to it. It is only needed for the ciphertext written to by encryptCBC(long, long, long, long, long, long, byte[], int, byte[], int, int) (CTR doesn't need it).
      Parameters:
      data - a byte array to copy, potentially including padding in the copy
      Returns:
      a byte array with a length that is a multiple of 16
    • expandKey

      public static long[] expandKey(long k1, long k2, long k3, long k4)
      Given a 256-bit key as four long values, this grows that initial key into a 2176-bit expanded key (a long[34]). This uses 34 rounds of the primary algorithm used by Speck. Used by encryptCBC(long, long, long, long, long, long, long[], int, long[], int, int), encryptCTR(long, long, long, long, long, long[], int, long[], int, int), decryptCBC(long, long, long, long, long, long, long[], int, long[], int, int), and decryptCTR(long, long, long, long, long, long[], int, long[], int, int) internally.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      Returns:
      a 34-item long array that should, of course, be kept secret to be used cryptographically
    • encrypt

      public static void encrypt(long[] key, long last0, long last1, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset)
      A usually-internal encryption step. You should use either CBC or CTR mode to actually encrypt a piece of plaintext, with encryptCBC(long, long, long, long, long, long, long[], int, long[], int, int) or encryptCTR(long, long, long, long, long, long[], int, long[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      last0 - the first half of the previous result, or the first IV if there was no previous result
      last1 - the last half of the previous result, or the second IV if there was no previous result
      plaintext - the plaintext array, as long items
      plainOffset - the index to start reading from in plaintext
      ciphertext - the ciphertext array, as long items that will be written to; may need to be padded
      cipherOffset - the index to start writing to in ciphertext
    • encrypt

      public static void encrypt(long[] key, long last0, long last1, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset)
      A usually-internal encryption step. You should use either CBC or CTR mode to actually encrypt a piece of plaintext, with encryptCBC(long, long, long, long, long, long, byte[], int, byte[], int, int) or encryptCTR(long, long, long, long, long, byte[], int, byte[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      last0 - the first half of the previous result, or the first IV if there was no previous result
      last1 - the last half of the previous result, or the second IV if there was no previous result
      plaintext - the plaintext array, as byte items
      plainOffset - the index to start reading from in plaintext
      ciphertext - the ciphertext array, as byte items that will be written to; may need to be padded
      cipherOffset - the index to start writing to in ciphertext
    • encryptWithXor

      public static void encryptWithXor(long[] key, long iv0, long iv1, byte[] plaintext, int plainOffset)
      A usually-internal encryption step. You should use either CBC or CTR mode to actually encrypt a piece of plaintext, with encryptCBC(long, long, long, long, long, long, byte[], int, byte[], int, int) or encryptCTR(long, long, long, long, long, byte[], int, byte[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      iv0 - the first IV
      iv1 - the second IV
      plaintext - the plaintext array, as byte items; will be modified
      plainOffset - the index to start writing to (with XOR) in plaintext
    • encryptWithXor

      public static void encryptWithXor(long[] key, long iv0, long iv1, ByteBuffer plaintext, int plainOffset)
      A usually-internal encryption step. You should use either CBC or CTR mode to actually encrypt a piece of plaintext, with encryptCBC(long, long, long, long, long, long, byte[], int, byte[], int, int) or encryptCTR(long, long, long, long, long, byte[], int, byte[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      iv0 - the first IV
      iv1 - the second IV
      plaintext - the plaintext array, as byte items; will be modified
      plainOffset - the index to start writing to (with XOR) in plaintext
    • decrypt

      public static void decrypt(long[] key, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset)
      A usually-internal decryption step. You should use either CBC or CTR mode to actually decrypt a piece of plaintext, with decryptCBC(long, long, long, long, long, long, long[], int, long[], int, int) or decryptCTR(long, long, long, long, long, long[], int, long[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      plaintext - the plaintext array, as long items that will be written to
      plainOffset - the index to start writing to in plaintext
      ciphertext - the ciphertext array, as long items
      cipherOffset - the index to start reading from in ciphertext
    • decrypt

      public static void decrypt(long[] key, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset)
      A usually-internal decryption step. You should use either CBC or CTR mode to actually decrypt a piece of plaintext, with decryptCBC(long, long, long, long, long, long, byte[], int, byte[], int, int) or decryptCTR(long, long, long, long, long, byte[], int, byte[], int, int).
      Parameters:
      key - an expanded key, as produced by expandKey(long, long, long, long)
      plaintext - the plaintext array, as byte items that will be written to
      plainOffset - the index to start writing to in plaintext
      ciphertext - the ciphertext array, as byte items
      cipherOffset - the index to start reading from in ciphertext
    • encryptCBC

      public static long[] encryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" long array and get back a coded "ciphertext" long array. This takes four longs as its key (256-bits), and also requires two unique (never used again) longs as IVs. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate IVs, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless IVs are requested for years from one generator, so it is a good option to produce IVs (using two DistinctRandom generators also works, with one for each IV). The rest of the arguments are about the data being encrypted. The plaintext is the long array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext will be written to, should usually be empty at the start (though it doesn't need to be), and must be padded as by newPaddedArray(long[]). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many long items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CBC mode, so it takes two IVs instead of how CTR mode takes one nonce. If the IVs aren't sufficiently random, this produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      iv1 - a long that must never be reused as iv1 again under the same key; needed to decrypt
      iv2 - a long that must never be reused as iv2 again under the same key; needed to decrypt
      plaintext - the long array to encrypt; will not be modified
      plainOffset - which index to start reading from plaintext
      ciphertext - the long array to write encrypted data to; will be modified, and should be padded
      cipherOffset - which index to start writing to in ciphertext
      textLength - how many long items to read and encrypt from plaintext
      Returns:
      ciphertext, after modifications
    • encryptCBC

      public static byte[] encryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array. This takes four longs as its key (256-bits), and also requires two unique (never used again) longs as IVs. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate IVs, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless IVs are requested for years from one generator, so it is a good option to produce IVs (using two DistinctRandom generators also works, with one for each IV). The rest of the arguments are about the data being encrypted. The plaintext is the byte array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext will be written to, should usually be empty at the start (though it doesn't need to be), and must be padded as by newPaddedArray(byte[]). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CBC mode, so it takes two IVs instead of how CTR mode takes one nonce. If the IVs aren't sufficiently random, this produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      iv1 - a long that must never be reused as iv1 again under the same key; needed to decrypt
      iv2 - a long that must never be reused as iv2 again under the same key; needed to decrypt
      plaintext - the byte array to encrypt; will not be modified
      plainOffset - which index to start reading from plaintext
      ciphertext - the byte array to write encrypted data to; will be modified, and should be padded
      cipherOffset - which index to start writing to in ciphertext
      textLength - how many byte items to read and encrypt from plaintext
      Returns:
      ciphertext, after modifications
    • decryptCBC

      public static long[] decryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to decrypt a coded "ciphertext" long array and get back the original "plaintext" long array from before encryptCBC(long, long, long, long, long, long, long[], int, long[], int, int) was called. This takes four longs as its key (256-bits), and also requires two unique (never used again) longs as IVs. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate IVs, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless IVs are requested for years from one generator, so it is a good option to produce IVs (using two DistinctRandom generators also works, with one for each IV). The rest of the arguments are about the data being encrypted. The plaintext is the long array to receive decrypted data; it will be modified, but doesn't have size restrictions. The plainOffset is which index in plaintext to start writing to. The ciphertext will only be read from here, and should start with the output of encryptCBC(). The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many long items to decrypt from ciphertext; this must be at least equal to plaintext's length.
      This uses CBC mode, so it takes two IVs instead of how CTR mode takes one nonce. If the IVs aren't sufficiently random, this produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 2 (16 bytes) when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      iv1 - a long that was used as iv1 to encrypt this specific data
      iv2 - a long that was used as iv2 to encrypt this specific data
      plaintext - the long array to write to
      plainOffset - which index to start writing to in plaintext
      ciphertext - the long array to read coded data from
      cipherOffset - which index to start reading from in ciphertext
      textLength - how many long items to read from ciphertext
      Returns:
      plaintext, after modifications
    • decryptCBC

      public static byte[] decryptCBC(long k1, long k2, long k3, long k4, long iv1, long iv2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the byte array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext is the byte array that will be written to, and should usually be empty at the start (though it doesn't need to be). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CBC mode, so it takes two IVs instead of how CTR mode takes one nonce. If the IVs aren't sufficiently random, this produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 16 when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      iv1 - a long that was used as iv1 to encrypt this specific data
      iv2 - a long that was used as iv2 to encrypt this specific data
      plaintext - the byte array to write to
      plainOffset - which index to start writing to in plaintext
      ciphertext - the byte array to read coded data from
      cipherOffset - which index to start reading from in ciphertext
      textLength - how many byte items to read from ciphertext
      Returns:
      plaintext, after modifications
    • encryptCTR

      public static long[] encryptCTR(long k1, long k2, long k3, long k4, long nonce, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" long array and get back a coded "ciphertext" long array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the long array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext is the long array that will be written to, and should usually be empty at the start (though it doesn't need to be). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many long items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that must never be reused as nonce again under the same key; needed to decrypt
      plaintext - the long array to encrypt; will not be modified
      plainOffset - which index to start reading from plaintext
      ciphertext - the long array to write encrypted data to; will be modified
      cipherOffset - which index to start writing to in ciphertext
      textLength - how many long items to read and encrypt from plaintext
      Returns:
      ciphertext, after modifications
    • encryptCTR

      public static byte[] encryptCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the byte array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext is the byte array that will be written to, and should usually be empty at the start (though it doesn't need to be). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that must never be reused as nonce again under the same key; needed to decrypt
      plaintext - the byte array to encrypt; will not be modified
      plainOffset - which index to start reading from plaintext
      ciphertext - the byte array to write encrypted data to; will be modified
      cipherOffset - which index to start writing to in ciphertext
      textLength - how many byte items to read and encrypt from plaintext
      Returns:
      ciphertext, after modifications
    • encryptCTR

      public static byte[] encryptCTR(long k1, long k2, long k3, long k4, long nonce, int nonce2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to encrypt a "plaintext" byte array and get back a coded "ciphertext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the byte array to encrypt; it will not be modified here. The plainOffset is which index in plaintext to start reading from. The ciphertext is the byte array that will be written to, and should usually be empty at the start (though it doesn't need to be). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start writing to in ciphertext. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that must never be reused as nonce again under the same key; needed to decrypt
      nonce2 - an int that must never be reused as nonce2 again under the same key; needed to decrypt
      plaintext - the byte array to encrypt; will not be modified
      plainOffset - which index to start reading from plaintext
      ciphertext - the byte array to write encrypted data to; will be modified
      cipherOffset - which index to start writing to in ciphertext
      textLength - how many byte items to read and encrypt from plaintext
      Returns:
      ciphertext, after modifications
    • decryptCTR

      public static long[] decryptCTR(long k1, long k2, long k3, long k4, long nonce, long[] plaintext, int plainOffset, long[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to decrypt a coded "ciphertext" long array and get back a "plaintext" long array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being decrypted. The plaintext is the long array that will receive the decrypted final result. The plainOffset is which index in plaintext to start writing to. The ciphertext is the long array that contains coded data, and should have been encrypted by encryptCTR(long, long, long, long, long, long[], int, long[], int, int). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many long items to decrypt from ciphertext; this can be less than ciphertext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 2 (16 bytes) when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that was used as nonce to encrypt this specific data
      plaintext - the long array to receive decrypted data; will be modified
      plainOffset - which index to start writing to in plaintext
      ciphertext - the long array to read encrypted data from; will not be modified
      cipherOffset - which index to start reading from in ciphertext
      textLength - how many long items to read and decrypt from ciphertext
      Returns:
      plaintext, after modifications
    • decryptCTR

      public static byte[] decryptCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to decrypt a coded "ciphertext" byte array and get back a "plaintext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being decrypted. The plaintext is the byte array that will receive the decrypted final result. The plainOffset is which index in plaintext to start writing to. The ciphertext is the byte array that contains coded data, and should have been encrypted by encryptCTR(long, long, long, long, long, byte[], int, byte[], int, int). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many byte items to decrypt from ciphertext; this can be less than ciphertext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 16 when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that was used as nonce to encrypt this specific data
      plaintext - the byte array to receive decrypted data; will be modified
      plainOffset - which index to start writing to in plaintext
      ciphertext - the byte array to read encrypted data from; will not be modified
      cipherOffset - which index to start reading from in ciphertext
      textLength - how many byte items to read and decrypt from ciphertext
      Returns:
      plaintext, after modifications
    • decryptCTR

      public static byte[] decryptCTR(long k1, long k2, long k3, long k4, long nonce, int nonce2, byte[] plaintext, int plainOffset, byte[] ciphertext, int cipherOffset, int textLength)
      One of the main ways here to decrypt a coded "ciphertext" byte array and get back a "plaintext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being decrypted. The plaintext is the byte array that will receive the decrypted final result. The plainOffset is which index in plaintext to start writing to. The ciphertext is the byte array that contains coded data, and should have been encrypted by encryptCTR(long, long, long, long, long, byte[], int, byte[], int, int). The ciphertext does not need to be padded (it does for CBC mode). The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many byte items to decrypt from ciphertext; this can be less than ciphertext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 16 when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that was used as nonce to encrypt this specific data
      nonce2 - an int that was used as nonce2 to encrypt this specific data
      plaintext - the byte array to receive decrypted data; will be modified
      plainOffset - which index to start writing to in plaintext
      ciphertext - the byte array to read encrypted data from; will not be modified
      cipherOffset - which index to start reading from in ciphertext
      textLength - how many byte items to read and decrypt from ciphertext
      Returns:
      plaintext, after modifications
    • encryptInPlaceCTR

      public static byte[] encryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, byte[] plaintext, int plainOffset, int textLength)
      Encrypts a "plaintext" byte array in-place, making it a coded "ciphertext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the byte array to encrypt; it will be modified here. The plainOffset is which index in plaintext to start reading from and writing to. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that must never be reused as nonce again under the same key; needed to decrypt
      plaintext - the byte array to encrypt in-place; will be modified
      plainOffset - which index to start reading from and writing to in plaintext
      textLength - how many byte items to read and encrypt from plaintext
    • decryptInPlaceCTR

      public static byte[] decryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, byte[] ciphertext, int cipherOffset, int textLength)
      Decrypts a coded "ciphertext" byte array and changes it in-place to a "plaintext" byte array. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being decrypted. The ciphertext is the byte array that contains coded data, and should have been encrypted by encryptInPlaceCTR(long, long, long, long, long, byte[], int, int). The ciphertext will be modified in-place to become the plaintext. The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many byte items to decrypt from ciphertext; this can be less than ciphertext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 16 when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that was used as nonce to encrypt this specific data
      ciphertext - the byte array to read encrypted data from; will be modified in-place
      cipherOffset - which index to start reading from and writing to in ciphertext
      textLength - how many byte items to read and decrypt from ciphertext
    • encryptInPlaceCTR

      public static ByteBuffer encryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, ByteBuffer plaintext, int plainOffset, int textLength)
      Encrypts a "plaintext" ByteBuffer in-place, making it a coded "ciphertext" ByteBuffer. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being encrypted. The plaintext is the ByteBuffer to encrypt; it will be modified here. The plainOffset is which index in plaintext to start reading from and writing to. Lastly, the textLength is how many byte items to encrypt from plaintext; this can be less than plaintext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding.
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that must never be reused as nonce again under the same key; needed to decrypt
      plaintext - the ByteBuffer to encrypt in-place; will be modified
      plainOffset - which index to start reading from and writing to in plaintext
      textLength - how many byte items to read and encrypt from plaintext
      Returns:
      plaintext, after modifications
    • decryptInPlaceCTR

      public static ByteBuffer decryptInPlaceCTR(long k1, long k2, long k3, long k4, long nonce, ByteBuffer ciphertext, int cipherOffset, int textLength)
      Decrypts a coded "ciphertext" ByteBuffer and changes it in-place to a "plaintext" ByteBuffer. This takes four longs as its key (256-bits), and also requires one unique (never used again) long as the nonce. How you generate keys is up to you, but the keys must be kept secret for encryption to stay secure. To generate nonce, secrecy isn't as important as uniqueness; calling DistinctRandom.nextLong() even many times will never return the same long unless nonce are requested for years from one generator, so it is a good option to produce nonce data. The rest of the arguments are about the data being decrypted. The ciphertext is the ByteBuffer that contains coded data, and should have been encrypted by encryptInPlaceCTR(long, long, long, long, long, ByteBuffer, int, int). The ciphertext will be modified in-place to become the plaintext. The cipheroffset is which index to start reading from in ciphertext. Lastly, the textLength is how many byte items to decrypt from ciphertext; this can be less than ciphertext's length.
      This uses CTR mode, so it takes one nonce instead of how CBC mode takes two IVs. If the IVs/nonce aren't sufficiently random, CBC mode produces higher-quality outputs than CTR mode. CBC mode may be slightly faster, though this isn't clear yet. CTR mode doesn't need its ciphertext to have padding. CBC mode requires textLength to be a multiple of 16 when decrypting (usually guaranteed by padding).
      Parameters:
      k1 - a secret long; part of the key
      k2 - a secret long; part of the key
      k3 - a secret long; part of the key
      k4 - a secret long; part of the key
      nonce - a long that was used as nonce to encrypt this specific data
      ciphertext - the ByteBuffer to read encrypted data from; will be modified in-place
      cipherOffset - which index to start reading from and writing to in ciphertext
      textLength - how many byte items to read and decrypt from ciphertext
      Returns:
      ciphertext, after modifications