Class BIP340Signer

java.lang.Object
org.bouncycastle.crypto.signers.BIP340Signer
All Implemented Interfaces:
Signer

public class BIP340Signer extends Object implements Signer
Schnorr signatures for secp256k1 per BIP-340 (with the BIP-340bis variable-length-message extension).

Public keys are the 32-byte big-endian X coordinate of the unique even-Y curve point with that X. Signatures are the fixed 64-byte concatenation bytes(R) || bytes(s) — neither encoding matches BC's ECDSA defaults.

Auxiliary randomness follows the usual BC low-level signer convention: the signer is randomized by default. A ParametersWithRandom on init(boolean, CipherParameters) supplies the source for the fresh 32-byte aux_rand drawn per generateSignature() call (BIP-340 §3.2, recommended for side-channel hardening); when none is supplied the default CryptoServicesRegistrar source is substituted, as for SM2Signer / ECDSASigner. Deterministic Schnorr (aux_rand = 0^32) is BIP-340 compliant but must be requested explicitly via BIP340Signer(boolean) — the absence of a supplied SecureRandom does not silently select it.

  • Constructor Details

    • BIP340Signer

      public BIP340Signer()
      Create a randomized BIP-340 signer: a per-signature aux_rand is drawn from the supplied ParametersWithRandom source, or the default CryptoServicesRegistrar source when none is supplied.
    • BIP340Signer

      public BIP340Signer(boolean deterministic)
      Parameters:
      deterministic - when true, sign deterministically with aux_rand = 0^32 (BIP-340 §3.3 default signing with empty auxiliary randomness) and ignore any supplied SecureRandom; when false (the usual case) draw a per-signature 32-byte aux_rand from the supplied or default SecureRandom.
  • Method Details

    • getDomain

      public static ECDomainParameters getDomain()
      secp256k1 domain parameters. Use to construct ECPrivateKeyParameters / call an ECKeyPairGenerator for BIP-340.
    • decodePublicKey

      public static ECPublicKeyParameters decodePublicKey(byte[] xOnly)
      Lift a 32-byte x-only BIP-340 public key to an ECPublicKeyParameters carrying the unique even-Y secp256k1 point with that X. Returns null for the cases BIP-340 §3.1 defines as verification failures: wrong length, X out of [0, p), or no curve point with that X.
    • init

      public void init(boolean forSigning, CipherParameters parameters)
      Description copied from interface: Signer
      Initialise the signer for signing or verification.
      Specified by:
      init in interface Signer
      Parameters:
      forSigning - true if for signing, false otherwise
      parameters - necessary parameters.
    • init

      public void init(boolean forSigning, AsymmetricCipherKeyPair keyPair)
      Initialise with a key pair whose public key is already to hand, drawing aux_rand from the default CryptoServicesRegistrar source when signing.
      Parameters:
      keyPair - a secp256k1 key pair, as produced by ECKeyPairGenerator over getDomain().
      See Also:
    • init

      public void init(boolean forSigning, AsymmetricCipherKeyPair keyPair, SecureRandom random)
      Initialise with a key pair whose public key is already to hand.

      Signing needs the public point twice - for the parity of d and for bytes(P) in the nonce and challenge hashes (BIP-340 sec. 3.3 steps 3-4) - and otherwise derives it with a d'*G multiplication, which is about half the cost of producing a signature. A caller that already holds the public key can supply it here and skip that.

      The public key must be the one belonging to the private key. That is not checked, since checking it means performing the very multiplication being avoided; supplying any other key simply yields a signature that does not verify. Prefer a pair that came from ECKeyPairGenerator, or one whose public half was read back through decodePublicKey(byte[]) from storage that recorded it alongside the private key.

      Parameters:
      keyPair - a secp256k1 key pair; only the public half is used when forSigning is false.
      random - source for the per-signature aux_rand, or null for the default CryptoServicesRegistrar source. Ignored when verifying, and by a signer constructed with deterministic signing.
    • update

      public void update(byte b)
      Description copied from interface: Signer
      update the internal digest with the byte b
      Specified by:
      update in interface Signer
    • update

      public void update(byte[] in, int off, int len)
      Description copied from interface: Signer
      update the internal digest with the byte array in
      Specified by:
      update in interface Signer
    • generateSignature

      public byte[] generateSignature()
      Description copied from interface: Signer
      generate a signature for the message we've been loaded with using the key we were initialised with.
      Specified by:
      generateSignature in interface Signer
    • verifySignature

      public boolean verifySignature(byte[] signature)
      Description copied from interface: Signer
      return true if the internal state represents the signature described in the passed in array.
      Specified by:
      verifySignature in interface Signer
    • reset

      public void reset()
      Description copied from interface: Signer
      reset the internal state
      Specified by:
      reset in interface Signer