.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(i) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask())
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(index).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask())
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(i) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask())
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(indexLeaf).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask())
otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withLayerAddress(layer) .withTreeAddress(indexTree).withOTSAddress(indexLeaf).build();
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(nextIndex).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask())
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(startIndex + steps - 1).withKeyAndMask(0).build(); byte[] key = khf.PRF(publicSeed, otsHashAddress.toByteArray()); otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder() .withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(1).build();
otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withLayerAddress(layer) .withTreeAddress(indexTree).withOTSAddress(indexLeaf).build();
indexTree = XMSSUtil.getTreeIndex(indexTree, xmssHeight); otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withLayerAddress(layer) .withTreeAddress(indexTree).withOTSAddress(indexLeaf).build();
/** * Calculates a new public key based on the state of secretKeySeed, * publicSeed and otsHashAddress. * * @param otsHashAddress OTS hash address for randomization. * @return WOTS+ public key. */ protected WOTSPlusPublicKeyParameters getPublicKey(OTSHashAddress otsHashAddress) { if (otsHashAddress == null) { throw new NullPointerException("otsHashAddress == null"); } byte[][] publicKey = new byte[params.getLen()][]; /* derive public key from secretKeySeed */ for (int i = 0; i < params.getLen(); i++) { otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder() .withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(i) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build(); publicKey[i] = chain(expandSecretKeySeed(i), 0, params.getWinternitzParameter() - 1, otsHashAddress); } return new WOTSPlusPublicKeyParameters(params, publicKey); } }
/** * 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); }
/** * Derive WOTS+ secret key for specific index as in XMSS ref impl Andreas * Huelsing. * * @param otsHashAddress * @return WOTS+ secret key at index. */ protected byte[] getWOTSPlusSecretKey(byte[] secretKeySeed, OTSHashAddress otsHashAddress) { otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder() .withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress()) .withOTSAddress(otsHashAddress.getOTSAddress()).build(); return khf.PRF(secretKeySeed, otsHashAddress.toByteArray()); }