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
- Object
- 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.KeyPair | A 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 = 32 | Length of an x-only public key. |
public static final int SIGNATURE_LENGTH = 64 | Length 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 = 32SIGNATURE_LENGTH
public static final int SIGNATURE_LENGTH = 64Method details
publicKey
public static byte[] publicKey(byte[] privateKey)Throws
CryptoException- if the private key is not valid
sign
public static byte[] sign(byte[] message, byte[] privateKey, byte[] auxRand)Parameters
messagebyte[]- the message; BIP-340 signs it as given
privateKeybyte[]- 32 bytes in
[1, n-1] auxRandbyte[]- 32 random bytes, or
nullfor the all-zero value the standard’s test vectors use
Returns
Throws
CryptoException- if the key or the randomness is malformed
verify
public static boolean verify(byte[] message, byte[] signature, byte[] publicKey)Returns
true if signature was made over message by the key behind
publicKey; false for any malformed or wrong signatureThrows
CryptoException- if the message is null or the public key is not 32 bytes