Allen Walters
7 min readJul 22, 2019


I never said WOTS+ isn’t part of XMSS. I say WOTS+ isn’t the same as XMSS and that you haven’t implemented XMSS. Period.

Your words:

“While Mochimo audited the underlying Post-Quantum Secure Digital Signature Algorithm first, and with it’s creator, QRL later audited XMSS, which includes some key generation routines that we didn’t audit, and therefore can honestly claim they audited THAT more specific system “first”.”

You admit it’s not the same and that QRL runs XMSS first. THAT’S MY WHOLE POINT!

Then you go on explaining the difference between your implementation and XMSS: “Now on to your comparison of Mochimo’s (Tag & WOTS+) system compared to XMSS […]”

Your previous claim that WOTS+ = XMSS: that’s absolutely false.

Adding to your own words: Hulsing named his review “Review of Mochimo’s WOTS implementation”

Then he sums up 3 schemes: “For WOTS-T (the scheme implemented here), XMSS-T, and SPHINCS+ reuse is minimized by using a new random seed per key pair of sufficient length […]”

WOTS+… Not XMSS, not SPHINCS+.. But WOTS+..

What you did was a self made variation at most. You rolled out your own crypto scheme.

I stand by my statement because it’s a true fact. “QRL is the only blockchain at this point of time that has a successful and externaly audited implementation of XMSS.”

Note to the review of Andreas: You wanted him to approve your WOTS implementation, but instead of simply writing “everything looks great”, he gave recommendations. You guys referred to that as “garbage” and expressed your annoyance about the fact that because of this, the review isn’t useful as a marketing tool. Posting the full text of the review here in the end of this comment.

And speaking of being bias and promote his own project: YOU THE DEV OF MOCHIMO! Bashing QRL and praising Mochimo with twisted facts and trying to get a sentence removed about QRL being the first to implement XMSS in their blockchain. Sad situation you have to go to these lows to get some attention.

And you keep pretending that QRL moved their date forward while they had no set date. Only an estimate that was delayed due to the audit. YOU had a set date and moved it forward. No matter if you were just waiting for the timer to expire, you set a date and moved it forward to be the first QR chain. While that is what you accuse QRL of doing. YOU did that. You can keep on trying to spin this, but it’s blatant facts.

And again: no lies and deceit, PoS is on the way and Ephemeral too. You simply prematurely sold with a loss and being sour over that fact. If they wouldn’t have launched with PoW, they would possibly still be an ERC20 token today. Way worse scenario than launching PoW. Perfectly fine in the interest of people buying the pre sale.


Here follows the full text of Andreas Hülsings Review of Mochimo’s WOTS+ implementation:


Review of Mochimo’s WOTS implementation

Andreas Hülsing

Department of Mathematics and Computer Science Technische Universiteit Eindhoven

P.O. Box 513, 5600 MB Eindhoven, The Netherlands

March 5, 2018


We analysed the C implementation of WOTS provided by Mochimo. We did not find any bugs or security issues in the core implementation (in the /wots subfolder). Under the assumption that the code provided in example.c shows how the signature scheme is used to sign transactions, we identified several issues worth reconsideration. At least one issue weakens the security of the used signature scheme. In addition we identify a possibility for optimization, reducing the size of a transaction from 8,792 bytes to 2,360 bytes.

Chapter 1


1.1 Review of core WOTS implementation

We conducted a review of the core WOTS implementation. This refers to the code in the /wots folder consisting of the files wots.h, wots.c, and wotshash.c. We assume that the file randomby.c is there for testing purposes only and did not review it for that reason. The code is a refactoring of former well tested code and we did not find any issues.

1.2 Review of the use of WOTS

We also reviewed the use of WOTS as presented in example.c. For this we found the following issues:

• Hashing a struct without explicit serialization.

• Non-collision-resilient hashing.

We will detail these points below. Afterwards we briefly discuss requirements on the public seed and hash addresses. We end with a suggestion for reducing the size of public keys thereby of addresses and in consequence of transactions.

1.2.1 Hashing a struct

