java.lang.Object
java.security.SignatureSpi
java.security.Signature
net.i2p.crypto.eddsa.EdDSAEngine
- Direct Known Subclasses:
RedDSAEngine
EdDSA signature engine implementing the Java Signature API. Supports both standard streaming and one-shot operation modes for efficiency.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classParameter spec carrying the one call data.Field Summary
Modifier and TypeFieldDescriptionprivate static final BigIntegerLittleEndianEncodingEncoder of big integers in little endian.private ByteArrayOutputStreamCollects the data to be signed.protected MessageDigestThe message digest used for signing/verification.private EdDSAKeyThe key used to sign or verify.static final AlgorithmParameterSpecTo efficiently sign or verify data in one shot, pass this to setParameters() after initSign() or initVerify() but BEFORE THE FIRST AND ONLY update(data) or update(data, off, len).private byte[]The data given in one call.private intLength of the one call data.private booleanTrue when the data is given in one call.private intOffset in the one call data.private static final byte[]EdDSABlinding.ORDERas 32 little-endian bytes, so that the RFC 8032 range check on S can be done by subtraction instead of building a BigInteger.private byte[]Reusable buffer for the S half of a signature, to avoid allocating a fresh array for every verification.static final StringThe signature algorithm name.Fields inherited from class Signature
SIGN, state, UNINITIALIZED, VERIFYFields inherited from class SignatureSpi
appRandomConstructor Summary
ConstructorsConstructorDescriptionNo specific EdDSA-internal hash requested, allows any EdDSA key.EdDSAEngine(MessageDigest digest) Specific EdDSA-internal hash requested, only matching keys will be allowed.Method Summary
Modifier and TypeMethodDescriptionprotected voiddigestInitSign(EdDSAPrivateKey privKey) Initialize the digest for signing.protected voidengineInitSign(PrivateKey privateKey) protected voidengineInitVerify(PublicKey publicKey) protected voidOnly the one-shot mode parameter specification is supported.protected byte[]protected voidengineUpdate(byte b) Update the signature with one byte.protected voidengineUpdate(byte[] b, int off, int len) Update the signature with the given bytes.protected booleanengineVerify(byte[] sigBytes) private static booleanisBelowOrder(byte[] s) Is the 32 byte little-endian value insstrictly less thanEdDSABlinding.ORDER?private voidreset()Reset the signer and verifier state.byte[]signOneShot(byte[] data) To efficiently sign all the data in one shot, if it is available, use this method, which will avoid copying the data.byte[]signOneShot(byte[] data, int off, int len) To efficiently sign all the data in one shot, if it is available, use this method, which will avoid copying the data.booleanverifyOneShot(byte[] data, byte[] signature) To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.booleanverifyOneShot(byte[] data, byte[] signature, int sigoff, int siglen) To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.booleanverifyOneShot(byte[] data, int off, int len, byte[] signature) To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.booleanverifyOneShot(byte[] data, int off, int len, byte[] signature, int sigoff, int siglen) To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.private byte[]Signs the collected data.private booleanx_engineVerify(byte[] sigBytes) Checks the signature of the collected data.Methods inherited from class Signature
clone, getAlgorithm, getInstance, getInstance, getInstance, getParameters, getProvider, initSign, initSign, initVerify, initVerify, setParameter, sign, sign, toString, update, update, update, update, verify, verifyMethods inherited from class SignatureSpi
engineGetParameters, engineInitSign, engineSign, engineUpdate, engineVerify
Field Details
SIGNATURE_ALGORITHM
The signature algorithm name.- See Also:
digest
The message digest used for signing/verification.baos
Collects the data to be signed.key
The key used to sign or verify.oneShotMode
private boolean oneShotModeTrue when the data is given in one call.oneShotBytes
private byte[] oneShotBytesThe data given in one call.oneShotOffset
private int oneShotOffsetOffset in the one call data.oneShotLength
private int oneShotLengthLength of the one call data.ONE_SHOT_MODE
To efficiently sign or verify data in one shot, pass this to setParameters() after initSign() or initVerify() but BEFORE THE FIRST AND ONLY update(data) or update(data, off, len). The data reference will be saved and then used in sign() or verify() without copying the data. Violate these rules and you will get a SignatureException._ble
Encoder of big integers in little endian.ORDER_LITTLE_ENDIAN
private static final byte[] ORDER_LITTLE_ENDIANEdDSABlinding.ORDERas 32 little-endian bytes, so that the RFC 8032 range check on S can be done by subtraction instead of building a BigInteger. Verified againstBigInteger.compareTo().sBuf
private byte[] sBufReusable buffer for the S half of a signature, to avoid allocating a fresh array for every verification. Only valid within one call, and never retained by any callee. Like the digest, baos and oneShotBytes state this class already keeps, it assumes the instance is used by one thread at a time - callers that care create a fresh engine per operation.
Constructor Details
EdDSAEngine
public EdDSAEngine()No specific EdDSA-internal hash requested, allows any EdDSA key.EdDSAEngine
Specific EdDSA-internal hash requested, only matching keys will be allowed.- Parameters:
digest- the hash algorithm that keys must have to sign or verify.
Method Details
reset
private void reset()Reset the signer and verifier state.engineInitSign
- Specified by:
engineInitSignin classSignatureSpi- Throws:
InvalidKeyException
digestInitSign
Initialize the digest for signing.- Parameters:
privKey- the private key
engineInitVerify
- Specified by:
engineInitVerifyin classSignatureSpi- Throws:
InvalidKeyException
engineUpdate
Update the signature with one byte.- Specified by:
engineUpdatein classSignatureSpi- Throws:
SignatureException- if in one-shot mode
engineUpdate
Update the signature with the given bytes.- Specified by:
engineUpdatein classSignatureSpi- Throws:
SignatureException- if one-shot rules are violated
engineSign
- Specified by:
engineSignin classSignatureSpi- Throws:
SignatureException
x_engineSign
Signs the collected data.- Returns:
- the signature bytes
- Throws:
SignatureException- if the signing fails
engineVerify
- Specified by:
engineVerifyin classSignatureSpi- Throws:
SignatureException
x_engineVerify
Checks the signature of the collected data.- Parameters:
sigBytes- the signature to check- Returns:
- true if the signature is valid
- Throws:
SignatureException- if the checking fails
isBelowOrder
private static boolean isBelowOrder(byte[] s) Is the 32 byte little-endian value insstrictly less thanEdDSABlinding.ORDER?Equivalent to
_ble.toBigInteger(s).compareTo(EdDSABlinding.ORDER) < 0without allocating a BigInteger and a reversed copy of the input. This is a fixed 32 iteration borrow chain: every byte is read and every byte is subtracted, and the only carry is folded into the next iteration with arithmetic, so there is no data-dependent branch or memory access. That makes it strictly better thanBigInteger.compareTo(), which exits early on the first differing magnitude word. A short-circuiting byte compare would be a timing oracle here;DataHelper.eq()/MessageDigest.isEqual(byte[], byte[])are equality tests and cannot express an ordering, so they don't apply.- Parameters:
s- the value to test, 32 bytes, little-endian- Returns:
- true if s is less than the group order
signOneShot
To efficiently sign all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data) sig = sign()
- Parameters:
data- the message to be signed- Returns:
- the R and S components, 2 * b/4 bytes long
- Throws:
SignatureException- if update() already called- See Also:
signOneShot
To efficiently sign all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data, off, len) sig = sign()
- Parameters:
data- byte array containing the message to be signedoff- the start of the message inside datalen- the length of the message- Returns:
- the R and S components, 2 * b/4 bytes long
- Throws:
SignatureException- if update() already called- See Also:
verifyOneShot
To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data) ok = verify(signature)
- Parameters:
data- the message that was signedsignature- of the message- Returns:
- true if the signature is valid, false otherwise
- Throws:
SignatureException- if update() already called- See Also:
verifyOneShot
public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature) throws SignatureException To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data, off, len) ok = verify(signature)
- Parameters:
data- byte array containing the message that was signedoff- the start of the message inside datalen- the length of the messagesignature- of the message- Returns:
- true if the signature is valid, false otherwise
- Throws:
SignatureException- if update() already called- See Also:
verifyOneShot
public boolean verifyOneShot(byte[] data, byte[] signature, int sigoff, int siglen) throws SignatureException To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data) ok = verify(signature, sigoff, siglen)
- Parameters:
data- the message that was signedsignature- byte array containing the signaturesigoff- the start of the signaturesiglen- the length of the signature- Returns:
- true if the signature is valid, false otherwise
- Throws:
SignatureException- if update() already called- See Also:
verifyOneShot
public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature, int sigoff, int siglen) throws SignatureException To efficiently verify all the data in one shot, if it is available, use this method, which will avoid copying the data.Same as:
setParameter(ONE_SHOT_MODE) update(data, off, len) ok = verify(signature, sigoff, siglen)
- Parameters:
data- byte array containing the message that was signedoff- the start of the message inside datalen- the length of the messagesignature- byte array containing the signaturesigoff- the start of the signaturesiglen- the length of the signature- Returns:
- true if the signature is valid, false otherwise
- Throws:
SignatureException- if update() already called- See Also:
engineSetParameter
protected void engineSetParameter(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException Only the one-shot mode parameter specification is supported.- Overrides:
engineSetParameterin classSignatureSpi- Throws:
InvalidAlgorithmParameterException- if spec is ONE_SHOT_MODE and update() already called- See Also: