blob: 77fe25a7aab45c47bd5885ae79ab0fbe7047113a [file] [log] [blame]
package org.bouncycastle.pqc.crypto.gmss;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.pqc.crypto.StateAwareMessageSigner;
import org.bouncycastle.util.Memoable;
/**
* This class implements the GMSS signature scheme, but allows multiple signatures to be generated.
* <p>
* Note: getUpdatedPrivateKey() needs to be called to fetch the current value of the usable private key.
* </p>
*/
public class GMSSStateAwareSigner
implements StateAwareMessageSigner
{
private final GMSSSigner gmssSigner;
private GMSSPrivateKeyParameters key;
public GMSSStateAwareSigner(final Digest digest)
{
if (!(digest instanceof Memoable))
{
throw new IllegalArgumentException("digest must implement Memoable");
}
final Memoable dig = ((Memoable)digest).copy();
gmssSigner = new GMSSSigner(new GMSSDigestProvider()
{
public Digest get()
{
return (Digest)dig.copy();
}
});
}
public void init(boolean forSigning, CipherParameters param)
{
if (forSigning)
{
if (param instanceof ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)param;
this.key = (GMSSPrivateKeyParameters)rParam.getParameters();
}
else
{
this.key = (GMSSPrivateKeyParameters)param;
}
}
gmssSigner.init(forSigning, param);
}
public byte[] generateSignature(byte[] message)
{
if (key == null)
{
throw new IllegalStateException("signing key no longer usable");
}
byte[] sig = gmssSigner.generateSignature(message);
key = key.nextKey();
return sig;
}
public boolean verifySignature(byte[] message, byte[] signature)
{
return gmssSigner.verifySignature(message, signature);
}
public AsymmetricKeyParameter getUpdatedPrivateKey()
{
AsymmetricKeyParameter k = key;
key = null;
return k;
}
}