.withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(i) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build();
OTSHashAddress otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withOTSAddress(index).build(); WOTSPlusSignature wotsPlusSignature = wotsSign(messageDigest, otsHashAddress); XMSSSignature signature = (XMSSSignature)new XMSSSignature.Builder(params).withIndex(index).withRandom(random)
.withOTSAddress(index).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build();
.withOTSAddress(indexLeaf).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build();
.withOTSAddress(indexLeaf).build(); .withTreeAddress(indexTree).withOTSAddress(indexLeaf).build();
.withOTSAddress(nextIndex).withChainAddress(otsHashAddress.getChainAddress()) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build();
otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder() .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(); byte[] bitmask = khf.PRF(publicSeed, otsHashAddress.toByteArray());
.withOTSAddress(otsHashAddress.getOTSAddress()).withChainAddress(i) .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build();
.withOTSAddress(indexLeaf).build(); .withTreeAddress(indexTree).withOTSAddress(indexLeaf).build();
.withOTSAddress(indexLeaf).build(); .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); } }
public boolean verifySignature(byte[] message, byte[] signature) { /* parse signature and public key */ XMSSSignature sig = new XMSSSignature.Builder(params).withSignature(signature).build(); /* generate public key */ int index = sig.getIndex(); /* reinitialize WOTS+ object */ params.getWOTSPlus().importKeys(new byte[params.getDigestSize()], publicKey.getPublicSeed()); /* create message digest */ byte[] concatenated = Arrays.concatenate(sig.getRandom(), publicKey.getRoot(), XMSSUtil.toBytesBigEndian(index, params.getDigestSize())); byte[] messageDigest = khf.HMsg(concatenated, message); int xmssHeight = params.getHeight(); int indexLeaf = XMSSUtil.getLeafIndex(index, xmssHeight); /* get root from signature */ OTSHashAddress otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder().withOTSAddress(index).build(); XMSSNode rootNodeFromSignature = XMSSVerifierUtil.getRootNodeFromSignature(params.getWOTSPlus(), xmssHeight, messageDigest, sig, otsHashAddress, indexLeaf); return Arrays.constantTimeAreEqual(rootNodeFromSignature.getValue(), publicKey.getRoot()); }
/** * 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()); }