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 Schnorr

  1. Object
  2. Schnorr

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 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 types

class Schnorr.KeyPairA private key with its x-only public key, derived once, for signing many messages; the counterpart of libsecp256k1’s secp256k1_keypair.

Fields

public static final int PUBLIC_KEY_LENGTH = 32Length of an x-only public key.
public static final int SIGNATURE_LENGTH = 64Length of a signature.

Methods

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

Inherited methods

Field details

PUBLIC_KEY_LENGTH

public static final int PUBLIC_KEY_LENGTH = 32
Length of an x-only public key.

SIGNATURE_LENGTH

public static final int SIGNATURE_LENGTH = 64
Length of a signature.

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 byte[]
the message; BIP-340 signs it as given
privateKey byte[]
32 bytes in [1, n-1]
auxRand byte[]
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