private BDS(BDS last, Digest digest) { this.wotsPlus = new WOTSPlus(new WOTSPlusParameters(digest)); this.treeHeight = last.treeHeight; this.k = last.k; this.root = last.root; this.authenticationPath = new ArrayList<XMSSNode>(); // note use of addAll to avoid serialization issues this.authenticationPath.addAll(last.authenticationPath); this.retain = last.retain; this.stack = new Stack<XMSSNode>(); // note use of addAll to avoid serialization issues this.stack.addAll(last.stack); this.treeHashInstances = last.treeHashInstances; this.keep = new TreeMap<Integer, XMSSNode>(last.keep); this.index = last.index; this.used = last.used; this.validate(); }
/** * Getter private key. * * @return WOTS+ private key. */ protected WOTSPlusPrivateKeyParameters getPrivateKey() { byte[][] privateKey = new byte[params.getLen()][]; for (int i = 0; i < privateKey.length; i++) { privateKey[i] = expandSecretKeySeed(i); } return new WOTSPlusPrivateKeyParameters(params, privateKey); }
public void init(boolean forSigning, CipherParameters param) { if (forSigning) { initSign = true; hasGenerated = false; privateKey = (XMSSPrivateKeyParameters)param; nextKeyGenerator = privateKey; params = privateKey.getParameters(); khf = params.getWOTSPlus().getKhf(); } else { initSign = false; publicKey = (XMSSPublicKeyParameters)param; params = publicKey.getParameters(); khf = params.getWOTSPlus().getKhf(); } }
private WOTSPlusSignature wotsSign(byte[] messageDigest, OTSHashAddress otsHashAddress) { if (messageDigest.length != params.getDigestSize()) { throw new IllegalArgumentException("size of messageDigest needs to be equal to size of digest"); } if (otsHashAddress == null) { throw new NullPointerException("otsHashAddress == null"); } /* (re)initialize WOTS+ instance */ wotsPlus.importKeys(wotsPlus.getWOTSPlusSecretKey(privateKey.getSecretKeySeed(), otsHashAddress), privateKey.getPublicSeed()); /* create WOTS+ signature */ return wotsPlus.sign(messageDigest, otsHashAddress); }
byte[][] tmpPublicKey = getPublicKeyFromSignature(messageDigest, signature, otsHashAddress).toByteArray(); return XMSSUtil.areEqual(tmpPublicKey, getPublicKey(otsHashAddress).toByteArray()) ? true : false;
wotsPlus.importKeys(wotsPlus.getWOTSPlusSecretKey(secretSeed, otsHashAddress), publicSeed); WOTSPlusPublicKeyParameters wotsPlusPublicKey = wotsPlus.getPublicKey(otsHashAddress); lTreeAddress = (LTreeAddress)new LTreeAddress.Builder().withLayerAddress(lTreeAddress.getLayerAddress()) .withTreeAddress(lTreeAddress.getTreeAddress()).withLTreeAddress(index) wotsPlus.importKeys(wotsPlus.getWOTSPlusSecretKey(secretSeed, otsHashAddress), publicSeed); XMSSNode node = XMSSNodeUtil.randomizeHash(wotsPlus, authenticationPath.get(tau - 1), keep.get(tau - 1), hashTreeAddress); node = new XMSSNode(node.getHeight() + 1, node.getValue());
List<Integer> baseWMessage = convertToBaseW(messageDigest, params.getWinternitzParameter(), params.getLen1()); int len2Bytes = (int)Math .ceil((double)(params.getLen2() * XMSSUtil.log2(params.getWinternitzParameter())) / 8); List<Integer> baseWChecksum = convertToBaseW(XMSSUtil.toBytesBigEndian(checksum, len2Bytes), params.getWinternitzParameter(), params.getLen2()); .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build(); signature[i] = chain(expandSecretKeySeed(i), 0, baseWMessage.get(i), otsHashAddress);
/** * Getter digest size. * * @return Digest size. */ public int getDigestSize() { return wotsPlus.getParams().getDigestSize(); }
byte[] publicSeed = wotsPlus.getPublicSeed(); byte[] key = wotsPlus.getKhf().PRF(publicSeed, address.toByteArray()); byte[] bitmask0 = wotsPlus.getKhf().PRF(publicSeed, address.toByteArray()); byte[] bitmask1 = wotsPlus.getKhf().PRF(publicSeed, address.toByteArray()); int n = wotsPlus.getParams().getDigestSize(); byte[] tmpMask = new byte[2 * n]; for (int i = 0; i < n; i++) byte[] out = wotsPlus.getKhf().H(key, tmpMask); return new XMSSNode(left.getHeight(), out);
byte[] messageDigest = wotsPlus.getKhf().HMsg(concatenated, message); wotsPlus.importKeys(new byte[params.getDigestSize()], publicKey.getPublicSeed());
/** * XMSS Constructor... * * @param height Height of tree. * @param digest Digest to use. */ public XMSSParameters(int height, Digest digest) { super(); if (height < 2) { throw new IllegalArgumentException("height must be >= 2"); } if (digest == null) { throw new NullPointerException("digest == null"); } wotsPlus = new WOTSPlus(new WOTSPlusParameters(digest)); this.height = height; this.k = determineMinK(); oid = DefaultXMSSOid.lookup(getDigest().getAlgorithmName(), getDigestSize(), getWinternitzParameter(), wotsPlus.getParams().getLen(), height); /* * if (oid == null) { throw new InvalidParameterException(); } */ }
List<Integer> baseWMessage = convertToBaseW(messageDigest, params.getWinternitzParameter(), params.getLen1()); int len2Bytes = (int)Math .ceil((double)(params.getLen2() * XMSSUtil.log2(params.getWinternitzParameter())) / 8); List<Integer> baseWChecksum = convertToBaseW(XMSSUtil.toBytesBigEndian(checksum, len2Bytes), params.getWinternitzParameter(), params.getLen2()); .withHashAddress(otsHashAddress.getHashAddress()).withKeyAndMask(otsHashAddress.getKeyAndMask()) .build(); publicKey[i] = chain(signature.toByteArray()[i], baseWMessage.get(i), params.getWinternitzParameter() - 1 - baseWMessage.get(i), otsHashAddress);
/** * 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); } }
OTSHashAddress otsHashAddress, int indexLeaf) if (messageDigest.length != wotsPlus.getParams().getDigestSize()) WOTSPlusPublicKeyParameters wotsPlusPK = wotsPlus.getPublicKeyFromSignature(messageDigest, signature.getWOTSPlusSignature(), otsHashAddress); XMSSNode[] node = new XMSSNode[2];
byte[] tmp = chain(startHash, startIndex, steps - 1, otsHashAddress); otsHashAddress = (OTSHashAddress)new OTSHashAddress.Builder() .withLayerAddress(otsHashAddress.getLayerAddress()).withTreeAddress(otsHashAddress.getTreeAddress())
/** * Generate a WOTS+ signature on a message without the corresponding * authentication path * * @param messageDigest Message digest of length n. * @param otsHashAddress OTS hash address. * @return XMSS signature. */ protected WOTSPlusSignature wotsSign(byte[] messageDigest, OTSHashAddress otsHashAddress) { if (messageDigest.length != params.getDigestSize()) { throw new IllegalArgumentException("size of messageDigest needs to be equal to size of digest"); } if (otsHashAddress == null) { throw new NullPointerException("otsHashAddress == null"); } /* (re)initialize WOTS+ instance */ wotsPlus.importKeys(wotsPlus.getWOTSPlusSecretKey(privateKey.getSecretKeySeed(), otsHashAddress), getPublicSeed()); /* create WOTS+ signature */ return wotsPlus.sign(messageDigest, otsHashAddress); }
wotsPlus.importKeys(wotsPlus.getWOTSPlusSecretKey(secretSeed, otsHashAddress), publicSeed); WOTSPlusPublicKeyParameters wotsPlusPublicKey = wotsPlus.getPublicKey(otsHashAddress); lTreeAddress = (LTreeAddress)new LTreeAddress.Builder().withLayerAddress(lTreeAddress.getLayerAddress()) .withTreeAddress(lTreeAddress.getTreeAddress()).withLTreeAddress(indexLeaf)
/** * Getter Winternitz parameter. * * @return Winternitz parameter. */ public int getWinternitzParameter() { return wotsPlus.getParams().getWinternitzParameter(); }
byte[] random = wotsPlus.getKhf().PRF(privateKey.getSecretKeyPRF(), XMSSUtil.toBytesBigEndian(globalIndex, 32)); byte[] concatenated = Arrays.concatenate(random, privateKey.getRoot(), XMSSUtil.toBytesBigEndian(globalIndex, params.getDigestSize())); byte[] messageDigest = wotsPlus.getKhf().HMsg(concatenated, message); wotsPlus.importKeys(new byte[params.getDigestSize()], privateKey.getPublicSeed());
private WOTSPlusSignature wotsSign(byte[] messageDigest, OTSHashAddress otsHashAddress) { if (messageDigest.length != params.getDigestSize()) { throw new IllegalArgumentException("size of messageDigest needs to be equal to size of digest"); } if (otsHashAddress == null) { throw new NullPointerException("otsHashAddress == null"); } /* (re)initialize WOTS+ instance */ params.getWOTSPlus().importKeys(params.getWOTSPlus().getWOTSPlusSecretKey(privateKey.getSecretKeySeed(), otsHashAddress), privateKey.getPublicSeed()); /* create WOTS+ signature */ return params.getWOTSPlus().sign(messageDigest, otsHashAddress); } }