Class VoucherSignatureService

java.lang.Object
xyz.tcheeric.cashu.voucher.domain.VoucherSignatureService

public final class VoucherSignatureService extends Object
Service for secp256k1/Schnorr signature generation and verification of voucher secrets.

This service provides cryptographic operations for vouchers using the same signature scheme as Nostr (BIP-340 Schnorr signatures over secp256k1):

  • Signing voucher secrets with issuer private keys (secp256k1/Schnorr)
  • Verifying signatures with issuer public keys (secp256k1 x-only)
  • Creating complete SignedVoucher instances

Cryptographic Details

Uses BIP-340 Schnorr signatures over the NUT-10 serialized representation of the voucher secret. The canonical bytes for signing are obtained by serializing the VoucherSecret without the signature tag, then hashing with SHA-256.

Key Format

Keys are expected as hex-encoded strings (matching Nostr format):

  • Private key: 64 hex characters (32 bytes) - secp256k1 scalar
  • Public key: 64 hex characters (32 bytes) - x-only secp256k1 point

Signature Format

Signatures are 64 bytes (BIP-340 Schnorr format).

Thread Safety

All methods are stateless and thread-safe.

See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    createSigned(@NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @NonNull String issuerPrivateKeyHex, @NonNull String issuerPublicKeyHex)
    Creates a signed voucher by signing the secret and setting the signature/pubkey tags.
    static byte[]
    sign(@NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @NonNull String issuerPrivateKeyHex)
    Signs a voucher secret with an issuer's private key using Schnorr signatures.
    static boolean
    verify(@NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret)
    Verifies a voucher secret's signature using the signature and public key from its tags.
    static boolean
    verify(@NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @lombok.NonNull byte[] signature, @NonNull String issuerPublicKeyHex)
    Verifies a voucher signature using the issuer's public key.

    Methods inherited from class java.lang.Object

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

    • sign

      public static byte[] sign(@NonNull @NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @NonNull @NonNull String issuerPrivateKeyHex)
      Signs a voucher secret with an issuer's private key using Schnorr signatures.

      The signature is generated over the canonical representation of the voucher secret (NUT-10 format without signature tag) using BIP-340 Schnorr signatures. The resulting signature is 64 bytes.

      Parameters:
      secret - the voucher secret to sign (must not be null)
      issuerPrivateKeyHex - the issuer's private key as hex string (64 chars, must not be null)
      Returns:
      the Schnorr signature (64 bytes)
      Throws:
      IllegalArgumentException - if the private key format is invalid
    • verify

      public static boolean verify(@NonNull @NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret)
      Verifies a voucher secret's signature using the signature and public key from its tags.
      Parameters:
      secret - the voucher secret with signature and public key tags set
      Returns:
      true if the signature is valid, false otherwise
    • verify

      public static boolean verify(@NonNull @NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @NonNull @lombok.NonNull byte[] signature, @NonNull @NonNull String issuerPublicKeyHex)
      Verifies a voucher signature using the issuer's public key.

      Verifies that the signature is valid for the voucher secret's canonical bytes using BIP-340 Schnorr signature verification.

      Parameters:
      secret - the voucher secret (must not be null)
      signature - the signature to verify (must not be null, 64 bytes)
      issuerPublicKeyHex - the issuer's public key as hex string (64 chars, must not be null)
      Returns:
      true if the signature is valid, false otherwise
    • createSigned

      public static SignedVoucher createSigned(@NonNull @NonNull xyz.tcheeric.cashu.common.nut18.VoucherSecret secret, @NonNull @NonNull String issuerPrivateKeyHex, @NonNull @NonNull String issuerPublicKeyHex)
      Creates a signed voucher by signing the secret and setting the signature/pubkey tags.

      This is a convenience method that:

      1. Signs the voucher secret with the private key using Schnorr
      2. Sets the signature and public key tags on the secret
      3. Creates a SignedVoucher wrapping the secret
      Parameters:
      secret - the voucher secret to sign (must not be null)
      issuerPrivateKeyHex - the issuer's private key as hex string (must not be null)
      issuerPublicKeyHex - the issuer's public key as hex string (must not be null)
      Returns:
      a new SignedVoucher instance
      Throws:
      IllegalArgumentException - if key formats are invalid