Class BIP340Signer

  • All Implemented Interfaces:
    Signer

    public class BIP340Signer
    extends java.lang.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, org.bouncycastle.crypto.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.

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      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.
      byte[] generateSignature()
      generate a signature for the message we've been loaded with using the key we were initialised with.
      static ECDomainParameters getDomain()
      secp256k1 domain parameters.
      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.
      void init​(boolean forSigning, AsymmetricCipherKeyPair keyPair, java.security.SecureRandom random)
      Initialise with a key pair whose public key is already to hand.
      void init​(boolean forSigning, CipherParameters parameters)
      Initialise the signer for signing or verification.
      void reset()
      reset the internal state
      void update​(byte b)
      update the internal digest with the byte b
      void update​(byte[] in, int off, int len)
      update the internal digest with the byte array in
      boolean verifySignature​(byte[] signature)
      return true if the internal state represents the signature described in the passed in array.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • 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 Detail

      • 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,
                         java.security.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