Generating and Verifying the Public Key Root
This page looks at the public key root value PK.root.
This is a published value included in both the public key and the private key.
Facts about the SLH-DSA Public Key Root
-
The SLH-DSA Public Key Root
PK.rootcan be computed from just the top-most HT subtree. -
Crucially, all leaf nodes of all intermediate trees are deterministically generated WOTS+ public keys that do not depend on any of the trees below it.
-
During key generation, only the top-most subtree is computed to derive the public key.
-
In our case we have a subtree of height $h' = h/d = 66 / 22 = 3$. This has $2^{h'} = 8$ leaves.
-
Each leaf value is the compression of $len = 35$ chain heads derived from the WOTS+ private key values $sk_0, sk_1, \ldots sk_{34}$, which in turn can be derived using the PRF function with
SK.seed. -
The value of the root node can then be calculated from the 8 leaf values using the usual Merkle tree computations, but note that the value of
ADRSin the $F$ function is different each time it is called. - Note also that the value of the ADRS parameter is different when computing the secret keys for the public key root and when computing the secret keys for the signature.
Python code
See wots_gen_pk.py
['2bd8631b653542190503f84e352c7494', '8e95255364f2e35b4bb0f037dc99ca67', 'e927d1024f4387de5f5ac37c5da87992', '9dd5de733baa4c80a75c23193fdbdd59', '76d299d90caddc06bb7cffc72bbb9535', '81486f9fb72ccde4211835fb774a8362', 'd7685e5ea26c07d38628ff7ca45ced0e', 'f9247aa899cf41af17a42668b30c1573']
Using the usual Merkle tree calculations, these give the root value of a67029e90668c5a58b96e60111491f3d,
which equals PK.root.
sk[0]..sk[34] and the corresponding public keys $pk[i]=F^{w-1}sk[i]$
leaf_idx=0 15000000000000000000000000000000000000000000 sk_adrs=15000000000000000005000000000000000000000000 sk[0]=4c4258d26981a1bf71965e5516a4c5e5 pk_adrs=15000000000000000000000000000000000000000000 adrs=15000000000000000000000000000000000000000000 F(0)= cafb82ff582ad7b1577c446f3186caba adrs=15000000000000000000000000000000000000000001 F(1)= f54ed1224f78a6d48257549c799b6299 adrs=15000000000000000000000000000000000000000002 F(2)= 6c7dfa02f6b6d05ff3681488f662f2e7 #...[CUT]... adrs=1500000000000000000000000000000000000000000d F(13)= 1728e9b3e68ba06875c21c19aaae42d7 adrs=1500000000000000000000000000000000000000000e F(14)= c99a06d927e9b37f48dc68e3a867ea42 pk=c99a06d927e9b37f48dc68e3a867ea42
sk_adrs=15000000000000000005000000000000000100000000 sk[1]=b0f9c327e0667dedbdca6042f8864346 pk_adrs=15000000000000000000000000000000000100000000 adrs=15000000000000000000000000000000000100000000 F(0)= c38276ad0eefce12568fd32618e4a7a4 adrs=15000000000000000000000000000000000100000001 F(1)= 9788825616fec546c07e33366f41c76a #...[CUT]... adrs=1500000000000000000000000000000000010000000d F(13)= ff16cf04725266e1feaeb104bb41f235 adrs=1500000000000000000000000000000000010000000e F(14)= 987f41ccaab78c40e154c2855c570004 pk=987f41ccaab78c40e154c2855c570004and so forth up to the 35th key
sk[34]=11e0afd5469565acfdcd109076f9cdaf pk_adrs=15000000000000000000000000070000002200000000 adrs=15000000000000000000000000070000002200000000 F(0)= c74b1f3fd346731c043c2c8387a4178f adrs=15000000000000000000000000070000002200000001 F(1)= c898a0d5a1d486a9aea12fb689d20e00 #...[CUT]... adrs=1500000000000000000000000007000000220000000e F(14)= 4f9c277466ca634aec0f9c2fc08a0f7f pk=4f9c277466ca634aec0f9c2fc08a0f7fAll these 35 public keys (560 bytes) are compressed using
T_len
Input to thash: 52aa2a77902676728e896b30c9ce0090 b1b73dcb81aa5af78f9d00855588888c ef7aed6235448dc5ecaf46bc460f77fd a8173eef59758276b7754e94e5882202 222bf255e46362beccb1d900abb969ea 12366626ee0ca196e635047926194063 425b7e9b7678aae37257ba0281af9981 ea78b8aa8526e8749cb4dcb94c32a896 584ae7e41c9cfbf847862412cdba40a3 cd1fb2ab799d81e0fd37cc61d589fb86 b492beb24f1de90ad09cb3512046a661 42b3fdf58877ee83e493f8be02092a65 4752f2ef840fd952e912f82826a58f89 ea4c1c993955680a20164a15d3f39ed7 26dd848ed435e49097a7caa17a94124b e188413aaeb6737522731311de6e14f6 98b0ff67964909e8e725f14f6aaef1c8 508fe1a71aeefd29506cc72189bdf8d2 0788ef710052ebe53f4214e8391ab4a1 df9e4558c288e1dcc79fe9a99138f955 d3e979ca8d123e2c5a49f842862fb70e 307beac4f874964294d3a113de913357 a954f1349c35bc060eae3e562bda5853 41db2786b8fdc25419d7534edb93853e 1cb399130a15fe7844b55eb1204d01f2 d1e2c28e47012ad3aa4a6f1ef8c97e6c 8115edf721617e5c598367d0b346a3d2 c973d4cab75500e7c05d4de0e707718e bf92a47bfc6e10690df4202a2b5f7975 9e2f3f64fef85b0e2b106bd34c3dfab7 e449717116cb63b900d66ae3ee02e1b9 2fc708bf4f6c15bceb28fa221bdbf6cc 009378459207cf32ca196636a0ea65f2 ca2ed8c66f570bcf66a3a84bea546381 4f9c277466ca634aec0f9c2fc08a0f7f wots_pk_addr=15000000000000000001000000070000000000000000 leaf[7]=f9247aa899cf41af17a42668b30c1573
The above calculations are repeated for the other seven leaf values leaf[1]...leaf[7] of the top-most tree,
and then the root value of the tree can be computed.
| << previous: The Hyper Tree Signature (SIG_HT) | Contents | next: SLH-DSA Python Code >> |
Rate this page
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 16 February 2026.

