org.bouncycastle.pqc.crypto.xmss.XMSSVerifierUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcprov-jdk15on Show documentation
Show all versions of bcprov-jdk15on Show documentation
The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5 and up.
The newest version!
package org.bouncycastle.pqc.crypto.xmss;
class XMSSVerifierUtil
{
/**
* Compute a root node from a tree signature.
*
* @param messageDigest Message digest.
* @param signature XMSS signature.
* @return Root node calculated from signature.
*/
static XMSSNode getRootNodeFromSignature(WOTSPlus wotsPlus, int height, byte[] messageDigest, XMSSReducedSignature signature,
OTSHashAddress otsHashAddress, int indexLeaf)
{
if (messageDigest.length != wotsPlus.getParams().getTreeDigestSize())
{
throw new IllegalArgumentException("size of messageDigest needs to be equal to size of digest");
}
if (signature == null)
{
throw new NullPointerException("signature == null");
}
if (otsHashAddress == null)
{
throw new NullPointerException("otsHashAddress == null");
}
/* prepare adresses */
LTreeAddress lTreeAddress = (LTreeAddress)new LTreeAddress.Builder()
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress())
.withLTreeAddress(otsHashAddress.getOTSAddress()).build();
HashTreeAddress hashTreeAddress = (HashTreeAddress)new HashTreeAddress.Builder()
.withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress())
.withTreeIndex(otsHashAddress.getOTSAddress()).build();
/*
* calculate WOTS+ public key and compress to obtain original leaf hash
*/
WOTSPlusPublicKeyParameters wotsPlusPK = wotsPlus.getPublicKeyFromSignature(messageDigest,
signature.getWOTSPlusSignature(), otsHashAddress);
XMSSNode[] node = new XMSSNode[2];
node[0] = XMSSNodeUtil.lTree(wotsPlus, wotsPlusPK, lTreeAddress);
for (int k = 0; k < height; k++)
{
hashTreeAddress = (HashTreeAddress)new HashTreeAddress.Builder()
.withLayerAddress(hashTreeAddress.getLayerAddress())
.withTreeAddress(hashTreeAddress.getTreeAddress()).withTreeHeight(k)
.withTreeIndex(hashTreeAddress.getTreeIndex()).withKeyAndMask(hashTreeAddress.getKeyAndMask())
.build();
if (Math.floor(indexLeaf / (1 << k)) % 2 == 0)
{
hashTreeAddress = (HashTreeAddress)new HashTreeAddress.Builder()
.withLayerAddress(hashTreeAddress.getLayerAddress())
.withTreeAddress(hashTreeAddress.getTreeAddress())
.withTreeHeight(hashTreeAddress.getTreeHeight())
.withTreeIndex(hashTreeAddress.getTreeIndex() / 2)
.withKeyAndMask(hashTreeAddress.getKeyAndMask()).build();
node[1] = XMSSNodeUtil.randomizeHash(wotsPlus, node[0], signature.getAuthPath().get(k), hashTreeAddress);
node[1] = new XMSSNode(node[1].getHeight() + 1, node[1].getValue());
}
else
{
hashTreeAddress = (HashTreeAddress)new HashTreeAddress.Builder()
.withLayerAddress(hashTreeAddress.getLayerAddress())
.withTreeAddress(hashTreeAddress.getTreeAddress())
.withTreeHeight(hashTreeAddress.getTreeHeight())
.withTreeIndex((hashTreeAddress.getTreeIndex() - 1) / 2)
.withKeyAndMask(hashTreeAddress.getKeyAndMask()).build();
node[1] = XMSSNodeUtil.randomizeHash(wotsPlus, signature.getAuthPath().get(k), node[0], hashTreeAddress);
node[1] = new XMSSNode(node[1].getHeight() + 1, node[1].getValue());
}
node[0] = node[1];
}
return node[0];
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy