Client and backend. This class is shared: the same code is compiled into your app and into your server, so everything on this page works in both.
public final class CryptoBatch
- Object
- CryptoBatch
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, Schnorr.verify,
Ed25519.verify 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
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 types
interface CryptoBatch.Callback | The answer of an asynchronous batch. |
Methods
Inherited methods
Method details
verifySecp256k1
public static boolean[] verifySecp256k1(byte[][] hashes, Secp256k1.EcdsaSignature[] signatures, byte[][] publicKeys)Secp256k1.verify: each
32-byte hash, signature and SEC1 public key.verifySchnorr
public static boolean[] verifySchnorr(byte[][] messages, byte[][] signatures, byte[][] publicKeys)Schnorr.verify: each message, 64-byte
signature and 32-byte x-only public key.verifyEd25519
public static boolean[] verifyEd25519(byte[][] messages, byte[][] signatures, byte[][] publicKeys)Ed25519.verify: each message, 64-byte
signature and 32-byte public key.sha256
public static byte[][] sha256(byte[][] inputs)null input has a null digest.keccak256
public static byte[][] keccak256(byte[][] inputs)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)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)sha256
public static void sha256(byte[] inputs, int inputLength, int count, byte[] digests)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)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)verifySchnorrAsync
public static void verifySchnorrAsync(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)verifyEd25519Async
public static void verifyEd25519Async(byte[][] messages, byte[][] signatures, byte[][] publicKeys, CryptoBatch.Callback<boolean[]> callback)sha256Async
public static void sha256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)keccak256Async
public static void keccak256Async(byte[][] inputs, CryptoBatch.Callback<byte[][]> callback)verifySecp256k1Async
public static void verifySecp256k1Async(byte[] hashes, byte[] signatures, byte[] publicKeys, int publicKeyLength, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)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)verifyEd25519Async
public static void verifyEd25519Async(byte[] messages, int messageLength, byte[] signatures, byte[] publicKeys, byte[] results, int count, CryptoBatch.Callback<byte[]> callback)sha256Async
public static void sha256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)digests.keccak256Async
public static void keccak256Async(byte[] inputs, int inputLength, int count, byte[] digests, CryptoBatch.Callback<byte[]> callback)digests.