Class Schnorr

java.lang.Object
com.codename1.security.Schnorr

public final class Schnorr extends Object

BIP-340 Schnorr signatures over secp256k1: the signatures of Bitcoin's Taproot (key-path spends, P2TR) and of Nostr events.

Keys are the 32-byte x coordinate alone ("x-only"); the point with the even y is meant. A private key is the same 32 bytes as for Secp256k1.

byte[] privateKey = SecureRandom.bytes(32);
byte[] messageHash = Hash.sha256("hello".getBytes());
byte[] pub = Schnorr.publicKey(privateKey);
byte[] sig = Schnorr.sign(messageHash, privateKey, SecureRandom.bytes(32));
boolean ok = Schnorr.verify(messageHash, sig, pub);

Signing is deterministic given the auxiliary randomness; passing fresh random bytes there, as BIP-340 recommends, protects against fault and side-channel attacks that a purely deterministic nonce does not.

[#sign(byte[], byte[], byte[])] derives the public key on every call, which BIP-340 signing needs, and that is half the work of a signature. A Schnorr.KeyPair derives it once:

byte[] privateKey = SecureRandom.bytes(32);
Schnorr.KeyPair keys = new Schnorr.KeyPair(privateKey);
byte[] first = keys.sign(Hash.sha256("first".getBytes()), SecureRandom.bytes(32));
byte[] second = keys.sign(Hash.sha256("second".getBytes()), SecureRandom.bytes(32));
keys.destroy();
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    A private key with its x-only public key, derived once, for signing many messages; the counterpart of libsecp256k1's secp256k1_keypair.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Length of an x-only public key.
    static final int
    Length of a signature.
  • Method Summary

    Modifier and Type
    Method
    Description
    static byte[]
    publicKey(byte[] privateKey)
    The x-only public key of a private key.
    static byte[]
    sign(byte[] message, byte[] privateKey, byte[] auxRand)
    Signs a message, normally a 32-byte hash.
    static boolean
    verify(byte[] message, byte[] signature, byte[] publicKey)
    Verifies a signature.

    Methods inherited from class Object

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

    • PUBLIC_KEY_LENGTH

      public static final int PUBLIC_KEY_LENGTH
      Length of an x-only public key.
      See Also:
    • SIGNATURE_LENGTH

      public static final int SIGNATURE_LENGTH
      Length of a signature.
      See Also:
  • Method Details

    • publicKey

      public static byte[] publicKey(byte[] privateKey)

      The x-only public key of a private key.

      Throws
      • CryptoException: if the private key is not valid
    • sign

      public static byte[] sign(byte[] message, byte[] privateKey, byte[] auxRand)

      Signs a message, normally a 32-byte hash.

      Parameters
      • message: the message; BIP-340 signs it as given

      • privateKey: 32 bytes in [1, n-1]

      • auxRand: 32 random bytes, or null for the all-zero value the standard's test vectors use

      Returns

      the 64-byte signature

      Throws
      • CryptoException: if the key or the randomness is malformed
    • verify

      public static boolean verify(byte[] message, byte[] signature, byte[] publicKey)

      Verifies a signature.

      Returns

      true if signature was made over message by the key behind publicKey; false for any malformed or wrong signature

      Throws
      • CryptoException: if the message is null or the public key is not 32 bytes