DI Management Home > Cryptography > SPHINCS+ > Python Code

SPHINCS+ Python Code

This page has the Python code we used to reproduce the example values in the previous pages.

Some of this Python code is a bit crude. It is not meant as an example of good or efficient coding practice. The intention is to demonstrate specific examples with hardcoded input and show we get the desired output. All the binary values are converted back and forth with hexadecimal encoding - this, again, is for clarity, not efficiency.

We find it easier to work through small self-contained blocks of code that do something simple, rather than obscure code hidden inside layers of abstraction. YMMV.

At the end, we pull it all together to compute the SPHINCS+ signature in one go. Beware, lots of hardcoded constants! Then we do the same program slightly rewritten to re-compute all the 100 test cases for SPHINCS+-SHA2-128f-simple using data from a separate JSON file.

We use the SHA-256 functions from our CryptoSys PKI toolkit library and its Python interface. There is an alternative interface using the pure Python hashlib and hmac libraries.

This was tested using Python 3.11.0 [MSC v.1933 64 bit (AMD64)] on 64-bit Windows 10.

spx_adrs.pySPHINCS+ ADRS Class.
spx_sha256.pySPHINCS+-SHA-256 crypto functions.
spx_util.pySPHINCS+ utilities for tree calculations.
hashlib_pki.pySHA-256 functions using cryptosyspki.
hashlib_pure.pySHA-256 functions using hashlib and hmac libraries.
Merkle trees
merkle_tree_4byte.pyGenerate a Merkle tree using weak 4-byte hash function.
merkle_authpath_verify.pyVerify authentication path for a simple Merkle tree.
FORS signature
PRF_msg.pyCompute the 16-byte randomizer R.
H_msg.pyCompute H_msg from the message, public key and randomizer.
message_to_indices.pyInterpret 25-byte mhash as 33 * 6-bit unsigned integers.
fors_sk_basic.pyCompute the FORS secret keys for i=0,1,32 with hardcoded ADRS
fors_sig_sk_all.pyCompute all the 33 FORS signature secret keys.
fors_authpath_basic.pyInitial basic calcs for authpath of first FORS tree.
fors_sk_pk_0.pyCompute the 64 FORS secret and public keys for the first tree.
fors_PKgen.pyCompute the FORS public key given the roots of the k FORS trees.
fors_authpath_0.pyCompute the authpath for the first FORS tree.
fors_authpath_01_32.pyCompute the authpaths from scratch for the FORS trees with i=1 and i=32.
fors_authpath_verify.pyVerify the first FORS authpath.
Hypertree signature (SIG_HT)
wots_len.pyCompute len_1 and len_2 given n and w.
wots_checksum.pySplit 16-byte message into 4-bit blocks then append 3 x 4-bit checksum.
wots_sig_0.pyCompute the first WOTS signature.
wots_pk.pyCompute the WOTS public key for the bottom HT subtree.
wots_PKgen.pyCompute the first WOTS public key with hardcoded root values.
wots_PKgen_sk.pyCompute WOTS secret key then derive public key.
wots_PKgenRoot.pyGenerate WOTS public key root value.
wots_ht_0.pyCompute root node and authpath for bottom HT subtree at layer 0.
wots_authpath_verify.pyVerify the authpath in the first WOTS subtree.
wots_layers.pyCompute the WOTS tree address for each layer.
wots_gen_pk.pyCompute root node of the top-most HT subtree = PK.root.
Do it all
spx_makesig.pyDo it all to make a SPHINCS+ signature in one go.
spx_makesigs100.pyReproduce all 100 SPHINCS+-SHA2-128f-simple test cases.
spx_inputkat100.jsonJSON data for SPHINCS+ test cases.

In the Python code, spx_makesig.py, we reproduce the first two test cases in the SPHINCS+ October 2020 round 3 submission for sphincs-sha256-128f-simple. All the required information is in the file PQCsignKAT_64.rsp except the value of OptRand, the optional randomness added when computing the randomizer, R. The value of OptRand can only be found by running the implementation code with its specific random bit generator. The SHA256 hash of the signature value is also computed separately.

<< previous: The Hyper Tree Signature (SIG_HT) Contents next: SPHINCS+ References >>

Contact us

To comment on this page or to contact us, please send us a message.

This page first published 17 March 2023. Last updated 20 March 2023.