package org.bouncycastle.pqc.crypto.xmss;

import java.security.SecureRandom;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.KeyGenerationParameters;

Key pair generator for XMSS^MT keys.
/** * Key pair generator for XMSS^MT keys. */
public final class XMSSMTKeyPairGenerator { private XMSSMTParameters params; private XMSSParameters xmssParams; private SecureRandom prng;
Base constructor...
/** * Base constructor... */
public XMSSMTKeyPairGenerator() { } public void init( KeyGenerationParameters param) { XMSSMTKeyGenerationParameters parameters = (XMSSMTKeyGenerationParameters)param; prng = parameters.getRandom(); this.params = parameters.getParameters(); this.xmssParams = params.getXMSSParameters(); }
Generate a new XMSSMT private key / public key pair.
/** * Generate a new XMSSMT private key / public key pair. */
public AsymmetricCipherKeyPair generateKeyPair() { XMSSMTPrivateKeyParameters privateKey; XMSSMTPublicKeyParameters publicKey; /* generate XMSSMT private key */ privateKey = generatePrivateKey(new XMSSMTPrivateKeyParameters.Builder(params).build().getBDSState()); /* import to xmss */ xmssParams.getWOTSPlus().importKeys(new byte[params.getDigestSize()], privateKey.getPublicSeed()); /* get root */ int rootLayerIndex = params.getLayers() - 1; OTSHashAddress otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withLayerAddress(rootLayerIndex) .build(); /* store BDS instance of root xmss instance */ BDS bdsRoot = new BDS(xmssParams, privateKey.getPublicSeed(), privateKey.getSecretKeySeed(), otsHashAddress); XMSSNode root = bdsRoot.getRoot(); privateKey.getBDSState().put(rootLayerIndex, bdsRoot); /* set XMSS^MT root / create public key */ privateKey = new XMSSMTPrivateKeyParameters.Builder(params).withSecretKeySeed(privateKey.getSecretKeySeed()) .withSecretKeyPRF(privateKey.getSecretKeyPRF()).withPublicSeed(privateKey.getPublicSeed()) .withRoot(root.getValue()).withBDSState(privateKey.getBDSState()).build(); publicKey = new XMSSMTPublicKeyParameters.Builder(params).withRoot(root.getValue()) .withPublicSeed(privateKey.getPublicSeed()).build(); return new AsymmetricCipherKeyPair(publicKey, privateKey); } private XMSSMTPrivateKeyParameters generatePrivateKey(BDSStateMap bdsState) { int n = params.getDigestSize(); byte[] secretKeySeed = new byte[n]; prng.nextBytes(secretKeySeed); byte[] secretKeyPRF = new byte[n]; prng.nextBytes(secretKeyPRF); byte[] publicSeed = new byte[n]; prng.nextBytes(publicSeed); XMSSMTPrivateKeyParameters privateKey = null; privateKey = new XMSSMTPrivateKeyParameters.Builder(params).withSecretKeySeed(secretKeySeed) .withSecretKeyPRF(secretKeyPRF).withPublicSeed(publicSeed) .withBDSState(bdsState).build(); return privateKey; } }