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.

Note: getUpdatedPrivateKey() needs to be called to fetch the current value of the usable private key.

/** * 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; } }