
@ David
2025-02-19 11:17:19
## Introduction: The Challenge of Time-Lock Encryption and Clock Servers
When I first set out to build **Hatchstr**, the idea was simple: create a way to send messages into the future, encrypted and locked to a specific Bitcoin block height. These messages would remain encrypted until the chosen block height was reached, creating a unique way to send a message to the future.
However, as I began working through the details, I quickly ran into some challenges. One key component of this system involves **clock servers**—decentralized nodes responsible for releasing decryption keys when the specified block height is reached.
### Clock Server Setup: The Basics
Initially, I adopted a simple model: each clock server holds a single public-private key pair *unique to that server* for a specific block height. When a user creates a message, they choose a clock server to trust and encrypt with the specific public key tied to that block height. Then, when the time comes, the clock server releases its private key to decrypt the message.

#### Positives:
- ✅ **Clean and Efficient Storage**: Each clock server only needs to store a single key pair for each block height, making storage lightweight and scalable.
- ✅ **Lazy Key Generation**: Keys are generated on-demand, meaning they’re only created when needed. This prevents unnecessary key generation or storage overhead.
- ✅ **Decentralized**: The clock servers don’t need to coordinate with each other or store any sensitive data besides their respective private keys, which simplifies the system architecture.
- ✅ **Limited Release Events**: Since each clock server only handles keys tied to a specific block height, the number of release events required is minimized, simplifying the key management process.
At first, this seemed like a good approach, but I quickly realized there were **critical limitations**:
#### Challenges:
- ❌ **Server Shutdown**: Capsules could be scheduled for many years in the future. If a clock server shuts down, all future capsules linked to it are lost.
- ❌ **Server Downtime**: If one of the clock servers is unavailable during unlock time, even for a short period, it leads to a delay for the users waiting for unlock.
- ❌ **Premature Release**: If a clock server accidentally releases its key too early, it could compromise the message, making it accessible before the intended time.
Though the setup worked for a basic system, I soon realized it couldn’t guarantee the reliability I wanted for a decentralized application.
## Tackling the Challenges of Multi-Sig and Secret Sharing
When I first approached the problem of securing time-lock capsules, I initially considered using multi-signature (multi-sig) solutions as a potential approach. The goal was simple: instead of relying on a single clock server to release its key, I could involve multiple servers to sign off on the decryption. This way, if one server failed or misbehaved, the message would still be protected.
However, as I delved deeper into the multi-sig approach, I quickly realized there were a few key issues:
🔒 **Communication Overhead**: Multi-sig requires servers to communicate and coordinate with each other. This introduces the possibility of new failure points, like network issues or miscommunication.
⚡ **Server Synchronization**: If one server was out of sync or released its key too early, it could still lead to the message being decrypted prematurely, breaking the system.
🛠 **Increased Complexity**: Each server would need to store and manage a unique key pair for every message, making the system more complicated and less efficient.
I quickly realized that multi-sig wasn’t the best fit for this kind of setup. Not only did it add unnecessary complexity, but it also conflicted with the decentralization goals I wanted to achieve. So, I started thinking about ways to **distribute the secret** across the clock servers without introducing all these new complications.
### Enter Shamir’s Secret Sharing (SSS)
Shamir's Secret Sharing (SSS) is a cryptographic technique designed to split a secret into multiple parts (called "shares") so that the secret can only be reconstructed when a specific minimum number of shares are combined. This process is based on polynomial interpolation, and it’s a powerful way to distribute secrets securely.
#### The Basic Concept
In SSS, a secret (like a cryptographic key or message) is divided into *n* shares, where *n* is the total number of shares you want to generate. You also specify a threshold, *k*, which represents the minimum number of shares required to reconstruct the original secret.
- **n** is the total number of shares.
- **k** is the minimum number of shares required to reconstruct the secret (known as the "threshold").
For example, in a **3-out-of-5** scheme, the secret is split into 5 shares, but at least 3 shares are required to reconstruct the secret. If fewer than 3 shares are available, the secret cannot be reconstructed.
#### Why This is Secure
Shamir’s Secret Sharing is secure because, with fewer than *k* shares, it is computationally infeasible to learn anything about the secret. The shares themselves don’t reveal any information; it’s only the combination of the right number of shares that allows reconstruction. This makes it resistant to attacks, as even if an attacker gets hold of some shares, they won’t be able to reconstruct the secret unless they have the required minimum number of shares (comparable to 256-bit cryptographic strength).
#### Applications of Shamir’s Secret Sharing
Shamir’s Secret Sharing is widely used in scenarios where high availability and reliability are needed, but security and privacy are equally important. Examples include:
- **Key management**: Protecting encryption keys by distributing them across multiple parties.
- **Multi-signature setups**: Requiring multiple parties to sign off on a transaction or access a secure system.
- **Distributed systems**: Ensuring that no single party holds a complete secret, and multiple parties must collaborate to unlock it.
By leveraging Shamir's Secret Sharing, you can strike the right balance between **redundancy**, **security**, and **availability** for your system’s sensitive information.
### The Problem with Distributing Secret Shares
SSS could give us exactly the properties I was looking for, with the added benefit that users could choose their preferred setup, for example:
- **1-out-of-5 scheme**: Prioritizing the likelihood that the message is decrypted even if only one of the 5 chosen clock servers does its job at unlock time. With the tradeoff that each of the 5 could leak the message early.
- **3-out-of-5 scheme**: A measured approach that allows for 2 servers to stop working and would also keep the capsule private even if 2 clock servers leak their secret early.
So I considered an approach where each clock server would store part of the key. Instead of a single server holding the full key, I would split the key into parts and distribute those parts across multiple servers. When the time arrived, I’d gather the required number of shares to reconstruct the key and decrypt the message.
At first glance, this seemed like a promising approach. But when we look through the implications, a few problems started to emerge:
💥 **Overhead**: Each clock server would need to store a share of every key for every message. This would quickly become inefficient and result in unnecessary overhead.
🔔 **Exploding Reveal Events**: Since each clock server would need to release all its shares at a specific time, there would be a massive increase in the number of reveal events, spamming and possibly overloading Nostr relays.
While the idea of distributing the key was very appealing, the practical issues around overhead and complexity made it clear that this wasn’t the final solution. I needed something that would be more efficient, scalable, while still in line with the decentralized model I was aiming for.
### Discovering a Hybrid Solution
After testing out various approaches, I realized that the breakthrough wasn’t just about Shamir’s Secret Sharing (SSS)—that part was fairly intuitive. The real insight came when I thought about how to preserve the original clock server design while solving the challenges of failover and early release.
Instead of having the clock servers store the secret or a share of it, **I kept the original design**: each clock server only holds a public-private key pair tied to a block height, as initially planned. The twist came when I decided to split an ephemeral AES key into shards using Shamir’s Secret Sharing, but instead of directly storing shares at the clock servers, we could encrypted each share with the public key of the clock server.
This approach would allow us to keep the clock server’s role simple:
When the time comes, the servers release their private keys, which can then be used to decrypt the encrypted shares of the AES key that were published alongside the original encrypted message. These shares, once decrypted, allow for the reconstruction of the AES key, which in turn decrypts the message.
This solution solved several key issues:
- ✅ **No Coordination Between Servers**: Each clock server only holds one key pair for a specific block height and doesn’t need to know about the other servers. This simplifies the system and removes the need for complex server coordination.
- ✅ **Minimal Overhead**: The clock servers only store a single key pair per block height, eliminating the need to store individual keys for each message.
- ✅ **Fault Tolerance**: If one clock server is offline, the other shares can still reconstruct the AES key and decrypt the message, ensuring reliability.
- ✅ **Client-Side Security**: The AES key is generated on the client side and never stored on the clock servers, providing a high level of security.
By combining the simplicity of the clock server model with the power of Shamir’s Secret Sharing, this hybrid solution allows us to securely split an AES key and manage decryption while ensuring the system remains decentralized, resilient, and efficient.
This was the method I had been searching for.
### The Process Breakdown
1. **AES Key Generation**:
- A **random AES key** is generated on the **client side** for each message. This key is **never stored** anywhere, ensuring that it remains secure and only used for encrypting the message.
2. **Shamir’s Secret Sharing**:
- The AES key is split into (in this example) **3 shares** using Shamir’s Secret Sharing. These shares are associated with **3 independent clock servers**.
- The threshold of **2 out of 3** means that only **2 clock servers** needed later to reconstruct the AES key and decrypt the message.
3. **Encrypting with Public Keys**:
- The secret shares are then **encrypted** using the **public keys** of the target block height for each specific clock server. This ensures that the shares are secure until the proper time comes.
4. **Storage**:
- The **encrypted shares** together with the **AES-encrypted message** can be published to Nostr relais or stored on a decentralized platform like **IPFS**, which provides redundancy and availability.
5. **Clock Servers Release Keys**:
- When the specified **Bitcoin block height** is reached, each clock server publishes its **private key** to Nostr, allowing everyone to decrypt the shares.
- The client reconstructs the AES key from the decrypted shares and finally decrypts the original message.

