Class XMSSMTSigner
- All Implemented Interfaces:
Signer
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbyte[]generate a signature for the message we've been loaded with using the key we were initialised with.longReturn the number of signatures the key this signer holds can still produce.voidinit(boolean forSigning, CipherParameters param) Initialise for signing or verification.voidreset()reset the internal statevoidupdate(byte b) Absorb a byte of the message to be signed or verified.voidupdate(byte[] in, int off, int len) update the internal digest with the byte array inbooleanverifySignature(byte[] signature) Verify the buffered message against the passed in signature.
-
Constructor Details
-
XMSSMTSigner
public XMSSMTSigner()
-
-
Method Details
-
init
Initialise for signing or verification. AParametersWithRandomwrapper is accepted and unwrapped before either branch is entered, the way LMSSigner.init accepts it, so a caller that wraps its key once and drives both sides is not refused by the verification one; the random the wrapper carries is not used. The randomizer r is derived from the key itself - r = PRF(SK_PRF, toByte(idx, 32)), RFC 8391 sec. 4.2.7 - so a SecureRandom supplied here has nothing to drive and is discarded, the way SPHINCS256Signer discards it. On the signing side accepting the wrapper is what BC itself needs: XMSSMTSignatureSpi.engineInitSign(PrivateKey, SecureRandom) wraps the key whenever a random is supplied, so initSign(key, random) used to fail on the cast.- Specified by:
initin interfaceSigner- Parameters:
forSigning- true for signing, false for verification.param- the key, optionally wrapped inParametersWithRandom.
-
generateSignature
public byte[] generateSignature()Description copied from interface:Signergenerate a signature for the message we've been loaded with using the key we were initialised with.- Specified by:
generateSignaturein interfaceSigner
-
verifySignature
public boolean verifySignature(byte[] signature) Verify the buffered message against the passed in signature.No monitor is taken here, the way the legacy signer and
LMSSignertake none. This reads the public key and the mode flag, spends no one-time key and advances no traversal state, so there is nothing for a lock to serialize; and it could not serialize the message in any case, sinceupdate(byte)andreset()write the buffer without one, so a monitor held over the read alone excludes nothing a caller sharing one signer across threads is doing. What the signing side takes this monitor for is the private key field, whichgetUpdatedPrivateKey()reassigns; nothing reassigns the public key butinit(boolean, CipherParameters), and re-initialising a signer under a running operation is the caller error it is in every other signer here.- Specified by:
verifySignaturein interfaceSigner
-
getUsagesRemaining
public long getUsagesRemaining()Return the number of signatures the key this signer holds can still produce. A signer that has never been initialised for signing, or one whose key has already been handed back bygetUpdatedPrivateKey(), holds no key and so reports zero - reading the absent key would otherwise raise a NullPointerException.Initialising for verification is not one of those cases:
init(boolean, org.bouncycastle.crypto.CipherParameters)deliberately leaves the private key in place, so that sign then verify then collect stays a legitimate sequence, and a signer that has signed and then been re-initialised to verify goes on reporting that key's count. What this answers is what the key it holds has left, not whether the signer is currently able to sign.No monitor is taken, the way the legacy signer takes none and the two key parameter classes LMS was promoted as leave their own getUsagesRemaining() unsynchronized. What this returns is a count and not a reservation: it is out of date the moment any monitor held over it is dropped, because the next signature made on that key - by this signer or by another holding it - moves it. The field read is of a reference and so cannot tear, and the key's own accessor takes the key's monitor for the traversal state the count is derived from.
-
update
public void update(byte b) Absorb a byte of the message to be signed or verified. The buffered message is consumed bygenerateSignature()/verifySignature(byte[]), which reset the buffer. -
update
-
reset
-
getUpdatedPrivateKey
-