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(); }
/** * Constructs a new WOTS+ one-time signature system based on the given WOTS+ * parameters. * * @param params Parameters for WOTSPlus object. */ protected WOTSPlus(WOTSPlusParameters params) { super(); if (params == null) { throw new NullPointerException("params == null"); } this.params = params; int n = params.getDigestSize(); khf = new KeyedHashFunctions(params.getDigest(), n); secretKeySeed = new byte[n]; publicSeed = new byte[n]; }
if (messageDigest.length != params.getDigestSize()) List<Integer> baseWMessage = convertToBaseW(messageDigest, params.getWinternitzParameter(), params.getLen1()); for (int i = 0; i < params.getLen1(); i++) checksum += params.getWinternitzParameter() - 1 - baseWMessage.get(i); checksum <<= (8 - ((params.getLen2() * XMSSUtil.log2(params.getWinternitzParameter())) % 8)); 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()); byte[][] publicKey = new byte[params.getLen()][]; for (int i = 0; i < params.getLen(); i++) .build(); publicKey[i] = chain(signature.toByteArray()[i], baseWMessage.get(i), params.getWinternitzParameter() - 1 - baseWMessage.get(i), otsHashAddress);
protected WOTSPlusPrivateKeyParameters(WOTSPlusParameters params, byte[][] privateKey) { super(); if (params == null) { throw new NullPointerException("params == null"); } if (privateKey == null) { throw new NullPointerException("privateKey == null"); } if (XMSSUtil.hasNullPointer(privateKey)) { throw new NullPointerException("privateKey byte array == null"); } if (privateKey.length != params.getLen()) { throw new IllegalArgumentException("wrong privateKey format"); } for (int i = 0; i < privateKey.length; i++) { if (privateKey[i].length != params.getDigestSize()) { throw new IllegalArgumentException("wrong privateKey format"); } } this.privateKey = XMSSUtil.cloneArray(privateKey); }
/** * Derive private key at index from secret key seed. * * @param index Index. * @return Private key at index. */ private byte[] expandSecretKeySeed(int index) { if (index < 0 || index >= params.getLen()) { throw new IllegalArgumentException("index out of bounds"); } return khf.PRF(secretKeySeed, XMSSUtil.toBytesBigEndian(index, 32)); }
/** * 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(); } */ }
/** * Getter digest size. * * @return Digest size. */ public int getDigestSize() { return wotsPlus.getParams().getDigestSize(); }
/** * 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); } }
int n = params.getDigestSize(); if (startHash == null) if ((startIndex + steps) > params.getWinternitzParameter() - 1)
/** * Getter Winternitz parameter. * * @return Winternitz parameter. */ public int getWinternitzParameter() { return wotsPlus.getParams().getWinternitzParameter(); }
protected Digest getDigest() { return wotsPlus.getParams().getDigest(); }
protected WOTSPlusSignature(WOTSPlusParameters params, byte[][] signature) { super(); if (params == null) { throw new NullPointerException("params == null"); } if (signature == null) { throw new NullPointerException("signature == null"); } if (XMSSUtil.hasNullPointer(signature)) { throw new NullPointerException("signature byte array == null"); } if (signature.length != params.getLen()) { throw new IllegalArgumentException("wrong signature size"); } for (int i = 0; i < signature.length; i++) { if (signature[i].length != params.getDigestSize()) { throw new IllegalArgumentException("wrong signature format"); } } this.signature = XMSSUtil.cloneArray(signature); }
protected int getLen() { return xmssParams.getWOTSPlus().getParams().getLen(); } }
/** * Import keys to WOTS+ instance. * * @param secretKeySeed Secret key seed. * @param publicSeed Public seed. */ void importKeys(byte[] secretKeySeed, byte[] publicSeed) { if (secretKeySeed == null) { throw new NullPointerException("secretKeySeed == null"); } if (secretKeySeed.length != params.getDigestSize()) { throw new IllegalArgumentException("size of secretKeySeed needs to be equal to size of digest"); } if (publicSeed == null) { throw new NullPointerException("publicSeed == null"); } if (publicSeed.length != params.getDigestSize()) { throw new IllegalArgumentException("size of publicSeed needs to be equal to size of digest"); } this.secretKeySeed = secretKeySeed; this.publicSeed = publicSeed; }
if (messageDigest.length != params.getDigestSize()) List<Integer> baseWMessage = convertToBaseW(messageDigest, params.getWinternitzParameter(), params.getLen1()); for (int i = 0; i < params.getLen1(); i++) checksum += params.getWinternitzParameter() - 1 - baseWMessage.get(i); checksum <<= (8 - ((params.getLen2() * XMSSUtil.log2(params.getWinternitzParameter())) % 8)); 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()); byte[][] signature = new byte[params.getLen()][]; for (int i = 0; i < params.getLen(); i++)
protected WOTSPlusPublicKeyParameters(WOTSPlusParameters params, byte[][] publicKey) { super(); if (params == null) { throw new NullPointerException("params == null"); } if (publicKey == null) { throw new NullPointerException("publicKey == null"); } if (XMSSUtil.hasNullPointer(publicKey)) { throw new NullPointerException("publicKey byte array == null"); } if (publicKey.length != params.getLen()) { throw new IllegalArgumentException("wrong publicKey size"); } for (int i = 0; i < publicKey.length; i++) { if (publicKey[i].length != params.getDigestSize()) { throw new IllegalArgumentException("wrong publicKey format"); } } this.publicKey = XMSSUtil.cloneArray(publicKey); }
/** * 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); }
if (messageDigest.length != params.getDigestSize())
public void init(boolean forSigning, CipherParameters param) { if (forSigning) { initSign = true; hasGenerated = false; privateKey = (XMSSMTPrivateKeyParameters)param; nextKeyGenerator = privateKey; params = privateKey.getParameters(); xmssParams = params.getXMSSParameters(); } else { initSign = false; publicKey = (XMSSMTPublicKeyParameters)param; params = publicKey.getParameters(); xmssParams = params.getXMSSParameters(); } wotsPlus = new WOTSPlus(new WOTSPlusParameters(params.getDigest())); }
public byte[] toByteArray() { /* signature || authentication path */ int n = params.getDigestSize(); int signatureSize = params.getWOTSPlus().getParams().getLen() * n; int authPathSize = params.getHeight() * n; int totalSize = signatureSize + authPathSize; byte[] out = new byte[totalSize]; int position = 0; /* copy signature */ byte[][] signature = this.wotsPlusSignature.toByteArray(); for (int i = 0; i < signature.length; i++) { XMSSUtil.copyBytesAtOffset(out, signature[i], position); position += n; } /* copy authentication path */ for (int i = 0; i < authPath.size(); i++) { byte[] value = authPath.get(i).getValue(); XMSSUtil.copyBytesAtOffset(out, value, position); position += n; } return out; }