## Conclusion: An Elegant Solution to Time-Lock Encryption
Through a series of experiments and iterations, We finally landed on a solution that balances **security**, **scalability**, and **efficiency**. By combining **AES encryption** with **Shamir’s Secret Sharing**, We were able to solve the multi-sig failover problem without adding unnecessary complexity. 🔥
### An Open Question: Clock Server Incentives 💰
Decentralized systems thrive when participants are motivated to contribute. For Hatchstr, a critical question remains: Why would anyone run a clock server?
One possibility is allowing users to **zap** (tip) servers for each capsule they help unlock. But this is just a starting point—how do we ensure reliability without centralizing trust?
I’d love to hear your thoughts. How would you design incentives for a decentralized network of clock servers?
This part is crucial, and I’m excited to explore it with the community.
### What's Next for Hatchstr?
🧩 **Leveraging Nostr**: Let's see how we can integrate the Nostr NIP standards and previous protocol developments into our system to enhance communication and data integrity.
🔮 **Designing a Web App**: We'll explore building a user-friendly web application for creating and managing digital time capsules. Focus will be on enhancing usability, interface design, and user interaction.
🎛️ **Building a Clock Server with Elixir**: We'll delve into developing a simple clock server using Elixir, capitalizing on its strengths in concurrency and real-time processing to support our time-locking mechanisms.
Stay tuned as we advance both the user experience and the backend infrastructure of Hatchstr together.
If you're interested in following along or contributing to the development, feel free to reach out!
[Nostr QR](https://bafybeig6dmqshbd7khcd7qr7ce6inslx4muebtt3bk5m33f4dplsx4et7y.ipfs.w3s.link/nostr_qr.png)
```
npub16scfufrpsqcukjg7ymu4r40h7j4dwqy4pajgz48e6lmnmz5pljcqh678uh
```
Thank you for reading and being part of this journey! 🧡