public void testSigningDistinctMessages(
      PublicKeySign signer,
      PublicKeyVerify verifier,
      boolean isDeterministic,
      int maxMessageSize,
      int numberOfThreads,
      int numberOfSignatures)
      throws Exception {
    ExceptionHandler exceptionHandler = new ExceptionHandler();
    Thread[] thread = new Thread[numberOfThreads];
    ArrayList<HashSet<String>> signatures = new ArrayList<HashSet<String>>();
    byte[][] messages = new byte[numberOfThreads][];
    for (int i = 0; i < numberOfThreads; i++) {
      // Just an arbitrary prime to get the plaintext sizes.
      int p = 28657;
      int size = i * p % (maxMessageSize + 1);
      messages[i] = new byte[size];
      HashSet<String> sigs = new HashSet<String>();
      signatures.add(sigs);
      thread[i] = new SigningThread(signer, sigs, messages[i], numberOfSignatures);
      thread[i].setUncaughtExceptionHandler(exceptionHandler);
    }
    for (int i = 0; i < numberOfThreads; i++) {
      thread[i].start();
    }
    for (int i = 0; i < numberOfThreads; i++) {
      thread[i].join();
    }
    exceptionHandler.check();
    if (isDeterministic) {
      for (int i = 0; i < numberOfThreads; i++) {
        String expectedSignature = Hex.encode(signer.sign(messages[i]));
        assertEquals(1, signatures.get(i).size());
        assertTrue(signatures.get(i).contains(expectedSignature));
      }
    } else {
      for (int i = 0; i < numberOfThreads; i++) {
        assertEquals(numberOfSignatures, signatures.get(i).size());
        for (String sig : signatures.get(i)) {
          verifier.verify(Hex.decode(sig), messages[i]);
        }
      }
    }
  }
Sign distinct messages concurrently in multiple threads. The purpose of this test is to find
deterministic signatures schemes, that share state to compute nonces.
java_src/src/test/java/com/google/crypto/tink/subtle/SignatureThreadSafetyTest.java