Directly feeding a struct to a hash function might lead to interoperability issues. The memory layout of structs is implementation specific as e.g. described in the C99 standard: (From C99 §

12 Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type.

13 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

(Page 1)

In general, the compiler might / will add padding which can lead to interop- erability issues. While it is not a problem in the given case as all elements of the struct are byte arrays, we would strongly suggest to manually serialize the struct into a byte string to avoid issues when changing the type of elements for some reason.

1.2.2 Non-collision-resilient hashing

WOTS+ and WOTS-T are designed to be collision-resilient. This is undermined if the message-to-be-signed is compressed in a way that requires a collision resistant hash function. More concretely this reduces the security of the scheme to the complexity of collision attacks against the used hash function, in this case SHA2. For quantum attacks this means a difference between 128 bit and 86 bit security when using query complexity as metric. While more realistic models predict a smaller gap between quantum (second-)preimage attacks and collision attacks, all known models predict a gap.

For that reason we strongly recommend to use a collision-resilient way to compress the message (i.e., transaction in this case), like randomized hashing. While this requires to add another 32 byte value to the signature, it ensures that the whole construction is not vulnerable to collision attacks. A common approach for message compression is to also add multi-user security. However, in the given application, messages always include the public key of the key pair used to sign the message which is considered sufficient in this regard.

We suggest the following change. First, a dedicated PRF key is derived from the secret seed:

sk_prf = prf(seed,”PRF-key”),

where the PRF call is keyed with the secret key seed and the message part is a constant string (e.g., “PRF-key”). Next, a message dependent pseudorandom value R is computed as

R = prf(sk_prf,message),

where now message is the message-to-be-signed. Then the message digest md

gets computed as

md = sha2(toByte(2, 32)||R||message),

where toByte(2,32) generates a 32 byte array containing the bit representa-

tion of 2 (essentially what ull_to_bytes does in the reviewed code).

1.2.3 Hash-addresses and public seeds

The abstract requirement on the use of the hash addresses and the public seed is that the same combination of these two is not used twice. The reuse of a combination decreases security. Namely, after using the same combination t times, an attacker can target these t hash function calls at once and apply a so-called multi-target attack which implies a multiplicative security loss linear in t.

For WOTS-T (the scheme implemented here), XMSS-T, and SPHINCS+ reuse is minimized by using a new random seed per key pair of sufficient length

(Page 2)

to prevent collisions and a deterministic hash-address that differs for all calls to a hash function associated with the generation and use of one key pair. Depending on the actual use and generation of user-addresses, it might be possible to use the same public seed for a user for all key pairs (which of course allows linking these key pairs with all its advantages and disadvantages) and encode an identifier of the WOTS key pair into the hash address. This identifier can, for example, just be a counter encoded in the two most significant 32bit words of the hash address. Of course, a user can still generate a new public seed for every key pair to avoid tracking.

1.3 Optimizations

The presented code uses unnecessarily long addresses. This is caused by the fact that it uses full WOTS public keys of length 2,208 bytes. This leads to transaction sizes of more than 8,792 bytes. It is possible to reduce this to 2,360 bytes. This works by compressing the WOTS-T public key nodes (excluding the public seed). This is a common approach, traditionally described in the context of the higher level schemes using WOTS, like XMSS or SPHINCS.

To do this in a collision resilient way, we suggest to use the approach used in SPHINCS+: Generate WOTS_LEN bitmasks, i.e., one per public key element, and a hash function key as for thash_f. This can be done introducing a new “hash-address type” for public key compression.

Hashing then works as for thash_f but with longer inputs. The key is prepended to the concatenation of the xor of the public key elements with the generated bitmasks. The resulting bit string is then hashed using SHA2.

This optimization reduces the size of a WOTS public key to 64 bytes, 32 bytes for the public seed and 32 bytes for the hash. The three addresses included in an transaction thereby shrink from 6624 bytes to 192 bytes. This achieves the total size reduction claimed above.

(Page 3)



Allen Walters

Discover the technology, even before it gets relevant