Class 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
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 ClassesModifier and TypeClassDescriptionstatic final classA private key with its x-only public key, derived once, for signing many messages; the counterpart of libsecp256k1'ssecp256k1_keypair. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intLength of an x-only public key.static final intLength of a signature. -
Method Summary
Modifier and TypeMethodDescriptionstatic 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 booleanverify(byte[] message, byte[] signature, byte[] publicKey) Verifies a signature.
-
Field Details
-
PUBLIC_KEY_LENGTH
public static final int PUBLIC_KEY_LENGTHLength of an x-only public key.- See Also:
-
SIGNATURE_LENGTH
public static final int SIGNATURE_LENGTHLength 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, ornullfor 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
trueifsignaturewas made overmessageby the key behindpublicKey;falsefor any malformed or wrong signatureThrows
CryptoException: if the message is null or the public key is not 32 bytes
-