Quantum computers pose a threat to traditional cryptography. Post-quantum (PQ) cryptography offers security against these threats, but PQ public keys come with usability challenges. They're big, cumbersome, and error-prone when manually shared. We built PQ Address to tackle these issues directly, creating a reliable and simple address format for PQ public keys. A PQ Address encodes the hash of a public key—meaning it’s strictly one-way. This makes PQ Addresses ideal for secure identity verification, integrity checks, or compactly referencing keys in distributed systems.
Here is a base64 encoded ML-DSA 44 public key (the smallest of the ML-DSA public key types)
e+ffcul9XkuQCkiCEYX2ES6KMGJ9c7+Z0PFfhnJRckbaHzh4EH9hcEkUoFZ4gK2ta6/xPzgxB1yTT92wPZw8SmrK3DeLMz9mkst0IWkSzJ/TPPHRcSYJekO+CLV8k7uXsGSSoK4fbLqkX8leQFMCzjzRYg06zb3SD7iQwK3O8dP2WWLa9PkBMl1LECCBtTHrxoqyYtKopNbn3wICOOxI1jjTTL46AZnE6Vw2vQdLB/Qg59Pq6su8P3zEqBbsVPwPpT9ZbBNCHE+puWjdYnOfttj6DZ748CRHibQ9WTkH+VpxssIxU62nsYes/fV85nDozwddZggZoLfRsmSlG1Yz6h4m5hMMu9Nku9myTTw4UCiGSxZmad+yIjl7hh6J3wDaLMDA6SXajLSXTk2RwmnsEUlYs+uXS6Wj5wzg+bLQDQVMkU+doOf4vPTArf4uwzJdZ9Ghp8vjHd+rQgKjuo+Hy+HWz4JgvaQXlln+3yF0eY4/v01Bhe8BwVCbFZX8ts2Ay53gJmZEtsnXw3d5xedAMO9LJt4UqwovnmWCuApzAG9jyvG3Wxxe572E725S4vLtgnESzfrsD3wWo/A0oP+wk4oOFjhRDdVwHzwBDiHPhl43b/lt6omQuxK+xF0BJ77X/VhAoCx5zwIQ1GnmtXmP5xqx8f+e9ceFWNSxBPVKakKx/BveCxF1uOLc7DZUFLDVxRBURiF4BQX/670+FaYF2BWS3XtxfCqxaCz3F177qUev3pYuwpvSIj6WNSmU8uyxvibSzvYtA50gQtznTfteWja14B8AB+rgagz5nEzRzO7u1+QmxbdvEyBKvmWzNtnvsNqee4LhU9sl6rPdyUScmDrCPVLiPhrqY/sBVfxzX6z40suflYFPYU+fE6lApXnpyDB8he25DmnmPYTEsCq9d2uYaYTSBAgeir0qi9Jnjj/mcJ/3sNwwTlh7Tp6ahJlqWEUJ4myGxcHEesgWAeIrqJ6bhHTxP1n+do4ffry4CMcAjoAPAwYY0JUTYANy722LbOgiN+z5KUryC/MYjw/azOHFcpYjsGR60fARG03yVBgNBuD5okkmxtrAGdS4w85UDMAa/dwobUI5bdigFHP0Av6hHQ5uxeaxt1gAO53veGmA8aIOidhtZyHhlv+ANl9VYyZMOdPP1DjBTd8AQTIGR2JglmGzE8/00Ndx736MNdVzxNG0iKOvLlgl3cd1cEjW6hfC47juSDCgZTs9oPeo2mr1qvtak7zVd/yByjP9KHh0mjCi3cZDButaTe/oic4bdf24xQDtahSEJpAf49i9gzIpqxG92pyM7HRaVSvScFmCNnNKLJSDCeYw4+zlU+jawGKPjX6ebFDGFV1gNiPvkZdYd/5UXFwpHt5saj/Lgfoe/BtJWUx53TNkYlTNytflgV/ssFo8k9aYlIq2SDDKeZdlZexeNJOvhr8yntOQzLK6WWVONUgilTFNKX3+NQTmMR1LhA7VSP17+/3NjM0wEaz/JpKRoqMMvrgzl2A/6s019UMoT81hGXNtk9Ed8vxtdeNi1BC+SHWWyazundxXMQ4/gD7PnJXQJduz0QZ8quxRQZZTn+u+t1hKyMQikRKqephJaIQv9NLnKffPncEii9ukfRuLLCy7hPFuAho1Bfgi6rJMN0AxlX9URe6LB6vjLMNdTvWVqCHtBvay4scJg58my00razBF8BhQe7db+UJiv5JwADSJ2fwO/oooReksH3Sv1U4UOx5Y7kK8bbChFg==
^ That's scrollable btw.
Here is the same public key encoded as a PQ Address:
yp1qpqg39uw700gcctpahe650p9zlzpnjt60cpz09m4kx7ncz8922635hs5cdx7q
When designing PQ Address, we aimed for clarity and efficiency. We prioritized four key features:
- Compact Representation: PQ keys are large. We use hashing to produce smaller, consistent-length representations.
- Error Detection: Robust checksums ensure errors like typos are caught immediately.
- Ease of Use: Addresses must be straightforward to read, write, and share without confusion.
- Clear Network Identification: Addresses explicitly indicate whether they're intended for testing or production environments.
We designed PQ Address around proven standards and clear logic:
We chose Bech32m (defined in Bitcoin’s BIP-350) for its practical benefits:
- Unambiguous character Set: Easy to visually confirm and transcribe.
- Case-Insensitive: Removes case-related confusion.
- Efficient Encoding: Optimized for shorter QR codes and compact data representation.
- Robust Checksums: Quickly detects input errors.
- Double clickable: Easy to copy and paste and move around.
PQ Address clearly distinguishes:
- Version bytes: range
0x00–0x3F
- Public key type bytes: range
0x40–0xFF
This prevents ambiguity and ensures any parsing error results in a clear and immediate failure, simplifying troubleshooting.
Addresses start with a Human Readable Prefix (HRP) to identify the network:
yp
for Mainnetrh
for Testnet
This reduces the risk of accidental deployments & use in the wrong environment.
Example address:
yp1qpqg39uw700gcctpahe650p9zlzpnjt60cpz09m4kx7ncz8922635hs5cdx7q
Breakdown:
- HRP:
yp
(indicating Mainnet) - Separator:
1
(constant) - Payload:
- Version byte
- Public key type byte
- Hashed public key
- Checksum: Last 6 characters is a BCH code to ensure data integrity.
PQ addresses have a fixed length of 64 characters for consistency.
Only 256-bit hashes 😱. SHA-256 remains secure against known quantum attacks like Grover's algorithm. Even if the hash were compromised, the revealed data is only the PQ-secure public key itself which is still protected against quantum threats such as Shor's algorithm.
The PQ Address design anticipates future developments in PQC. New public key algorithms and version updates can be integrated without disrupting existing addresses. The current design gives us the flexibility for up to 64 distinct versions and 192 different public key types. It’s important to note that a public key type consists of both the algorithm and parameter set. E.g ML_DSA_44
, ML_DSA_65
, SLH_DSA_SHA2_128F
, SLH_DSA_SHAKE_128S
. With NISTs first round of PQ standardization, there are eighteen distinct public key types across three distinct algorithms. This is will to grow considerably after further standardization of selected algorithms (FN-DSA & HQC) and the future rounds; here and here.
Use it, comment, and contribute! We have implemented PQ Address in Rust and Typescript: