public XMSSPrivateKeyParameters build() { return new XMSSPrivateKeyParameters(this); } }
protected void setIndex(int index) { privateKey = new XMSSPrivateKeyParameters.Builder(params) .withSecretKeySeed(privateKey.getSecretKeySeed()).withSecretKeyPRF(privateKey.getSecretKeyPRF()) .withPublicSeed(privateKey.getPublicSeed()).withRoot(privateKey.getRoot()) .withBDSState(privateKey.getBDSState()).build(); }
public long getUsagesRemaining() { return (1L << this.getParameters().getHeight()) - this.getIndex(); }
if (privateKey.getBDSState().getAuthenticationPath().isEmpty()) int index = privateKey.getIndex(); if (!XMSSUtil.isIndexValid(params.getHeight(), index)) byte[] random = khf.PRF(privateKey.getSecretKeyPRF(), XMSSUtil.toBytesBigEndian(index, 32)); byte[] concatenated = Arrays.concatenate(random, privateKey.getRoot(), XMSSUtil.toBytesBigEndian(index, params.getDigestSize())); byte[] messageDigest = khf.HMsg(concatenated, message); WOTSPlusSignature wotsPlusSignature = wotsSign(messageDigest, otsHashAddress); XMSSSignature signature = (XMSSSignature)new XMSSSignature.Builder(params).withIndex(index).withRandom(random) .withWOTSPlusSignature(wotsPlusSignature).withAuthPath(privateKey.getBDSState().getAuthenticationPath()) .build(); privateKey = nextKeyGenerator.getNextKey(); nextKeyGenerator = privateKey;
protected void setRoot(byte[] root) { privateKey = new XMSSPrivateKeyParameters.Builder(params) .withSecretKeySeed(privateKey.getSecretKeySeed()).withSecretKeyPRF(privateKey.getSecretKeyPRF()) .withPublicSeed(getPublicSeed()).withRoot(root).withBDSState(privateKey.getBDSState()).build(); publicKey = new XMSSPublicKeyParameters.Builder(params).withRoot(root).withPublicSeed(getPublicSeed()) .build(); }
void importState(XMSSPrivateKeyParameters privateKey, XMSSPublicKeyParameters publicKey) { if (!Arrays.areEqual(privateKey.getRoot(), publicKey.getRoot())) { throw new IllegalStateException("root of private key and public key do not match"); } if (!Arrays.areEqual(privateKey.getPublicSeed(), publicKey.getPublicSeed())) { throw new IllegalStateException("public seed of private key and public key do not match"); } /* import */ this.privateKey = privateKey; this.publicKey = publicKey; wotsPlus.importKeys(new byte[params.getDigestSize()], this.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); } }
private static XMSSPrivateKey xmssCreateKeyStructure(XMSSPrivateKeyParameters keyParams) { byte[] keyData = keyParams.toByteArray(); int n = keyParams.getParameters().getDigestSize(); int totalHeight = keyParams.getParameters().getHeight(); int indexSize = 4; int secretKeySize = n; int secretKeyPRFSize = n; int publicSeedSize = n; int rootSize = n; int position = 0; int index = (int)XMSSUtil.bytesToXBigEndian(keyData, position, indexSize); if (!XMSSUtil.isIndexValid(totalHeight, index)) { throw new IllegalArgumentException("index out of bounds"); } position += indexSize; byte[] secretKeySeed = XMSSUtil.extractBytesAtOffset(keyData, position, secretKeySize); position += secretKeySize; byte[] secretKeyPRF = XMSSUtil.extractBytesAtOffset(keyData, position, secretKeyPRFSize); position += secretKeyPRFSize; byte[] publicSeed = XMSSUtil.extractBytesAtOffset(keyData, position, publicSeedSize); position += publicSeedSize; byte[] root = XMSSUtil.extractBytesAtOffset(keyData, position, rootSize); position += rootSize; /* import BDS state */ byte[] bdsStateBinary = XMSSUtil.extractBytesAtOffset(keyData, position, keyData.length - position); return new XMSSPrivateKey(index, secretKeySeed, secretKeyPRF, publicSeed, root, bdsStateBinary); }
new XMSSKeyParams(keyParams.getParameters().getHeight(), Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest())));
/** * Getter XMSS public seed. * * @return Public seed. */ public byte[] getPublicSeed() { return privateKey.getPublicSeed(); }
/** * Getter XMSS index. * * @return Index. */ public int getIndex() { return privateKey.getIndex(); }
public int getHeight() { return keyParams.getParameters().getHeight(); }
/** * Getter XMSS root. * * @return Root of binary tree. */ public byte[] getRoot() { return privateKey.getRoot(); }
public AsymmetricKeyParameter getUpdatedPrivateKey() { // if we've generated a signature return the last private key generated // if we've only initialised leave it in place and return the next one instead. if (hasGenerated) { XMSSPrivateKeyParameters privKey = privateKey; privateKey = null; nextKeyGenerator = null; return privKey; } else { XMSSPrivateKeyParameters privKey = nextKeyGenerator.getNextKey(); nextKeyGenerator = null; return privKey; } }
/** * 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); }
protected void setPublicSeed(byte[] publicSeed) { privateKey = new XMSSPrivateKeyParameters.Builder(params) .withSecretKeySeed(privateKey.getSecretKeySeed()).withSecretKeyPRF(privateKey.getSecretKeyPRF()) .withPublicSeed(publicSeed).withRoot(getRoot()).withBDSState(privateKey.getBDSState()).build(); publicKey = new XMSSPublicKeyParameters.Builder(params).withRoot(getRoot()).withPublicSeed(publicSeed) .build(); wotsPlus.importKeys(new byte[params.getDigestSize()], publicSeed); }
XMSSPublicKeyParameters tmpPublicKey = new XMSSPublicKeyParameters.Builder(params).withPublicKey(publicKey) .build(); if (!Arrays.areEqual(tmpPrivateKey.getRoot(), tmpPublicKey.getRoot())) if (!Arrays.areEqual(tmpPrivateKey.getPublicSeed(), tmpPublicKey.getPublicSeed())) wotsPlus.importKeys(new byte[params.getDigestSize()], this.privateKey.getPublicSeed());
/** * Generate a new XMSS private key / public key pair. */ public void generateKeys() { XMSSKeyPairGenerator kpGen = new XMSSKeyPairGenerator(); kpGen.init(new XMSSKeyGenerationParameters(getParams(), prng)); AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); privateKey = (XMSSPrivateKeyParameters)kp.getPrivate(); publicKey = (XMSSPublicKeyParameters)kp.getPublic(); wotsPlus.importKeys(new byte[params.getDigestSize()], this.privateKey.getPublicSeed()); }
public XMSSPrivateKeyParameters getNextKey() { /* prepare authentication path for next leaf */ int treeHeight = this.params.getHeight(); if (this.getIndex() < ((1 << treeHeight) - 1)) { return new XMSSPrivateKeyParameters.Builder(params) .withSecretKeySeed(secretKeySeed).withSecretKeyPRF(secretKeyPRF) .withPublicSeed(publicSeed).withRoot(root) .withBDSState(bdsState.getNextState(publicSeed, secretKeySeed, (OTSHashAddress)new OTSHashAddress.Builder().build())).build(); } else { return new XMSSPrivateKeyParameters.Builder(params) .withSecretKeySeed(secretKeySeed).withSecretKeyPRF(secretKeyPRF) .withPublicSeed(publicSeed).withRoot(root) .withBDSState(new BDS(params, getIndex() + 1)).build(); // no more nodes left. } }
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(); } }