openhub.net
Black Duck Software, Inc.
Open Hub
Follow @
OH
Sign In
Join Now
Projects
People
Organizations
Tools
Blog
BDSA
Projects
People
Projects
Organizations
B
bouncy Castle Java
Settings
1
I Use This!
×
Login Required
Log in to Open Hub
Remember Me
Very High Activity
Commits
: Listings
Analyzed
about 19 hours
ago. based on code collected
2 days
ago.
Nov 06, 2025 — Nov 06, 2026
Showing page 20 of 806
Search / Filter on:
Commit Message
Contributor
Files Modified
Lines Added
Lines Removed
Code Location
Date
Take over the collections a decoder built rather than copying them out from under it. The field by field BDS constructor cloned all five - the authentication path, the retain map and every queue in it, the stack, a clone of each tree hash instance, and the keep map - and its production caller is BDSStateCodec.readBDS, which assembles each of them a node at a time out of the stream it is reading and holds the only reference to what it hands over. So every private key decode built the traversal state twice and dropped the first one: 950 of the 8113 bytes an h = 10 SHA-256 key decode allocates, and 1712 of the 14814 an h = 20 d = 2 XMSS^MT key does, both measured JIT warm over 20000 decodes with the decoded root printed alongside so the two builds are visibly decoding to the same key.
gefeili
More...
2 months ago
Import a placeholder where advancing a BDS state needs the public seed and not the one-time key. The branch nextAuthenticationPath takes when the leaf is a right node hands randomizeHash the node the state kept and the one the path already holds, and randomizeHash reads getPublicSeed() and getKhf() off the WOTS+ instance and nothing else - so the importKeys ahead of it was there for the seed, and the getWOTSPlusSecretKey inside it was a PRF whose result nothing read. The left node branch above it does need the key, because it derives a WOTS+ public key from it.
gefeili
More...
2 months ago
Read a public key's root once per verification rather than at each of the two places a verification wants it. getRoot() hands out a clone - the field is the key's, and a caller that wrote to what it got back would change what every later verification compares against - so asking twice made two n-byte copies of a field that is written at construction and never after. Both verifiers asked twice, for the middle of the H_msg key and then for the comparison at the end, and the signing side beside them already reads its key's root once.
gefeili
More...
2 months ago
Ask hasTraversalState whether a key can sign where the signature methods asked the state directly. The two are the same question and one of them is a public helper with a javadoc saying so, which the signers call before they reach the engine; the engine's own copy of the check reached past it into the state - isAuthenticationPathEmpty() on the lone BDS, isEmpty() on the state map - so what counts as no state was written down in three places for two families. Widening it, and the reason to widen it is that the two families already answer differently, would have meant finding the two private call sites that do not go through the helper their own class declares.
gefeili
More...
2 months ago
Drop the two OTS hash address setters no walk calls, and have the address test write those words the way the walks write them. withChainAddress and withHashAddress had no caller in the tree outside AddressTests: every signing and verification site builds the address with withOTSAddress alone and then steps the chain and hash address words through the encoding it holds, WOTSPlus.chain writing both once per chain step at CHAIN_ADDRESS_OFFSET and HASH_ADDRESS_OFFSET, and getWOTSPlusSecretKey putting them back to zero before each one-time key. So the fields behind the setters were zero in every address this package builds, and toByteArray() wrote two zeros into two bytes of a fresh array that already held them; a reader had to walk every call site to find that out.
gefeili
More...
2 months ago
Ask org.bouncycastle.util.Arrays whether a byte[][] holds a null, rather than walking it here. hasNullPointer was a byte for byte carryover from the deprecated pqc.crypto.xmss copy, and isNullOrContainsNull(Object[]) is the same walk with the same answer for the same argument - a byte[][] is an Object[] - in the class this file already imports for the row comparison the caller goes on to make. The same commit that promoted this file, 9180cbfec6, replaced the method beside it, log2, for exactly this reason and left this one; areEqual is its only caller and there is nowhere else in the package a second one could come from, XMSSUtil being package private.
gefeili
More...
2 months ago
Record that a signer has spent its key from what the signature did to the key, not from having called the engine. hasGenerated is what getUpdatedPrivateKey() reads to decide between handing the key straight back - the engine having already rolled it - and advancing it first, and both signers set it on the line before the engine call. Neither side of that call is the answer. The engine refuses a signature before it touches the key: its "one time key at index N has already signed" check sits ahead of the try whose finally rolls, and it is the one guard the signer does not repeat, so it is reachable with the flag already set. It also rolls the key from that finally once it has started, so a signature that fails part way through leaves a rolled key, and setting the flag after the call would leave that one looking unspent.
gefeili
More...
2 months ago
Compare an XMSS^MT key's two records of its position where it spends a one-time key, not only where it is moved and stored. The key records where it has got to twice - the index field, and the per-layer BDS traversal states - and github #2414 closed that by comparing them wherever the pair could have come apart: the constructor and builder do it, rollKey() does it, and both encoders do it. Signing did not. What it asked instead was isUsed(), which is the other half of the question - whether the layer zero state has already signed where it stands, not whether it is standing where the index says it is - and a state that lags without having signed there answers no to it.
gefeili
More...
2 months ago
Read a state map's top layer under that map's monitor, as every other read of it is. validateRoot() was the one accessor on BDSStateMap that reached bdsState with no synchronized block around it - isEmpty(), getStateMap(), validate(), validateIndex(), get(), put() and update() all take the monitor, and the hardening that gave them one left this one behind. It is not an accessor that runs at a quiet moment: the XMSS^MT key constructor and its builder both call it, and the state map a key is being built around is reachable from a live key through getBDSState(), so the map being read can be one a signature is descending. That signature puts each lazily built layer into the same map as it goes - only the top layer exists at key generation - and an insertion rebalances the TreeMap under the lookup.
gefeili
More...
2 months ago
Say what getEncodedBDSState(BDS) writes, rather than describing the form it reads. Its javadoc called the encoding it produces "the legacy Java-serialized form" and said "nothing generates it any more" - of the one method in this tree that generates it. Both halves of that belong to deserialize(): the legacy names CheckingStream resolves are what nothing writes any more, and the comment there says so correctly, that serialize() has emitted the versioned BDSStateCodec form since the codec was introduced. Carried onto the encoder, it tells a reader that a live key's toByteArray() and the state half of its equals() - which is what reaches this, along with XmssKeyUtil writing a PKCS#8 - go through a path kept only for old keys, so a change made here looks like it can only affect reading them.
gefeili
More...
2 months ago
Compare and hash an XMSS private key in the class that holds the layout it is stored in, rather than writing the same method out once per family. XMSSPrivateKeyParameters and XMSSMTPrivateKeyParameters carried a line for line copy of one equals() and one hashCode() each - the same seven fields in the same order, the same chain joined the same way, the same two monitors taken in the same sequence, and the same hundred lines of javadoc saying why - which is the shape their encodings were in before XMSSPrivateKeyCodec held those. So the comparison goes where the layout is: what a key is compared on is what a key is stored as, the index and the four n-byte fields, and the codec is package private in the same package as both, so nothing here is new public API and the crypto/params/XMSS* excludes the jdk1.4 and jdk1.3 Ant builds carry keep covering it.
gefeili
More...
2 months ago
Move an XMSS private key's equals() and hashCode() onto the key parameters that hold the fields and the monitor, leaving each provider key the delegating line BCLMSPrivateKey already is. The comparison was written out in BCXMSSPrivateKey and BCXMSSMTPrivateKey over the accessors, and none of it belonged there: the fields are the key parameters' own, so each accessor hands back a clone rather than a value that can be held still beside another key's, and the monitor a signature is taken under is the key parameters' own, so the method reached into it from outside with synchronized (keyParams), twice per call, per key. The other stateful family in this tree keeps the same reasoning one layer down - HSSPrivateKeyParameters.equals() takes each key's moving trio under that key's own monitor and BCLMSPrivateKey is keyParams.equals(...) and keyParams.hashCode(), dcaa1ae456 and 658e247fb4, both on main - while XMSSPrivateKeyParameters and XMSSMTPrivateKeyParameters defined neither method at all.
gefeili
More...
2 months ago
Read an XMSS^MT key's index inside the block that encodes its traversal state, so the pair its equals() answers on is a pair that key was in. The method takes each key's monitor twice - once for the index and the usages remaining, once for the state below the field chain - and a signature landing between the two leaves the chain answering on a position its key has already left. All that can do is make it answer false, which is the answer for the instant it read, so what the state comparison is left holding is the position the answer is about. An XMSS state pins that down on its own: the encoding BDSStateCodec writes for a lone BDS opens with the maximum index and the index, so two states that compare equal are two keys at one position with the same usages left. A state map does not - it carries its own maximum index and each layer's position inside its subtree, but the key's global index is the volatile field beside it that rollKey() advances, and toByteArray() was the only thing that ever wrote the two out together.
gefeili
More...
2 months ago
bulk arraycopy in BDS
gefeili
More...
2 months ago
Take the floor of a base 2 logarithm from Integers.bitLength rather than counting the shifts by hand. XMSSUtil.log2 walked n right one bit at a time until what was left was zero, and how many shifts that takes is what org.bouncycastle.util.Integers.bitLength(n) - 1 answers for every n of 1 or more - the same class BDSStateMap and BDSStateCodec already import in this package for valueOf, and one the jdk1.4 overlay carries too. Checked against the loop exhaustively from 1 to 2^24, at 2^k - 1, 2^k and 2^k + 1 for k up to 30 and at Integer.MAX_VALUE, and at each value WOTS+ can ask for: lg(4) and lg(16) for the base w conversion, and lg(len1 * (w - 1)) for the len2 of RFC 8391 sec. 3.1.1, which is 2n * 15 - 720 for the n = 24 of SHAKE256-192, 960 for the n = 32 of SHA-256, SHAKE128 and SHAKE256-256, 1920 for the n = 64 of SHA-512 and SHAKE256, each giving back the len2 of 3 that RFC's parameter tables fix for w = 16.
gefeili
More...
2 months ago
Merge branch 'main' into xmss-promote-crypto-signers-pick
gefeili
More...
2 months ago
Write a BDS state out through the state's own collections rather than a copy of each of them. BDSStateCodec.writeBDS read the traversal state through five defensive-copying accessors - the authentication path, the retain queues, the stack, the tree hash instances and the keep map - and copied the whole state once per encoding in order to iterate it, which costs an h = 10 SHA-256 XMSS key 896 of the 5664 bytes it allocates per getEncoded(), and an h = 20 d = 2 XMSS^MT key 857 of 5825. That is the path a stateful key travels after every signature, and most of it is the eight tree hash instances cloneTreeHashInstances() walks, at 368 bytes, plus the 184 a stack and a keep map that are both empty at index 0 were costing to copy.
gefeili
More...
2 months ago
Ask a BDS state whether it has an authentication path rather than taking a copy of one to measure. Both places that want to know - hasTraversalState(), and the "not initialized" check every XMSS signature makes - said getBDSState().getAuthenticationPath().isEmpty(), and that accessor exists to hand out a copy: a caller that changed the live path would corrupt the signing position, so it builds a list and fills it with the h nodes before anything can ask its size. Neither caller wants the path, and the XMSS^MT side already asks its BDSStateMap the same question with a plain isEmpty(), so the XMSS side gets one too.
gefeili
More...
2 months ago
Measure a signature encoding in one place rather than on both sides of it. All three signature classes wrote their size out twice, once where an encoding is taken apart and once where one is laid down - XMSSReducedSignature len n-byte WOTS+ blocks and h authentication path nodes, XMSSSignature four bytes of index and n of randomizer in front of that, XMSSMTSignature ceil(h/8) and n in front of one reduced signature per layer - so three layouts lived in six places, and a decoder that drifts from its encoder is a length check admitting what the writer never writes, or an array a byte short of what goes in it.
gefeili
More...
2 months ago
Drop XMSSUtil.serialize(Object), which nothing calls. It encodes a BDS state binding its checksum to nothing, by way of serialize(Object, byte[]) with a null public seed, and every writer in this tree hands that method the owning key's seed - so it has had no caller since the binding was introduced for github #2414. XMSSUtil is package private, so the package is the whole of its reach and there is nowhere else a call could come from.
gefeili
More...
2 months ago
Say in a private key's equals() why the field chain answering ahead of the traversal state is not the thing that chain was just joined with | to stop. The two read as the same objection: the chain no longer says which of the seven fields two keys first disagree on, but it does still say whether they agree on all seven, because that is what decides whether the state encoding below it runs at all - so the method has a short answer and a long one and which it took is visible. What makes that different from what | fixed is where the long one is reachable from. Getting to it means having matched both secret seeds, so what its running time says is something a caller had to be holding already to arrive there, and it is the answer the method returns rather than anything behind it; the || chain said which field differed to a caller holding none of them. It is also why the state encoding is left below the chain rather than joined onto it with &, the way the single comparison this chain replaced was joined to the tree digest - that comparison encoded both keys whatever they were and so had nothing left for a short circuit to skip, where joining this one would encode two whole traversal states for every pair of keys that differ. Measured over 20000 comparisons at an h = 10 SHA-256 XMSS key, that is 13096ns against the 419ns the chain answers an unequal pair in, and the unequal pair is the common one: hashCode() is the public key's, so keys taken from one key pair land in one bucket of a Set or a Map and are told apart there by their index, which is the case the paragraph above already reasons about. Documentation only, the same paragraph in both key classes. The provider's XMSSTest at 33 and XMSSMTTest at 29, and checkstyleMain on prov.
gefeili
More...
2 months ago
Read a private key's index and its usages remaining together, under that key's own monitor. Both come from state that a signature replaces while holding that monitor - for XMSS the BDS the two are derived from, for XMSS^MT the index field and the state map beside it - and equals() read them one at a time, getUsagesRemaining() taking the monitor and getIndex() not taking it at all, so a signature landing between the two left the method holding an index from one side of it and a usage count from the other, a pairing the key was never in. Each key's two are now read in one block, the way the traversal state encoding at the end of the method already was.
gefeili
More...
2 months ago
Evaluate the whole of a private key's equals() field chain whatever the two keys are. The seven comparisons in front of the traversal state were joined with ||, so the chain stopped at the first field the two keys disagree on: two keys differing in their tree digest are answered after one comparison and two differing only in their secretKeyPRF after seven, and how long the method takes is what says which. Four of the seven are the constant time comparisons this method has and two of those four are the secret seeds, so short circuiting hands back through the method's own running time the thing comparing those fields in constant time is there to withhold. Joining with | instead evaluates all seven and answers the same thing: the operands are a tree digest every constructor sets, two numbers, and Arrays.constantTimeAreEqual, which answers false for a null argument rather than raising, so not one of them can throw or carries a side effect that the order of evaluation matters to. It is also what this method said before the field chain replaced it - a single & of the tree digest against a constant time comparison of two whole key encodings - the & having been put there along with the provider's other secret bearing equals() when the && they all had was found to leak this way. The provider's XMSSTest at 32 and XMSSMTTest at 28, and checkstyleMain on prov.
gefeili
More...
2 months ago
Drop XMSSEngine.isIndexValid, which nothing calls. XMSSEngine is the one public door into a package whose internals - XMSSUtil, XMSSAddress, OTSHashAddress - are all package private, so every method on it is API this branch mints, and this one is a pass-through to XMSSUtil.isIndexValid that no caller ever went through. The only place wanting that bound is XMSSMTSignature, which shares the package and calls XMSSUtil directly; everything outside wants isStoredIndexValid instead - the one leaf wider bound a stored key's index field has to satisfy - which is what XmssKeyUtil asks for twice and XMSSPrivateKeyCodec once. What it published was not quite what was behind it either: the javadoc said 0 <= index < 2^height, where XMSSUtil throws IllegalStateException on a negative index rather than answering false. All that is left of it is the sentence isStoredIndexValid used it to state the tighter bound with, which now states that bound rather than linking to a method that is gone. crypto.signers.xmss.AllTests at 93, and checkstyleMain on core and prov.
gefeili
More...
2 months ago
Carry a private key's PKCS#8 attributes onto the key that replaces it, rather than dropping them the first time it signs or is sharded. BCXMSSPrivateKey and BCXMSSMTPrivateKey take their attributes from the PrivateKeyInfo they were loaded from and write them back out in getEncoded(), and both have a two-argument constructor - tree digest and key parameters - that sets none. That constructor is right for the one caller with no key behind it, key pair generation, and every other caller is re-wrapping a key that already exists: extractKeyShard() on the key classes themselves, and getUpdatedPrivateKey() on the two signature SPIs, which is what the StateAwareSignature contract says to call to get the advanced key back after signing. So a key read from a PKCS#8 carrying attributes lost them on its first signature and on its first shard, silently - the key is otherwise the same key, and the encoding it produces is still well formed, just without the attributes it came with.
gefeili
More...
2 months ago
Report a key height or layer count too wide for an int as a key that will not decode, rather than letting it out of the factory unchecked. The legacy XMSSKeyParams and XMSSMTKeyParams take those fields with ASN1Integer.intValueExact(), which throws ArithmeticException when the INTEGER carries more than four content octets. ArithmeticException is a sibling of IllegalArgumentException rather than a subclass of it, so it went past every block below the decode - the four legacy-form parse boundaries here name IllegalArgumentException, IllegalStateException and ClassNotFoundException between them - and straight out of PublicKeyFactory.createKey and PrivateKeyFactory.createKey, which are declared throws IOException. A caller holding the contract those signatures state, catch (IOException), did not catch it.
gefeili
More...
2 months ago
Refuse an XMSS^MT index the hypertree cannot hold where the single-tree side already refuses one, rather than falling through to a placeholder state map that nothing downstream can object to. A private key built from fields rather than from an encoding has its traversal state rebuilt from its index, and on the XMSS side that goes through XMSSEngine.createBDS, which bounds the index with isStoredIndexValid, throws "index out of bounds" if it is outside 0 to 2^h, and returns the exhausted state for the one position at the top of that range. The XMSS^MT side had the same job written out inline and incomplete: it built a state map when isIndexValid said the index was inside 0 to 2^h - 1 and the seeds were present, and otherwise built new BDSStateMap(builder.maxIndex + 1) and carried on.
gefeili
More...
2 months ago
Take LTreeAddress.Builder and HashTreeAddress.Builder away, and the two classes fall to what this package actually asks of them. The previous commit took the last caller either had: the four walks that were assembling a sibling address out of fields now take its encoding off the OTS hash address they are already carrying, so nothing builds an L-tree or a hash tree address any more, and with no Builder there is no way to construct one at all - the fields, the private constructor that copied a Builder into them and the toByteArray() override that wrote them back out are unreachable and go with it. What is left in each is the type word and the offsets of the words below it, which is what a walk names as it steps an encoding, and HashTreeAddress.PADDING goes as well: that word is zero because subtreeAddressOf leaves everything past the type word at zero and no walk writes it afterwards, so it needs a sentence rather than a constant. OTSHashAddress.Builder stays, twelve sites in XMSSEngine and BDSStateMap building the one address a walk starts from, and it is where withLayerAddress, withTreeAddress and withKeyAndMask on the shared XMSSAddress.Builder keep their callers. The three AddressTests cases that were building through the deleted Builders are rewritten rather than dropped, and they now build an address the way the package does - subtreeAddressOf from an OTS hash address that has every one of its own words set, then the index words written in at the offsets named here - which pins strictly more than the Builder form did, because the Builder form never went near the code that produces these encodings today. It pins that the layer address and the tree address of the source carry across and that the OTS address, chain address, hash address and key-and-mask do not, and it is that half which is measured: with subtreeAddressOf copying twenty bytes rather than twelve, both cases fail on word 4 reading 0x11223344, the OTS address of the source leaking into the L-tree address word and into the padding word a hash tree address keeps there; with the type word stamped one out, both fail on the type word. Neither of those reached AddressTests before - the twenty-byte copy showed up only in XMSSPromotionCompatibilityTest, at the ninth leaf of a tree - and both mutations were run in a shadow class tree put ahead of core's rather than in this one. WOTSPlusTests takes its L-tree address off the OTS hash address it already holds for the same reason the walk it stands in for does. Nothing else moves: XMSSPromotionCompatibilityTest at 6, crypto.signers.xmss.AllTests at 90, pqc.crypto.test.AllTests at 136, the provider's XMSSTest at 31 and XMSSMTTest at 27, and core's checkstyleMain.
gefeili
More...
2 months ago
Name the L-tree and hash tree addresses of a walk out of the OTS hash address encoding it is already carrying rather than taking that encoding apart in order to build them back up. RFC 8391 sec. 2.5 gives every address type one 32-byte frame with the words numbered the same way, so the twelve bytes before the type word - the layer address and the two of the tree address - say which tree an address is in whatever its type, and the reference implementation names a sibling address by copying exactly those twelve bytes and stamping the type word over them: copy_subtree_addr followed by set_type. This package was going the long way round. Four walks - BDS.initialize, BDS.nextAuthenticationPath, BDSTreeHash.update and XMSSVerifierUtil.getRootNodeFromSignature - read the layer address and the tree address back out of the encoding they had been handed, fed them to an LTreeAddress.Builder and a HashTreeAddress.Builder, built the two addresses and encoded them, in order to arrive at bytes that are twelve bytes of the first encoding and a type word. XMSSAddress.subtreeAddressOf does that as it reads, and the leaf's index - the one word of the two the callers set beyond the tree - is written into the result the way this package writes every other word that moves, so the two lines that produce an address now say which tree it is in and which leaf of it rather than naming six fields to get there. XMSSAddress.layerAddressOf and treeAddressOf go with them, those four call sites having been the only readers either had, and LTreeAddress.TYPE and HashTreeAddress.TYPE stop being private so the caller can say which type it is asking for. Where the copy stops is the whole of the correctness argument, so it is pinned rather than argued: the three words below the type word mean something different per type and are live in the OTS hash address handed in - the OTS address naming the leaf, and the chain and hash addresses the last WOTS+ chain of that leaf left behind, with its key-and-mask below them - and none of that may reach a sibling address. Copying twenty bytes instead of twelve, so that the OTS address word lands in the padding word a hash tree address keeps there, fails one of the six compatibility cases at the ninth leaf of a tree; stamping the type word one out fails five of the six on differing public key encodings. Both were run in a shadow class tree put ahead of core's rather than in this one. Green as it stands: XMSSPromotionCompatibilityTest at 6, which compares keys, signatures and cross-verification against the deprecated org.bouncycastle.pqc.crypto.xmss copy over six parameter sets and every index of a key, crypto.signers.xmss.AllTests at 90, pqc.crypto.test.AllTests at 136, the provider's XMSSTest at 31 and XMSSMTTest at 27, and core's checkstyleMain. What it saves is not why it is here and is not much: an h = 10 SHA-256 key generation falls 184 bytes and an XMSS^MT h = 20 d = 2 first signature 552, those being one and three sibling-address pairs at 96 bytes for the L-tree side - a 48-byte Builder, a 48-byte address and the byte[32] they were built to produce, against one byte[32] - and 88 for the hash tree side, whose Builder carries two fields rather than three and so is 40. Both figures are measured over com.sun.management.ThreadMXBean.getThreadAllocatedBytes with the signature path warmed and are reproducible to the byte.
gefeili
More...
2 months ago
Take the seven getters off XMSSAddress and OTSHashAddress, which nothing has called since the addresses started travelling as their encodings. getLayerAddress, getTreeAddress, getType and getKeyAndMask, and getOTSAddress, getChainAddress and getHashAddress under them, were how a walk read back an address it had been handed; a walk is handed the 32 bytes now and reads what it needs off those, through layerAddressOf, treeAddressOf and otsAddressOf, so the last caller of each went with the previous commit. What is left in these two classes, and in LTreeAddress and HashTreeAddress before them, is a Builder and a toByteArray(), which is the whole of what this package asks of them: an address is assembled once where a walk starts and is never asked about itself again. The class javadoc says that, so that a value class with no accessors reads as the shape it is rather than as something half finished. The fields stay, every one of them still being written into the encoding, and so do the Builder setters, all of which still have callers - several only in AddressTests, which is the test that pins the 32-byte layout the readers index into, and so is the right place for them to be exercised from. Nothing else moves: XMSSPromotionCompatibilityTest at 6, crypto.signers.xmss.AllTests at 90, pqc.crypto.test.AllTests at 136, the provider's XMSSTest at 31 and XMSSMTTest at 27, and core's checkstyleMain.
gefeili
More...
2 months ago
←
1
2
…
16
17
18
19
20
21
22
23
24
…
805
806
→
This site uses cookies to give you the best possible experience. By using the site, you consent to our use of cookies. For more information, please see our
Privacy Policy
Agree