
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Mon, 13 Apr 2026 16:55:03 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Cloudflare One is the first SASE offering modern post-quantum encryption across the full platform]]></title>
            <link>https://blog.cloudflare.com/post-quantum-sase/</link>
            <pubDate>Mon, 23 Feb 2026 06:00:00 GMT</pubDate>
            <description><![CDATA[ We’ve upgraded Cloudflare One to support post-quantum encryption by implementing the latest IETF drafts for hybrid ML-KEM into our Cloudflare IPsec product. This extends post-quantum encryption across all major Cloudflare One on-ramps and off-ramps. ]]></description>
            <content:encoded><![CDATA[ <p>During Security Week 2025, we launched the industry’s first cloud-native<a href="https://www.cloudflare.com/press/press-releases/2025/cloudflare-advances-industrys-first-cloud-native-quantum-safe-zero-trust/"> <u>post-quantum Secure Web Gateway (SWG) and Zero Trust solution</u></a>, a major step towards securing enterprise network traffic sent from end user devices to public and private networks.</p><p>But this is only part of the equation. To truly secure the future of enterprise networking, you need a complete <a href="https://www.cloudflare.com/learning/access-management/what-is-sase/"><u>Secure Access Service Edge (SASE)</u></a>. </p><p>Today, we complete the equation: Cloudflare One is the first SASE platform to support modern standards-compliant post-quantum (PQ) encryption in our Secure Web Gateway, and across Zero Trust and Wide Area Network (WAN) use cases.  More specifically, Cloudflare One now offers post-quantum hybrid ML-KEM (Module-Lattice-based Key-Encapsulation Mechanism) across all major on-ramps and off-ramps.</p><p>To complete the equation, we added support for post-quantum encryption to our <a href="https://developers.cloudflare.com/magic-wan/reference/gre-ipsec-tunnels/"><u>Cloudflare IPsec</u></a> (our cloud-native WAN-as-a-Service) and <a href="https://developers.cloudflare.com/magic-wan/configuration/connector/"><u>Cloudflare One Appliance</u></a> (our physical or virtual WAN appliance that establish Cloudflare IPsec connections). Cloudflare IPsec uses the <a href="https://www.cloudflare.com/learning/network-layer/what-is-ipsec/"><u>IPsec</u></a> protocol to establish encrypted tunnels from a customer’s network to Cloudflare’s global network, while IP <a href="https://www.cloudflare.com/learning/cdn/glossary/anycast-network/"><u>Anycast</u></a> is used to automatically route that tunnel to the nearest Cloudflare data center. Cloudflare IPsec simplifies configuration and provides high availability; if a specific data center becomes unavailable, traffic is automatically rerouted to the closest healthy data center. Cloudflare IPsec runs at the scale of our global network, and supports site-to-site across a WAN as well as outbound connections to the Internet.</p><p>The <a href="https://developers.cloudflare.com/magic-wan/configuration/connector/"><u>Cloudflare One Appliance</u></a> upgrade is generally available as of appliance version 2026.2.0. The <a href="https://developers.cloudflare.com/magic-wan/reference/gre-ipsec-tunnels/"><u>Cloudflare IPsec</u></a> upgrade is in closed beta, and you can request access by adding your name to our <a href="https://www.cloudflare.com/security-week/pq-ipsec-beta/"><u>closed beta list</u></a>.</p>
    <div>
      <h2>Post-quantum cryptography matters now</h2>
      <a href="#post-quantum-cryptography-matters-now">
        
      </a>
    </div>
    <p>Quantum threats are not a "next decade" problem. Here is why our customers are prioritizing <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/"><u>post-quantum cryptography (PQC)</u></a> today:</p><p><b>The deadline is approaching. </b>At the end of 2024, the National Institute of Standards and Technology (NIST) sent a <a href="https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf"><u>clear signal</u></a> (that has been <a href="https://www.bsi.bund.de/EN/Service-Navi/Presse/Pressemitteilungen/Presse2024/241127_Post-Quantum_Cryptography.html"><u>echoed</u></a> by other <a href="https://www.ncsc.gov.uk/guidance/pqc-migration-timelines"><u>agencies</u></a>): the era of classical public-key cryptography is coming to an end. NIST set a 2030 deadline for depreciating RSA and Elliptic Curve Cryptography (ECC) and <a href="https://www.cloudflare.com/pqc/"><u>transitioning to PQC</u></a> that cannot be broken by powerful quantum computers. Organizations that haven't begun their migration risk being out of compliance and vulnerable as the deadline nears.</p><p><b>Upgrades have historically been tricky. </b>While 2030 might seem far away, upgrading cryptographic algorithms is notoriously difficult. History has shown us that depreciating cryptography can take decades: we found examples of <a href="https://blog.cloudflare.com/radius-udp-vulnerable-md5-attack/"><u>MD5 causing problems 20 years after it was deprecated</u></a>. This lack of crypto agility — the ability to easily swap out cryptographic algorithms — is a major bottleneck. By integrating PQ encryption directly into <a href="https://www.cloudflare.com/zero-trust/"><u>Cloudflare One</u></a>, our SASE platform, we provide built-in crypto agility, simplifying how organizations offer remote access and site-to-site connectivity.</p><p><b>Data may already be at risk.</b> Finally, "Harvest Now, Decrypt Later" is a present and persistent threat, where attackers harvest sensitive network traffic today and then store it until quantum computers become powerful enough to decrypt it. If your data has a shelf life of more than a few years (e.g. financial information, health data, state secrets) it is already at risk unless it is protected by PQ encryption.</p>
    <div>
      <h3>The two migrations on the road to quantum safety: key agreement and digital signatures</h3>
      <a href="#the-two-migrations-on-the-road-to-quantum-safety-key-agreement-and-digital-signatures">
        
      </a>
    </div>
    <p>Transitioning network traffic to post-quantum cryptography (PQC) requires an overhaul of two cryptographic primitives: key agreement and digital signatures.  </p><p><b>Migration 1: Key establishment. </b>Key agreement allows two parties to establish a shared secret over an insecure channel; the shared secret is then used to encrypt network traffic, resulting in post-quantum encryption. The industry has largely converged on ML-KEM (Module-Lattice-based Key-Encapsulation Mechanism) as the standard PQ key agreement protocol. </p><p>ML-KEM has been widely adopted for use in <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a>, usually deployed alongside classical Elliptic Curve Diffie Hellman (ECDHE), where the key used to encrypt network traffic is derived by mixing the outputs of the ML-KEM and ECDHE key agreements. (This is also known as “hybrid ML-KEM”). Well over <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption"><u>60% of human-generated TLS traffic</u></a> to Cloudflare’s network is currently protected with hybrid ML-KEM. The transition to hybrid ML-KEM has been successful because it:</p><ul><li><p>stops "harvest-now, decrypt-later" attacks</p></li><li><p>does not require specialized hardware or specialized physical connectivity between client and server, unlike approaches like <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>Quantum Key Distribution (QKD)</u></a></p></li><li><p>has <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>little impact on performance</u></a>, even for short-lived TLS connections</p></li></ul><p>Because ML-KEM runs in <i>parallel </i>with classical ECDHE, there is no reduction in security and compliance as compared to the classical ECDHE approach.  </p><p><b>Migration 2: Digital signatures. </b>Meanwhile, digital signatures and certificates protect authenticity, stopping active adversaries from impersonating the server to the client. Unfortunately, PQ signatures are currently larger in size than classical ECC algorithms, which has slowed their adoption. Fortunately, the migration to PQ signatures is less urgent, because PQ signatures are designed to stop active adversaries armed with powerful quantum computers, which are not known to exist yet. Thus, while Cloudflare is actively contributing to the standardization and rollout of PQ digital signatures, the current Cloudflare IPsec upgrade focuses on upgrading key establishment to hybrid ML-KEM.  </p><p>The U.S. Cybersecurity &amp; Infrastructure Security Agency (CISA) recognized the nature of these two migrations in its <a href="https://www.cisa.gov/resources-tools/resources/product-categories-technologies-use-post-quantum-cryptography-standards"><u>January 2026 publication</u></a>, “Product Categories for Technologies That Use Post-Quantum Cryptography Standards.”</p>
    <div>
      <h2>Breaking new ground with IPsec </h2>
      <a href="#breaking-new-ground-with-ipsec">
        
      </a>
    </div>
    <p>To achieve a SASE fully protected with post-quantum encryption, we’ve upgraded our Cloudflare IPsec products to support hybrid ML-KEM in the IPsec protocol.</p><p>The IPsec community’s journey toward post-quantum cryptography has been very different from that of TLS. <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> is the de facto standard for encrypting public Internet traffic at Layer 4  — e.g. from a browser to a <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/"><u>content delivery network (CDN)</u></a> — so security and vendor interoperability are at the forefront of its design. Meanwhile, IPsec is a Layer 3 protocol that commonly connects devices built by the same vendor (e.g. two routers), so interoperability has historically been less of a concern. With this in mind, let’s take a look at IPsec’s journey into the quantum future. </p>
    <div>
      <h3>Pre-Shared Keys? Quantum key distribution?</h3>
      <a href="#pre-shared-keys-quantum-key-distribution">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/html/rfc8784"><u>RFC 8784</u></a>, published in May 2020, was intended to be the post-quantum update to IPsec Internet Key Exchange v2 (IKEv2), which is used to establish the symmetric keys used to encrypt IPsec network traffic. RFC 8784 implies the use of either long-lived pre-shared keys (PSK) or quantum key distribution (QKD). Neither of these approaches are very palatable.</p><p>RFC 8784 proposes mixing a PSK with a key derived from Diffie Hellman Exchange (DHE), essentially running PSK in hybrid with DHE. This approach protects against harvest-now-decrypt-later attackers, but does not offer <a href="https://blog.cloudflare.com/staying-on-top-of-tls-attacks/#forward-secrecy"><u>forward secrecy</u></a> against quantum adversaries. </p><p><a href="https://blog.cloudflare.com/staying-on-top-of-tls-attacks/#forward-secrecy"><u>Forward secrecy</u></a> is a standard desideratum of key agreement protocols. It ensures that a system is secure even if the long-lived key is leaked. The PSK approach in RFC 8784 is vulnerable to an harvest-now-decrypt-later adversary that also obtains a copy of a long-lived PSK, and can then decrypt traffic in the future (by breaking the DHE key agreement) once powerful quantum computers become available.</p><p>To solve this forward secrecy issue, RFC 8784 can instead be used to mix the key from the classical DHE with a freshly generated key derived from a QKD protocol.</p><p>QKD uses quantum mechanics to establish a shared, secret cryptographic key between two parties. Importantly, for QKD to work, the parties must have specialized hardware or be connected by a dedicated physical connection. This is a <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>significant limitation</u></a>, rendering QKD useless for common Internet use cases like connecting a laptop to a distant server over Wi-Fi. These limitations are also why we never invested in deploying QKD for Cloudflare IPsec. The U.S. <a href="https://www.nsa.gov/Cybersecurity/Quantum-Key-Distribution-QKD-and-Quantum-Cryptography-QC/"><u>National Security Agency (NSA)</u></a>, <a href="https://www.bsi.bund.de/EN/Themen/Unternehmen-und-Organisationen/Informationen-und-Empfehlungen/Quantentechnologien-und-Post-Quanten-Kryptografie/quantentechnologien-und-post-quanten-kryptografie_node.html"><u>Germany’s BSI</u></a> and the <a href="https://www.ncsc.gov.uk/whitepaper/quantum-security-technologies"><u>UK National Cyber Security Centre</u></a> have also warned against relying solely on QKD.</p>
    <div>
      <h3>But what about interoperability? </h3>
      <a href="#but-what-about-interoperability">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/html/rfc9370"><u>RFC 9370</u></a> landed in May 2023, specifying the use of hybrid key agreement rather than PSK or QKD. But unlike TLS, which only supports using post-quantum ML-KEM in parallel with classical DHE, this IPsec standard allows using up to <i>seven different key agreements to run at the same time</i> in parallel with classical Diffie Helman. Moreover, it doesn't specify details about what these key agreements should be, leaving it up to the vendors to choose their algorithms and implementations. Palo Alto Networks, for example, took this seriously and built support for over <a href="https://docs.paloaltonetworks.com/compatibility-matrix/reference/supported-cipher-suites/cipher-suites-supported-in-pan-os-11-2/cipher-suites-supported-in-pan-os-11-2-ipsec"><u>seven different PQC ciphersuites</u></a> into its next generation firewall (NGFW), most of which do not interoperate with other vendors and some of which have not yet been standardized by NIST.</p><p>Over the years, TLS has gone in the opposite direction, reducing the number of registered ciphersuites from hundreds in TLS 1.2, down to around five in TLS 1.3. This philosophy of reducing “ciphersuite bloat” is also in line with NIST’s <a href="https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf"><u>SP 800 52</u></a> from 2019.  The rationale for reducing “ciphersuite bloat” includes: </p><ul><li><p>Improved interoperability across vendors and regions</p></li><li><p>Lower risk of attacks that exploit downgrades to weak ciphersuites </p></li><li><p>Lower risk of security problems due to misconfiguration</p></li><li><p>Lower risk of implementation flaws by reducing the size of the codebase</p></li></ul><p>This is why we didn’t initially build support for RFC 9370. </p>
    <div>
      <h3>Standards that are finally on the right track</h3>
      <a href="#standards-that-are-finally-on-the-right-track">
        
      </a>
    </div>
    <p>It’s also why we were excited when the IPsec community put forth <a href="https://datatracker.ietf.org/doc/draft-ietf-ipsecme-ikev2-mlkem/"><u>draft-ietf-ipsecme-ikev2-mlkem</u></a>. This Internet-Draft standardizes PQ exchange for IPsec in the same way PQ key exchange has been widely deployed for TLS: hybrid ML-KEM. The new draft fills in the gaps in RFC 9370, by specifying how to run the ML-KEM as the additional key exchange in parallel with classical Diffie Hellman in IKEv2. </p><p>Now that this specification is available, we’ve moved forward with supporting post-quantum IPsec in our Cloudflare IPsec products. </p>
    <div>
      <h2>Cloudflare IPsec goes post-quantum</h2>
      <a href="#cloudflare-ipsec-goes-post-quantum">
        
      </a>
    </div>
    <p>Cloudflare IPsec is a WAN <a href="https://www.cloudflare.com/learning/network-layer/network-as-a-service-naas/"><u>Network-as-a-Service</u></a> solution that replaces legacy private network architectures by connecting data centers, branch offices, and cloud VPCs to Cloudflare’s global IP Anycast network. </p><p>With Cloudflare IPsec, Cloudflare’s network acts as the <a href="https://datatracker.ietf.org/doc/html/rfc5996"><u>IKEv2</u></a> Responder, awaiting connection requests from an IPsec initiator, which is a branch connector device in the customer’s network. Cloudflare IPsec supports IPsec sessions initiated by branch connectors that include our own Cloudflare One Appliance, along with branch connectors from a <a href="https://developers.cloudflare.com/magic-wan/reference/device-compatibility/"><u>diverse set of vendors</u></a>, including Cisco, Juniper, Palo Alto Networks, Fortinet, Aruba and others.</p><p>We’ve implemented production hybrid ML-KEM support in the Cloudflare IPsec IKEv2 Responder, as specified in <a href="https://datatracker.ietf.org/doc/draft-ietf-ipsecme-ikev2-mlkem/"><u>draft-ietf-ipsecme-ikev2-mlkem</u></a>. The draft requires a first key exchange to run using a classical Diffie Helman key exchange. The derived key is used to encrypt a second key exchange that is run using ML-KEM. Finally, the keys derived by the two exchanges are mixed and the result is used to secure the data plane traffic in IPsec ESP (Encapsulating Security Payload) mode. ESP mode uses symmetric cryptography and is thus already quantum safe without any additional upgrades.  We’ve tested our implementation against the IPsec Initiator in the <a href="https://strongswan.org/"><u>strongswan</u></a> reference implementation.</p><p>You can see the ciphersuite used in the IKEv2 negotiation by viewing the Cloudflare <a href="https://developers.cloudflare.com/logs/logpush/logpush-job/datasets/account/ipsec_logs/"><u>IPsec logs</u></a>.</p><p>We chose to implement hybrid ML-KEM rather than “pure” ML-KEM, i.e. only ML-KEM without DHE running in parallel, for two reasons. First, we’ve used hybrid ML-KEM across all of our other Cloudflare products, since this is the approach adopted across the TLS community. And second, it provides a “belt-and-suspenders” security: ML-KEM provides protection against quantum harvest-now-decrypt-later attacks, while DHE provides a tried-and-true algorithm against non-quantum adversaries.</p>
    <div>
      <h3>An invitation for interoperability</h3>
      <a href="#an-invitation-for-interoperability">
        
      </a>
    </div>
    <p>The full value of this implementation can be realized only via interoperability. For this reason, we are inviting other vendors that are building out support for IPsec Initiators in their branch connectors per <a href="https://datatracker.ietf.org/doc/draft-ietf-ipsecme-ikev2-mlkem/"><u>draft-ietf-ipsecme-ikev2-mlkem</u></a> to test against our Cloudflare IPsec implementation. Cloudflare customers looking to test out interoperability with third-party branch connectors while we are in closed beta can <a href="https://www.cloudflare.com/security-week/pq-ipsec-beta/"><u>sign up here</u></a>. We plan to GA and build out interoperability with other vendors as more begin to come online with support for <a href="https://datatracker.ietf.org/doc/draft-ietf-ipsecme-ikev2-mlkem/"><u>draft-ietf-ipsecme-ikev2-mlkem</u></a>.</p>
    <div>
      <h3>Quantum-safe hardware: the Cloudflare One Appliance</h3>
      <a href="#quantum-safe-hardware-the-cloudflare-one-appliance">
        
      </a>
    </div>
    <p>Many of our customers purchase their branch connector (hardware or virtualized) from Cloudflare, rather than a third-party vendor. That’s why the <a href="https://developers.cloudflare.com/magic-wan/configuration/connector/"><u>Cloudflare One Appliance</u></a> — our plug-and-play appliance that connects your local network to Cloudflare One — has also been upgraded with post-quantum encryption.</p><p>Cloudflare One Appliance does not use IKEv2 for key agreement or session establishment, opting instead to rely on TLS. The appliance periodically initiates a TLS handshake with the Cloudflare edge, shares a symmetric secret over the resulting TLS connection, then injects that symmetric secret into the ESP layer of IPsec, which then encrypts and authenticates the IPsec data plane traffic. This design allowed us to avoid building out IKEv2 Initiator logic, and makes the Connector easier to maintain using our existing TLS libraries. </p><p>Thus, upgrading Cloudflare One Appliance to PQ encryption was just a matter of upgrading TLS 1.2 to TLS 1.3 with hybrid ML-KEM — something we’ve done many times on different products at Cloudflare. </p>
    <div>
      <h3>How do I turn this on? And what does it cost?</h3>
      <a href="#how-do-i-turn-this-on-and-what-does-it-cost">
        
      </a>
    </div>
    <p>As always, this upgrade to Cloudflare IPsec comes at no extra cost to our customers. Because we believe that a secure and private Internet should be accessible to all, we’re on a mission to include PQC in all our <a href="https://blog.cloudflare.com/post-quantum-cryptography-ga/"><u>products</u></a>, without <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>specialized hardware</u></a>, at <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free/"><u>no extra cost</u></a> to our customers and end users.</p><p>Customers using the Cloudflare One Appliance obtained this upgrade to PQC in version 2026.2.0 (released 2026-02-11). The upgrade is pushed automatically (with no customer action required) according to each appliance’s configured interrupt window.</p><p>For customers using Cloudflare IPsec with another vendor’s branch connector appliance, we will be interoperating with these once more support for <a href="https://datatracker.ietf.org/doc/draft-ietf-ipsecme-ikev2-mlkem/"><u>draft-ietf-ipsecme-ikev2-mlkem</u></a> comes online. <a href="https://www.cloudflare.com/security-week/pq-ipsec-beta/"><u>You can also contact us</u></a> directly to get access to closed beta and request that we interoperate with a specific vendor’s branch connector.</p>
    <div>
      <h2>The full picture: post-quantum SASE</h2>
      <a href="#the-full-picture-post-quantum-sase">
        
      </a>
    </div>
    <p>The value proposition for a post-quantum SASE is clear: organizations can obtain immediate end-to-end protection for their private network traffic by sending it over tunnels protected by hybrid ML-KEM. This protects traffic from  harvest-now-decrypt-later attacks, even if the individual applications in the corporate network are not yet upgraded to PQC.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xK6FEbQYw9vLJKgx0bHp6/c4b584cc95adc5f8320d03c86b8fe38c/Cloudflare-s_post-quantum_SASE_2.png" />
          </figure><p>The diagram above shows how post-quantum hybrid ML-KEM is offered in various Cloudflare One network configurations.  It includes the following on-ramps:</p><ul><li><p>clientless (<a href="https://blog.cloudflare.com/post-quantum-zero-trust/"><u>TLS 1.3 with hybrid ML-KEM</u></a> (assuming the browser supports hybrid ML-KEM))</p></li><li><p>Cloudflare One Client (<a href="https://blog.cloudflare.com/post-quantum-warp/"><u>MASQUE over TLS 1.3 with hybrid ML-KEM</u></a> initiated by the device client)</p></li><li><p>Cloudflare IPsec on-ramp (as described in this blog)</p></li></ul><p>and the following off-ramps:</p><ul><li><p>Cloudflare Tunnel off-ramp (<a href="https://blog.cloudflare.com/post-quantum-tunnel/"><u>TLS 1.3 with hybrid ML-KEM tunnel</u></a> initiated by the cloudflared server agent)</p></li><li><p>Cloudflare IPsec off-ramp (as described in this blog)</p></li></ul><p>The diagram below highlights a sample network configuration that uses the Cloudflare One Client on-ramp to connect a device to a server behind a Cloudflare One Appliance offramp. The end user's device connects to the Cloudflare network (link 1) using <a href="https://blog.cloudflare.com/post-quantum-warp/"><u>MASQUE with hybrid ML-KEM</u></a>. The traffic then travels across Cloudflare’s global network over TLS 1.3 with hybrid ML-KEM (link 2). Traffic then leaves the Cloudflare network over a post-quantum Cloudflare IPsec link (link 3) that is terminated at a Cloudflare One Appliance appliance. Finally it connects to a server inside the customer’s environment. Traffic is protected by post-quantum cryptography as it travels over the public Internet, even if the server itself does not support post-quantum cryptography.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2mrF4j8VDBGOzGEQNCobo4/b78ae6bef6f1152d92c9f63102aa8491/image4.png" />
          </figure><p>Finally, we note that traffic that on-ramps to Cloudflare One and then egresses to the public Internet can also be protected by our post-quantum <a href="https://developers.cloudflare.com/cloudflare-one/traffic-policies/http-policies/tls-decryption/#post-quantum-support"><u>Cloudflare Gateway</u></a>, our Secure Web Gateway (SWG).  Here’s a diagram showing how the SWG works:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3j3uN3x5oyUZBWbXIECxzA/9f2fd83cc567c8e511de08dd86ee462f/image2.png" />
          </figure><p> As discussed in <a href="https://blog.cloudflare.com/post-quantum-zero-trust/#quantum-safe-swg-end-to-end-pqc-for-access-to-third-party-web-applications"><u>an earlier blog post</u></a>, our SWG can already support hybrid ML-KEM on traffic from SWG to the origin server (as long as the origin supports hybrid ML-KEM), and on traffic from the client to the SWG (if the client supports hybrid ML-KEM, which is the case for most modern browsers). Importantly, any traffic that onramps to the SWG via a device that has Cloudflare One Client installed is still protected with hybrid ML-KEM — even if the web browser itself does not yet support post-quantum cryptography. This is due to the <a href="https://blog.cloudflare.com/post-quantum-warp/"><u>post-quantum MASQUE tunnel</u></a> that the Cloudflare One Client establishes to Cloudflare’s global network.  The same is true of traffic that onramps to the SWG via a post-quantum Cloudflare IPsec tunnel.</p><p>Putting it all together, Cloudflare One now offers post-quantum encryption on our TLS, MASQUE and IPsec on-ramp and off-ramps, and for private network traffic, and to traffic that egresses to the public Internet via our SWG. </p>
    <div>
      <h2>The future is quantum-safe</h2>
      <a href="#the-future-is-quantum-safe">
        
      </a>
    </div>
    <p>By completing the post-quantum SASE equation with Cloudflare IPsec and the Cloudflare One Appliance, we have extended post-quantum encryption across all our major on-ramps and off-ramps. We have intentionally chosen the path of interoperability and simplicity — the hybrid ML-KEM approach that the IETF and NIST have championed, rather than locking our customers into proprietary implementations, “ciphersuite bloat," or unnecessary hardware upgrades. </p><p>This is the promise of Cloudflare One: a SASE platform that is not only faster and more reliable than the legacy architectures it replaces, but one that provides post-quantum encryption. Whether you are securing a remote worker’s browser or a multi-gigabit data center link, you can now do so with the confidence that your data is protected from harvest-now-decrypt-later attacks and other future-looking threats.  </p><p><a href="https://www.cloudflare.com/lp/pqc/"><u>Sign up here</u></a> to get a full demo of our post-quantum capabilities across the Cloudflare One SASE platform, or <a href="https://www.cloudflare.com/security-week/pq-ipsec-beta/"><u>register here</u></a> to get on the list for the Cloudflare IPsec closed beta. We are proud to lead the industry into this new era of cryptography, and we invite you to join us in building a scalable, standards-compliant, and post-quantum Internet.</p> ]]></content:encoded>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <category><![CDATA[IPsec]]></category>
            <guid isPermaLink="false">4R1725ncbcxxmKyZueXmhw</guid>
            <dc:creator>Sharon Goldberg</dc:creator>
            <dc:creator>Amos Paul</dc:creator>
            <dc:creator>David Gauch</dc:creator>
        </item>
        <item>
            <title><![CDATA[Policy, privacy and post-quantum: anonymous credentials for everyone]]></title>
            <link>https://blog.cloudflare.com/pq-anonymous-credentials/</link>
            <pubDate>Thu, 30 Oct 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ The world is adopting anonymous credentials for digital privacy, but these systems are vulnerable to quantum computers. This post explores the cryptographic challenges and promising research paths toward building new, quantum-resistant credentials from the ground up. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Internet is in the midst of one of the most complex transitions in its history: the migration to <a href="https://www.cloudflare.com/en-gb/pqc/"><u>post-quantum (PQ) cryptography.</u></a> Making a system safe against quantum attackers isn't just a matter of replacing elliptic curves and RSA with PQ alternatives, such as <a href="https://csrc.nist.gov/pubs/fips/203/final"><u>ML-KEM</u></a> and <a href="https://csrc.nist.gov/pubs/fips/204/final"><u>ML-DSA</u></a>. These algorithms have higher costs than their classical counterparts, making them unsuitable as drop-in replacements in many situations.</p><p>Nevertheless, we're <a href="https://blog.cloudflare.com/pq-2025/"><u>making steady progress</u></a> on the most important systems. As of this writing, <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption"><u>about 50%</u></a> of <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS connections</u></a> to Cloudflare's edge are safe against <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>store-now/harvest-later attacks</u></a>. Quantum safe authentication is further out, as it will require more significant changes to how certificates work. Nevertheless, this year we've <a href="https://blog.cloudflare.com/bootstrap-mtc/"><u>taken a major step</u></a> towards making TLS deployable at scale with PQ certificates.</p><p>That said, TLS is only the lowest hanging fruit. There are <a href="https://github.com/fancy-cryptography/fancy-cryptography"><u>many more ways</u></a> we have come to rely on cryptography than key exchange and authentication and which aren’t as easy to migrate. In this blog post, we'll take a look at <b>Anonymous Credentials (ACs)</b>.</p><p>ACs solve a common privacy dilemma: how to prove a specific fact (for example that one has had a valid driver’s license for more than three years) without over-sharing personal information (like the place of birth)? Such problems are fundamental to a number of use cases, and ACs may provide the foundation we need to make these applications as private as possible.</p><p>Just like for TLS, the central question for ACs is whether there are drop-in, PQ replacements for its classical primitives that will work at the scale required, or will it be necessary to re-engineer the application to mitigate the cost of PQ.</p><p>We'll take a stab at answering this question in this post. We'll focus primarily on an emerging use case for ACs described in a <a href="https://blog.cloudflare.com/private-rate-limiting/"><u>concurrent post</u></a>: rate-limiting requests from agentic AI platforms and users. This demanding, high-scale use case is the perfect lens through which to evaluate the practical readiness of today's post-quantum research. We'll use it as our guiding problem to measure each cryptographic approach.</p><p>We'll first explore the current landscape of classical AC adoption across the tech industry and the public sector. Then, we’ll discuss what cryptographic researchers are currently looking into on the post-quantum side. Finally, we’ll take a look at what it'll take to bridge the gap between theory and real-world applications.</p><p>While anonymous credentials are only seeing their first real-world deployments in recent years, it is critical to start thinking about the post-quantum challenge concurrently. This isn’t a theoretical, too-soon problem given the store-now decrypt-later threat. If we wait for mass adoption before solving post-quantum anonymous credentials, ACs risk being dead on arrival. Fortunately, our survey of the state of the art shows the field is close to a practical solution. Let’s start by reviewing real-world use-cases of ACs. </p>
    <div>
      <h2>Real world (classical) anonymous credentials</h2>
      <a href="#real-world-classical-anonymous-credentials">
        
      </a>
    </div>
    <p>In 2026, the European Union is <a href="https://eur-lex.europa.eu/eli/reg/2024/1183/oj"><u>set to launch its digital identity wallet</u></a>, a system that will allow EU citizens, residents and businesses to digitally attest to their personal attributes. This will enable them, for example, to display their driver’s license on their phone or <a href="https://educatedguesswork.org/posts/age-verification-id/"><u>perform age</u></a> <a href="https://soatok.blog/2025/07/31/age-verification-doesnt-need-to-be-a-privacy-footgun/"><u>verification</u></a>. Cloudflare's use cases for ACs are a bit different and revolve around keeping our customers secure by, for example, rate limiting bots and humans as we <a href="https://blog.cloudflare.com/privacy-pass-standard/"><u>currently do with Privacy Pass</u></a>. The EU wallet is a massive undertaking in identity provisioning, and our work operates at a massive scale of traffic processing. Both initiatives are working to solve a shared fundamental problem: allowing an entity to prove a specific attribute about themselves without compromising their privacy by revealing more than they have to.</p><p>The EU's goal is a fully mobile, secure, and user-friendly digital ID. The current technical plan is ambitious, as laid out in the <a href="https://ec.europa.eu/digital-building-blocks/sites/spaces/EUDIGITALIDENTITYWALLET/pages/900014854/Version+2.0+of+the+Architecture+and+Reference+Framework+now+available"><u>Architecture Reference Framework (ARF)</u></a>. It defines the key privacy goals of unlinkability to guarantee that if a user presents attributes multiple times, the recipients cannot link these separate presentations to conclude that they concern the same user. However, currently proposed solutions fail to achieve this. The framework correctly identifies the core problem: attestations contain <i>unique, fixed elements such as hash values, […], public keys, and signatures</i> that colluding entities could store and compare to track individuals.</p><p>In its present form, the ARF's recommendation to mitigate cross-session linkability is <i>limited-time attestations</i>. The framework acknowledges in the text that this would <i>only partially mitigate Relying Party linkability</i>. An alternative proposal that would mitigate linkability risks are single-use credentials. They are not considered at the moment due to <i>complexity and management overhead</i>. The framework therefore leans on <i>organisational and enforcement measure</i>s to deter collusion instead of providing a stronger guarantee backed by cryptography.</p><p>This reliance on trust assumptions could become problematic, especially in the sensitive context of digital identity. When asked for feedback, c<a href="https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/issues/200"><u>ryptographic researchers agree</u></a> that the proper solution would be to adopt anonymous credentials. However, this solution presents a long-term challenge. Well-studied methods for anonymous credentials, such as those based on <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-bbs-signatures/"><u>BBS signatures</u></a>, are vulnerable to quantum computers. While some <a href="https://datatracker.ietf.org/doc/rfc9474/"><u>anonymous</u></a> <a href="https://datatracker.ietf.org/doc/draft-schlesinger-cfrg-act/"><u>schemes</u></a> are PQ-unlinkable, meaning that user privacy is preserved even when cryptographically relevant quantum computers exist, new credentials could be forged. This may be an attractive target for, say, a nation state actor.</p><p>New cryptography also faces deployment challenges: in the EU, only approved cryptographic primitives, as listed in the <a href="https://www.sogis.eu/documents/cc/crypto/SOGIS-Agreed-Cryptographic-Mechanisms-1.3.pdf"><u>SOG-IS catalogue,</u></a> can be used. At the time of writing, this catalogue is limited to established algorithms such as RSA or ECDSA. But when it comes to post-quantum cryptography, SOG-IS is <a href="https://www.sogis.eu/documents/cc/crypto/SOGIS-Agreed-Cryptographic-Mechanisms-1.3.pdf"><u>leaving the problem wide open</u></a>.</p><p>The wallet's first deployment will not be quantum-secure. However, with the transition to post-quantum algorithms being ahead of us, as soon as 2030 for high-risk use cases per <a href="https://digital-strategy.ec.europa.eu/en/library/coordinated-implementation-roadmap-transition-post-quantum-cryptography"><u>the EU roadma</u></a>p, research in a post-quantum compatible alternative for anonymous credentials is critical. This will encompass<b> </b><i>standardizing more cryptography.</i></p><p>Regarding existing large scale deployments, the US has allowed digital ID on smartphones since 2024. They <a href="https://www.tsa.gov/digital-id/participating-states"><u>can be used at TSA checkpoints</u></a> for instance. The <a href="https://www.dhs.gov/science-and-technology/privacy-preserving-digital-credential-wallets-verifiers"><u>Department of Homeland Security lists funding for six privacy-preserving digital credential wallets and verifiers on their website.</u></a> This early exploration and engagement is a positive sign, and highlights the need to plan for privacy-preserving presentations. </p><p>Finally, ongoing efforts at the Internet Engineering Task Force (IETF)<b> </b>aim<b> </b>to build a more private Internet by standardizing advanced cryptographic techniques. Active individual drafts (i.e., not yet adopted by a working group), such as <a href="https://datatracker.ietf.org/doc/draft-google-cfrg-libzk/"><u>Longfellow</u></a> and Anonymous Credit Tokens (<a href="https://datatracker.ietf.org/doc/draft-schlesinger-cfrg-act/"><u>ACT</u></a>), and adopted drafts like Anonymous Rate-limited Credentials (<a href="https://datatracker.ietf.org/doc/draft-yun-privacypass-crypto-arc/"><u>ARC</u></a>), propose more flexible multi-show anonymous credentials that incorporate developments over the last several years. At IETF 117 in 2023, <a href="https://www.irtf.org/anrw/2023/slides-117-anrw-sessc-not-so-low-hanging-fruit-security-and-privacy-research-opportunities-for-ietf-protocols-00.pdf"><u>post-quantum anonymous credentials and deployable generic anonymous credentials were presented as a research opportunity</u></a>. Check out our <a href="https://blog.cloudflare.com/private-rate-limiting/"><u>post on rate limiting agents</u></a> for details.</p><p>Before we get into the state-of-the-art for PQ, allow us to try to crystalize a set of requirements for real world applications.</p>
    <div>
      <h3>Requirements</h3>
      <a href="#requirements">
        
      </a>
    </div>
    <p>Given the diversity of use cases, adoption of ACs will be made easier by the fact that they can be built from a handful of powerful primitives. (More on this in our <a href="https://blog.cloudflare.com/private-rate-limiting/"><u>concurrent post</u></a>.) As we'll see in the next section, we don't yet have drop-in, PQ alternatives for these kinds of primitives. The "building blocks" of PQ ACs are likely to look quite different, and we're going to know something about what we're building towards.</p><p>For our purposes, we can think of an anonymous credential as a kind of fancy <a href="https://en.wikipedia.org/wiki/Blind_signature"><b><u>blind signature</u></b></a>. What's that you ask? A blind signature scheme has two phases: <b>issuance</b>, in which the server signs a message chosen by the client; and <b>presentation</b>, in which the client reveals the message and the signature to the server. The scheme should be <b>unlinkable</b> in the sense that the server can't link any message and signature to the run of the issuance protocol in which it was produced. It should also be <b>unforgeable</b> in the sense that no client can produce a valid signature without interacting with the server.</p><p>The key difference between ACs and blind signatures is that, during presentation of an AC, the client only presents <i>part of the message</i> in plaintext; the rest of the message is kept secret. Typically, the message has three components:</p><ol><li><p>Private <b>state</b>, such as a counter that, for example, keeps track of the number of times the credential was presented. The client would prove to the server that the state is "valid", for example, a counter with value $0 \leq C \leq N$, without revealing $C$. In many situations, it's desirable to allow the server to update this state upon successful presentation, for example, by decrementing the counter. In the context of rate limiting, this is the number of how many requests are left for a credential.</p></li><li><p>A random value called the <b>nullifier</b> that is revealed to the server during presentation. In rate-limiting, the nullifier prevents a user from spending a credential with a given state more than once.</p></li><li><p>Public <b>attributes</b> known to both the client and server that bind the AC to some application context. For example, this might represent the window of time in which the credential is valid (without revealing the exact time it was issued).</p></li></ol><p>Such ACs are well-suited for rate limiting requests made by the client. Here the idea is to prevent the client from making more than some maximum number of requests during the credential's lifetime. For example, if the presentation limit is 1,000 and the validity window is one hour, then the clients can make up to 0.27 requests/second on average before it gets throttled.</p><p>It's usually desirable to enforce rate limits on a <b>per-origin</b> basis. This means that if the presentation limit is 1,000, then the client can make at most 1,000 requests to any website that can verify the credential. Moreover, it can do so safely, i.e., without breaking unlinkability across these sites.</p><p>The current generation of ACs being considered for standardization at IETF are only <b>privately verifiable,</b> meaning the server issuing the credential (the <b>issuer</b>) must share a private key with the server verifying the credential (the <b>origin</b>). This will be sufficient for some deployment scenarios, but many will require <b>public verifiability</b>, where the origin only needs the issuer's public key. This is possible with BBS-based credentials, for example.</p><p>Finally, let us say a few words about round complexity. An AC is <b>round optimal</b> if issuance and presentation both complete in a single HTTP request and response. In our survey of PQ ACs, we found a number of papers that discovered neat tricks that reduce bandwidth (the total number of bits transferred between the client and server) at the cost of additional rounds. However, for use cases like ours, <b>round optimality</b> is an absolute necessity, especially for presentation. Not only do multiple rounds have a high impact on latency, they also make the implementation far more complex.</p><p>Within these constraints, our goal is to develop PQ ACs that have as low communication cost (i.e., bandwidth consumption) and runtime as possible in the context of rate-limiting.</p>
    <div>
      <h2>"Ideal world" (PQ) anonymous credentials</h2>
      <a href="#ideal-world-pq-anonymous-credentials">
        
      </a>
    </div>
    <p>The academic community has produced a number of promising post-quantum ACs. In our survey of the state of the art, we evaluated several leading schemes, scoring them on their underlying primitives and performance to determine which are truly ready for the Internet. To understand the challenges, it is essential to first grasp the cryptographic building blocks used in ACs today. We’ll now discuss some of the core concepts that frequently appear in the field.</p>
    <div>
      <h3>Relevant cryptographic paradigms</h3>
      <a href="#relevant-cryptographic-paradigms">
        
      </a>
    </div>
    
    <div>
      <h4>Zero-knowledge proofs</h4>
      <a href="#zero-knowledge-proofs">
        
      </a>
    </div>
    <p>Zero-knowledge proofs (ZKPs) are a cryptographic protocol that allows a <i>prover</i> to convince a <i>verifier</i> that a statement is true without revealing the secret information, or <i>witness</i>. ZKPs play a central role in ACs: they allow proving statements of the secret part of the credential's state without revealing the state itself. This is achieved by transforming the statement into a mathematical representation, such as a set of polynomial equations over a finite field. The prover then generates a proof by performing complex operations on this representation, which can only be completed correctly if they possess the valid witness.</p><p>General-purpose ZKP systems, like <a href="https://eprint.iacr.org/2018/046"><u>Scalable Transparent Arguments of Knowledge (STARKs)</u></a>, can prove the integrity of <i>any</i> computation up to a certain size. In a STARK-based system, the computational trace is represented as a <i>set of polynomials</i>. The prover then constructs a proof by evaluating these polynomials and committing to them using cryptographic hash functions. The verifier can then perform a quick probabilistic check on this proof to confirm that the original computation was executed correctly. Since the proof itself is just a collection of hashes and sampled polynomial values, it is secure against quantum computers, providing a statistically sound guarantee that the claimed result is valid.</p>
    <div>
      <h4>Cut-and-Choose</h4>
      <a href="#cut-and-choose">
        
      </a>
    </div>
    <p>Cut-and-choose is a cryptographic technique designed to ensure a prover’s honest behaviour by having a verifier check a random subset of their work. The prover first commits to multiple instances of a computation, after which the verifier randomly chooses a portion to be <i>cut open</i> by revealing the underlying secrets for inspection. If this revealed subset is correct, the verifier gains high statistical confidence that the remaining, un-opened instances are also correct.</p><p>This technique is important because while it is a generic tool used to build protocols secure against malicious adversaries, it also serves as a crucial case study. Its security is not trivial; for example, practical attacks on cut-and-choose schemes built with (post-quantum) homomorphic encryption have succeeded by <a href="https://eprint.iacr.org/2025/1890.pdf"><u>attacking the algebraic structure of the encoding</u></a>, not the encryption itself. This highlights that even generic constructions must be carefully analyzed in their specific implementation to prevent subtle vulnerabilities and information leaks.</p>
    <div>
      <h4>Sigma Protocols</h4>
      <a href="#sigma-protocols">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-sigma-protocols/01/"><u>Sigma protocols</u></a> follow a more structured approach that does not require us to throw away any computations. The <a href="https://pages.cs.wisc.edu/~mkowalcz/628.pdf"><u>three-move protocol</u></a> starts with a <i>commitment</i> phase where the prover generates some randomness<i>,</i> which is added to the input to generate the commitment, and sends the commitment to the verifier. Then, the verifier <i>challenges </i>the prover with an unpredictable challenge. To finish the proof, the prover provides a <i>response</i> in which they combine the initial randomness with the verifier’s challenge in a way that is only possible if the secret value, such as the solution to a discrete logarithm problem, is known.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ihEZ5KhWBQ0PZF5pTc0Bi/e35de03a89af0c2254bcc114041f6904/image4.png" />
          </figure><p><sup>Depiction of a Sigma protocol flow, where the prover commits to their witness $w$, the verifier challenges the prover to prove knowledge about $w$, and the prover responds with a mathematical statement that the verifier can either accept or reject.</sup></p><p>In practice, the prover and verifier don't run this interactive protocol. Instead, they make it non-interactive using a technique known as the <a href="https://link.springer.com/content/pdf/10.1007/3-540-47721-7_12.pdf"><u>Fiat-Shamir transformation</u></a>. The idea is that the prover generates the challenge <i>itself</i>, by deriving it from its own commitment. It may sound a bit odd, but it works quite well. In fact, it's the basis of signatures like ECDSA and even PQ signatures like ML-DSA.</p>
    <div>
      <h4>MPC in the head</h4>
      <a href="#mpc-in-the-head">
        
      </a>
    </div>
    <p>Multi-party computation (MPC) is a cryptographic tool that allows multiple parties to jointly compute a function over their inputs without revealing their individual inputs to the other parties. <a href="https://web.cs.ucla.edu/~rafail/PUBLIC/77.pdf"><u>MPC in the Head</u></a> (MPCitH) is a technique to generate zero-knowledge proofs by simulating a multi-party protocol <i>in the head</i> of the prover.</p><p>The prover simulates the state and communication for each virtual party, commits to these simulations, and shows the commitments to the verifier. The verifier then challenges the prover to open a subset of these virtual parties. Since MPC protocols are secure even if a minority of parties are dishonest, revealing this subset doesn't leak the secret, yet it convinces the verifier that the overall computation was correct. </p><p>This paradigm is particularly useful to us because it's a flexible way to build post-quantum secure ZKPs. MPCitH constructions build their security from symmetric-key primitives (like hash functions). This approach is also transparent, requiring no trusted setup. While STARKs share these post-quantum and transparent properties, MPCitH often offers faster prover times for many computations. Its primary trade-off, however, is that its proofs scale linearly with the size of the circuit to prove, while STARKs are succinct, meaning their proof size grows much slower.</p>
    <div>
      <h4>Rejection sampling</h4>
      <a href="#rejection-sampling">
        
      </a>
    </div>
    <p>When a randomness source is biased or outputs numbers outside the desired range, rejection sampling can correct the distribution. For example, imagine you need a random number between 1 and 10, but your computer only gives you random numbers between 0 and 255. (Indeed, this is the case!) The rejection sampling algorithm calls the RNG until it outputs a number below 11 and above 0: </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ogslPSn4DJYx3R5jGZ3mi/7ab640864dc26d6e1e2eb53c25f628ea/image6.png" />
          </figure><p>Calling the generator over and over again may seem a bit wasteful. An efficient implementation can be realized with an eXtendable Output Function (XOF). A XOF takes an input, for example a seed, and computes an arbitrarily-long output. An example is the SHAKE family (part of the <a href="https://csrc.nist.gov/pubs/fips/202/final"><u>SHA3 standard</u></a>), and the recently proposed round-reduced version of SHAKE called <a href="https://datatracker.ietf.org/doc/rfc9861/"><u>TurboSHAKE</u></a>.</p><p>Let’s imagine you want to have three numbers between 1 and 10. Instead of calling the XOF over and over, you can also ask the XOF for several bytes of output. Since each byte has a probability of 3.52% to be in range, asking the XOF for 174 bytes is enough to have a greater than 99% chance of finding at least three usable numbers. In fact, we can be even smarter than this: 10 fits in four bits, so we can split the output bytes into lower and higher <a href="https://en.wikipedia.org/wiki/Nibble"><u>nibbles</u></a>. The probability of a nibble being in the desired range is now 56.4%:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4W98tjgA7gIkaM7A5LBMyi/7b12bbfd22e53b84439a7c9e690605d9/image2.png" />
          </figure><p><sup>Rejection sampling by batching queries. </sup></p><p>Rejection sampling is a part of many cryptographic primitives, including many we'll discuss in the schemes we look at below.</p>
    <div>
      <h3>Building post-quantum ACs</h3>
      <a href="#building-post-quantum-acs">
        
      </a>
    </div>
    <p>Classical anonymous credentials (ACs), such as ARC and ACT, are built from algebraic groups- specifically, elliptic curves, which are very efficient. Their security relies on the assumption that certain mathematical problems over these groups are computationally hard. The premise of post-quantum cryptography, however, is that quantum computers can solve these supposedly hard problems. The most intuitive solution is to replace elliptic curves with a post-quantum alternative. In fact, cryptographers have been working on a replacement for a number of years: <a href="https://eprint.iacr.org/2018/383"><u>CSIDH</u></a>. </p><p>This raises the key question: can we simply adapt a scheme like ARC by replacing its elliptic curves with CSIDH? The short answer is <b>no</b>, due to a critical roadblock in constructing the necessary zero-knowledge proofs. While we can, in theory, <a href="https://eprint.iacr.org/2023/1614"><u>build the required Sigma protocols or MPC-in-the-Head (MPCitH) proofs from CSIDH</u></a>, they have a prerequisite that makes them unusable in practice: they require a <b>trusted setup</b> to ensure the prover cannot cheat. This requirement is a non-starter, as <a href="https://eprint.iacr.org/2022/518"><u>no algorithm for performing a trusted setup in CSIDH exists</u></a>. The trusted setup for sigma protocols can be replaced by a combination of <a href="https://eprint.iacr.org/2016/505"><u>generic techniques from multi-party computation</u></a> and cut-and-choose protocols, but that adds significant computation cost to the already computationally expensive isogeny operations.</p><p>This specific difficulty highlights a more general principle. The high efficiency of classical credentials like ARC is deeply tied to the rich algebraic structure of elliptic curves. Swapping this component for a post-quantum alternative, or moving to generic constructions, fundamentally alters the design and its trade-offs. We must therefore accept that post-quantum anonymous credentials cannot be a simple "lift-and-shift" of today's schemes. They will require new designs built from different cryptographic primitives, such as lattices or hash functions.</p>
    <div>
      <h3>Prefabricated schemes from generic approaches</h3>
      <a href="#prefabricated-schemes-from-generic-approaches">
        
      </a>
    </div>
    <p>At Cloudflare, we explored a <a href="https://eprint.iacr.org/2023/414"><u>post-quantum privacy pass construction in 2023</u></a> that closely resembles the functionality needed for anonymous credentials. The main result is a generic construction that composes separate, quantum-secure building blocks: a digital signature scheme and a general-purpose ZKP system:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4dpmFzSv7HG5JHEEqu7D9o/ea1f02c37c0e36dc0972dfd1044fa9a3/image8.png" />
          </figure><p>The figure shows a cryptographic protocol divided into two main phases: (1.) Issuance: The user commits to a message (without revealing it) and sends the commitment to the server. The server signs the commitment and returns this signed commitment, which serves as a token. The user verifies the server's signature. (2.) Redemption: To use the token, the user presents it and constructs a proof. This proof demonstrates they have a valid signature on the commitment and opens the commitment to reveal the original message. If the server validates the proof, the user and server continue (e.g., to access a rate-limited origin).</p><p>The main appeal of this modular design is its flexibility. The experimental <a href="https://github.com/guruvamsi-policharla/zkdilithium"><u>implementation</u></a> uses a modified version of the signature ML-DSA signatures and STARKs, but the components can be easily swapped out. The design provides strong, composable security guarantees derived directly from the underlying parts. A significant speedup for the construction came from replacing the hash function SHA3 in ML-DSA with the zero-knowledge friendly <a href="https://eprint.iacr.org/2019/458"><u>Poseidon</u></a>.</p><p>However, the modularity of our post-quantum Privacy Pass construction <a href="https://zkdilithium.cloudflareresearch.com/index.html"><u>incurs a significant performance overhead</u></a> demonstrated in a clear trade-off between proof generation time and size: a fast 300 ms proof generation requires a large 173 kB signature, while a 4.8s proof generation time cuts the size of the signature nearly in half. A balanced parameter set, which serves as a good benchmark for any dedicated solution to beat, took 660 ms to sign and resulted in a 112 kB signature. The implementation is currently a proof of concept, with perhaps some room for optimization. Alternatively, a different signature like <a href="https://datatracker.ietf.org/doc/draft-ietf-cose-falcon/"><u>FN-DSA</u></a> could offer speed improvements: while its issuance is more complex, its verification is far more straightforward, boiling down to a simple hash-to-lattice computation and a norm check.</p><p>However, while this construction gives a functional baseline, these figures highlight the performance limitations for a real-time rate limiting system, where every millisecond counts. The 660 ms signing time strongly motivates the development of <i>dedicated</i> cryptographic constructions that trade some of the modularity for performance.</p>
    <div>
      <h3>Solid structure: Lattices</h3>
      <a href="#solid-structure-lattices">
        
      </a>
    </div>
    <p><a href="https://blog.cloudflare.com/lattice-crypto-primer/"><u>Lattices</u></a> are a natural starting point when discussing potential post-quantum AC candidates. NIST standardized ML-DSA and ML-KEM as signature and KEM algorithms, both of which are based on lattices. So, are lattices the answer to post-quantum anonymous credentials?</p><p>The answer is a bit nuanced. While explicit anonymous credential schemes from lattices exist, they have shortcomings that prevent real-world deployment: for example, a <a href="https://eprint.iacr.org/2023/560.pdf"><u>recent scheme</u></a> sacrifices round-optimality for smaller communication size, which is unacceptable for a service like Privacy Pass where every second counts. Given that our RTT is 100ms or less for the majority of users, each extra communication round adds tangible latency especially for those on slower Internet connections. When the final credential size is still over 100 kB, the trade-offs are hard to justify. So, our search continues. We expand our horizon by looking into <i>blind signatures </i>and whether we can adapt them for anonymous credentials.</p>
    <div>
      <h4>Two-step approach: Hash-and-sign</h4>
      <a href="#two-step-approach-hash-and-sign">
        
      </a>
    </div>
    <p>A prominent paradigm in lattice-based signatures is the <i>hash-and-sign</i> construction. Here, the message is first hashed to a point in the lattice. Then, the signer uses their secret key, a <a href="https://eprint.iacr.org/2007/432"><u>lattice trapdoor</u></a>, to generate a vector that, when multiplied with the private key, evaluates to the hashed point in the lattice. This is the core mechanism behind signature schemes like FN-DSA.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/66hA0KmluGoGO4I2SHAGTv/1a465c6c810e4f17df3112b96ed816da/image1.png" />
          </figure><p>Adapting hash-and-sign for blind signatures is tricky, since the signer may not learn the message. This introduces a significant security challenge: If the user can request signatures on arbitrary points, they can mount an attack to extract the trapdoor by repeatedly requesting signatures for carefully chosen arbitrary points. These points can be used to reconstruct a short basis, which is equivalent to a key recovery. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1lyCHqOTL477mFGSWjH3dv/48ffe46acfbe81b692c2ba30f383634b/image9.png" />
          </figure><p>The standard defense against this attack is to require the user to prove in zero-knowledge that the point they are asking to be signed is the blinded output of the specified hash function. However, proving hash preimages leads to the same problem as in the generic post-quantum privacy pass paper: proving a conventional hash function (like SHA3) inside a ZKP is computationally expensive and has a large communication complexity.</p><p>This difficult trade-off is at the heart of recent academic work. The <a href="https://eprint.iacr.org/2023/077.pdf"><u>state-of-the-art paper</u></a> presents two lattice-based blind signature schemes with small signature sizes of 22 KB for a signature and 48 kB for a privately-verifiable protocol that may be more useful in a setting like anonymous credential. However, this focus on the final signature size comes at the cost of an impractical <i>issuance</i>. The user must provide ZKPs for the correct hash and lattice relations that, by the paper’s own analysis, can add to<i> several hundred kilobytes</i> and take<i> 20 seconds to generate and 10 seconds to verify</i>.</p><p>While these results are valuable for advancing the field, this trade-off is a significant barrier for any large-scale, practical system. For our use case, a protocol that increases the final signature size moderately in exchange for a more efficient and lightweight issuance process would be a more suitable and promising direction.</p>
    <div>
      <h4>Best of two signatures: Hash-and-sign with aborts</h4>
      <a href="#best-of-two-signatures-hash-and-sign-with-aborts">
        
      </a>
    </div>
    <p>A promising technique for blind signatures combines the hash-and-sign paradigm with <i>Fiat-Shamir with aborts</i>, a method that relies on rejection sampling signatures. In this approach, the signer repeatedly attempts to generate a signature and aborts any result that may leak information about the secret key. This process ensures the final signature is statistically independent of the key and is used in modern signatures like ML-DSA. The <a href="https://eprint.iacr.org/2014/1027"><u>Phoenix signature</u></a> scheme uses <i>hash-and-sign with aborts</i>, where a message is first hashed into the lattice and signed, with rejection sampling employed to break the dependency between the signature and the private key.</p><p>Building on this foundation is an <a href="https://eprint.iacr.org/2024/131"><u>anonymous credential scheme for hash-and-sign with aborts</u></a>. The main improvement over hash-and-sign anonymous credentials is that, instead of proving the validity of a hash, the user commits to their attributes, which avoids costly zero-knowledge proofs.</p><p>The scheme is <a href="https://github.com/Chair-for-Security-Engineering/lattice-anonymous-credentials"><u>fully implemented</u></a> and credentials with attribute proofs just under 80 KB and signatures under 7 kB. The scheme takes less than 400 ms for issuance and 500 ms for showing the credential. The protocol also has a lot of features necessary for anonymous credentials, allowing users to prove relations between attributes and request pseudonyms for different instances.</p><p>This research presents a compelling step towards real-world deployability by combining state-of-the-art techniques to achieve a much healthier balance between performance and security. While the underlying mathematics are a bit more complex, the scheme is fully implemented and with a proof of knowledge of a signature at 40 kB and a prover time under a second, the scheme stands out as a great contender. However, for practical deployment, these figures would likely need a significant speedup to be usable in real-time systems. An improvement seems plausible, given recent <a href="https://eprint.iacr.org/2024/1952"><u>advances in lattice samplers</u></a>. Though the exact scale we can achieve is unclear. Still, we think it would be worthwhile to nudge the underlying design paradigm a little closer to our use cases.</p>
    <div>
      <h3>Do it yourself: MPC-in-the-head </h3>
      <a href="#do-it-yourself-mpc-in-the-head">
        
      </a>
    </div>
    <p>While the lattice-based hash-and-sign with aborts scheme provides one path to post-quantum signatures, an alternative approach is emerging from the MPCitH variant VOLE-in-the-Head <a href="https://eprint.iacr.org/2023/996"><u>(VOLEitH)</u></a>. </p><p>This scheme builds on <a href="https://eprint.iacr.org/2017/617"><u>Vector Oblivious Linear Evaluation (VOLE)</u></a>, an interactive protocol where one party's input vector is processed with another's secret value <i>delta</i>, creating a <i>correlation</i>. This VOLE correlation is used as a cryptographic commitment to the prover’s input. The system provides a zero-knowledge proof because the prover is bound by this correlation and cannot forge a solution without knowing the secret delta. The verifier, in turn, just has to verify that the final equation holds when the commitment is opened. This system is <i>linearly homomorphic</i>, which means that two commitments can be combined. This property is ideal for the <i>commit-and-prove</i> paradigm, where the prover first commits to the witnesses and then proves the validity of the circuit gate by gate. The primary trade-off is that the proofs are linear in the size of the circuit, but they offer substantially better runtimes. We also use linear-sized proofs for ARC and ACT.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6o073F0y7J7RxxHuDb4BSY/1ac0c4fc8b154dd77a8d3294016cbd32/image4.png" />
          </figure><p><sup>Example of evaluating a circuit gate by first committing to each wire and then proving the composition. This is easy for linear gates.</sup></p><p>This commit-and-prove approach allows <a href="https://link.springer.com/chapter/10.1007/978-3-031-91134-7_14"><u>VOLEitH</u></a> to efficiently prove the evaluation of symmetric ciphers, which are quantum-resistant. The transformation to a non-interactive protocol follows the standard MPCitH method: the prover commits to all secret values, a challenge is used to select a subset to reveal, and the prover proves consistency.</p><p>Efficient implementations operate over two mathematical fields (binary and prime) simultaneously, allowing these ZK circuits to handle both arithmetic and bitwise functions (like XORs) efficiently. Based on this foundation, a <a href="https://www.youtube.com/watch?v=VMeaF9xgbcw"><u>recent talk</u></a> teased the potential for blind signatures from the multivariate quadratic signature scheme <a href="https://pqmayo.org/about/"><u>MAYO</u></a> with sizes of just 7.5 kB and signing/verification times under 50 ms.</p><p>The VOLEitH approach, as a general-purpose solution system, represents a promising new direction for performant constructions. There are a <a href="https://pqc-mirath.org"><u>number</u></a> <a href="https://mqom.org"><u>of</u></a> <a href="https://pqc-perk.org"><u>competing</u></a> <a href="https://sdith.org"><u>in-the-head</u></a> schemes in the <a href="https://csrc.nist.gov/projects/pqc-dig-sig"><u>NIST competition for additional signature schemes</u></a>, including <a href="https://faest.info/authors.html"><u>one based on VOLEitH</u></a>. The current VOLEitH literature focuses on high-performance digital signatures, and an explicit construction for a full anonymous credential system has not yet been proposed. This means that features standard to ACs, such as multi-show unlinkability or the ability to prove relations between attributes, are not yet part of the design, whereas they are explicitly supported by the lattice construction. However, the preliminary results show great potential for performance, and it will be interesting to see the continued cryptanalysis and feature development from this line of VOLEitH in the area of anonymous credentials, especially since the general-purpose construction allows adding features easily.
</p><table><tr><td><p><b>Approach</b></p></td><td><p><b>Pros</b></p></td><td><p><b>Cons</b></p></td><td><p><b>Practical Viability</b></p></td></tr><tr><td><p><a href="https://eprint.iacr.org/2023/414"><u>Generic Composition</u></a></p></td><td><p>Flexible construction, strong security</p></td><td><p>Large signatures (112 kB), slow (660 ms)</p></td><td><p>Low: Performance is not great</p></td></tr><tr><td><p><a href="https://eprint.iacr.org/2023/077.pdf"><u>Hash-and-sign</u></a></p></td><td><p>Potentially tiny signatures, lots of optimization potential</p></td><td><p>Current implementation large and slow</p></td><td><p>Low: Performance is not great</p></td></tr><tr><td><p><a href="https://eprint.iacr.org/2024/131"><u>Hash-and-sign with aborts</u></a></p></td><td><p>Full AC system, good balance in communication</p></td><td><p>Slow runtimes (1s)</p></td><td><p>Medium: promising but performance would need to improve</p></td></tr><tr><td><p><a href="https://www.youtube.com/watch?v=VMeaF9xgbcw"><u>VOLEitH</u></a></p></td><td><p>Excellent potential performance (&lt;50ms, 7.5 kB)</p></td><td><p>not a full AC system, not peer-reviewed</p></td><td><p>Medium: promising research direction, no full solution available so far</p></td></tr></table>
    <div>
      <h2>Closing the gap</h2>
      <a href="#closing-the-gap">
        
      </a>
    </div>
    <p>My (that is Lena's) internship focused on a critical question: what should we look at next to build ACs for the Internet? For us, "the right direction" means developing protocols that can be integrated with real world applications, and developed collaboratively at the IETF. To make these a reality, we need researchers to look beyond blind signatures; we need a complete privacy-preserving protocol that combines blind signatures with efficient zero-knowledge proofs and properties like multi-show credentials that have an internal state. The issuance should also be sublinear in communication size with the number of presentations.</p><p>So, with the transition to post-quantum cryptography on the horizon, what are our thoughts on the current IETF proposals? A 2022 NIST presentation on the current state of anonymous credentials states that <a href="https://csrc.nist.gov/csrc/media/Presentations/2022/stppa4-revoc-decent/images-media/20221121-stppa4--baldimtsi--anon-credentials-revoc-decentral.pdf"><u>efficient post-quantum secure solutions are basically non-existent</u></a>. We argue that the last three years show nice developments in lattices and MPCitH anonymous credentials, but efficient post-quantum protocols still need work. Moving protocols into a post-quantum world isn't just a matter of swapping out old algorithms for new ones. A common approach on constructing post-quantum versions of classical protocols is swapping out the building blocks for their quantum-secure counterpart. </p><p>We believe this approach is essential, but not forward-looking. In addition to identifying how modern concerns can be accommodated on old cryptographic designs, we should be building new, post-quantum native protocols.</p><ul><li><p>For ARC, the conceptual path to a post-quantum construction seems relatively straightforward. The underlying cryptography follows a similar structure as the lattice-based anonymous credentials, or, when accepting a protocol with fewer features, the <a href="https://eprint.iacr.org/2023/414"><u>generic post-quantum privacy-pass</u></a> construction. However, we need to support per-origin rate-limiting, which allows us to transform a token at an origin without leaking us being able to link the redemption to redemptions at other origins, a feature that none of the post-quantum anonymous credential protocols or blind signatures support. Also, ARC is sublinear in communication size with respect to the number of tokens issued, which so far only the hash-and-sign with abort lattices achieve, although the notion of “limited shows” is not present in the current proposal. In addition, it would be great to gauge efficient implementations, especially for blind signatures, as well as looking into efficient zero-knowledge proofs. </p></li><li><p>For ACT, we need the protocols for ARC and an additional state. Even for the simplest counter, we need the ability to homomorphically subtract from that balance within the credential itself. This is a much more complex cryptographic requirement. It would also be interesting to see a post-quantum double-spend prevention that enforces the sequential nature of ACT. </p></li></ul><p>Working on ACs and other privacy-preserving cryptography inevitably leads to a major bottleneck: efficient zero-knowledge proofs, or to be more exact, efficiently proving hash function evaluations. In a ZK circuit, multiplications are expensive. Each wire in the circuit that performs a multiplication requires a cryptographic commitment, which adds communication overhead. In contrast, other operations like XOR can be virtually "free." This makes a huge difference in performance. For example, SHAKE (the primitive used in ML-DSA) can be orders of magnitude slower than arithmetization-friendly hash functions inside a ZKP. This is why researchers and implementers are already using <a href="https://eprint.iacr.org/2019/458"><u>Poseidon</u></a> or <a href="https://eprint.iacr.org/2023/323"><u>Poseidon2</u></a> to make their protocols faster.</p><p>Currently, <a href="https://www.poseidon-initiative.info/"><u>Ethereum</u></a> is <a href="https://x.com/VitalikButerin/status/1894681713613164888"><u>seriously considering migrating Ethereum to the Poseidon hash</u></a> and calls for cryptanalysis, but there is no indication of standardization. This is a problem: papers increasingly use different instantiations of Poseidon to fit their use-case, and there <a href="https://eprint.iacr.org/2016/492"><u>are</u></a> <a href="https://eprint.iacr.org/2023/323"><u>more</u></a> <a href="https://eprint.iacr.org/2022/840"><u>and</u></a> <a href="https://eprint.iacr.org/2025/1893"><u>more</u></a> <a href="https://eprint.iacr.org/2025/926"><u>zero</u></a>-<a href="https://eprint.iacr.org/2020/1143"><u>knowledge</u></a> <a href="https://eprint.iacr.org/2019/426"><u>friendly</u></a> <a href="https://eprint.iacr.org/2023/1025"><u>hash</u></a> <a href="https://eprint.iacr.org/2021/1038"><u>functions</u></a> <a href="https://eprint.iacr.org/2022/403"><u>coming</u></a> <a href="https://eprint.iacr.org/2025/058"><u>out</u></a>, tailored to different use-cases. We would like to see at least one XOF and one hash each for a prime field and for a binary field, ideally with some security levels. And also, is Poseidon the best or just the most well-known ZK friendly cipher? Is it always secure against quantum computers (like we believe AES to be), and are there other attacks like the <a href="https://eprint.iacr.org/2025/950"><u>recent</u></a> <a href="https://eprint.iacr.org/2025/937"><u>attacks</u></a> on round-reduced versions?</p><p>Looking at algebra and zero-knowledge brings us to a fundamental debate in modern cryptography. Imagine a line representing the spectrum of research: On one end, you have protocols built on very well-analyzed standard assumptions like the <a href="https://blog.cloudflare.com/lattice-crypto-primer/#breaking-lattice-cryptography-by-finding-short-vectors"><u>SIS problem</u></a> on lattices or the collision resistance of SHA3. On the other end, you have protocols that gain massive efficiency by using more algebraic structure, which in turn relies on newer, stronger cryptographic assumptions. Breaking novel hash functions is somewhere in the middle. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2BMtbDoVnrmKeTvhCyfOjK/616438127351eedf6ff41db282a0511e/image7.png" />
          </figure><p>The answer for the Internet can’t just be to relent and stay at the left end of our graph to be safe. For the ecosystem to move forward, we need to have confidence in both. We need more research to validate the security of ZK-friendly primitives like Poseidon, and we need more scrutiny on the stronger assumptions that enable efficient algebraic methods.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>As we’ve explored, the cryptographic properties that make classical ACs efficient, particularly the rich structure of elliptic curves, do not have direct post-quantum equivalents. Our survey of the state of the art from generic compositions using STARKs, to various lattice-based schemes, and promising new directions like MPC-in-the-head, reveals a field full of potential but with no clear winner. The trade-offs between communication cost, computational cost, and protocol rounds remain a significant barrier to practical, large-scale deployment, especially in comparison to elliptic curve constructions.</p><p>To bridge this gap, we must move beyond simply building post-quantum blind signatures. We challenge our colleagues in academia and industry to develop complete, post-quantum native protocols that address real-world needs. This includes supporting essential features like the per-origin rate-limiting required for ARC or the complex stateful credentials needed for ACT.</p><p>A critical bottleneck for all these approaches is the lack of efficient, standardized, and well-analyzed zero-knowledge-friendly hash functions. We need to research zero-knowledge friendly primitives and build industry-wide confidence to enable efficient post-quantum privacy.</p><p>If you’re working on these problems, or you have experience in the management and deployment of classical credentials, now is the time to engage. The world is rapidly adopting credentials for everything from digital identity to bot management, and it is our collective responsibility to ensure these systems are private and secure for a post-quantum future. We can tell for certain that there are more discussions to be had, and if you’re interested in helping to build this more secure and private digital world, we’re hiring 1,111 interns over the course of next year, and have open positions!</p> ]]></content:encoded>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[IETF]]></category>
            <category><![CDATA[European Union]]></category>
            <category><![CDATA[Elliptic Curves]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">JA04hlqr6TaeGhkvyutbt</guid>
            <dc:creator>Lena Heimberger</dc:creator>
            <dc:creator>Christopher Patton</dc:creator>
        </item>
        <item>
            <title><![CDATA[Keeping the Internet fast and secure: introducing Merkle Tree Certificates]]></title>
            <link>https://blog.cloudflare.com/bootstrap-mtc/</link>
            <pubDate>Tue, 28 Oct 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is launching an experiment with Chrome to evaluate fast, scalable, and quantum-ready Merkle Tree Certificates, all without degrading performance or changing WebPKI trust relationships. ]]></description>
            <content:encoded><![CDATA[ <p>The world is in a race to build its first quantum computer capable of solving practical problems not feasible on even the largest conventional supercomputers. While the quantum computing paradigm promises many benefits, it also threatens the security of the Internet by breaking much of the cryptography we have come to rely on.</p><p>To mitigate this threat, Cloudflare is helping to migrate the Internet to Post-Quantum (PQ) cryptography. Today, <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption"><u>about 50%</u></a> of traffic to Cloudflare's edge network is protected against the most urgent threat: an attacker who can intercept and store encrypted traffic today and then decrypt it in the future with the help of a quantum computer. This is referred to as the <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest now, decrypt later</u></a><i> </i>threat.</p><p>However, this is just one of the threats we need to address. A quantum computer can also be used to crack a server's <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a>, allowing an attacker to impersonate the server to unsuspecting clients. The good news is that we already have PQ algorithms we can use for quantum-safe authentication. The bad news is that adoption of these algorithms in TLS will require significant changes to one of the most complex and security-critical systems on the Internet: the Web Public-Key Infrastructure (WebPKI).</p><p>The central problem is the sheer size of these new algorithms: signatures for ML-DSA-44, one of the most performant PQ algorithms standardized by NIST, are 2,420 bytes long, compared to just 64 bytes for ECDSA-P256, the most popular non-PQ signature in use today; and its public keys are 1,312 bytes long, compared to just 64 bytes for ECDSA. That's a roughly 20-fold increase in size. Worse yet, the average TLS handshake includes a number of public keys and signatures, adding up to 10s of kilobytes of overhead per handshake. This is enough to have a <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/#how-many-added-bytes-are-too-many-for-tls"><u>noticeable impact</u></a> on the performance of TLS.</p><p>That makes drop-in PQ certificates a tough sell to enable today: they don’t bring any security benefit before Q-day — the day a cryptographically relevant quantum computer arrives — but they do degrade performance. We could sit and wait until Q-day is a year away, but that’s playing with fire. Migrations always take longer than expected, and by waiting we risk the security and privacy of the Internet, which is <a href="https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl/"><u>dear to us</u></a>.</p><p>It's clear that we must find a way to make post-quantum certificates cheap enough to deploy today by default for everyone — not just those that can afford it. In this post, we'll introduce you to the plan we’ve brought together with industry partners to the <a href="https://datatracker.ietf.org/group/plants/about/"><u>IETF</u></a> to redesign the WebPKI in order to allow a smooth transition to PQ authentication with no performance impact (and perhaps a performance improvement!). We'll provide an overview of one concrete proposal, called <a href="https://datatracker.ietf.org/doc/draft-davidben-tls-merkle-tree-certs/"><u>Merkle Tree Certificates (MTCs)</u></a>, whose goal is to whittle down the number of public keys and signatures in the TLS handshake to the bare minimum required.</p><p>But talk is cheap. We <a href="https://blog.cloudflare.com/experiment-with-pq/"><u>know</u></a> <a href="https://blog.cloudflare.com/announcing-encrypted-client-hello/"><u>from</u></a> <a href="https://blog.cloudflare.com/why-tls-1-3-isnt-in-browsers-yet/"><u>experience</u></a> that, as with any change to the Internet, it's crucial to test early and often. <b>Today we're announcing our intent to deploy MTCs on an experimental basis in collaboration with Chrome Security.</b> In this post, we'll describe the scope of this experiment, what we hope to learn from it, and how we'll make sure it's done safely.</p>
    <div>
      <h2>The WebPKI today — an old system with many patches</h2>
      <a href="#the-webpki-today-an-old-system-with-many-patches">
        
      </a>
    </div>
    <p>Why does the TLS handshake have so many public keys and signatures?</p><p>Let's start with Cryptography 101. When your browser connects to a website, it asks the server to <b>authenticate</b> itself to make sure it's talking to the real server and not an impersonator. This is usually achieved with a cryptographic primitive known as a digital signature scheme (e.g., ECDSA or ML-DSA). In TLS, the server signs the messages exchanged between the client and server using its <b>secret key</b>, and the client verifies the signature using the server's <b>public key</b>. In this way, the server confirms to the client that they've had the same conversation, since only the server could have produced a valid signature.</p><p>If the client already knows the server's public key, then only <b>1 signature</b> is required to authenticate the server. In practice, however, this is not really an option. The web today is made up of around a billion TLS servers, so it would be unrealistic to provision every client with the public key of every server. What's more, the set of public keys will change over time as new servers come online and existing ones rotate their keys, so we would need some way of pushing these changes to clients.</p><p>This scaling problem is at the heart of the design of all PKIs.</p>
    <div>
      <h3>Trust is transitive</h3>
      <a href="#trust-is-transitive">
        
      </a>
    </div>
    <p>Instead of expecting the client to know the server's public key in advance, the server might just send its public key during the TLS handshake. But how does the client know that the public key actually belongs to the server? This is the job of a <b>certificate</b>.</p><p>A certificate binds a public key to the identity of the server — usually its DNS name, e.g., <code>cloudflareresearch.com</code>. The certificate is signed by a Certification Authority (CA) whose public key is known to the client. In addition to verifying the server's handshake signature, the client verifies the signature of this certificate. This establishes a chain of trust: by accepting the certificate, the client is trusting that the CA verified that the public key actually belongs to the server with that identity.</p><p>Clients are typically configured to trust many CAs and must be provisioned with a public key for each. Things are much easier however, since there are only 100s of CAs instead of billions. In addition, new certificates can be created without having to update clients.</p><p>These efficiencies come at a relatively low cost: for those counting at home, that's <b>+1</b> signature and <b>+1</b> public key, for a total of <b>2 signatures and 1 public key</b> per TLS handshake.</p><p>That's not the end of the story, however. As the WebPKI has evolved, so have these chains of trust grown a bit longer. These days it's common for a chain to consist of two or more certificates rather than just one. This is because CAs sometimes need to rotate<b> </b>their keys, just as servers do. But before they can start using the new key, they must distribute the corresponding public key to clients. This takes time, since it requires billions of clients to update their trust stores. To bridge the gap, the CA will sometimes use the old key to issue a certificate for the new one and append this certificate to the end of the chain.</p><p>That's<b> +1</b> signature and<b> +1</b> public key, which brings us to<b> 3 signatures and 2 public keys</b>. And we still have a little ways to go.</p>
    <div>
      <h3>Trust but verify</h3>
      <a href="#trust-but-verify">
        
      </a>
    </div>
    <p>The main job of a CA is to verify that a server has control over the domain for which it’s requesting a certificate. This process has evolved over the years from a high-touch, CA-specific process to a standardized, <a href="https://datatracker.ietf.org/doc/html/rfc8555/"><u>mostly automated process</u></a> used for issuing most certificates on the web. (Not all CAs fully support automation, however.) This evolution is marked by a number of security incidents in which a certificate was <b>mis-issued </b>to a party other than the server, allowing that party to impersonate the server to any client that trusts the CA.</p><p>Automation helps, but <a href="https://en.wikipedia.org/wiki/DigiNotar#Issuance_of_fraudulent_certificates"><u>attacks</u></a> are still possible, and mistakes are almost inevitable. <a href="https://blog.cloudflare.com/unauthorized-issuance-of-certificates-for-1-1-1-1/"><u>Earlier this year</u></a>, several certificates for Cloudflare's encrypted 1.1.1.1 resolver were issued without our involvement or authorization. This apparently occurred by accident, but it nonetheless put users of 1.1.1.1 at risk. (The mis-issued certificates have since been revoked.)</p><p>Ensuring mis-issuance is detectable is the job of the Certificate Transparency (CT) ecosystem. The basic idea is that each certificate issued by a CA gets added to a public <b>log</b>. Servers can audit these logs for certificates issued in their name. If ever a certificate is issued that they didn't request itself, the server operator can prove the issuance happened, and the PKI ecosystem can take action to prevent the certificate from being trusted by clients.</p><p>Major browsers, including Firefox and Chrome and its derivatives, require certificates to be logged before they can be trusted. For example, Chrome, Safari, and Firefox will only accept the server's certificate if it appears in at least two logs the browser is configured to trust. This policy is easy to state, but tricky to implement in practice:</p><ol><li><p>Operating a CT log has historically been fairly expensive. Logs ingest billions of certificates over their lifetimes: when an incident happens, or even just under high load, it can take some time for a log to make a new entry available for auditors.</p></li><li><p>Clients can't really audit logs themselves, since this would expose their browsing history (i.e., the servers they wanted to connect to) to the log operators.</p></li></ol><p>The solution to both problems is to include a signature from the CT log along with the certificate. The signature is produced immediately in response to a request to log a certificate, and attests to the log's intent to include the certificate in the log within 24 hours.</p><p>Per browser policy, certificate transparency adds <b>+2</b> signatures to the TLS handshake, one for each log. This brings us to a total of <b>5 signatures and 2 public keys</b> in a typical handshake on the public web.</p>
    <div>
      <h3>The future WebPKI</h3>
      <a href="#the-future-webpki">
        
      </a>
    </div>
    <p>The WebPKI is a living, breathing, and highly distributed system. We've had to patch it a number of times over the years to keep it going, but on balance it has served our needs quite well — until now.</p><p>Previously, whenever we needed to update something in the WebPKI, we would tack on another signature. This strategy has worked because conventional cryptography is so cheap. But <b>5 signatures and 2 public keys </b>on average for each TLS handshake is simply too much to cope with for the larger PQ signatures that are coming.</p><p>The good news is that by moving what we already have around in clever ways, we can drastically reduce the number of signatures we need.</p>
    <div>
      <h3>Crash course on Merkle Tree Certificates</h3>
      <a href="#crash-course-on-merkle-tree-certificates">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/draft-davidben-tls-merkle-tree-certs/"><u>Merkle Tree Certificates (MTCs)</u></a> is a proposal for the next generation of the WebPKI that we are implementing and plan to deploy on an experimental basis. Its key features are as follows:</p><ol><li><p>All the information a client needs to validate a Merkle Tree Certificate can be disseminated out-of-band. If the client is sufficiently up-to-date, then the TLS handshake needs just <b>1 signature, 1 public key, and 1 Merkle tree inclusion proof</b>. This is quite small, even if we use post-quantum algorithms.</p></li><li><p>The MTC specification makes certificate transparency a first class feature of the PKI by having each CA run its own log of exactly the certificates they issue.</p></li></ol><p>Let's poke our head under the hood a little. Below we have an MTC generated by one of our internal tests. This would be transmitted from the server to the client in the TLS handshake:</p>
            <pre><code>-----BEGIN CERTIFICATE-----
MIICSzCCAUGgAwIBAgICAhMwDAYKKwYBBAGC2ksvADAcMRowGAYKKwYBBAGC2ksv
AQwKNDQzNjMuNDguMzAeFw0yNTEwMjExNTMzMjZaFw0yNTEwMjgxNTMzMjZaMCEx
HzAdBgNVBAMTFmNsb3VkZmxhcmVyZXNlYXJjaC5jb20wWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAARw7eGWh7Qi7/vcqc2cXO8enqsbbdcRdHt2yDyhX5Q3RZnYgONc
JE8oRrW/hGDY/OuCWsROM5DHszZRDJJtv4gno2wwajAOBgNVHQ8BAf8EBAMCB4Aw
EwYDVR0lBAwwCgYIKwYBBQUHAwEwQwYDVR0RBDwwOoIWY2xvdWRmbGFyZXJlc2Vh
cmNoLmNvbYIgc3RhdGljLWN0LmNsb3VkZmxhcmVyZXNlYXJjaC5jb20wDAYKKwYB
BAGC2ksvAAOB9QAAAAAAAAACAAAAAAAAAAJYAOBEvgOlvWq38p45d0wWTPgG5eFV
wJMhxnmDPN1b5leJwHWzTOx1igtToMocBwwakt3HfKIjXYMO5CNDOK9DIKhmRDSV
h+or8A8WUrvqZ2ceiTZPkNQFVYlG8be2aITTVzGuK8N5MYaFnSTtzyWkXP2P9nYU
Vd1nLt/WjCUNUkjI4/75fOalMFKltcc6iaXB9ktble9wuJH8YQ9tFt456aBZSSs0
cXwqFtrHr973AZQQxGLR9QCHveii9N87NXknDvzMQ+dgWt/fBujTfuuzv3slQw80
mibA021dDCi8h1hYFQAA
-----END CERTIFICATE-----</code></pre>
            <p>Looks like your average PEM encoded certificate. Let's decode it and look at the parameters:</p>
            <pre><code>$ openssl x509 -in merkle-tree-cert.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 531 (0x213)
        Signature Algorithm: 1.3.6.1.4.1.44363.47.0
        Issuer: 1.3.6.1.4.1.44363.47.1=44363.48.3
        Validity
            Not Before: Oct 21 15:33:26 2025 GMT
            Not After : Oct 28 15:33:26 2025 GMT
        Subject: CN=cloudflareresearch.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:70:ed:e1:96:87:b4:22:ef:fb:dc:a9:cd:9c:5c:
                    ef:1e:9e:ab:1b:6d:d7:11:74:7b:76:c8:3c:a1:5f:
                    94:37:45:99:d8:80:e3:5c:24:4f:28:46:b5:bf:84:
                    60:d8:fc:eb:82:5a:c4:4e:33:90:c7:b3:36:51:0c:
                    92:6d:bf:88:27
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:cloudflareresearch.com, DNS:static-ct.cloudflareresearch.com
    Signature Algorithm: 1.3.6.1.4.1.44363.47.0
    Signature Value:
        00:00:00:00:00:00:02:00:00:00:00:00:00:00:02:58:00:e0:
        44:be:03:a5:bd:6a:b7:f2:9e:39:77:4c:16:4c:f8:06:e5:e1:
        55:c0:93:21:c6:79:83:3c:dd:5b:e6:57:89:c0:75:b3:4c:ec:
        75:8a:0b:53:a0:ca:1c:07:0c:1a:92:dd:c7:7c:a2:23:5d:83:
        0e:e4:23:43:38:af:43:20:a8:66:44:34:95:87:ea:2b:f0:0f:
        16:52:bb:ea:67:67:1e:89:36:4f:90:d4:05:55:89:46:f1:b7:
        b6:68:84:d3:57:31:ae:2b:c3:79:31:86:85:9d:24:ed:cf:25:
        a4:5c:fd:8f:f6:76:14:55:dd:67:2e:df:d6:8c:25:0d:52:48:
        c8:e3:fe:f9:7c:e6:a5:30:52:a5:b5:c7:3a:89:a5:c1:f6:4b:
        5b:95:ef:70:b8:91:fc:61:0f:6d:16:de:39:e9:a0:59:49:2b:
        34:71:7c:2a:16:da:c7:af:de:f7:01:94:10:c4:62:d1:f5:00:
        87:bd:e8:a2:f4:df:3b:35:79:27:0e:fc:cc:43:e7:60:5a:df:
        df:06:e8:d3:7e:eb:b3:bf:7b:25:43:0f:34:9a:26:c0:d3:6d:
        5d:0c:28:bc:87:58:58:15:00:00</code></pre>
            <p>While some of the parameters probably look familiar, others will look unusual. On the familiar side, the subject and public key are exactly what we might expect: the DNS name is <code>cloudflareresearch.com</code> and the public key is for a familiar signature algorithm, ECDSA-P256. This algorithm is not PQ, of course — in the future we would put ML-DSA-44 there instead.</p><p>On the unusual side, OpenSSL appears to not recognize the signature algorithm of the issuer and just prints the raw OID and bytes of the signature. There's a good reason for this: the MTC does not have a signature in it at all! So what exactly are we looking at?</p><p>The trick to leave out signatures is that a Merkle Tree Certification Authority (MTCA) produces its <i>signatureless</i> certificates <i>in batches</i> rather than individually. In place of a signature, the certificate has an <b>inclusion proof</b> of the certificate in a batch of certificates signed by the MTCA.</p><p>To understand how inclusion proofs work, let's think about a slightly simplified version of the MTC specification. To issue a batch, the MTCA arranges the unsigned certificates into a data structure called a <b>Merkle tree</b> that looks like this:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4LGhISsS07kbpSgDkqx8p2/68e3b36deeca7f97139654d2c769df68/image3.png" />
          </figure><p>Each leaf of the tree corresponds to a certificate, and each inner node is equal to the hash of its children. To sign the batch, the MTCA uses its secret key to sign the head of the tree. The structure of the tree guarantees that each certificate in the batch was signed by the MTCA: if we tried to tweak the bits of any one of the certificates, the treehead would end up having a different value, which would cause the signature to fail.</p><p>An inclusion proof for a certificate consists of the hash of each sibling node along the path from the certificate to the treehead:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4UZZHkRwsBLWXRYeop4rXv/8598cde48c27c112bc4992889f3d5799/image1.gif" />
          </figure><p>Given a validated treehead, this sequence of hashes is sufficient to prove inclusion of the certificate in the tree. This means that, in order to validate an MTC, the client also needs to obtain the signed treehead from the MTCA.</p><p>This is the key to MTC's efficiency:</p><ol><li><p>Signed treeheads can be disseminated to clients out-of-band and validated offline. Each validated treehead can then be used to validate any certificate in the corresponding batch, eliminating the need to obtain a signature for each server certificate.</p></li><li><p>During the TLS handshake, the client tells the server which treeheads it has. If the server has a signatureless certificate covered by one of those treeheads, then it can use that certificate to authenticate itself. That's <b>1 signature,1 public key and 1 inclusion proof</b> per handshake, both for the server being authenticated.</p></li></ol><p>Now, that's the simplified version. MTC proper has some more bells and whistles. To start, it doesn’t create a separate Merkle tree for each batch, but it grows a single large tree, which is used for better transparency. As this tree grows, periodically (sub)tree heads are selected to be shipped to browsers, which we call <b>landmarks</b>. In the common case browsers will be able to fetch the most recent landmarks, and servers can wait for batch issuance, but we need a fallback: MTC also supports certificates that can be issued immediately and don’t require landmarks to be validated, but these are not as small. A server would provision both types of Merkle tree certificates, so that the common case is fast, and the exceptional case is slow, but at least it’ll work.</p>
    <div>
      <h2>Experimental deployment</h2>
      <a href="#experimental-deployment">
        
      </a>
    </div>
    <p>Ever since early designs for MTCs emerged, we’ve been eager to experiment with the idea. In line with the IETF principle of “<a href="https://www.ietf.org/runningcode/"><u>running code</u></a>”, it often takes implementing a protocol to work out kinks in the design. At the same time, we cannot risk the security of users. In this section, we describe our approach to experimenting with aspects of the Merkle Tree Certificates design <i>without</i> changing any trust relationships.</p><p>Let’s start with what we hope to learn. We have lots of questions whose answers can help to either validate the approach, or uncover pitfalls that require reshaping the protocol — in fact, an implementation of an early MTC draft by <a href="https://www.cs.ru.nl/masters-theses/2025/M_Pohl___Implementation_and_Analysis_of_Merkle_Tree_Certificates_for_Post-Quantum_Secure_Authentication_in_TLS.pdf"><u>Maximilian Pohl</u></a> and <a href="https://www.ietf.org/archive/id/draft-davidben-tls-merkle-tree-certs-07.html#name-acknowledgements"><u>Mia Celeste</u></a> did exactly this. We’d like to know:</p><p><b>What breaks?</b> Protocol ossification (the tendency of implementation bugs to make it harder to change a protocol) is an ever-present issue with deploying protocol changes. For TLS in particular, despite having built-in flexibility, time after time we’ve found that if that flexibility is not regularly used, there will be buggy implementations and middleboxes that break when they see things they don’t recognize. TLS 1.3 deployment <a href="https://blog.cloudflare.com/why-tls-1-3-isnt-in-browsers-yet/"><u>took years longer</u></a> than we hoped for this very reason. And more recently, the rollout of PQ key exchange in TLS caused the Client Hello to be split over multiple TCP packets, something that many middleboxes <a href="https://tldr.fail/"><u>weren't ready for</u></a>.</p><p><b>What is the performance impact?</b> In fact, we expect MTCs to <i>reduce </i>the size of the handshake, even compared to today's non-PQ certificates. They will also reduce CPU cost: ML-DSA signature verification is about as fast as ECDSA, and there will be far fewer signatures to verify. We therefore expect to see a <i>reduction in latency</i>. We would like to see if there is a measurable performance improvement.</p><p><b>What fraction of clients will stay up to date? </b>Getting the performance benefit of MTCs requires the clients and servers to be roughly in sync with one another. We expect MTCs to have fairly short lifetimes, a week or so. This means that if the client's latest landmark is older than a week, the server would have to fallback to a larger certificate. Knowing how often this fallback happens will help us tune the parameters of the protocol to make fallbacks less likely.</p><p>In order to answer these questions, we are implementing MTC support in our TLS stack and in our certificate issuance infrastructure. For their part, Chrome is implementing MTC support in their own TLS stack and will stand up infrastructure to disseminate landmarks to their users.</p><p>As we've done in past experiments, we plan to enable MTCs for a subset of our free customers with enough traffic that we will be able to get useful measurements. Chrome will control the experimental rollout: they can ramp up slowly, measuring as they go and rolling back if and when bugs are found.</p><p>Which leaves us with one last question: who will run the Merkle Tree CA?</p>
    <div>
      <h3>Bootstrapping trust from the existing WebPKI</h3>
      <a href="#bootstrapping-trust-from-the-existing-webpki">
        
      </a>
    </div>
    <p>Standing up a proper CA is no small task: it takes years to be trusted by major browsers. That’s why Cloudflare isn’t going to become a “real” CA for this experiment, and Chrome isn’t going to trust us directly.</p><p>Instead, to make progress on a reasonable timeframe, without sacrificing due diligence, we plan to "mock" the role of the MTCA. We will run an MTCA (on <a href="https://github.com/cloudflare/azul/"><u>Workers</u></a> based on our <a href="https://blog.cloudflare.com/azul-certificate-transparency-log/"><u>StaticCT logs</u></a>), but for each MTC we issue, we also publish an existing certificate from a trusted CA that agrees with it. We call this the <b>bootstrap certificate</b>. When Chrome’s infrastructure pulls updates from our MTCA log, they will also pull these bootstrap certificates, and check whether they agree. Only if they do, they’ll proceed to push the corresponding landmarks to Chrome clients. In other words, Cloudflare is effectively just “re-encoding” an existing certificate (with domain validation performed by a trusted CA) as an MTC, and Chrome is using certificate transparency to keep us honest.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>With almost 50% of our traffic already protected by post-quantum encryption, we’re halfway to a fully post-quantum secure Internet. The second part of our journey, post-quantum certificates, is the hardest yet though. A simple drop-in upgrade has a noticeable performance impact and no security benefit before Q-day. This means it’s a hard sell to enable today by default. But here we are playing with fire: migrations always take longer than expected. If we want to keep an ubiquitously private and secure Internet, we need a post-quantum solution that’s performant enough to be enabled by default <b>today</b>.</p><p>Merkle Tree Certificates (MTCs) solves this problem by reducing the number of signatures and public keys to the bare minimum while maintaining the WebPKI's essential properties. We plan to roll out MTCs to a fraction of free accounts by early next year. This does not affect any visitors that are not part of the Chrome experiment. For those that are, thanks to the bootstrap certificates, there is no impact on security.</p><p>We’re excited to keep the Internet fast <i>and</i> secure, and will report back soon on the results of this experiment: watch this space! MTC is evolving as we speak, if you want to get involved, please join the IETF <a href="https://mailman3.ietf.org/mailman3/lists/plants@ietf.org/"><u>PLANTS mailing list</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Chrome]]></category>
            <category><![CDATA[Google]]></category>
            <category><![CDATA[IETF]]></category>
            <category><![CDATA[Transparency]]></category>
            <category><![CDATA[Rust]]></category>
            <category><![CDATA[Open Source]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <guid isPermaLink="false">4jURWdZzyjdrcurJ4LlJ1z</guid>
            <dc:creator>Luke Valenta</dc:creator>
            <dc:creator>Christopher Patton</dc:creator>
            <dc:creator>Vânia Gonçalves</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Improving the trustworthiness of Javascript on the Web]]></title>
            <link>https://blog.cloudflare.com/improving-the-trustworthiness-of-javascript-on-the-web/</link>
            <pubDate>Thu, 16 Oct 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ There's no way to audit a site’s client-side code as it changes, making it hard to trust sites that use cryptography. We preview a specification we co-authored that adds auditability to the web. ]]></description>
            <content:encoded><![CDATA[ <p>The web is the most powerful application platform in existence. As long as you have the <a href="https://developer.mozilla.org/en-US/docs/Web/API"><u>right API</u></a>, you can safely run anything you want in a browser.</p><p>Well… anything but cryptography.</p><p>It is as true today as it was in 2011 that <a href="https://web.archive.org/web/20200731144044/https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/"><u>Javascript cryptography is Considered Harmful</u></a>. The main problem is code distribution. Consider an end-to-end-encrypted messaging web application. The application generates <a href="https://www.cloudflare.com/learning/ssl/what-is-a-cryptographic-key/"><u>cryptographic keys</u></a> in the client’s browser that lets users view and send <a href="https://en.wikipedia.org/wiki/End-to-end_encryption"><u>end-to-end encrypted</u></a> messages to each other. If the application is compromised, what would stop the malicious actor from simply modifying their Javascript to exfiltrate messages?</p><p>It is interesting to note that smartphone apps don’t have this issue. This is because app stores do a lot of heavy lifting to provide security for the app ecosystem. Specifically, they provide <b>integrity</b>, ensuring that apps being delivered are not tampered with, <b>consistency</b>, ensuring all users get the same app, and <b>transparency</b>, ensuring that the record of versions of an app is truthful and publicly visible.</p><p>It would be nice if we could get these properties for our end-to-end encrypted web application, and the web as a whole, without requiring a single central authority like an app store. Further, such a system would benefit all in-browser uses of cryptography, not just end-to-end-encrypted apps. For example, many web-based confidential <a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/"><u>LLMs</u></a>, cryptocurrency wallets, and voting systems use in-browser Javascript cryptography for the last step of their verification chains.</p><p>In this post, we will provide an early look at such a system, called <a href="https://github.com/beurdouche/explainers/blob/main/waict-explainer.md"><u>Web Application Integrity, Consistency, and Transparency</u></a> (WAICT) that we have helped author. WAICT is a <a href="https://www.w3.org/"><u>W3C</u></a>-backed effort among browser vendors, cloud providers, and encrypted communication developers to bring stronger security guarantees to the entire web. We will discuss the problem we need to solve, and build up to a solution resembling the <a href="https://github.com/rozbb/draft-waict-transparency"><u>current transparency specification draft</u></a>. We hope to build even wider consensus on the solution design in the near future.</p>
    <div>
      <h2>Defining the Web Application</h2>
      <a href="#defining-the-web-application">
        
      </a>
    </div>
    <p>In order to talk about security guarantees of a web application, it is first necessary to define precisely what the application <i>is</i>. A smartphone application is essentially just a zip file. But a website is made up of interlinked assets, including HTML, Javascript, WASM, and CSS, that can each be locally or externally hosted. Further, if any asset changes, it could drastically change the functioning of the application. A coherent definition of an application thus requires the application to commit to precisely the assets it loads. This is done using integrity features, which we describe now.</p>
    <div>
      <h3>Subresource Integrity</h3>
      <a href="#subresource-integrity">
        
      </a>
    </div>
    <p>An important building block for defining a single coherent application is <b>subresource integrity</b> (SRI). SRI is a feature built into most browsers that permits a website to specify the cryptographic hash of external resources, e.g.,</p>
            <pre><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.7/underscore-min.js" integrity="sha512-dvWGkLATSdw5qWb2qozZBRKJ80Omy2YN/aF3wTUVC5+D1eqbA+TjWpPpoj8vorK5xGLMa2ZqIeWCpDZP/+pQGQ=="&gt;&lt;/script&gt;</code></pre>
            <p>This causes the browser to fetch <code>underscore.js</code> from <code>cdnjs.cloudflare.com</code> and verify that its SHA-512 hash matches the given hash in the tag. If they match, the script is loaded. If not, an error is thrown and nothing is executed.</p><p>If every external script, stylesheet, etc. on a page comes with an SRI integrity attribute, then the whole page is defined by just its HTML. This is close to what we want, but a web application can consist of many pages, and there is no way for a page to enforce the hash of the pages it links to.</p>
    <div>
      <h3>Integrity Manifest</h3>
      <a href="#integrity-manifest">
        
      </a>
    </div>
    <p>We would like to have a way of enforcing integrity on an entire site, i.e., every asset under a domain. For this, WAICT defines an <b>integrity manifest</b>, a configuration file that websites can provide to clients. One important item in the manifest is the <b>asset hashes dictionary</b>, mapping a hash belonging to an asset that the browser might load from that domain, to the path of that asset. Assets that may occur at any path, e.g., an error page, map to the empty string:</p>
            <pre><code>"hashes": {
"81db308d0df59b74d4a9bd25c546f25ec0fdb15a8d6d530c07a89344ae8eeb02": "/assets/js/main.js",
"fbd1d07879e672fd4557a2fa1bb2e435d88eac072f8903020a18672d5eddfb7c": "/index.html",
"5e737a67c38189a01f73040b06b4a0393b7ea71c86cf73744914bbb0cf0062eb": "/vendored/main.css",
"684ad58287ff2d085927cb1544c7d685ace897b6b25d33e46d2ec46a355b1f0e": "",
"f802517f1b2406e308599ca6f4c02d2ae28bb53ff2a5dbcddb538391cb6ad56a": ""
}
</code></pre>
            <p>The other main component of the manifest is the <b>integrity policy</b>, which tells the browser which data types are being enforced and how strictly. For example, the policy in the manifest below will:</p><ol><li><p>Reject any script before running it, if it’s missing an SRI tag and doesn’t appear in the hashes</p></li><li><p>Reject any WASM possibly after running it, if it’s missing an SRI tag and doesn’t appear in hashes</p></li></ol>
            <pre><code>"integrity-policy": "blocked-destinations=(script), checked-destinations=(wasm)"</code></pre>
            <p>Put together, these make up the integrity manifest:</p>
            <pre><code>"manifest": {
  "version": 1,
  "integrity-policy": ...,
  "hashes": ...,
}
</code></pre>
            <p>Thus, when both SRI and integrity manifests are used, the entire site and its interpretation by the browser is uniquely determined by the hash of the integrity manifest. This is exactly what we wanted. We have distilled the problem of endowing authenticity, consistent distribution, etc. to a web application to one of endowing the same properties to a single hash.</p>
    <div>
      <h2>Achieving Transparency</h2>
      <a href="#achieving-transparency">
        
      </a>
    </div>
    <p>Recall, a transparent web application is one whose code is stored in a publicly accessible, append-only log. This is helpful in two ways: 1) if a user is served malicious code and they learn about it, there is a public record of the code they ran, and so they can prove it to external parties, and 2) if a user is served malicious code and they don’t learn about it, there is still a chance that an external auditor may comb through the historical web application code and find the malicious code anyway. Of course, transparency does not help detect malicious code or even prevent its distribution, but it at least makes it <i>publicly auditable</i>.</p><p>Now that we have a single hash that commits to an entire website’s contents, we can talk about ensuring that that hash ends up in a public log. We have several important requirements here:</p><ol><li><p><b>Do not break existing sites.</b> This one is a given. Whatever system gets deployed, it should not interfere with the correct functioning of existing websites. Participation in transparency should be strictly opt-in.</p></li><li><p><b>No added round trips.</b> Transparency should not cause extra network round trips between the client and the server. Otherwise there will be a network latency penalty for users who want transparency.</p></li><li><p><b>User privacy.</b> A user should not have to identify themselves to any party more than they already do. That means no connections to new third parties, and no sending identifying information to the website.</p></li><li><p><b>User statelessness.</b> A user should not have to store site-specific data. We do not want solutions that rely on storing or gossipping per-site cryptographic information.</p></li><li><p><b>Non-centralization.</b> There should not be a single point of failure in the system—if any single party experiences downtime, the system should still be able to make progress. Similarly, there should be no single point of trust—if a user distrusts any single party, the user should still receive all the security benefits of the system.</p></li><li><p><b>Ease of opt-in.</b> The barrier of entry for transparency should be as low as possible. A site operator should be able to start logging their site cheaply and without being an expert.</p></li><li><p><b>Ease of opt-out.</b> It should be easy for a website to stop participating in transparency. Further, to avoid accidental lock-in like the <a href="https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning#Criticism_and_decline"><u>defunct HPKP spec</u></a>, it should be possible for this to happen even if all cryptographic material is lost, e.g., in the seizure or selling of a domain.</p></li><li><p><b>Opt-out is transparent.</b> As described before, because transparency is optional, it is possible for an attacker to disable the site’s transparency, serve malicious content, then enable transparency again. We must make sure this kind of attack is detectable, i.e., the act of disabling transparency must itself be logged somewhere.</p></li><li><p><b>Monitorability.</b> A website operator should be able to efficiently monitor the transparency information being published about their website. In particular, they should not have to run a high-network-load, always-on program just to notify them if their site has been hijacked.</p></li></ol><p>With these requirements in place, we can move on to construction. We introduce a data structure that will be essential to the design.</p>
    <div>
      <h3>Hash Chain</h3>
      <a href="#hash-chain">
        
      </a>
    </div>
    <p>Almost everything in transparency is an append-only log, i.e., a data structure that acts like a list and has the ability to produce an <b>inclusion proof</b>, i.e., a proof that an element occurs at a particular index in the list; and a <b>consistency proof</b>, i.e., a proof that a list is an extension of a previous version of the list. A consistency proof between two lists demonstrates that no elements were modified or deleted, only added.</p><p>The simplest possible append-only log is a <b>hash chain</b>, a list-like data structure wherein each subsequent element is hashed into the running <i>chain hash</i>. The final chain hash is a succinct representation of the entire list.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nVcIeoKTYEd0hydT9jdpj/fd90a78cba46c1893058a7ff40a42fac/BLOG-2875_2.png" />
          </figure><p><sub>A hash chain. The green nodes represent the </sub><sub><i>chain hash</i></sub><sub>, i.e., the hash of the element below it, concatenated with the previous chain hash. </sub></p><p>The proof structures are quite simple. To prove inclusion of the element at index i, the prover provides the chain hash before <code>i</code>, and all the elements after <code>i</code>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7tYbCRVVTV3osE3lWs8YjG/be76d6022420ffa3d78b0180ef69bb1a/BLOG-2875_3.png" />
          </figure><p><sub>Proof of inclusion for the second element in the hash chain. The verifier knows only the final chain hash. It checks equality of the final computed chain hash with the known final chain hash. The light green nodes represent hashes that the verifier computes. </sub></p><p>Similarly, to prove consistency between the chains of size i and j, the prover provides the elements between i and j:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/rR4DMJIVxNxePI6DARtFD/e9da2930043864a4add3a74b699535d6/BLOG-2875_4.png" />
          </figure><p><sub>Proof of consistency of the chain of size one and chain of size three. The verifier has the chain hashes from the starting and ending chains. It checks equality of the final computed chain hash with the known ending chain hash. The light green nodes represent hashes that the verifier computes. </sub></p>
    <div>
      <h3>Building Transparency</h3>
      <a href="#building-transparency">
        
      </a>
    </div>
    <p>We can use hash chains to build a transparency scheme for websites.</p>
    <div>
      <h4>Per-Site Logs</h4>
      <a href="#per-site-logs">
        
      </a>
    </div>
    <p>As a first step, let’s give every site its own log, instantiated as a hash chain (we will discuss how these all come together into one big log later). The items of the log are just the manifest of the site at a particular point in time:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/35o9mKoVPkOExKRFHRgWTu/305d589e0a584a3200670aab5b060c2b/BLOG-2875_5.png" />
          </figure><p><sub>A site’s hash chain-based log, containing three historical manifests. </sub></p><p>In reality, the log does not store the manifest itself, but the manifest hash. Sites designate an <b>asset host</b> that knows how to map hashes to the data they reference. This is a content-addressable storage backend, and can be implemented using strongly cached static hosting solutions.</p><p>A log on its own is not very trustworthy. Whoever runs the log can add and remove elements at will and then recompute the hash chain. To maintain the append-only-ness of the chain, we designate a trusted third party, called a <b>witness</b>. Given a hash chain consistency proof and a new chain hash, a witness:</p><ol><li><p>Verifies the consistency proof with respect to its old stored chain hash, and the new provided chain hash.</p></li><li><p>If successful, signs the new chain hash along with a signature timestamp.</p></li></ol><p>Now, when a user navigates to a website with transparency enabled, the sequence of events is:</p><ol><li><p>The site serves its manifest, an inclusion proof showing that the manifest appears in the log, and all the signatures from all the witnesses who have validated the log chain hash.</p></li><li><p>The browser verifies the signatures from whichever witnesses it trusts.</p></li><li><p>The browser verifies the inclusion proof. The manifest must be the newest entry in the chain (we discuss how to serve old manifests later).</p></li><li><p>The browser proceeds with the usual manifest and SRI integrity checks.</p></li></ol><p>At this point, the user knows that the given manifest has been recorded in a log whose chain hash has been saved by a trustworthy witness, so they can be reasonably sure that the manifest won’t be removed from history. Further, assuming the asset host functions correctly, the user knows that a copy of all the received code is readily available.</p><p><b>The need to signal transparency.</b> The above algorithm works, but we have a problem: if an attacker takes control of a site, they can simply stop serving transparency information and thus implicitly disable transparency without detection. So we need an explicit mechanism that keeps track of every website that has enrolled into transparency.</p>
    <div>
      <h3>The Transparency Service</h3>
      <a href="#the-transparency-service">
        
      </a>
    </div>
    <p>To store all the sites enrolled into transparency, we want a global data structure that maps a site domain to the site log’s chain hash. One efficient way of representing this is a <b>prefix tree</b> (a.k.a., a <i>trie</i>). Every leaf in the tree corresponds to a site’s domain, and its value is the chain hash of that site’s log, the current log size, and the site’s asset host URL. For a site to prove validity of its transparency data, it will have to present an inclusion proof for its leaf. Fortunately, these proofs are efficient for prefix trees.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/26ieMXRdvWIhLKv6J6Cdd7/29814a4a51c8ca8e3279e9b5756d0c67/BLOG-2875_6.png" />
          </figure><p><sub>A prefix tree with four elements. Each leaf’s path corresponds to a domain. Each leaf’s value is the chain hash of its site’s log. </sub></p><p>To add itself to the tree, a site proves possession of its domain to the <b>transparency service</b>, i.e., the party that operates the prefix tree, and provides an asset host URL. To update the entry, the site sends the new entry to the transparency service, which will compute the new chain hash. And to unenroll from transparency, the site just requests to have its entry removed from the tree (an adversary can do this too; we discuss how to detect this below).</p>
    <div>
      <h4>Proving to Witnesses and Browsers</h4>
      <a href="#proving-to-witnesses-and-browsers">
        
      </a>
    </div>
    <p>Now witnesses only need to look at the prefix tree instead of individual site logs, and thus they must verify whole-tree updates. The most important thing to ensure is that every site’s log is append-only. So whenever the tree is updated, it must produce a “proof” containing every new/deleted/modified entry, as well as a consistency proof for each entry showing that the site log corresponding to that entry has been properly appended to. Once the witness has verified this prefix tree update proof, it signs the root.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2bq4UBxoOgKPcysPPxnKD8/9e8c2a8a3b092fffae853b8d477efb07/BLOG-2875_7.png" />
          </figure><p><sub>The sequence of updating a site’s assets and serving the site with transparency enabled.</sub></p><p>The client-side verification procedure is as in the previous section, with two modifications:</p><ol><li><p>The client now verifies two inclusion proofs: one for the integrity policy’s membership in the site log, and one for the site log’s membership in a prefix tree.</p></li><li><p>The client verifies the signature over the prefix tree root, since the witness no longer signs individual chain hashes. As before, the acceptable public keys are whichever witnesses the client trusts.</p></li></ol><p><b>Signaling transparency.</b> Now that there is a single source of truth, namely the prefix tree, a client can know a site is enrolled in transparency by simply fetching the site’s entry in the tree. This alone would work, but it violates our requirement of “no added round trips,” so we instead require that client browsers will ship with the list of sites included in the prefix tree. We call this the <b>transparency preload list</b>. </p><p>If a site appears in the preload list, the browser will expect it to provide an inclusion proof in the prefix tree, or else a proof of non-inclusion in a newer version of the prefix tree, thereby showing they’ve unenrolled. The site must provide one of these proofs until the last preload list it appears in has expired. Finally, even though the preload list is derived from the prefix tree, there is nothing enforcing this relationship. Thus, the preload list should also be published transparently.</p>
    <div>
      <h4>Filling in Missing Properties</h4>
      <a href="#filling-in-missing-properties">
        
      </a>
    </div>
    <p>Remember we still have the requirements of monitorability, opt-out being transparent, and no single point of failure/trust. We fill in those details now.</p><p><b>Adding monitorability.</b> So far, in order for a site operator to ensure their site was not hijacked, they would have to constantly query every transparency service for its domain and verify that it hasn’t been tampered with. This is certainly better than the <a href="https://ct.cloudflare.com/"><u>500k events per hour</u></a> that CT monitors have to ingest, but it still requires the monitor to be constantly polling the prefix tree, and it imposes a constant load for the transparency service.</p><p>We add a field to the prefix tree leaf structure: the leaf now stores a “created” timestamp, containing the time the leaf was created. Witnesses ensure that the “created” field remains the same over all leaf updates (and it is deleted when the leaf is deleted). To monitor, a site operator need only keep the last observed “created” and “log size” fields of its leaf. If it fetches the latest leaf and sees both unchanged, it knows that no changes occurred since the last check.</p><p><b>Adding transparency of opt-out.</b> We must also do the same thing as above for leaf deletions. When a leaf is deleted, a monitor should be able to learn when the deletion occurred within some reasonable time frame. Thus, rather than outright removing a leaf, the transparency service responds to unenrollment requests by replacing the leaf with a <b>tombstone</b> value, containing just a “created” timestamp. As before, witnesses ensure that this field remains unchanged until the leaf is permanently deleted (after some visibility period) or re-enrolled.</p><p><b>Permitting multiple transparency services.</b> Since we require that there be no single point of failure or trust, we imagine an ecosystem where there are a handful of non-colluding, reasonably trustworthy transparency service providers, each with their own prefix tree. Like Certificate Transparency (CT), this set should not be too large. It must be small enough that reasonable levels of trust can be established, and so that independent auditors can reasonably handle the load of verifying all of them.</p><p>Ok that’s the end of the most technical part of this post. We’re now going to talk about how to tweak this system to provide all kinds of additional nice properties.</p>
    <div>
      <h2>(Not) Achieving Consistency</h2>
      <a href="#not-achieving-consistency">
        
      </a>
    </div>
    <p>Transparency would be useless if, every time a site updates, it serves 100,000 new versions of itself. Any auditor would have to go through every single version of the code in order to ensure no user was targeted with malware. This is bad even if the velocity of versions is lower. If a site publishes just one new version per week, but every version from the past ten years is still servable, then users can still be served extremely old, potentially vulnerable versions of the site, without anyone knowing. Thus, in order to make transparency valuable, we need <b>consistency</b>, the property that every browser sees the same version of the site at a given time.</p><p>We will not achieve the strongest version of consistency, but it turns out that weaker notions are sufficient for us. If, unlike the above scenario, a site had 8 valid versions of itself at a given time, then that would be pretty manageable for an auditor. So even though it’s true that users don’t all see the same version of the site, they will all still benefit from transparency, as desired.</p><p>We describe two types of inconsistency and how we mitigate them.</p>
    <div>
      <h3>Tree Inconsistency</h3>
      <a href="#tree-inconsistency">
        
      </a>
    </div>
    <p>Tree inconsistency occurs when transparency services’ prefix trees disagree on the chain hash of a site, thus disagreeing on the history of the site. One way to fully eliminate this is to establish a consensus mechanism for prefix trees. A simple one is majority voting: if there are five transparency services, a site must present three tree inclusion proofs to a user, showing the chain hash is present in three trees. This, of course, triples the tree inclusion proof size, and lowers the fault tolerance of the entire system (if three log operators go down, then no transparent site can publish any updates).</p><p>Instead of consensus, we opt to simply limit the amount of inconsistency by limiting the number of transparency services. In 2025, Chrome <a href="https://www.gstatic.com/ct/log_list/v3/log_list.json"><u>trusts</u></a> eight Certificate Transparency logs. A similar number of transparency services would be fine for our system. Plus, it is still possible to detect and prove the existence of inconsistencies between trees, since roots are signed by witnesses. So if it becomes the norm to use the same version on all trees, then social pressure can be applied when sites violate this.</p>
    <div>
      <h3>Temporal Inconsistency</h3>
      <a href="#temporal-inconsistency">
        
      </a>
    </div>
    <p>Temporal inconsistency occurs when a user gets a newer or older version of the site (both still unexpired), depending on some external factors such as geographic location or cookie values. In the extreme, as stated above, if a signed prefix root is valid for ten years, then a site can serve a user any version of the site from the last ten years.</p><p>As with tree inconsistency, this can be resolved using consensus mechanisms. If, for example, the latest manifest were published on a blockchain, then a user could fetch the latest blockchain head and ensure they got the latest version of the site. However, this incurs an extra network round trip for the client, and requires sites to wait for their hash to get published on-chain before they can update. More importantly, building this kind of consensus mechanism into our specification would drastically increase its complexity. We’re aiming for v1.0 here.</p><p>We mitigate temporal inconsistency by requiring reasonably short validity periods for witness signatures. Making prefix root signatures valid for, e.g., one week would drastically limit the number of simultaneously servable versions. The cost is that site operators must now query the transparency service at least once a week for the new signed root and inclusion proof, even if nothing in the site changed. The sites cannot skip this, and the transparency service must be able to handle this load. This parameter must be tuned carefully.</p>
    <div>
      <h2>Beyond Integrity, Consistency, and Transparency</h2>
      <a href="#beyond-integrity-consistency-and-transparency">
        
      </a>
    </div>
    <p>Providing integrity, consistency, and transparency is already a huge endeavor, but there are some additional app store-like security features that can be integrated into this system without too much work.</p>
    <div>
      <h3>Code Signing</h3>
      <a href="#code-signing">
        
      </a>
    </div>
    <p>One problem that WAICT doesn’t solve is that of <i>provenance</i>: where did the code the user is running come from, precisely? In settings where audits of code happen frequently, this is not so important, because some third party will be reading the code regardless. But for smaller self-hosted deployments of open-source software, this may not be viable. For example, if Alice hosts her own version of <a href="https://cryptpad.org/"><u>Cryptpad</u></a> for her friend Bob, how can Bob be sure the code matches the real code in Cryptpad’s Github repo?</p><p><b>WEBCAT.</b> The folks at the Freedom of Press Foundation (FPF) have built a solution to this, called <a href="https://securedrop.org/news/introducing-webcat-web-based-code-assurance-and-transparency/"><u>WEBCAT</u></a>. This protocol allows site owners to announce the identities of the developers that have signed the site’s integrity manifest, i.e., have signed all the code and other assets that the site is serving to the user. Users with the WEBCAT plugin can then see the developer’s <a href="https://www.sigstore.dev/"><u>Sigstore</u></a> signatures, and trust the code based on that.</p><p>We’ve made WAICT extensible enough to fit WEBCAT inside and benefit from the transparency components. Concretely, we permit manifests to hold additional metadata, which we call <b>extensions</b>. In this case, the extension holds a list of developers’ Sigstore identities. To be useful, browsers must expose an API for browser plugins to access these extension values. With this API, independent parties can build plugins for whatever feature they wish to layer on top of WAICT.</p>
    <div>
      <h2>Cooldown</h2>
      <a href="#cooldown">
        
      </a>
    </div>
    <p>So far we have not built anything that can prevent attacks in the moment. An attacker who breaks into a website can still delete any code-signing extensions, or just unenroll the site from transparency entirely, and continue with their attack as normal. The unenrollment will be logged, but the malicious code will not be, and by the time anyone sees the unenrollment, it may be too late.</p><p>To prevent spontaneous unenrollment, we can enforce <b>unenrollment cooldown</b> client-side. Suppose the cooldown period is 24 hours. Then the rule is: if a site appears on the preload list, then the client will require that either 1) the site have transparency enabled, or 2) the site have a tombstone entry that is at least 24 hours old. Thus, an attacker will be forced to either serve a transparency-enabled version of the site, or serve a broken site for 24 hours.</p><p>Similarly, to prevent spontaneous extension modifications, we can enforce <b>extension cooldown</b> on the client. We will take code signing as an example, saying that any change in developer identities requires a 24 hour waiting period to be accepted. First, we require that extension <code>dev-ids</code> has a preload list of its own, letting the client know which sites have opted into code signing (if a preload list doesn’t exist then any site can delete the extension at any time). The client rule is as follows: if the site appears in the preload list, then both 1) <code>dev-ids</code> must exist as an extension in the manifest, and 2) <code>dev-ids-inclusion</code> must contain an inclusion proof showing that the current value of dev-ids was in a prefix tree that is at least 24 hours old. With this rule, a client will reject values of <code>dev-ids</code> that are newer than a day. If a site wants to delete <code>dev-ids</code>, they must 1) request that it be removed from the preload list, and 2) in the meantime, replace the dev-ids value with the empty string and update <code>dev-ids-inclusion</code> to reflect the new value.</p>
    <div>
      <h2>Deployment Considerations</h2>
      <a href="#deployment-considerations">
        
      </a>
    </div>
    <p>There are a lot of distinct roles in this ecosystem. Let’s sketch out the trust and resource requirements for each role.</p><p><b>Transparency service.</b> These parties store metadata for every transparency-enabled site on the web. If there are 100 million domains, and each entry is 256B each (a few hashes, plus a URL), this comes out to 26GB for a single tree, not including the intermediate hashes. To prevent size blowup, there would probably have to be a pruning rule that unenrolls sites after a long inactivity period. Transparency services should have largely uncorrelated downtime, since, if all services go down, no transparency-enabled site can make any updates. Thus, transparency services must have a moderate amount of storage, be relatively highly available, and have downtime periods uncorrelated with each other.</p><p>Transparency services require some trust, but their behavior is narrowly constrained by witnesses. Theoretically, a service can replace any leaf’s chain hash with its own, and the witness will validate it (as long as the consistency proof is valid). But such changes are detectable by anyone that monitors that leaf.</p><p><b>Witness.</b> These parties verify prefix tree updates and sign the resulting roots. Their storage costs are similar to that of a transparency service, since they must keep a full copy of a prefix tree for every transparency service they witness. Also like the transparency services, they must have high uptime. Witnesses must also be trusted to keep their signing key secret for a long period of time, at least long enough to permit browser trust stores to be updated when a new key is created.</p><p><b>Asset host.</b> These parties carry little trust. They cannot serve bad data, since any query response is hashed and compared to a known hash. The only malicious behavior an asset host can do is refuse to respond to queries. Asset hosts can also do this by accident due to downtime.</p><p><b>Client.</b> This is the most trust-sensitive part. The client is the software that performs all the transparency and integrity checks. This is, of course, the web browser itself. We must trust this.</p><p>We at Cloudflare would like to contribute what we can to this ecosystem. It should be possible to run both a transparency service and a witness. Of course, our witness should not monitor our own transparency service. Rather, we can witness other organizations’ transparency services, and our transparency service can be witnessed by other organizations.</p>
    <div>
      <h3>Supporting Alternate Ecosystems</h3>
      <a href="#supporting-alternate-ecosystems">
        
      </a>
    </div>
    <p>WAICT should be compatible with non-standard ecosystems, ones where the large players do not really exist, or at least not in the way they usually do. We are working with the FPF on defining transparency for alternate ecosystems with different network and trust environments. The primary example we have is that of the Tor ecosystem.</p><p>A paranoid Tor user may not trust existing transparency services or witnesses, and there might not be any other trusted party with the resources to self-host these functionalities. For this use case, it may be reasonable to put the <a href="https://github.com/freedomofpress/webcat-infra-chain"><u>prefix tree on a blockchain somewhere</u></a>. This makes the usual domain validation impossible (there’s no validator server to speak of), but this is fine for onion services. Since an onion address is just a public key, a signature is sufficient to prove ownership of the domain.</p><p>One consequence of a consensus-backed prefix tree is that witnesses are now unnecessary, and there is only need for the single, canonical, transparency service. This mostly solves the problems of tree inconsistency at the expense of latency of updates.</p>
    <div>
      <h2>Next Steps</h2>
      <a href="#next-steps">
        
      </a>
    </div>
    <p>We are still very early in the standardization process. One of the more immediate next steps is to get subresource integrity working for more data types, particularly WASM and images. After that, we can begin standardizing the integrity manifest format. And then after that we can start standardizing all the other features. We intend to work on this specification hand-in-hand with browsers and the IETF, and we hope to have some exciting betas soon.</p><p>In the meantime, you can follow along with our <a href="https://github.com/rozbb/draft-waict-transparency"><u>transparency specification draft</u></a>, check out the open problems, and share your ideas. Pull requests and issues are always welcome!</p>
    <div>
      <h2>Acknowledgements</h2>
      <a href="#acknowledgements">
        
      </a>
    </div>
    <p>Many thanks to Dennis Jackson from Mozilla for the lengthy back-and-forth meetings on design, to Giulio B and Cory Myers from FPF for their immensely helpful influence and feedback, and to Richard Hansen for great feedback.</p> ]]></content:encoded>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Malicious JavaScript]]></category>
            <category><![CDATA[JavaScript]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">6GRxDReQHjD7T0xpfjf7Iq</guid>
            <dc:creator>Michael Rosenberg</dc:creator>
        </item>
        <item>
            <title><![CDATA[Securing today for the quantum future: WARP client now supports post-quantum cryptography (PQC)]]></title>
            <link>https://blog.cloudflare.com/post-quantum-warp/</link>
            <pubDate>Wed, 24 Sep 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ To prepare for a future where powerful quantum computers come online, we've upgraded our WARP client with post-quantum cryptography. ]]></description>
            <content:encoded><![CDATA[ <p>The Internet is currently transitioning to <a href="https://www.cloudflare.com/pqc/"><u>post-quantum cryptography (PQC)</u></a> in preparation for Q-Day, when quantum computers break the classical cryptography that underpins all modern computer systems.  The US <a href="https://www.nist.gov/"><u>National Institute of Standards and Technology (NIST)</u></a> recognized the urgency of this transition, announcing that classical cryptography (<a href="https://en.wikipedia.org/wiki/RSA_cryptosystem"><u>RSA</u></a>, Elliptic Curve Cryptography (<a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>ECC</u></a>)) must be <a href="https://csrc.nist.gov/pubs/ir/8547/ipd"><u>deprecated by 2030 and completely disallowed by 2035</u></a>.</p><p>Cloudflare is well ahead of NIST’s schedule. Today, over <a href="https://radar.cloudflare.com/adoption-and-usage?cf_history_state=%7B%22guid%22%3A%22C255D9FF78CD46CDA4F76812EA68C350%22%2C%22historyId%22%3A20%2C%22targetId%22%3A%22583662CE97724FCE7A7C0844276279FE%22%7D#post-quantum-encryption-adoption"><u>45%</u></a> of human-generated Internet traffic sent to Cloudflare’s network is already post-quantum encrypted. Because we believe that a secure and private Internet should be free and accessible to all, we’re on a mission to include PQC in all our <a href="https://blog.cloudflare.com/post-quantum-cryptography-ga/"><u>products</u></a>, <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>without specialized hardware</u></a>, and at <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free/"><u>no extra cost to our customers and end users</u></a>.</p><p>That’s why we’re proud to announce that <a href="https://developers.cloudflare.com/warp-client/"><u>Cloudflare’s WARP client</u></a> now supports post-quantum key agreement — both in our free consumer WARP client <a href="https://one.one.one.one/"><u>1.1.1.1</u></a>, and in our enterprise WARP client, the <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/download-warp/"><u>Cloudflare One Agent</u></a>. </p>
    <div>
      <h2>Post-quantum tunnels using the WARP client</h2>
      <a href="#post-quantum-tunnels-using-the-warp-client">
        
      </a>
    </div>
    <p>This upgrade of the WARP client to post-quantum key agreement provides end users with immediate protection for their Internet traffic against <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest-now-decrypt-later attacks</u></a>. The value proposition is clear — by tunneling your Internet traffic over the WARP client’s post-quantum MASQUE tunnels, you get immediate post-quantum encryption of your network traffic. And this holds even if the individual connections sent through the tunnel have not yet been upgraded to post-quantum cryptography.</p><p>Here’s how it works.</p><p>When the <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/download-warp/"><u>Cloudflare One Agent</u></a> (our enterprise WARP client) connects employees to the internal corporate resources as part of the <a href="https://developers.cloudflare.com/cloudflare-one/"><u>Cloudflare One Zero Trust</u></a> platform, it now provides <a href="https://blog.cloudflare.com/post-quantum-zero-trust/"><u>end-to-end quantum encryption</u></a> of network traffic. As shown in the figure below, traffic from the WARP client is wrapped in a post-quantum encrypted <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>MASQUE</u></a> (<a href="https://datatracker.ietf.org/wg/masque/about/"><u>Multiplexed Application Substrate over QUIC Encryption</u></a>) tunnel, sent to Cloudflare’s <a href="https://www.cloudflare.com/network/"><u>global network</u></a> network (link (1)). Cloudflare’s global network then forwards the traffic another set of post-quantum encrypted tunnels (link (2)), and then finally on to the internal corporate resource using a <a href="https://blog.cloudflare.com/post-quantum-tunnel/"><u>post-quantum encrypted</u></a> Cloudflare <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Tunnel</u></a> established using the <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>cloudflared agent</u></a> (which installed near the corporate resource) (link (3)). </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7q9k7Ss95iM1PSiSIW76MD/db8146afa3da442d5459dac0919a3f31/image2.png" />
          </figure><p><sup><i>We have upgraded the </i></sup><a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/download-warp/"><sup><i><u>Cloudflare One Agent</u></i></sup></a><sup> </sup><sup><i>to post-quantum key agreement, providing end-to-end post quantum protection for traffic sent to internal corporate resources. </i></sup></p><p>When an end user <a href="https://developers.cloudflare.com/learning-paths/secure-internet-traffic/connect-devices-networks/install-agent/"><u>installs</u></a> the consumer WARP Client (<a href="https://one.one.one.one/"><u>1.1.1.1</u></a>), the WARP client wraps the end user’s network traffic in a post-quantum encrypted <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>MASQUE</u></a> tunnel. As shown in the figure below, the MASQUE tunnel protects the traffic on its way to Cloudflare’s <a href="https://www.cloudflare.com/network/"><u>global network</u></a> (link (1)). Cloudflare's global network then uses post-quantum encrypted tunnels to bring the traffic as close as possible to its final destination (link (2)). Finally, the traffic is forwarded over the public Internet to the origin server (i.e. its final destination). That final connection (link (3)) may or may not be post-quantum (PQ). It will not be PQ if the origin server is not PQ.  It will be PQ if the origin server is (a) upgraded to PQC, and (b) the end user is connecting to over a client that supports PQC (like Chrome, Edge or Firefox).  In the future, <a href="https://blog.cloudflare.com/automatically-secure"><u>Automatic SSL/TLS</u></a> will ensure that your entire connection will be PQ as long as the origin server is behind Cloudflare and supports PQ connections (even if your browser doesn’t).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/gagcJJsc6aLeAThvV5Wa4/c01ea5a20ea19778deca13e0eb4c7de3/image4.png" />
          </figure><p><sup><i>Consumer WARP client (</i></sup><a href="https://one.one.one.one/"><sup><i><u>1.1.1.1</u></i></sup></a><sup><i>) is now upgraded to post-quantum key agreement.</i></sup></p>
    <div>
      <h2>The cryptography landscape</h2>
      <a href="#the-cryptography-landscape">
        
      </a>
    </div>
    <p>Before we get into the details of our upgrade to the WARP client, let’s review the different cryptographic primitives involved in the transition to PQC. </p><p>Key agreement is a method by which two or more parties can establish a shared secret key over an insecure communication channel. This shared secret can then be used to encrypt and authenticate subsequent communications. Classical key agreement in <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>Transport Layer Security (TLS)</u></a> typically uses the <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>Elliptic Curve Diffie Hellman (ECDH)</u></a> cryptographic algorithm, whose security can be broken by a quantum computer using <a href="https://en.wikipedia.org/wiki/Shor%27s_algorithm"><u>Shor's algorithm</u></a>. </p><p>We need <a href="https://blog.cloudflare.com/post-quantum-key-encapsulation/"><b><u>post-quantum key agreement</u></b></a> today to stop <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest-now-decrypt-later attacks</u></a>, where attackers collect encrypted data today, and then decrypt it in future once powerful quantum computers become available. Any institution that deals with data that could still be valuable ten years in the future (<a href="https://www.cloudflare.com/cloudflare-for-government/"><u>governments</u></a>, <a href="https://www.cloudflare.com/banking-and-financial-services/"><u>financial institutions</u></a>, <a href="https://www.cloudflare.com/healthcare/"><u>healthcare organizations</u></a>, and more) should deploy PQ key agreement to prevent these attacks.</p><p>This is why we upgraded the WARP client to post-quantum key agreement.</p><p>Post-quantum key agreement is already quite mature and performant; our <a href="https://blog.cloudflare.com/pq-2024/#ml-kem-versus-x25519"><u>experiments</u></a> have shown that deploying the post-quantumModule-Lattice-Based Key-Encapsulation Mechanism (<a href="https://csrc.nist.gov/pubs/fips/203/final"><u>ML-KEM</u></a>) algorithm in hybrid mode (in parallel with classical ECDH) over <a href="https://www.cloudflare.com/learning/ssl/why-use-tls-1.3/"><u>TLS 1.3</u></a> is actually more performant than using <a href="https://www.cloudflare.com/learning/ssl/why-use-tls-1.3/"><u>TLS 1.2</u></a> with classical cryptography. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ggHbhukH4atXV4EIbPlrl/9845ac63363c9233fa0bff6b47a1ea79/image1.png" />
          </figure><p><sup><i>Over one-third of the human-generated traffic to our network uses TLS 1.3 with hybrid post-quantum key agreement (shown as X25519MLKEM768 in the screen capture above); in fact, if you’re on a Chrome, Edge or Firefox browser, you’re probably reading this blog right now over a PQ encrypted connection.</i></sup></p><p><b>Post-quantum digital signatures and certificates, </b>by contrast, are still in the process of being <a href="https://datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates/"><u>standardized</u></a> for use in TLS and the Internet’s Public Key Infrastructure (PKI). <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/"><u>PQ signatures and certificates</u></a> are required to prevent an active attacker who uses a quantum computer to forge a digital certificate/signature and then uses it to decrypt or manipulate communications by impersonating a trusted server. As far as we know, we don’t have such attackers yet, which is why post-quantum signatures and certificates are not widely deployed across the Internet. We have not yet upgraded the WARP client to <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/"><u>PQ signatures and certificates</u></a>, but we plan to do so soon.</p>
    <div>
      <h2>A unique challenge: PQC upgrade in the WARP client </h2>
      <a href="#a-unique-challenge-pqc-upgrade-in-the-warp-client">
        
      </a>
    </div>
    <p>While Cloudflare is on the <a href="https://blog.cloudflare.com/tag/post-quantum/"><u>forefront of the PQC transition</u></a>, a different kind of challenge emerged when we upgraded our WARP client. Unlike a server that we fully control and can hotfix at any time, our WARP client runs directly on end user devices. In fact, it runs on millions of end user devices that we do not control. This fundamental difference means that every time we update the WARP client, our release must work properly on the first try, with no room for error.</p><p>To make things even more challenging, we need to support the WARP client across five different operating systems (Windows, macOS, Linux, iOS, and Android/ChromeOS), while also ensuring consistency and reliability for both our consumer 1.1.1.1 WARP client and our Cloudflare One Agent. In addition, because the WARP client relies on the fairly new <a href="https://datatracker.ietf.org/doc/rfc9298/"><u>MASQUE protocol</u></a>, which the industry only standardized in August 2022, we need to be extra careful to make sure our upgrade to post-quantum key agreement does not expose latent bugs or instabilities in the MASQUE protocol itself. </p><p>All these challenges point to a slow and careful transition to PQC in the WARP client, while still supporting customers that want to immediately activate PQC. To accomplish this, we used three techniques: </p><ol><li><p>temporary PQC downgrades, </p></li><li><p>gradual rollout across our WARP client population, and</p></li><li><p>a <a href="https://en.wikipedia.org/wiki/Mobile_device_management"><u>Mobile Device Management (MDM)</u></a> override. </p></li></ol><p>Let’s take a deep dive into each. </p>
    <div>
      <h3>Temporary PQC downgrades</h3>
      <a href="#temporary-pqc-downgrades">
        
      </a>
    </div>
    <p>As we roll out PQ key agreement in MASQUE to the WARP client, we want to make sure we don’t have WARP clients that struggle to connect due to an error, middlebox, or a latent implementation bug triggered by our PQC migration. One way to accomplish this level of robustness is to have clients downgrade to a classic cryptographic connection if they fail to negotiate a PQ connection.</p><p>To really understand this strategy, we need to review the concept of <b>cryptographic downgrades</b>. In cryptography, a <b>downgrade attack</b> is a cyber attack where an attacker forces a system to abandon a secure cryptographic algorithm in favor of an older, less secure, or even unencrypted one that allows the attacker to introspect on the communications. Thus, when newly rolling out a PQ encryption, it is standard practice to ensure that: if the client and server <i>both </i>support PQ encryption, it should not be possible for an attacker to downgrade their connection to a classic encryption. </p><p>Thus, to prevent downgrade attacks, we should ensure that if the client and server both support PQC, but fail to negotiate a PQC connection, then the connection will just fail. However, while this prevents downgrade attacks, it also creates problems with robustness.</p><p>We cannot have both robustness (i.e. the ability for client to downgrade to a classical connection if the PQC fails) and security against downgrades (i.e. the client is forbidden to downgrade to classical cryptography once it supports PQC) at the same time. We have to choose one. For this reason, we opted for a phased approach.</p><ul><li><p><b>Phase 1: Automated PQC downgrades.</b> We start by choosing robustness at the cost of providing security against downgrade attacks.  In this phase, we support automated PQC downgrades — if a client fails to negotiate a PQC connection, it will downgrade to classical cryptography. That way, if there are bugs or other instability introduced by PQC, the client automatically downgrades to classical cryptography and the end user will not experience any issues. (Note: because MASQUE establishes a single very long-lived TLS connection only when the user logs in, an end user is unlikely to notice a downgrade.) </p></li><li><p><b>Phase 2: PQC with security against downgrades. </b>Then, once the rollout is stable and we are convinced that there are no issues interfering with PQC, we will choose security against downgrade attacks over robustness. In this phase, if a client fails to negotiate a PQC connection, the connection will just fail, which provides security against downgrade attacks.</p></li></ul><p>To implement this phased approach, we introduced an API flag that the client uses to determine how it should initiate TLS handshakes, which has three states:</p><ul><li><p><b>No PQC: </b>The client initiates a TLS handshake using classical cryptography only. .</p></li><li><p><b>PQC downgrades allowed:</b> The client initiates a TLS handshake using post-quantum key agreement. If the PQC handshake negotiation fails, the client downgrades to classical cryptography. This flag supports Phase 1 of our rollout. </p></li><li><p><b>PQC only:</b> The client initiates a TLS handshake using post-quantum key agreement cryptography. If the PQC handshake negotiation fails, the connection fails. This flag supports Phase 2 of our rollout.</p></li></ul><p>The WARP <a href="https://developers.cloudflare.com/changelog/2025-06-30-warp-windows-ga/"><u>desktop version 2025.5.893.0</u></a>, <a href="https://developers.cloudflare.com/changelog/2025-06-30-warp-ga-ios/"><u>iOS version 1.11</u></a> and <a href="https://developers.cloudflare.com/changelog/2025-06-30-warp-ga-android/"><u>Android version 2.4.2 </u></a>all support post-quantum key agreement along with this API flag.</p><p>With this as our framework, the next question becomes: what timing makes sense for this phased approach?</p>
    <div>
      <h3>Gradual rollout across the WARP client population</h3>
      <a href="#gradual-rollout-across-the-warp-client-population">
        
      </a>
    </div>
    <p>To limit the risk of errors or latent implementation bugs triggered by our PQC migration, we gradually rolled out PQC across our population of WARP clients.</p><p>In Phase 1 of our rollout, we prioritized robustness rather than security against downgrade attacks. Thus, initially the API flag is set to “No PQC” for our entire client population, and we gradually turn on the “PQC downgrades allowed” across groups of clients. As we do this, we monitor whether any clients downgrade from PQC to classical cryptography. At the time of this writing, we have completed the Phase 1 rollout to all of our consumer WARP (1.1.1.1) clients. We expect to complete Phase 1 for our Cloudflare One Agent by the end of 2025.</p><p>Downgrades are not expected during Phase 1. In fact, downgrades indicate that there may be a latent issue that we have to fix. If you are using a WARP client and encounter issues that you believe might be related to PQC, you can let us know by using the feedback button in the WARP client interface (by clicking the bug icon in the top-right corner of the WARP client application). Enterprise users can also file a support ticket for the Cloudflare One Agent.</p><p>We plan to enter Phase 2 — where the API flag is set to “PQC only” in order to provide security against downgrade attacks — by summer of mid 2026. </p>
    <div>
      <h3>MDM override</h3>
      <a href="#mdm-override">
        
      </a>
    </div>
    <p>Finally, we know that some of our customers may not be willing to wait for us to complete this careful upgrade to PQC. So, those customers can activate PQC right now. </p><p>We’ve built a <a href="https://en.wikipedia.org/wiki/Mobile_device_management"><u>Mobile Device Management (MDM)</u></a> override for the Cloudflare One Agent. MDM allows organizations to centrally manage, monitor, and secure mobile devices that access corporate resources; it works on multiple types of devices, not just mobile devices. The override for the Cloudflare One Agent allows an administrator (with permissions to manage the device) to turn on PQC. To use the <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/mdm-deployment/parameters/#enable_post_quantum"><u>MDM post-quantum override</u></a>, set the ‘enable_post_quantum’ MDM flag to true. This flag takes precedence over the signal from the API flag we described earlier, and will activate PQC without downgrades. With this setting, the client will only negotiate a PQC connection. And if the PQC negotiation fails, the connection will fail, which provides security against downgrade attacks. </p>
    <div>
      <h2>Ciphersuites, FIPS and Fedramp </h2>
      <a href="#ciphersuites-fips-and-fedramp">
        
      </a>
    </div>
    <p>The <a href="https://www.cloudflare.com/learning/privacy/what-is-fedramp/">Federal Risk and Authorization Management Program (FedRAMP)</a> is a U.S. government standard for securing federal data in the cloud. <a href="https://cf-assets.www.cloudflare.com/slt3lc6tev37/7wOGN7Ua9rvgzlQAwlFZ6y/324506e91b62aa4de55bcb2ceb5d8ee8/Cloudflare-s_Unique_FedRAMP_Architecture.pdf"><u>Cloudflare has a FedRAMP certification</u></a> that requires that we use cryptographic ciphersuites that comply with <a href="https://csrc.nist.gov/glossary/term/federal_information_processing_standard"><u>FIPS</u></a> (Federal Information Processing Standards) for certain products that are inside our FIPS boundary.</p><p>Because the WARP client is inside Cloudflare’s FIPS boundary for our <a href="https://www.fedramp.gov/"><u>FedRAMP</u></a> certification, we had to ensure it uses FIPS-compliant cryptography. For internal links (where Cloudflare controls both sides of the connection) within the FIPS boundary, we currently use a hybrid key agreement consisting of FIPS-compliant EDCH using the P256 Elliptic curve, in parallel with an early version of ML-KEM-768 (which we started using before the ML-KEM standards were finalized) — a key agreement called P256Kyber768Draft00. To observe this ciphersuite in action in your WARP client, you can use the <code>warp-cli tunnel stats</code> utility. Here’s an example of what we find when PQC is enabled:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ilpmpuGdOAzbqX28T34tc/17254678b17ba493da1da09f10493e9e/image5.png" />
          </figure><p>And here is an example when PQC is not enabled:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3mdNurLT1USiRICpkvIKa8/1af40525be2ccaa5b6ef71824f0ace37/image6.png" />
          </figure>
    <div>
      <h2>PQC tunnels for everyone </h2>
      <a href="#pqc-tunnels-for-everyone">
        
      </a>
    </div>
    <p>We believe that PQC should be available to everyone, without <a href="https://blog.cloudflare.com/you-dont-need-quantum-hardware/"><u>specialized hardware</u></a>, at <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free/"><u>no additional cost</u></a>. To that end, we’re proud to help shoulder the burden of the Internet’s upgrade to PQC.</p><p>A powerful strategy is to use tunnels protected by post-quantum key agreement to protect Internet traffic, in bulk, from harvest-now-decrypt-later attacks – even if the individual connections sent through the tunnel have not yet been upgraded to PQC. Eventually, we will upgrade these tunnels to also support post-quantum signatures and certificates, to stop active attacks by adversaries armed with quantum computers after Q-Day.</p><p>This staged approach keeps up with Internet standards. And the use of tunnels provides customers and end users with built-in <i>cryptographic agility</i>, so they can easily adapt to changes in the cryptographic landscape without a major architectural overhaul.</p><p>Cloudflare’s WARP client is just the latest tunneling technology that we’ve upgraded to post-quantum key agreement. You can try it out today for free on personal devices using our free consumer WARP client <a href="https://one.one.one.one/"><u>1.1.1.1</u></a>, or for your corporate devices using our <a href="https://dash.cloudflare.com/sign-up/zero-trust"><u>free zero-trust offering for teams of under 50 users</u></a> or a paid <a href="https://www.cloudflare.com/plans/zero-trust-services/"><u>enterprise zero-trust or SASE subscription</u></a>. Just <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/download-warp/"><u>download</u></a> and install the client on your Windows, Linux, macOS, iOS, Android/ChromeOS device, and start protecting your network traffic with PQC.</p><div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[WARP]]></category>
            <category><![CDATA[Cloudflare Zero Trust]]></category>
            <category><![CDATA[SASE]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <category><![CDATA[1.1.1.1]]></category>
            <guid isPermaLink="false">6Z8Ii372a6Lta1Y2ISnfWw</guid>
            <dc:creator>Sharon Goldberg</dc:creator>
            <dc:creator>Tochukwu Nkemdilim (Toks)</dc:creator>
            <dc:creator>Koko Uko</dc:creator>
        </item>
        <item>
            <title><![CDATA[You don’t need quantum hardware for post-quantum security]]></title>
            <link>https://blog.cloudflare.com/you-dont-need-quantum-hardware/</link>
            <pubDate>Fri, 19 Sep 2025 13:44:40 GMT</pubDate>
            <description><![CDATA[ Post-quantum cryptography protects against quantum threats using today’s hardware. Quantum tech like QKD may sound appealing, but it isn’t necessary or sufficient to secure organizations. ]]></description>
            <content:encoded><![CDATA[ <p>Organizations have finite resources available to combat threats, both by the adversaries of today and those in the not-so-distant future that are armed with quantum computers. In this post, we provide guidance on what to prioritize to best prepare for the future, when quantum computers become powerful enough to break the conventional cryptography that underpins the security of modern computing systems.  We describe how <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/"><u>post-quantum cryptography (PQC)</u></a> can be deployed <b>on your existing hardware</b> to protect from threats posed by <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-quantum-computing/"><u>quantum computing</u></a>, and explain why quantum key distribution (QKD) and quantum random number generation (QRNG) are neither necessary nor sufficient for security in the quantum age.</p>
    <div>
      <h2>Are you quantum ready?</h2>
      <a href="#are-you-quantum-ready">
        
      </a>
    </div>
    <p>“Quantum” is becoming one of the most heavily used buzzwords in the tech industry. What does it actually mean, and why should you care?</p><p>At its core, “quantum” refers to technologies that harness principles of quantum mechanics to perform tasks that are not feasible with classical computers. Quantum computers have exciting potential to unlock advancements in <a href="https://pubs.aip.org/aip/jap/article/133/22/221102/2896017/Quantum-computing-and-materials-science-A"><u>materials science</u></a> and <a href="https://www.weforum.org/stories/2025/01/quantum-computing-drug-development/"><u>medicine</u></a>, but also pose a <a href="https://blog.cloudflare.com/the-quantum-menace/"><u>threat</u></a> to computer security systems. The term <i>Q-day</i> refers to the day that adversaries possess quantum computers that are large and stable enough to break the conventional <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/"><u>public-key cryptography</u></a> that secures much of today’s data and communications. Recent <a href="https://sam-jaques.appspot.com/quantum_landscape"><u>advances in quantum computing</u></a> have made it clear that it is no longer a question of <i>if </i>Q-day will arrive, but <i>when</i>.</p><p>What does it mean, then, for your organization to be <a href="https://www.cloudflare.com/the-net/top-of-mind-technology/post-quantum-security/"><u>quantum ready</u></a>? At Cloudflare, our definition is simple: <i>your systems and communications should be secure even after Q-day</i>. </p><p>However, this definition often gets muddied by vendors insisting that products <i>built using quantum technology</i> are required in order to <i>secure </i>an organization <i>against quantum adversaries</i>. In this blog post we explain why quantum technologies are neither necessary nor sufficient to <a href="https://www.cloudflare.com/the-net/security-signals/post-quantum-era/"><u>protect against attacks by a quantum adversary</u></a>.</p><p>The good news is that there is already a solution: <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/"><u>post-quantum cryptography (PQC)</u></a>. PQC protects against attacks by quantum adversaries, but PQC is not a quantum technology — it runs on conventional computers without specialized hardware. You can use PQC today on the computers you already have, without buying expensive new hardware.</p>
    <div>
      <h2>Post-quantum cryptography</h2>
      <a href="#post-quantum-cryptography">
        
      </a>
    </div>
    <p>We’ve written <a href="https://blog.cloudflare.com/tag/post-quantum/"><u>quite a few blog posts</u></a> on post-quantum cryptography already, so we will keep this section brief.</p><p>The <a href="https://en.wikipedia.org/wiki/Public-key_cryptography"><u>public-key cryptography</u></a> that we’ve used for decades to secure our data and communications is based on math problems (like <a href="https://en.wikipedia.org/wiki/RSA_cryptosystem"><u>factoring large numbers</u></a>) that are believed to be <a href="https://en.wikipedia.org/wiki/Computational_hardness_assumption"><u>computationally hard</u></a> to solve on conventional computers. If you can efficiently solve the underlying math problem, you can efficiently break the cryptography and the systems that depend on it. As it turns out, the math problems underlying much of today’s public-key cryptography can be efficiently solved by specialized algorithms, like <a href="https://en.wikipedia.org/wiki/Shor%27s_algorithm"><u>Shor’s algorithm</u></a>, on large-scale quantum computers. </p><p>The solution? Pick new hard math problems (like finding <a href="https://blog.cloudflare.com/lattice-crypto-primer/"><u>“short” vectors in algebraic lattices</u></a>) that are no easier to solve with a quantum computer than with a conventional computer. Then, build new cryptographic systems around them. The <a href="https://www.nist.gov/"><u>US National Institute of Standards and Technologies (NIST)</u></a> launched an <a href="https://csrc.nist.gov/projects/post-quantum-cryptography/post-quantum-cryptography-standardization"><u>international competition</u></a> in 2016 to identify and standardize such cryptographic systems, which resulted in several new standards for post-quantum cryptography being published in 2024, and <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/"><u>several more under consideration</u></a> for future standardization.</p><p>Post-quantum cryptography (PQC) runs on your existing phones, laptops, and servers. PQC runs at <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>Internet scale</u></a> and can even be <a href="https://blog.cloudflare.com/pq-2024/#ml-kem-versus-x25519"><u>more performant</u></a> than classical cryptography. Except in rare cases, like when you need additional hardware acceleration in cheap smartcards or to replace legacy systems that lack <a href="https://en.wikipedia.org/wiki/Cryptographic_agility"><u>cryptographic agility</u></a>, there is <b>no need to purchase new hardware to migrate to PQC</b>.</p><p><b>If you want to know how to protect your organization from security threats posed by quantum computers, you can stop reading now. Post-quantum cryptography is the solution. </b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6V5tcIzTpANpLJ0lQFUKKJ/50c58a5536a25b39985b6fc5f17ed432/image_-_2025-09-19T142023.308.png" />
          </figure><p>Alternatively, you can read below for our perspective on hardware-based quantum security technologies that are sometimes marketed as security solutions.</p>
    <div>
      <h2>Quantum security technologies</h2>
      <a href="#quantum-security-technologies">
        
      </a>
    </div>
    <p>Quantum technologies capture the imagination. <a href="https://en.wikipedia.org/wiki/Quantum_computing"><u>Quantum computers</u></a> (possibly linked together in a <a href="https://en.wikipedia.org/wiki/Quantum_network"><u>quantum Internet</u></a>) promise to deliver breakthroughs in <a href="https://www.weforum.org/stories/2025/01/quantum-computing-drug-development/"><u>drug discovery</u></a> and <a href="https://pubs.aip.org/aip/jap/article/133/22/221102/2896017/Quantum-computing-and-materials-science-A"><u>materials science</u></a> via advanced molecular simulation. Measurement of physical <a href="https://en.wikipedia.org/wiki/Hardware_random_number_generator"><u>quantum processes</u></a> can be used to generate <a href="https://en.wikipedia.org/wiki/Entropy"><u>entropy</u></a> with mathematically <a href="https://www.nature.com/articles/s41467-022-35556-z"><u>provable properties</u></a>.</p><p>This is exciting technology and fundamental scientific research. But this technology is <b>not</b> required to secure data and communications against quantum attackers.</p><p>In this section, we’ll explain why quantum security technologies do not need to be part of your quantum readiness strategy, and <b>any decision to invest in quantum technology should not be based on a desire to defend data and communications systems against the threat of quantum adversaries. </b>Instead, investments should be based on a desire to improve quantum technologies in their own right, for example to help with applications like <a href="https://pubs.acs.org/doi/10.1021/acs.chemrev.4c00678"><u>chemistry</u></a>, <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/"><u>machine learning</u></a>, and <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC11257328/"><u>financial modeling</u></a>.</p><p>Our position here is largely in agreement with the strategies towards quantum security technologies of the <a href="https://www.nsa.gov/Cybersecurity/Post-Quantum-Cybersecurity-Resources/"><u>US National Security Agency (NSA)</u></a>, <a href="https://www.ncsc.gov.uk/whitepaper/quantum-networking-technologies"><u>UK National Cyber Security Centre (NCSC)</u></a>, <a href="https://english.ncsc.nl/binaries/ncsc-en/documenten/publications/2024/march/25/quantum-secure/Make+your+organization+quantum+secure.pdf"><u>NL Nationaal Cyber Security Centrum (NCSC)</u></a>, and <a href="https://www.bsi.bund.de/EN/Themen/Unternehmen-und-Organisationen/Informationen-und-Empfehlungen/Quantentechnologien-und-Post-Quanten-Kryptografie/quantentechnologien-und-post-quanten-kryptografie_node.html"><u>DE Federal Office for Information Security (BSI)</u></a>. We’ll focus on two quantum technologies widely marketed as security products: quantum key distribution (QKD) and quantum random number generation (QRNG).</p>
    <div>
      <h3>Quantum key distribution</h3>
      <a href="#quantum-key-distribution">
        
      </a>
    </div>
    <p>Quantum key distribution (QKD) is a hardware-based solution to secure communications across point-to-point links. Rather than relying on hard mathematical problems, QKD relies on principles of quantum physics to establish a shared symmetric secret between two parties, while ensuring that eavesdropping can be detected. QKD provides security guarantees that are based on physical properties of the communication channel. Once a shared secret is established, parties can switch to traditional symmetric-key cryptography for secure communication. QKD is the first step towards a futuristic “quantum Internet.” However, there are some fundamental reasons why QKD cannot be a general replacement for classical cryptography running on conventional hardware.</p><p>Most importantly, <i>QKD does not operate at Internet scale</i>. QKD is used to establish an unauthenticated secret between pairs of parties with a direct physical link between them. The parties can then use an authentication mechanism based on conventional cryptography to bootstrap a secure communication channel over that link. While building dedicated physical links may be feasible for cross-datacenter communication or across major Internet backbones, it is not possible for most pairs of parties on the Internet. In particular, deploying QKD for the “last-mile” connection to end-user devices would require that each device has a direct physical connection to every server or device it needs to securely communicate with.</p><p>Connectivity aside, there's a good reason why the Internet doesn't rely on secure point-to-point links: they do not scale (or rather, they scale exponentially). Bringing a new device online would require a change to <i>every other device</i> it needs to communicate with, a massive operational burden on everyone. Fortunately, there’s a better way. The <a href="https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/"><u>OSI model</u></a> for networking provides an abstraction such that two parties can communicate even if they don’t share a direct physical link, so long as some chain of physical links exists between them. Public-key cryptography, invented in the seminal “<a href="https://www-ee.stanford.edu/~hellman/publications/24.pdf"><u>New Directions in Cryptography</u></a>” paper in 1976, allows two parties participating in the same <a href="https://en.wikipedia.org/wiki/Public_key_infrastructure"><u>public-key infrastructure</u></a> to establish a secure <a href="https://en.wikipedia.org/wiki/End-to-end_encryption"><u>end-to-end encrypted</u></a> communication channel, without requiring any prior setup between them. The massive scaling enabled by these technologies is why the secure Internet exists as we know it. Secure point-to-point links are not part of the solution.</p><p>Lack of scalability is enough for us to disqualify QKD outright: if a technology can’t bring security to the whole Internet, we’re not going to spend much time on it.</p><p>The challenges with QKD don’t stop there though.</p><p>QKD touts theoretical security guarantees, but achieving security in practice is not so simple. QKD systems have been <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Studies/QKD-Systems/QKD-Systems.pdf?__blob=publicationFile&amp;v=3"><u>plagued by implementation attacks</u></a>, both classical <a href="https://en.wikipedia.org/wiki/Side-channel_attack"><u>sidechannel attacks</u></a> and <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Studies/QKD-Systems/QKD-Systems.pdf?__blob=publicationFile&amp;v=3"><u>new ones</u></a> specific to the technology. Further, QKD works best over a special medium: either <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC4646568/"><u>fiber</u></a> or a <a href="https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.19.064003"><u>vacuum</u></a>. QKD has been demonstrated <a href="https://iopscience.iop.org/article/10.1088/1367-2630/16/4/043003"><u>over the air</u></a>, but performance and the implementation security mentioned before suffers. We still have not seen QKD work on a mobile phone or over Wi-Fi networks.</p><p>Further, neither QKD nor any other quantum technologies provide authentication to prove that the party on the other end of the key exchange is who you think they are. This opens the door for a classic <a href="https://blog.cloudflare.com/monsters-in-the-middleboxes/"><u>monster in the middle (MITM)</u></a> attack, where an adversary intercepts your connection, establishes a separate secure QKD link to you and your intended destination, and then sits in the middle reading and relaying all traffic. To prevent this, you must authenticate the identity of the party you are connecting to, using either <a href="https://en.wikipedia.org/wiki/Pre-shared_key"><u>pre-shared keys</u></a> or conventional public-key cryptography. The bottom line is, whether or not you invest in QKD, you still need a solution for authentication to protect against active attackers armed with quantum computers. Practically speaking, that means you need PQC, but PQC is already a standalone solution that provides both authentication and key agreement, which leads to questions of why use QKD in the first place.</p><p>Some <a href="https://www.amazon.science/blog/qkd-and-authentication-separating-facts-from-myths"><u>proponents</u></a> <a href="https://www.bluequbit.io/quantum-internet"><u>argue</u></a> that QKD should be integrated into existing systems as an extra security layer. The value proposition of QKD relates to the “<a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest now, decrypt later</u></a>” threat. In public-key cryptography, the key exchange messages used to set up encryption keys to secure a communication channel are exchanged in full view of a potential adversary. If an adversary records the key exchange messages, they might hope to use improved techniques in the future to solve the hard math problems upon which the security of the key exchange relies, allowing them to recover the encryption keys and decrypt the communication. If encryption keys are exchanged directly via QKD instead, the eavesdropper protections provided by QKD stop an adversary from recording messages that could later allow them to recover the encryption key (e.g. by using a quantum computer or other advances in cryptanalysis). The problem is, however, that this “extra security layer” is brittle, and limited to a single physical link. As soon as the data is transmitted elsewhere — for instance at an Internet exchange point or to travel to an end-user — the QKD security ends. For the rest of its journey, the data is protected by standard protocols like <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a>, making the value of the initial QKD link questionable.</p><p>While we hope the technology progresses, QKD is neither necessary nor sufficient for security against a quantum adversary. PQC is sufficient for security against a quantum adversary, already runs on your existing hardware, and works everywhere.</p>
    <div>
      <h3>Quantum random number generators</h3>
      <a href="#quantum-random-number-generators">
        
      </a>
    </div>
    <p>Quantum random number generators (QRNGs) are a type of<a href="https://en.wikipedia.org/wiki/Hardware_random_number_generator"><u> “true” random number generator (TRNG)</u></a> that work by harnessing inherent unpredictability of quantum mechanics, for example by measuring <a href="https://en.wikipedia.org/wiki/Radioactive_decay"><u>atomic decay</u></a> or shooting photons at a <a href="https://en.wikipedia.org/wiki/Beam_splitter"><u>beam splitter</u></a>. Other types of classical (non-quantum) TRNGs use physical phenomena that exhibit random properties, such as <a href="https://ieeexplore.ieee.org/abstract/document/982700"><u>thermal noise</u></a> from electrical components, the motion of hot wax in <a href="https://blog.cloudflare.com/randomness-101-lavarand-in-production/"><u>lava lamps</u></a>, <a href="https://blog.cloudflare.com/harnessing-office-chaos/#londons-unpredictable-pendulums"><u>double pendulums</u></a>, <a href="https://blog.cloudflare.com/harnessing-office-chaos/#austins-mesmerizing-mobiles"><u>hanging mobiles</u></a>, or <a href="https://blog.cloudflare.com/chaos-in-cloudflare-lisbon-office-securing-the-internet-with-wave-motion/"><u>water wave machines</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6hDsBCSgInfwiAP7Qlnmth/8c1601c30a8982a164edfd096a3792a6/image_-_2025-09-19T141347.781.png" />
          </figure><p>In cryptography and computer security, the essential property required from a random number generator is that the outputs are unpredictable and unbiased. This can be achieved by taking a small seed (say, 256 bits) of true randomness and feeding it to a cryptographically-secure pseudorandom number generator (CSPRNG) to produce an essentially limitless stream of pseudorandom output indistinguishable from true randomness. The randomness used to seed the CSPRNG can be based on either classical or quantum physical processes, as long as it is not known to the adversary. Whether or not you use a QRNG to generate the seed, a CSPRNG is essential for cryptographic applications.</p><p>We are the first to get excited about <a href="https://blog.cloudflare.com/randomness-101-lavarand-in-production/"><u>fun</u></a> <a href="https://blog.cloudflare.com/chaos-in-cloudflare-lisbon-office-securing-the-internet-with-wave-motion/"><u>new</u></a> <a href="https://blog.cloudflare.com/harnessing-office-chaos/"><u>sources</u></a> of <a href="https://blog.cloudflare.com/league-of-entropy/"><u>randomness</u></a>. However, we’d like to emphasize that randomness derived from quantum effects is not necessary to combat threats from quantum computers. Quantum computers do not enable any practical new attacks against classical TRNGs in widespread use today. Your decision to invest in QRNGs should be based on a perceived improvement in the quality of randomness they produce and not on a perceived threat to classical TRNGs from quantum computing.</p>
    <div>
      <h2>Post-quantum cryptography at Cloudflare</h2>
      <a href="#post-quantum-cryptography-at-cloudflare">
        
      </a>
    </div>
    <p>Cloudflare has been at the forefront of developing and deploying PQC, and we are committed to making PQC available <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free"><u>for free and by default</u></a> for all of our products. And we run it at scale — already <a href="https://radar.cloudflare.com/explorer?dataSet=http&amp;groupBy=post_quantum&amp;filters=botClass%253DLIKELY_HUMAN&amp;dt=1d"><u>over 40% of the human-generated traffic</u></a> to our network uses PQC.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1UaPlayxwXxE9cKVZAVAQR/d605e06ae2a173c8344c1def89d64b1c/image_-_2025-09-19T141341.648.png" />
          </figure><p>So what’s in that 40%? PQC is supported for all <a href="https://developers.cloudflare.com/ssl/post-quantum-cryptography/"><u>website and API traffic</u></a> served through Cloudflare, most of Cloudflare’s <a href="https://blog.cloudflare.com/post-quantum-cryptography-ga"><u>internal network traffic</u></a>, and traffic running over our <a href="https://blog.cloudflare.com/post-quantum-zero-trust/"><u>Zero-Trust platform</u></a>. All these connections use post-quantum key agreement to protect against the “<a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest now, decrypt later</u></a>” threat, where an adversary intercepts and stores encrypted data today with the hope of decrypting with a quantum computer or other cryptanalytic advances in the future. Key agreement is an important first step, but there’s still more work to be done. We’re <a href="https://mailarchive.ietf.org/arch/msg/ietf-announce/OWIjlOTCI_PIO0S2O9NHj8YUY0I/"><u>actively working</u></a> with stakeholders in the industry to prepare for the upcoming migration to post-quantum signatures to prevent active impersonation attacks from quantum adversaries (after Q-day).</p>
    <div>
      <h2>Quantum readiness strategy</h2>
      <a href="#quantum-readiness-strategy">
        
      </a>
    </div>
    <p>If purchasing quantum hardware is not necessary, how <i>should</i> organizations <a href="https://www.cloudflare.com/the-net/quantum-computing/"><u>prepare for a quantum future</u></a>? The most effective strategy will depend on your organization’s individual needs, but some general strategies will pay off for most organizations:</p><p>Investing in basic security practices is a good start. Hire the right expertise if you don’t already have it. Find vendors that support post-quantum encryption in their offerings today, and whose products are cryptographically agile so you can enjoy a seamless transition to <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/"><u>post-quantum signatures</u></a> and certificates when the industry migrates before Q-day. Follow a tunneling strategy: routing application traffic over the Internet via <a href="https://developers.cloudflare.com/ssl/post-quantum-cryptography/pqc-and-zero-trust/"><u>secure quantum safe tunnels</u></a> allows you to reduce your attack surface area with minimal changes to existing systems. If you’re already a Cloudflare customer (or want to be), our <a href="https://www.cloudflare.com/application-services/products/cdn/"><u>Content Distribution Network</u></a> and <a href="https://blog.cloudflare.com/post-quantum-zero-trust/"><u>Zero Trust platform</u></a> makes this easy. Learn more about how we can help at our <a href="https://www.cloudflare.com/pqc"><u>Post-Quantum Cryptography</u></a> webpage.</p> ]]></content:encoded>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Entropy]]></category>
            <category><![CDATA[Randomness]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">3X7BJlPGwok0pKcR33AUs0</guid>
            <dc:creator>Luke Valenta</dc:creator>
        </item>
        <item>
            <title><![CDATA[Message Signatures are now part of our Verified Bots Program, simplifying bot authentication]]></title>
            <link>https://blog.cloudflare.com/verified-bots-with-cryptography/</link>
            <pubDate>Tue, 01 Jul 2025 10:00:00 GMT</pubDate>
            <description><![CDATA[ Bots can start authenticating to Cloudflare using public key cryptography, preventing them from being spoofed and allowing origins to have confidence in their identity. ]]></description>
            <content:encoded><![CDATA[ <p>As a site owner, how do you know which bots to allow on your site, and which you’d like to block? Existing identification methods rely on a combination of IP address range (which may be shared by other services, or change over time) and user-agent header (easily spoofable). These have limitations and deficiencies. In our <a href="https://blog.cloudflare.com/web-bot-auth/"><u>last blog post</u></a>, we proposed using HTTP Message Signatures: a way for developers of bots, agents, and crawlers to clearly identify themselves by cryptographically signing requests originating from their service. </p><p>Since we published the blog post on Message Signatures and the <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>IETF draft for Web Bot Auth</u></a> in May 2025, we’ve seen significant interest around implementing and deploying Message Signatures at scale. It’s clear that well-intentioned bot owners want a clear way to identify their bots to site owners, and site owners want a clear way to identify and manage bot traffic. Both parties seem to agree that deploying cryptography for the purposes of authentication is the right solution.     </p><p>Today, we’re announcing that we’re integrating HTTP Message Signatures directly into our <b>Verified Bots Program</b>. This announcement has two main parts: (1) for bots, crawlers, and agents, we’re simplifying enrollment into the Verified Bots program for those who sign requests using Message Signatures, and (2) we’re encouraging <i>all bot operators moving forward </i>to use Message Signatures over existing verification mechanisms. Because Verified Bots are considered authenticated, they do not face challenges from our Bot Management to identify as bots, given they’re already identified as such.</p><p>For site owners, no additional action is required – Cloudflare will automatically validate signatures on our edge, and if that validation is a success, that traffic will be marked as verified so that site owners can use the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/categories/"><u>verified bot fields</u></a> to create Bot Management and <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF rules</u></a> based on it.  </p><p>This isn't just about simplifying things for bot operators — it’s about giving website owners unparalleled accuracy in identifying trusted bot traffic, cutting down on the overhead for cryptographic verification, and fundamentally transforming how we manage authentication across the Cloudflare network.</p>
    <div>
      <h2>Become a Verified Bot with Message Signatures</h2>
      <a href="#become-a-verified-bot-with-message-signatures">
        
      </a>
    </div>
    <p>Cloudflare’s existing <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/"><u>Verified Bots program</u></a> is for bots that are transparent about who they are and what they do, like indexing sites for search or scanning for security vulnerabilities. You can see a list of these verified bots in <a href="https://radar.cloudflare.com/bots#verified-bots"><u>Cloudflare Radar</u></a>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2lMYno3QOwtwfTDDgeqFx8/c69088229dcf9fc08f5a76ce7e0a0354/1.png" />
          </figure><p><sup><i>A preview of the Verified Bots page on Cloudflare Radar. </i></sup></p><p>In the past, in order to <a href="https://dash.cloudflare.com/?to=/:account/configurations/verified-bots"><u>apply</u></a> to be a verified bot, we used to ask for IP address ranges or reverse DNS names so that we could verify your identity. This required some manual steps like checking that the IP address range is valid and is associated with the appropriate <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>ASN</u></a>. </p><p>With the integration of Message Signatures, we’re aiming to streamline applications into our Verified Bot program. Bots applying with well-formed Message Signatures will be prioritized, and approved more quickly! </p>
    <div>
      <h2>Getting started</h2>
      <a href="#getting-started">
        
      </a>
    </div>
    <p>In order to make generating Message Signatures as easy as possible, Cloudflare is providing two open source libraries: a <a href="https://crates.io/crates/web-bot-auth"><u>web-bot-auth library in rust</u></a>, and a <a href="https://www.npmjs.com/package/web-bot-auth"><u>web-bot-auth npm package in TypeScript</u></a>. If you’re working on a different implementation, <a href="https://www.cloudflare.com/lp/verified-bots/"><u>let us know</u></a> – we’d love to add it to our <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/"><u>developer docs</u></a>!</p><p>At a high level, signing your requests with web bot auth consists of the following steps: </p><ul><li><p>Generate a valid signing key. See <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/#1-generate-a-valid-signing-key"><u>Signing Key section</u></a> for step-by-step instructions.</p></li><li><p>Host a JSON web key set containing your public key under <code>/.well-known/http-message-signature-directory</code> of your website.</p></li><li><p>Sign responses for that URL using a Web Bot Auth library, one signature for each key contained in it, to prove you own it. See the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/#2-host-a-key-directory"><u>Hosting section</u></a> for step-by-step instructions.</p></li><li><p>Register that URL with us, using our Verified Bots form. This can be done directly in your Cloudflare account. See <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/overview/"><u>our documentation</u></a>.</p></li><li><p>Sign requests using a Web Bot Auth library. </p></li></ul><p>
As an example, <a href="https://radar.cloudflare.com/scan"><u>Cloudflare Radar's URL Scanner</u></a> lets you scan any URL and get a publicly shareable report with security, performance, technology, and network information. Here’s an example of what a well-formed signature looks like for requests coming from URL Scanner:</p>
            <pre><code>GET /path/to/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Signature-Agent: "https://web-bot-auth-directory.radar-cfdata-org.workers.dev"
Signature-Input: sig=("@authority" "signature-agent");\
             	 created=1700000000;\
             	 expires=1700011111;\
             	 keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U";\
             	 tag="web-bot-auth"
Signature:sig=jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKrD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA==:</code></pre>
            <p>Since we’ve already registered URLScanner as a Verified Bot, Cloudflare will now automatically verify that the signature in the <code>Signature</code> header matches the request — more on that later.</p>
    <div>
      <h2>Register your bot</h2>
      <a href="#register-your-bot">
        
      </a>
    </div>
    <p>Access the <a href="https://dash.cloudflare.com/?to=/:account/configurations/verified-bots"><u>Verified Bots submission form</u></a> on your account. If that link does not immediately take you there, go to <i>your Cloudflare account</i> →  <i>Account Home</i>  → <i>the three dots next to your account name</i>  → <i>Configurations</i> → <i>Verified Bots.</i></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/73yQcvLmiVDe19HJXYvBIc/ca2bdb2bb81addc29583568087c2ccc2/3.png" />
          </figure><p>If you do not have a Cloudflare account, you can <a href="https://dash.cloudflare.com/sign-up"><u>sign up for a free one</u></a>.</p><p>For the verification method, select "Request Signature", then enter the URL of your key directory in Validation Instructions. Specifying the User-Agent values is optional if you’re submitting a Request Signature bot. </p><p>Once your application has gone through our (now shortened) review process, you don’t need to take any further action.</p>
    <div>
      <h2>Message Signature verification for origins</h2>
      <a href="#message-signature-verification-for-origins">
        
      </a>
    </div>
    <p>Starting today, Cloudflare is ramping up verification of <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>cryptographic signatures provided by automated crawlers and bots</u></a>. This is currently available for all Free and Pro plans, and as we continue to test and validate at scale, will be released to all Business and Enterprise plans. This means that as time passes, the number of unauthenticated web crawlers should diminish, ensuring most bot traffic is authenticated before it reaches your website’s servers, helping to prevent spoofing attacks. </p><p>At a high level, signature verification works like this: </p><ol><li><p>A bot or agent sends a request to a website behind Cloudflare.</p></li><li><p>Cloudflare’s Message Signature verification service checks for the <code>Signature</code>, <code>Signature-Input</code>, and <code>Signature-Agent</code> headers.</p></li><li><p>It checks that the incoming request presents a <code>keyid</code> parameter in your Signature-Input that points to a key we already know.</p></li><li><p>It looks at the <code>expires</code> parameter in the incoming bot request. If the current time is after expiration, verification fails. This guards against replay attacks, preventing malicious agents from trying to pass as a bot by retrying messages they captured in the past.</p></li><li><p>It checks that you’ve specified a <code>tag</code> parameter indicating <code>web-bot-auth</code>, to indicate your intent that the message be handled using web bot authentication specifically</p></li><li><p>It looks at all the <a href="https://www.rfc-editor.org/rfc/rfc9421#covered-components"><u>components</u></a> chosen in your <code>Signature-Input</code> header, and constructs <a href="https://www.rfc-editor.org/rfc/rfc9421#name-creating-the-signature-base"><u>a signature base</u></a> from it. </p></li><li><p>If all pre-flight checks pass, Cloudflare attempts to verify the signature base against the value in Signature field using an <a href="https://www.rfc-editor.org/rfc/rfc9421#name-eddsa-using-curve-edwards25"><u>ed25519 verification algorithm</u></a> and the key supplied in <code>keyid</code>.</p></li><li><p>Verified Bots and other systems at Cloudflare use a successful verification as proof of your identity, and apply rules corresponding to that identity. </p></li></ol><p>If any of the above steps fail, Cloudflare falls back to existing bot identification and mitigation mechanisms. As the system matures, we would strengthen these requirements, and limit the possibilities of a soft downgrade.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/128Ox15wBqBPVKUUzvn4gA/acca9b9e6df243b8317b8964285ce57c/2.png" />
          </figure><p>As a site owner, you can segment your Verified Bot traffic by its type and purpose by adding the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/categories/"><u>Verified Bot Categories</u></a> field <code>cf.verified_bot_category</code> as a filter criterion in <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF Custom rules</u></a>, <a href="https://developers.cloudflare.com/waf/rate-limiting-rules/"><u>Advanced Rate Limiting</u></a>, and Late <a href="https://developers.cloudflare.com/rules/transform/"><u>Transform rules</u></a>. For instance, to allow the Bibliothèque nationale de France and the Library of Congress, and institutions dedicated to academic research, you can add a rule that allows bots in the <code>Academic Research</code> category.</p>
    <div>
      <h2>Where we’re going next</h2>
      <a href="#where-were-going-next">
        
      </a>
    </div>
    <p>HTTP Message Signatures is a primitive that is useful beyond Cloudflare – the IETF standardized it as part of <a href="https://datatracker.ietf.org/doc/html/rfc9421"><u>RFC 9421</u></a>.</p><p>As discussed in our <a href="https://blog.cloudflare.com/web-bot-auth/#introducing-http-message-signatures"><u>previous blog post</u></a>, Cloudflare believes that making Message Signatures a core component of bot authentication on the web should follow the same path. The <a href="https://www.ietf.org/archive/id/draft-meunier-web-bot-auth-architecture-02.html"><u>specifications</u></a> for the protocol are being built in the open, and they have already evolved following feedback.</p><p>Moreover, due to widespread interest, the IETF is considering forming a working group around <a href="https://datatracker.ietf.org/wg/webbotauth/about/"><u>Web Bot Auth</u></a>. Should you be a crawler, an origin, or even a CDN, we invite you to provide feedback to ensure the solution gets stronger, and suits your needs.</p>
    <div>
      <h2>A better, more trusted Internet</h2>
      <a href="#a-better-more-trusted-internet">
        
      </a>
    </div>
    <p>For bot, agent, and crawler operators that act transparently and provide vital services for the Internet, we’re providing a faster and more automated path to being recognized as a Verified Bot, reducing manual processes. We trust that this approach improves bot authentication from what were formerly brittle and unreliable authentication methods, to a secure and reliable alternative. It should reduce the overall volume of friction and hurdles genuinely useful bots face.</p><p>For site owners, Message Signatures provides better assurance that the bot traffic is legitimate — automatically recognized and allowed, minimizing disruption to essential services (e.g., search engine indexing, monitoring). In line with our commitments to making TLS/<a href="https://blog.cloudflare.com/introducing-universal-ssl/"><u>SSL</u></a> and <a href="https://blog.cloudflare.com/pt-br/post-quantum-zero-trust/"><u>Post-Quantum</u></a> certificates available for everyone, we’ll always offer the cryptographic verification of Message Signatures for all sites because we believe in a safer and more efficient Internet by fostering a trusted environment for both human and automated traffic.</p><p>If you have a feature request, feedback, or are interested in partnering with us, please <a href="https://www.cloudflare.com/lp/verified-bots/"><u>reach out</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Pay Per Crawl]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">5K5btgE8vXWGaGxCrs5yFH</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Akshat Mahajan</dc:creator>
            <dc:creator>Gauri Baraskar</dc:creator>
            <dc:creator>Helen Du</dc:creator>
        </item>
        <item>
            <title><![CDATA[Forget IPs: using cryptography to verify bot and agent traffic]]></title>
            <link>https://blog.cloudflare.com/web-bot-auth/</link>
            <pubDate>Thu, 15 May 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Bots now browse like humans. We're proposing bots use cryptographic signatures so that website owners can verify their identity. Explanations and demonstration code can be found within the post. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>With the rise of traffic from <a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/">AI agents</a>, what’s considered a bot is no longer clear-cut. There are some clearly malicious bots, like ones that DoS your site or do <a href="https://www.cloudflare.com/learning/bots/what-is-credential-stuffing/">credential stuffing</a>, and ones that most site owners do want to interact with their site, like the bot that indexes your site for a search engine, or ones that fetch RSS feeds.      </p><p>Historically, Cloudflare has relied on two main signals to verify legitimate web crawlers from other types of automated traffic: user agent headers and IP addresses. The <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent"><code><u>User-Agent</u></code><u> header</u></a> allows bot developers to identify themselves, i.e. <code>MyBotCrawler/1.1</code>. However, user agent headers alone are easily spoofed and are therefore insufficient for reliable identification. To address this, user agent checks are often supplemented with <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/policy/#ip-validation"><u>IP address validation</u></a>, the inspection of published IP address ranges to confirm a crawler's authenticity. However, the logic around IP address ranges representing a product or group of users is brittle – connections from the crawling service might be shared by multiple users, such as in the case of <a href="https://blog.cloudflare.com/icloud-private-relay/"><u>privacy proxies</u></a> and VPNs, and these ranges, often maintained by cloud providers, change over time.</p><p>Cloudflare will always try to block malicious bots, but we think our role here is to also provide an affirmative mechanism to authenticate desirable bot traffic. By using well-established cryptography techniques, we’re proposing a better mechanism for legitimate agents and bots to declare who they are, and provide a clearer signal for site owners to decide what traffic to permit. </p><p><b>Today, we’re introducing two proposals – HTTP message signatures and request mTLS – for </b><a href="https://blog.cloudflare.com/friendly-bots/"><b><u>friendly bots</u></b></a><b> to authenticate themselves, and for customer origins to identify them. </b>In this blog post, we’ll share how these authentication mechanisms work, how we implemented them, and how you can participate in our closed beta.</p>
    <div>
      <h2>Existing bot verification mechanisms are broken </h2>
      <a href="#existing-bot-verification-mechanisms-are-broken">
        
      </a>
    </div>
    <p>Historically, if you’ve worked on ChatGPT, Claude, Gemini, or any other agent, you’ve had several options to identify your HTTP traffic to other services: </p><ol><li><p>You define a <a href="https://www.rfc-editor.org/rfc/rfc9110#name-user-agent"><u>user agent</u></a>, an HTTP header described in <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-user-agent"><u>RFC 9110</u></a>. The problem here is that this header is easily spoofable and there’s not a clear way for agents to identify themselves as semi-automated browsers — agents often use the Chrome user agent for this very reason, which is discouraged. The RFC <a href="https://www.rfc-editor.org/rfc/rfc9110.html#section-10.1.5-9"><u>states</u></a>: 
<i>“If a user agent masquerades as a different user agent, recipients can assume that the user intentionally desires to see responses tailored for that identified user agent, even if they might not work as well for the actual user agent being used.” </i> </p></li><li><p>You publish your IP address range(s). This has limitations because the same IP address might be shared by multiple users or multiple services within the same company, or even by multiple companies when hosting infrastructure is shared (like <a href="https://www.cloudflare.com/developer-platform/products/workers/">Cloudflare Workers</a>, for example). In addition, IP addresses are prone to change as underlying infrastructure changes, leading services to use ad-hoc sharing mechanisms like <a href="https://www.cloudflare.com/ips-v4"><u>CIDR lists</u></a>. </p></li><li><p>You go to every website and share a secret, like a <a href="https://www.rfc-editor.org/rfc/rfc6750"><u>Bearer</u></a> token. This is impractical at scale because it requires developers to maintain separate tokens for each website their bot will visit.</p></li></ol><p>We can do better! Instead of these arduous methods, we’re proposing that developers of bots and agents cryptographically sign requests originating from their service. When protecting origins, <a href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/">reverse proxies</a> such as Cloudflare can then validate those signatures to confidently identify the request source on behalf of site owners, allowing them to take action as they see fit. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3yB6h6XcSWNQO5McRWIpL8/edf32f7938b01a4c8f5eedefee2b9328/image2.png" />
          </figure><p>A typical system has three actors:</p><ul><li><p>User: the entity that wants to perform some actions on the web. This may be a human, an automated program, or anything taking action to retrieve information from the web.</p></li><li><p>Agent: an orchestrated browser or software program. For example, Chrome on your computer, or OpenAI’s <a href="https://operator.chatgpt.com/"><u>Operator</u></a> with ChatGPT. Agents can interact with the web according to web standards (HTML rendering, JavaScript, subrequests, etc.).</p></li><li><p>Origin: the website hosting a resource. The user wants to access it through the browser. This is Cloudflare when your website is using our services, and it’s your own server(s) when exposed directly to the Internet.</p></li></ul><p>In the next section, we’ll dive into HTTP Message Signatures and request mTLS, two mechanisms a browser agent may implement to sign outgoing requests, with different levels of ease for an origin to adopt. </p>
    <div>
      <h2>Introducing HTTP Message Signatures</h2>
      <a href="#introducing-http-message-signatures">
        
      </a>
    </div>
    <p><a href="https://www.rfc-editor.org/rfc/rfc9421.html"><u>HTTP Message Signatures</u></a> is a standard that defines the cryptographic authentication of a request sender. It’s essentially a cryptographically sound way to say, “hey, it’s me!”. It’s not the only way that developers can sign requests from their infrastructure — for example, AWS has used <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html"><u>Signature v4</u></a>, and Stripe has a framework for <a href="https://docs.stripe.com/webhooks#verify-webhook-signatures-with-official-libraries"><u>authenticating webhooks</u></a> — but Message Signatures is a published standard, and the cleanest, most developer-friendly way to sign requests.  </p><p>We’re working closely with the wider industry to support these standards-based approaches. For example, OpenAI has started to sign their requests. In their own words:   </p><blockquote><p><i>"Ensuring the authenticity of Operator traffic is paramount. With HTTP Message Signatures (</i><a href="https://www.rfc-editor.org/rfc/rfc9421.html"><i><u>RFC 9421</u></i></a><i>), OpenAI signs all Operator requests so site owners can verify they genuinely originate from Operator and haven’t been tampered with” </i>– Eugenio, Engineer, OpenAI</p></blockquote><p>Without further delay, let’s dive in how HTTP Messages Signatures work to identify bot traffic.</p>
    <div>
      <h3>Scoping standards to bot authentication</h3>
      <a href="#scoping-standards-to-bot-authentication">
        
      </a>
    </div>
    <p>Generating a message signature works like this: before sending a request, the agent signs the target origin with a public key. When fetching <code>https://example.com/path/to/resource</code>, it signs <code>example.com</code>. This public key is known to the origin, either because the agent is well known, because it has previously registered, or any other method. Then, the agent writes a <b>Signature-Input</b> header with the following parameters:</p><ol><li><p>A validity window (<code>created</code> and <code>expires</code> timestamps)</p></li><li><p>A Key ID that uniquely identifies the key used in the signature. This is a <a href="https://www.rfc-editor.org/rfc/rfc7638.html"><u>JSON Web Key Thumbprint</u></a>.  </p></li><li><p>A tag that shows websites the signature’s purpose and validation method, i.e. <code>web-bot-auth</code> for bot authentication.</p></li></ol><p>In addition, the <code>Signature-Agent</code> header indicates where the origin can find the public keys the agent used when signing the request, such as in a directory hosted by <code>signer.example.com</code>. This header is part of the signed content as well.</p><p>Here’s an example:</p>
            <pre><code>GET /path/to/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 Chrome/113.0.0 MyBotCrawler/1.1
Signature-Agent: signer.example.com
Signature-Input: sig=("@authority" "signature-agent");\
             	 created=1700000000;\
             	 expires=1700011111;\
             	 keyid="ba3e64==";\
             	 tag="web-bot-auth"
Signature: sig=abc==</code></pre>
            <p>For those building bots, <a href="https://datatracker.ietf.org/doc/draft-meunier-web-bot-auth-architecture/"><u>we propose</u></a> signing the authority of the target URI, i.e. www.example.com, and a way to retrieve the bot public key in the form of <a href="https://datatracker.ietf.org/doc/draft-meunier-http-message-signatures-directory/"><u>signature-agent</u></a>, if present, i.e. <a href="http://crawler.search.google.com"><u>crawler.search.google.com</u></a> for Google Search, <a href="http://operator.openai.com"><u>operator.openai.com</u></a> for OpenAI Operator, workers.dev for Cloudflare Workers.</p><p>The <code>User-Agent</code> from the example above indicates that the software making the request is Chrome, because it is an agent that uses an orchestrated Chrome to browse the web. You should note that <code>MyBotCrawler/1.1</code> is still present. The <code>User-Agent</code> header can actually contain multiple products, in decreasing order of importance. If our agent is making requests via Chrome, that’s the most important product and therefore comes first.</p><p>At Internet-level scale, these signatures may add a notable amount of overhead to request processing. However, with the right cryptographic suite, and compared to the cost of existing bot mitigation, both technical and social, this seems to be a straightforward tradeoff. This is a metric we will monitor closely, and report on as adoption grows.</p>
    <div>
      <h3>Generating request signatures</h3>
      <a href="#generating-request-signatures">
        
      </a>
    </div>
    <p>We’re making several examples for generating Message Signatures for bots and agents <a href="https://github.com/cloudflareresearch/web-bot-auth/"><u>available on Github</u></a> (though we encourage other implementations!), all of which are standards-compliant, to maximize interoperability. </p><p>Imagine you’re building an agent using a managed Chromium browser, and want to sign all outgoing requests. To achieve this, the <a href="https://github.com/w3c/webextensions"><u>webextensions standard</u></a> provides <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeSendHeaders"><u>chrome.webRequest.onBeforeSendHeaders</u></a>, where you can modify HTTP headers before they are sent by the browser. The event is <a href="https://developer.chrome.com/docs/extensions/reference/api/webRequest#life_cycle_of_requests"><u>triggered</u></a> before sending any HTTP data, and when headers are available.</p><p>Here’s what that code would look like: </p>
            <pre><code>chrome.webRequest.onBeforeSendHeaders.addListener(
  function (details) {
	// Signature and header assignment logic goes here
      // &lt;CODE&gt;
  },
  { urls: ["&lt;all_urls&gt;"] },
  ["blocking", "requestHeaders"] // requires "installation_mode": "force_installed"
);</code></pre>
            <p>Cloudflare provides a <a href="https://www.npmjs.com/package/web-bot-auth"><u>web-bot-auth</u></a> helper package on npm that helps you generate request signatures with the correct parameters. <code>onBeforeSendHeaders</code> is a Chrome extension hook that needs to be implemented synchronously. To do so, we <code>import {signatureHeadersSync} from “web-bot-auth”</code>. Once the signature completes, both <code>Signature</code> and <code>Signature-Input</code> headers are assigned. The request flow can then continue.</p>
            <pre><code>const request = new URL(details.url);
const created = new Date();
const expired = new Date(created.getTime() + 300_000)


// Perform request signature
const headers = signatureHeadersSync(
  request,
  new Ed25519Signer(jwk),
  { created, expires }
);
// `headers` object now contains `Signature` and `Signature-Input` headers that can be used</code></pre>
            <p>This extension code is available on <a href="https://github.com/cloudflareresearch/web-bot-auth/"><u>GitHub</u></a>, alongside a  debugging server, deployed at <a href="https://http-message-signatures-example.research.cloudflare.com"><u>https://http-message-signatures-example.research.cloudflare.com</u></a>. </p>
    <div>
      <h3>Validating request signatures </h3>
      <a href="#validating-request-signatures">
        
      </a>
    </div>
    <p>Using our <a href="https://http-message-signatures-example.research.cloudflare.com"><u>debug server</u></a>, we can now inspect and validate our request signatures from the perspective of the website we’d be visiting. We should now see the Signature and Signature-Input headers:  </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/18P5OyGxu2fU0Dpyv70Gjz/d82d62355524ad1914deb41b601bcad2/image3.png" />
          </figure><p><sup><i>In this example, the homepage of the debugging server validates the signature from the RFC 9421 Ed25519 verifying key, which the extension uses for signing.</i></sup></p><p>The above demo and code walkthrough has been fully written in TypeScript: the verification website is on Cloudflare Workers, and the client is a Chrome browser extension. We are cognisant that this does not suit all clients and servers on the web. To demonstrate the proposal works in more environments, we have also implemented bot signature validation in Go with a <a href="https://github.com/cloudflareresearch/web-bot-auth/tree/main/examples/caddy-plugin"><u>plugin</u></a> for <a href="https://caddyserver.com/"><u>Caddy server</u></a>.</p>
    <div>
      <h2>Experimentation with request mTLS</h2>
      <a href="#experimentation-with-request-mtls">
        
      </a>
    </div>
    <p>HTTP is not the only way to convey signatures. For instance, one mechanism that has been used in the past to authenticate automated traffic against secured endpoints is <a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/"><u>mTLS</u></a>, the “mutual” presentation of <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificates</a>. As described in our <a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/"><u>knowledge base</u></a>:</p><blockquote><p><i>Mutual TLS, or mTLS for short, is a method for</i><a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-authentication/"><i> </i><i><u>mutual authentication</u></i></a><i>. mTLS ensures that the parties at each end of a network connection are who they claim to be by verifying that they both have the correct private</i><a href="https://www.cloudflare.com/learning/ssl/what-is-a-cryptographic-key/"><i> </i><i><u>key</u></i></a><i>. The information within their respective</i><a href="https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/"><i> </i><i><u>TLS certificates</u></i></a><i> provides additional verification.</i></p></blockquote><p>While mTLS seems like a good fit for bot authentication on the web, it has limitations. If a user is asked for authentication via the mTLS protocol but does not have a certificate to provide, they would get an inscrutable and unskippable error. Origin sites need a way to conditionally signal to clients that they accept or require mTLS authentication, so that only mTLS-enabled clients use it.</p>
    <div>
      <h3>A TLS flag for bot authentication</h3>
      <a href="#a-tls-flag-for-bot-authentication">
        
      </a>
    </div>
    <p>TLS flags are an efficient way to describe whether a feature, like mTLS, is supported by origin sites. Within the IETF, we have proposed a new TLS flag called <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><code><u>req mTLS</u></code></a> to be sent by the client during the establishment of a connection that signals support for authentication via a client certificate. </p><p>This proposal leverages the <a href="https://www.ietf.org/archive/id/draft-ietf-tls-tlsflags-14.html"><u>tls-flags</u></a> proposal under discussion in the IETF. The TLS Flags draft allows clients and servers to send an array of one bit flags to each other, rather than creating a new extension (with its associated overhead) for each piece of information they want to share. This is one of the first uses of this extension, and we hope that by using it here we can help drive adoption.</p><p>When a client sends the <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><code><u>req mTLS</u></code></a> flag to the server, they signal to the server that they are able to respond with a certificate if requested. The server can then safely request a certificate without risk of blocking ordinary user traffic, because ordinary users will never set this flag. </p><p>Let’s take a look at what an example of such a req mTLS would look like in <a href="https://www.wireshark.org/"><u>Wireshark</u></a>, a network protocol analyser. You can follow along in the packet capture <a href="https://github.com/cloudflareresearch/req-mtls/tree/main/assets/demonstration-capture.pcapng"><u>here</u></a>.</p>
            <pre><code>Extension: req mTLS (len=12)
	Type: req mTLS (65025)
	Length: 12
	Data: 0b0000000000000000000001</code></pre>
            <p>The extension number is 65025, or 0xfe01. This corresponds to an unassigned block of <a href="https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-1"><u>TLS extensions</u></a> that can be used to experiment with TLS Flags. Once the standard is adopted and published by the IETF, the number would be fixed. To use the <code>req mTLS</code> flag the client needs to set the 80<sup>th</sup> bit to true, so with our block length of 12 bytes, it should  contain the data 0b0000000000000000000001, which is the case here. The server then responds with a certificate request, and the request follows its course.</p>
    <div>
      <h3>Request mTLS in action</h3>
      <a href="#request-mtls-in-action">
        
      </a>
    </div>
    <p><i>Code for this section is available in GitHub under </i><a href="https://github.com/cloudflareresearch/req-mtls"><i><u>cloudflareresearch/req-mtls</u></i></a></p><p>Because mutual TLS is widely supported in TLS libraries already, the parts we need to introduce to the client and server are:</p><ol><li><p>Sending/parsing of TLS-flags</p></li><li><p>Specific support for the <code>req mTLS</code> flag</p></li></ol><p>To the best of our knowledge, there is no complete public implementation of either scheme. Using it for bot authentication may provide a motivation to do so.</p><p>Using <a href="https://github.com/cloudflare/go"><u>our experimental fork of Go</u></a>, a TLS client could support req mTLS as follows:</p>
            <pre><code>config := &amp;tls.Config{
    	TLSFlagsSupported:  []tls.TLSFlag{0x50},
    	RootCAs:       	rootPool,
    	Certificates:  	certs,
    	NextProtos:    	[]string{"h2"},
}
trans := http.Transport{TLSClientConfig: config, ForceAttemptHTTP2: true}</code></pre>
            <p>This example library allows you to configure Go to send <code>req mTLS 0x50</code> bytes in the <code>TLS Flags</code> extension. If you’d like to test your implementation out, you can prompt your client for certificates against <a href="http://req-mtls.research.cloudflare.com"><u>req-mtls.research.cloudflare.com</u></a> using the Cloudflare Research client <a href="https://github.com/cloudflareresearch/req-mtls"><u>cloudflareresearch/req-mtls</u></a>. For clients, once they set the TLS Flags associated with <code>req mTLS</code>, they are done. The code section taking care of normal mTLS will take over at that point, with no need to implement something new.</p>
    <div>
      <h2>Two approaches, one goal</h2>
      <a href="#two-approaches-one-goal">
        
      </a>
    </div>
    <p>We believe that developers of agents and bots should have a public, standard way to authenticate themselves to CDNs and website hosting platforms, regardless of the technology they use or provider they choose. At a high level, both HTTP Message Signatures and request mTLS achieve a similar goal: they allow the owner of a service to authentically identify themselves to a website. That’s why we’re participating in the standardizing effort for both of these protocols at the IETF, where many other authentication mechanisms we’ve discussed here — from TLS to OAuth Bearer tokens –— been developed by diverse sets of stakeholders and standardized as RFCs.   </p><p>Evaluating both proposals against each other, we’re prioritizing <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>HTTP Message Signatures for Bots</u></a> because it relies on the previously adopted <a href="https://datatracker.ietf.org/doc/html/rfc9421"><u>RFC 9421</u></a> with several <a href="https://httpsig.org/"><u>reference implementations</u></a>, and works at the HTTP layer, making adoption simpler. <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><u>request mTLS</u></a> may be a better fit for site owners with concerns about the additional bandwidth, but <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-tlsflags"><u>TLS Flags</u></a> has fewer implementations, is still waiting for IETF adoption, and upgrading the TLS stack has proven to be more challenging than with HTTP. Both approaches share similar discovery and key management concerns, as highlighted in a <a href="https://datatracker.ietf.org/doc/draft-meunier-web-bot-auth-glossary/"><u>glossary</u></a> draft at the IETF. We’re actively exploring both options, and would love to <a href="https://www.cloudflare.com/lp/verified-bots/"><u>hear</u></a> from both site owners and bot developers about how you’re evaluating their respective tradeoffs.</p>
    <div>
      <h2>The bigger picture </h2>
      <a href="#the-bigger-picture">
        
      </a>
    </div>
    <p>In conclusion, we think request signatures and mTLS are promising mechanisms for bot owners and developers of AI agents to authenticate themselves in a tamper-proof manner, forging a path forward that doesn’t rely on ever-changing IP address ranges or spoofable headers such as <code>User-Agent</code>. This authentication can be consumed by Cloudflare when acting as a reverse proxy, or directly by site owners on their own infrastructure. This means that as a bot owner, you can now go to content creators and discuss crawling agreements, with as much granularity as the number of bots you have. You can start implementing these solutions today and test them against the research websites we’ve provided in this post.</p><p>Bot authentication also empowers site owners small and large to have more control over the traffic they allow, empowering them to continue to serve content on the public Internet while monitoring automated requests. Longer term, we will integrate these authentication mechanisms into our <a href="https://blog.cloudflare.com/cloudflare-ai-audit-control-ai-content-crawlers/"><u>AI Audit</u></a> and <a href="https://developers.cloudflare.com/bots/get-started/bot-management/"><u>Bot Management</u></a> products, to provide better visibility into the bots and agents that are willing to identify themselves.</p><p>Being able to solve problems for both origins and clients is key to helping build a better Internet, and we think identification of automated traffic is a step towards that. If you want us to start verifying your message signatures or client certificates, have a compelling use case you’d like us to consider, or any questions, please <a href="https://www.cloudflare.com/lp/verified-bots/"><u>reach out</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">2hUP3FdePgIYVDwhgJVLeV</guid>
            <dc:creator>Thibault Meunier</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Open-sourcing OpenPubkey SSH (OPKSSH): integrating single sign-on with SSH]]></title>
            <link>https://blog.cloudflare.com/open-sourcing-openpubkey-ssh-opkssh-integrating-single-sign-on-with-ssh/</link>
            <pubDate>Tue, 25 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ OPKSSH (OpenPubkey SSH) is now open-sourced as part of the OpenPubkey project. ]]></description>
            <content:encoded><![CDATA[ <p>OPKSSH makes it easy to <a href="https://en.wikipedia.org/wiki/Secure_Shell"><u>SSH</u></a> with single sign-on technologies like OpenID Connect, thereby removing the need to manually manage and configure SSH keys. It does this without adding a trusted party other than your identity provider (IdP).</p><p>We are excited to announce <a href="https://github.com/openpubkey/opkssh/"><u>OPKSSH (OpenPubkey SSH)</u></a> has been open-sourced under the umbrella of the OpenPubkey project. While the underlying protocol <a href="https://github.com/openpubkey/openpubkey/"><u>OpenPubkey</u></a> became <a href="https://www.linuxfoundation.org/press/announcing-openpubkey-project"><u>an open source Linux foundation project in 2023</u></a>, OPKSSH was closed source and owned by <a href="https://www.cloudflare.com/press-releases/2024/cloudflare-acquires-bastionzero-to-add-zero-trust-infrastructure-access/"><u>BastionZero (now Cloudflare)</u></a>. Cloudflare has gifted this code to the OpenPubkey project, making it open source.</p><p>In this post, we describe what OPKSSH is, how it simplifies SSH management, and what OPKSSH being open source means for you.</p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>A cornerstone of modern access control is single sign-on <a href="https://www.cloudflare.com/learning/access-management/what-is-sso/"><u>(SSO)</u></a>, where a user authenticates to an <a href="https://www.cloudflare.com/learning/access-management/what-is-an-identity-provider/"><u>identity provider (IdP)</u></a>, and in response the IdP issues the user a <i>token</i>. The user can present this token to prove their identity, such as “Google says I am Alice”. SSO is the rare security technology that both increases convenience — users only need to sign in once to get access to many different systems — and increases security.</p>
    <div>
      <h3>OpenID Connect</h3>
      <a href="#openid-connect">
        
      </a>
    </div>
    <p><a href="https://openid.net/developers/how-connect-works/"><u>OpenID Connect (OIDC)</u></a> is the main protocol used for SSO. As shown below, in OIDC the IdP, called an OpenID Provider (OP), issues the user an ID Token which contains identity claims about the user, such as “email is alice@example.com”. These claims are digitally signed by the OP, so anyone who receives the ID Token can check that it really was issued by the OP.</p><p>Unfortunately, while ID Tokens <i>do </i>include identity claims like name, organization, and email address, they <i>do not</i> include the user’s public key. This prevents them from being used to directly secure protocols like SSH or <a href="https://www.cloudflare.com/learning/privacy/what-is-end-to-end-encryption/"><u>End-to-End Encrypted messaging</u></a>.</p><p>Note that throughout this post we use the term OpenID Provider (OP) rather than IdP, as OP specifies the exact type of IdP we are using, i.e., an OpenID IdP. We use Google as an example OP, but OpenID Connect works with Google, Azure, Okta, etc.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2zfixdknoL3a9HqBzcsmAY/605f469bdd25b4b8cfaf29dac3561c4f/image1.png" />
          </figure><p><sup><i>Shows a user Alice signing in to Google using OpenID Connect and receiving an ID Token</i></sup></p>
    <div>
      <h3>OpenPubkey</h3>
      <a href="#openpubkey">
        
      </a>
    </div>
    <p>OpenPubkey, shown below, adds public keys to ID Tokens. This enables ID Tokens to be used like certificates, e.g. “Google says <code>alice@example.com</code> is using public key 0x123.” We call an ID token that contains a public key a <i>PK Token</i>. The beauty of OpenPubkey is that, unlike other approaches, OpenPubkey does not require any changes to existing SSO protocols and supports any OpenID Connect compliant OP.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2HNkaW8vPE26KQrNwNOzNo/ef00f91dc983f3f2ac3c3a00b223b3e5/image3.png" />
          </figure><p><sup><i>Shows a user Alice signing in to Google using OpenID Connect/OpenPubkey and then producing a PK Token</i></sup>
While OpenPubkey enables ID Tokens to be used as certificates, OPKSSH extends this functionality so that these ID Tokens can be used as SSH keys in the SSH protocol. This adds SSO authentication to SSH without requiring changes to the SSH protocol.</p>
    <div>
      <h2>Why this matters</h2>
      <a href="#why-this-matters">
        
      </a>
    </div>
    <p>OPKSSH frees users and administrators from the need to manage long-lived SSH keys, making SSH more secure and more convenient.</p><blockquote><p><i>“In many organizations – even very security-conscious organizations – there are many times more obsolete authorized keys than they have employees. Worse, authorized keys generally grant command-line shell access, which in itself is often considered privileged. We have found that in many organizations about 10% of the authorized keys grant root or administrator access. SSH keys never expire.”</i>  
- <a href="https://ylonen.org/papers/ssh-key-challenges.pdf">Challenges in Managing SSH Keys – and a Call for Solutions</a> by Tatu Ylonen (Inventor of SSH)</p></blockquote><p>In SSH, users generate a long-lived SSH public key and SSH private key. To enable a user to access a server, the user or the administrator of that server configures that server to trust that user’s public key. Users must protect the file containing their SSH private key. If the user loses this file, they are locked out. If they copy their SSH private key to multiple computers or back up the key, they increase the risk that the key will be compromised. When a private key is compromised or a user no longer needs access, the user or administrator must remove that public key from any servers it currently trusts. All of these problems create headaches for users and administrators.</p><p>OPKSSH overcomes these issues:</p><p><b>Improved security:</b> OPKSSH replaces long-lived SSH keys with ephemeral SSH keys that are created on-demand by OPKSSH and expire when they are no longer needed. This reduces the risk a private key is compromised, and limits the time period where an attacker can use a compromised private key. By default, these OPKSSH public keys expire every 24 hours, but the expiration policy can be set in a configuration file.</p><p><b>Improved usability:</b> Creating an SSH key is as easy as signing in to an OP. This means that a user can SSH from any computer with opkssh installed, even if they haven’t copied their SSH private key to that computer.</p><p>To generate their SSH key, the user simply runs opkssh login, and they can use ssh as they typically do.</p><p><b>Improved visibility:</b> OPKSSH moves SSH from authorization by public key to authorization by identity. If Alice wants to give Bob access to a server, she doesn’t need to ask for his public key, she can just add Bob’s email address bob@example.com to the OPKSSH authorized users file, and he can sign in. This makes tracking who has access much easier, since administrators can see the email addresses of the authorized users.</p><p>OPKSSH does not require any code changes to the SSH server or client. The only change needed to SSH on the SSH server is to add two lines to the SSH config file. For convenience, we provide an installation script that does this automatically, as seen in the video below.</p><div>
  
</div>
<p></p>
    <div>
      <h2>How it works</h2>
      <a href="#how-it-works">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5rVAtbu3vv9wU84ke8IZIb/a5e564c2ae3834391bd7f04c843508b7/image4.png" />
          </figure><p><sup><i>Shows a user Alice SSHing into a server with her PK Token inside her SSH public key. The server then verifies her SSH public key using the OpenPubkey verifier.</i></sup></p><p>Let’s look at an example of Alice (<code>alice@example.com</code>) using OPKSSH to SSH into a server:</p><ul><li><p>Alice runs <code>opkssh login</code>. This command automatically generates an ephemeral public key and private key for Alice. Then it runs the OpenPubkey protocol by opening a browser window and having Alice log in through their SSO provider, e.g., Google. </p></li><li><p>If Alice SSOs successfully, OPKSSH will now have a PK Token that commits to Alice’s ephemeral public key and Alice’s identity. Essentially, this PK Token says “<code>alice@example.com</code> authenticated her identity and her public key is 0x123…”.</p></li><li><p>OPKSSH then saves to Alice’s <code>.ssh </code>directory:</p><ul><li><p>an SSH public key file that contains Alice’s PK Token </p></li><li><p>and an SSH private key set to Alice’s ephemeral private key.</p></li></ul></li><li><p>When Alice attempts to SSH into a server, the SSH client will find the SSH public key file containing the PK Token in Alice’s <code>.ssh</code> directory, and it will send it to the SSH server to authenticate.</p></li><li><p>The SSH server forwards the received SSH public key to the OpenPubkey verifier installed on the SSH server. This is because the SSH server has been configured to use the OpenPubkey verifier via the AuthorizedKeysCommand.</p></li><li><p>The OpenPubkey verifier receives the SSH public key file and extracts the PK Token from it. It then verifies that the PK Token is unexpired, valid, signed by the OP and that the public key in the PK Token matches the public key field in the SSH public key file. Finally, it extracts the email address from the PK Token and checks if <code>alice@example.com</code> is allowed to SSH into this server.</p></li></ul><p>Consider the problems we face in getting OpenPubkey to work with SSH without requiring any changes to the SSH protocol or software:</p><p><b>How do we get the PK Token from the user’s machine to the SSH server inside the SSH protocol?</b>
We use the fact that SSH public keys can be SSH certificates, and that SSH certificates have <a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.4&amp;content-type=text/x-cvsweb-markup"><u>an extension field</u></a> that allows arbitrary data to be included in the certificate. Thus, we package the PK Token into an SSH certificate extension so that the PK Token will be transmitted inside the SSH public key as a normal part of the SSH protocol. This enables us to send the PK Token to the SSH server as additional data in the SSH certificate, and allows OPKSSH to work without any changes to the SSH client.</p><p><b>How do we check that the PK Token is valid once it arrives at the SSH server?
</b>SSH servers support a configuration parameter called the <a href="https://man.openbsd.org/sshd_config#AuthorizedKeysCommand"><i><u>AuthorizedKeysCommand</u></i></a><i> </i>that allows us to use a custom program to determine if an SSH public key is authorized or not. Thus, we change the SSH server’s config file to use the OpenPubkey verifier instead of the SSH verifier by making the following two line change to <code>sshd_config</code>:</p>
            <pre><code>AuthorizedKeysCommand /usr/local/bin/opkssh verify %u %k %t
AuthorizedKeysCommandUser root</code></pre>
            <p>The OpenPubkey verifier will check that the PK Token is unexpired, valid and signed by the OP. It checks the user’s email address in the PK Token to determine if the user is authorized to access the server.</p><p><b>How do we ensure that the public key in the PK Token is actually the public key that secures the SSH session?</b>
The OpenPubkey verifier also checks that the public key in the public key field in the SSH public key matches the user’s public key inside the PK Token. This works because the public key field in the SSH public key is the actual public key that secures the SSH session.</p>
    <div>
      <h2>What is happening</h2>
      <a href="#what-is-happening">
        
      </a>
    </div>
    <p>We have <a href="https://github.com/openpubkey/openpubkey/pull/234"><u>open sourced OPKSSH</u></a> under the <a href="https://www.apache.org/licenses/LICENSE-2.0"><u>Apache 2.0 license</u></a>, and released it as <a href="https://github.com/openpubkey/opkssh/"><u>openpubkey/opkssh on GitHub</u></a>. While the OpenPubkey project has had code for using SSH with OpenPubkey since the early days of the project, this code was intended as a prototype and was missing many important features. With OPKSSH, SSH support in OpenPubkey is no longer a prototype and is now a complete feature. Cloudflare is not endorsing OPKSSH, but simply donating code to OPKSSH.</p><p><b>OPKSSH provides the following improvements to OpenPubkey:</b></p><ul><li><p>Production ready SSH in OpenPubkey</p></li><li><p>Automated installation</p></li><li><p>Better configuration tools</p></li></ul>
    <div>
      <h2>To learn more</h2>
      <a href="#to-learn-more">
        
      </a>
    </div>
    <p>See the <a href="https://github.com/openpubkey/opkssh/blob/main/README.md"><u>OPKSSH readme</u></a> for documentation on how to install and connect using OPKSSH.</p>
    <div>
      <h2>How to get involved</h2>
      <a href="#how-to-get-involved">
        
      </a>
    </div>
    <p>There are a number of ways to get involved in OpenPubkey or OPKSSH. The project is organized through the <a href="https://github.com/openpubkey/opkssh"><u>OPKSSH GitHub</u></a>. We are building an open and friendly community and welcome pull requests from anyone. If you are interested in contributing, see <a href="https://github.com/openpubkey/openpubkey/blob/main/CONTRIBUTING.md"><u>our contribution guide</u></a>.</p><p>We run a <a href="https://github.com/openpubkey/community"><u>community</u></a> meeting every month which is open to everyone, and you can also find us over on the <a href="https://openssf.org/getinvolved/"><u>OpenSSF Slack</u></a> in the #openpubkey channel.</p> ]]></content:encoded>
            <category><![CDATA[Open Source]]></category>
            <category><![CDATA[SSH]]></category>
            <category><![CDATA[Single Sign On (SSO)]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Authentication]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">01zA7RtUKkhrUeINJ9AIS3</guid>
            <dc:creator>Ethan Heilman</dc:creator>
        </item>
        <item>
            <title><![CDATA[Prepping for post-quantum: a beginner’s guide to lattice cryptography]]></title>
            <link>https://blog.cloudflare.com/lattice-crypto-primer/</link>
            <pubDate>Fri, 21 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ This post is a beginner's guide to lattices, the math at the heart of the transition to post-quantum (PQ) cryptography. It explains how to do lattice-based encryption and authentication from scratch. ]]></description>
            <content:encoded><![CDATA[ <p>The cryptography that secures the Internet is evolving, and it's time to catch up. This post is a tutorial on lattice cryptography, the paradigm at the heart of the post-quantum (PQ) transition.</p><p>Twelve years ago (in 2013), the <a href="https://en.wikipedia.org/wiki/Edward_Snowden"><u>revelation of mass surveillance in the US</u></a> kicked off the widespread adoption of <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> for encryption and authentication on the web. This transition was buoyed by the standardization and implementation of new, more efficient public-key cryptography based on <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>elliptic curves</u></a>. Elliptic curve cryptography was both faster and required less communication than its predecessors, including <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)"><u>RSA</u></a> and <a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange"><u>Diffie-Hellman</u></a> over finite fields.</p><p>Today's transition to <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/"><u>PQ cryptography</u></a> addresses a looming threat for TLS and beyond: once built, a sufficiently large quantum computer can be used to break all <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/">public-key cryptography</a> in use today. And we continue to see <a href="https://blog.google/technology/research/google-willow-quantum-chip/"><u>advancements</u></a> in quantum-computer engineering that bring us closer to this threat becoming a reality.</p><p>Fortunately, this transition is well underway. The research and standards communities have spent the last several years developing alternatives that resist quantum cryptanalysis. For its part, Cloudflare has contributed to this process and is an early adopter of newly developed schemes. In fact, PQ encryption has been available at our edge <a href="https://blog.cloudflare.com/post-quantum-for-all/"><u>since 2022</u></a> and is <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>used in over 35% of non-automated HTTPS traffic today (2025)</u></a>. And this year we're beginning a major push towards PQ authentication for the TLS ecosystem.</p><p>Lattice-based cryptography is the first paradigm that will replace <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>elliptic curves</u></a>. Apart from being PQ secure, lattices are often as fast, and sometimes faster, in terms of CPU time. However, this new paradigm for public key crypto has one major cost: <b>lattices require much more communication than elliptic curves.</b> For example, establishing an encryption key using lattices requires 2272 bytes of communication between the client and the server (<a href="https://csrc.nist.gov/pubs/fips/203/final"><u>ML-KEM-768</u></a>), compared to just 64 bytes for a key exchange using a modern elliptic-curve-based scheme (<a href="https://datatracker.ietf.org/doc/html/rfc7748"><u>X25519</u></a>). Accommodating such costs requires a significant amount of engineering, from dealing with <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>TCP packet fragmentation</u></a>, to reworking <a href="https://blog.cloudflare.com/pq-2024/#two-migrations"><u>TLS and its public key infrastructure</u></a>. Thus, the PQ transition is going to require the participation of a large number of people with a variety of backgrounds, not just cryptographers.</p><p>The primary audience for this blog post is those who find themselves involved in the PQ transition and want to better understand what's going on under the hood. However, more fundamentally, we think it's important for everyone to understand lattice cryptography on some level, especially if we're going to trust it for our security and privacy.</p><p>We'll assume you have a software-engineering background and some familiarity with concepts like TLS, encryption, and authentication. We'll see that the math behind lattice cryptography is, at least at the highest level, not difficult to grasp. Readers with a crypto-engineering background who want to go deeper might want to start with the excellent <a href="https://eprint.iacr.org/2024/1287"><u>tutorial by Vadim Lyubashevsky</u></a> on which this blog post is based. We also recommend <a href="https://keymaterial.net/2023/09/01/learning-but-with-errors/"><u>Sophie Schmieg's blog</u></a> on this subject.</p><p>While the transition to lattice cryptography incurs costs, it also creates opportunities. Many things we can build with elliptic curves we can also build with lattices, though not always as efficiently; but there are also things we can do with lattices that we don't know how to do efficiently with anything else. We'll touch on some of these applications at the very end.</p><p>We're going to cover a lot of ground in this post. If you stick with it, we hope you'll come away feeling empowered, not only to tackle the engineering challenges the PQ transition entails, but to solve problems you didn't know how to solve before.</p><p>Strap in — let's have some fun!</p>
    <div>
      <h3>Encryption</h3>
      <a href="#encryption">
        
      </a>
    </div>
    <p>The most pressing problem for the PQ transition is to ensure that tomorrow's quantum computers don't break today's encryption. An attacker today can store the packets exchanged between your laptop and a website you visit, and then, some time in the future, decrypt those packets with the help of a quantum computer. This means that much of the sensitive information transiting the Internet today — everything from <a href="https://blog.cloudflare.com/https-only-for-cloudflare-apis-shutting-the-door-on-cleartext-traffic/"><u>API tokens</u></a> and passwords to database encryption keys — may one day be unlocked by a quantum computer.</p><p>In fact, today's encryption in TLS is <i>mostly</i> PQ secure: <b>what's at risk is the process by which your browser and a server establish an encryption key</b>. Today this is usually done with elliptic-curve-based schemes, which are not PQ secure; our goal for this section is to understand how to do key exchange with lattices-based schemes, which are.</p><p>We will work through and implement a simplified version of <a href="https://csrc.nist.gov/pubs/fips/203/final"><u>ML-KEM</u></a>, a.k.a. Kyber, the most widely deployed PQ key exchange in use today. Our code will be less efficient and secure than a <a href="https://pkg.go.dev/github.com/cloudflare/circl@v1.6.0/kem/mlkem"><u>spec-compliant, production-quality implementation</u></a>, but will be good enough to grasp the main ideas.</p><p>Our starting point is a protocol that looks an awful lot like <a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange"><u>Diffie-Hellman (DH)</u></a> key exchange. For those readers unacquainted with DH, the goal is for Alice and Bob to establish a shared secret over an insecure network. To do so, each picks a random secret number, computes the corresponding "key share", and sends the key share to the other:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5yWJO1Sem97PfhwqiKZRLm/bfacc44ca4f7187f4212b7b4616dd86d/image7.png" />
          </figure><p>Alice's secret number is $s$ and her key share is $g^s$; Bob's secret number is $r$ and his key share is $g^r$. Then given their secret and their peer's key share, each can compute $g^{rs}$. The security of this protocol comes from how we choose $g$, $s$, and $r$ and how we do arithmetic. The most efficient instantiation of DH uses elliptic curves.</p><p>In ML-KEM we replace operations on elliptic curves with <b>matrix </b>operations. It's not quite a drop-in replacement, so we'll need a little linear algebra to make sense of it. But don't worry: we're going to work with Python so we have running code to play with, and we'll use <a href="https://numpy.org/"><u>NumPy</u></a> to keep things high level.</p>
    <div>
      <h4>All the math we'll need</h4>
      <a href="#all-the-math-well-need">
        
      </a>
    </div>
    <p>A matrix is just a two-dimensional array of numbers. In NumPy, we can create a matrix as follows (importing <code>numpy</code> as <code>np</code>):</p>
            <pre><code>A = np.matrix([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])</code></pre>
            <p>This defines <code>A</code> to be the <code>3</code>-by-<code>3</code> matrix with entries <code>A[0,0]==1, A[0,1]==2, A[0,2]==3, A[1,0]==4</code>, and so on.</p><p>For the purposes of this post, the entries of our matrices will always be integers. Furthermore, whenever we add, subtract, or multiply two integers, we then <b>reduce</b> the result, just like we do with hours on a clock, so that we end up with a number in <code>range(Q)</code> for some positive number <code>Q</code>, called the modulus. The exact value doesn’t really matter now, but for ML-KEM it’s <code>Q=3329</code>, so let's go with that for now. (The modulus for a clock would be <code>Q=12</code>.)</p><p>In Python, we write multiplication of integers <code>a</code> and <code>b</code> modulo <code>Q</code> as<code> c = a*b % Q</code>. Here we compute <code>a*b</code>, divide the result by <code>Q</code>, then set <code>c</code> to the remainder. For example, <code>42*1337</code> <code>% Q</code> is equal to <code>2890</code> rather than <code>56154</code>. Modular addition and subtraction are done analogously. For the rest of this blog, we will sometimes omit "<code>% Q</code>" when it's clear in context that we mean modular arithmetic.</p><p>Next, we'll need three operations on matrices.</p><p>The first is <b>matrix transpose</b>, written <code>A.T </code>in NumPy. This operation flips the matrix along its diagonal so that <code>A.T[j,i] == A[i,j]</code> for all rows <code>i</code> and columns <code>j</code>:</p>
            <pre><code>print(A.T)
# [[1 4 7]
#  [2 5 8]
#  [3 6 9]]</code></pre>
            <p>To visualize this, imagine writing down a matrix on a translucent piece of paper. Draw a line from the top left corner to the bottom right corner of that paper, then rotate the paper 180° around that line:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2x3qNDptBldEKCgQBbmNPr/ad174561910e6c90753024625f16fd68/image3.png" />
          </figure><p>The second operation we'll need is <b>matrix multiplication</b>. Normally, we will multiply a matrix by a <b>column vector</b>, which is just a matrix with one column. For example, the following <code>3</code>-by-<code>1</code> matrix is a column vector:</p>
            <pre><code>s = np.matrix([[0],
               [1],
               [0]])</code></pre>
            <p>We can also write <code>s </code>more concisely as <code>np.matrix([[0,1,0]]).T</code>.  To multiply a square matrix <code>A</code> by a column vector <code>s</code>, we compute the <b>dot product</b> of each row of <code>A</code> with <code>s</code>. That is, if <code>t = A*s % Q</code>, then <code>t[i] == (A[i,0]*s[0,0] + A[i,1]*s[1,0] + A[i,2]*s[2,0]) % Q </code>for each row <code>i</code>. The output will always be a column vector:</p>
            <pre><code>print(A*s % Q)
# [[2]
#  [5]
#  [8]]</code></pre>
            <p>The number of rows of this column vector is equal to the number of rows of the matrix on the left hand side. In particular, if we take our column vector <code>s</code>, transpose it into a <code>1</code>-by-<code>3</code> matrix, and multiply it by a <code>3</code>-by-<code>1</code> matrix <code>r</code>, then we end up with a <code>1</code>-by-<code>1 </code>matrix:</p>
            <pre><code>r = np.matrix([[1,2,3]]).T
print(s.T*r % Q)
# [[2]]</code></pre>
            <p>The final matrix operation we'll need is <b>matrix addition</b>. If <code>A</code> and <code>B</code> are both <code>N</code>-by-<code>M</code> matrices, then <code>C = (A+B) % Q</code> is the <code>N</code>-by-<code>M</code> matrix for which <code>C[i,j] == (A[i,j]+B[i,j]) % Q</code>. Of course, this only works if the matrices we're adding have the same dimensions.</p>
    <div>
      <h4>Warm up</h4>
      <a href="#warm-up">
        
      </a>
    </div>
    <p>Enough maths — let's get to exchanging some keys. We start with the DH diagram from before and swap out the computations with matrix operations. Note that this protocol is not secure, but will be the basis of a secure key exchange mechanism we'll develop in the next section:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3qRFXuCjStyX8IdRgHogJi/0ea04a675e6b8b52fc74a2375827890c/image6.png" />
          </figure><ul><li><p>Alice and Bob agree on a public, <code>N</code>-by-<code>N</code> matrix <code>A</code>. This is analogous to the number $g$ that Alice and Bob agree on in the DH diagram.</p></li><li><p>Alice chooses a random length<code>-N</code> vector <code>s</code> and sends <code>t = A*s % Q</code> to Bob.</p></li><li><p>Bob chooses a random length<code>-N</code>  vector <code>r</code> and sends <code>u = r.T*A % Q</code> to Alice. You can also compute this as <code>(A.T*r).T % Q.</code></p></li></ul><p>The vectors <code>t</code> and <code>u</code> are analogous to DH key shares. After the exchange of these key shares, Alice and Bob can compute a shared secret. Alice computes the shared secret as <code>u*s % Q</code> and Bob computes the shared secret as <code>r.T*t % Q</code>. To see why they compute the same key, notice that <code>u*s == (r.T*A)*s == r.T*(A*s) == r.T*t.</code></p><p>In fact, this key exchange is essentially what happens in ML-KEM. However, we don't use this directly, but rather as part of a <b>public key encryption scheme</b>. Public key encryption involves three algorithms:</p><ul><li><p><code>key_gen():</code> The key generation algorithm that outputs a public encryption key <code>pk</code> and the corresponding secret decryption key <code>sk</code>.</p></li><li><p><code>encrypt()</code>: The encryption algorithm that takes the public key and a plaintext and outputs a ciphertext.</p></li><li><p><code>decrypt()</code>: The decryption algorithm that takes the secret key and a ciphertext and outputs the underlying plaintext. That is, <code>decrypt(sk, encrypt(pk, ptxt)) == ptxt</code> for any plaintext <code>ptxt</code>.</p></li></ul><p>We'll say the scheme is secure if, given a ciphertext and the public key used to encrypt it, no attacker can discern any information about the underlying plaintext without knowledge of the secret key. Once we have this encryption scheme, we then transform it into a <b>key-encapsulation mechanism</b> (the "KEM" in "ML-KEM") in the last step. A KEM is very similar to encryption except that the plaintext is always a randomly generated key.</p><p>Our encryption scheme is as follows:</p><ul><li><p><code>key_gen()</code>: To generate a key pair, we choose a random, square matrix <code>A</code> and a random column vector <code>s</code>. We set our public key to <code>(A,t=A*s % Q)</code> and our secret key to <code>s</code>. Notice that <code>t </code>is Alice's  key share from the key exchange protocol above.</p></li><li><p><code>encrypt()</code>: Suppose our plaintext <code>ptxt </code>is an integer in <code>range(Q)</code>. To encrypt <code>ptxt</code>, Bob generates his key share <code>u</code>. He then derives the shared secret and adds it to <code>ptxt</code>. The ciphertext has two components:</p></li></ul><blockquote><p><code>u = r.T*A % Q</code></p><p><code>v = (r.T*t + m) % Q</code></p></blockquote><p>Here <code>m </code>is a <code>1</code>-by-<code>1 </code>matrix containing the plaintext, i.e., <code>m = np.matrix([[ptxt]])</code>, and <code>r</code> is a random column vector.</p><ul><li><p><code>decrypt()</code>: To decrypt, Alice computes the shared secret and subtracts it from <code>v</code>:</p></li></ul><blockquote><p><code>m = (v - u*s) % Q</code></p></blockquote><p>Some readers will notice that this looks an awful lot like <a href="https://en.wikipedia.org/wiki/ElGamal_encryption"><u>El Gamal</u></a> encryption. This isn't a coincidence. Good cryptographers roll their own crypto; great cryptographers steal from good cryptographers.</p><p>Let's now put this together into code. The last thing we'll need is a method of generating random matrices and column vectors. We call this function <code>gen_mat() </code>below. Take a crack at implementing this yourself. Our scheme has two parameters: the modulus <code>Q</code>; and the dimension of <code>N</code> of the matrix and column vectors. The choice of <code>N</code> matters for security, but for now feel free to pick whatever value you want.</p>
            <pre><code>def key_gen():
    # Here `gen_mat()` returns an N-by-N matrix with entries
    # randomly chosen from `range(0, Q)`.
    A = gen_mat(N, N, 0, Q)
    # Like above except the matrix is N-by-1.
    s = gen_mat(N, 1, 0, Q)
    t = A*s % Q
    return ((A, t), s)

def encrypt(pk, ptxt):
    (A, t) = pk
    m = np.matrix([[ptxt]])
    r = gen_mat(N, 1, 0, Q)
    u = r.T*A % Q
    v = (r.T*t + m) % Q
    return (u, v)

def decrypt(sk, ctxt):
    s = sk
    (u, v) = ctxt
    m = (v - u*s) % Q
    return m[0,0]

# Test
assert decrypt(sk, encrypt(pk, 1)) == 1</code></pre>
            
    <div>
      <h4>Making the scheme secure (or "What is a lattice?")</h4>
      <a href="#making-the-scheme-secure-or-what-is-a-lattice">
        
      </a>
    </div>
    <p>By now, you might be wondering what on Earth a lattice even is. We promise we'll define it, but before we do, it'll help to understand why our warm-up scheme is insecure and what it'll take to fix it.</p><p>Readers familiar with linear algebra may already see the problem: in order for this scheme to be secure, it should be impossible for the attacker to recover the secret key <code>s</code>; but given the public <code>(A,t)</code>, we can immediately solve for <code>s</code> using <a href="https://en.wikipedia.org/wiki/Gaussian_elimination"><u>Gaussian elimination</u></a>.</p><p>In more detail, if <code>A</code> is invertible, we can write the secret key as <code>A</code><code><sup>-1</sup></code><code>*t == A</code><code><sup>-1</sup></code><code>*(A*s) == (A</code><code><sup>-1</sup></code><code>*A)*s == s,</code> where <code>A</code><code><sup>-1</sup></code> is the inverse of <code>A</code>. (When you multiply a matrix by its inverse, you get the identity matrix <code>I</code>, which simply takes a column vector to itself, i.e., <code>I*s == s.</code>) We can use Gaussian elimination to compute this matrix. Intuitively, all we're doing is solving a set of linear equations, where the entries of <code>s</code> are the unknown variables. (Note that this is possible even if <code>A</code> is not invertible.)</p><p>In order to make this encryption scheme secure, we need to make it a little... “messier”.</p>
    <div>
      <h5>Let's get messy</h5>
      <a href="#lets-get-messy">
        
      </a>
    </div>
    <p>For starters, we need to make it hard to recover the secret key from the public key. Let's try the following: generate another random vector <code>e</code> and add it into <code>A*</code>s. Our key generation algorithm becomes:</p>
            <pre><code>def key_gen():
    A = gen_mat(N, N, 0, Q)
    s = gen_mat(N, 1, 0, Q)
    e = gen_mat(N, 1, 0, Q)
    t = (A*s + e) % Q
    return ((A, t), s)</code></pre>
            <p>Our formula for the column vector component of the public key, <code>t</code>, now includes an additive term <code>e</code>, which we'll call the <b>error</b>. Like the secret key, the error is just a random vector. </p><p>Notice that the previous attack no longer works: since <code>A</code><code><sup>-1</sup></code><code>*t == A</code><code><sup>-1</sup></code><code>*(A*s + e) == A</code><code><sup>-1</sup></code><code>*(A*s) + A</code><code><sup>-1</sup></code><code>*e == s + A</code><code><sup>-1</sup></code><code>*e</code>, we need to know <code>e</code> in order to compute <code>s</code>.</p><p>Great, but this patch creates another problem. Take a second to plug in this new key generation algorithm into your implementation and test it out. What happens?</p><p>You should see that <code>decrypt()</code> now outputs garbage. We can see why using a little algebra:</p><blockquote><p>	<code>(v - u*s) == (r.T*t + m) - (r.T*A)*s</code></p><p><code>                == r.T*(A*s + e) + m - (r.T*A)*s</code></p><p><code>                == r.T*(A*s) + r.T*e + m - r.T*(A*s)</code></p><p><code>                == r.T*e + m</code></p></blockquote><p>The entries of <code>r</code> and <code>e</code> are sampled randomly, so <code>r.T*e</code> is also uniformly random. It's as if we encrypted <code>m</code> with a <a href="https://en.wikipedia.org/wiki/One-time_pad"><u>one-time pad</u></a>, then threw away the one-time pad!</p><h6>Handling decryption errors</h6><p>What can we do about this? First, it would help if <code>r.T*e</code> were small so that decryption yields something that's close to the plaintext. Imagine we could generate <code>r</code> and<code> e</code> in such a way that <code>r.T*e</code> were in <code>range(-epsilon, epsilon+1)</code> for some small <code>epsilon</code>. Then <code>decrypt</code> would output a number in <code>range(ptxt-epsilon, ptxt+epsilon+1)</code>, which would be pretty close to the actual plaintext.</p><p>However, we need to do better than get close. Imagine your browser failing to load your favorite website one-third of the time because of a decryption error. Nobody has time for that.</p><p>ML-KEM reduces the probability of decryption errors by being clever about how we encode the plaintext. Suppose all we want to do is encrypt a single bit, i.e., <code>ptxt </code>is either <code>0</code> or <code>1</code>. Consider the numbers in <code>range(Q)</code>, and split the number line into four chunks of roughly equal length:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3xojaMtl881io3pH4BdXNe/d47aede96c751942b82fedf0ca396450/image2.png" />
          </figure><p>Here we've labeled the region around zero (<code>-Q/4</code> to <code>Q/4</code> modulo <code>Q</code>) with <code>ptxt=0</code> and the region far away from zero with <code>ptxt=1</code>. To encode the bit, we set it to the integer corresponding to the middle of its range, i.e., <code>m = np.matrix([[ptxt * Q//2]])</code>. (Note the double "<code>//</code>" — this denotes integer division in Python.) To decode, we choose the <code>ptxt</code> corresponding to whatever range<code> m[0,0] </code>is in. That way if the decryption error is small, then we're highly likely to end up in the correct range.</p><p>Now all that's left is to ensure the decryption error, <code>r.T*e</code>, is small. We do this by sampling <b>short vectors </b><code>r</code> and <code>e</code>. By "short" we mean the entries of these vectors are sampled from a range that is much smaller than <code>range(Q)</code>. In particular, we'll pick some small positive integer <code>beta</code> and sample entries <code>range(-beta,beta+1)</code>.</p><p>How do we choose <code>beta</code>? Well, it should be small enough that decryption succeeds with overwhelming probability, but not so small that <code>r</code> and <code>e</code> are easy to guess and our scheme is broken. Take a minute or two to play with this. The parameters we can vary are:</p><ul><li><p>the modulus <code>Q</code></p></li><li><p>the dimension of the column vectors <code>N</code></p></li><li><p>the shortness parameter <code>beta</code></p></li></ul><p>For what ranges of these parameters is the decryption error low but the secret vectors are hard to guess? For what ranges is our scheme most efficient, in terms of runtime and communication cost (size of the public key plus the ciphertext)? We'll give a concrete answer at the end of this section, but in the meantime, we encourage you to play with this a bit.</p><h6>Gauss strikes back</h6><p>At this point, we have a working encryption scheme that mitigates at least one key-recovery attack. We've come pretty far, but we have at least one more problem.</p><p>Take another look at our formula for the ciphertext  <code>ctxt = (u,v)</code>. What would happen if we managed to recover the random vector <code>r</code>? That would be catastrophic, since <code>v == r.T*t + m</code>, and we already know <code>t</code> (part of the public key) and<code> v </code>(part of the ciphertext).</p><p>Just as we were able to compute the secret key from the public key in our initial scheme, we can recover the encryption randomness <code>r</code> from the ciphertext component <code>u</code> using Gaussian elimination. Again, this is just because <code>r</code> is the solution to a system of linear equations.</p><p>We can mitigate this plaintext-recovery attack just as before, by adding some noise. In particular, we'll generate a short vector according to <code>gen_mat(N,1,-beta,beta+1)</code> and add it into <code>u</code>. We also need to add noise to <code>v</code> in the same way, for reasons that we'll discuss in the next section.</p><p>Once again, adding noise increases the probability of a decryption error, but this time the magnitude of the error also depends on the secret key <code>s</code>. To see this, recall that during decryption, we multiply <code>u</code> by <code>s</code> (to compute the shared secret), and the error vector is an additive term. We'll therefore need <code>s</code> to be a short vector as well.</p><p>Let's now put together everything we've learned into an updated encryption scheme. Our scheme now has three parameters, <code>Q</code>, <code>N</code>, and <code>beta</code>, and can be used to encrypt a single bit:</p>
            <pre><code>def key_gen():
    A = gen_mat(N, N, 0, Q)
    s = gen_mat(N, 1, -beta, beta+1)
    e1 = gen_mat(N, 1, -beta, beta+1)
    t = (A*s + e1) % Q
    return ((A, t), s)

def encrypt(pk, ptxt):
    (A, t) = pk
    m = np.matrix([[ptxt*(Q//2) % Q]])
    r = gen_mat(N, 1, -beta, beta+1)
    e2 = gen_mat(N, 1, -beta, beta+1)
    e3 = gen_mat(1, 1, -beta, beta+1)
    u = (r.T*A + e2) % Q
    v = (r.T*t + e3 + m) % Q
    return (u, v)

def decrypt(sk, ctxt):
    s = sk
    (u, v) = ctxt
    m = (v - u*s) % Q
    if m[0,0] in range(Q//4, 3*Q//4):
        return 1
    return 0

# Test
assert decrypt(sk, encrypt(pk, 0)) == 0
assert decrypt(sk, encrypt(pk, 1)) == 1</code></pre>
            <p>Before moving on, try to find parameters for which the scheme works and for which the secret and error vectors seem hard to guess.</p>
    <div>
      <h5>Learning with errors</h5>
      <a href="#learning-with-errors">
        
      </a>
    </div>
    <p>So far we have a functioning encryption scheme for which we've mitigated two attacks, one a key-recovery attack and the other a plaintext-recovery attack. There seems to be no other obvious way of breaking our scheme, unless we choose parameters that are so weak that an attacker can easily guess the secret key s or ciphertext randomness r. Again, these vectors need to be short in order to prevent decryption errors, but not so short that they are easy to guess. (Likewise for the error terms.)</p><p>Still, there may be other attacks that require a little more sophistication to pull off. For instance, there might be some mathematical analysis we can do to recover, or at least make a good guess of, a portion of the ciphertext randomness. This raises a more fundamental question: in general, how do we establish that cryptosystems like this are actually secure?</p><p>As a first step, cryptographers like to try and reduce the attack surface. <b>Modern cryptosystems are designed so that the problem of attacking the scheme reduces to solving some other problem that is easier to reason about.</b></p><p>Our public key encryption scheme is an excellent illustration of this idea. Think back to the key- and plaintext-recovery attacks from the previous section. What do these attacks have in common?</p><p>In both instances, the attacker knows some public vector that allowed it to recover a secret vector:</p><ul><li><p>In the key-recovery attack, the attacker knew <code>t</code> for which <code>A*s == t.</code></p></li><li><p>In the plaintext-recovery attack, the attacker knew <code>u</code> for which <code>r.T*A == u </code>(or, equivalently,<code> A.T*r == u.T</code>).</p></li></ul><p>The fix in both cases was to construct the public vector in such a manner that it is hard to solve for the secret, namely, by adding an error term. However, ideally the public vector would reveal no information about the secret whatsoever. This ideal is formalized by the <b>Learning With Errors (LWE)</b> problem.</p><p>The LWE problem asks the attacker to distinguish between two distributions. Concretely, imagine we flip a coin, and if it comes up heads, we sample from the first distribution and give the sample to the attacker; and if the coin comes up tails, we sample from the second distribution and give the sample to the attacker. The distributions are as follows:</p><ul><li><p><code>(A,t=A*s + e</code>) where <code>A</code> is a random matrix generated with <code>gen_mat(N,N,0,Q)</code> and <code>s</code> and <code>e</code> are short vectors generated with <code>gen_mat(N,1,-beta,beta+1)</code>.</p></li><li><p><code>(A,t) </code>where <code>A</code> is a random matrix generated with <code>gen_mat(N,N,0,Q)</code> and <code>t</code> is a random vector generated with <code>gen_mat(N,1,0,Q)</code>.</p></li></ul><p>The first distribution corresponds to what we actually do in the encryption scheme; in the second, <code>t</code> is just a random vector, and no longer a secret vector at all. We say that the LWE problem is "hard" if no attacker is able to guess the coin flip with probability significantly better than one-half.</p><p>Our encryption is <i>passively </i>secure — meaning the ciphertext doesn't leak any information about the plaintext — if the LWE problem is hard for the parameters we chose. To see why, notice that both the public key and ciphertext look like LWE instances; if we can replace each instance with an instance of the random distribution, then the ciphertext would be completely independent of the plaintext and therefore leak no information about it at all. Note that, for this argument to go through, we also have to add the error term <code>e3</code> to the ciphertext component <code>v</code>.</p>
    <div>
      <h5>Choosing the parameters</h5>
      <a href="#choosing-the-parameters">
        
      </a>
    </div>
    <p>We've established that if solving the LWE problem is hard for parameters <code>N</code>, <code>Q</code>, and <code>beta</code>, then so is breaking our public key encryption scheme. What's left for us to do is tune the parameters so that solving LWE is beyond the reach of any attacker we can think of. This is where lattices come in.</p><h6>Lattices</h6><p>A <b>lattice </b>is an infinite grid of points in high-dimensional space. A two-dimensional lattice might look something like this:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5Js1SkG7bWyCNwPxKaYf3i/277a665f0e44ec7594e7e11b35958bc8/image4.png" />
          </figure><p>The points always follow a clear pattern that resembles "lattice work" you might see in a garden:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5kOimwlM1guY2YMj9Gn9xu/62ee11ddde1e18ba0cf3151a0b87092e/image5.jpg" />
          </figure><p><sup><i>(Source: https://picryl.com/media/texture-wood-vintage-backgrounds-textures-8395bb)</i></sup></p><p>For cryptography, we care about a special class of lattices, those defined by a matrix <code>P</code> that "recognizes" points in the lattice. That is, the lattice recognized by <code>P</code> is the set of vectors <code>v</code> for which <code>P*v == 0</code>, where "<code>0</code>" denotes the all-zero vector. The all-zero vector is <code>np.zeros((N,1), dtype=int)</code> in NumPy.</p><p>Readers familiar with linear algebra may have a different definition of lattices in mind: in general, a lattice is the set of points obtained by taking linear combinations of some basis. Our lattices can also be formulated in this way, i.e., for a matrix <code>P</code> that recognizes a lattice, we can compute the basis vectors that generate the lattice. However, we don't much care about this representation here.</p><p>The LWE problem boils down to distinguishing a set of points that are "close to" the lattice from a set of points that are "far away from" the lattice. We construct these points from an LWE instance and a random <code>(A,t)</code> respectively. Here we have an LWE sample (left) and a sample from the random distribution (right):</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/45bmYu3jdn8g7cI1i7WC3t/c82617991463169ecd83b1b944aa879a/image10.png" />
          </figure><p>What this shows is that the points of the LWE instance are much closer to the lattice than the random instance. This is indeed the case on average. However, while distinguishing LWE instances from random is easy in two dimensions, it gets harder in higher dimensions.</p><p>Let's take a look at how we construct these points. First, let's take an LWE instance <code>(A,t=(A*s + e) % Q</code>) and consider the lattice recognized by the matrix <code>P</code> we get by concatenating <code>A</code> with the identity matrix <code>I</code>. This might look something like this (<code>N=3</code>):</p>
            <pre><code>A = gen_mat(N, N, 0, Q)
P = np.concatenate((A, np.identity(N, dtype=int)), axis=1)
print(P)
# [[1570  634  161	1	0	0]
#  [1522 1215  861	0	1	0]
#  [ 344 2651 1889	0	0	1]]</code></pre>
            <p>Notice that we can compute <code>t</code> by multiplying <code>P</code> by the vector we get by concatenating <code>s</code> and <code>e</code> (<code>beta=2</code>):</p>
            <pre><code>s = gen_mat(N, 1, -beta, beta+1)
e = gen_mat(N, 1, -beta, beta+1)
t = (A*s + e) % Q
z = np.concatenate((s, e))
print(z)
# [[-2]
#  [ 0]
#  [-2]
#  [ 0]
#  [-1]
#  [ 2]]
assert np.array_equal(t, P*z % Q)</code></pre>
            <p>Let <code>z</code> denote this vector and consider the set of points <code>v</code> for which <code>P*v == t</code>. By definition, we say this set of points is "close to" the lattice because <code>z</code> is a short vector. (Remember: by "short" we mean its entries are bounded around <code>0</code> by <code>beta</code>.)</p><p>Now consider a random<code> (A,t)</code> and consider the set of points <code>v</code> for which <code>P*v == t</code>. We won't prove it, but it is a fact that this set of points is likely to be "far away from" the lattice in the sense that there is no short vector <code>z</code> for which<code> P*z == t.</code></p><p>Intuitively, solving LWE gets harder as <code>z</code> gets longer. Indeed, increasing the average length of <code>z</code> (by making <code>beta</code> larger) increases the average distance to the lattice, making it look more like a random instance: </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4oN8fydfP54b6EDLIOTYjI/85813f716b48164077b8f6d27586f768/unnamed__1_.png" />
          </figure><p>On the other hand, making <code>z</code> too long creates another problem.</p><h6>Breaking lattice cryptography by finding short vectors</h6><p>Given a random matrix <code>A</code>, the <b>Short Integer Solution (SIS)</b> problem is to find short vectors (i.e., whose entries are bounded by <code>beta</code>) <code>z1</code> and <code>z2</code> for which <code>(A*z1 + z2) % Q</code> is zero. Notice that this is equivalent to finding a short vector <code>z</code> in the lattice recognized by <code>P</code>:</p>
            <pre><code>z = np.concatenate((z1, z2))
assert np.array_equal((A*z1 + z2) % Q, P*z % Q)</code></pre>
            <p>If we had a (quantum) computer program for solving SIS, then we could use this program to solve LWE as well: if <code>(A,t) </code>is an LWE instance, then <code>z1.T*t </code>will be small; otherwise, if <code>(A,t)</code> is random, then <code>z1.T*t </code>will be uniformly random. (You can convince yourself of this using a little algebra.) Therefore, in order for our encryption scheme to be secure, it must be hard to find short vectors in the lattice defined by those parameters.</p><p>Intuitively, finding long vectors in the lattice is easier than finding short ones, which means that solving the SIS problem gets easier as <code>beta </code>gets closer to <code>Q</code>. On the other hand, as <code>beta </code> gets closer to <code>0</code>, it gets easier to distinguish LWE instances from random!</p><p><b>This suggests a kind of Goldilocks zone for LWE-based encryption</b>: if the secret and noise vectors are too short, then LWE is easy; but if the secret and noise vectors are too long, then SIS is easy. The optimal choice is somewhere in the middle.</p><h6>Enough math, just give me my parameters!</h6><p>To tune our encryption scheme, we want to choose parameters for which the most efficient known algorithms (quantum or classical) for solving LWE are out of reach for any attacker with as many resources as we can imagine (and then some, in case new algorithms are discovered). But how do we know which attacks to look out for?</p><p>Fortunately, the community of expert lattice cryptographers and cryptanalysts maintains a tool called <a href="https://github.com/malb/lattice-estimator"><u>lattice-estimator</u></a> that estimates the complexity of the best known (quantum) algorithms for lattice problems relevant to cryptography. Here's what we get when we run this tool for ML-KEM (this requires <a href="https://www.sagemath.org/"><u>Sage</u></a> to run):</p>
            <pre><code>sage: from estimator import *
sage: res = LWE.estimate.rough(schemes.Kyber768)
usvp        :: rop: ≈2^182.2, red: ≈2^182.2, δ: 1.002902, β: 624, d: 1427, tag: usvp
dual_hybrid :: rop: ≈2^174.3, red: ≈2^174.3, guess: ≈2^162.5, β: 597, p: 4, ζ: 10, t: 60, β': 597, N: ≈2^122.7, m: 768</code></pre>
            <p>The number that we're most interested in is "<code>rop</code>", which estimates the amount of computation the attack would consume. Playing with this tool a bit, we eventually find some parameters for our scheme for which the "<code>usvp</code>" and "<code>dual_hybrid</code>" attacks have comparable complexity. However, lattice-estimator identifies an attack it calls "<code>arora-gb</code>" that applies to our scheme, but not to ML-KEM, that has much lower complexity.  (<code>N=600</code>, <code>Q=3329</code>, and <code>beta=4</code>):</p>
            <pre><code>sage: res = LWE.estimate.rough(LWE.Parameters(n=600, q=3329, Xs=ND.Uniform(-4,4), Xe=ND.Uniform(-4,4)))
usvp        :: rop: ≈2^180.2, red: ≈2^180.2, δ: 1.002926, β: 617, d: 1246, tag: usvp
dual_hybrid :: rop: ≈2^226.2, red: ≈2^225.4, guess: ≈2^224.9, β: 599, p: 3, ζ: 10, t: 0, β': 599, N: ≈2^174.8, m: 600
arora-gb    :: rop: ≈2^129.4, dreg: 9, mem: ≈2^129.4, t: 4, m: ≈2^64.7</code></pre>
            <p>We'd have to bump the parameters even further to the scheme to a regime that has comparable security to ML-KEM.</p><p>Finally, a word of warning: when designing lattice cryptography, determining whether our scheme is secure requires a lot more than estimating the cost of generic attacks on our LWE parameters. In the absence of a mathematical proof of security in a realistic adversarial model, we can't rule out other ways of breaking our scheme. Tread lightly, fair traveler, and bring a friend along for the journey.</p>
    <div>
      <h4>Making the scheme efficient</h4>
      <a href="#making-the-scheme-efficient">
        
      </a>
    </div>
    <p>Now that we understand how to encrypt with LWE, let's take a quick look at how to make our scheme efficient.</p><p>The main problem with our scheme is that we can only encrypt a bit at a time. This is because we had to split the  <code>range(Q)</code> into two chunks, one that encodes <code>1</code> and another that encodes <code>0</code>. We could improve the bit rate by splitting the range into more chunks, but this would make decryption errors more likely.</p><p>Another problem with our scheme is that the runtime depends heavily on our security parameters. Encryption requires <code>O(N</code><code><sup>2</sup></code><code>)</code> multiplications (multiplication is the most expensive part of a secure implementation of modular arithmetic), and in order for our scheme to be secure, we need to make <code>N</code> quite large.</p><p>ML-KEM solves both of these problems by replacing modular arithmetic with arithmetic over a <a href="https://en.wikipedia.org/wiki/Polynomial_ring"><b><u>polynomial ring</u></b></a>. This means the entries of our matrices will be polynomials rather than integers. We need to define what it means to add, subtract, and multiply polynomials, but once we've done that, everything else about the encryption scheme is the same.</p><p>In fact, you probably learned polynomial arithmetic in grade school. The only thing you might not be familiar with is polynomial modular reduction. To multiply two polynomials $f(X)$ and $g(X)$, we start by multiplying $f(X)\cdot g(X)$ as usual. Then we're going to <b>divide </b>$f(X)\cdot g(X)$ by some special polynomial — ML-KEM uses $X^{256}+1$ — and take the remainder. We won't try to explain this algorithm, but the takeaway is that the result is a polynomial with $256$ coefficients, each of which is an integer in <code>range(Q)</code>.</p><p>The main advantage of using a polynomial ring for arithmetic is that we can pack more bits into the ciphertext. Our formula for the ciphertext is exactly the same (<code>u=r.T*A + e2, v=r.T*t + e3 + m</code>), but this time the plaintext <code>m </code>encodes a polynomial. Each coefficient of the polynomial encodes a bit, and we'll handle decryption errors just as we did before, by splitting <code>range(Q)</code> into two chunks, one that encodes <code>1</code> and another that encodes <code>0</code>. This allows us to reliably encrypt 256 bits (32 bytes) per ciphertext.</p><p>Another advantage of using polynomials is that it significantly reduces the dimension of the matrix without impacting security. Concretely, the most widely used variant of ML-KEM, ML-KEM-768, uses a <code>3</code>-by-<code>3</code> matrix <code>A</code>, so just <code>9 </code>polynomials in total. (Note that $256 \cdot 3 = 768$, hence the name "ML-KEM-768".) However, note that we have to be careful in how we choose the modulus: $X^{256}+1$ is special in that it does not exhibit any algebraic structure that is known to permit attacks.</p><p>The choices of <code>Q=3329</code> for the coefficient modulus and $X^{256}+1$ for the polynomial modulus have one more benefit. They allow polynomial multiplication to be carried out using the <a href="https://eprint.iacr.org/2024/585"><u>NTT algorithm</u></a>, which massively reduces the number of multiplications and additions we have to perform. In fact, this optimization is a major reason why ML-KEM is sometimes faster in terms of CPU time than key exchange with elliptic curves.</p><p>We won't get into how NTT works here, except to say that the algorithm will look familiar to you if you've ever implemented RSA. In both cases we use the <a href="https://en.wikipedia.org/wiki/Chinese_remainder_theorem"><u>Chinese Remainder Theorem</u></a> to split multiplication up into multiple, cheaper multiplications with smaller moduli.</p>
    <div>
      <h4>From public key encryption to ML-KEM</h4>
      <a href="#from-public-key-encryption-to-ml-kem">
        
      </a>
    </div>
    <p>The last step to build ML-KEM is to make the scheme secure against chosen ciphertext attacks (CCA). Currently, it's only secure against chosen plaintext attacks (CPA), which basically means that the ciphertext leaks no information about the plaintext, regardless of the distribution of plaintexts. CCA security is stronger in that it gives the attacker access to <a href="https://en.wikipedia.org/wiki/Adaptive_chosen-ciphertext_attack#Practical_attacks"><u>decryptions of ciphertexts of its choosing</u></a>. (Of course, it's not allowed to decrypt the target ciphertext itself.) The specific transform used in ML-KEM results in a CCA-secure KEM ("Key-Encapsulation Mechanism").</p><p>Chosen ciphertext attacks might seem a bit abstract, but in fact they formalize a realistic threat model for many applications of KEMs (and public key encryption for that matter). For example, suppose we use the scheme in a protocol in which the server authenticates itself to a client by proving it was able to decrypt a ciphertext generated by the client. In this kind of protocol, the server acts as a sort of "decryption oracle" in which its responses to clients depend on the secret key. Unless the scheme is CCA secure, this oracle can be abused by an attacker to leak information about the secret key over time, allowing it to eventually impersonate the server.</p><p>ML-KEM incorporates several more optimizations to make it as fast and as compact as possible. For example, instead of generating a random matrix <code>A</code>, we can derive it from a random, 32-byte string (called a "seed") using a hash-based primitive called a XOF ("eXtendable Output Function"), in the case of ML-KEM this XOF is <a href="https://pycryptodome.readthedocs.io/en/latest/src/hash/shake128.html"><u>SHAKE128</u></a>. This significantly reduces the size of the public key.</p><p>Another interesting optimization is that the polynomial coefficients (integers in <code>range(Q)</code>) in the ciphertext are compressed by rounding off the least significant bits of each coefficient, thereby reducing the overall size of the ciphertext.</p><p>All told, for the most widely deployed parameters (ML-KEM-768), the public key is 1184 bytes and the ciphertext is 1088 bytes. There's no obvious way to reduce this, except by reducing the size of the encapsulated key or the size of the public matrix <code>A</code>. The former would make ML-KEM useful for fewer applications, and the latter would reduce the security margin.</p><p>Note that there are <a href="https://eprint.iacr.org/2022/031"><u>other lattice schemes</u></a> that are smaller, but they are based on different hardness assumptions and are still undergoing analysis.</p>
    <div>
      <h3>Authentication</h3>
      <a href="#authentication">
        
      </a>
    </div>
    <p>In the previous section, we learned about ML-KEM, the algorithm already in use to make encryption PQ-secure. However, encryption is only one piece of the puzzle: establishing a secure connection also requires <b>authenticating</b> the server — and sometimes the client, depending on the application.</p><p>Authentication is usually provided by a <b>digital signature scheme</b>, which uses a secret key to sign a message and a public key to verify the signature. The signature schemes used today aren't PQ-secure: a quantum computer can be used to compute the secret key corresponding to a server's public key, then use this key to impersonate the server.</p><p>While this threat is less urgent than the threat to encryption, mitigating it is going to be more complicated. Over the years, we've bolted a number of signatures onto the <a href="https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/">TLS handshake</a> in order to meet the evolving requirements of the web <a href="https://en.wikipedia.org/wiki/Public_key_infrastructure"><u>PKI</u></a>. We have PQ alternatives for these signatures, one of which we'll study in this section, but so far these signatures and their public keys are too large (i.e., take up too many bytes) to make comfortable replacements for today's schemes. Barring some breakthrough in <a href="https://blog.cloudflare.com/another-look-at-pq-signatures/"><u>NIST's ongoing standardization effort</u></a>, we will have to re-engineer TLS and the web PKI to use fewer signatures.</p><p>For now, let's dive into the PQ signature scheme we're likely to see deployed first: <a href="https://csrc.nist.gov/pubs/fips/204/final"><u>ML-DSA</u></a>, a.k.a. Dillithium. The design of ML-DSA follows a similar template as ML-KEM. We start by building some intermediate primitive, then we transform that primitive into the primitive we want, in this case a signature scheme.</p><p>ML-DSA is quite a bit more involved than ML-KEM, so we're going to try to boil it down even further and just try to get across the main ideas.</p>
    <div>
      <h4>Warm up</h4>
      <a href="#warm-up">
        
      </a>
    </div>
    <p>Whereas ML-KEM is basically El Gamal encryption with elliptic curves replaced with lattices, ML-DSA is basically the <a href="https://www.zkdocs.com/docs/zkdocs/zero-knowledge-protocols/schnorr/"><u>Schnorr identification protocol</u></a> with elliptic curves replaced with lattices. Schnorr's protocol is used by a <b>prover </b>to convince a <b>verifier</b> that it knows the secret key associated with its public key without revealing the secret key itself. The protocol has three moves and is executed with four algorithms:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7lV5fU3j9rRQ2j2Y4lpW8r/a12908c078ec46e0fa35ef674fcfdb07/image8.png" />
          </figure><ol><li><p><code>initialize()</code>: The prover initializes the protocol and sends a <b>commitment</b> to the verifier</p></li><li><p><code>challenge()</code>:  The verifier receives the commitment and sends the prover a <b>challenge</b></p></li><li><p><code>finish()</code>: The prover receives the challenge and sends the verifier the <b>proof</b> </p></li><li><p><code>verify()</code>:  Finally, the verifier uses the proof to decide whether the prover knows the secret key</p></li></ol><p>We get the high-level structure of ML-DSA by making this protocol non-interactive. In particular, the prover derives the challenge itself by hashing the commitment together with the message to be signed. The signature consists of the commitment and proof: to verify the signature, the verifier recomputes the challenge from the commitment and message and runs <code>verify()</code>as usual.</p><p>Let's jump right in to building Schnorr's identification protocol from lattices. If you've never seen this protocol before, then this will look a little like black magic at first. We'll go through it slowly enough to see how and why it works.</p><p>Just like for ML-KEM, our public key is an LWE instance <code>(A,t=A*s1 + s2)</code>. However, this time our secret key is the <i>pair</i> of short vectors <code>(s1,s2)</code>, i.e., it includes the error term. Otherwise, key generation is exactly the same:</p>
            <pre><code>def key_gen():
    A = gen_mat(N, N, 0, Q)
    s1 = gen_mat(N, 1, -beta, beta+1)
    s2 = gen_mat(N, 1, -beta, beta+1)
    t = (A*s1 + s2) % Q
    return ((A, t), (s1, s2))</code></pre>
            <p>To initialize the protocol, the prover generates another LWE instance <code>(A,w=A*y1 + y2)</code>. You'll see why in just a moment. The prover sends the <i>hash</i> of <code>w</code> as its commitment:</p>
            <pre><code>def initialize(A):
    y1 = gen_mat(N, 1, -beta, beta+1)
    y2 = gen_mat(N, 1, -beta, beta+1)
    w = (A*y1 + y2) % Q
    return (H(w), (y1, y2))</code></pre>
            <p>Here <code>H </code>is some cryptographic hash function, like <a href="https://en.wikipedia.org/wiki/SHA-3"><u>SHA-3</u></a>. The prover stores the secret vectors<code> (y1,y2)</code> for use in its next move.</p><p>Now it's time for the verifier's challenge. The challenge is just an integer, but we need to be careful about how we choose it. For now let's just pick it at random:</p>
            <pre><code>def challenge():
    return random.randrange(0, Q)</code></pre>
            <p>Remember: when we turn this protocol into a digital signature, the challenge is derived from the commitment, <code>H(w)</code>, and the message. The range of this hash function must be the same as the set of outputs of <code>challenge()</code>.</p><p>Now comes the fun part. The proof is a pair of vectors<code> (z1,z2)</code> satisfying <code>A*z1 + z2 == c*t + w</code>. We can easily produce this proof if we know the secret key:</p><p>	<code>z1 = (c*s1 + y1) % Q</code></p><p>        <code>z2 = (c*s2 + y2) % Q</code></p><p>Then <code>A*z1 + z2 == A*(c*s1 + y1) + (c*s2 + y2) == c*(A*s1 + s2) + (A*y1 + y2) == c*t + w</code>. Our goal is to design the protocol such that it's hard to come up with <code>(z1,z2)</code> without knowing <code>(s1,s2)</code>, even after observing many executions of the protocol.</p><p>Here are the <code>finish() </code>and <code>verify() </code>algorithms for completeness:</p>
            <pre><code>def finish(s1, s2, y1, y2, c):
    z1 = (c*s1 + y1) % Q
    z2 = (c*s2 + y2) % Q
    return (z1, z2)

def verify(A, t, hw, c, z1, z2):
	return H((A*z1 + z2 - c*t) % Q) == hw

# Test
((A, t), (s1, s2)) = key_gen()
(hw, (y1, y2)) = initialize(A)        # hw: prover -&gt; verifier
c = challenge()                       # c: verifier -&gt; prover
(z1, z2) = finish(s1, s2, y1, y2, c)  # (z1, z2): prover -&gt; verifier
assert verify(A, t, hw, c, z1, z2)    # verifier</code></pre>
            <p>Notice that the verifier doesn't actually check <code>A*z1 + z2 == c*t + w</code> directly; we have to rearrange the equation so that we can set the commitment to <code>H(w)</code> rather than <code>w</code>. We'll explain the need for hashing in the next section.</p>
    <div>
      <h4>Making this scheme secure</h4>
      <a href="#making-this-scheme-secure">
        
      </a>
    </div>
    <p>The question of whether this protocol is secure boils down to whether it's possible to impersonate the prover without knowledge of the secret key. Let's put our attacker hat on and poke around.</p><p>Perhaps there's a way to compute the secret key, either from the public key directly or by eavesdropping on executions of the protocol with the honest prover. If LWE is hard, then clearly there's no way we're going to extract the secret key from the public key <code>t</code>. Likewise, the commitment <code>H(w)</code>doesn't leak any information that would help us extract the secret key from the proof<code> (z1,z2)</code>.</p><p>Let's take a closer look at the proof. Notice that the vectors <code>(y1,y2)</code> "mask" the secret key vectors, sort of how the shared secret masks the plaintext in ML-KEM. However, there's one big exception: we also scale the secret key vectors by the challenge <code>c</code>.</p><p>What's the effect of scaling these vectors? If we squint at a few proofs, we start to see a pattern emerge. Let's look at <code>z1</code> first (<code>N=3, Q=3329, beta=4</code>):</p>
            <pre><code>((A, t), (s1, s2)) = key_gen()
print('s1={}'.format(s1.T % Q))
for _ in range(10):
    (w, (y1, y2)) = initialize(A)
    c = challenge()
    (z1, z2) = finish(s1, s2, y1, y2, c)
    print('c={}, z1={}'.format(c, z1.T))
# s1=[[   1	0 3326]]
# c=1123, z1=[[1121 3327 3287]]
# c=1064, z1=[[1060	4  137]]
# c=1885, z1=[[1884 3327  999]]
# c=269, z1=[[ 270 3325 2524]]
# c=1506, z1=[[1510 3325 2141]]
# c=3147, z1=[[3149	4  547]]
# c=703, z1=[[ 700	4 1219]]
# c=1518, z1=[[1518 3327 2104]]
# c=1726, z1=[[1726	0 1478]]
# c=2591, z1=[[2589	4 2217]]</code></pre>
            <p>Indeed, with enough proof samples, we should be able to make a pretty good guess of the value of <code>s1</code>. In fact, for these parameters, there is a simple statistical analysis we can do to compute <code>s1</code> exactly. (Hint: <code>Q</code> is a prime number, which means <code>c*pow(c,-1,Q)==1 </code>whenever <code>c&gt;0</code>.) We can also apply this analysis to <code>s2</code>, or compute it directly from <code>t</code>, <code>s1</code>, and <code>A</code>.</p><p>The main flaw in our protocol is that, although our secret vectors are short, scaling them makes them so long that they're not completely masked by<code> (y1,y2)</code>. Since <code>c</code> spans the entire <code>range(Q)</code>, so do the entries of <code>c*s1.</code> and <code>c*s2,</code> which means in order to mask these entries, we need the entries of <code>(y1,y2) </code>to span <code>range(Q)</code> as well. However, doing this would make solving LWE for <code>(A,w)</code> easy, by solving SIS. We somehow need to strike a balance between the length of the vectors of our LWE instances and the leakage induced by the challenge.</p><p>Here's where things get tricky. Let's refer to the set of possible outputs of <code>challenge() </code>as the <b>challenge space. </b>We need the challenge space to be fairly large, large enough that the probability of outputting the same challenge twice is negligible.</p><p>Why would such a collision be a problem? It's a little easier to see in the context of digital signatures. Let's say an attacker knows a valid signature for a message <code>m</code>. The signature includes the commitment <code>H(m)</code>, so the attacker also knows the challenge is <code>c == H(H(w),m)</code>. Suppose it manages to find a different message <code>m</code><code><sup>*</sup></code> for which <code>c == H(H(w),m</code><code><sup>*</sup></code><code>)</code>. Then the signature is also valid for m! And this attack is easy to pull off if the challenge space, that is, the set of possible outputs of <code>H</code>, is too small.</p><p>Unfortunately, we can't make the challenge space larger simply by increasing the size of the modulus <code>Q</code>: the larger the challenge might be, the more information we'd leak about the secret key. We need a new idea.</p>
    <div>
      <h5>The best of both worlds</h5>
      <a href="#the-best-of-both-worlds">
        
      </a>
    </div>
    <p>Remember that the hardness of LWE depends on the ratio between <code>beta</code> and <code>Q</code>. This means that <code>y1</code> and <code>y2</code> don't need to be short in absolute terms, but short relative to random vectors.</p><p>With that in mind, consider the following idea. Let's take a larger modulus, say <code>Q=2**31 - 1</code>, and we'll continue to sample from the same challenge space, <code>range(2**16)</code>.</p><p>First, notice that <code>z1</code> is now "relatively" short, since its entries are now in <code>range(-gamma, gamma+1)</code>, where <code>gamma = beta*(2**16-1),</code> rather than uniform over <code>range(Q)</code>. Let's also modify <code>initialize()</code> to sample the entries of <code>(y1,y2)</code> from the same range and see what happens:</p>
            <pre><code>def initialize(A):
	y1 = gen_mat(N, 1, -gamma, gamma+1)
	y2 = gen_mat(N, 1, -gamma, gamma+1)
	w = (A*y1 + y2) % Q
	return (H(w), (y1, y2))

((A, t), (s1, s2)) = key_gen()
print('s1={}'.format(s1.T % Q))
for _ in range(10):
    (w, (y1, y2)) = initialize(A)
    c = challenge()
    (z1, z2) = finish(s1, s2, y1, y2, c)
    print('c={}, z1={}'.format(c, z1.T))
# s1=[[3 0 1]]
# c=31476, z1=[[175933 141954  93186]]
# c=27360, z1=[[    136404 2147438807     283758]]
# c=33536, z1=[[2147430945 2147377022     190671]]
# c=23283, z1=[[186516  73400   4955]]
# c=24756, z1=[[    328377 2147438906 2147388768]]
# c=12428, z1=[[2147340715     188675      90282]]
# c=24266, z1=[[    175498 2147261581 2147301553]]
# c=45331, z1=[[357595 185269 177155]]
# c=45641, z1=[[     21592 2147249191 2147446200]]
# c=57893, z1=[[297750 113335 144894]]</code></pre>
            <p>This is definitely going in the right direction, since there are no obvious correlations between <code>z1</code> and <code>s1</code>. (Likewise for <code>z2</code> and <code>s2</code>.) However, we're not quite there.</p><p>One problem is that the challenge space is still quite small. With only <code>2**16 </code>challenges to choose from, we're likely to see a collision even after only a handful of protocol executions. We need the challenge space to be much, much larger, say around <code>2**256</code>. But then <code>Q</code> has to be an insanely large number in order for the <code>beta</code> to <code>Q</code> ratio to be secure.</p><p>ML-DSA is able to side step this problem due to its use of arithmetic over polynomial rings. It uses the same modulus polynomial as ML-KEM, so the challenge is a polynomial with 256 coefficients. The coefficients are chosen carefully so that the challenge space is large, but multiplication by the challenge scales the secret vector by a small amount. Note that we still end up using a slightly larger modulus (<code>Q=8380417</code>) for ML-DSA than for ML-KEM, but only by about twelve bits.</p><p>However, there is a more fundamental problem here, which is that we haven't completely ruled out that signatures may leak information about the secret key.</p>
    <div>
      <h5>Cause and effect</h5>
      <a href="#cause-and-effect">
        
      </a>
    </div>
    <p>Suppose we run the protocol a number of times, and in each run, we happen to choose a relatively small value for some entry of <code>y1</code>. After enough runs, this would eventually allow us to reconstruct the corresponding entry of <code>s1</code>. To rule this out as a possibility, we need to make <code>y1 </code>even longer. (Likewise for <code>y2</code>.) But how long?</p><p>Suppose we know that the entries of <code>z1</code> and <code>z2</code> are always in <code>range(-beta_loose,beta_loose+1) </code>for some <code>beta_loose &gt; beta</code>. Then we can <b>simulate </b>an honest run of the protocol as follows:</p>
            <pre><code>def simulate(A, t):
    z1 = gen_mat(N, 1, -beta_loose, beta_loose+1)
    z2 = gen_mat(N, 1, -beta_loose, beta_loose+1)
    c = challenge()
    w = (A*z1 + z2 - c*t) % Q
    return (H(w), c, (z1, z2))

# Test
((A, t), (s1, s2)) = key_gen()
(hw, c, (z1, z2)) = simulate(A, t)
assert verify(A, t, hw, c, z1, z2)</code></pre>
            <p>This procedure perfectly simulates honest runs of the protocol, in the sense that the output of <code>simulate() </code>is indistinguishable from the transcript of a real run of the protocol with the honest prover. To see this, notice that the <code>w</code>,<code> c</code>, <code>z1</code>, and <code>z2 </code>all have the same mathematical relationship (the verification equation still holds) and have the same distribution.</p><p>And here's the punch line: since this procedure doesn't use the secret key, it follows that the attacker learns nothing from eavesdropping on the honest prover that it can't compute from the public key itself. Pretty neat!</p><p>What's left to do is arrange for <code>z1</code> and <code>z2</code> to fall in this range. First, we modify <code>initialize() </code>by increasing the range of <code>y1 </code>and<code> y2 </code>by<code> beta_loose</code>:</p>
            <pre><code>def initialize(A):
    y1 = gen_mat(N, 1, -gamma+beta_loose, gamma+beta_loose+1)
    y2 = gen_mat(N, 1, -gamma+beta_loose, gamma+beta_loose+1)
    w = (A*y1 + y2) % Q
    return (H(w), (y1, y2))</code></pre>
            <p>This ensures the proof vectors <code>z1</code> and <code>z2 </code>are roughly uniform over r<code>ange(-beta_loose, beta_loose+1)</code>. However, they may fall slightly outside of this range, so need to modify <code>finalize() </code>to <b>abort </b>if not. Correspondingly, <code>verify() </code>should reject proof vectors that are out of range:</p>
            <pre><code>def finish(s1, s2, y1, y2, c):
    z1 = (c*s1 + y1) % Q
    z2 = (c*s2 + y2) % Q
    if not in_range(z1, beta_loose) or not in_range(z2, beta_loose):
        return (None, None)
    return (z1, z2)

def verify(A, t, hw, c, z1, z2):
    if not in_range(z1, beta_loose) or not in_range(z2, beta_loose):
        return False
    return H((A*z1 + z2 - c*t) % Q) == hw</code></pre>
            <p>If <code>finish()</code> returns <code>(None,None)</code>, then the prover and verifier are meant to abort the protocol and retry until the protocol succeeds:</p>
            <pre><code>((A, t), (s1, s2)) = key_gen()
while True:
    (hw, (y1, y2)) = initialize(A)        # hw: prover -&gt; verifier
    c = challenge()                       # c: verifier -&gt; prover
    (z1, z2) = finish(s1, s2, y1, y2, c)  # (z1, z2): prover -&gt; verifier
    if z1 is not None and z2 is not None:
        break
assert verify(A, t, hw, c, z1, z2)</code></pre>
            <p>Interestingly, we should expect aborts to be quite common. The parameters of ML-DSA are tuned so that the protocol runs five times on average before it succeeds.</p><p>Another interesting point is that the security proof requires us to simulate not only successful protocol runs, but aborted protocol runs as well. More specifically, the protocol simulator must abort with the same probability as the real protocol, which implies that the rejection probability is <i>independent </i>of the secret key.</p><p>The simulator also needs to be able to produce realistic looking commitments for aborted transcripts. This is exactly why the prover commits to the <i>hash</i> of <code>w </code>rather than <code>w </code> itself: in the security proof, we can easily simulate hashes of random inputs.</p>
    <div>
      <h4>Making this scheme efficient</h4>
      <a href="#making-this-scheme-efficient">
        
      </a>
    </div>
    <p>ML-DSA benefits from many of the same optimizations as ML-KEM, including using polynomial rings, NTT for polynomial multiplication, and encoding polynomials with a fixed number of bits. However, ML-DSA has a few more tricks to make things smaller.</p><p>First, in ML-DSA, instead of the pair of short vectors <code>z1 </code>and <code>z2</code>, the proof consists of a single vector <code>z=c*s1 + y,</code> where <code>y</code> was committed to in the previous step. In turn, we only end up with a single proof vector <code>z</code> rather than two as before. Getting this to work requires a special encoding of the commitment so that we can't compute <code>y</code> from it. ML-DSA uses a related trick to reduce the size of the <code>t</code> vector of the public key, but the details are more complicated.</p><p>For the parameters we expect to deploy first (ML-DSA-44), the public key is 1312 bytes long and the signature is a whopping 2420 bytes. In contrast to ML-KEM, it is possible to shave off some more bytes. This does not come for free and requires complicating the scheme. An example is <a href="https://eprint.iacr.org/2023/624.pdf"><u>HAETAE</u></a>, which changes the distributions used. <a href="https://github.com/pornin/rust-fn-dsa"><u>Falcon</u></a> takes it a step further with even smaller signatures, using a completely different approach, which although elegant is also more complex to implement.</p>
    <div>
      <h3>Wrap up</h3>
      <a href="#wrap-up">
        
      </a>
    </div>
    <p>Lattice cryptography underpins the first generation of PQ algorithms to get widely deployed on the Internet. ML-KEM is already widely used today to protect encryption from quantum computers, and in the coming years we expect to see ML-DSA deployed to get ahead of the threat of quantum computers to authentication.</p><p>Lattices are also the basis of a new frontier for cryptography: computing on encrypted data.</p><p>Suppose you wanted to aggregate some metrics submitted by clients without learning the metrics themselves. <a href="https://eprint.iacr.org/2024/936"><u>With LWE-based encryption</u></a>, you can arrange for each client to encrypt their metrics before submission, aggregate the ciphertexts, then decrypt to get the aggregate.</p><p>Suppose instead that a server has a database that it wants to provide clients access to without revealing to the server which rows of the database the client wants to query. <a href="https://eprint.iacr.org/2022/949"><u>LWE-based encryption</u></a> allows the database to be encoded in a manner that permits encrypted queries.</p><p>These applications are special cases of a paradigm known as <a href="https://en.wikipedia.org/wiki/Homomorphic_encryption"><u>FHE</u></a> ("Fully Homomorphic Encryption"), which allows for arbitrary computations on encrypted data. FHE is an extremely powerful primitive, and the only way we know how to build it today is with lattices. However, for most applications, FHE is far less practical than a special-purpose protocol would be (lattice-based or not). Still, over the years we've seen FHE get better and better, and for many applications it is already a decent option. Perhaps we'll dig into this and other lattice schemes in a future blog post.</p><p>We hope you enjoyed this whirlwind tour of lattices. Thanks for reading!</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">01euRoOpkvsq16eKrMZ6hu</guid>
            <dc:creator>Christopher Patton</dc:creator>
            <dc:creator>Peter Schwabe (Guest Author)</dc:creator>
        </item>
        <item>
            <title><![CDATA[An early look at cryptographic watermarks for AI-generated content]]></title>
            <link>https://blog.cloudflare.com/an-early-look-at-cryptographic-watermarks-for-ai-generated-content/</link>
            <pubDate>Wed, 19 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ It's hard to tell the difference between web content produced by humans and web content produced by AI. We're taking new approach to making AI content distinguishable without impacting performance.  ]]></description>
            <content:encoded><![CDATA[ <p><a href="https://www.cloudflare.com/learning/ai/what-is-generative-ai/">Generative AI</a> is reshaping many aspects of our lives, from how we work and learn, to how we play and interact. Given that it's Security Week, it's a good time to think about some of the unintended consequences of this information revolution and the role that we play in bringing them about.</p><p>Today's web is full of AI-generated content: text, code, <a href="https://www.cloudflare.com/learning/ai/ai-image-generation/">images</a>, audio, and video can all be generated by machines, normally based on a prompt from a human. Some models have become so sophisticated that distinguishing their artifacts — that is, the text, audio, and video they generate — from everything else can be quite difficult, <a href="https://originality.ai/blog/openai-text-classifier-review"><u>even for machines themselves</u></a>. This difficulty creates a number of challenges. On the one hand, those who train and deploy generative AI need to be able to identify AI-created artifacts they scrape from websites in order <a href="https://www.cloudflare.com/learning/ai/how-to-secure-training-data-against-ai-data-leaks/"><u>to avoid polluting their training data</u></a>. On the other hand, the origin of these artifacts may be intentionally misrepresented, creating <a href="https://www.gov.ca.gov/2024/09/19/governor-newsom-signs-bills-to-crack-down-on-sexually-explicit-deepfakes-require-ai-watermarking/"><u>myriad problems</u></a> for society writ large.</p><p>Part of the solution to this problem might be <b>watermarking</b>. The basic idea of watermarking is to modify the training process, the inference process, or both so that an artifact of the model embeds some identifying information of the model from which it originates. This way a model operator, or potentially the consumer of the content themselves, can determine whether some artifact came from the model by checking for the presence of the watermark.</p><p>Watermarking shares many of the same goals as the <a href="https://c2pa.org/"><u>C2PA initiative</u></a>. C2PA seeks to add provenance of media from a variety of sources, not just AI. Think of it as a chain of digital signatures, where each link in the chain corresponds to some modification of the artifact. For example, if you're a Cloudflare customer using <a href="https://www.cloudflare.com/developer-platform/products/cloudflare-images/"><u>Images</u></a> to serve C2PA-tagged content, <a href="https://blog.cloudflare.com/preserve-content-credentials-with-cloudflare-images/"><u>you can opt in to preserve the provenance</u></a> by extending this signature chain, even after the image is compressed on our network.</p><p>The challenge of this approach is that it requires participation by each entity in the chain of custody of the artifact. Watermarking has the potential to make C2PA more robust by preserving the origin of the artifact even after unattributed modification. Whereas the C2PA signature is encoded in an image’s metadata, a watermark is embedded in the pixels of the image itself.</p><p>In this post, we're going to take a look at an emerging paradigm for AI watermarking. Based on cryptography, these new watermarks aim to provide rigorous, mathematical guarantees of quality preservation and robustness to modification of the content. This field is, as of 2025, only a couple of years old, and we don't yet know if it will yield schemes that are practical to deploy. Nevertheless, we believe this is a promising area of research, and we hope this post inspires someone to come up with the next big idea.</p>
    <div>
      <h3>The case for cryptography</h3>
      <a href="#the-case-for-cryptography">
        
      </a>
    </div>
    <p>It's often said that cryptography is necessary but not sufficient for security. In other words, cryptographers make certain assumptions about the state of the system, like that a key is kept secret from the attacker, or that some computational puzzle is hard to solve. When these assumptions hold, a good cryptosystem provides a mathematical proof of security against the class of attacks it is designed to prevent.</p><p>Artifact watermarking usually has three security goals:</p><ol><li><p>Robustness: Users of the model should not be able to easily misrepresent the origin of its artifacts. The watermark should be verifiable even after the artifact is modified to some extent.</p></li><li><p>Undetectability: Watermarking should have negligible impact on the quality of the model output. In particular, watermarked artifacts should be indistinguishable from non-watermarked artifacts of the same model.</p></li><li><p>Unforgeability: It should be impossible for anyone but the model operator to produce watermarked artifacts. No one should be able to convince the model operator that an artifact was generated by the model when it wasn't.</p></li></ol><p>Today's state-of-the-art watermarks, including Google's <a href="https://deepmind.google/technologies/synthid/"><u>SynthID</u></a> and Meta's <a href="https://aidemos.meta.com/videoseal/"><u>Video Seal</u></a>, are often based on <a href="https://www.cloudflare.com/learning/ai/what-is-deep-learning/"><u>deep learning</u></a>. These schemes involve training a <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning model</a>, typically one with an encoder–decoder architecture where the encoder encodes a signature into an artifact and the decoder decodes the signature:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/wk6vE9ArPOK7EXP2otytf/f847db73272c932ba546d8a6b3176480/1.png" />
          </figure><p><sup><i>Figure 1: Illustration of the process of training an encoder-decoder watermarking model.</i></sup></p><p>The training process involves subjecting the watermarked artifact to a series of known attacks. The more attacks the model thwarts, the higher the model quality. For example, the trainer would alter the artifact in various ways and run the decoder on the outputs: the model scores high if the decoder manages to correctly output the signature most of the time.</p><p>This idea is quite beautiful. It's like a scaled up version of <a href="https://www.cloudflare.com/learning/security/glossary/what-is-penetration-testing/">penetration testing</a>, an essential practice of security engineering whereby the system is subjected to a suite of known attacks until all known vulnerabilities are patched. Of course, there will always be new attack variants or new attack strategies that the model was not trained on and that may evade the model.</p><p>And so ensues the proverbial game of cat-and-mouse that consumes so much time in security engineering. Coping with new attacks on robustness, undetectability, or unforgeability of deep-learning based watermarks requires continual intelligence gathering and re-training of deployed models to keep up with attackers.</p><p>The promise of cryptography is that it helps us break out of these kinds of cat-and-mouse games. Cryptography reduces the attack surface by focusing the attacker's attention on breaking some narrow aspect of the system that is easier to reason about. This might be gaining access to some secret key, or solving some (seemingly unrelated) computational puzzle that is believed to be impossible to solve.</p>
    <div>
      <h3>Pseudorandom codes</h3>
      <a href="#pseudorandom-codes">
        
      </a>
    </div>
    <p>To the best of our knowledge, the first cryptographic AI watermark was proposed by Scott Aaronson <a href="https://scottaaronson.blog/?p=6823"><u>in the summer of 2022 while he was working at OpenAI</u></a>. Tailored specifically for chatbots, Aaronson's simple scheme was both undetectable and unforgeable. However, it was susceptible to some simple attacks on robustness.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4XcSE2infymYTGywob2XlS/b79819f48b58c26a7c1713a89879d412/2.png" />
          </figure><p><sup><i>Figure 2: The "emoji attack": Ask the chatbot to embed a simple pattern in its response, then remove the pattern manually. This is sufficient to remove some cryptographic watermarks from the model output.</i></sup></p><p>In the year or so that followed, other cryptographic watermarks were proposed, all making different trade-offs between detectability and robustness. Two years later, in a paper that appeared at <a href="https://eprint.iacr.org/2024/235"><u>CRYPTO 2024</u></a>, Miranda Christ and Sam Gunn articulated a new framework for watermarks that, if properly instantiated, would provide all three properties simultaneously.</p><p>Along with the prompt provided by the user, generative AI models typically take as input some randomness generated by the model operator. For many such models, it is often possible to run the model "in reverse" such that, given an artifact of the model, one can recover <b>an approximation of</b> the initial randomness used to generate it. We'll see why this is important in a moment.</p><p>The starting point for Christ-Gunn-2024 is a mathematical tool called an <a href="https://en.wikipedia.org/wiki/Error_correction_code"><u>error correcting code</u></a>. These codes are normally used to transmit messages over noisy channels and are found in just about every system we rely on, including fiber optics, satellites, the data bus on your motherboard, and even quantum computers.</p><p>To transmit a message <code>m</code>, one first encodes it into a <b>codeword</b> <code>c=encode(m)</code>. Then the receiver attempts to decode the codeword as <code>decode(c)</code>. Error correcting codes are designed to tolerate some fraction of the codeword bits being flipped: if too many bits are flipped, then decoding will fail.</p><p>Now, ignoring undetectability and unforgeability for a moment, we can use an error correcting code to make a robust watermark as follows:</p><ol><li><p>Generate the initial randomness.</p></li><li><p>Embed a codeword <code>c=encode(m)</code> into the randomness in some manner, by overwriting bits of randomness with bits of <code>c</code>. The message <code>m</code> can be whatever we want, for example a short string identifying the version of our model.</p></li><li><p>Run the model with the modified randomness.</p></li></ol><p>To verify the watermark, we:</p><ol><li><p>Run the model "in reverse" on the artifact, obtaining an approximation of the initial randomness.</p></li><li><p>Extract the codeword <code>c</code><code><sup>*</sup></code> from the randomness.</p></li><li><p>If <code>decode(c</code><code><sup>*</sup></code><code>) </code>succeeds, then the watermark is present.</p></li></ol><p>Why does this work? Since c is a codeword, we can verify the watermark even if our approximation of the initial randomness isn't perfect. Some of the bits will be flipped, but the error correcting property of the code allows us to compensate for this. In fact, this is also what makes the watermark robust, since we can also tolerate bit flips caused by an attacker munging the artifact. Of course, the better our approximation of the initial randomness, the more robust our watermark will be, since we'll be able to correct for more bit flips.</p><p>To see why this watermark is detectable, notice that overwriting bits of the randomness with a fixed codeword (<code>c=encode(m)</code>) biases the randomness and thereby the output of the model. Thus, the distribution of watermarked artifacts will be slightly different from unwatermarked artifacts, perhaps even noticeably so. This watermark is also forgeable, since the encoding algorithm is public and can be run by anyone.</p><p>The challenge then is to design error-correcting codes for which codewords look random, and generating codewords requires knowledge of a secret key held by the model operator. Christ-Gunn-2024 names these <b>pseudorandom error-correcting codes</b>, or simply <b>pseudorandom codes</b>.</p><p>A pseudorandom code consists of three algorithms:</p><ul><li><p><code>k = key_gen()</code>: the key generation algorithm. Let's call <code>k</code> the <b>watermarking key</b>.</p></li><li><p><code>c = encode(k,m)</code>: the encoding algorithm takes in a message <code>m</code> and outputs a codeword <code>c</code>.</p></li><li><p><code>m = decode(k,c)</code>: the decoding algorithm takes in a codeword <code>c</code> and outputs the underlying message <code>m</code>, or an indication that decoding failed.</p></li></ul><p>The term "pseudorandom" refers to the fact that codewords aren't technically random bit strings. Intuitively, an attacker can distinguish a codeword from a random string if it manages to guess the watermarking key. Thus, our goal is to choose parameters for the code such that distinguishing codewords from random — for example, by guessing the watermarking key — is hard for any computationally bounded attacker.</p><p>To use a pseudorandom code for watermarking, the operator first generates a watermarking key <code>k</code>. Then each time it gets a prompt from a user, it generates the initial randomness, embeds <code>c=encode(k,m)</code> into the initial randomness, and runs the model. To verify the watermark, the operator runs the model in reverse to get the inverted randomness, extracts the inverted codeword, <code>c</code><code><sup>*</sup></code>, and computes <code>decode(k,c</code><code><sup>*</sup></code><code>)</code>: if decoding succeeds, then the watermark is present.</p><p>In order for this watermark to be undetectable, we need to pick an embedding of the codeword that doesn't change the distribution of the initial randomness. The details of this embedding depend on the model. Let's take a look at <a href="https://en.wikipedia.org/wiki/Stable_Diffusion"><u>Stable Diffusion</u></a> as an example.</p>
    <div>
      <h3>A watermark for Stable Diffusion</h3>
      <a href="#a-watermark-for-stable-diffusion">
        
      </a>
    </div>
    <p><a href="https://en.wikipedia.org/wiki/Stable_Diffusion"><u>Stable Diffusion</u></a> is a model used for image generation that takes as input a tensor of normally distributed floating point numbers called a <b>latent</b>. The model uses the user's prompt to "denoise" the latent tensor over a number of iterations, then converts the final version of the latent to an image.</p>
    <div>
      <h4>Approximating the initial latent</h4>
      <a href="#approximating-the-initial-latent">
        
      </a>
    </div>
    <p>Diffusion inversion is an iterative process that returns an exact or approximate initial latent by reversing the sampling process that generated an image. Inversion for text to image diffusion models is a relatively new area of research. A common application of diffusion inversion is <a href="https://arxiv.org/abs/2211.09794"><u>editing images by text prompts</u></a>.</p><p><a href="https://arxiv.org/abs/2010.02502"><u>Denoising Diffusion Implicit Models (DDIMs)</u></a> are iterative, implicit probabilistic models that can generate high quality images using a faster sampling process than other approaches, as it only requires a relatively small number of timesteps to generate a sample. This makes <a href="https://arxiv.org/abs/2211.09794"><u>DDIM Inversion</u></a> a popular inversion technique because it is computationally fast, as it requires only a few timesteps to return an approximate initial latent of a generated image. Despite its popularity, it has some known limitations and can be <a href="https://arxiv.org/abs/2312.12540v5"><u>problematic to use for tasks where exact image reproduction is required</u></a>. These limitations have led researchers to explore techniques that produce <a href="https://arxiv.org/abs/2311.18387"><u>exact initial latents</u></a>. However, since watermarks based on pseudorandom codes can tolerate errors, it's worth investigating whether DDIM Inversion suffices for our purposes.</p><p>Before we can generate an approximate initial latent, we need a generated image. To do this we use a pretrained Stable Diffusion model that uses a DDIM scheduler. The scheduler performs the “denoising” process that generates an image from a random noise seed (initial latent). By default, the pipeline computes random latents; when embedding a watermark we will generate this latent ourselves as described in the next section. The Stable Diffusion pipelines in the code snippets below sets the number of inference steps to 50. This parameter controls the number of steps the denoising process takes. 50 steps provides a nice balance between speed and image quality.</p>
            <pre><code>from stable_diffusion.utils import build_stable_diffusion_pipeline
from stable_diffusion.schedulers import ddim_scheduler

# Instantiate Stable Diffusion pipeline
model_cache_path = './model_cache'
model = 'stabilityai/stable-diffusion-2-1-base'
scheduler, _ = ddim_scheduler()
pipe, device = build_stable_diffusion_pipeline(model, model_cache_path, scheduler)

# Generate image
prompt = 'grainy photo of a UFO at night'
image, _ = pipe(prompt, num_inference_steps=50, return_dict=False)</code></pre>
            <p>To compute the approximate initial latent for the image we generated, we run the sampling process backwards. We could include the prompt, but in the case of verifying a watermark, we will usually not know the initial prompt, so we instead just set it to the empty string:</p>
            <pre><code>from PIL import Image
from stable_diffusion.utils import build_stable_diffusion_pipeline,   
                                   convert_pil_to_latents
from stable_diffusion.schedulers import ddim_inverse_scheduler

# Load image
img = Image.open(image_path)

# Instantiate Stable Diffusion pipeline with DDIM Inverse scheduler
model_cache_path = './model_cache'
model = 'stabilityai/stable-diffusion-2-1-base'
scheduler, _= ddim_inverse_scheduler()
pipe, _ = build_stable_diffusion_pipeline(model, model_cache_path, scheduler)

# Convert the input image to latent space
image_latent = convert_pil_to_latents(pipe, img)

# Invert the sampling process that generated the image with an empty prompt
inverted_latent, _ = pipe('', output_type='latent', latents=image_latent,  
                          num_inference_steps=50, return_dict=False)</code></pre>
            
    <div>
      <h4>Embedding the code</h4>
      <a href="#embedding-the-code">
        
      </a>
    </div>
    <p>The initial latent used for stable diffusion consists of a bunch of floating point numbers, each independently and <a href="https://en.wikipedia.org/wiki/Normal_distribution"><u>normally</u></a> distributed with a mean of zero.</p><p>The following observation is from a <a href="https://arxiv.org/pdf/2410.07369"><u>recent evaluation</u></a> of the watermark of Christ and Gunn for stable diffusion. (There they used a more sophisticated but expensive inversion method than DDIM.) Observe that the probability that each number is negative is equal to the probability that the number is positive. Likewise, if the code is indeed pseudorandom, then each bit of the codeword is computationally indistinguishable from a bit that is one with probability ½ and zero with probability ½.</p><p>To embed the codeword in the latent, we just set the sign of each number according to the corresponding bit of the codeword:</p>
            <pre><code>from stable_diffusion.utils import build_stable_diffusion_pipeline
from stable_diffusion.schedulers import ddim_scheduler
import numpy as np
import torch

# Generate a normally distributed latent. For the default image
# size of 512x512 pixels, the latent shape is `[1, 4, 64, 64]`.
initial_latent = np.abs(np.random.randn(*LATENTS_SHAPE))

with np.nditer(initial_latent, op_flags=['readwrite']) as it:
    	codeword = encode(k, m)
    	for (i, x) in enumerate(it):
             # `codeword[i]` is a `bool` representing the `i`-th bit of
             # the codeword.
             x *= 1 if codeword[i] else -1

watermarked_latent = torch.from_numpy(initial_latent).to(dtype=torch.float32)

# Instantiate Stable Diffusion pipeline
model_cache_path = './model_cache'
model = 'stabilityai/stable-diffusion-2-1-base'
scheduler, _ = ddim_scheduler()
pipe, _ = build_stable_diffusion_pipeline(model, model_cache_path, scheduler)

# Generate watermarked image
prompt = 'grainy photo of a UFO at night'
watermarked_image, _ = pipe(prompt, num_inference_steps=50,
                                              latents=watermarked_latent, 
                                              return_dict=False)</code></pre>
            <p>To verify this watermark, we compute the inverted latent, extract the codeword, and attempt to decode:</p>
            <pre><code>from PIL import Image
from stable_diffusion.utils import build_stable_diffusion_pipeline,   
                                   convert_pil_to_latents
from stable_diffusion.schedulers import ddim_inverse_scheduler
import numpy as np

# Load image
img = Image.open(image_path)

# Instantiate Stable Diffusion pipeline with DDIM Inverse scheduler
model_cache_path = './model_cache'
model = 'stabilityai/stable-diffusion-2-1-base'
scheduler, _ = ddim_inverse_scheduler()
pipe, _ = build_stable_diffusion_pipeline(model, model_cache_path, scheduler)

# Convert the input image to latent space
image_latent = convert_pil_to_latents(pipe, img)

# Invert the sampling process that generated the image
inverted_latent, _ = pipe('', output_type='latent', latents=image_latent,     
                         num_inference_steps=50, return_dict=False)

watermark_verified = False
with np.nditer(inverted_latent.cpu().numpy()) as it:
    inverted_codeword = []
    for x in it:
         inverted_codeword.append(x &gt; 0)

    if decode(k, inverted_codeword) == m:
         watermark_verified = True</code></pre>
            <p>This should work in theory given the error-correcting properties of the code. But does it work in practice?</p>
    <div>
      <h4>Evaluation</h4>
      <a href="#evaluation">
        
      </a>
    </div>
    <p>A good approximate initial latent is one that is very similar to the original latent that generated an image.  Given our embedding of a codeword into the latent, we define similarity as latents that have a high percentage of overlapping or matching signs.</p><p>To get a feel for this difference, we can visualize it by comparing a generated image to the same image, but with the inverted latent (these images are unwatermarked):</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ZFAAipEvnp6u79lcQrk5t/0d06e07468c05d707289a322937e9253/1.png" />
          </figure><p><sup><i>Figure 3: Image generated with prompt 'grainy photo of a UFO at night' (left) and the same image generated using the inverted latent (right).</i></sup></p><p>To evaluate how good the approximate latents are for preserving the robustness of watermarks, we randomly sampled 1,000 prompts from the <a href="https://github.com/google-research/parti?tab=readme-ov-file#partiprompts-benchmark"><u>PartiPrompts benchmark dataset</u></a>. For each of these prompts we generated initial latent and inverted latent pairs. We then computed our similarity metric for each pair. We found that on average, 82% of the signs matched for all initial latent and inverted latent pairs, and at least 75% of signs matched for 90% of the pairs.</p><p>We were pleasantly surprised with how accurate the approximation was on average. If 75% of the signs are preserved, then this gives us a decent margin for correcting for errors introduced by an attacker attempting to remove the watermark. Of course a better approximation would give us a better robustness margin. More study is required to fully understand the strengths and limitations of using DDIM Inversion for watermark decoding.</p>
    <div>
      <h3>Candidate pseudorandom codes</h3>
      <a href="#candidate-pseudorandom-codes">
        
      </a>
    </div>
    <p>Now that we have a feel for how to apply pseudorandom codes, let's take a look at how we actually build them. Although the field is barely a year old, we already have a handful of candidates.</p><p>One obvious idea to try is to compose a plain error-correcting code with some cryptographic primitive to make the code pseudorandom. For instance, we might use some standard authenticated encryption scheme, like <a href="https://datatracker.ietf.org/doc/html/rfc8452"><u>AES-GCM-SIV</u></a>, to encrypt <code>m</code>, then apply an error correcting code to the ciphertext. (The watermarking key would be the encryption key.) This "encrypt-then-encode" composition seems natural because encryption schemes are already designed so that their ciphertexts are pseudorandom. Unfortunately, error correcting codes are generally highly structured, and this structure would be betrayed by the codeword, even when applied to a (pseudo)random input.</p><p>The dual composition, "encode-then-encrypt", also doesn't work. If the ciphertext is non-malleable, as in AES-GCM-SIV, then we wouldn't be able to tolerate any number of bit flips. On the other hand, if the ciphertext were malleable, as in <a href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)"><u>AES-CTR</u></a>, then the attacker would be able to forge codewords by manipulating a known codeword in a targeted manner.</p><p>The strategy of Christ-Gunn-2024 is to modify an existing error-correcting code to make it pseudorandom.</p>
    <div>
      <h4>Pseudorandom LDPC codes</h4>
      <a href="#pseudorandom-ldpc-codes">
        
      </a>
    </div>
    <p>Their starting point is the widely used <a href="https://en.wikipedia.org/wiki/Low-density_parity-check_code"><u>Low-Density Parity-Check (LDPC) code</u></a>. This code is defined by a <b>parity check</b> matrix <code>P</code> with and a corresponding <b>generator</b> matrix <code>G</code>. The parity check matrix has bit entries and might look something like this:</p>
            <pre><code>import numpy as np
P = np.matrix([[1, 0, 1],
               [0, 0, 1],
               [0, 1, 1],
               [1, 1, 1],
               [1, 0, 0],
               [0, 1, 0]])</code></pre>
            <p>This matrix is used to check if a given bit string is a codeword. By definition, a codeword is any bit string c for which the weight of <code>P*c</code> (the number ones in the output of <code>P*c</code>) is small. (Note that arithmetic is modulo <code>2</code> here.) The generator matrix <code>G</code> is constructed from <code>P </code>so that it can be used as the encoder. In particular, for any bit string <code>m</code>, <code>c=G*m </code>is a codeword. The performance of this code depends in large part on the sparsity of the parity check matrix: roughly speaking, the more zero entries the matrix has, the more the bit flips the code can tolerate.</p><p>The main idea of Christ-Gunn-2024 is to tune the parameters of the LDPC code (the dimensions of the parity check matrix and its density) so that when the parity-check matrix <code>P</code> is chosen at random, the generator matrix <code>G</code> is pseudorandom. This means that, intuitively, when we encode a random input <code>m</code> as <code>c=G*m</code>, the codeword <code>c</code> is also pseudorandom. (There is a bit more that goes into constructing the input <code>m</code>, but this is roughly the idea.)</p><p>It's easy to see that a watermark based on this construction is robust, as it follows immediately from the capacity of LDPC to tolerate bit flips. Ensuring the watermark remains undetectable is more delicate, as it relies on relatively strong and understudied computational assumptions. As a result, it's not clear today for what parameter ranges this scheme is concretely secure. (There has been some progress here: <a href="https://eprint.iacr.org/2024/1425"><u>a recent preprint</u></a> by Surendra Ghentiyala and Venkatesan Guruswami showed that the pseudorandomness of Christ-Gunn-2024 can be proved with slightly weaker assumptions.)</p><p>To get a feel for how things might go wrong, consider what happens if the attacker manages to guess one of the rows of the parity check matrix<code> P</code>. When we take the dot product of this row with a codeword, then the output will be 0 with high probability. (By definition, <code>c</code> is a codeword if the sum of the dot products of <code>c </code>with each row of <code>P</code> is small.) But if we take the dot product of this row with a random bit string, then we should expect to see 0 with probability roughly ½. This gives us a way of distinguishing codewords from random bit strings.</p><p>Guessing a row of <code>P</code> is easy if the matrix is too sparse. In the extreme case, if each row has only one bit set, then there are only <code>n</code> possible values for that row, where <code>n</code> is the number of columns of <code>P</code>. On the other hand, making <code>P</code> too dense will degrade the code's ability to detect bit flips.</p><p>Similarly, it may be easy to guess a row of <code>P</code> if the length of the codeword itself (<code>n</code>) is too small. Thus, in order for this code to be pseudorandom, it is necessary (but not sufficient) for the number of possible parity check matrices to be so large that exhaustively searching for <code>P</code> is not feasible. This can be done by increasing the size of the codeword or tolerating fewer bit flips.</p>
    <div>
      <h4>Pseudorandom codes from PRFs</h4>
      <a href="#pseudorandom-codes-from-prfs">
        
      </a>
    </div>
    <p>Another approach to constructing pseudorandom codes comes from <a href="https://eprint.iacr.org/2024/898"><u>a 2024 preprint</u></a> from Noah Golowich and Ankur Moitra. Their starting point is a common cryptographic primitive called a pseudorandom function (PRF). They require a PRF that takes as input a key <code>k</code>, a bit string <code>x</code> of length <code>m</code> and outputs a bit, denoted <code>F(k,m)</code>.</p><p>Suppose our codewords are <code>x</code><code><sub>1</sub></code>, ⁣<code>w</code><code><sub>1</sub></code><code>=F(k,x</code><code><sub>1</sub></code><code>)</code>, …,<code> x</code><code><sub>n</sub></code>,<code> w</code><code><sub>n</sub></code><code>=F(k,x</code><code><sub>n</sub></code><code>) </code>where <code>x</code><code><sub>1</sub></code>, …, <code>x</code><code><sub>n</sub></code> are random <code>m</code>-bit strings. (Notice that the codeword length is <code>(m+1)*n</code>.) To verify if a string is a codeword, we parse the codeword into <code>x</code><code><sub>1</sub></code>, <code>w</code><code><sub>1</sub></code>, …, <code>x</code><code><sub>n</sub></code>, <code>w</code><code><sub>n</sub></code><code> </code>and check if <code>w</code><code><sub>i</sub></code><code> = F(k,x</code><code><sub>i</sub></code><code>)</code> for all <code>i</code>. If the number of checks that pass is sufficiently high, then the string is likely a codeword.</p><p>It's easy to see that this code is pseudorandom if the output of <code>F</code> is pseudorandom. However, it's not very robust: to make the <code>i</code>-th check fail, we just need to flip a single bit, <code>w</code><code><sub>i</sub></code>. The attacker just needs to flip a sufficient number of these bits to cause verification to fail. To defeat this attack, the encoder permutes the bits of the codeword with a secret, random permutation. That way the attacker has to guess the position of a sufficient number of <code>w</code><code><sub>i</sub></code>s in the permuted bit string. (A bit more is required to make this scheme provably robust, but this is the idea.)</p><p>Note that the number of bit flips we can tolerate with this scheme depends significantly on the number of PRF checks. This in turn determines the length of the codeword, so we may only get a reasonable degree of robustness for longer codewords. Note that we can increase the number of PRF checks by decreasing the length <code>m</code> of the <code>x</code><code><sub>i</sub></code>s, but making these strings too short is detrimental for pseudorandomness. (What happens if we happen to randomly pick <code>x</code><code><sub>i</sub></code><code>==x</code><code><sub>j</sub></code><code> </code>for <code>i!=j</code>?)</p>
    <div>
      <h4>Are these schemes practical?</h4>
      <a href="#are-these-schemes-practical">
        
      </a>
    </div>
    <p>In our own experiments with Stable Diffusion, we were able to tune the LDPC code to tolerate up to 33% of the codeword bits being mangled, which is likely more than sufficient for robustness in practice. However, achieving this required making the parity check matrix so sparse that the code is not strongly pseudorandom. Thus, the resulting watermark cannot be considered cryptographically undetectable. Among the parameter sets for which the code is plausibly pseudorandom, we didn't find any for which the code tolerates more than 5% bit flips.</p><p>Our findings were similar for the PRF-based code: with plausibly pseudorandom parameters, we couldn't tune the code to tolerate more than 1% bit flips. Like the LDPC code, we can crank this higher by sacrificing pseudorandomness, but we weren't able to crack 5% with any parameters we tried.</p><p>There are a few ways to think about this.</p><p>First, for both codes, robustness improves as the codeword gets larger. In particular, if the latent space for Stable Diffusion were larger, then we'd expect to be able to tolerate more bit flips. In general, cryptographic watermarks of all kinds perform better when there is more randomness to work with. For example, short responses produced by chatbots are especially hard for any watermarking strategy, including pseudorandom codes.</p><p>Another takeaway is that we need a better approximation of the initial latent than provided by DDIM. Indeed, <a href="https://arxiv.org/abs/2410.07369"><u>in their own evaluation</u></a> of the LDPC-based code, Sam Gunn, Xuandong Zhao, and Dawn Song chose a much more sophisticated inversion method, which exhibited better results, albeit at a higher computational cost.</p><p>A third view is that, as a practical matter, cryptographic undetectability might not be all that important for some applications. For instance, we might decide the watermark is good enough on the basis of statistical tests to check for biases within, or correlations across, codewords. Of course, such tests can't rule out the possibility of perceptible differences between watermarked and unwatermarked artifacts.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7BVEy8oI4HZUU6u7zUgW9G/20c48669c252dfe99a689dd0860a54a7/2.png" />
          </figure><p><sup><i>Figure 4: Images with verified LDPC watermarks generated with prompt 'grainy photo of a UFO at night'.</i></sup></p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>The sign of a good abstraction boundary is that it allows folks to collaborate across disciplines. With pseudorandom codes, it seems like we've landed on the right abstraction for AI watermarking: it's up to cryptography experts to figure out how to instantiate them; and it's up to AI/ML experts to figure out how to embed them in their applications. We believe this separation of concerns has the potential to make watermarking easier to deploy, especially for operators like Cloudflare's <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Workers AI</u></a>, who don't train and maintain the models themselves.</p><p>After spending a few weeks playing around with this stuff, we're excited by the potential of pseudorandom codes to make strong watermarks for generative AI. However, we feel it will take some time for this field to yield practical schemes.</p><p>Existing candidates will require further study to determine the parameter ranges for which they provide good security. It is also worthwhile to investigate new approaches to building pseudorandom codes, perhaps starting with some other error correcting code besides LDPC. We should also examine what is even theoretically possible in this space: perhaps there is a fundamental tension between detectability and robustness that can't be resolved for some parameter regimes.</p><p>It's also going to be important for watermarks based on pseudorandom codes to be publicly verifiable, as some other cryptographic watermarks are. Concretely, the LDPC code is sort of analogous to public key encryption, where the ciphertext corresponds to a codeword. It might be possible to flip this paradigm around and make a digital signature where the signature is a codeword. Of course, this only works when the weights of the model are also publicly available.</p><p>On the AI/ML side, we need to look closer at methods of approximating the initial randomness for different types of models. This blog looked at what is perhaps the simplest possible method for Stable Diffusion, and while this seems to work pretty well, it's obvious that we can do a lot better. It's just a matter of keeping costs low. A good rule of thumb might be that verifying the watermark should not be more expensive than watermarked inference.</p><p>Pseudorandom codes may also have applications beyond watermarking. When we circulated this blog post internally, an idea that came up a lot was to somehow apply this technology to non-AI content, to embed in the content its provenance. Indeed, this is the idea behind the <a href="https://blog.cloudflare.com/preserve-content-credentials-with-cloudflare-images/"><u>C2PA integration</u></a>. Pseudorandom codes aren't immediately applicable, but may be in the future. Wherever you have a source of randomness in the process of generating some artifact, like digital photography, you can embed in that randomness a codeword.</p><p>Thanks for reading! We hope we've managed to pique your interest in this field. We certainly will be following along. If you'd like to play with the code we used to produce the numbers in this blog, or just make some cool watermarked AI content, you can find our demo on <a href="https://github.com/cloudflareresearch/poc-watermark"><u>GitHub</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">VxbhII1JF1Bnb4w9D1kEQ</guid>
            <dc:creator>Teresa Brooks-Mejia</dc:creator>
            <dc:creator>Christopher Patton</dc:creator>
        </item>
        <item>
            <title><![CDATA[Conventional cryptography is under threat. Upgrade to post-quantum cryptography with Cloudflare Zero Trust]]></title>
            <link>https://blog.cloudflare.com/post-quantum-zero-trust/</link>
            <pubDate>Mon, 17 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ We’re thrilled to announce that organizations can now protect their sensitive corporate network traffic against quantum threats by tunneling it through Cloudflare’s Zero Trust platform. ]]></description>
            <content:encoded><![CDATA[ <p>Quantum computers are actively being developed that will eventually have the ability to break the cryptography we rely on for securing modern communications. Recent <a href="https://blog.google/technology/research/google-willow-quantum-chip/"><u>breakthroughs</u></a> in quantum computing have underscored the vulnerability of conventional cryptography to these attacks. Since 2017, Cloudflare has <a href="https://blog.cloudflare.com/tag/post-quantum/"><u>been at the forefront</u></a> of developing, standardizing, and implementing <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/"><u>post-quantum cryptography</u></a> to withstand attacks by quantum computers. </p><p>Our mission is simple: we want every Cloudflare customer to have a clear path to quantum safety. Cloudflare recognizes the urgency, so we’re committed to managing the complex process of upgrading cryptographic algorithms, so that you don’t have to worry about it. We're not just talking about doing it. <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>Over 35% of the non-bot HTTPS traffic that touches Cloudflare today is post-quantum secure.</u></a> </p><p>The <a href="https://www.nist.gov/"><u>National Institute of Standards and Technology (NIST)</u></a> also recognizes the urgency of this transition. On November 15, 2024, NIST made a landmark <a href="https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf"><u>announcement</u></a> by setting a timeline to phase out <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)"><u>RSA</u></a> and <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>Elliptic Curve Cryptography (ECC)</u></a>, the conventional cryptographic algorithms that underpin nearly every part of the Internet today. According to NIST’s announcement, these algorithms will be deprecated by 2030 and completely disallowed by 2035.</p><p>At Cloudflare, we aren’t waiting until 2035 or even 2030. We believe privacy is a fundamental human right, and advanced cryptography should be <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free/"><u>accessible to everyone</u></a> without compromise. No one should be required to pay extra for post-quantum security. That’s why any visitor accessing a <a href="https://blog.cloudflare.com/pq-2024/"><u>website protected by Cloudflare today</u></a> benefits from post-quantum cryptography, when using a major browser like <a href="https://blog.chromium.org/2024/05/advancing-our-amazing-bet-on-asymmetric.html"><u>Chrome, Edge</u></a>, or <a href="https://www.mozilla.org/en-US/firefox/135.0/releasenotes/"><u>Firefox</u></a>. (And, we are excited to see a <a href="https://radar.cloudflare.com/explorer?dataSet=http&amp;groupBy=post_quantum&amp;filters=botClass%253DLikely_Human%252Cos%253DiOS"><u>small percentage of (mobile) Safari traffic</u></a> in our Radar data.) Well over a third of the human traffic passing through Cloudflare today already enjoys this enhanced security, and we expect this share to increase as more browsers and clients are upgraded to support post-quantum cryptography. </p><p>While great strides have been made to protect human web traffic, not every application is a web application. And every organization has internal applications (both web and otherwise) that do not support post-quantum cryptography.  </p><p>How should organizations go about upgrading their sensitive corporate network traffic to support post-quantum cryptography?</p><p>That’s where today’s announcement comes in. We’re thrilled to announce the first phase of end-to-end quantum readiness of our <a href="https://www.cloudflare.com/zero-trust/">Zero Trust platform</a><b>, </b>allowing customers to protect their corporate network traffic with post-quantum cryptography.<b> Organizations can tunnel their corporate network traffic though Cloudflare’s Zero Trust platform, protecting it against quantum adversaries without the hassle of individually upgrading each and every corporate application, system, or network connection.</b> </p><p>More specifically, organizations can use our Zero Trust platform to route communications from end-user devices (via web browser or Cloudflare’s <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/"><u>WARP device client</u></a>) to secure applications connected with <a href="https://blog.cloudflare.com/post-quantum-tunnel/"><u>Cloudflare Tunnel</u></a>, to gain end-to-end quantum safety, in the following use cases: </p><ul><li><p><b>Cloudflare’s clientless </b><a href="https://developers.cloudflare.com/cloudflare-one/policies/access/"><b><u>Access</u></b></a><b>: </b>Our clientless <a href="https://www.cloudflare.com/learning/access-management/what-is-ztna/">Zero Trust Network Access (ZTNA)</a> solution verifies user identity and device context for every HTTPS request to corporate applications from a web browser. Clientless Access is now protected end-to-end with post-quantum cryptography.</p></li><li><p><b>Cloudflare’s </b><a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/"><b><u>WARP device client</u></b></a><b>:</b> By mid-2025, customers using the WARP device client will have all of their traffic (regardless of protocol) tunneled over a connection protected by post-quantum cryptography. The WARP client secures corporate devices by privately routing their traffic to Cloudflare's global network, where Gateway applies advanced web filtering and Access enforces policies for secure access to applications. </p></li><li><p><b>Cloudflare </b><a href="https://developers.cloudflare.com/cloudflare-one/policies/gateway/http-policies/"><b><u>Gateway</u></b></a>: Our <a href="https://www.cloudflare.com/learning/access-management/what-is-a-secure-web-gateway/">Secure Web Gateway (SWG) </a>— designed to inspect and filter TLS traffic in order to block threats and unauthorized communications — now supports TLS with post-quantum cryptography. </p></li></ul><p>In the remaining sections of this post, we’ll explore the threat that quantum computing poses and the challenges organizations face in transitioning to post-quantum cryptography. We’ll also dive into the technical details of how our Zero Trust platform supports post-quantum cryptography today and share some plans for the future.</p>
    <div>
      <h3>Why transition to post-quantum cryptography and why now? </h3>
      <a href="#why-transition-to-post-quantum-cryptography-and-why-now">
        
      </a>
    </div>
    <p>There are two key reasons to adopt post-quantum cryptography now:</p>
    <div>
      <h4>1. The challenge of deprecating cryptography</h4>
      <a href="#1-the-challenge-of-deprecating-cryptography">
        
      </a>
    </div>
    <p>History shows that updating or removing outdated cryptographic algorithms from live systems is extremely difficult. For example, although the MD5 hash function was <a href="https://iacr.org/archive/eurocrypt2005/34940019/34940019.pdf"><u>deemed insecure in 2004</u></a> and long since deprecated, it was still in use with the RADIUS enterprise authentication protocol as recently as 2024. In July 2024, Cloudflare contributed to research revealing an <a href="https://blog.cloudflare.com/radius-udp-vulnerable-md5-attack/"><u>attack on RADIUS</u></a> that exploited its reliance on MD5. This example underscores the enormous challenge of updating legacy systems — this difficulty in achieving <a href="https://en.wikipedia.org/wiki/Cryptographic_agility"><i><u>crypto-agility</u></i></a> — which will be just as demanding when it’s time to transition to post-quantum cryptography. So it makes sense to start this process now.</p>
    <div>
      <h4>2. The “harvest now, decrypt later” threat</h4>
      <a href="#2-the-harvest-now-decrypt-later-threat">
        
      </a>
    </div>
    <p>Even though quantum computers lack enough qubits to break conventional cryptography today, adversaries can harvest and store encrypted communications or steal datasets with the intent of decrypting them once quantum technology matures. If your encrypted data today could become a liability in 10 to 15 years, planning for a post-quantum future is essential. For this reason, we have already started working with some of the most innovative <a href="https://www.cloudflare.com/banking-and-financial-services/">banks</a>, ISPs, and <a href="https://www.cloudflare.com/public-sector/">governments</a> around the world as they begin their journeys to quantum safety. </p><p>The U.S. government is already addressing these risks. On January 16, 2025, the White House issued <a href="https://www.federalregister.gov/documents/2025/01/17/2025-01470/strengthening-and-promoting-innovation-in-the-nations-cybersecurity"><u>Executive Order 14144</u></a> on Strengthening and Promoting Innovation in the Nation’s Cybersecurity. This order requires government agencies to “<i>regularly update a list of product categories in which products that support post-quantum cryptography (PQC) are widely available…. Within 90 days of a product category being placed on the list … agencies shall take steps to include in any solicitations for products in that category a requirement that products support PQC.</i>”</p><p>At Cloudflare, we’ve been <a href="https://blog.cloudflare.com/the-tls-post-quantum-experiment/"><u>researching</u></a>, <a href="https://blog.cloudflare.com/securing-the-post-quantum-world/"><u>developing</u></a>, and <a href="https://www.ietf.org/archive/id/draft-kwiatkowski-tls-ecdhe-mlkem-02.html"><u>standardizing</u></a> post-quantum cryptography <a href="https://blog.cloudflare.com/tag/post-quantum/"><u>since 2017</u></a>. Our strategy is simple:</p><p><b>Simply tunnel your traffic through Cloudflare’s quantum-safe connections to immediately protect against harvest-now-decrypt-later attacks, without the burden of upgrading every cryptographic library yourself.</b></p><p>Let’s take a closer look at how the migration to post-quantum cryptography is taking shape at Cloudflare.</p>
    <div>
      <h3>A two-phase migration to post-quantum cryptography</h3>
      <a href="#a-two-phase-migration-to-post-quantum-cryptography">
        
      </a>
    </div>
    <p>At Cloudflare, we’ve largely focused on migrating the <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS (Transport Layer Security) 1.3</u></a> protocol to post-quantum cryptography.   TLS primarily secures the communications for web applications, but it is also widely used to secure email, messaging, <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>VPN connections</u></a>, <a href="https://www.cloudflare.com/learning/dns/dns-over-tls/"><u>DNS</u></a>, and many other protocols.  This makes TLS an ideal protocol to focus on when migrating to post-quantum cryptography.</p><p>The migration involves updating two critical components of TLS 1.3: <a href="https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/"><u>digital signatures used in certificates</u></a> and <a href="https://blog.cloudflare.com/post-quantum-key-encapsulation/"><u>key agreement mechanisms</u></a>. We’ve made significant progress on key agreement, but the migration to post-quantum digital signatures is still in its early stages.</p>
    <div>
      <h4>Phase 1: Migrating key agreement</h4>
      <a href="#phase-1-migrating-key-agreement">
        
      </a>
    </div>
    <p>Key agreement protocols enable two parties to securely establish a shared secret key that they can use to secure and encrypt their communications. Today, vendors have largely converged on transitioning TLS 1.3 to support a post-quantum key exchange protocol known as <a href="https://blog.cloudflare.com/nists-first-post-quantum-standards/"><u>ML-KEM</u></a> (Module-lattice based Key-Encapsulation Mechanism Standard). There are two main reasons for prioritizing migration of key agreement:</p><ul><li><p><b>Performance:</b> ML-KEM <a href="https://blog.cloudflare.com/pq-2024/"><u>performs</u></a> well with the <a href="https://www.cloudflare.com/learning/ssl/why-use-tls-1.3/">TLS 1.3 protocol,</a> even for short-lived network connections.</p></li><li><p><b>Security</b>: Conventional cryptography is vulnerable to “harvest now, decrypt later” attacks. In this threat model, an adversary intercepts and stores encrypted communications today and later (in the future) uses a quantum computer to derive the secret key, compromising the communication. As of March 2025, well over a third of the human web traffic reaching the Cloudflare network is protected against these attacks by TLS 1.3 with hybrid ML-KEM key exchange.</p></li></ul>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1Tgfy0HYHA5MM6JjaNP2Z1/b601d2938be3c52decf1f3cec7313c6e/image6.png" />
          </figure><p><sup><i>Post-quantum encrypted share of human HTTPS request traffic seen by Cloudflare per </i></sup><a href="https://radar.cloudflare.com/adoption-and-usage?dateRange=52w"><sup><i><u>Cloudflare Radar</u></i></sup></a><sup><i> from March 1, 2024 to March 1, 2025. (Captured on March 13, 2025.)</i></sup></p><p>Here’s how to check if your Chrome browser is using ML-KEM for key agreement when visiting a website: First, <a href="https://developer.chrome.com/docs/devtools/inspect-mode#:~:text=Open%20DevTools,The%20element's%20margin%2C%20in%20pixels."><u>Inspect the page</u></a>, then open the <a href="https://developer.chrome.com/docs/devtools/security"><u>Security tab</u></a>, and finally look for <a href="https://www.ietf.org/archive/id/draft-kwiatkowski-tls-ecdhe-mlkem-02.html"><u>X25519MLKEM768</u></a> as shown here:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6EoD5jFMXJeWFeRtG9w6Uy/85aa13123d64f21ea93313f674d4378f/image1.png" />
          </figure><p>This indicates that your browser is using key-agreement protocol ML-KEM <i>in combination with</i> conventional <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>elliptic curve cryptography</u></a> on curve <a href="https://en.wikipedia.org/wiki/Curve25519"><u>X25519</u></a>. This provides the protection of the tried-and-true conventional cryptography (<a href="https://en.wikipedia.org/wiki/Curve25519"><u>X25519</u></a>) alongside the new post-quantum key agreement (<a href="https://blog.cloudflare.com/nists-first-post-quantum-standards/"><u>ML-KEM</u></a>).</p>
    <div>
      <h4>Phase 2: Migrating digital signatures</h4>
      <a href="#phase-2-migrating-digital-signatures">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/"><u>Digital signatures are used in TLS certificates</u></a> to validate the authenticity of connections — allowing the client to be sure that it is really communicating with the server, and not with an adversary that is impersonating the server. </p><p>Post-quantum digital signatures, however, are significantly larger, and thus slower, than their current counterparts. This performance impact has slowed their adoption, particularly because they slow down short-lived TLS connections. </p><p>Fortunately, post-quantum signatures are not needed to prevent harvest-now-decrypt-later attacks. Instead, they primarily protect against attacks by an adversary that is actively using a quantum computer to tamper with a live TLS connection. We still have some time before quantum computers are able to do this, making the migration of digital signatures a lower priority.</p><p>Nevertheless, Cloudflare is actively <a href="https://datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates/07/"><u>involved in standardizing</u></a> post-quantum signatures for TLS certificates. We are also experimenting with their deployment on long-lived TLS connections and exploring <a href="https://datatracker.ietf.org/doc/draft-davidben-tls-merkle-tree-certs/"><u>new approaches</u></a> to achieve post-quantum authentication without sacrificing performance. Our goal is to ensure that post-quantum digital signatures are ready for widespread use when quantum computers are able to actively attack live TLS connections.</p>
    <div>
      <h3>Cloudflare Zero Trust + PQC: future-proofing security</h3>
      <a href="#cloudflare-zero-trust-pqc-future-proofing-security">
        
      </a>
    </div>
    <p>The Cloudflare Zero Trust platform replaces legacy corporate security perimeters with Cloudflare's global network, making access to the Internet and to corporate resources faster and safer for teams around the world. Today, we’re thrilled to announce that Cloudflare's Zero Trust platform protects your data from quantum threats as it travels over the public Internet.  There are three key quantum-safe use cases supported by our Zero Trust platform in this first phase of quantum readiness.</p>
    <div>
      <h4>Quantum-safe clientless Access</h4>
      <a href="#quantum-safe-clientless-access">
        
      </a>
    </div>
    <p><a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/agentless/"><u>Clientless</u></a> <a href="https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-public-app/"><u>Cloudflare Access</u></a> now protects an organization’s Internet traffic to internal web applications against quantum threats, even if the applications themselves have not yet migrated to post-quantum cryptography. ("Clientless access" is a method of accessing network resources without installing a dedicated client application on the user's device. Instead, users connect and access information through a web browser.)</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5mKiboLMsIEuNt1MaXlWsy/dad0956066e97db69401757b18e8ce5f/image4.png" />
          </figure><p>Here’s how it works today:</p><ul><li><p><b>PQ connection via browser: </b>(Labeled (1) in the figure.)
As long as the user's web browser supports post-quantum key agreement, the connection from the device to Cloudflare's network is secured via TLS 1.3 with post-quantum key agreement.</p></li><li><p><b>PQ within Cloudflare’s global network: </b>(Labeled (2) in the figure) 
If the user and origin server are geographically distant, then the user’s traffic will enter Cloudflare’s global network in one geographic location (e.g. Frankfurt), and exit at another (e.g. San Francisco).  As this traffic moves from one datacenter to another inside Cloudflare’s global network, these hops through the network are secured via TLS 1.3 with post-quantum key agreement.<b> </b></p></li><li><p><b>PQ Cloudflare Tunnel: </b>(Labeled (3) in the figure)
Customers establish a Cloudflare Tunnel from their datacenter or public cloud — where their corporate web application is hosted — to Cloudflare's network. This tunnel is secured using TLS 1.3 with post-quantum key agreement, safeguarding it from harvest-now-decrypt-later attacks.</p></li></ul><p>Putting it together, clientless Access provides <b>end-to-end</b> quantum safety for accessing corporate HTTPS applications, without requiring customers to upgrade the security of corporate web applications.</p>
    <div>
      <h4>Quantum-safe Zero Trust with Cloudflare’s WARP Client-to-Tunnel configuration (as a VPN replacement)</h4>
      <a href="#quantum-safe-zero-trust-with-cloudflares-warp-client-to-tunnel-configuration-as-a-vpn-replacement">
        
      </a>
    </div>
    <p>By mid-2025, organizations will be able to protect <b>any protocol</b>, not just HTTPS, by tunneling it through Cloudflare's Zero Trust platform with post quantum cryptography, thus providing quantum safety as traffic travels across the Internet from the end-user’s device to the corporate office/data center/cloud environment.</p><p>Cloudflare’s Zero Trust platform is ideal for replacing traditional VPNs, and enabling <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/"><u>Zero Trust architectures</u></a> with modern authentication and authorization polices.  Cloudflare’s WARP client-to-tunnel is a popular network configuration for our Zero Trust platform: organizations deploy Cloudflare’s <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/"><u>WARP device client</u></a> on their end users’ devices, and then use <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Cloudflare Tunnel</u></a> to connect to their corporate office, cloud, or data center environments.   </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5xovIIyVOO32xrXBs0ZFcf/110928926b86f12777f16518b1313875/image3.png" />
          </figure><p> Here are the details:  </p><ul><li><p><b>PQ connection via WARP client (coming in mid-2025): </b>(Labeled (1) in the figure)
The WARP client uses the <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>MASQUE protocol</u></a> to connect from the device to Cloudflare’s global network. We are working to add support for establishing this MASQUE connection with TLS 1.3 with post-quantum key agreement, with a target completion date of mid-2025.  </p></li><li><p><b>PQ within Cloudflare’s global network:  </b>(Labeled (2) in the figure) 
As traffic moves from one datacenter to another inside Cloudflare’s global network, each hop it takes through Cloudflare’s network is already secured with TLS 1.3 with post-quantum key agreement.</p></li><li><p><b>PQ Cloudflare Tunnel: </b>(Labeled (3) in the figure)
As mentioned above, <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Cloudflare Tunnel</u></a> already supports post-quantum key agreement. </p></li></ul><p>Once the upcoming post-quantum enhancements to the WARP device client are complete, customers can encapsulate their traffic in quantum-safe tunnels, effectively mitigating the risk of harvest-now-decrypt-later attacks without any heavy lifting to individually upgrade their networks or applications.  And this provides comprehensive protection for any protocol that can be sent through these tunnels, not just for HTTPS!</p>
    <div>
      <h4>Quantum-safe SWG (end-to-end PQC for access to third-party web applications)</h4>
      <a href="#quantum-safe-swg-end-to-end-pqc-for-access-to-third-party-web-applications">
        
      </a>
    </div>
    <p>A <a href="https://developers.cloudflare.com/cloudflare-one/policies/gateway/http-policies/"><u>Secure Web Gateway</u></a> (SWG) is used to secure access to third-party websites on the public Internet by intercepting and inspecting TLS traffic. </p><p>Cloudflare Gateway is now a quantum-safe SWG for HTTPS traffic. As long as the third-party website that is being inspected supports post-quantum key agreement, then Cloudflare’s SWG also supports post-quantum key agreement. This holds regardless of the onramp that the customer uses to get to Cloudflare's network (i.e. <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/agentless/"><u>web browser</u></a>, <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/"><u>WARP device client</u></a>, <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/warp-connector/"><u>WARP Connector</u></a>, <a href="https://developers.cloudflare.com/magic-wan/"><u>Magic WAN</u></a>), and only requires the use of a browser that supports post-quantum key agreement.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6vnkEFkvKbhSAxp33GmRk7/c58d00a14767a03b2422af1c48a53ba9/image5.png" />
          </figure><p>Cloudflare Gateway's HTTPS SWG feature involves two post-quantum TLS connections, as follows:</p><ul><li><p><b>PQ connection via browser: </b>(Labeled (1) in the figure)  
A TLS connection is initiated from the user's browser to a data center in Cloudflare's network that performs the TLS inspection. As long as the user's web browser supports post-quantum key agreement, this connection is secured by TLS 1.3 with post-quantum key agreement.  </p></li><li><p><b>PQ connection to the origin server: </b>(Labeled (2) in the figure)  
A TLS connection is initiated from a datacenter in Cloudflare's network to the origin server, which is typically controlled by a third party. The connection from Cloudflare’s SWG currently supports post-quantum key agreement, as long as the third party’s origin server also already supports post-quantum key agreement.  You can test this out today by using <a href="https://pq.cloudflareresearch.com/"><u>https://pq.cloudflareresearch.com/</u></a> as your third-party origin server. </p></li></ul><p>Put together, Cloudflare’s SWG is quantum-ready to support secure access to any third-party website that is quantum ready today or in the future. And this is true regardless of the onramp used to get end users' traffic into Cloudflare's global network!</p>
    <div>
      <h3>The post-quantum future: Cloudflare’s Zero Trust platform leads the way</h3>
      <a href="#the-post-quantum-future-cloudflares-zero-trust-platform-leads-the-way">
        
      </a>
    </div>
    <p>Protecting our customers from emerging quantum threats isn't just a priority — it's our responsibility. Since 2017, Cloudflare has been pioneering post-quantum cryptography through research, standardization, and strategic implementation across our product ecosystem.</p><p><b>Today marks a milestone: </b>We're launching the first phase of quantum-safe protection for our Zero Trust platform. Quantum-safe clientless Access and Secure Web Gateway are available immediately, with WARP client-to-tunnel network configurations coming by mid-2025. As we continue to advance the state of the art in post-quantum cryptography, our commitment to continuous innovation ensures that your organization stays ahead of tomorrow's threats.  Let us worry about crypto-agility so that you don’t have to.</p><p>To learn more about how Cloudflare’s built-in crypto-agility can future-proof your business, visit our <a href="http://cloudflare.com/pqc"><u>Post-Quantum Cryptography</u></a> webpage.</p>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Cloudflare Gateway]]></category>
            <category><![CDATA[Cloudflare Access]]></category>
            <category><![CDATA[Clientless]]></category>
            <category><![CDATA[Cloudflare Tunnel]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">18HFPrh07hn9Zqp8kaonRp</guid>
            <dc:creator>Sharon Goldberg</dc:creator>
            <dc:creator>Wesley Evans</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
            <dc:creator>John Engates</dc:creator>
        </item>
        <item>
            <title><![CDATA[Chaos in Cloudflare’s Lisbon office: securing the Internet with wave motion]]></title>
            <link>https://blog.cloudflare.com/chaos-in-cloudflare-lisbon-office-securing-the-internet-with-wave-motion/</link>
            <pubDate>Mon, 17 Mar 2025 12:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is now using a wall of waves in our Lisbon, Portugal office to create entropy and strengthen Internet security, turning liquid chaos into secure, unpredictable encryption. ]]></description>
            <content:encoded><![CDATA[ <p>Over the years, Cloudflare has gained fame for many things, including our technical blog, but also as <a href="https://www.wired.com/story/cloudflare-lava-lamps-protect-from-hackers/"><u>a tech company securing the Internet using </u><b><u>lava lamps</u></b></a>, a story that began as a research/science project almost 10 years ago. In March 2025, we added another layer to its legacy: a "wall of entropy" made of 50 <b>wave machines </b>in constant motion at our Lisbon office, the company's European HQ. </p><p>These wave machines are a new source of entropy, joining <b>lava lamps</b> in San Francisco, <b>suspended rainbows</b> in Austin, and <b>double chaotic pendulums </b>in London. The entropy they generate contributes to securing the Internet <a href="#lavarand-origins-and-walls-of-entropy"><u>through LavaRand</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6sp4ZXYnpwUGAabVB0fRKW/f56edd916efeb49173c623e99b87bc70/DSC00336.JPG" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1D1cayhBpPyuUNKV4JCcvF/e6d493a71e41c3622dd4f895505a3f43/DSC00450.JPG" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/EE2gOFRrXCGM5ASh3uCl7/b282e0ed651cb5c354b183bc33aff116/image4.jpg" />
          </figure><p><sup><i>The new waves wall at Cloudflare’s Lisbon office sits beside the Radar Display of global Internet insights, with the 25th of April Bridge overlooking the Tagus River in the background.</i></sup></p><p>It’s exciting to see waves in Portugal now playing a role in keeping the Internet secure, especially given Portugal’s deep maritime history.</p><p>The installation honors Portugal’s passion for the sea and exploration of the unknown, famously beginning over 600 years ago, in 1415, with pioneering vessels like <a href="https://en.wikipedia.org/wiki/Caravel"><u>caravels</u></a> and naus/carracks, precursors to galleons and other ships. Portuguese sea exploration was driven by navigation schools and historic voyages <i>“through seas never sailed before”</i> (<i>“Por mares nunca dantes navegados” </i>in Portuguese), as described by Portugal’s famous poet, Luís Vaz de Camões, born 500 years ago (1524).</p><p>Anyone familiar with Portugal knows the <a href="https://en.wikipedia.org/wiki/History_of_Portugal#Naval_exploration_and_Portuguese_Empire_(15th%E2%80%9316th_centuries)"><u>sea is central</u></a> to its identity. The small country has 980 km of coastline, where most of its main cities are located. Maritime areas make up 90% of its territory, including the mid-Atlantic Azores. In 1998, Lisbon’s <a href="https://en.wikipedia.org/wiki/Expo_%2798"><u>Expo 98</u></a> celebrated the oceans and this maritime heritage. Since 2011, the small town of Nazaré also became globally <a href="https://allwaves.surf/waves-explained-nazare/"><u>famous among the surfing community</u></a> for its <a href="https://earthobservatory.nasa.gov/images/149486/monster-waves-of-nazare"><u>giant waves</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2zN2XfhmWnjbFmkXfTiYGw/fa321c61b54e676136f93d050364ee8b/image6.jpg" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Tyu4Wlgn1NMihceYSCUvI/45905ee3820880371b508dc13c32f11b/image2.jpg" />
          </figure><p><sup><i>Nazaré’s waves, famous since Garrett McNamara’s 23.8 m (78 ft) ride in 2011, hold </i></sup><a href="https://www.guinnessworldrecords.com/world-records/78115-largest-wave-surfed-unlimited"><sup><i><u>Guinness World Records</u></i></sup></a><sup><i> for the biggest waves ever surfed. Photos: Sam Khawasé &amp; Beatriz Paula, from Cloudflare.</i></sup></p><p>Portugal’s maritime culture also inspired literature and music, including poet Fernando Pessoa, who referenced it in his 1934 book <a href="https://en.wikipedia.org/wiki/Mensagem"><u>Mensagem</u></a>, and musician Rui Veloso, who dedicated his 1990s album <a href="https://open.spotify.com/album/2mzMuD3bxwFaFgfjU2vigY"><u>Auto da Pimenta</u></a> to Portugal’s historic connection to the sea.</p>
    <div>
      <h3>How this chaos came to be</h3>
      <a href="#how-this-chaos-came-to-be">
        
      </a>
    </div>
    <p>As Cloudflare’s CEO, Matthew Prince, <a href="https://x.com/eastdakota/status/1899226252956827846"><u>said</u></a> recently, this new wall of entropy began with an idea back in 2023: “What could we use for randomness that was like our lava lamp wall in San Francisco but represented our team in Portugal?”</p><p>The original inspiration came from wave motion machine desk toys, which were popular among some of our team members. Waves and the ocean not only provide a source of movement and randomness, but also align with Portugal’s maritime history and the office’s scenic view.</p><p>However, this was easier said than done. It turns out that making a wave machine wall is a real challenge, given that these toys are not as popular as they were in the past,  and aren’t being manufactured in the size we needed any more. We scoured eBay and other sources but couldn't find enough, consistent in style and in working order wave machines. We also discovered that off-the-shelf models weren’t designed to run 24/7, which was a critical requirement for our use.</p>
    <div>
      <h4>Artistry to create wave machines</h4>
      <a href="#artistry-to-create-wave-machines">
        
      </a>
    </div>
    <p>Undaunted, <a href="https://blog.cloudflare.com/cloudflare-top-100-most-loved-workplaces-in-2022"><u>Cloudflare’s Places team</u></a>, which ensures our offices reflect our values and culture, found a <a href="https://wavemotionmachines.com/"><u>U.S.-based artisan</u></a> that specializes in ocean wave displays to create the wave machines for us. Since 2009, his one-person business, <a href="https://wavemotionmachines.com/"><u>Hughes Wave Motion Machines</u></a>, has blended artistry, engineering, and research, following his transition from Lockheed Martin Space Systems, where he designed military and commercial satellites.</p><div>
  
</div>
<p></p><p><sup><i>Timelapse of the mesmerizing office waves, set to the tune of an AI-generated song.</i></sup></p><p>Collaborating closely, we developed a custom rectangular wave machine (18 inches/45 cm long) that runs nonstop — not an easy task — which required hundreds of hours of testing and many iterations. Featuring rotating wheels, continuous motors, and a unique fluid formula, these machines create realistic ocean-like waves in green, blue, and Cloudflare’s signature orange. </p><p>Here’s a quote from the artist himself about these wave machines:</p><blockquote><p><i>“The machine’s design is a balancing act of matching components and their placement to how the fluid responds in a given configuration. There is a complex yet delicate relationship between viscosity, specific gravity, the size and design of the vessel, and the placement of each mechanical interface. Everything must be precisely aligned, centered around the fluid like a mathematical function. I like to say it’s akin to ’balancing a checkerboard on a beach ball in the wind.’”</i></p></blockquote>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3K9fpTU0D0xi831MHFOFBj/570b8c307fea1078f3c0262e13447bf6/image7.jpg" />
          </figure><p><sup><i>The Cloudflare Places Team with Lisbon office architects and contractor testing wave machine placement, shelves, lighting, and mirrors to enhance movement and reflection, March 2024.</i></sup></p><p>Despite delays, the Lisbon wave machines finally debuted on March 10, 2025 — an incredibly exciting moment for the Places team.</p><p><b>Some numbers about our wave-machine entropy wall:</b></p><ul><li><p>50 wave machines, 50 motion wheels &amp; motors, 50 acrylic containers filled with Hughes Wave Fluid Formula (two <a href="https://www.sciencedirect.com/topics/engineering/immiscible-liquid"><u>immiscible liquids</u></a>)</p></li><li><p>3 liquid colors: blue, green, and orange</p></li><li><p>15 months from concept to completion</p></li><li><p>14 flips (side-to-side balancing movements) per minute — over 20,000 per day</p></li><li><p>Over 15 waves per minute</p></li><li><p>~0.5 liters of liquid per machine</p></li></ul>
    <div>
      <h3>LavaRand origins and walls of entropy</h3>
      <a href="#lavarand-origins-and-walls-of-entropy">
        
      </a>
    </div>
    <p>Cloudflare’s servers handle 71 million HTTP requests per second on average, with 100 million HTTP requests per second at peak. <a href="https://radar.cloudflare.com/adoption-and-usage#http-vs-https"><u>Most of these requests are secured via TLS</u></a>, which relies on secure randomness for cryptographic integrity. A Cryptographically Secure Pseudorandom Number Generator (<a href="https://www.cloudflare.com/learning/ssl/lava-lamp-encryption/"><u>CSPRNG</u></a>) ensures unpredictability, but only when seeded with high-quality entropy. Since chaotic movement in the real world is truly random, Cloudflare designed a system to harness it. Our <a href="https://blog.cloudflare.com/harnessing-office-chaos/"><u>2024 blog post</u></a> expands on this topic in a more technical way, but here’s a quick summary.</p><p>In <a href="https://blog.cloudflare.com/randomness-101-lavarand-in-production/"><u>2017</u></a>, Cloudflare launched LavaRand, inspired by <a href="https://www.wired.com/1997/03/lava-lites-easy-to-break-hard-to-crack/"><u>Silicon Graphics’ 1997 concept</u></a> However, the need for randomness in security was already a hot topic on our blog before that, such as in our discussions of <a href="https://blog.cloudflare.com/why-randomness-matters/"><u>securing systems</u></a> and <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>cryptography</u></a>. Originally, LavaRand collected entropy from a wall of lava lamps in our San Francisco office, feeding an internal API that servers periodically query to include in their entropy pools. Over time, we expanded LavaRand beyond lava lamps, incorporating <a href="https://blog.cloudflare.com/harnessing-office-chaos/#londons-unpredictable-pendulums"><u>new sources of office chaos</u></a> while maintaining the same core method.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2v6Wvde8j8R7482QjBsSrV/89b37c652654e27c13d328e9acac6489/image9.png" />
          </figure><p>A camera captures images of dynamic, unpredictable randomness displays. Shadows, lighting changes, and even sensor noise contribute entropy. Each image is then processed into a compact hash, converting it into a sequence of random bytes. These, combined with the previous seed and local system entropy, serve as input for a Key Derivation Function (<a href="https://en.wikipedia.org/wiki/Key_derivation_function"><u>KDF</u></a>), which generates a new seed for a CSPRNG — capable of producing virtually unlimited random bytes upon request. The waves in our Lisbon office are now contributing to this pool of randomness.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1XFFjr4jhRMQlz6akHKZm4/44759c4e879de3792cd21b4ce2525c90/image5.png" />
          </figure><p>Cloudflare’s LavaRand API makes this randomness accessible internally, strengthening cryptographic security across our global infrastructure. For example, when you use <i>Math.random()</i> in <a href="https://workers.cloudflare.com/"><u>Cloudflare Workers</u></a>, part of that randomness comes from LavaRand. Similarly, querying our <a href="https://blog.cloudflare.com/harnessing-office-chaos/#drand-distributed-and-verifiable-public-randomness"><u>drand API</u></a> taps into LavaRand as well. Cloudflare offers this API to enable anyone to generate random numbers and even seed their own systems.</p>
    <div>
      <h3>Our new Lisbon office space</h3>
      <a href="#our-new-lisbon-office-space">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5ivPkCfTkGxfo6Swt6p9qY/e7414a14b88bef7ac7e0ef6f737b58c6/image8.jpg" />
          </figure><p><sup><i>Photo of the view from our Lisbon office, featuring ceiling lights arranged in a wave-like pattern.</i></sup></p><p>Entropy also inspired the design ethos of our new Lisbon office, given that the wall of waves and the office are part of the same project. As soon as you enter, you're greeted not only by the motion of the entropy wall but also by the constant movement of planet Earth on our Cloudflare Radar Display screen that stands next to it. But the waves don’t stop there — more elements throughout the space mimic the dynamic flow of the Internet itself. Unlike ocean tides, however, Internet traffic ebbs and flows with the motion of the Sun, not the Moon.</p><p>As you walk through the office, waves are everywhere — in the ceiling lights, the architectural contours, and even the floor plan, thoughtfully designed by our architect to reflect the fluid movement of water. The visual elements create a cohesive experience, reinforcing a sense of motion. Each meeting room embraces this maritime theme, named after famous Portuguese beaches — including, naturally, Nazaré.</p><p>We partnered with an incredible group of local Portuguese vendors for this construction project, where all the leads were women — something incredibly rare for the industry. The local teams worked with passion, proudly wore Cloudflare t-shirts, and fostered a warm, family-like atmosphere. They openly expressed pride in the project, sharing how it stood out from anything they had worked on before.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7lpuurEtWfpIPKvHVqmD0L/0b0561097859f286d6b5e98db82f1e0f/image3.jpg" />
          </figure><p><sup><i>Our amazing third-party team and internal Places team, proudly rocking Cloudflare shirts after bringing this project to life.</i></sup></p>
    <div>
      <h3>Help us select a name for our new wall of entropy</h3>
      <a href="#help-us-select-a-name-for-our-new-wall-of-entropy">
        
      </a>
    </div>
    <p>Next, we have several name options for this new wall of entropy. Help us decide the best one, and register your vote using <a href="https://forms.gle/L2gAqoJTwQmJFkmy8"><u>this form</u></a>.</p><blockquote><p><b>The Surf Board</b></p><p><b>Chaos Reef</b></p><p><b>Waves of Entropy</b></p><p><b>Wall of Waves</b></p><p><b>Whirling Wave Wall</b></p><p><b>Chaotic Wave Wall</b></p><p><b>Waves of Chaos</b></p></blockquote><p>If you’re interested in working in Cloudflare’s Lisbon office, we’re hiring! Our <a href="https://www.cloudflare.com/careers/jobs/"><b><u>career page</u></b></a> lists our open roles in Lisbon, as well as our other locations in the U.S., Mexico, Europe and Asia.</p><p><sup><i>Acknowledgements: This project was only possible with the effort, vision and help of John Graham-Cumming, Caroline Quick, Jen Preston, Laura Atwall, Carolina Beja, Hughes Wave Motion Machines, P4 Planning and Project Management, Gensler Europe, Openbook Architecture, and Vector Mais.</i></sup></p> ]]></content:encoded>
            <category><![CDATA[LavaRand]]></category>
            <category><![CDATA[Entropy]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Randomness]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Portugal]]></category>
            <category><![CDATA[Life at Cloudflare]]></category>
            <category><![CDATA[Lisbon]]></category>
            <category><![CDATA[Offices]]></category>
            <guid isPermaLink="false">1QYrEI6OwTmFuhZNnURL95</guid>
            <dc:creator>João Tomé</dc:creator>
            <dc:creator>Caroline Quick</dc:creator>
        </item>
        <item>
            <title><![CDATA[A look at the latest post-quantum signature standardization candidates]]></title>
            <link>https://blog.cloudflare.com/another-look-at-pq-signatures/</link>
            <pubDate>Thu, 07 Nov 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[ NIST has standardized four post-quantum signature schemes so far, and they’re not done yet: there are fourteen new candidates in the running for standardization. ]]></description>
            <content:encoded><![CDATA[ <p>On October 24, 2024, the National Institute of Standards and Technology (NIST) <a href="https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/khAfIZPktRE/m/bBZWmET-AAAJ"><u>announced</u></a> that they’re advancing fourteen post-quantum signature schemes to the second round of the “<a href="https://csrc.nist.gov/projects/pqc-dig-sig"><u>signatures on ramp</u></a>” competition. “Post-quantum” means that these algorithms are designed to resist <a href="https://blog.cloudflare.com/the-quantum-menace/"><u>the attack of quantum computers</u></a>. NIST already standardized four post-quantum signature schemes (<a href="https://blog.cloudflare.com/nists-first-post-quantum-standards/"><u>ML-DSA, SLH-DSA</u></a>, <a href="https://csrc.nist.gov/News/2020/stateful-hash-based-signature-schemes-sp-800-208"><u>XMSS, and LMS</u></a>) and they are drafting a standard for a fifth (<a href="https://falcon-sign.info/"><u>Falcon</u></a>). Why do we need even more, you might ask? We’ll get to that.</p><p>A regular reader of the blog will know that this is not the first time we’ve taken measure of post-quantum signatures. In <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>2021</u></a> we took a first hard look, and reported on the performance impact we expect from large-scale measurements.  Since then, dozens of new post-quantum algorithms have been proposed. Many of them have been submitted to this new NIST competition. We discussed some of the more promising ones in our <a href="https://blog.cloudflare.com/pq-2024/"><u>early 2024 blog post</u></a>.</p><p>In this blog post, we will go over the fourteen schemes advanced to the second round of the on ramp and discuss their feasibility for use in TLS — the protocol that secures browsing the Internet. The defining feature of practically all of them, is that they require much more bytes on the wire. Back in 2021 we shared <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>experimental results</u></a> on the impact of these extra bytes. Today, we will share some surprising statistics on how TLS is used in practice. One is that today already almost half the data sent over more than half the QUIC connections are just for the certificates.</p><p>For a broader context and introduction to the post-quantum migration, check out our <a href="https://blog.cloudflare.com/pq-2024"><u>early 2024 blog post</u></a>. One take-away to mention here: there will be two migrations for TLS. First, we urgently need to migrate key agreement to <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/">post-quantum cryptography</a> to protect against <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>attackers that store encrypted communication today</u></a> in order to decrypt it in the future when a quantum computer is available. The industry is making good progress here: <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>18% of human requests</u></a> to websites using Cloudflare are <a href="https://blog.cloudflare.com/post-quantum-for-all/"><u>secured</u></a> using post-quantum key agreement. The second migration, to post-quantum signatures (certificates), is not as urgent: we will need to have this sorted by the time the quantum computer arrives. However, it will be a bigger challenge.</p>
    <div>
      <h2>The signatures in TLS</h2>
      <a href="#the-signatures-in-tls">
        
      </a>
    </div>
    <p>Before we have a look at the long list of post-quantum signature algorithms and their performance characteristics, let’s go through the signatures involved when browsing the Internet and their particular constraints.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/415VcZzABkhZjT60GRkQZM/f30ae24bd14e86534efd3e74d15eb5b5/image3.png" />
          </figure><p>When you visit a website, the browser establishes a TLS connection with the server for that website. The connection starts with a cryptographic handshake. During this handshake, to authenticate the connection, the server signs the transcript so far, and presents the browser with a TLS <i>leaf</i> certificate to prove that it’s allowed to serve the website. This <i>leaf </i>certificate is signed by a certification authority (CA). Typically, it’s not signed by the CA’s <i>root</i> certificate, but by an <i>intermediate</i> CA certificate, which in turn is signed by the root CA, or another intermediate. That’s not all: a leaf certificate has to include at least two <i>signed certificate timestamps</i> (SCTs). These SCTs are signatures created by <a href="https://blog.cloudflare.com/introducing-certificate-transparency-and-nimbus/"><u>certificate transparency (CT) logs</u></a> to attest they’ve been publicly logged. <a href="https://certificate.transparency.dev/howctworks/"><u>Certificate Transparency</u></a> is what enables you to look up a certificate on websites such <a href="http://crt.sh"><u>crt.sh</u></a> and <a href="https://www.merklemap.com/"><u>merklemap</u></a>. In the future three or more SCTs might be required. Finally, servers may also send an <a href="https://blog.cloudflare.com/high-reliability-ocsp-stapling/"><u>OCSP staple</u></a> to demonstrate a certificate hasn’t been revoked.</p><p>Thus, we’re looking at a minimum of five signatures (not counting the OCSP staple) and two public keys transmitted across the network to establish a new TLS connection.</p>
    <div>
      <h3>Tailoring</h3>
      <a href="#tailoring">
        
      </a>
    </div>
    <p>Only the handshake transcript signature is created <i>online</i>; the other signatures are “offline”. That is, they are created ahead of time. For these offline signatures, fast verification is much more important than fast signing. On the other hand, for the handshake signature, we want to minimize the sum of signing and verification time.</p><p>Only the public keys of the leaf and intermediate certificates are transmitted on the wire during the handshake, and for those we want to minimize the combined size of the signature and the public key. For the other signatures, the public key is not transmitted during the handshake, and thus a scheme with larger public keys would be tolerable, and preferable if it trades larger public keys for smaller signatures.</p>
    <div>
      <h2>The algorithms</h2>
      <a href="#the-algorithms">
        
      </a>
    </div>
    <p>Now that we’re up to speed, let’s have a look at the candidates that progressed (marked by 🤔 below), compared to the classical algorithms vulnerable to quantum attack (marked by ❌), and the post-quantum algorithms that are already standardized (✅) or soon will be (📝). Each submission proposes several variants. We list the most relevant variants to TLS from each submission. To explore all variants, check out <a href="https://research.cloudflare.com/outreach/academic-programs/interns/thom-wiggers/"><u>Thom Wigger</u></a>’s <a href="https://pqshield.github.io/nist-sigs-zoo/"><u>signatures zoo</u></a>.</p>
<div><table><thead>
  <tr>
    <th></th>
    <th></th>
    <th></th>
    <th><span>Sizes (bytes)</span></th>
    <th><span>CPU time (lower is better)</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>Family</span></td>
    <td><span>Name variant</span></td>
    <td></td>
    <td><span>Public key</span></td>
    <td><span>Signature</span></td>
    <td><span>Signing</span></td>
    <td><span>Verification</span></td>
  </tr>
  <tr>
    <td><span>Elliptic curves</span></td>
    <td><span>Ed25519</span></td>
    <td><span>❌</span></td>
    <td><span>32</span></td>
    <td><span>64</span></td>
    <td><span>0.15</span></td>
    <td><span>1.3</span></td>
  </tr>
  <tr>
    <td><span>Factoring</span></td>
    <td><span>RSA<small> 2048</small></span></td>
    <td><span>❌</span></td>
    <td><span>256</span></td>
    <td><span>256</span></td>
    <td><span>80</span></td>
    <td><span>0.4</span></td>
  </tr>
  <tr>
    <td><span>Lattices</span></td>
    <td><span>ML-DSA <small>44</small></span></td>
    <td><span>✅</span></td>
    <td><span>1,312</span></td>
    <td><span>2,420</span></td>
    <td><span>1 (baseline)</span></td>
    <td><span>1 (baseline)</span></td>
  </tr>
  <tr>
    <td><span>Symmetric</span></td>
    <td><span>SLH-DSA <small>128s</small></span></td>
    <td><span>✅</span></td>
    <td><span>32</span></td>
    <td><span>7,856</span></td>
    <td><span>14,000</span></td>
    <td><span>40</span></td>
  </tr>
  <tr>
    <td><span>SLH-DSA <small>128f</small></span></td>
    <td><span>✅</span></td>
    <td><span>32</span></td>
    <td><span>17,088</span></td>
    <td><span>720</span></td>
    <td><span>110</span></td>
  </tr>
  <tr>
    <td><span>LMS <small>M4_H20_W8</small></span></td>
    <td><span>✅</span></td>
    <td><span>48</span></td>
    <td><span>1,112</span></td>
    <td><span>2.9</span> ⚠️</td>
    <td><span>8.4</span></td>
  </tr>
  <tr>
    <td><span>Lattices</span></td>
    <td><span>Falcon <small>512</small></span></td>
    <td><span>📝</span></td>
    <td><span>897</span></td>
    <td><span>666</span></td>
    <td><span>3 ⚠️</span></td>
    <td><span>0.7</span></td>
  </tr>
  <tr>
    <td><span>Codebased</span></td>
    <td><span>CROSS <small>R-SDP(G)1 small</small></span></td>
    <td><span>🤔</span></td>
    <td><span>38</span></td>
    <td><span>7,956</span></td>
    <td><span>20</span></td>
    <td><span>35</span></td>
  </tr>
  <tr>
    <td><span>LESS <small>1s</small></span></td>
    <td><span>🤔</span></td>
    <td><span>97,484</span></td>
    <td><span>5,120</span></td>
    <td><span>620</span></td>
    <td><span>1800</span></td>
  </tr>
  <tr>
    <td><span>MPC in the head</span></td>
    <td><span>Mirath <small>Mirith Ia fast</small></span></td>
    <td><span>🤔</span></td>
    <td><span>129</span></td>
    <td><span>7,877</span></td>
    <td><span>25</span></td>
    <td><span>60</span></td>
  </tr>
  <tr>
    <td><span>MQOM <small>L1-gf251-fast</small></span></td>
    <td><span>🤔</span></td>
    <td><span>59</span></td>
    <td><span>7,850</span></td>
    <td><span>35</span></td>
    <td><span>85</span></td>
  </tr>
  <tr>
    <td><span>PERK <small>I-fast5</small></span></td>
    <td><span>🤔</span></td>
    <td><span>240</span></td>
    <td><span>8,030</span></td>
    <td><span>20</span></td>
    <td><span>40</span></td>
  </tr>
  <tr>
    <td><span>RYDE <small>128F</small></span></td>
    <td><span>🤔</span></td>
    <td><span>86</span></td>
    <td><span>7,446</span></td>
    <td><span>15</span></td>
    <td><span>40</span></td>
  </tr>
  <tr>
    <td><span>SDitH <small>gf251-L1-hyp</small></span></td>
    <td><span>🤔</span></td>
    <td><span>132</span></td>
    <td><span>8,496</span></td>
    <td><span>30</span></td>
    <td><span>80</span></td>
  </tr>
  <tr>
    <td><span>VOLE in the head</span></td>
    <td><span>FAEST <small>EM-128f</small></span></td>
    <td><span>🤔</span></td>
    <td><span>32</span></td>
    <td><span>5,696</span></td>
    <td><span>6</span></td>
    <td><span>18</span></td>
  </tr>
  <tr>
    <td><span>Lattices</span></td>
    <td><span>HAWK <small>512</small></span></td>
    <td><span>🤔</span></td>
    <td><span>1,024</span></td>
    <td><span>555</span></td>
    <td><span>0.25</span></td>
    <td><span>1.2</span></td>
  </tr>
  <tr>
    <td><span>Isogeny</span></td>
    <td><span>SQISign <small>I</small></span></td>
    <td><span>🤔</span></td>
    <td><span>64</span></td>
    <td><span>177</span></td>
    <td><span>17,000</span></td>
    <td><span>900</span></td>
  </tr>
  <tr>
    <td><span>Multivariate</span></td>
    <td><span>MAYO <small>one</small></span></td>
    <td><span>🤔</span></td>
    <td><span>1,168</span></td>
    <td><span>321</span></td>
    <td><span>1.4</span></td>
    <td><span>1.4</span></td>
  </tr>
  <tr>
    <td><span>MAYO <small>two</small></span></td>
    <td><span>🤔</span></td>
    <td><span>5,488</span></td>
    <td><span>180</span></td>
    <td><span>1.7</span></td>
    <td><span>0.8</span></td>
  </tr>
  <tr>
    <td><span>QR-UOV <small>I-(31,165,60,3)</small></span></td>
    <td><span>🤔</span></td>
    <td><span>23,657</span></td>
    <td><span>157</span></td>
    <td><span>75</span></td>
    <td><span>125</span></td>
  </tr>
  <tr>
    <td><span>SNOVA <small>(24,5,4)</small></span></td>
    <td><span>🤔</span></td>
    <td><span>1,016</span></td>
    <td><span>248</span></td>
    <td><span>0.9</span></td>
    <td><span>1.4</span></td>
  </tr>
  <tr>
    <td><span>SNOVA <small>(25,8,3)</small></span></td>
    <td><span>🤔</span></td>
    <td><span>2,320</span></td>
    <td><span>165</span></td>
    <td><span>0.9</span></td>
    <td><span>1.8</span></td>
  </tr>
  <tr>
    <td><span>SNOVA <small>(37,17,2)</small></span></td>
    <td><span>🤔</span></td>
    <td><span>9,842</span></td>
    <td><span>106</span></td>
    <td><span>1</span></td>
    <td><span>1.2</span></td>
  </tr>
  <tr>
    <td><span>UOV <small>Is-pkc</small></span></td>
    <td><span>🤔</span></td>
    <td><span>66,576</span></td>
    <td><span>96</span></td>
    <td><span>0.3</span></td>
    <td><span>2.3</span></td>
  </tr>
  <tr>
    <td><span>UOV <small>Ip-pkc</small></span></td>
    <td><span>🤔</span></td>
    <td><span>43,576</span></td>
    <td><span>128</span></td>
    <td><span>0.3</span></td>
    <td><span>0.8</span></td>
  </tr>
</tbody></table></div><p>Some notes about the table. It compares selected variants of the submissions progressed to the second round of the NIST PQC signature on ramp with earlier existing traditional and post-quantum schemes at the security level of AES-128. CPU times are taken from the <a href="https://pqshield.github.io/nist-sigs-zoo/"><u>signatures zoo</u></a>, which collected them from the submission documents and some later advances. CPU performance varies significantly by platform and implementation, and should only be taken as a rough indication. We are early in the competition, and the on-ramp schemes will evolve: some will improve drastically (both in compute and size), whereas others will regress to counter new attacks. Check out <a href="https://pqshield.github.io/nist-sigs-zoo/"><u>the zoo</u></a> for the latest numbers. We marked Falcon signing with a <i>⚠️</i>, as Falcon signing is hard to implement in a fast and timing side-channel secure manner. LMS signing has a ⚠️, as secure LMS signing requires keeping a state and the listed signing time assumes a 32MB cache. This will be discussed later on.</p><p>These are a lot of algorithms, and we didn’t even list all variants. One thing is clear: none of them perform as well as classical elliptic curve signatures across the board. Let’s start with NIST’s 2022 picks.</p>
    <div>
      <h3>ML-DSA, SLH-DSA, and Falcon</h3>
      <a href="#ml-dsa-slh-dsa-and-falcon">
        
      </a>
    </div>
    <p>The most viable general purpose post-quantum signature scheme standardized today is the lattice-based <b>ML-DSA</b> (<a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.204.pdf"><u>FIPS 204</u></a>), which started its life as <a href="https://pq-crystals.org/dilithium/index.shtml"><u>Dilithium</u></a>. It’s light on the CPU and reasonably straightforward to implement. The big downside is that its signatures and public keys are large: 2.4kB and 1.3kB respectively. Here and for the balance of the blog post, we will only consider the variants at the AES-128 security level unless stated otherwise. Adding ML-DSA, adds 14.7kB to the TLS handshake (two 1312-byte public keys plus five 2420-byte signatures).</p><p><b>SLH-DSA</b> (<a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.205.pdf"><u>FIPS 205</u></a>, née <a href="https://sphincs.org/"><u>SPHINCS</u><u><sup>+</sup></u></a>) looks strictly worse, adding 39kB and significant computational overhead for both signing and verification. The advantage of SLH-DSA, being solely based on hashes, is that its security is much better understood than ML-DSA. The lowest security level of SLH-DSA is generally more trusted than the highest security levels of many other schemes.</p><p><a href="https://falcon-sign.info/"><b><u>Falcon</u></b></a> (to be renamed <a href="https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards"><u>FN-DSA</u></a>) seems much better than SLH-DSA and ML-DSA if you look only at the numbers in the table. There is a catch though. For fast signing, Falcon requires fast floating-point arithmetic, which turns out to be <a href="https://blog.cloudflare.com/nist-post-quantum-surprise/#digital-signatures"><u>difficult to implement securely</u></a>. Signing can be performed securely with emulated floating-point arithmetic, but that makes it roughly twenty times slower. This makes Falcon ill-suited for online signatures. Furthermore, the signing procedure of Falcon is complicated to implement. On the other hand, Falcon verification is simple and doesn’t require floating-point arithmetic.</p><p>Leaning into Falcon’s strength, by using ML-DSA for the handshake signature, and Falcon for the rest, we’re only adding 7.3kB (at security level of AES-128).</p><p>There is one more difficulty with Falcon worth mentioning: it’s missing a middle security level. That means that if Falcon-512 (which we considered so far) turns out to be weaker than expected, then the next one up is Falcon-1024, which has double signature and public key size. That amounts to adding about 11kB.</p>
    <div>
      <h3>Stateful hash-based signatures</h3>
      <a href="#stateful-hash-based-signatures">
        
      </a>
    </div>
    <p>The very first post-quantum signature algorithms standardized are the stateful hash-based <a href="https://datatracker.ietf.org/doc/html/rfc8391"><u>XMSS</u><u><sup>(MT)</sup></u></a> and <a href="https://datatracker.ietf.org/doc/html/rfc8554#page-45"><u>LMS/HSS</u></a>. These are hash-based signatures, similar to SLH-DSA, and so we have a lot of trust in their security. They come with a big drawback: when creating a keypair you prepare a finite number of <i>signature slots</i>. For the variant listed in the table, there are about one million slots. Each slot can only be used once. If by accident a slot is used twice, then anyone can (<a href="https://eprint.iacr.org/2016/1042"><u>probably</u></a>) use those two signatures to forge any new signature from that slot and break into the connection the certificate is supposed to protect. Remembering which slots have been used, is the <i>state</i> in <i>stateful</i> hash-based signature. Certificate authorities might be able to keep the state, but for general use, Adam Langley calls keeping the state a <a href="https://www.imperialviolet.org/2013/07/18/hashsig.html"><u>huge foot-cannon</u></a>.</p><p>There are more quirks to keep in mind for stateful hash-based signatures. To start, during key generation, each slot needs to be prepared. Preparing each slot takes approximately the same amount of time as verifying a signature. Preparing all million takes a couple of hours on a single core. For intermediate certificates of a popular certificate authority, a million slots are not enough. Indeed, Let’s Encrypt issues more than <a href="https://letsencrypt.org/stats/"><u>four million certificates per day</u></a>. Instead of increasing the number of slots directly, we can use an extra intermediate. This is what XMSS<sup>MT</sup> and HSS do internally. A final quirk of stateful hash-based signatures is that their security is bottlenecked on non-repudiation: the listed LMS instance has 192 bits of security against forgery, but only 96 bits against the signer themselves creating a single signature that verifies two different messages.</p><p>Even when stateful hash-based signatures or Falcon can be used, we are still adding a lot of bytes on the wire. From <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>earlier experiments</u></a> we know that that will impact performance significantly. We summarize those findings later in this blog post, and share some new data. The short of it: it would be nice to have a post-quantum signature scheme that outperforms Falcon, or at least outperforms ML-DSA and is easier to deploy. This is one of the reasons NIST is running the second competition.</p><p>With that in mind, let’s have a look at the candidates.</p>
    <div>
      <h3>Structured lattice alternatives</h3>
      <a href="#structured-lattice-alternatives">
        
      </a>
    </div>
    <p>With only performance in mind, it is surprising that half of the candidates do worse than ML-DSA. There is a good reason for it: NIST is worried that we’re putting all our eggs in the structured lattices basket. SLH-DSA is an alternative to lattices today, but it doesn’t perform well enough for many applications. As such, NIST <a href="https://csrc.nist.gov/csrc/media/Projects/pqc-dig-sig/documents/call-for-proposals-dig-sig-sept-2022.pdf"><u>would primarily like to standardize</u></a> another general purpose signature algorithm that is not based on structured lattices, and that outperforms SLH-DSA. We will briefly touch upon these schemes here.</p>
    <div>
      <h4>Code-based</h4>
      <a href="#code-based">
        
      </a>
    </div>
    <p><a href="https://www.cross-crypto.com/"><u>CROSS</u></a> and <a href="https://www.less-project.com/#:~:text=LESS%20(Linear%20Equivalence%20Signature%20Scheme,the%20Linear%20Code%20Equivalence%20problem."><u>LESS</u></a> are two<b> code-based signature</b> schemes. <b>CROSS</b> is based on a variant of the traditional syndrome decoding problem. Its signatures are about as large as SLH-DSA, but its edge over SLH-DSA is the much better signing times. <b>LESS</b> is based on the novel <a href="https://eprint.iacr.org/2023/847"><u>linear equivalence problem</u></a>. It only outperforms SLH-DSA on signature size, requiring larger public keys in return. For use in TLS, the high verification times of LESS are especially problematic. Given that LESS is based on a new approach, it will be interesting to see how much it can improve going forward.</p>
    <div>
      <h4>Multi-party computation in the head</h4>
      <a href="#multi-party-computation-in-the-head">
        
      </a>
    </div>
    <p>Five of the submissions (<a href="https://pqc-mira.org/"><u>Mira</u></a><a href="https://pqc-mirith.org/"><u>th</u></a>, <a href="https://mqom.org/"><u>MQOM</u></a>, <a href="https://pqc-perk.org/"><u>PERK</u></a>, <a href="https://pqc-ryde.org/"><u>RYDE</u></a>, <a href="https://sdith.org/"><u>SDitH</u></a>) use the <b>Multi-Party Computation in the Head</b> (MPCitH) paradigm.</p><p>It has been exciting to see the developments in this field. To explain a bit about it, let’s go back to <a href="https://microsoft.github.io/Picnic/"><u>Picnic</u></a>. Picnic was an MPCitH submission to the previous NIST PQC competition. In essence, its private key is a random key <i>x</i>, and its public key is the hash <i>H(x)</i>. A signature is a zero-knowledge proof demonstrating that the signer knows <i>x</i>. So far, it’s pretty similar in shape to other signature schemes that use zero knowledge proofs. The difference is in how that proof is created. We have to talk about multi-party computation (MPC) first. MPC starts with splitting the key <i>x</i> into shares, using <a href="https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing"><u>Shamir secret sharing</u></a> for instance, and giving each party one share. No single party knows the value of <i>x</i> itself, but they can recover it by recombining. The insight of MPC is that these parties (with some communication) can perform arbitrary computation on the data they shared. In particular, they can compute a secret share of <i>H(x)</i>. Now, we can use that to make a zero-knowledge proof as follows. The signer simulates all parties in the multi-party protocol to compute and recombine <i>H(x)</i>. The signer then reveals part of the intermediate values of the computation using <a href="https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic"><u>Fiat–Shamir</u></a>: enough so that none of the parties could have cheated on any of the steps, but not enough that it allows the verifier to figure out <i>x</i> themselves.</p><p>For <i>H</i>, Picnic uses <a href="https://lowmc.github.io/"><u>LowMC</u></a>, a block cipher for which it’s easy to do the multi-party computation. The initial submission of Picnic performed poorly compared to SLH-DSA with 32kB signatures. For the second round, Picnic was improved considerably, boasting 12kB signatures. SLH-DSA won out with smaller signatures, and more conservative security assumptions: Picnic relies on LowMC which didn’t receive as much study as the hashes on which SLH-DSA is based.</p><p>Back to the MPCitH candidates that progressed. All of them have variants (listed in the table) with similar or better signature sizes as SLH-DSA, while outperforming SLH-DSA considerably in signing time. There are variants with even smaller signatures, but their verification performance is significantly higher. The difference between the MPCitH candidates is the underlying <a href="https://en.wikipedia.org/wiki/Trapdoor_function"><u>trapdoor</u></a> they use. In Picnic the trapdoor was LowMC. For both RYDE and SDiTH, the trapdoors used are based on variants of <a href="https://en.wikipedia.org/wiki/Decoding_methods#Syndrome_decoding"><u>syndrome decoding</u></a>, and could be classified as code-based cryptography.</p><p>Over the years, MPCitH schemes have seen remarkable improvements in performance, and we don’t seem to have reached the end of it yet. There is still some way to go before these schemes would be competitive in TLS: signature size needs to be reduced without sacrificing the currently borderline acceptable verification performance. On top of that, not all underlying trapdoors of the various schemes have seen enough scrutiny.</p>
    <div>
      <h4>FAEST</h4>
      <a href="#faest">
        
      </a>
    </div>
    <p><a href="https://faest.info/"><u>FAEST</u></a> is a peek into the future. It’s similar to the MPCitH candidates in that its security reduces to an underlying trapdoor. It is quite different from those in that FAEST’s underlying trapdoor is AES. That means that, given the security analysis of FAEST is correct, it’s on the same footing as SLH-DSA. Despite the conservative trapdoor, FAEST beats the MPCitH candidates in performance. It also beats SLH-DSA on all metrics.</p><p>At the AES-128 security level, FAEST’s signatures are larger than ML-DSA. For those that want to hedge against improvements in lattice attacks, and would only consider higher security levels of ML-DSA, FAEST becomes an attractive alternative. ML-DSA-65 has a combined public key and signature size of 5.2kB, which is similar to FAEST EM-128f. ML-DSA-65 still has a slight edge in performance.</p><p>FAEST is based on the 2023 <a href="https://eprint.iacr.org/2023/996.pdf"><u>VOLE in the Head</u></a> paradigm. These are new ideas, and it seems likely their full potential has not been realized yet. It is likely that FAEST will see improvements.</p><p>The VOLE in the Head techniques can and probably will be adopted by some of the MPCitH submissions. It will be interesting to see how far VOLEitH can be pushed when applied to less conservative trapdoors. Surpassing ML-DSA seems in reach, but Falcon? We will see.</p><p>Now, let’s move on to the submissions that surpass ML-DSA today.</p>
    <div>
      <h3>HAWK</h3>
      <a href="#hawk">
        
      </a>
    </div>
    <p><a href="https://hawk-sign.info/"><u>HAWK</u></a> is similar to Falcon, but improves upon it in a few key ways. Most importantly, it doesn’t rely on floating point arithmetic. Furthermore, its signing procedure is simpler and much faster. This makes HAWK suitable for online signatures. Using HAWK adds 4.8kB. Apart from size and speed, it’s beneficial to rely on only a single scheme: using multiple schemes increases the attack surface for algorithmic weaknesses and implementation mistakes.</p><p>Similar to Falcon, HAWK is missing a middle security level. Using HAWK-1024 doubles sizes (9.6kB).</p><p>There is one downside to HAWK over Falcon: HAWK relies on a new security assumption, the <a href="https://eprint.iacr.org/2021/1332.pdf"><u>lattice isomorphism problem</u></a>.</p>
    <div>
      <h3>SQISign</h3>
      <a href="#sqisign">
        
      </a>
    </div>
    <p><a href="https://sqisign.org/"><u>SQISign</u></a> is based on <a href="https://blog.cloudflare.com/sidh-go/"><u>isogenies</u></a>. Famously, SIKE, another isogeny-based scheme in the previous competition, got <a href="https://eprint.iacr.org/2022/975.pdf"><u>broken badly</u></a> late into the competition. SQISign is based on a different problem, though. SQISign is remarkable for having very small signatures and public keys: it even beats RSA-2048. The glaring downside is that it is computationally very expensive to compute and verify a signature. Isogeny-based signature schemes is a very active area of research with many advances over the years.</p><p>It seems unlikely that any future SQISign variant will sign fast enough for the TLS handshake signature. Furthermore, SQISign signing seems to be hard to implement in a timing side-channel secure manner. What about the other signatures of TLS? The bottleneck is verification time. It would be acceptable for SQISign to have larger signatures, if that allows it to have faster verification time.</p>
    <div>
      <h3>UOV</h3>
      <a href="#uov">
        
      </a>
    </div>
    <p><a href="https://www.uovsig.org/"><u>UOV</u></a> (unbalanced oil and vinegar) is an old multivariate scheme with large public keys (67kB), but small signatures (96 bytes). Furthermore, it has excellent signing and verification performance. These interesting size tradeoffs make it quite suited for use cases where the public key is known in advance.</p><p>If we use UOV in TLS for the SCTs and root CA, whose public keys are not transmitted when setting up the connection, together with ML-DSA for the others, we’re looking at 7.2kB. That’s a clear improvement over using ML-DSA everywhere, and a tad better than combining ML-DSA with Falcon.</p><p>When combining UOV with HAWK instead of ML-DSA, we’re looking at adding only 3.4kB. That’s better again, but only a marginal improvement over using HAWK everywhere (4.8kB). The relative advantage of UOV improves if the certificate transparency ecosystem moves towards requiring more SCTs.</p><p>For SCTs, the size of UOV public keys seems acceptable, as there are not that many certificate transparency logs at the moment. Shipping a UOV public key for hundreds of root CAs is more painful, but within reason. Even with <a href="https://blog.cloudflare.com/pq-2024/#leaving-out-intermediate-certificates"><u>intermediate suppression</u></a>, using UOV in each of the thousands of intermediate certificates does not make sense.</p>
    <div>
      <h3>Structured multivariate</h3>
      <a href="#structured-multivariate">
        
      </a>
    </div>
    <p>Since the original UOV, over the decades, many attempts have been made to add additional structure UOV, to get a better balance between the size of the signature and public key. Unfortunately many of these <i>structured multivariate</i> schemes, which include GeMMS and Rainbow, have been broken.</p><p>Let’s have a look at the multivariate candidates. The most interesting variant of <b>QR-UOV</b> for TLS has 24kB public keys and 157 byte signatures. The current verification times are unacceptably high, but there seems to be plenty of room for an improved implementation. There is also a variant with a 12kB public key, but its verification time needs to come down even further. In any case, the combined size QR-UOV’s public key and signatures remain large enough that it’s not a competitor of ML-DSA or Falcon. Instead, QR-UOV competes with UOV, where UOV’s public keys are unwieldy. Although QR-UOV hasn’t seen a direct attack yet, a similar scheme has recently been <a href="https://link.springer.com/chapter/10.1007/978-3-031-62746-0_9"><u>weakened</u></a> and another <a href="https://link.springer.com/chapter/10.1007/978-3-030-44223-1_18"><u>broken</u></a>.</p><p>Finally, we get to<b> </b><a href="https://snova.pqclab.org/"><b><u>SNOVA</u></b></a> and <a href="https://pqmayo.org/"><b><u>MAYO</u></b></a>. Although they’re based on a different technique, they have a lot of properties in common. To start, they have the useful property that they allow for a granular tradeoff between public key and signature size. This allows us to use a different variant optimized for whether we’re transmitting the public in the connection or not. Using MAYO<sub>one</sub> for the leaf and intermediate, and MAYO<sub>two</sub> for the others, adds 3.5kB. Similarly with SNOVA, we add 2.8kB. On top of that, both schemes have excellent signing and verification performance.</p><p>The elephant in the room is the security. During the end of the first round, a new <a href="https://www.jstage.jst.go.jp/article/jsiaml/15/0/15_53/_article"><u>generic attack</u></a> on underdefined multivariate systems prompted the MAYO team to <a href="https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/jEKfDYUgdec/m/0UP_GNKSAwAJ"><u>tweak their parameters</u></a> slightly. SNOVA has been hit a bit harder by three attacks (<a href="https://dl.acm.org/doi/10.1145/3659467.3659900"><u>1</u></a>, <a href="https://eprint.iacr.org/2024/1297"><u>2</u></a>, <a href="https://eprint.iacr.org/2024/1770.pdf"><u>3</u></a>), but so far it seems that SNOVA’s parameters can be adjusted to compensate.</p><p>Ok, we had a look at all the candidates. What did we learn? There are some very promising algorithms that will reduce the number of bytes required on the wire compared to ML-DSA and Falcon. None of the practical ones will prevent us from adding any extra bytes to TLS. So, given that we must add some bytes: how many extra bytes are too many?</p>
    <div>
      <h2>How many added bytes are too many for TLS?</h2>
      <a href="#how-many-added-bytes-are-too-many-for-tls">
        
      </a>
    </div>
    <p>On average, around 15 million TLS connections are established with Cloudflare per second. Upgrading each to ML-DSA, would take 1.8Tbps, which is 0.6% of our current total network capacity. No problem so far. The question is how these extra bytes affect performance.</p><p>Back in 2021, we <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>ran a large-scale experiment</u></a> to measure the impact of big post-quantum certificate chains on connections to Cloudflare’s network over the open Internet. There were two important results. First, we saw a steep increase in the rate of client and middlebox failures when we added more than 10kB to existing certificate chains. Secondly, when adding less than 9kB, the slowdown in TLS handshake time would be approximately 15%. We felt the latter is workable, but far from ideal: such a slowdown is noticeable and people might hold off deploying post-quantum certificates before it’s too late.</p><p>Chrome is more cautious and set 10% as their target for maximum TLS handshake time regression. They <a href="https://dadrian.io/blog/posts/pqc-signatures-2024/#fnref:3"><u>report</u></a> that deploying post-quantum key agreement has already incurred a 4% slowdown in TLS handshake time, for the extra 1.1kB from server-to-client and 1.2kB from client-to-server. That slowdown is proportionally larger than the 15% we found for 9kB, but that could be explained by slower upload speeds than download speeds.</p><p>There has been pushback against the focus on TLS handshake times. One argument is that session resumption alleviates the need for sending the certificates again. A second argument is that the data required to visit a typical website dwarfs the additional bytes for post-quantum certificates. One example is this <a href="https://www.amazon.science/publications/the-impact-of-data-heavy-post-quantum-tls-1-3-on-the-time-to-last-byte-of-real-world-connections"><u>2024 publication</u></a>, where Amazon researchers have simulated the impact of large post-quantum certificates on data-heavy TLS connections. They argue that typical connections transfer multiple requests and hundreds of kilobytes, and for those the TLS handshake slowdown disappears in the margin.</p><p>Are session resumption and hundreds of kilobytes over a connection typical though? We’d like to share what we see. We focus on QUIC connections, which are likely initiated by browsers or browser-like clients. Of all QUIC connections with Cloudflare that carry at least one HTTP request, 37% are <a href="https://blog.cloudflare.com/even-faster-connection-establishment-with-quic-0-rtt-resumption/"><u>resumptions</u></a>, meaning that key material from a previous TLS connection is reused, avoiding the need to transmit certificates. The median number of bytes transferred from server-to-client over a resumed QUIC connection is 4.4kB, while the average is 395kB. For non-resumptions the median is 7.8kB and average is 551kB. This vast difference between median and average indicates that a small fraction of data-heavy connections skew the average. In fact, only 15.8% of all QUIC connections transfer more than 100kB.</p><p>The median certificate chain today (with compression) is <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-cert-abridge-02#section-4"><u>3.2kB</u></a>. That means that almost 40% of all data transferred from server to client on more than half of the non-resumed QUIC connections are just for the certificates, and this only gets worse with post-quantum algorithms. For the majority of QUIC connections, using ML-DSA as a drop-in replacement for classical signatures would more than double the number of transmitted bytes over the lifetime of the connection.</p><p>It sounds quite bad if the vast majority of data transferred for a typical connection is just for the post-quantum certificates. It’s still only a proxy for what is actually important: the effect on metrics relevant to the end-user, such as the browsing experience (e.g. <a href="https://web.dev/articles/optimize-lcp"><u>largest contentful paint</u></a>) and the amount of data those certificates take from a user’s monthly data cap. We will continue to investigate and get a better understanding of the impact.</p>
    <div>
      <h2>Zooming out</h2>
      <a href="#zooming-out">
        
      </a>
    </div>
    <p>That was a lot — let’s step back.</p><p>It’s great to see how much better the post-quantum signature algorithms are today in almost every family than they were in <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>2021</u></a>. The improvements haven’t slowed down either. Many of the algorithms that do not improve over ML-DSA for TLS today could still do so in the third round. Looking back, we are also cautioned: several algorithms considered in 2021 have since been broken.</p><p>From an implementation and performance perspective for TLS today, HAWK, SNOVA, and MAYO are all clear improvements over ML-DSA and Falcon. They are also very new, and presently we cannot depend on them without a <a href="https://blog.cloudflare.com/pq-2024/#way-forward"><u>plan B</u></a>. UOV has been around a lot longer. Due to its large public key, it will not work on its own, but be a very useful complement to another general purpose signature scheme.</p><p>Even with the best performers out of the competition, the way we see TLS connections used today, suggest that drop-in post-quantum certificates will have a big impact on at least half of them.</p><p>In the meantime, we can also make plan B our plan A: there are several ways in which we can reduce the number of signatures used in TLS. We can leave out intermediate certificates (<a href="https://datatracker.ietf.org/doc/html/draft-kampanakis-tls-scas-latest"><u>1</u></a>, <a href="https://datatracker.ietf.org/doc/draft-ietf-tls-cert-abridge/"><u>2</u></a>, <a href="https://datatracker.ietf.org/doc/html/draft-davidben-tls-trust-expr-04#name-intermediate-elision"><u>3</u></a>). Another is to use a KEM <a href="https://kemtls.org/"><u>instead of a signature</u></a> for handshake authentication. We can even get rid of all the offline signatures with a more <a href="https://datatracker.ietf.org/doc/html/draft-davidben-tls-merkle-tree-certs-03"><u>ambitious redesign</u></a> for the <a href="https://www.youtube.com/watch?v=f8unMB2Qjho"><u>vast majority</u></a> of visits: a post-quantum Internet with fewer bytes on the wire! We’ve discussed these ideas at more length in a <a href="https://blog.cloudflare.com/pq-2024/#way-forward"><u>previous blog post</u></a>.</p><p>So what does this mean for the coming years? We will continue to work with browsers to understand the end user impact of large drop-in post-quantum certificates. When certificate authorities support them (our guess: 2026), we will add support for ML-DSA certificates <a href="https://blog.cloudflare.com/post-quantum-crypto-should-be-free/"><u>for free</u></a>. This will be opt-in until cryptographically relevant quantum computers are imminent, to prevent undue performance regression. In the meantime, we will continue to pursue larger changes to the WebPKI, so that we can bring full post-quantum security to the Internet without performance compromise.</p><p>We’ve talked a lot about certificates, but what we need to care about today is encryption. Along with many across industry, including the major browsers, we have deployed the post-quantum key agreement X25519MLKEM768 across the board, and you can make sure your connections with Cloudflare are already secured against harvest-now/decrypt-later. Visit <a href="http://pq.cloudflareresearch.com"><u>pq.cloudflareresearch.com</u></a> to learn how.</p> ]]></content:encoded>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[TLS]]></category>
            <guid isPermaLink="false">3mOPXbiTgeQHBChx4vUuMs</guid>
            <dc:creator>Bas Westerbaan</dc:creator>
            <dc:creator>Luke Valenta</dc:creator>
        </item>
        <item>
            <title><![CDATA[NIST’s first post-quantum standards]]></title>
            <link>https://blog.cloudflare.com/nists-first-post-quantum-standards/</link>
            <pubDate>Tue, 20 Aug 2024 21:00:00 GMT</pubDate>
            <description><![CDATA[ NIST has published the first cryptographic standards for protecting against attacks from quantum computers. Learn what this means for you and your organization. ]]></description>
            <content:encoded><![CDATA[ <p>On August 13th, 2024, the US National Institute of Standards and Technology (NIST) <a href="https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards"><u>published</u></a> the first three cryptographic standards designed to resist an <a href="https://blog.cloudflare.com/the-quantum-menace"><u>attack</u></a> from quantum computers: <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf"><u>ML-KEM</u></a>, <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.204.pdf"><u>ML-DSA</u></a>, and <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.205.pdf"><u>SLH-DSA</u></a>. This announcement marks a significant milestone for ensuring that today’s communications remain secure in a future world where large-scale quantum computers are a reality.</p><p>In this blog post, we briefly discuss the significance of NIST’s recent announcement, how we expect the ecosystem to evolve given these new standards, and the next steps we are taking. For a deeper dive, see <a href="https://blog.cloudflare.com/pq-2024"><u>our March 2024 blog post</u></a>.</p>
    <div>
      <h2>Why are quantum computers a threat?</h2>
      <a href="#why-are-quantum-computers-a-threat">
        
      </a>
    </div>
    <p>Cryptography is a fundamental aspect of modern technology, securing everything from online communications to financial transactions. For instance, when visiting this blog, your web browser used cryptography to establish a secure communication channel to Cloudflare’s server to ensure that you’re really talking to Cloudflare (and not an impersonator), and that the conversation remains private from eavesdroppers.</p><p>Much of the cryptography in widespread use today is based on mathematical puzzles (like <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)"><u>factoring very large numbers</u></a>) which are computationally out of reach for classical (non-quantum) computers. We could likely continue to use traditional cryptography for decades to come if not for the advent of <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-quantum-computing/"><u>quantum computers</u></a>, devices that use properties of quantum mechanics to perform certain specialized calculations much more efficiently than traditional computers. Unfortunately, those specialized calculations include solving the mathematical puzzles upon which most widely deployed cryptography depends.</p><p>As of today, no quantum computers exist that are large and stable enough to break today’s cryptography, but experts predict that it’s only a matter of time until such a cryptographically-relevant quantum computer (CRQC) exists. For instance, more than a quarter of interviewed experts in a <a href="https://globalriskinstitute.org/publication/2023-quantum-threat-timeline-report/"><u>2023 survey</u></a> expect that a CRQC is more likely than not to appear in the next decade.</p>
    <div>
      <h2>What is being done about the quantum threat?</h2>
      <a href="#what-is-being-done-about-the-quantum-threat">
        
      </a>
    </div>
    <p>In recognition of the quantum threat, the US National Institute of Standards and Technology (<a href="https://nist.gov"><u>NIST</u></a>) launched a public <a href="https://csrc.nist.gov/projects/post-quantum-cryptography"><u>competition in 2016</u></a> to solicit, evaluate, and standardize new “post-quantum” cryptographic schemes that are designed to be resistant to attacks from quantum computers. On August 13, 2024, NIST <a href="https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards"><u>published</u></a> the final standards for the first three post-quantum algorithms to come out of the competition: <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf"><u>ML-KEM</u></a> for key agreement, and <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.204.pdf"><u>ML-DSA</u></a> and <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.205.pdf"><u>SLH-DSA</u></a> for digital signatures. A <a href="https://www.nist.gov/news-events/news/2022/07/nist-announces-first-four-quantum-resistant-cryptographic-algorithms"><u>fourth standard</u></a> based on <a href="https://falcon-sign.info/"><u>FALCON</u></a> is planned for release in late 2024 and will be dubbed FN-DSA, short for FFT (fast-Fourier transform) over NTRU-Lattice-Based Digital Signature Algorithm.</p><p>The publication of the final standards marks a significant milestone in an <a href="https://www.nist.gov/news-events/news/2016/04/nist-kicks-effort-defend-encrypted-data-quantum-computer-threat"><u>eight-year</u></a> global community effort managed by NIST to prepare for the arrival of quantum computers. Teams of cryptographers from around the world jointly submitted <a href="https://csrc.nist.gov/Projects/post-quantum-cryptography/post-quantum-cryptography-standardization/round-1-submissions"><u>82 algorithms</u></a> to the first round of the competition in 2017. After years of evaluation and cryptanalysis from the global cryptography community, NIST winnowed the algorithms under consideration down through several rounds until they decided upon the first four algorithms to standardize, which they <a href="https://blog.cloudflare.com/nist-post-quantum-surprise"><u>announced in 2022</u></a>.</p><p>This has been a monumental effort, and we would like to extend our gratitude to NIST and all the cryptographers and engineers across academia and industry that participated.</p><p>Security was a primary concern in the selection process, but algorithms also need to be performant enough to be deployed in real-world systems. Cloudflare’s involvement in the NIST competition began in 2019 when we <a href="https://blog.cloudflare.com/the-tls-post-quantum-experiment"><u>performed experiments</u></a> with industry partners to evaluate how algorithms under consideration performed when deployed on the open Internet. Gaining practical experience with the new algorithms was a crucial part of the evaluation process, and helped to identify and remove obstacles for deploying the final standards.</p><p>Having standardized algorithms is a significant step, but migrating systems to use these new algorithms is going to require a multi-year effort. To understand the effort involved, let’s look at two classes of traditional cryptography that are susceptible to quantum attacks: key agreement and digital signatures.</p><p><b>Key agreement</b> allows two parties that have never communicated before to establish a shared secret over an insecure communication channel (like the Internet). The parties can then use this shared secret to encrypt future communications between them. An adversary may be able to observe the encrypted communication going over the network, but without access to the shared secret they cannot decrypt and “see inside” the encrypted packets.</p><p>However, in what is known as the <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>"harvest now, decrypt later"</u></a> threat model, an adversary can store encrypted data until some point in the future when they gain access to a sufficiently large quantum computer, and then can decrypt at their leisure. Thus, today’s communication is already at risk from a future quantum adversary, and it is urgent that we upgrade systems to use post-quantum key agreement as soon as possible.</p><p>In 2022, soon after NIST announced the first set of algorithms to be standardized, Cloudflare worked with industry partners to deploy a preliminary version of ML-KEM to protect traffic arriving at Cloudflare’s servers (and our internal systems), both to pave the way for adoption of the final standard and to start protecting traffic as soon as possible. As of mid-August 2024, over 16% of human-generated requests to Cloudflare’s servers are already protected with post-quantum key agreement.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4vTixjEDsg7Tu5YW6Xhy9p/7ad1860335cb330637629c4625b5fc76/2499-2.png" />
          </figure><p><sub><i>Percentage of human traffic to Cloudflare protected by X25519Kyber, a preliminary version of ML-KEM as shown on </i></sub><a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><sub><i><u>Cloudflare Radar</u></i></sub></a><sub><i>.</i></sub></p><p>Other players in the tech industry have deployed post-quantum key agreement as well, including <a href="https://blog.chromium.org/2024/05/advancing-our-amazing-bet-on-asymmetric.html"><u>Google</u></a>, <a href="https://security.apple.com/blog/imessage-pq3/"><u>Apple</u></a>, <a href="https://engineering.fb.com/2024/05/22/security/post-quantum-readiness-tls-pqr-meta/"><u>Meta</u></a>, and <a href="https://signal.org/blog/pqxdh/"><u>Signal</u></a>.</p><p><b>Signatures</b> are crucial to ensure that you’re communicating with who you think you are communicating. In the web public key infrastructure (WebPKI), signatures are used in certificates to prove that a website operator is the rightful owner of a domain. The threat model for signatures is different than for key agreement. An adversary capable of forging a digital signature could carry out an <i>active</i> attack to impersonate a web server to a client, but today’s communication is not yet at risk.</p><p>While the migration to post-quantum signatures is less urgent than the migration for key agreement (since traffic is only at risk once CRQCs exist), it is much more challenging. Consider, for instance, the number of parties involved. In key agreement, only two parties need to support a new key agreement protocol: the client and the server. In the WebPKI, there are many more parties involved, from library developers, to browsers, to server operators, to certificate authorities, to hardware manufacturers. Furthermore, post-quantum signatures are <a href="https://dadrian.io/blog/posts/pqc-signatures-2024/"><u>much larger</u></a> than we’re used to from traditional signatures. For more details on the tradeoffs between the different signature algorithms, deployment challenges, and out-of-the-box solutions see our <a href="https://blog.cloudflare.com/pq-2024"><u>previous blog post</u></a>.</p><p>Reaching consensus on the right approach for migrating to post-quantum signatures is going to require extensive effort and coordination among stakeholders. However, that work is already well underway. For instance, in 2021 we ran large scale <a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"><u>experiments</u></a> to understand the feasibility of post-quantum signatures in the WebPKI, and we have more studies planned.</p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Now that NIST has published the first set of standards for post-quantum cryptography, what comes next?</p><p>In 2022, Cloudflare <a href="https://blog.cloudflare.com/post-quantum-cryptography-ga"><u>deployed</u></a> a preliminary version of the ML-KEM key agreement algorithm, Kyber, which is now used to protect <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>double-digit percentages</u></a> of requests to Cloudflare’s network. We use a <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-hybrid-design"><i><u>hybrid</u></i></a> with X25519, to hedge against future advances in cryptanalysis and implementation vulnerabilities. In coordination with industry partners at the <a href="https://www.nccoe.nist.gov/"><u>NIST NCCoE</u></a> and <a href="https://www.ietf.org/"><u>IETF</u></a>, we will upgrade our systems to support the final ML-KEM standard, again using a hybrid. We will slowly phase out support for the pre-standard version X25519Kyber768 after clients have moved to the ML-KEM-768 hybrid, and will quickly phase out X25519Kyber512, which hasn’t seen real-world usage.</p><p>Now that the final standards are available, we expect to see widespread adoption of ML-KEM industry-wide as support is added in software and hardware, and post-quantum becomes the new default for key agreement. Organizations should look into upgrading their systems to use post-quantum key agreement as soon as possible to protect their data from future quantum-capable adversaries. Check if your browser already supports post-quantum key agreement by visiting <a href="https://pq.cloudflareresearch.com"><u>pq.cloudflareresearch.com</u></a>, and if you’re a Cloudflare customer, see how you can <a href="https://blog.cloudflare.com/post-quantum-to-origins/"><u>enable post-quantum key agreement support to your origin</u></a> today.</p><p>Adoption of the newly-standardized post-quantum signatures ML-DSA and SLH-DSA will take longer as stakeholders work to reach consensus on the migration path. We expect the first post-quantum certificates to be available in 2026, but not to be enabled by default. Organizations should prepare for a future flip-the-switch migration to post-quantum signatures, but there is no need to flip the switch just yet.</p><p>We’ll continue to provide updates in this blog and at <a href="https://pq.cloudflareresearch.com"><u>pq.cloudflareresearch.com</u></a>. Don’t hesitate to reach out to us at <a><u>ask-research@cloudflare.com</u></a> with any questions.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <guid isPermaLink="false">5JwNgDhEFBcPJq3mVrYMUx</guid>
            <dc:creator>Luke Valenta</dc:creator>
            <dc:creator>Vânia Gonçalves</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare now uses post-quantum cryptography to talk to your origin server]]></title>
            <link>https://blog.cloudflare.com/post-quantum-to-origins/</link>
            <pubDate>Fri, 29 Sep 2023 13:00:45 GMT</pubDate>
            <description><![CDATA[ Starting today, you can secure the connection between Cloudflare and your origin server with post-quantum cryptography ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Quantum computers pose a <a href="/the-quantum-menace/">serious threat</a> to security and privacy of the Internet: encrypted communication intercepted today can be decrypted <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later">in the future</a> by a sufficiently advanced quantum computer. To counter this <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later">store-now/decrypt-later</a> threat, cryptographers have been hard at work over the last decades proposing and vetting <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/">post-quantum cryptography (PQC)</a>, cryptography that’s designed to withstand attacks of quantum computers. After a six-year public competition, in July 2022, the US National Institute of Standards and Technology (NIST), known for standardizing AES and SHA, announced <a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a> as <a href="/nist-post-quantum-surprise/">their pick</a> for post-quantum key agreement. Now the baton has been handed to Industry to deploy post-quantum key agreement to protect today’s communications from the threat of future decryption by a quantum computer.</p><p>Cloudflare operates as a reverse proxy between clients (“visitors”) and customers’ web servers (“origins”), so that we can protect origin sites from attacks and improve site performance. In this post we explain how we secure the connection from Cloudflare to <i>origin servers</i>. To put that in context, let’s have a look at the connection involved when visiting an uncached page on a website served through Cloudflare.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2WZQZByAjMmuu53BzxjNik/170ebefe3aec6f8277f4c2e4e34b76f1/Connections-involved-when-user-visits-an-uncached-page-on-a-website-served-through-Cloudflare.png" />
            
            </figure><p>The first connection is from the visitor’s browser to Cloudflare. In October 2022, <a href="/post-quantum-for-all/">we enabled <i>X25519+Kyber</i> as a beta for all websites and APIs</a> served through Cloudflare. However, it takes two to tango: the connection is only secured if the browser also supports post-quantum cryptography. As of August 2023, <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">Chrome</a> is slowly enabling <i>X25519+Kyber</i> by default.</p><p>The visitor’s request is routed through Cloudflare’s network (2). We have <a href="/post-quantum-cryptography-ga">upgraded</a> many of these internal connections to use post-quantum cryptography, and expect to be done upgrading all of our internal connections by the end of 2024. That leaves as the final link the connection (3) between us and the <i>origin server</i>.</p><p>We are happy to announce that <b>we are rolling out support for X25519+Kyber for most outbound connections</b>, including <i>origin servers</i> and <a href="https://workers.cloudflare.com/">Cloudflare Workers</a> <code>fetch()</code> calls.</p>
<table>
<thead>
  <tr>
    <th><span>Plan</span></th>
    <th><span>Support for post-quantum outbound connections</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Free</span></td>
    <td><span>Started roll-out. Aiming for 100% by the end of the October.</span></td>
  </tr>
  <tr>
    <td><span>Pro and Business</span></td>
    <td><span>Started roll-out. Aiming for 100% by the end of year.</span></td>
  </tr>
  <tr>
    <td><span>Enterprise</span></td>
    <td><span>Start roll-out February 2024. 100% by March 2024.</span></td>
  </tr>
</tbody>
</table><p>You can skip the roll-out and opt-in your zone today, or opt-out ahead of time, using an API described below. Before rolling out this support for enterprise customers in February 2024, we will add a toggle on the dashboard to opt out.</p><p>In this post we will dive into the nitty-gritty of what we enabled; how we have to be a bit subtle to prevent breaking connections to origins that are not ready yet, and how you can add support to your (origin) server.</p><p>But before we dive in, for the impatient:</p>
    <div>
      <h3>Quick start</h3>
      <a href="#quick-start">
        
      </a>
    </div>
    <p>To enable a post-quantum connection between Cloudflare and your origin server today, opt-in your zone to skip the gradual roll-out:</p>
            <pre><code>curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "preferred"}'</code></pre>
            <p>Replace <a href="https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/"><code>(zone_id)</code></a> and <a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/"><code>(API token)</code></a> appropriately. Then, make sure your server supports TLS 1.3; enable and prefer the key agreement <code>X25519Kyber768Draft00;</code> and ensure it’s configured with <i>server cipher preference</i>. For example, to configure <a href="https://www.nginx.com/">nginx</a> (compiled with a recent <a href="https://boringssl.googlesource.com/boringssl">BoringSSL</a>) like this, use</p>
            <pre><code>	http {
		# [...]
		ssl_ecdh_curve X25519Kyber768Draft00:X25519;
		ssl_prefer_server_ciphers on;
		ssl_protocols TLSv1.3;
	}</code></pre>
            <p>To check your server is properly configured, you can use the <code>bssl</code> tool of <a href="https://github.com/google/boringssl">BoringSSL</a>:</p>
            <pre><code>	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            <p>We’re looking for <code>X25519Kyber768Draft00</code> for a post-quantum connection as shown above instead of merely <code>X25519</code>.For more client and server support, check out <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a>. Now, let’s dive in.</p>
    <div>
      <h2>Overview of a TLS 1.3 handshake</h2>
      <a href="#overview-of-a-tls-1-3-handshake">
        
      </a>
    </div>
    <p>To understand how a smooth upgrade is possible, and where it might go wrong, we need to understand a few basics of the TLS 1.3 protocol, which is used to protect traffic on the Internet. A TLS connection starts with a <b>handshake</b> which is used to authenticate the server and derive a shared key. The browser (client) starts by sending a <i>ClientHello</i> message that contains among other things, the hostname (SNI) and the list of key agreement methods it supports.</p><p>To remove a round trip, the client is allowed to make a guess of what the server supports and start the key agreement by sending one or more <i>client keyshares</i>. That guess might be correct (on the left in the diagram below) or the client has to retry (on the right). By the way, this guessing of keyshares is a <a href="/rfc-8446-aka-tls-1-3/">new feature of TLS 1.3</a>, and it is the main reason why it’s faster than TLS 1.2.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/QbpgdMdMdt9aW2nmrBSnT/97fee7c97d8c726e29fbf7b72666bfb6/image2-30.png" />
            
            </figure><p><i>Protocol flow for server-authenticated TLS 1.3 with a supported client keyshare on the left and a</i> HelloRetryRequest <i>on the right.</i></p><p>In both cases the client sends a <i>client keyshare</i> to the server. From this client keyshare the server generates the <i>shared key</i>. The server then returns a <i>server keyshare</i> with which the client can also compute the shared key. This shared key is used to protect the rest of the connection using symmetric cryptography, such as AES.</p><p>Today <a href="https://cr.yp.to/ecdh.html">X25519</a> is used as the key agreement in the vast majority of connections. To secure the connection against store-now/decrypt-later in the post-quantum world, a client can simply send a <a href="https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/">X25519+Kyber</a> keyshare.</p>
    <div>
      <h3>Hello! Retry Request? (HRR)</h3>
      <a href="#hello-retry-request-hrr">
        
      </a>
    </div>
    <p>What we just described is the happy flow, where the client guessed correctly which key agreement the server supports. If the server does not support the keyshare that the client sent, then the server picks one of the supported key agreements that the client advertised, and asks for it in a <i>HelloRetryRequest</i> message.</p><p>This is not the only case where a server can use a HelloRetryRequest: even if the client sent keyshares that the server supports, the server is allowed to prefer a different key agreement the client advertised, and ask for it with a HelloRetryRequest. This will turn out to be very useful.</p><p>_HelloRetryRequest_s are mostly undesirable: they add an extra round trip, and bring us back to the performance of TLS 1.2. We already had a transition of key agreement methods: back in the day P-256 was the de facto standard. When browsers couldn’t assume support for the newer X25519, some would send two keyshares, both X25519 and P-256 to prevent a <i>HelloRetryRequest</i>.</p><p>Also today, when enabling <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">Kyber in Chrome</a>, Chrome will send two keyshares: X25519 and X25519+Kyber to prevent a <i>HelloRetryRequest</i>. Sending two keyshares is not ideal: it requires the client to compute more, and it takes more space on the wire. This becomes more problematic when we want to send two post-quantum keyshares, as post-quantum keyshares are much larger. Talking about post-quantum keyshares, let’s have a look at X25519+Kyber.</p>
    <div>
      <h2>The nitty-gritty of X25519+Kyber</h2>
      <a href="#the-nitty-gritty-of-x25519-kyber">
        
      </a>
    </div>
    <p>The full name of the post-quantum key agreement we have enabled is <a href="https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/">X25519Kyber768Draft00</a>, which has become the industry standard for early deployment. It is the combination (a so-called <i>hybrid</i>, more about that later) of two key agreements: <a href="https://cr.yp.to/ecdh.html">X25519</a> and a <a href="https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/">preliminary version</a> of NIST’s pick Kyber. Preliminary, because standardization of Kyber is not complete: NIST has released a <a href="https://csrc.nist.gov/pubs/fips/203/ipd">draft standard</a> for which it has requested public input. The final standard might change a little, but we do not expect any radical changes in security or performance. One notable change is the name: the NIST standard is set to be called <a href="https://csrc.nist.gov/pubs/fips/203/ipd"><i>ML-KEM</i></a>. Once ML-KEM is released in 2024, we will promptly adopt support for the corresponding hybrid, and deprecate support for X25519Kyber768Draft00. We will announce deprecation on this blog and <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a>.</p>
    <div>
      <h3>Picking security level: 512 vs 768</h3>
      <a href="#picking-security-level-512-vs-768">
        
      </a>
    </div>
    <p>Back in 2022, for incoming connections, <a href="/post-quantum-for-all/">we enabled</a> hybrids with both Kyber512 and Kyber768. The difference is target security level: Kyber512 aims for the same security as AES-128, whereas Kyber768 matches up with AES-192. Contrary to popular belief, AES-128 is <a href="/nist-post-quantum-surprise/#grover-s-algorithm">not broken</a> in practice by quantum computers.</p><p>So why go with Kyber768? After years of analysis, there is no indication that Kyber512 fails to live up to its target security level. The designers of Kyber feel more comfortable, though, with the wider security margin of Kyber768, and we follow their advice.</p>
    <div>
      <h3>Hybrid</h3>
      <a href="#hybrid">
        
      </a>
    </div>
    <p>It is not inconceivable though, that an unexpected improvement in cryptanalysis will completely break Kyber768. Notably <a href="https://eprint.iacr.org/2022/214.pdf">Rainbow</a>, GeMMS and <a href="https://eprint.iacr.org/2022/975">SIDH</a> survived several rounds of public review before being broken. We do have to add nuance here. For a big break you need some mathematical trick, and compared to other schemes, SIDH had a lot of <i>mathematical attack surface</i>. Secondly, even though a scheme participated in many rounds of review doesn’t mean it saw a lot of attention. Because of their performance characteristics, these three schemes have more niche applications, and therefore received much less scrutiny from cryptanalysts. In contrast, Kyber is the big prize: breaking it will ensure fame.</p><p>Notwithstanding, for the moment, we feel it’s wiser to stick with hybrid key agreement. We combine Kyber together with X25519, which is currently the de facto standard key agreement, so that if Kyber turns out to be broken, we retain the non-post quantum security of X25519.</p>
    <div>
      <h3>Performance</h3>
      <a href="#performance">
        
      </a>
    </div>
    <p>Kyber is fast. Very fast. It easily beats X25519, which is already known for its speed:</p><table>
	<thead>
		<tr>
			<th> </th>
			<th> </th>
			<th><span>Size keyshares(in bytes)</span></th>
			<th><span>Ops/sec (higher is better)</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span>Algorithm</span></td>
			<td><span>PQ</span></td>
			<td><strong>Client</strong></td>
			<td><strong>Server</strong></td>
			<td><strong>Client</strong></td>
			<td><strong>Server</strong></td>
		</tr>
		<tr>
			<td><strong>X25519</strong></td>
			<td><span>❌</span></td>
			<td><span>32</span></td>
			<td><span>32</span></td>
			<td><span>17,000</span></td>
			<td><span>17,000</span></td>
		</tr>
		<tr>
			<td><strong>Kyber768</strong></td>
			<td><span>✅</span></td>
			<td><span>1,184</span></td>
			<td><span>1,088</span></td>
			<td><span>31,000</span></td>
			<td><span>70,000</span></td>
		</tr>
		<tr>
			<td><strong>X25519Kyber768Draft00</strong></td>
			<td><span>✅</span></td>
			<td><span>1,216</span></td>
			<td><span>1,120</span></td>
			<td><span>11,000</span></td>
			<td><span>14,000</span></td>
		</tr>
	</tbody>
</table><p>Combined X25519Kyber768Draft00 is slower than X25519, but not by much. The big difference is its size: when connecting the client has to send 1,184 extra bytes for Kyber in the first message. That brings us to the next topic.</p>
    <div>
      <h2>When things break, and how to move forward</h2>
      <a href="#when-things-break-and-how-to-move-forward">
        
      </a>
    </div>
    
    <div>
      <h3>Split ClientHello</h3>
      <a href="#split-clienthello">
        
      </a>
    </div>
    <p>As we saw, the <i>ClientHello</i> is the first message that is sent by the client when setting up a TLS connection. With X25519, the ClientHello almost always fits within one network packet. With Kyber, the ClientHello doesn’t fit anymore with typical packet sizes and needs to be split over two network packets.</p><p>The TLS standard allows for the ClientHello to be split in this way. However, it used to be so exceedingly rare to see a split ClientHello that there is plenty of software and hardware out there that falsely assumes it never happens.</p><p>This so-called <b>protocol ossification</b> is the major challenge rolling out post-quantum key agreement. Back in 2019, during <a href="/the-tls-post-quantum-experiment/">earlier post-quantum experiments</a>, middleboxes of a particular vendor dropped connections with a split ClientHello. Chrome is currently <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">slowly ramping up</a> the number of post-quantum connections to catch these issues early. Several reports are listed <a href="https://twitter.com/davidcadrian/status/1692572405368078816">here</a>, and luckily most vendors seem to fix issues promptly.</p><p>Over time, with the slow ramp up of browsers, many of these implementation bugs will be found and corrected. However, we cannot completely rely on this for our outbound connections since in many cases Cloudflare is the sole client to connect directly to the origin server. Thus, we must exercise caution when deploying post-quantum cryptography to ensure that we are still able to reach origin servers even in the presence of buggy implementations.</p>
    <div>
      <h3>HelloRetryRequest to the rescue</h3>
      <a href="#helloretryrequest-to-the-rescue">
        
      </a>
    </div>
    <p>To enable support for post-quantum key agreement on all outbound connections, without risking issues with split ClientHello for those servers that are not ready yet, we make clever use of HelloRetryRequest. Instead of sending a X25519+Kyber keyshare, we will only advertise support for it, and send a non-post quantum secure X25519 keyshare in the first ClientHello.</p><p>If the origin does not support X25519+Kyber, then nothing changes. One might wonder: could merely advertising support for it trip up any origins? This used to be a real concern in the past, but luckily browsers have adopted a clever mechanism called <a href="https://datatracker.ietf.org/doc/html/rfc8701">GREASE</a>: they will send codepoints selected from unpredictable regions to make it hard to implement any software that could trip up on unknown codepoints.</p><p>If the origin does support X25519+Kyber, then it can use the HelloRetryRequest to request a post-quantum key agreement from us.</p><p>Things might still break then: for instance a malfunctioning middlebox, load-balancer, or the server software itself might still trip over the large ClientHello with X25519+Kyber sent in response to the HelloRetryRequest.</p><p>If we’re frank, the HRR trick kicks the can down the road: we as an industry will need to fix broken hardware and software before we can enable post-quantum on every last connection. The important thing though is that those past mistakes will not hold us back from securing the majority of connections. Luckily, from our experience, breakage will not be common.</p><p>So, when you have flipped the switch on your origin server, and things do break against expectation, what could be the root cause?</p>
    <div>
      <h3>Debugging and examples</h3>
      <a href="#debugging-and-examples">
        
      </a>
    </div>
    <p>It’s impossible to exhaustively list all bugs that could interfere with the post-quantum connection, but we like to share a few we’ve seen.</p><p>The first step is to figure out what pieces of hardware and software are involved in the connection. Rarely it’s just the server: there could be a load-balancer, and even a humble router could be at fault.</p><p>One straightforward mistake is to conveniently assume the ClientHello is small by reserving only a small, say 1000 byte, buffer.</p><p>A variation of this is where a server uses a single call to <a href="https://man7.org/linux/man-pages/man2/recv.2.html"><code>recv()</code></a> to read the ClientHello from the TCP connection. This works perfectly fine if it fits within one packet, but when split over multiple, it might require more calls.</p><p>Not all issues that we encountered relate directly to split ClientHello. For instance, servers using the Rust TLS library <a href="https://github.com/rustls/rustls">rustls</a> did <a href="https://github.com/rustls/rustls/issues/1373">not implement HelloRetryRequest correctly</a> before 0.21.7.</p><p>If you turned on post-quantum support for your origin, and hit issues, please do reach out: email <a>ask-research@cloudflare.com</a>.</p>
    <div>
      <h2>Opting in and opting out</h2>
      <a href="#opting-in-and-opting-out">
        
      </a>
    </div>
    <p>Now that you know what might lie in wait for you, let’s cover how to configure the outbound connections of your zone. There are three settings. The setting affects all outbound connections for your zone: to the origin server, but also for <code>fetch()</code> requests made by Workers on your zone.</p><table>
	<thead>
		<tr>
			<th><strong>Setting</strong></th>
			<th><strong>Meaning</strong></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span><span>supported</span></span></td>
			<td><span>Advertise support for post-quantum key agreement, but send a classical keyshare in the first </span><em>ClientHello</em><span>.When the origin supports and prefers X25519+Kyber, a post-quantum connection will be established, but it incurs an extra roundtrip.This is the most compatible way to enable post-quantum.</span></td>
		</tr>
		<tr>
			<td><span><span>preferred</span></span></td>
			<td><span>Send a post-quantum keyshare in the first </span><em>ClientHello</em><span>.When the origin supports X25519+Kyber, a post-quantum connection will be established without an extra roundtrip. We continue advertising support for classical keyshares as well, so that origins that do not support X25519+Kyber will continue to function.
This is the most performant way to enable post-quantum.</span></td>
		</tr>
		<tr>
			<td><span><span>off</span></span></td>
			<td><span>Do not send or advertise support for post-quantum key agreement to the origin.</span></td>
		</tr>
		<tr>
			<td><span>(default)</span></td>
			<td><span>Allow us to determine the best behavior for your zone. (More about that later.)</span></td>
		</tr>
	</tbody>
</table><p>The setting can be adjusted using the following API call:</p>
            <pre><code>curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "(setting)"}'</code></pre>
            <p>Here, the parameters are as follows.</p><table>
	<thead>
		<tr>
			<th><strong>Parameter</strong></th>
			<th><strong>Value</strong></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span>setting</span></td>
			<td><span><span>supported</span>, <span>preferred</span>, or <span>off</span>, with meaning as described above</span></td>
		</tr>
		<tr>
			<td><span>zone_id</span></td>
			<td><span>Identifier of the zone to control. You can </span><a href="https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/"><u>look up the zone_id</u></a><span> in the dashboard.</span></td>
		</tr>
		<tr>
			<td><span>API token</span></td>
			<td><span>Token used to authenticate you. You can </span><a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/"><u>create one in the dashboard</u></a><span>. Use </span><em>create custom token</em><span> and under permissions select </span><em>zone → zone settings → edit</em><span>.</span></td>
		</tr>
	</tbody>
</table>
    <div>
      <h3>Testing whether your origin server is configured correctly</h3>
      <a href="#testing-whether-your-origin-server-is-configured-correctly">
        
      </a>
    </div>
    <p>If you set your zone to <code>preferred</code> mode, you only need to check support for the proper post-quantum key agreement with your origin server. This can be done with the <code>bssl</code> tool of <a href="https://github.com/google/boringssl">BoringSSL</a>:</p>
            <pre><code>	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            <p>If you set your zone to <code>supported</code> mode, or if you wait for the gradual roll-out, you will need to make sure that your origin server prefers post-quantum key agreement even if we sent a classical keyshare in the initial <i>ClientHello</i>. This can be done with <a href="https://github.com/cloudflare/boringssl-pq">our fork of BoringSSL</a>:</p>
            <pre><code>	$ git clone https://github.com/cloudflare/boringssl-pq
	[...]
	$ cd boringssl-pq &amp;&amp; cmake -B build &amp;&amp; make -C build
$ build/bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00 -disable-second-keyshare
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            
    <div>
      <h2>Scanning ahead to remove the extra roundtrip</h2>
      <a href="#scanning-ahead-to-remove-the-extra-roundtrip">
        
      </a>
    </div>
    <p>With the <i>HelloRetryRequest</i> trick today, we can safely advertise support for post-quantum key agreement to all origins. The downside is that for those origins that do support post-quantum key agreement, we’re incurring an extra roundtrip for the <i>HelloRetryRequest</i>, which hurts performance.</p><p>You can remove the roundtrip by configuring your zone as <code>preferred</code>, but we can do better: the best setting is the one you shouldn’t have to touch.</p><p>We have started scanning all active origins for support of post-quantum key agreement. Roughly every 24 hours, we will attempt a series of about ten TLS connections to your origin, to test support and preferences for the various key agreements.</p><p>Our preliminary results show that 0.5% of origins support a post-quantum connection. As expected, we found that a small fraction (&lt;0.34%) of all origins do not properly establish a connection, when we send a post-quantum keyshare in the first ClientHello, which corresponds to the <code>preferred</code> setting. Unexpectedly the vast majority of these origins do return a <i>HelloRetryRequest</i>, but fail after receiving the second ClientHello with a classical keyshare. We are investigating the exact causes of these failures, and will reach out to vendors to help resolve them.</p><p>Later this year, we will start using these scan results to determine the best setting for zones that haven’t been configured yet. That means that for those zones whose origins support it reliably, we will send a post-quantum keyshare directly without extra roundtrip.</p>
    <div>
      <h3>Also speeding up non post-quantum origins</h3>
      <a href="#also-speeding-up-non-post-quantum-origins">
        
      </a>
    </div>
    <p>The scanner pipeline we built will not just benefit post-quantum origins. By default we send X25519, but not every origin supports or prefers X25519. We find that 4% of origin servers will send us a HelloRetryRequest for other key agreements such as P-384.</p>
<table>
<thead>
  <tr>
    <th><span>Key agreement</span></th>
    <th><span>Fraction supported</span></th>
    <th><span>Fraction preferred</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>X25519</span></td>
    <td><span>96%</span></td>
    <td><span>96%</span></td>
  </tr>
  <tr>
    <td><span>P-256</span></td>
    <td><span>97%</span></td>
    <td><span>0.6%</span></td>
  </tr>
  <tr>
    <td><span>P-384</span></td>
    <td><span>89%</span></td>
    <td><span>2.3%</span></td>
  </tr>
  <tr>
    <td><span>P-521</span></td>
    <td><span>82%</span></td>
    <td><span>0.1%</span></td>
  </tr>
  <tr>
    <td><span>X25519Kyber768Draft00</span></td>
    <td><span>0.5%</span></td>
    <td><span>0.5%</span></td>
  </tr>
</tbody>
</table><p>Also, later this year, we will use these scan results to directly send the most preferred keyshare to your origin removing the need for an extra roundtrip caused by HRR.</p>
    <div>
      <h2>Wrapping up</h2>
      <a href="#wrapping-up">
        
      </a>
    </div>
    <p>To mitigate the <i>store-now/decrypt-later</i> threat, and ensure the Internet stays encrypted, the IT industry needs to work together to roll out post-quantum cryptography. We’re excited that today we’re rolling out support for post-quantum secure outbound connections: connections between Cloudflare and the origins.</p><p>We would love it if you would try and enable post-quantum key agreement on your origin. Please, do share your experiences, or reach out for any questions: <a>ask-research@cloudflare.com</a>.</p><p>To follow the latest developments of our deployment of post-quantum cryptography, and client/server support, check out <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a> and keep an eye on this blog.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">7D9GZLWGiSDKHz84NFp54d</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Luke Valenta</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
        <item>
            <title><![CDATA[No, AI did not break post-quantum cryptography]]></title>
            <link>https://blog.cloudflare.com/kyber-isnt-broken/</link>
            <pubDate>Thu, 16 Mar 2023 13:00:00 GMT</pubDate>
            <description><![CDATA[ The recent news reports of AI cracking post-quantum cryptography are greatly exaggerated. In this blog, we take a deep dive into the world of side-channel attacks and how AI has been used for more than a decade already to aid it ]]></description>
            <content:encoded><![CDATA[ <p></p><p><a href="https://www.securityweek.com/ai-helps-crack-a-nist-recommended-post-quantum-encryption-algorithm/">News coverage</a> of a recent paper caused a bit of a stir with this headline: “<a href="https://www.securityweek.com/ai-helps-crack-a-nist-recommended-post-quantum-encryption-algorithm/">AI Helps Crack NIST-Recommended Post-Quantum Encryption Algorithm</a>”. The news article claimed that <a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a>, the encryption algorithm in question, <a href="/post-quantum-for-all/">which we have deployed world-wide</a>, had been “broken.” Even more dramatically, the news article claimed that “the revolutionary aspect of the research was to apply deep learning analysis to side-channel differential analysis”, which seems aimed to scare the reader into wondering what will <a href="https://www.cloudflare.com/learning/ai/what-is-artificial-intelligence/">Artificial Intelligence (AI)</a> break next?</p><p>Reporting on the paper has been wildly inaccurate: <b>Kyber is not broken</b> and AI has been used for more than a decade now to aid side-channel attacks. To be crystal clear: our concern is with the news reporting around the paper, not the quality of the paper itself. In this blog post, we will explain how AI is actually helpful in cryptanalysis and dive into the <a href="https://eprint.iacr.org/2022/1713">paper</a> by Dubrova, Ngo, and Gärtner (DNG), that has been misrepresented by the news coverage. We’re honored to have Prof. Dr. <a href="https://www.cs.ru.nl/~lejla/">Lejla Batina</a> and Dr. <a href="https://www.ru.nl/en/people/picek-s">Stjepan Picek</a>, world-renowned experts in the field of applying AI to side-channel attacks, join us on this blog.</p><p>We start with some background, first on side-channel attacks and then on Kyber, before we dive into the paper.</p>
    <div>
      <h2>Breaking cryptography</h2>
      <a href="#breaking-cryptography">
        
      </a>
    </div>
    <p>When one thinks of breaking cryptography, one imagines a room full of mathematicians puzzling over minute patterns in intercepted messages, aided by giant computers, until they figure out the key. Famously in World War II, the Nazis’ Enigma cipher machine code was completely broken in this way, allowing the Allied forces to read along with their communications.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/oJxQ8srTTh2HafYmNbKaP/c07d942fdda653c963fd047756e8b6f4/image7-5.png" />
            
            </figure><p>It’s exceedingly rare for modern established cryptography to get broken head-on in this way. The last catastrophically broken cipher was RC4, designed in 1987, while AES, designed in 1998, stands proud with barely a scratch. The last big break of a cryptographic hash was on SHA-1, designed in 1995, while SHA-2, published in 2001, remains untouched in practice.</p><p>So what to do if you can’t break the cryptography head-on? Well, you get clever.</p>
    <div>
      <h2>Side-channel attacks</h2>
      <a href="#side-channel-attacks">
        
      </a>
    </div>
    <p>Can you guess the pin code for this gate?</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1UhJuQgQaoWjZ4JHSAHff6/0bebc7553f411c4246a750e39b1f627f/image4-1.jpg" />
            
            </figure><p>You can clearly see that some of the keys are more worn than the others, suggesting heavy use. This observation gives us some insight into the correct pin, namely the digits. But the correct order is not immediately clear. It might be 1580, 8510, or even 115085, but it’s a lot easier than trying every possible pin code. This is an example of a <i>side-channel attack</i>. Using the security feature (entering the PIN) had some unintended consequences (abrading the paint), which leaks information.</p><p>There are many different types of side channels, and which one you should worry about depends on the context. For instance, the sounds your keyboard makes as you type <a href="https://dl.acm.org/doi/abs/10.1145/1609956.1609959">leaks what you write</a>, but you should not worry about that if no one is listening in.</p>
    <div>
      <h3>Remote timing side channel</h3>
      <a href="#remote-timing-side-channel">
        
      </a>
    </div>
    <p>When writing cryptography in software, one of the best known side channels is the time it takes for an algorithm to run. For example, let’s take the classic example of creating an RSA signature. Grossly simplified, to sign a message <i>m</i> with private key <i>d</i>, we compute the signature <i>s</i> as m<sup>d</sup> (mod n). Computing the exponent of a big number is hard, but luckily, because we’re doing modular arithmetic, there is the <a href="https://youtu.be/cbGB__V8MNk">square-and-multiply</a> trick. Here is a naive implementation in pseudocode:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ugGnB4EmViLt8e9E97YyJ/d204b867a50f5470d0ae680f4eea47fd/Screenshot-2023-03-16-at-12.35.40.png" />
            
            </figure><p>The algorithm loops over the bits of the secret key, and does a <i>multiply</i> step if the current bit is a 1. Clearly, the runtime depends on the secret key. Not great, but if the attacker can only time the full run, then they only learn the number of 1s in the secret key. The typical catastrophic timing attack against RSA instead is hidden behind the “<b>mod</b> n”. In a naive implementation this modular reduction is slower if the number being reduced is larger or equal <i>n</i>. This <a href="https://www.cs.sjsu.edu/faculty/stamp/students/article.html#:~:text=Timing%20attacks%20are%20a%20form,performed%20or%20the%20media%20used.">allows</a> an attacker to send specially crafted messages to tease out the secret key bit-by-bit and similar attacks are <a href="https://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf">surprisingly practical</a>.</p><p>Because of this, the mantra is: cryptography should run in “constant time”. This means that the runtime does not depend on any secret information. In our example, to remove the first timing issue, one would replace the if-statement with something equivalent to:</p>
            <pre><code>	s = ((s * powerOfM) mod n) * bit(s, i) + s * (1 - bit(s, i))</code></pre>
            <p>This ensures that the multiplication is always done. Similar countermeasures prevent practically all remote timing attacks.</p>
    <div>
      <h3>Power side-channel</h3>
      <a href="#power-side-channel">
        
      </a>
    </div>
    <p>The story is quite different for power side-channel attacks. Again, the classic example is RSA signatures. If we hook up an oscilloscope to a smartcard that uses the naive algorithm from before, and measure the power usage while it signs, we can read off the private key by eye:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5BgQG934ghuxV9D6JoSF0H/14c882de669ff23990f96a1281304e3f/image1-33.png" />
            
            </figure><p>Even if we use a constant-time implementation, there are still minute changes in power usage that can be detected. The underlying issue is that hardware gates that switch use more power than those that don’t. For instance, computing 127 + 64 takes more energy than 64 + 64.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3U58Xc7isXGpdg2bHxhTRA/c8b3ea9d01d38f9af644a2cd51079caf/image3-25.png" />
            
            </figure><p><i>127+64 and 64+64 in binary. There are more switched bits in the first.</i></p><p><b>Masking</b>A common countermeasure against power side-channel leakage is <i>masking</i>. This means that before using the secret information, it is split randomly into <i>shares</i>. Then, the brunt of the computation is done on the shares, which are finally recombined.</p><p>In the case of RSA, before creating a new signature, one can generate a random <i>r</i> and compute m<sup>d+r</sup> (mod n) and m<sup>r</sup> (mod n) separately. From these, the final signature m<sup>d</sup> (mod n) can be computed with some extra care.</p><p>Masking is not a perfect defense. The parts where shares are created or recombined into the final value are especially vulnerable. It does make it harder for the attacker: they will need to collect more power traces to cut through the noise. In our example we used two shares, but we could bump that up even higher. There is a trade-off between power side-channel resistance and implementation cost.</p><p>One of the challenging parts in the field is to estimate how much secret information is actually leaked through the traces, and how to extract it. Here machine learning enters the picture.</p>
    <div>
      <h3>Machine learning: extracting the key from the traces</h3>
      <a href="#machine-learning-extracting-the-key-from-the-traces">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">Machine learning</a>, of which deep learning is a part, represents the capability of a system to acquire its knowledge by extracting patterns from data —  in this case, the secrets from the power traces. Machine learning algorithms can be divided into several categories based on their learning style. The most popular machine learning algorithms in side-channel attacks follow the supervised learning approach. In supervised learning, there are two phases: 1) training, where a machine learning model is trained based on known labeled examples (e.g., side-channel measurements where we know the key) and 2) testing, where, based on the trained model and additional side-channel measurements (now, with an unknown key), the attacker guesses the secret key. A common depiction of such attacks is given in the figure below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4V2bcSsbSJtCmorq8HaUzc/1545a94c79aef5d72b6acd8573cf5f07/image5-3.png" />
            
            </figure><p>While the threat model may sound counterintuitive, it is actually not difficult to imagine that the attacker will have access (and control) of a device similar to the one being attacked.</p><p>In side-channel analysis, the attacks following those two phases (training and testing) are called profiling attacks.</p><p>Profiling attacks are not new. The first such attack, called the <a href="https://link.springer.com/chapter/10.1007/3-540-36400-5_3">template attack</a>, appeared in 2002. Diverse <a href="https://link.springer.com/article/10.1007/s13389-011-0023-x">machine learning techniques</a> have been used since around 2010, all reporting good results and the ability to break various targets. The big breakthrough came in 2016, when the side-channel community started using <a href="https://www.cloudflare.com/learning/ai/what-is-deep-learning/">deep learning</a>. It greatly increased the effectiveness of power side-channel attacks both against symmetric-key and public-key cryptography, even if the targets were protected with, for instance, masking or some other countermeasures. To be clear: it doesn’t magically figure out the key, but it gets much better at extracting the leaked bits from a smaller number of power traces.</p><p>While machine learning-based side-channel attacks are powerful, they have limitations. Carefully implemented countermeasures make the attacks more difficult to conduct. Finding a good machine learning model that can break a target can be far from trivial: this phase, commonly called tuning, can last weeks on powerful clusters.</p><p>What will the future bring for machine learning/AI in side-channel analysis? Counter intuitively, we would like to see more powerful and easy to use attacks. You’d think that would make us worse off, but to the contrary it will allow us to better estimate how much actual information is leaked by a device. We also hope that we will be able to better understand why certain attacks work (or not), so that more cost-effective countermeasures can be developed. As such, the future for AI in side-channel analysis is bright especially for security evaluators, but we are still far from being able to break most of the targets in real-world applications.</p>
    <div>
      <h2>Kyber</h2>
      <a href="#kyber">
        
      </a>
    </div>
    <p>Kyber is a <a href="/the-quantum-menace/">post-quantum</a> (PQ) key encapsulation method (KEM). After a six-year worldwide competition, the <a href="https://www.nist.gov/">National Institute of Standards and Technology</a> (NIST) <a href="/nist-post-quantum-surprise/">selected</a> Kyber as the post-quantum key agreement they will standardize. The goal of a key agreement is for two parties that haven’t talked to each other before to agree securely on a <i>shared key</i> they can use for symmetric encryption (such as <a href="/it-takes-two-to-chacha-poly/">Chacha20Poly1305</a>). As a KEM, it works slightly different with different terminology than a traditional <a href="https://developers.cloudflare.com/internet/protocols/tls#ephemeral-diffie-hellman-handshake">Diffie–Hellman</a> key agreement (such as X25519):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Dbor76rFhzvg1PhuCI0xT/9bbd95bd542a065a679b5b27e2c188cb/image9-3.png" />
            
            </figure><p>When connecting to a website the client first generates a new <i>ephemeral</i> keypair that consists of a <i>private</i> and <i>public key</i>. It sends the public key to the server. The server then <i>encapsulates</i>  a shared key with that public key, which gives it a random <i>shared key</i>, which it keeps, and a ciphertext (in which the shared key is hidden), which the server returns to the client. The client can then use its private key to <i>decapsulate</i> the shared key from the ciphertext. Now the server and client can communicate with each other using the shared key.</p><p>Key agreement is particularly important to make secure against attacks of quantum computers. The reason is that an attacker can store traffic today, and crack the key agreement in the future, revealing the shared key and all communication encrypted with it afterwards. That is why we have already <a href="/post-quantum-for-all/">deployed support</a> for Kyber across our network.</p>
    <div>
      <h2>The DNG paper</h2>
      <a href="#the-dng-paper">
        
      </a>
    </div>
    <p>With all the background under our belt, we’re ready to take a look at the <a href="https://eprint.iacr.org/2022/1713.pdf">DNG paper</a>. The authors perform a power side-channel attack on their own masked implementation of Kyber with six shares.</p>
    <div>
      <h3>Point of attack</h3>
      <a href="#point-of-attack">
        
      </a>
    </div>
    <p>They attack the <i>decapsulation</i> step. In the decapsulation step, after the shared key is extracted, it’s encapsulated again, and compared against the original ciphertext to detect tampering. For this <i>re-encryption</i> step, the precursor of the shared key—let’s call it the secret—is encoded bit-by-bit into a polynomial. To be precise, the 256-bit <i>secret</i> needs to be converted to a polynomial with 256 coefficients <i>modulo</i> q=3329, where the i<sup>th</sup> coefficient is (q+1)/2 if the ith b<sup>th</sup> is 1 and zero otherwise.</p><p>This function sounds simple enough, but creating a masked version is tricky. The rub is that the natural way to create shares of the <i>secret</i> is to have shares that <i>xor</i> together to be the secret, and that the natural way to share polynomials is to have shares that <i>add</i> together to get to the intended polynomial.</p><p>This is the two-shares implementation of the conversion that the DNG paper attacks:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7GjnFQyhXsLRqHJqgypOpx/c93d159488b4ba8ef043e1049eb21649/image8.png" />
            
            </figure><p>The code loops over the bits of the two shares. For each bit, it creates a mask, that’s <code>0xffff</code> if the bit was 1 and 0 otherwise. Then this mask is used to add (q+1)/2 to the polynomial share if appropriate. Processing a 1 will use a bit more power. It doesn’t take an AI to figure out that this will be a leaky function. In fact, this pattern was pointed out to be weak <a href="https://eprint.iacr.org/2016/923">back in 2016</a>, and explicitly mentioned to be a risk for masked Kyber <a href="https://eprint.iacr.org/2016/923">in 2020</a>. Apropos, one way to mitigate this, is to process multiple bits at once — for the state of the art, tune into <a href="https://csrc.nist.gov/Projects/post-quantum-cryptography/workshops-and-timeline/pqc-seminars">April 2023’s NIST PQC seminar</a>. For the moment, let’s allow the paper its weak target.</p><p>The authors do not claim any fundamentally new attack here. Instead, they improve the effectiveness of the attack in two ways: the way they train the <a href="https://www.cloudflare.com/learning/ai/what-is-neural-network/">neural network</a>, and how to use multiple traces more effectively by changing the ciphertext sent. So, what did they achieve?</p>
    <div>
      <h3>Effectiveness</h3>
      <a href="#effectiveness">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1nVauArEr9f940eJstkDu5/8c793320acb617a3ae0436908196e546/image6-7.png" />
            
            </figure><p>To test the attack, they use a <a href="https://www.newae.com/products/NAE-CW1173#:~:text=The%20ChipWhisperer%2DLite%20integrates%20hardware,all%20into%20a%20single%20board.">Chipwhisperer-lite</a> board, which has a Cortex M4 CPU, which they downclock to 24Mhz. Power usage is sampled at 24Mhz, with high 10-bit precision.</p><p>To train the neural networks, 150,000 power traces are collected for decapsulation of different ciphertexts (with known shared key) for the same KEM keypair. This is already a somewhat unusual situation for a real-world attack: for key agreement KEM keypairs are ephemeral; generated and used only once. Still, there are certainly legitimate use cases for long-term KEM keypairs, such as <a href="/kemtls-post-quantum-tls-without-signatures/">for authentication</a>, <a href="/hybrid-public-key-encryption/">HPKE</a>, and in particular <a href="/encrypted-client-hello/">ECH</a>.</p><p>The training is a key step: different devices even from the same manufacturer can have wildly different power traces running the same code. Even if two devices are of the same model, their power traces might still differ significantly.</p><p>The main contribution highlighted by the authors is that they train their neural networks to attack an implementation with 6 shares, by starting with a neural network trained to attack an implementation with 5 shares. That one can be trained from a model to attack 4 shares, and so on. Thus to apply their method, of these 150,000 power traces, one-fifth must be from an implementation with 6 shares, another one-fifth from one with 5 shares, et cetera. It seems unlikely that anyone will deploy a device where an attacker can switch between the number of shares used in the masking on demand.</p><p>Given these affordances, the attack proper can commence. The authors report that, from a single power trace of a two-share decapsulation, they could recover the shared key under these ideal circumstances with probability… 0.12%. They do not report the numbers for single trace attacks on more than two shares.</p><p>When we’re allowed multiple traces of the same decapsulation, side-channel attacks become much more effective. The second trick is a clever twist on this: instead of creating a trace of decapsulation of exactly the same message, the authors <i>rotate</i> the ciphertext to move bits of the shared key in more favorable positions. With 4 traces that are rotations of the same message, the success probability against the two-shares implementation goes up to 78%. The six-share implementation stands firm at 0.5%. When allowing 20 traces from the six-share implementation, the shared key can be recovered with an 87% chance.</p>
    <div>
      <h3>In practice</h3>
      <a href="#in-practice">
        
      </a>
    </div>
    <p>The hardware used in the demonstration might be somewhat comparable to a smart card, but it is very different from high-end devices such as smartphones, desktop computers and servers. Simple power analysis side-channel attacks on even just embedded 1GHz processors are much more challenging, requiring <a href="https://eprint.iacr.org/2015/727.pdf">tens of thousands of traces</a> using a high-end oscilloscope connected close to the processor. There are much better avenues for attack with this kind of physical access to a server: just connect the oscilloscope to the memory bus.</p><p>Except for especially vulnerable applications, such as smart cards and HSMs, power-side channel attacks are widely considered infeasible. Although sometimes, when the planets align,  an especially potent power side-channel attack can be turned into a remote timing attack due to throttling, as demonstrated by <a href="/hertzbleed-explained/">Hertzbleed</a>. To be clear: the present attack does not even come close.</p><p>And even for these vulnerable applications, such as smart cards, this attack is not particularly potent or surprising. In the field, it is not a question of whether a masked implementation leaks its secrets, because it always does. It’s a question of how hard it is to actually pull off. Papers such as the DNG paper contribute by helping manufacturers estimate how many countermeasures to put in place, to make attacks too costly. It is not the first paper studying power side-channel attacks on Kyber and it will not be the last.</p>
    <div>
      <h2>Wrapping up</h2>
      <a href="#wrapping-up">
        
      </a>
    </div>
    <p>AI did not completely undermine a new wave of cryptography, but instead is a helpful tool to deal with noisy data and discover the vulnerabilities within it. There is a big difference between a direct break of cryptography and a power side-channel attack. Kyber is not broken, and the presented power side-channel attack is not cause for alarm.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Guest Post]]></category>
            <guid isPermaLink="false">5nkxnUeSeZlhciKkqTAbah</guid>
            <dc:creator>Lejla Batina (Guest Author)</dc:creator>
            <dc:creator>Stjepan Picek (Guest Author)</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Inside Geo Key Manager v2: re-imagining access control for distributed systems]]></title>
            <link>https://blog.cloudflare.com/inside-geo-key-manager-v2/</link>
            <pubDate>Fri, 27 Jan 2023 14:00:00 GMT</pubDate>
            <description><![CDATA[ Using the story of Geo Key Manager v2 as an example, let’s re-imagine access control for distributed systems using a variant of public-key cryptography, called attribute-based encryption. ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LkGR7C3vqnJCAudl3sGpL/ecbf276116cffbcaac0c3548d955510d/image1-49.png" />
            
            </figure><p>In December 2022 we announced the closed beta of the new version of <a href="/configurable-and-scalable-geo-key-manager-closed-beta/">Geo Key Manager</a>. Geo Key Manager v2 (GeoV2) is the next step in our journey to provide customers with a secure and flexible way to control the distribution of their private keys by geographic location. Our original system, <a href="/introducing-cloudflare-geo-key-manager/">Geo Key Manager v1</a>, was launched as a research project in 2017, but as customer needs evolved and our scale increased, we realized that we needed to make significant improvements to provide a better user experience.</p><p>One of the principal challenges we faced with Geo Key Manager v1 (GeoV1) was the inflexibility of our access control policies. Customers required richer data localization, often spurred by regulatory concerns. Internally, events such as the conflict in Ukraine reinforced the need to be able to quickly restrict access to sensitive key material. Geo Key Manager v1’s underlying cryptography was a combination of identity-based broadcast encryption and identity-based revocation that simulated a subset of the functionality offered by Attribute-Based Encryption (ABE). Replacing this with an established ABE scheme addressed the inflexibility of our access control policies and provided a more secure foundation for our system.</p><p>Unlike our previous scheme, which limited future flexibility by freezing the set of participating data centers and policies at the outset, using ABE made the system easily adaptable for future needs. It allowed us to take advantage of performance gains from additional data centers added after instantiation and drastically simplified the process for handling changes to attributes and policies. Furthermore, GeoV1 struggled with some perplexing performance issues that contributed to high tail latency and a painfully manual key rotation process. GeoV2 is our answer to these challenges and limitations of GeoV1.</p><p>While this blog focuses on our solution for geographical key management, the lessons here can also be applied to other access control needs. Access control solutions are traditionally implemented using a highly-available central authority to police access to resources. As we will see, ABE allows us to avoid this single point of failure. As there are no large scale ABE-based access control systems we are aware of, we hope our discussion can help engineers consider using ABE as an alternative to access control with minimal reliance on a centralized authority. To facilitate this, we’ve included our implementation of ABE in <a href="https://pkg.go.dev/github.com/cloudflare/circl@v1.3.0/abe/cpabe/tkn20">CIRCL</a>, our open source cryptographic library.</p>
    <div>
      <h2>Unsatisfactory attempts at a solution</h2>
      <a href="#unsatisfactory-attempts-at-a-solution">
        
      </a>
    </div>
    <p>Before coming back to GeoV2, let’s take a little detour and examine the problem we’re trying to solve.</p><p>Consider this example: a large European bank wants to store their TLS private keys only within the EU. This bank is a customer of Cloudflare, which means we perform TLS handshakes on their behalf. The reason we need to terminate TLS for them is so that we can provide the best protection against DDoS attacks, improve performance by caching, support <a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/">web application firewalls</a>, etc.</p><p>In order to terminate TLS, we need to have access to their TLS private keys<sup>1</sup>. The control plane, which handles API traffic, encrypts the customer’s uploaded private key with a master public key shared amongst all machines globally. It then puts the key into a globally distributed KV store, <a href="/introducing-quicksilver-configuration-distribution-at-internet-scale/">Quicksilver</a>. This means every machine in every data center around the world has a local copy of this customer’s TLS private key. Consequently, every machine in each data center has a copy of every customer’s private key.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/45KOue4Z7Pqt5PT5yUSVqw/1478d3b8a9bce8d50eab6f22b321bbbf/Customer-uploading-their-TLS-certificate-and-private-key-to-be-stored-in-all-datacenters.png" />
            
            </figure><p>Customer uploading their <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> and private key to be stored in all data centers</p><p>This bank however, wants its key to be stored only in EU data centers. In order to allow this to happen, we have three options.</p><p>The first option is to ensure that only EU data centers can receive this key and terminate the handshake. All other machines proxy TLS requests to an EU server for processing. This would require giving each machine only a subset of the entire keyset stored in Quicksilver, which challenges core design decisions Cloudflare has made over the years that assume the entire dataset is replicated on every machine.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6se4wT6SdniH54NPfm18mS/81a94976157a104513106e2e3ff426f8/Restricting-customer-keys-to-EU-datacenters.png" />
            
            </figure><p>Restricting customer keys to EU data centers</p><p>Another option is to store the keys in the core data center instead of Quicksilver. This would allow us to enforce the proper access control policy every time, ensuring that only certain machines can access certain keys. However, this would defeat the purpose of having a global network in the first place: to reduce latency and avoid a single point of failure at the core.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2f1eETLrGxbeaXVif6AMeT/e254472211468e843c88ef4993d66477/Storing-keys-in-core-datacenter-where-complicated-business-logic-runs-to-enforce-policies.png" />
            
            </figure><p>Storing keys in core data center where complicated business logic runs to enforce policies</p><p>A third option is to use public key cryptography. Instead of having a master key pair, every data center is issued its own key pair. The core encrypts the customer's private key with the keys of every data center allowed to use it. Only machines in the EU will be able to access the key in this example. Let’s assume there are 500 data centers, with 50 machines each. Of these 500 data centers, let’s say 200 are in the EU. Where 100 keys of 1kB consumed a total of 100 x 500 x 50 x 1 kB (globally), now they will consume 200 times that, and in the worst case, up to 500 times. This increases the space it takes to store the keys on each machine by a whole new factor - before, the storage space was purely a function of how many customer keys are registered; now, the storage space is still a function of the number of customer keys, but also multiplied by the number of data centers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3LjmrV6IchJV7XMwBrLh3P/f20b5c276ed32ba768c35a27fcfd42cc/Assigning-unique-keys-to-each-data-center.png" />
            
            </figure><p>Assigning unique keys to each data center and wrapping customer key with EU data center keys</p><p>Unfortunately, all three of these options are undesirable in their own ways. They would either require changing fundamental assumptions we made about the architecture of Cloudflare, abandoning the advantages of using a highly distributed network, or quadratically increasing the storage this feature uses.</p><p>A deeper look at the third option reveals – why not create two key pairs instead of a unique one for each data center? One pair would be common among all EU data centers, and one for all non-EU data centers. This way, the core only needs to encrypt the customer’s key twice instead of for each EU data center. This is a good solution for the EU bank, but it doesn’t scale once we start adding additional policies. Consider the example: a data center in New York City could have a key for the policy “<code>country: US</code>”, another one for “<code>country: US or region: EU</code>”, another one for “<code>not country: RU</code>”, and so on… You can already see this getting rather unwieldy. And every time a new data center is provisioned, all policies must be re-evaluated and the appropriate keys assigned.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ZU5iEwhfO1EJ16MHNTov8/cbf855da065b17fbd258fef678100116/A-key-for-a-each-policy-and-its-negation.png" />
            
            </figure><p>A key for each policy and its negation</p>
    <div>
      <h2>Geo Key Manager v1: identity-based encryption and broadcast encryption</h2>
      <a href="#geo-key-manager-v1-identity-based-encryption-and-broadcast-encryption">
        
      </a>
    </div>
    <p>The invention of RSA in 1978 kicked off the era of modern public key cryptography, but anyone who has used GPG or is involved with certificate authorities can attest to the difficulty of managing public key infrastructure that connects keys to user identities. In 1984, Shamir asked if it was possible to create a public-key encryption system where the public key could be any string. His motivation for this question was to simplify email management. Instead of encrypting an email to Bob using Bob’s public key, Alice could encrypt it to Bob’s identity <a><code>bob@institution.org</code></a>. Finally, in 2001, <a href="https://crypto.stanford.edu/~dabo/papers/bfibe.pdf">Boneh and Franklin</a> figured out how to make it work.</p><p>Broadcast encryption was first proposed in 1993 by <a href="https://www.wisdom.weizmann.ac.il/~naor/PAPERS/broad.pdf">Fiat and Naor</a>. It lets you send the same encrypted message to everyone, but only people with the right key can decrypt it. Looking back to our third option, instead of wrapping the customer’s key with the key of every EU data center, we could use broadcast encryption to create a singular encryption of the customer’s key that only EU-based data centers could decrypt. This would solve the storage problem.</p><p>Geo Key Manager v1 used a combination of identity-based broadcast encryption and identity-based revocation to implement access control. Briefly, a set of identities is designated for each region and each data center location. Then, each machine is issued an identity-based private key for its region and location. With this in place, access to the customer’s key can be controlled using three sets: the set of regions to encrypt to, the set of locations inside the region to exclude, and the set of locations outside the region to include. For example, the customer’s key could be encrypted so that it is available in all regions except for a few specific locations, and also available in a few locations outside those regions. This blog post has all the <a href="/geo-key-manager-how-it-works/">nitty-gritty details</a> of this approach.</p><p>Unfortunately this scheme was insufficiently responsive to customer needs; the parameters used during initial cryptographic setup, such as the list of regions, data centers, and their attributes, were baked into the system and could not be easily changed. Tough luck excluding the UK from the EU region post Brexit, or supporting a new region based on a recent compliance standard that customers need. Using a predetermined static list of locations also made it difficult to quickly revoke machine access. Additionally, decryption keys could not be assigned to new data centers provisioned after setup, preventing them from speeding up requests. These limitations provided the impetus for integrating Attribute-Based Encryption (ABE) into Geo Key Manager.</p>
    <div>
      <h2>Attribute-Based Encryption</h2>
      <a href="#attribute-based-encryption">
        
      </a>
    </div>
    <p>In 2004, Amit Sahai and Brent Waters proposed a new cryptosystem based on access policies, known as attribute-based encryption (ABE). Essentially, a message is encrypted under an access policy rather than an identity. Users are issued a private key based on their attributes, and they can only decrypt the message if their attributes satisfy the policy. This allows for more flexible and fine-grained access control than traditional methods of encryption.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/18dR8oSxVPuawAc3180G0h/97bfa963a7638667b85d468e5dcc5ae6/Group-4899-1.png" />
            
            </figure><p>Brief timeline of Public Key Encryption</p><p>The policy can be attached either to the key or to the ciphertext, leading to two variants of ABE: key-policy attribute-based encryption (KP-ABE) and ciphertext-policy attribute-based encryption (CP-ABE). There exist trade-offs between them, but they are functionally equivalent as they are duals of each other. Let’s focus on CP-ABE it aligns more closely with real-world access control. Imagine a hospital where a doctor has the attributes “<code>role: doctor</code>” and “<code>region: US</code>”, while a nurse has the attributes “<code>role: nurse</code>” and “<code>region: EU</code>”. A document encrypted under the policy “<code>role: doctor or region: EU</code>” can be decrypted by both the doctor and nurse. In other words, ABE is like a magical lock that only opens for people who have the right attributes.</p>
<table>
<thead>
  <tr>
    <th><span>Policy</span></th>
    <th><span>Semantics</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>country: US or region: EU</span></td>
    <td><span>Decryption is possible either in the US or in the European Union</span></td>
  </tr>
  <tr>
    <td><span>not (country: RU or country: US)</span></td>
    <td><span>Decryption is not possible in Russia and US</span></td>
  </tr>
  <tr>
    <td><span>country: US and security: high</span></td>
    <td><span>Decryption is possible only in data centers within the US that have a high level of security (for some security definition established previously)</span></td>
  </tr>
</tbody>
</table><p>There are many different ABE schemes out there, with varying properties. The scheme we choose must satisfy a few requirements:</p><ol><li><p><b>Negation</b> We want to be able to support boolean formulas consisting of <b>AND</b>, <b>OR</b> and <b>NOT</b>, aka non-monotonic boolean formulas. While practically every scheme handles <b>AND</b> and <b>OR</b>, <b>NOT</b> is rarer to find. Negation makes blocklisting certain countries or machines easier.</p></li><li><p><b>Repeated Attributes</b> Consider the policy “<code>organization: executive or (organization: weapons and clearance: top-secret)</code>”. The attribute “<code>organization</code>” has been repeated twice in the policy. Schemes with support for repetition add significant expressibility and flexibility when composing policies.</p></li><li><p><b>Security against Chosen Ciphertext Attacks</b> Most schemes are presented in a form that is only secure if the attacker doesn’t choose the messages to decrypt (<a href="https://en.wikipedia.org/wiki/Chosen-plaintext_attack">CPA</a>). There are <a href="https://www.cs.umd.edu/~jkatz/papers/id-cca-mac.pdf">standard ways</a> to convert such a scheme into one that is secure even if the attacker manipulates ciphertexts (<a href="https://en.wikipedia.org/wiki/Ciphertext_indistinguishability#Indistinguishability_under_chosen_ciphertext_attack/adaptive_chosen_ciphertext_attack_(IND-CCA1,_IND-CCA2)">CCA</a>), but it isn’t automatic. We apply the well-known <a href="https://www.iacr.org/archive/pkc2011/65710074/65710074.pdf">Boneh-Katz transform</a> to our chosen scheme to make it secure against this class of attacks. We will present a proof of security for the end to end scheme in our forthcoming paper.</p></li></ol><p>Negation in particular deserves further comment. For an attribute to be satisfied when negated, the name must stay the same, but the value must differ. It’s like the data center is saying, “I have a country, but it’s definitely not Japan”, instead of “I don’t have a country”. This might seem counterintuitive, but it enables decryption without needing to examine every attribute value. It also makes it safe to roll out attributes incrementally. Based on these criteria, we ended up choosing the scheme by <a href="https://eprint.iacr.org/2019/966">Tomida et al (2021)</a>.</p><p>Implementing a complex cryptographic scheme such as this can be quite challenging. The discrete log assumption that underlies traditional public key cryptography is not sufficient to meet the security requirements of ABE. ABE schemes must secure both ciphertexts and the attribute-based secret keys, whereas traditional public key cryptography only imposes security constraints on the ciphertexts, while the secret key is merely an integer. To achieve this, most ABE schemes are constructed using a mathematical operation known as bilinear pairings.</p><p>The speed at which we can perform pairing operations determines the baseline performance of our implementation. Their efficiency is particularly desirable during decryption, where they are used to combine the attribute-based secret key with the ciphertext in order to recover the plaintext. To this end, we rely on our highly optimized pairing implementations in our open source library of cryptographic suites, CIRCL, which we discuss at length in a <a href="/circl-pairings-update/">previous blog</a>. Additionally, the various keys, attributes and the ciphertext that embeds the access structure are expressed as matrices and vectors. We wrote linear algebra routines to handle matrix operations such as multiplication, transpose, inverse that are necessary to manipulate the structures as needed. We also added serialization, extensive testing and benchmarking. Finally, we implemented our conversion to a <a href="https://en.wikipedia.org/wiki/Adaptive_chosen-ciphertext_attack">CCA2 secure</a> scheme.</p><p>In addition to the core cryptography, we had to decide how to express and represent policies. Ultimately we decided on using strings for our API. While perhaps less convenient for programs than structures would be, users of our scheme would have to implement a parser anyway. Having us do it for them seemed like a way to have a more stable interface. This means the frontend of our policy language was composed of boolean expressions as strings, such as “<code>country: JP or (not region: EU)</code>”, while the backend is a <i>monotonic</i> boolean circuit consisting of wires and gates. Monotonic boolean circuits only include AND and OR gates. In order to handle NOT gates, we assigned positive or negative values to the wires. Every NOT gate can be placed directly on a wire because of <a href="https://en.wikipedia.org/wiki/De_Morgan%27s_laws">De Morgan’s Law</a>, which allows the conversion of a formula like “<code>not (X and Y)” into “not X or not Y</code>”, and similarly for disjunction.</p><p>The following is a demonstration of the API. The central authority runs Setup to generate the master public key and master secret key. The master public key can be used by anyone to encrypt a message over an access policy. The master secret key, held by the central authority, is used to generate secret keys for users based on their attributes. Attributes themselves can be supplied out-of-band. In our case, we rely on the machine provisioning database to provide and validate attributes. These attribute-based secret keys are securely distributed to users, such as over TLS, and are used to decrypt ciphertexts. The API also includes helper functions to check decryption capabilities and extract policies from ciphertexts for improved usability.</p>
            <pre><code>publicKey, masterSecretKey := cpabe.Setup()

policy := cpabe.Policy{}
policy.FromString("country: US or region: EU")

ciphertext := publicKey.Encrypt(policy, []byte("secret message"))

attrsParisDC := cpabe.Attributes{}
attrsParisDC.FromMap(map[string]string{"country": "FR", "region": "EU"}

secretKeyParisDC := masterSecretKey.KeyGen(attrsParisDC)

plaintext := secretKeyParisDC.Decrypt(ciphertext)

assertEquals(plaintext, "secret message")</code></pre>
            <p>We now come back to our original example. This time, the central authority holds the master secret key. Each machine in every data center presents its set of attributes to the central authority, which, after some validation, generates a unique attribute-based secret key for that particular machine. Key issuance happens when a machine is first brought up, if keys must be rotated, or if an attribute has changed, but never in the critical path of a TLS handshake. This solution is also collusion resistant, which means two machines without the appropriate attributes cannot combine their keys to decrypt a secret that they individually could not decrypt. For example, a machine with the attribute  “<code>country: US</code>” and another with “<code>security: high</code>”. These machines cannot collude together to decrypt a resource with the policy “<code>country: US and security: high</code>”.</p><p>Crucially, this solution can seamlessly scale and respond to changes to machines. If a new machine is added, the central authority can simply issue it a secret key since the participants of the scheme don’t have to be predetermined at setup, unlike our previous identity-broadcast scheme.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2GTPTWKh3s1zmc4VdZqePQ/e64697fee21cbbf6271b2e2a6c0f0021/Key-Distribution.png" />
            
            </figure><p>Key Distribution</p><p>When a customer uploads their TLS certificate, they can specify a policy, and the central authority will encrypt their private key with the master public key under the specified policy. The encrypted customer key then gets written to Quicksilver, to be distributed to all data centers. In practice, there is a layer of indirection here that we will discuss in a later section.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4q8tdE0dcq932Wf6YOkkmq/67d3cc560610e82696d01aee83f67443/Encryption-using-Master-Public-Key.png" />
            
            </figure><p>Encryption using Master Public Key</p><p>When a user visits the customer’s website, the TLS termination service at the data center that first receives the request, fetches the customer’s encrypted private key from Quicksilver. If the service's attributes do not satisfy the policy, decryption fails and the request is proxied to the closest data center that satisfies the policy. Whichever data center can successfully decrypt the key performs the signature to complete the TLS handshake.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7id4cGjSPw6lO8QJR0OJU1/012337eb76f55a9e1d39bcca4bcdc76f/Decryption-using-Attribute-based-Secret-Key.png" />
            
            </figure><p>Decryption using Attribute-based Secret Key (Simplified)</p><p>The following table summarizes the pros and cons of the various solutions we discussed:</p>
<table>
<thead>
  <tr>
    <th><span>Solution</span></th>
    <th><span>Flexible policies</span></th>
    <th><span>Fault Tolerant</span></th>
    <th><span>Efficient Space</span></th>
    <th><span>Low Latency</span></th>
    <th><span>Collusion-resistant</span></th>
    <th><span>Changes to machines</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Different copies of Quicksilver in data centers</span></td>
    <td><span>✅</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
  </tr>
  <tr>
    <td><span>Complicated Business Logic in Core</span></td>
    <td><span>✅</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
  </tr>
  <tr>
    <td><span>Encrypt customer keys with each data center’s unique keypair</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Encrypt customer keys with a policy-based keypair, where each data center has multiple policy-based keypairs</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Identity-Based Broadcast Encryption + Identity-Based Negative Broadcast Encryption</span><span>(Geo Key Manager v1)</span></td>
    <td></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Attribute-Based Encryption</span><span>(Geo Key Manager v2)</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
    <td><span>✅</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Performance characteristics</h3>
      <a href="#performance-characteristics">
        
      </a>
    </div>
    <p>We characterize our scheme’s performance on measures inspired by <a href="https://bench.cr.yp.to/results-encrypt.html">ECRYPT</a>. We set the <b>attribute size to 50</b>, which is significantly higher than necessary for most applications, but serves as a worst case scenario for benchmarking purposes. We conduct our measurements on a laptop with Intel Core i7-10610U CPU @ 1.80GHz and compare the results against RSA with 2048-bit security, X25519 and our previous scheme.</p>
<table>
<thead>
  <tr>
    <th><span>Scheme</span></th>
    <th><span>Secret key(bytes)</span></th>
    <th><span>Public key(bytes)</span></th>
    <th><span>Overhead of encrypting 23 bytes</span><br /><span>(ciphertext length - message length)</span></th>
    <th><span>Overhead of encrypting 10k bytes</span><br /><span>(ciphertext length - message length)</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>RSA-2048</span></td>
    <td><span>1190 (PKCS#1)</span></td>
    <td><span>256</span></td>
    <td><span>233</span></td>
    <td><span>3568</span></td>
  </tr>
  <tr>
    <td><span>X25519</span></td>
    <td><span>32</span></td>
    <td><span>32</span></td>
    <td><span>48</span></td>
    <td><span>48</span></td>
  </tr>
  <tr>
    <td><span>GeoV1 scheme</span></td>
    <td><span>4838</span></td>
    <td><span>4742</span></td>
    <td><span>169</span></td>
    <td><span>169</span></td>
  </tr>
  <tr>
    <td><span>GeoV2 ABE scheme</span></td>
    <td><span>33416</span></td>
    <td><span>3282</span></td>
    <td><span>19419</span></td>
    <td><span>19419</span></td>
  </tr>
</tbody>
</table><p>Different attribute based encryption schemes optimize for different performance profiles. Some may have fast key generation, while others may prioritize fast decryption. In our case, we only care about fast decryption because it is the only part of the process that lies in the critical path of a request. Everything else happens out-of-band where the extra overhead is acceptable.</p>
<table>
<thead>
  <tr>
    <th><span>Scheme</span></th>
    <th><span>Generating keypair</span></th>
    <th><span>Encrypting 23 bytes</span></th>
    <th><span>Decrypting 23 bytes</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>RSA-2048</span></td>
    <td><span>117 ms</span></td>
    <td><span>0.043 ms</span></td>
    <td><span>1.26 ms</span></td>
  </tr>
  <tr>
    <td><span>X25519</span></td>
    <td><span>0.045 ms</span></td>
    <td><span>0.093 ms</span></td>
    <td><span>0.046 ms</span></td>
  </tr>
  <tr>
    <td><span>GeoV1 scheme</span></td>
    <td><span>75 ms</span></td>
    <td><span>10.7 ms</span></td>
    <td><span>13.9 ms</span></td>
  </tr>
  <tr>
    <td><span>GeoV2 ABE scheme</span></td>
    <td><span>1796 ms</span></td>
    <td><span>704 ms</span></td>
    <td><span>62.4 ms</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>A Brief Note on Attribute-Based Access Control (ABAC)</h3>
      <a href="#a-brief-note-on-attribute-based-access-control-abac">
        
      </a>
    </div>
    <p>We have used Attribute-Based Encryption to implement what is commonly known as <a href="https://csrc.nist.gov/Projects/Attribute-Based-Access-Control">Attribute-Based Access Control (ABAC)</a>.</p><p>ABAC is an extension of the more familiar <a href="https://csrc.nist.gov/Projects/Role-Based-Access-Control">Role-Based Access Control (RBAC)</a>. To understand why ABAC is relevant, let’s briefly discuss its origins. In 1970, the United States Department of Defense introduced Discretionary Access Control (DAC). DAC is how Unix file systems are implemented. But DAC isn’t enough if you want to restrict resharing, because the owner of the resource can grant other users permission to access it in ways that the central administrator does not agree with. To address this, the Department of Defense introduced Mandatory Access Control (MAC). DRM is a good example of MAC. Even though you have the file, you don’t have a right to share it to others.</p><p><a href="https://www.cloudflare.com/learning/access-management/role-based-access-control-rbac/">RBAC is an implementation</a> of certain aspects of MAC. ABAC is an extension of RBAC that was defined by NIST in 2017 to address the increasing characteristics of users that are not restricted to their roles, such as time of day, user agent, and so on.</p><p>However, RBAC/ABAC is simply a specification. While they are traditionally implemented using a central authority to police access to some resource, it doesn’t have to be so. Attribute-based encryption is an excellent mechanism to implement ABAC in distributed systems.</p>
    <div>
      <h2>Key rotation</h2>
      <a href="#key-rotation">
        
      </a>
    </div>
    <p>While it may be tempting to attribute all failures to DNS, changing keys is another strong contender in this race. Suffering through the rather manual and error-prone key rotation process of Geo Key Manager v1 taught us to make robust and simple key rotation without impact on availability, an explicit design goal for Geo Key Manager v2.</p><p>To facilitate key rotation and improve performance, we introduce a layer of indirection to the customer key wrapping (encryption) process. When a customer uploads their TLS private key, instead of encrypting with the Master Public Key, we generate a X25519 keypair, called the <i>policy key</i>. The central authority then adds the public part of this newly minted policy keypair and its associated policy label to a database. It then encrypts the private half of the policy keypair with the Master Public Key, over the associated access policy. The customer’s private key is encrypted with the public policy key, and saved into Quicksilver.</p><p>When a user accesses the customer’s website, the TLS termination service at the data center that receives the request fetches the encrypted policy key associated with the customer’s access policy. If the machine’s attributes don’t satisfy the policy, decryption fails and the request is forwarded to the closest satisfying data center. If decryption succeeds, the policy key is used to decrypt the customer’s private key and complete the handshake.</p>
<table>
<thead>
  <tr>
    <th><span>Key</span></th>
    <th><span>Purpose</span></th>
    <th><span>CA in core</span></th>
    <th><span>Core</span></th>
    <th><span>Network</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Master Public Key</span></td>
    <td><span>Encrypts private policy keys over an access policy</span></td>
    <td><span>Generate</span></td>
    <td><span>Read</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Master Secret Key</span></td>
    <td><span>Generates secret keys for machines based on their attributes</span></td>
    <td><span>Generate,Read</span></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Machine Secret Key / Attribute-Based Secret Key</span></td>
    <td><span>Decrypts private policy keys stored in global KV store, Quicksilver</span></td>
    <td><span>Generate</span></td>
    <td></td>
    <td><span>Read</span></td>
  </tr>
  <tr>
    <td><span>Customer TLS Private Key</span></td>
    <td><span>Performs digital signature necessary to complete TLS handshake to the customer’s website</span></td>
    <td></td>
    <td><span>Read (transiently on upload)</span></td>
    <td><span>Read</span></td>
  </tr>
  <tr>
    <td><span>Public Policy Key</span></td>
    <td><span>Encrypts customers’ TLS private keys</span></td>
    <td></td>
    <td><span>Generate,</span><br /><span>Read</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Private Policy Key</span></td>
    <td><span>Decrypts customer’s TLS private keys</span></td>
    <td><span>Read (transiently during key rotation)</span></td>
    <td><span>Generate</span></td>
    <td><span>Read</span></td>
  </tr>
</tbody>
</table><p>However, policy keys are not generated for every customer’s certificate upload. As shown in the figure below, if a customer requests a policy that already exists in the system and thus has an associated policy key, the policy key will get re-used. Since most customers use the same few policies, such as restricting to one country, or restricting to the EU, the number of policy keys is orders of magnitude smaller compared to the number of customer keys.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5p1FE2hanxyCKNkkOAeJ1n/58831f6155a861c2fe004ea2a026f3b0/Policy-Keys.png" />
            
            </figure><p>Policy Keys</p><p>This sharing of policy keys is tremendously useful for key rotation. When master keys are rotated (and consequently the machine secret keys), only the handful of policy keys used to control access to the customers’ keys need to be re-encrypted, rather than every customer’s key encryption. This reduces compute and bandwidth requirements. Additionally, caching policy keys at the TLS termination service improves performance by reducing the need for frequent decryptions in the critical path.</p><p>This is similar to hybrid encryption, where public key cryptography is used to establish a shared symmetric key, which then gets used to encrypt data. The difference here is that the policy keys are not symmetric, but rather X25519 keypairs, which is an asymmetric scheme based on elliptic curves. While not as fast as symmetric schemes like AES, traditional elliptic curve cryptography is significantly faster than attribute-based encryption. The advantage here is that the central service doesn’t need access to secret key material to encrypt customer keys.</p><p>The other component of robust key rotation involves maintaining multiple key versions.The latest key generation is used for encryption, but the latest and previous versions can be used for decryption. We use a system of states to manage key transitions and safe deletion of older keys. We also have extensive monitoring in place to alert us if any machines are not using the appropriate key generations.</p>
    <div>
      <h2>The Tail At Scale</h2>
      <a href="#the-tail-at-scale">
        
      </a>
    </div>
    <p>Geo Key Manager suffered from high tail latency, which occasionally impacted availability. Jeff Dean’s paper, <a href="https://research.google/pubs/pub40801/">The Tail at Scale</a>, is an enlightening read on how even elevated p99 latency at Cloudflare scale can be damaging. Despite revamping the server and client components of our service, the p99 latency didn’t budge. These revamps, such as switching from worker pools to one goroutine per request, did simplify the service, as they removed thousands of lines of code. Distributed tracing was able to pin down the delays: they took place between the client sending a request and the server receiving it. But we could not dig in further. We even wrote a blog last year describing our <a href="/scaling-geo-key-manager/">debugging endeavors</a>, but without a concrete solution.</p><p>Finally, we realized that there is a level of indirection between the client and the server. Our data centers around the world are very different sizes. To avoid swamping smaller data centers with connections, larger data centers would task individual, intermediary machines with proxying requests to other data centers using the Go net/rpc library.</p><p>Once we included the forwarding function on the intermediary server in the trace, the problem became clear. There was a long delay between issuing the request and processing it. Yet the code was merely a call to a built-in library function. Why was it delaying the request?</p><p>Ultimately we found that there was a lock held while the request was serialized. The net/rpc package does not support streams, but our packet-oriented custom application protocol, which we wrote before the advent of gRPC, does support streaming. To bridge this gap, we executed a request and waited for the response in the serialization function. While an expedient way to get the code written, it created a performance bottleneck as only one request could be forwarded at a time.</p><p>Our solution was to use channels for coordination, letting multiple requests execute while we waited for the responses to arrive. When we rolled it out we saw dramatic decreases in tail latency.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/z3qVC6TmrFhWrVyJDS2Am/19e394a04c4b0c30e8fc4d04cb34fa86/Untitled-4.png" />
            
            </figure><p>The results of fixing RPC failures in remote colo in Australia</p><p>Unfortunately we cannot make the speed of light any faster (yet). Customers who want their keys kept only in the US while their website users are in the land down under will have to endure some delays as we make the trans-pacific voyage. But thanks to session tickets, those delays only affect new connections.</p><div></div><p>Uptime was also significantly improved. Data centers provisioned after cryptographic initiation could now participate in the system, which also implies that data centers that did not satisfy a certain policy had a broader range of satisfying neighbors to which they could forward the signing request to. This increased redundancy in the system, and particularly benefited data centers in regions without the best internet connectivity. The graph below represents successful probes spanning every machine globally over a two-day period. For GeoV1, we see websites with policies for US and EU regions falling to under 98% at one point, while for GeoV2, uptime rarely drops below 4 9s of availability.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/69GPaZv0uid2bQK8sc9NPL/d55819c043a0cc35bd6596e7fcf5ab8d/ss.png" />
            
            </figure><p>Uptime by Key Profile across US and EU for GeoV1 and GeoV2, and IN for GeoV2</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>Congratulations dear reader for making it this far. Just like you, applied cryptography has come a long way, but only limited slivers manage to penetrate the barrier between research and real-world adoption. Bridging this gap can help enable novel capabilities for protecting sensitive data. Attribute-based encryption itself has become much more efficient and featureful over the past few years. We hope that this post encourages you to consider ABE for your own access control needs, particularly if you deal with distributed systems and don’t want to depend on a highly available central authority. We have open-sourced our implementation of CP-ABE in <a href="https://github.com/cloudflare/circl/tree/main/abe/cpabe/tkn20">CIRCL</a>, and plan on publishing a paper with additional details.</p><p>We look forward to the numerous product improvements to Geo Key Manager made possible by this new cryptographic foundation. We plan to use this ABE-based mechanism for storing not just private keys, but also other types of data. We are working on making it more user-friendly and generalizable for internal services to use.</p>
    <div>
      <h2>Acknowledgements</h2>
      <a href="#acknowledgements">
        
      </a>
    </div>
    <p>We’d like to thank Watson Ladd for his contributions to this project during his tenure at Cloudflare.</p><p>......</p><p><sup>1</sup>While true for most customers, we do offer <a href="https://www.cloudflare.com/ssl/keyless-ssl/">Keyless SSL</a> that allows customers who can run their own keyservers, the ability to store their private keys on-prem</p> ]]></content:encoded>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Geo Key Manager]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">6GfvoTWvRo60gaXvQScL51</guid>
            <dc:creator>Tanya Verma</dc:creator>
        </item>
        <item>
            <title><![CDATA[Defending against future threats: Cloudflare goes post-quantum]]></title>
            <link>https://blog.cloudflare.com/post-quantum-for-all/</link>
            <pubDate>Mon, 03 Oct 2022 13:01:00 GMT</pubDate>
            <description><![CDATA[ The future of a private and secure Internet is at stake; that is why today we have enabled post-quantum cryptography support for all our customers ]]></description>
            <content:encoded><![CDATA[ <p>There is an expiration date on the cryptography we use every day. It’s not easy to read, but somewhere <a href="https://globalriskinstitute.org/download/quantum-threat-timeline-report-2021-full-report/">between 15 or 40 years</a>, a sufficiently powerful quantum computer is expected to be built that will be <a href="https://en.wikipedia.org/wiki/Shor%27s_algorithm">able to decrypt</a> essentially any encrypted data on the Internet today.</p><p>Luckily, there is a solution: <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/">post-quantum (PQ) cryptography</a> has been designed to be secure against the threat of quantum computers. Just three months ago, in July 2022, after a six-year worldwide competition, the US National Institute of Standards and Technology (NIST), known for AES and SHA2, <a href="/nist-post-quantum-surprise/">announced</a> which post-quantum cryptography they will standardize. NIST plans to publish the final standards in 2024, but we want to help drive early adoption of post-quantum cryptography.</p><p>Starting today, as a beta service, <b>all</b> websites and APIs served through Cloudflare support post-quantum hybrid key agreement. This is on by default<sup>1</sup>; no need for an opt-in. This means that if your browser/app supports it, the connection to our network is also secure against any future quantum computer.</p><p>We offer this post-quantum cryptography free of charge: we believe that post-quantum security should be the new baseline for the Internet.</p><p>Deploying post-quantum cryptography seems like a no-brainer with quantum computers on the horizon, but it’s not without risks. To start, this is new cryptography: even with years of scrutiny, it is not inconceivable that a catastrophic attack might still be discovered. That is why we are deploying <i>hybrids</i>: a combination of a tried and tested key agreement together with a new one that adds post-quantum security.</p><p>We are primarily worried about what might seem mere practicalities. Even though the protocols used to secure the Internet are designed to allow smooth transitions like this, in reality there is a lot of buggy code out there: trying to create a post-quantum secure connection might fail for many reasons — for example a middlebox being confused about the larger post-quantum keys and other reasons we have yet to observe because these post-quantum key agreements are brand new. It’s because of these issues that we feel it is important to deploy post-quantum cryptography early, so that together with browsers and other clients we can find and work around these issues.</p><p>In this blog post we will explain how TLS, the protocol used to secure the Internet, is designed to allow a smooth and secure migration of the cryptography it uses. Then we will discuss the technical details of the post-quantum cryptography we have deployed, and how, in practice, this migration might not be that smooth at all. We finish this blog post by explaining how you can build a better, post-quantum secure, Internet by helping us test this new generation of cryptography.</p>
    <div>
      <h2>TLS: Transport Layer Security</h2>
      <a href="#tls-transport-layer-security">
        
      </a>
    </div>
    <p>When you’re browsing a website using a <i>secure connection</i>, whether that’s using HTTP/1.1 or <a href="/quic-version-1-is-live-on-cloudflare/">QUIC</a>, you are using the Transport Layer Security (<b>TLS</b>) protocol under the hood. There are two major versions of TLS <a href="https://radar.cloudflare.com/adoption-and-usage">in common use today</a>: the new <a href="/rfc-8446-aka-tls-1-3/">TLS 1.3</a> (~90%) and the older TLS 1.2 (~10%), which is on the decline.</p><p>TLS 1.3 is a <a href="/rfc-8446-aka-tls-1-3/">huge improvement</a> over TLS 1.2: it’s faster, more secure, simpler and more flexible in just the right places. This makes it easier to add post-quantum security to TLS 1.3 compared to 1.2. For the moment, we will leave it at that: we’ve only added post-quantum support to TLS 1.3.</p><p>So, what is TLS all about? The goal is to set up a connection between a browser and website such that</p><ul><li><p><b>Confidentiality and integrity</b>, no one can read along or tamper with the data undetected.</p></li><li><p><b>Authenticity</b> you know you’re connected to the right website; not an imposter.</p></li></ul>
    <div>
      <h3>Building blocks: AEAD, key agreement and signatures</h3>
      <a href="#building-blocks-aead-key-agreement-and-signatures">
        
      </a>
    </div>
    <p>Three different types of cryptography are used in TLS to reach this goal.</p><ul><li><p><b>Symmetric encryption</b>, or more precisely <i>Authenticated Encryption With Associated Data</i> (AEAD), is the workhorse of cryptography: it’s used to ensure confidentiality and integrity. This is a straight-forward kind of encryption: there is a <i>single key</i> that is used to encrypt and decrypt the data. Without the right key you cannot decrypt the data and any tampering with the encrypted data results in an error while decrypting.</p></li></ul><p>In TLS 1.3, <a href="/do-the-chacha-better-mobile-performance-with-cryptography/">ChaCha20-Poly1305</a> and AES128-GCM are in common use today. What about quantum attacks? At first glance, it looks like we need to switch to 256-bit symmetric keys to defend against <a href="https://en.wikipedia.org/wiki/Grover%27s_algorithm">Grover’s algorithm</a>. In practice, however, Grover’s algorithm <a href="/nist-post-quantum-surprise/#post-quantum-security-levels">doesn’t parallelize well</a>, so the currently deployed AEADs will serve just fine.</p><p>So if we can agree on a shared key to use with symmetric encryption, we’re golden. But how to get to a shared key? You can’t just pick a key and send it to the server: anyone listening in would know the key as well. One might think it’s an impossible task, but this is where the magic of asymmetric cryptography helps out:</p><ul><li><p>A <b>key agreement</b>, also called <i>key exchange</i> or <i>key distribution</i>, is a cryptographic protocol with which two parties can agree on a shared key without an eavesdropper being able to learn anything. Today the <a href="https://cr.yp.to/ecdh.html">X25519</a> Elliptic Curve <a href="https://developers.cloudflare.com/internet/protocols/tls#ephemeral-diffie-hellman-handshake">Diffie–Hellman</a> protocol (ECDH) is the de facto standard key agreement used in TLS 1.3. The security of X25519 is based on the <a href="https://en.wikipedia.org/wiki/Discrete_logarithm">discrete logarithm problem</a> for elliptic curves, which is vulnerable to quantum attacks, as it is easily solved by a cryptographically relevant quantum computer using <a href="https://en.wikipedia.org/wiki/Shor%27s_algorithm">Shor’s algorithm</a>. The solution is to use a post-quantum key agreement, such as <a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a>.</p></li></ul><p>A key agreement only protects against a passive attacker. An active attacker, that can intercept and modify messages (<a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">MitM</a>), can establish separate shared keys with both the server and the browser, re-encrypting all data passing through. To solve this problem, we need the final piece of cryptography.</p><ul><li><p>With a <b>digital</b> <b>signature</b> algorithm, such as <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)">RSA</a> or <a href="https://www.cloudflare.com/learning/dns/dnssec/ecdsa-and-dnssec/">ECDSA</a>, there are two keys: a <i>public</i> and a <i>private key</i>. Only with the private key, one can create a <i>signature</i> for a message. Anyone with the corresponding public key can check whether a signature is indeed valid for a given message. These digital signatures are at the heart of <a href="https://www.cloudflare.com/application-services/products/ssl/"><i>TLS certificates</i></a> that are used to authenticate websites. Both RSA and ECDSA are vulnerable to quantum attacks. We haven’t replaced those with post-quantum signatures, yet. The reason is that authentication is less urgent: we only need to have them replaced by the time a sufficiently large quantum computer is built, whereas any data secured by a vulnerable key agreement today can be stored and decrypted in the future. Even though we have more time, deploying post-quantum authentication will be <a href="/sizing-up-post-quantum-signatures/">quite challenging</a>.</p></li></ul><p>So, how do these building blocks come together to create TLS?</p><h2>High-level overview of TLS 1.3</h2><p>A TLS connection starts with a <b>handshake</b> which is used to authenticate the server and derive a shared key. The browser (client) starts by sending a <i>ClientHello</i> message that contains a list of the AEADs, signature algorithms, and key agreement methods it supports. To remove a roundtrip, the client is allowed to make a guess of what the server supports and start the key agreement by sending one or more <i>client keyshares</i>. That guess might be correct (on the left in the diagram below) or the client has to retry (on the right).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4jeNtG1jP4LRmICiNeBUIG/87c30c89aeef2ce319bb25c0c5cddc2d/image4.png" />
            
            </figure><p>Protocol flow for server-authenticated TLS 1.3 with a supported client keyshare on the left and a HelloRetryRequest on the right.</p>
    <div>
      <h4><b>Key agreement</b></h4>
      <a href="#key-agreement">
        
      </a>
    </div>
    <p>Before we explain the rest of this interaction, let’s dig into the key agreement: what is a keyshare? The way the key agreement for Kyber and X25519 work <a href="/nist-post-quantum-surprise/#kem-versus-diffie-hellman">is different</a>: the first is a Key Encapsulation Mechanism (KEM), while the latter is a Diffie–Hellman (DH) style agreement. The latter is more flexible, but for TLS it doesn’t make a difference.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/25zN3n7EymPx0ZLTOKBEO6/71928fb621191c1de4883f77b1e9cae5/image3.png" />
            
            </figure><p>The shape of a KEM and Diffie–Hellman key agreement in TLS-compatible handshake is the same.</p><p>In both cases the client sends a <i>client keyshare</i> to the server. From this <i>client keyshare</i> the server generates the <i>shared key</i>. The server then returns a <i>server keyshare</i> with which the client can also compute the shared key.</p><p>Going back to the TLS 1.3 flow: when the server receives the <i>ClientHello</i> message it picks an AEAD (cipher), signature algorithm and client keyshare that it supports. It replies with a <i>ServerHello</i> message that contains the chosen AEAD and the <i>server keyshare</i> for the selected key agreement. With the AEAD and shared key locked in, the server starts encrypting data (shown with blue boxes).</p>
    <div>
      <h4><b>Authentication</b></h4>
      <a href="#authentication">
        
      </a>
    </div>
    <p>Together with the AEAD and server keyshare, the server sends a signature, the <i>handshake signature</i>, on the transcript of the communication so far together with a <a href="https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/"><i>certificate</i></a><i> (chain)</i> for the public key that it used to create the signature. This allows the client to authenticate the server: it checks whether it trusts the <i>certificate authority</i> (e.g. <a href="https://letsencrypt.org/">Let’s Encrypt</a>) that certified the public key and whether the signature verifies for the messages it sent and received so far. This not only authenticates the server, but it also protects against downgrade attacks.</p>
    <div>
      <h4><b>Downgrade protection</b></h4>
      <a href="#downgrade-protection">
        
      </a>
    </div>
    <p>We cannot upgrade all clients and servers to post-quantum cryptography at once. Instead, there will be a transition period where only some clients and some servers support post-quantum cryptography. The key agreement negotiation in TLS 1.3 allows this: during the transition servers and clients will still support non post-quantum key agreements, and can fall back to it if necessary.</p><p>This flexibility is great, but also scary: if both client and server support post-quantum key agreement, we want to be sure that they also negotiate the post-quantum key agreement. This is the case in TLS 1.3, but it is not obvious: the keyshares, the chosen keyshare and the list of supported key agreements are all sent in plain text. Isn’t it possible for an attacker in the middle to remove the post-quantum key agreements? This is called a <i>downgrade attack</i>.</p><p>This is where the transcript comes in: the handshake signature is taken over all messages received and sent by the server so far. This includes the supported key agreements and the key agreement that was picked. If an attacker changes the list of supported key agreements that the client sends, then the server will not notice. However, the client checks the server’s handshake signature against the list of supported key agreements it has actually sent and thus will detect the mischief.</p><p>The downgrade attack problems are <a href="https://eprint.iacr.org/2018/298">much</a> <a href="https://eprint.iacr.org/2016/072.pdf">more</a> <a href="https://www.rfc-editor.org/rfc/rfc7627">complicated</a> for TLS 1.2, which is one of the reasons we’re hesitant to retrofit post-quantum security in TLS 1.2.</p>
    <div>
      <h4><b>Wrapping up the handshake</b></h4>
      <a href="#wrapping-up-the-handshake">
        
      </a>
    </div>
    <p>The last part of the server’s response is <i>“server finished”,</i> a <i>message authentication code</i> (MAC) on the whole transcript so far. Most of the work has been done by the handshake signature, but in other operating modes of TLS without handshake signature, such as session resumption, it’s important.</p><p>With the chosen AEAD and server keyshare, the client can compute the shared key and decrypt and verify the certificate chain, handshake signature and handshake MAC. We did not mention it before, but the shared key is not used directly for encryption. Instead, for good measure, <a href="https://www.rfc-editor.org/rfc/rfc8446.html#page-93">it’s mixed together</a> with communication transcripts, to derive several specific keys for use during the handshake and the main connection afterwards.</p><p>To wrap up the handshake, the client sends its own handshake MAC, and can then proceed to send application-specific data encrypted with the keys derived during the handshake.</p>
    <div>
      <h4><b>Hello! Retry Request?</b></h4>
      <a href="#hello-retry-request">
        
      </a>
    </div>
    <p>What we just sketched is the desirable flow where the client sends a keyshare that is supported by the server. That might not be the case. If the server doesn’t accept any key agreements advertised by the client, then it will tell the client and abort the connection.</p>If there is a key agreement that both support, but for which the client did not send a keyshare, then the server will respond with a HelloRetryRequest (HRR) message requesting a keyshare of a specific key agreement that the client supports as shown <a href="#tls-anchor">on the diagram on the right</a>. In turn, the client responds with a new ClientHello with the selected keyshare.
<p></p><p>This is not the whole story: a server is also allowed to send a <i>HelloRetryRequest</i> to request a different key agreement that it prefers over those for which the client sent shares. For instance, a server can send a <i>HelloRetryRequest</i> to a post-quantum key agreement if the client supports it, but didn’t send a keyshare for it.</p><p>_HelloRetryRequest_s are rare today. Almost every server supports the X25519 key-agreement and almost every client (98% today) sends a X25519 keyshare. Earlier P-256 was the de facto standard and for a long time many browsers would send both a P-256 and X25519 keyshare to prevent a HelloRetryRequest. As we will discuss later, we might not have the luxury to send two post-quantum keyshares.</p>
    <div>
      <h4><b>That’s the theory</b></h4>
      <a href="#thats-the-theory">
        
      </a>
    </div>
    <p>TLS 1.3 is designed to be flexible in the cryptography it uses without sacrificing security or performance, which is convenient for our migration to post-quantum cryptography. That is the theory, but there are some serious issues in practice — we’ll go into detail later on. But first, let’s check out the post-quantum key agreements we’ve deployed.</p>
    <div>
      <h3>What we deployed</h3>
      <a href="#what-we-deployed">
        
      </a>
    </div>
    <p>Today we have enabled support for the <b>X25519Kyber512Draft00</b> and <b>X25519Kyber768Draft00</b> key agreements using TLS identifiers 0xfe30 and 0xfe31 respectively. These are exactly the same key agreements <a href="/experiment-with-pq/">we enabled</a> on a limited number of zones this July.</p><p>These two key agreements are a combination, a <a href="https://datatracker.ietf.org/doc/draft-stebila-tls-hybrid-design/"><b>hybrid</b></a>, of the classical <a href="https://www.rfc-editor.org/rfc/rfc8410">X25519</a> and the new post-quantum Kyber512 and Kyber768 respectively and in that order. That means that even if Kyber turns out to be insecure, the connection remains as secure as X25519.</p><p><a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a>, for now, is the only key agreement that NIST <a href="/nist-post-quantum-surprise/">has selected</a> for standardization. Kyber is very light on the CPU: it is faster than X25519 which is already known for its speed. On the other hand, its keyshares are much bigger:</p>
<table>
<thead>
  <tr>
    <th></th>
    <th><span>Size keyshares(in bytes)</span></th>
    <th><span>Ops/sec (higher is better)</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Algorithm</span></td>
    <td><span>PQ</span></td>
    <td><span>Client</span></td>
    <td><span>Server</span></td>
    <td><span>Client</span></td>
    <td><span>Server</span></td>
  </tr>
  <tr>
    <td><span>Kyber512</span></td>
    <td><span>✅</span></td>
    <td><span>800</span></td>
    <td><span>768</span></td>
    <td><span>50,000</span></td>
    <td><span>100,000</span></td>
  </tr>
  <tr>
    <td><span>Kyber768</span></td>
    <td><span>✅</span></td>
    <td><span>1,184</span></td>
    <td><span>1,088</span></td>
    <td><span>31,000</span></td>
    <td><span>70,000</span></td>
  </tr>
  <tr>
    <td><span>X25519</span></td>
    <td><span>❌</span></td>
    <td><span>32</span></td>
    <td><span>32</span></td>
    <td><span>17,000</span></td>
    <td><span>17,000</span></td>
  </tr>
</tbody>
</table><p><i>Size and CPU performance compared between X25519 and Kyber. Performance varies considerably by hardware platform and implementation constraints and should be taken as a rough indication only.</i></p><p>Kyber is expected to change in minor, but backwards incompatible ways, before final standardization by NIST in 2024. Also, the integration with TLS, including the choice and details of the hybrid key agreement, are not yet finalized by the TLS working group. Once they are, we will adopt them promptly.</p><p>Because of this, we will not support the preliminary key agreements announced today for the long term; they’re provided as a beta service. We will post updates on our deployment on <a href="http://pq.cloudflareresearch.com">pq.cloudflareresearch.com</a> and announce it on the <a href="https://mailman3.ietf.org/mailman3/lists/pqc.ietf.org/">IETF PQC mailing list</a>.</p><p>Now that we know how TLS negotiation works in theory, and which key agreements we’re adding, how could it fail?</p>
    <div>
      <h2>Where things might break in practice</h2>
      <a href="#where-things-might-break-in-practice">
        
      </a>
    </div>
    
    <div>
      <h3>Protocol ossification</h3>
      <a href="#protocol-ossification">
        
      </a>
    </div>
    <p>Protocols are often designed with flexibility in mind, but if that flexibility is not exercised in practice, it’s often lost. This is called <i>protocol ossification</i>. The roll-out of TLS 1.3 <a href="/why-tls-1-3-isnt-in-browsers-yet/">was difficult</a> because of several instances of ossification. One poignant example is TLS’ version negotiation: there is a version field in the ClientHello message that indicates the latest version supported by the client. A new version was assigned to TLS 1.3, but in testing it turned out that many servers would not fallback properly to TLS 1.2, but crash the connection instead. How do we deal with ossification?</p>
    <div>
      <h4><b>Workaround</b></h4>
      <a href="#workaround">
        
      </a>
    </div>
    <p>Today, TLS 1.3 masquerades itself as TLS 1.2 down to including many legacy fields in the <i>ClientHello</i>. The actual version negotiation is moved into a new <i>extension</i> to the message. A TLS 1.2 server will ignore the new extension and ignorantly continue with TLS 1.2, while a TLS 1.3 server picks up on the extension and continues with TLS 1.3 proper.</p>
    <div>
      <h4><b>Protocol grease</b></h4>
      <a href="#protocol-grease">
        
      </a>
    </div>
    <p>How do we prevent ossification? Having learnt from this experience, browsers will regularly advertise dummy versions in this new version field, so that misbehaving servers are caught early on. This is not only done for the new version field, but in many other places in the TLS handshake, and presciently also for the key agreement identifiers. Today, 40% of browsers send two client keyshares: one X25519 and another a bogus 1-byte keyshare to keep key agreement flexibility.</p><p>This behavior is standardized in <a href="https://datatracker.ietf.org/doc/html/rfc8701">RFC 8701</a>: <i>Generate Random Extensions And Sustain Extensibility</i> (GREASE) and we call it protocol <i>greasing</i>, as in “greasing the joints” from Adam Langley’s metaphor of <a href="https://www.imperialviolet.org/2016/05/16/agility.html">protocols having rusty joints</a> in need of oil.</p><p>This keyshare grease helps, but it is not perfect, because it is the size of the keyshare that in this case causes the most concern.</p>
    <div>
      <h3>Fragmented ClientHello</h3>
      <a href="#fragmented-clienthello">
        
      </a>
    </div>
    <p>Post-quantum keyshares are big. The two Kyber hybrids are 832 and 1,216 bytes. Compared to that, X25519 is tiny with only 32 bytes. It is not unlikely that some implementations will fail when seeing such large keyshares.</p><p>Our biggest concern is with the larger Kyber768 based keyshare. A ClientHello with the smaller 832 byte Kyber512-based keyshare will just barely fit in a typical network packet. On the other hand, the larger 1,216 byte Kyber768-keyshare will typically fragment the ClientHello into two packets.</p><p>Assembling packets together isn’t free: it requires you to keep track of the partial messages around. Usually this is done transparently by the operating system’s TCP stack, but optimized middleboxes and load balancers that look at each packet separately, have to (and might not) keep track of the connections themselves.</p>
    <div>
      <h3><b>QUIC</b></h3>
      <a href="#quic">
        
      </a>
    </div>
    <p>The situation for <a href="https://www.cloudflare.com/learning/performance/what-is-http3/">HTTP/3</a>, which is built on <a href="/quic-version-1-is-live-on-cloudflare/">QUIC</a>, is particularly interesting. Instead of a simple port number chosen by the client (as in TCP), a QUIC packet from the client contains a <i>connection ID</i> that is chosen by the server. Think of it as “your reference” and “our reference” in snailmail. This allows a QUIC load-balancer to encode the particular machine handling the connection into the connection ID.</p><p>When opening a connection, the QUIC client doesn’t know which connection ID the server would like and sends a random one instead. If the client needs multiple initial packets, such as with a big ClientHello, then the client will use the same random connection ID. Even though multiple initial packets are allowed by the QUIC standard, a QUIC load balancer might not expect this, and won’t be able to refer to an underlying TCP connection.</p>
    <div>
      <h3>Performance</h3>
      <a href="#performance">
        
      </a>
    </div>
    <p>Aside from these hard failures, <i>soft</i> failures, such as performance degradation are also of concern: if it’s too slow to load, a website might as well have been broken to begin with.</p><p>Back in 2019 in a joint experiment with Google, we deployed two post-quantum key agreements: CECPQ2, based on NTRU-HRSS, and CECPQ2b, based on SIKE. NTRU-HRSS is very similar to Kyber: it’s a bit larger and slower. <a href="/the-tls-post-quantum-experiment/">Results from 2019</a> are very promising: X25519+NTRU-HRSS (orange line) is hard to distinguish from X25519 on its own (blue line).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3aqgMsHQUv4sMeIF3eHDOK/ac2d93d5156efd813d007997eb712c5f/image2-2.png" />
            
            </figure><p>We will continue to keep a close eye on performance, especially on the tail performance: we want a smooth transition for everyone, from the fastest to the slowest clients on the Internet.</p>
    <div>
      <h2>How to help out</h2>
      <a href="#how-to-help-out">
        
      </a>
    </div>
    <p>The Internet is a very heterogeneous system. To find all issues, we need sufficient numbers of diverse testers. We are working with browsers to add support for these key agreements, but there may not be one of these browsers in every network.</p><p>So, to help the Internet out, try and switch a small part of your traffic to Cloudflare domains to use these new key agreement methods. We have open-sourced forks for <a href="https://github.com/cloudflare/boringssl-pq">BoringSSL</a>, <a href="https://github.com/cloudflare/go">Go</a> and <a href="https://github.com/cloudflare/qtls-pq">quic-go</a>. For BoringSSL and Go, check out <a href="/experiment-with-pq/#boringssl">the sample code here</a>. If you have any issues, please let us know at <a>ask-research@cloudflare.com</a>. We will be discussing any issues and workarounds at the IETF <a href="https://datatracker.ietf.org/group/tls/about/">TLS working group</a>.</p>
    <div>
      <h2>Outlook</h2>
      <a href="#outlook">
        
      </a>
    </div>
    <p>The transition to a post-quantum secure Internet is urgent, but not without challenges. Today we have deployed a preliminary post-quantum key agreement on all our servers — a sizable portion of the Internet — so that we can all start testing the big migration today. We hope that come 2024, when NIST puts a bow on Kyber, we will all have laid the groundwork for a smooth transition to a Post-Quantum Internet.</p><p>.....</p><p><sup>1</sup>We only support these post-quantum key agreements in protocols based on TLS 1.3 including HTTP/3. There is one exception: for the moment we disable these hybrid key exchanges for websites in FIPS-mode.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">4UeqNREMkVNSaC66RE5DEo</guid>
            <dc:creator>Bas Westerbaan</dc:creator>
            <dc:creator>Cefan Daniel Rubin</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing post-quantum Cloudflare Tunnel]]></title>
            <link>https://blog.cloudflare.com/post-quantum-tunnel/</link>
            <pubDate>Mon, 03 Oct 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ Every connection we make post-quantum secure, we remove one opportunity for compromise: that's why we are announcing post-quantum Cloudflare Tunnel to help you secure every connection to our network ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Undoubtedly, one of the big themes in IT for the next decade will be <i>the migration</i> to <i>post-quantum cryptography</i>. From tech giants to small businesses: we will all have to make sure our hardware and software is updated so that our data is protected against the arrival of <a href="/the-quantum-menace/">quantum computers</a>. It seems far away, but it’s not a problem for later: any encrypted data captured today (not protected by post-quantum cryptography) can be broken by a sufficiently powerful quantum computer in the future.</p><p>Luckily we’re almost there: after a tremendous worldwide effort by the cryptographic community, <a href="/nist-post-quantum-surprise/">we know</a> what will be the gold standard of post-quantum cryptography for the next decades. Release date: somewhere in 2024. Hopefully, for most, the transition will be a simple software update then, but it will not be that simple for everyone: not all software is maintained, and it could well be that hardware needs an upgrade as well. Taking a step back, many companies don’t even have a full list of all software running on their network.</p><p>For Cloudflare Tunnel customers, this migration will be much simpler: introducing <b>Post-Quantum</b> <b>Cloudflare Tunnel</b>. In this blog post, first we give an overview of how Cloudflare Tunnel works and explain how it can help you with your post-quantum migration. Then we’ll explain how to get started and finish with the nitty-gritty technical details.</p>
    <div>
      <h2>Cloudflare Tunnel</h2>
      <a href="#cloudflare-tunnel">
        
      </a>
    </div>
    <p>With <a href="https://www.cloudflare.com/products/tunnel/">Cloudflare Tunnel</a> you can securely expose a server sitting within an internal network to the Internet by running the <a href="https://github.com/cloudflare/cloudflared"><code>cloudflared</code></a> service next to it. For instance, after having installed <a href="https://github.com/cloudflare/cloudflared"><code>cloudflared</code></a> on your internal network, you can expose your on-prem webapp on the Internet under, say example.com, so that <a href="https://www.cloudflare.com/products/zero-trust/remote-workforces/">remote workers</a> can access it from anywhere,</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4JiK6i2ZWO5iktBimbbSw3/9308d07667006ac4d8aa6d0b0b53d401/image1.png" />
            
            </figure><p>Life of a Cloudflare Tunnel request.</p><p>How does it work? <code>cloudflared</code> creates long-running connections to two nearby Cloudflare data centers, for instance San Francisco (connection 3) and one other. When your employee visits your domain, they connect (1) to a Cloudflare server close to them, say in Frankfurt. That server knows that this is a Cloudflare Tunnel and that your <code>cloudflared</code> has a connection to a server in San Francisco, and thus it relays (2) the request to it. In turn, via the reverse connection, the request ends up at <code>cloudflared</code>, which passes it (4) to the webapp via your internal network.</p><p>In essence, Cloudflare Tunnel is a simple but convenient tool, but the magic is in what you can do on top with it: you get <a href="https://www.cloudflare.com/ddos/">Cloudflare’s DDoS protection</a> for free; fine-grained access control with <a href="https://www.cloudflare.com/products/zero-trust/access/">Cloudflare Access</a> (even if the application didn’t support it) and <a href="https://developers.cloudflare.com/cloudflare-one/analytics/logs/audit-logs/">request logs</a> just to name a few. And let’s not forget the matter at hand:</p>
    <div>
      <h2>Post-quantum tunnels</h2>
      <a href="#post-quantum-tunnels">
        
      </a>
    </div>
    <p>Our goal is to make it easy for everyone to have a fully post-quantum secure connection from users to origin. For this, Post-Quantum Cloudflare Tunnel is a powerful tool, because with it, your users can benefit from a post-quantum secure connection without upgrading your application (connection 4 in the diagram).</p><p>Today, we make two important steps towards this goal: <code>cloudflared</code> <a href="https://github.com/cloudflare/cloudflared/releases/tag/2022.9.1">2022.9.1</a> adds the <code>--post-quantum</code> flag, that when given, makes the connection from <code>cloudflared</code> to our network (connection 3) post-quantum secure.</p><p>Also today, <a href="/post-quantum-for-all">we have announced</a> support for post-quantum browser connections (connection 1).</p><p>We aren’t there yet: browsers (and other HTTP clients) do not support the post-quantum security offered by our network, yet, and we still have to make the connections between our data centers (connection 2) post-quantum secure.</p><p>An attacker only needs to have access to one vulnerable connection, but attackers don’t have access everywhere: with every connection we make post-quantum secure, we remove one opportunity for compromise.</p><p>We are eager to make post-quantum tunnels the default, but for now it is a beta feature. The reason is that the cryptography used and its integration into the network protocol are not yet final. Making post-quantum the default now, would require users to update <code>cloudflared</code> more often than we can reasonably expect them to.</p>
    <div>
      <h2>Getting started</h2>
      <a href="#getting-started">
        
      </a>
    </div>
    <p>Are frequent updates to <code>cloudflared</code> not a problem for you? Then please do give post-quantum Cloudflare Tunnel a try. Make sure you’re on at least <a href="https://github.com/cloudflare/cloudflared/releases/tag/2022.9.1">2022.9.1</a> and simply run <code>cloudflared</code> with the <code>--post-quantum</code> flag:</p>
            <pre><code>$ cloudflared tunnel run --post-quantum tunnel-name
2022-09-23T11:44:42Z INF Starting tunnel tunnelID=[...]
2022-09-23T11:44:42Z INF Version 2022.9.1
2022-09-23T11:44:42Z INF GOOS: darwin, GOVersion: go1.19.1, GoArch: amd64
2022-09-23T11:44:42Z INF Settings: map[post-quantum:true pq:true]
2022-09-23T11:44:42Z INF Generated Connector ID: [...]
2022-09-23T11:44:42Z INF cloudflared will not automatically update if installed by a package manager.
2022-09-23T11:44:42Z INF Initial protocol quic
2022-09-23T11:44:42Z INF Using experimental hybrid post-quantum key agreement X25519Kyber768Draft00
2022-09-23T11:44:42Z INF Starting metrics server on 127.0.0.1:53533/metrics
2022-09-23T11:44:42Z INF Connection [...] registered connIndex=0 ip=[...] location=AMS
2022-09-23T11:44:43Z INF Connection [...] registered connIndex=1 ip=[...] location=AMS
2022-09-23T11:44:44Z INF Connection [...] registered connIndex=2 ip=[...] location=AMS
2022-09-23T11:44:45Z INF Connection [...] registered connIndex=3 ip=[...] location=AMS</code></pre>
            <p>If you run <code>cloudflared</code> <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/local/as-a-service/">as a service</a>, you can turn on post-quantum by adding <code>post-quantum: true</code> to the tunnel configuration file. Conveniently, the <code>cloudflared</code> service will <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/local/local-management/arguments/#no-autoupdate">automatically update itself</a> if not installed by a package manager.</p><p>If, for some reason, creating a post-quantum tunnel fails, you’ll see an error message like</p>
            <pre><code>2022-09-22T17:30:39Z INF Starting tunnel tunnelID=[...]
2022-09-22T17:30:39Z INF Version 2022.9.1
2022-09-22T17:30:39Z INF GOOS: darwin, GOVersion: go1.19.1, GoArch: amd64
2022-09-22T17:30:39Z INF Settings: map[post-quantum:true pq:true]
2022-09-22T17:30:39Z INF Generated Connector ID: [...]
2022-09-22T17:30:39Z INF cloudflared will not automatically update if installed by a package manager.
2022-09-22T17:30:39Z INF Initial protocol quic
2022-09-22T17:30:39Z INF Using experimental hybrid post-quantum key agreement X25519Kyber512Draft00
2022-09-22T17:30:39Z INF Starting metrics server on 127.0.0.1:55889/metrics
2022-09-22T17:30:39Z INF 

===================================================================================
You are hitting an error while using the experimental post-quantum tunnels feature.

Please check:

   https://pqtunnels.cloudflareresearch.com

for known problems.
===================================================================================


2022-09-22T17:30:39Z ERR Failed to create new quic connection error="failed to dial to edge with quic: CRYPTO_ERROR (0x128): tls: handshake failure" connIndex=0 ip=[...]</code></pre>
            <p>When the post-quantum flag is given, <code>cloudflared</code> will <i>not</i> fall back to a non post-quantum connection.</p>
    <div>
      <h3>What to look for</h3>
      <a href="#what-to-look-for">
        
      </a>
    </div>
    <p>The setup phase is the crucial part: once established, the tunnel is the same as a normal tunnel. That means that performance and reliability should be identical once the tunnel is established.</p><p>The post-quantum cryptography we use is very fast, but requires roughly a kilobyte of extra data to be exchanged during the handshake. The difference will be hard to notice in practice.</p><p>Our biggest concern is that some network equipment/middleboxes might be confused by the bigger handshake. If the post-quantum Cloudflare Tunnel isn’t working for you, we’d love to hear about it. Contact us at <a>ask-research@cloudflare.com</a> and tell us which middleboxes or ISP you’re using.</p>
    <div>
      <h2>Under the hood</h2>
      <a href="#under-the-hood">
        
      </a>
    </div>
    <p>When the <code>--post-quantum</code> flag is given, <code>cloudflared</code> restricts itself to the QUIC transport for the tunnel connection to our network and will only allow the post-quantum hybrid key exchanges <code>X25519Kyber512Draft00</code> and <code>X25519Kyber768Draft00</code> with TLS identifiers <code>0xfe30</code> and <code>0xfe31</code> respectively. These are <a href="https://datatracker.ietf.org/doc/draft-stebila-tls-hybrid-design/">hybrid</a> key exchanges between the classical <a href="https://cr.yp.to/ecdh.html">X25519</a> and the post-quantum secure <a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a>. Thus, on the off-chance that Kyber turns out to be insecure, we can still rely on the non-post quantum security of X25519. These are the same key exchanges <a href="/post-quantum-for-all">supported on our network</a>.</p><p><code>cloudflared</code> randomly picks one of these two key exchanges. The reason is that the latter usually requires two initial packets for the TLS <i>ClientHello</i> whereas the former only requires one. That allows us to test whether a fragmented <i>ClientHello</i> causes trouble.</p><p>When <code>cloudflared</code> fails to set up the post-quantum connection, it will report the attempted key exchange, <code>cloudflared</code> version and error to <a href="https://pqtunnels.cloudflareresearch.com">pqtunnels.cloudflareresearch.com</a> so that we have visibility into network issues. Have a look at that page for updates on our post-quantum tunnel deployment.</p><p>The control connection and authentication of the tunnel between <code>cloudflared</code> and our network are not post-quantum secure yet. This is less urgent than the <i>store-now-decrypt-later</i> issue of the data on the tunnel itself.</p><p>We have <a href="https://github.com/cloudflare/qtls-pq">open-sourced</a> support for these post-quantum QUIC key exchanges in Go.</p>
    <div>
      <h2>Outlook</h2>
      <a href="#outlook">
        
      </a>
    </div>
    <p>In the coming decade the industry will roll out post-quantum data protection. Some cases will be as simple as a software update and others will be much more difficult. Post-Quantum Cloudflare Tunnel will secure the connection between Cloudflare’s network and your origin in a simple and user-friendly way — an important step towards the Post-Quantum Internet, so that everyone may continue to enjoy a private and secure Internet.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">4Uq6jjYa61mn71YcLKIpsF</guid>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
    </channel>
</rss>