<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Athena&#x27;s Parthenon - DHTKEM</title>
    <subtitle>Athena&#x27;s Parthenon</subtitle>
    <link rel="self" type="application/atom+xml" href="https://parthen.online/topics/dhtkem/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://parthen.online"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-18T00:00:00+00:00</updated>
    <id>https://parthen.online/topics/dhtkem/atom.xml</id>
    <entry xml:lang="en">
        <title>DHTKEM-DH: A Group Key Agreement System on the Veilid DHT</title>
        <published>2026-10-18T00:00:00+00:00</published>
        <updated>2026-10-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Athena
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://parthen.online/notes/dhtkem-dh/"/>
        <id>https://parthen.online/notes/dhtkem-dh/</id>
        
        <content type="html" xml:base="https://parthen.online/notes/dhtkem-dh/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;parthen.online&#x2F;notes&#x2F;dhtkem-dh&#x2F;.&#x2F;header.jpg&quot; alt=&quot;A photograph of white clouds, possibly contrails, against a blue sky, forming a obtuse V shape.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Written for &lt;code&gt;veilid_core&lt;&#x2F;code&gt; version 0.5.7&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This post presents DHTKEM-DH: a &lt;strong&gt;D&lt;&#x2F;strong&gt;istributed &lt;strong&gt;H&lt;&#x2F;strong&gt;ash &lt;strong&gt;T&lt;&#x2F;strong&gt;able &lt;strong&gt;K&lt;&#x2F;strong&gt;ey
