Class CryptoBatch

java.lang.Object
com.codename1.security.CryptoBatch

public final class CryptoBatch extends Object

Many signature verifications or hashes in one call: the deposits of a block an exchange scans, the transactions an indexer checks, the leaves of a Merkle tree.

Where the platform has native kernels the whole batch crosses into native code once and is spread over every CPU core, so a batch of thousands runs several times faster than the same calls one at a time. Elsewhere it is the same loop over Secp256k1.verify(byte[], Secp256k1.EcdsaSignature, byte[]), Schnorr.verify(byte[], byte[], byte[]), Ed25519.verify(byte[], byte[], byte[]) or Hash that a caller would write.

Every entry gets exactly the answer the single call gives it; nothing here uses a batch equation that could accept a signature a single verify rejects. A malformed entry -- a null, a key that does not parse, a wrong length -- is simply invalid, so one bad entry never aborts the rest.

Every method has an asynchronous form, named with Async and taking a CryptoBatch.Callback, which runs the same batch off the calling thread. In the app the callback runs on the EDT, so a screen can start a batch and show its result without blocking; in a backend it runs on the thread that did the work. In a browser the asynchronous forms are the ones to use: there a large batch goes to the GPU through WebGPU, which answers only asynchronously, and the synchronous form holds its thread for that long. The arguments are checked before the call returns, so a malformed batch throws right away rather than reaching the callback. The batch reads the arrays it was given, not a copy, so they belong to it until the callback runs: changing one before then changes the entries being verified. The callback runs exactly once, with the result or with whatever was thrown, an Error included.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    The answer of an asynchronous batch.
  • Method Summary

    Modifier and Type
    Method
    Description
    static byte[][]
    keccak256(byte[][] inputs)
    The Keccak-256 of each input (Ethereum's hash).
    static void
    keccak256(byte[] inputs, int inputLength, int count, byte[] digests)
    The Keccak-256 of count packed inputs, laid out as [#sha256(byte[], int, int, byte[])].
    static void
    keccak256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)
    [#keccak256(byte[][])] off the calling thread.
    static void
    keccak256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)
    [#keccak256(byte[], int, int, byte[])] off the calling thread; the callback gets digests.
    static byte[][]
    sha256(byte[][] inputs)
    The SHA-256 of each input.
    static void
    sha256(byte[] inputs, int inputLength, int count, byte[] digests)
    The SHA-256 of count inputs of inputLength bytes each, input i at inputLength * i of inputs and its digest written at 32 * i of digests.
    static void
    sha256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)
    [#sha256(byte[][])] off the calling thread.
    static void
    sha256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)
    [#sha256(byte[], int, int, byte[])] off the calling thread; the callback gets digests.
    static boolean[]
    verifyEd25519(byte[][] messages, byte[][] signatures, byte[][] publicKeys)
    Ed25519, entry by entry as Ed25519.verify(byte[], byte[], byte[]): each message, 64-byte signature and 32-byte public key.
    static void
    verifyEd25519(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count)
    The packed form of [#verifyEd25519(byte[][], byte[][], byte[][])], laid out as [#verifySchnorr(byte[], int, byte[], byte[], byte[], int)].
    static void
    verifyEd25519Async(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
    [#verifyEd25519(byte[][], byte[][], byte[][])] off the calling thread.
    static void
    verifyEd25519Async(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
    [#verifyEd25519(byte[], int, byte[], byte[], byte[], int)] off the calling thread, as [#verifySecp256k1Async(byte[], byte[], byte[], int, byte[], int, Callback)].
    static boolean[]
    verifySchnorr(byte[][] messages, byte[][] signatures, byte[][] publicKeys)
    BIP-340 Schnorr, entry by entry as Schnorr.verify(byte[], byte[], byte[]): each message, 64-byte signature and 32-byte x-only public key.
    static void
    verifySchnorr(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count)
    The packed form of [#verifySchnorr(byte[][], byte[][], byte[][])]: entry i is the message of messageLength bytes at messageLength * i of messages, the 64-byte signature at 64 * i of signatures and the 32-byte x-only key at 32 * i of publicKeys.
    static void
    verifySchnorrAsync(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
    [#verifySchnorr(byte[][], byte[][], byte[][])] off the calling thread.
    static void
    verifySchnorrAsync(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
    [#verifySchnorr(byte[], int, byte[], byte[], byte[], int)] off the calling thread, as [#verifySecp256k1Async(byte[], byte[], byte[], int, byte[], int, Callback)].
    static boolean[]
    verifySecp256k1(byte[][] hashes, Secp256k1.EcdsaSignature[] signatures, byte[][] publicKeys)
    ECDSA over secp256k1, entry by entry as Secp256k1.verify(byte[], Secp256k1.EcdsaSignature, byte[]): each 32-byte hash, signature and SEC1 public key.
    static void
    verifySecp256k1(byte[] hashes, byte[] signatures, byte[] publicKeys, int publicKeyLength, byte[] results, int count)
    The packed form of [#verifySecp256k1(byte[][], Secp256k1.EcdsaSignature[], byte[][])], for batches large enough that an object per entry matters.
    static void
    verifySecp256k1Async(byte[][] hashes, Secp256k1.EcdsaSignature[] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
    [#verifySecp256k1(byte[][], Secp256k1.EcdsaSignature[], byte[][])] off the calling thread.
    static void
    verifySecp256k1Async(byte[] hashes, byte[] signatures, byte[] publicKeys, int publicKeyLength, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
    [#verifySecp256k1(byte[], byte[], byte[], int, byte[], int)] off the calling thread.

    Methods inherited from class Object

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

    • verifySecp256k1

      public static boolean[] verifySecp256k1(byte[][] hashes, Secp256k1.EcdsaSignature[] signatures, byte[][] publicKeys)
      ECDSA over secp256k1, entry by entry as Secp256k1.verify(byte[], Secp256k1.EcdsaSignature, byte[]): each 32-byte hash, signature and SEC1 public key.
    • verifySchnorr

      public static boolean[] verifySchnorr(byte[][] messages, byte[][] signatures, byte[][] publicKeys)
      BIP-340 Schnorr, entry by entry as Schnorr.verify(byte[], byte[], byte[]): each message, 64-byte signature and 32-byte x-only public key.
    • verifyEd25519

      public static boolean[] verifyEd25519(byte[][] messages, byte[][] signatures, byte[][] publicKeys)
      Ed25519, entry by entry as Ed25519.verify(byte[], byte[], byte[]): each message, 64-byte signature and 32-byte public key.
    • sha256

      public static byte[][] sha256(byte[][] inputs)
      The SHA-256 of each input. A null input has a null digest.
    • keccak256

      public static byte[][] keccak256(byte[][] inputs)
      The Keccak-256 of each input (Ethereum's hash). A null input has a null digest.
    • verifySecp256k1

      public static void verifySecp256k1(byte[] hashes, byte[] signatures, byte[] publicKeys, int publicKeyLength, byte[] results, int count)

      The packed form of [#verifySecp256k1(byte[][], Secp256k1.EcdsaSignature[], byte[][])], for batches large enough that an object per entry matters. Entry i is the 32-byte hash at 32 * i of hashes, the 64-byte compact signature (r || s) at 64 * i of signatures, and the SEC1 public key of publicKeyLength bytes (33 or 65) at publicKeyLength * i of publicKeys. Writes 1 (valid) or 0 to each of the first count bytes of results; a malformed entry is 0.

      On a native target the kernels read and write these arrays where they are, without copying them, so a pipeline that fills them in place pays nothing per entry outside the verification itself. Allocating them with Simd.get().allocByte(int) in an app aligns them for the vector units and the GPU.

    • verifySchnorr

      public static void verifySchnorr(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count)
      The packed form of [#verifySchnorr(byte[][], byte[][], byte[][])]: entry i is the message of messageLength bytes at messageLength * i of messages, the 64-byte signature at 64 * i of signatures and the 32-byte x-only key at 32 * i of publicKeys. Writes 1 or 0 to each of the first count bytes of results. See [#verifySecp256k1(byte[], byte[], byte[], int, byte[], int)] on allocating the arrays.
    • verifyEd25519

      public static void verifyEd25519(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count)
      The packed form of [#verifyEd25519(byte[][], byte[][], byte[][])], laid out as [#verifySchnorr(byte[], int, byte[], byte[], byte[], int)].
    • sha256

      public static void sha256(byte[] inputs, int inputLength, int count, byte[] digests)
      The SHA-256 of count inputs of inputLength bytes each, input i at inputLength * i of inputs and its digest written at 32 * i of digests. A level of a Merkle tree is inputLength 64 over the level below; digests may then be the next level's inputs.
    • keccak256

      public static void keccak256(byte[] inputs, int inputLength, int count, byte[] digests)
      The Keccak-256 of count packed inputs, laid out as [#sha256(byte[], int, int, byte[])].
    • verifySecp256k1Async

      public static void verifySecp256k1Async(byte[][] hashes, Secp256k1.EcdsaSignature[] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
      [#verifySecp256k1(byte[][], Secp256k1.EcdsaSignature[], byte[][])] off the calling thread.
    • verifySchnorrAsync

      public static void verifySchnorrAsync(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
      [#verifySchnorr(byte[][], byte[][], byte[][])] off the calling thread.
    • verifyEd25519Async

      public static void verifyEd25519Async(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)
      [#verifyEd25519(byte[][], byte[][], byte[][])] off the calling thread.
    • sha256Async

      public static void sha256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)
      [#sha256(byte[][])] off the calling thread.
    • keccak256Async

      public static void keccak256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)
      [#keccak256(byte[][])] off the calling thread.
    • verifySecp256k1Async

      public static void verifySecp256k1Async(byte[] hashes, byte[] signatures, byte[] publicKeys, int publicKeyLength, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
      [#verifySecp256k1(byte[], byte[], byte[], int, byte[], int)] off the calling thread. The callback gets results once every entry is written; until then the arrays belong to the batch and must not be changed.
    • verifySchnorrAsync

      public static void verifySchnorrAsync(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
      [#verifySchnorr(byte[], int, byte[], byte[], byte[], int)] off the calling thread, as [#verifySecp256k1Async(byte[], byte[], byte[], int, byte[], int, Callback)].
    • verifyEd25519Async

      public static void verifyEd25519Async(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)
      [#verifyEd25519(byte[], int, byte[], byte[], byte[], int)] off the calling thread, as [#verifySecp256k1Async(byte[], byte[], byte[], int, byte[], int, Callback)].
    • sha256Async

      public static void sha256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)
      [#sha256(byte[], int, int, byte[])] off the calling thread; the callback gets digests.
    • keccak256Async

      public static void keccak256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)
      [#keccak256(byte[], int, int, byte[])] off the calling thread; the callback gets digests.