java.lang.Object
net.i2p.crypto.DSAEngine

public final class DSAEngineextends Object
Digital signature algorithm engine supporting DSA, ECDSA, RSA, and EdDSA. Provides signing and verification operations for all supported signature types.
  • Field Details

    • _log

      private final Log _log
      Logger for this class.
    • _context

      private final I2PAppContext _context
      The context supplying the random.
    • _useJavaLibs

      private static final boolean _useJavaLibs
      Whether to use the JVM's own DSA implementation.
      See Also:
    • _sha1

      private static final ThreadLocal<MessageDigest> _sha1
      Thread-local SHA-1 digest for calculateHash(byte[], int, int) and calculateHash(InputStream), so that a DSA-SHA1 hash does not allocate a fresh SHA1 (a MessageDigestSpi plus a 64 byte pad) each time. Reset on every acquire and never handed outside this class, so there is no state that can leak between calls.
    • _sha512

      private static final ThreadLocal<MessageDigest> _sha512
      Thread-local SHA-512 digest for the EdDSA sign/verify paths, so that each operation does not clone a fresh MessageDigest off the SigType prototype. The engine resets it on every init, and it is never handed outside this class, so no state can leak between calls.
    • DSAQ_MINUS_2

      private static final BigInteger DSAQ_MINUS_2
      Two less than dsaq, the Fermat exponent for the constant-time DSA nonce inverse.
      See Also:
  • Constructor Details

    • DSAEngine

      public DSAEngine(I2PAppContext context)
      Create a DSA engine for the given context.
      Parameters:
      context - the application context, supplying the log, clock and random source
  • Method Details

    • sha512

      private static MessageDigest sha512()
      Gives a SHA-512 digest, from a pool.
      Returns:
      a digest ready for use
    • engineFor

      private static EdDSAEngine engineFor(SigType type, MessageDigest md)
      New EdDSA or RedDSA engine for the given type, sharing the caller's (thread-local) SHA-512 digest.
      Parameters:
      type - the signature type; RedDSA_SHA512_Ed25519 selects the RedDSA engine, any other type the standard EdDSA engine
      md - the SHA-512 digest the new engine writes into
      Returns:
      a newly allocated engine, non-null
    • getInstance

      public static DSAEngine getInstance()
      Get the DSA engine instance from the global context.
      Returns:
      the DSA engine
    • verifySignature

      public boolean verifySignature(Signature signature, byte[] signedData, SigningPublicKey verifyingKey)
      Verify a signature using any supported signature type.
      Parameters:
      signature - the signature to verify
      signedData - the data that was signed
      verifyingKey - the public key to verify with
      Returns:
      true if the signature is valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, byte[] signedData, int offset, int size, SigningPublicKey verifyingKey)
      Verify using any sig type as of 0.9.12 (DSA only prior to that).
      Parameters:
      signature - the signature to verify
      signedData - the data that was signed
      offset - index within signedData of the first signed byte
      size - number of signed bytes to verify, starting at offset
      verifyingKey - the public key to verify with
      Returns:
      true if valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, InputStream in, SigningPublicKey verifyingKey)
      Verify using DSA-SHA1 ONLY.
      Parameters:
      signature - the signature to verify
      in - the data to hash and verify, read to EOF but not closed
      verifyingKey - the public key to verify with
      Returns:
      true if valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, SHA1Hash hash, SigningPublicKey verifyingKey)
      Verify using DSA-SHA1 ONLY.
      Parameters:
      signature - the signature to verify
      hash - SHA-1 hash, NOT a SHA-256 hash
      verifyingKey - the public key to verify with
      Returns:
      true if valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, Hash hash, SigningPublicKey verifyingKey)
      Nonstandard. Used by Syndie.
      Parameters:
      signature - the signature to verify
      hash - the pre-computed hash, of the length required by the key's type
      verifyingKey - the public key to verify with
      Returns:
      true if valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey)
      Generic signature type.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      signature - the signature to verify
      hash - SHA1Hash, Hash, Hash384, or Hash512
      verifyingKey - the public key to verify with
      Returns:
      true if valid, false otherwise
    • verifySignature

      public boolean verifySignature(Signature signature, SimpleDataStructure hash, PublicKey pubKey)
      Generic signature type. If you have a Java pubkey, use this, so you don't lose the key parameters, which may be different than the ones defined in SigType.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      signature - the signature to verify
      hash - SHA1Hash, Hash, Hash384, or Hash512
      pubKey - Java key
      Returns:
      true if valid, false otherwise
    • verifySig

      private boolean verifySig(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey)
      Verify using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
      Parameters:
      signature - a DSA-SHA1 signature, the only type accepted
      hash - either a Hash or a SHA1Hash
      verifyingKey - a DSA-SHA1 public key, the only type accepted
      Returns:
      true if valid, false otherwise
      Throws:
      IllegalArgumentException - if the signature or the key is not DSA-SHA1
    • sign

      public Signature sign(byte[] data, SigningPrivateKey signingKey)
      Sign using any key type. Uses TheCrypto code unless configured to use the java.security libraries.
      Parameters:
      data - the data to sign
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(byte[] data, int offset, int length, SigningPrivateKey signingKey)
      Sign using any key type as of 0.9.12 (DSA-SHA1 only prior to that).
      Parameters:
      data - the data to sign
      offset - index within data of the first byte to sign
      length - number of bytes to sign, starting at offset
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(InputStream in, SigningPrivateKey signingKey)
      Sign using DSA-SHA1 ONLY. Reads the stream until EOF. Does not close the stream.
      Parameters:
      in - the data to hash and sign, read to EOF but not closed
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(SHA1Hash hash, SigningPrivateKey signingKey)
      Sign using DSA-SHA1 ONLY.
      Parameters:
      hash - SHA-1 hash, NOT a SHA-256 hash
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(Hash hash, SigningPrivateKey signingKey)
      Nonstandard. Used by Syndie.
      Parameters:
      hash - the pre-computed hash, of the length required by the key's type
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(SimpleDataStructure hash, SigningPrivateKey signingKey)
      Generic signature type.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      hash - SHA1Hash, Hash, Hash384, or Hash512
      signingKey - the private key matching the signature type
      Returns:
      null on error
    • sign

      public Signature sign(SimpleDataStructure hash, PrivateKey privKey, SigType type)
      Generic signature type. If you have a Java privkey, use this, so you don't lose the key parameters, which may be different than the ones defined in SigType.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      hash - SHA1Hash, Hash, Hash384, or Hash512
      privKey - Java key
      type - returns a Signature of this type
      Returns:
      null on error
    • signIt

      private Signature signIt(SimpleDataStructure hash, SigningPrivateKey signingKey)
      Sign using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
      Parameters:
      hash - either a Hash or a SHA1Hash
      signingKey - a DSA-SHA1 private key, the only type accepted
      Returns:
      the 40-byte signature (r then s), or null on error
      Throws:
      IllegalArgumentException - if the key is not DSA-SHA1
    • calculateHash

      public SHA1Hash calculateHash(InputStream in)
      Reads the stream until EOF. Does not close the stream. Prefer calculateHash(byte[], int, int) for byte array inputs.
      Parameters:
      in - the stream to read to EOF, not closed here
      Returns:
      the SHA-1 hash, NOT a SHA-256 hash, or null on an IO error
    • calculateHash

      public static SHA1Hash calculateHash(byte[] source, int offset, int len)
      Calculate a SHA-1 hash of the source data.
      Parameters:
      source - the data to hash
      offset - the offset in the source data
      len - the length of data to hash
      Returns:
      the SHA-1 hash
    • altVerifySig

      private boolean altVerifySig(Signature signature, byte[] data, int offset, int len, SigningPublicKey verifyingKey) throws GeneralSecurityException
      Generic verify any type.
      Parameters:
      signature - the signature to check, of any signature type
      data - the data the signature was made over
      offset - where the signed data starts in data
      len - how many bytes of data to verify
      verifyingKey - the public key to check against, of the same type as the signature
      Returns:
      true if valid, false otherwise
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
      IllegalArgumentException - if the signature and key types differ
    • altVerifySigRaw

      private boolean altVerifySigRaw(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey) throws GeneralSecurityException
      Generic raw verify any type

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      signature - the signature to check, of any signature type
      hash - the pre-computed hash, of the signature type's hash length
      verifyingKey - the public key to check against, of the same type as the signature
      Returns:
      true if valid, false otherwise
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
      IllegalArgumentException - if the signature and key types differ
    • altVerifySigRaw

      private boolean altVerifySigRaw(Signature signature, SimpleDataStructure hash, PublicKey pubKey) throws GeneralSecurityException
      Generic raw verify any type. If you have a Java pubkey, use this, so you don't lose the key parameters, which may be different than the ones defined in SigType.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      signature - the signature to check, of any signature type
      hash - the pre-computed hash, of the signature type's hash length
      pubKey - the public key as a Java key, with its own parameters intact
      Returns:
      true if valid, false otherwise
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
      IllegalArgumentException - if the hash length does not match the signature type's hash length
    • altVerifySigSHA1

      private boolean altVerifySigSHA1(Signature signature, byte[] data, int offset, int len, SigningPublicKey verifyingKey) throws GeneralSecurityException
      Alternate to verifySignature(Signature, byte[], int, int, SigningPublicKey) using java.security libraries.
      Parameters:
      signature - the DSA-SHA1 signature to check
      data - the data the signature was made over
      offset - where the signed data starts in data
      len - how many bytes of data to verify
      verifyingKey - the DSA public key to check against
      Returns:
      true if valid, false otherwise
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
    • altSign

      private Signature altSign(byte[] data, int offset, int len, SigningPrivateKey privateKey) throws GeneralSecurityException
      Generic sign any type.
      Parameters:
      data - the data to sign
      offset - where the data to sign starts in data
      len - how many bytes of data to sign
      privateKey - the key to sign with, whose type selects the algorithm
      Returns:
      the Signature, or null on error
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
    • altSignRaw

      private Signature altSignRaw(SimpleDataStructure hash, SigningPrivateKey privateKey) throws GeneralSecurityException
      Generic raw sign any type.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      hash - SHA1Hash, Hash, Hash384, or Hash512
      privateKey - the key to sign with, whose type selects the algorithm
      Returns:
      the signature over the hash, of the private key's type
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
    • altSignRaw

      private Signature altSignRaw(String algo, SimpleDataStructure hash, PrivateKey privKey, SigType type) throws GeneralSecurityException
      Generic raw sign any type.

      Warning, nonstandard for EdDSA, double-hashes, not recommended.

      Parameters:
      algo - the raw JCA algorithm name, e.g. NONEwithDSA, ignored for EdDSA types
      hash - SHA1Hash, Hash, Hash384, or Hash512
      privKey - the key to sign with, as a Java key
      type - returns a Signature of this type
      Returns:
      the signature over the hash, of the type named by algo
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
      IllegalArgumentException - if the hash length does not match the type's hash length
    • altSignSHA1

      private Signature altSignSHA1(byte[] data, int offset, int len, SigningPrivateKey privateKey) throws GeneralSecurityException
      Alternate to sign(byte[], int, int, SigningPrivateKey) using java.security libraries.
      Parameters:
      data - the data to sign
      offset - where the data to sign starts in data
      len - how many bytes of data to sign
      privateKey - the DSA private key to sign with
      Returns:
      the DSA-SHA1 signature, non-null
      Throws:
      GeneralSecurityException - if algorithm unavailable or on other errors
    • getRawAlgo

      private static String getRawAlgo(SigType type)
      Map a signature type to the raw (prehashed) JCA algorithm name.
      Parameters:
      type - the signature type whose base algorithm selects the name
      Returns:
      the JCA algorithm name, e.g. NONEwithDSA
      Throws:
      UnsupportedOperationException - if the type's base algorithm has no raw form
    • getRawAlgo

      private static String getRawAlgo(Key key)
      Map a Java key to the raw (prehashed) JCA algorithm name.
      Parameters:
      key - the Java key whose class selects the algorithm name
      Returns:
      the JCA algorithm name, e.g. NONEwithDSA
      Throws:
      UnsupportedOperationException - if the key implements none of the four supported key interfaces