&lt;strong&gt;E&lt;&#x2F;strong&gt;ncapsulation &lt;strong&gt;M&lt;&#x2F;strong&gt;echanism using &lt;strong&gt;D&lt;&#x2F;strong&gt;iffie-&lt;strong&gt;H&lt;&#x2F;strong&gt;ellman, a system which
implements secure secret sharing and group membership using the Veilid
Distributed Hash Table (or &lt;em&gt;DHT&lt;&#x2F;em&gt;). Note that the system described here is not
completely implemented and this post is primarily to serve as point of
discussion for subsequent iterations on the idea. In particular, I do not
recommend you use this design as written for anything, particularly the
incomplete proof-of-concept implementation linked at the end. Again, this post
is motivated primarily by a desire to document my thinking somewhere other than
offline journals and to serve as a point of discussion for future iterations -
for which there is a teaser at the end of this post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivations-threat-model&quot;&gt;Motivations &amp;amp; Threat Model&lt;&#x2F;h2&gt;
&lt;p&gt;Cryptographically defining group membership is frequently useful for
decentralized applications, especially those in which members of a group may not
be online at the same time and between whom secure out-of-band coordination may
be difficult.&lt;&#x2F;p&gt;
&lt;p&gt;Distribution is the perennial challenge with simply sharing a group key:
out-of-band key distribution (i.e. telling your friend the password on the
phone) frequently leaves much to be desired in terms of security, and sharing
device-to-device via some interactive mechanism requires both the joiner and the
inviter to be online at the same time. It would be nice if no private
information had to be shared out of band, and did not require any particular
members to be online simultaneously to agree on group membership.&lt;&#x2F;p&gt;
&lt;p&gt;To define our threat model more precisely: Privacy from casual surveillance by
third-party actors with access to IP flows is the priority; resistance to attack
by insiders or highly motivated targeted attacks is worthy of consideration but
as a secondary concern. DHTKEM-DH is motivated a desire for a more
decentralized, distributed world: devices should talk to each other directly,
servers be used judiciously rather than treated as a baseline assumption, and
data remain on its owner&#x27;s devices.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;It is assumed that the reader is familiar with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Public-key_cryptography&quot;&gt;public-key
cryptography&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Diffie%E2%80%93Hellman_key_exchange&quot;&gt;Diffie-Hellman key exchange&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;veilid&#x2F;veilid&quot;&gt;Veilid&lt;&#x2F;a&gt; DHT is, to summarize extremely briefly for those
unfamiliar, a key-value store kept on the Veilid network. The table is keyed by
a hash of two things: A public key and a schema. The &quot;schema&quot; in this case is
not a schema like a database schema; for the purposes of this post I will
grievously oversimplify it as &quot;the number of values in the record&quot;. If we fix
that number, the Veilid DHT is effectively keyed by public key. In order to
publish new values, those values must be signed with that public key&#x27;s partner
private key. Each record&#x27;s values are limited to 1MB total maximum, among other
limitations. For the rest of this post, a &quot;record&quot; will refer to a DHT record, a
set of values associated with a keypair.&lt;&#x2F;p&gt;
&lt;p&gt;A DHT record remains available via the Veilid network while devices
participating in the record have it open, and may be cached for a while beyond
that. This has consequences for users of DHTKEM-DH, which will be described in
the next section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dhtkem-dh-design-properties&quot;&gt;DHTKEM-DH Design &amp;amp; Properties&lt;&#x2F;h2&gt;
&lt;p&gt;DHTKEM is concerned with trusted group membership and sharing information (such
as encryption keys) within that group. A &quot;group&quot; is represented by a DHT record,
with its data composed of references to &quot;left&quot; and &quot;right&quot; branches to other
&quot;group&quot; records, and its own secret key encrypted for the owners of the left and
right keys, using the shared secret resulting from the Diffie-Hellman key
exchange of left and right. This forms a binary tree of records, where leaf
nodes represent individual devices. Not every leaf node needs to have a DHT
record associated with it; a public key may be present in the tree only as a
child.&lt;&#x2F;p&gt;
&lt;p&gt;This may be slightly confusing. If so, I highly recommend pausing to go read
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.inkandswitch.com&#x2F;keyhive&#x2F;notebook&#x2F;02&#x2F;&quot;&gt;Ink &amp;amp; Switch&#x27;s description of BeeKEM&lt;&#x2F;a&gt;, then coming back to finish.
Seriously, it&#x27;s very good at explaining the binary-tree-Diffie-Hellman thing,
even though I apply the idea differently here. It&#x27;s got pictures.&lt;&#x2F;p&gt;
&lt;p&gt;A group record is composed of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;header&lt;&#x2F;code&gt;, containing the public key of the record&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;left&lt;&#x2F;code&gt; child public key&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;right&lt;&#x2F;code&gt; child public key&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;code&gt;payload&lt;&#x2F;code&gt; of bytes encrypted with &lt;code&gt;left&lt;&#x2F;code&gt; and &lt;code&gt;right&lt;&#x2F;code&gt;&#x27;s Diffie-Hellman shared secret&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A decrypted payload contains the record&#x27;s ownership key (i.e. the private key
corresponding to the public key in the header), and a list of symmetric keys
(intended as a log of rotated keys). Data can be encrypted for other group
members by using one of the symmetric keys stored in the payload. The group&#x27;s
public key may be included with data encrypted for the group. The maximum length
of the list is dependent on the cryptosystem chosen and is left as an exercise
to the reader.&lt;&#x2F;p&gt;
&lt;p&gt;New members may be added to the group by ensuring a public key owned by the new
user appears in the tree.  This may be done by creating a new individual node and
converting the previous individual node into a group node, or by altering the
child of a node to &quot;insert&quot; a new record midway into the tree. This can be used
to maintain logical &quot;subgroups&quot;, depending on where in the hierarchy new members
are added.&lt;&#x2F;p&gt;
&lt;p&gt;In order to validate if a given public key is a member of a group, a validator
must walk the tree starting from the root of the group until it either finds
that public key or exhausts the tree. Group membership can only be determined by
starting at the &quot;root&quot; group and walking the tree; since child nodes contain no
information about &quot;parent&quot; nodes, nodes may be part of multiple group trees,
there is no way to determine which groups a given public key is part of without
inspecting the group trees in question.&lt;&#x2F;p&gt;
&lt;p&gt;The membership tree may be cached for offline use at the cost of possibly being
out of date with membership additions or removals. The process of walking the
tree may be slow, depending on the speed of the DHT and state of the
participating devices, and walking the tree for a group in advance and keeping
up to date using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;veilid-core&#x2F;0.5.7&#x2F;veilid_core&#x2F;struct.RoutingContext.html#method.watch_dht_values&quot;&gt;Veilid&#x27;s DHT record watching mechanism&lt;&#x2F;a&gt; is
recommended for devices that are not resource-constrained. In addition, this
will ensure the entire tree remains available via the DHT for other group
members.&lt;&#x2F;p&gt;
&lt;p&gt;Since DHT records may &quot;age out&quot; and become unavailable on the network unless
kept open or rehydrated, it is possible for portions of the tree to &quot;age out&quot; of
the network, resulting in failures to traverse the tree. To prevent this, member
systems which are able to should hold the records for the entire membership tree
for known groups, and all nodes should minimally be able to rehydrate the
records in the tree between their leaf and the root of the tree in order to
guarantee that new or long-offline members can successfully traverse the tree to
the root.&lt;&#x2F;p&gt;
&lt;p&gt;Member removal proves a bit trickier than member addition: once someone is a
member of a group, they know the private key of the root group (and the groups
in the tree between their node and the root). The keypair of the group cannot be
changed, as it determines the DHT record&#x27;s address, and so a new root group must
be created with modified entries. Portions of the tree between the root and the
subgroup containing the member to be removed must be replaced. Since members
&quot;higher&quot; in the hierarchy cannot &quot;look down&quot; into child records to retrieve
private key material, this may involve creating new subgroups out of whole-cloth.
In this case, the member performing the group replacement ought to indicate this
by placing itself in the new hierarchy.&lt;&#x2F;p&gt;
&lt;p&gt;To be honest, member removal with this scheme just sucks. It was part of the way
through figuring out member removal that I decided that the limitations inherent
in this scheme make it more trouble than it&#x27;s worth to finish the implementation
of this design, and to focus on a second iteration, using some of the same ideas
with with slightly different primitives.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation-future-work&quot;&gt;Implementation &amp;amp; Future Work&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve published a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~athenaeryma&#x2F;dhtkem&#x2F;tree&#x2F;dhtkem-dh&quot;&gt;very rough proof-of-concept implementation&lt;&#x2F;a&gt;
demonstrating the core idea. Most notably missing is any implementation of
removal, even as a stub. While figuring out how it would need to work, I was
also considering how this design to could be adapted to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;info&#x2F;rfc9180&#x2F;&quot;&gt;RFC
9180-compliant&lt;&#x2F;a&gt; Hybrid Public Key Encryption (HPKE) primitives, and
came to believe that a fundamental shift in the nature of the scheme is
required. That new design based on HPKE primitives, however, will enable both
more useful properties in the final scheme and also drastically reduce the
number of DHT fetches required - look out for a draft design of DHTKEM-HPKE in
this space in the coming months.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inspirations-comparisons&quot;&gt;Inspirations &amp;amp; Comparisons&lt;&#x2F;h2&gt;
&lt;p&gt;I will again tip my hat to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.inkandswitch.com&#x2F;keyhive&#x2F;notebook&#x2F;02&#x2F;&quot;&gt;BeeKEM&lt;&#x2F;a&gt; as the primary inspiration for this
work, though by necessity the application of the ideas differs: BeeKEM makes a
similar application of the cryptographic properties of the Diffie-Hellman binary
tree, but uses its own synchronization mechanism for sharing that tree between
member systems. Effort is also dedicated to conflict resolution in BeeKEM,
whereas DHTKEM-DH can largely rely on the Veilid DHT to solve both.&lt;&#x2F;p&gt;
&lt;p&gt;DHTKEM-DH&#x27;s approach to member removal is more or less the same as well, in
terms of &quot;blanking&quot; the tree between the member to be removed and the root.
However, that becomes significantly more painful since the keys in question are
used to address the DHT records holding the tree data, so changing the keys
necessarily changes the address! It sure would be nice if we could figure out
how to separate out some of these keys so granting group membership doesn&#x27;t
necessarily grant write access to the root record (perhaps something that can be
resolved in a future iteration!).&lt;&#x2F;p&gt;
&lt;p&gt;The idea of the binary tree of Diffie-Hellman pairs, however, was used in
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;info&#x2F;rfc9420&#x2F;&quot;&gt;RFC9420&lt;&#x2F;a&gt;&#x27;s &quot;Ratchet Trees&quot; as part of Messaging Layer Security (MLS)
Protocol before it appeared in BeeKEM, in yet another context which uses a
different coordination mechanism, in this case a central server which holds the
tree.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
