From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Sat, 09 May 2026 02:39:21 -0700 Received: from mail-ot1-f57.google.com ([209.85.210.57]) by mail.fairlystable.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1wLe9V-0001Gr-5Q for bitcoindev@gnusha.org; Sat, 09 May 2026 02:39:21 -0700 Received: by mail-ot1-f57.google.com with SMTP id 46e09a7af769-7dcd603873fsf720471a34.2 for ; Sat, 09 May 2026 02:39:14 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1778319545; cv=pass; d=google.com; s=arc-20240605; b=YTNvv0KXscj55jPpHmw+9iHmeO9stYvkPNfEyGl2EdgWwofdvvAo7Lsri4OzvKcwzR b2jNAFM/dgYW6AZwmXtbtxQbjZhQkka/yiON36C/7GTAtQZH75uzvEIB4tw9F9NubHgu qSDbuhOVwgz91r0EAxdq3o45JYlXd5qPFR4fK1zOAJjNWX6MEgSryRtwZl9yYJtTsOxS SHiTbx0h9SfDzUMyD4u4CdElKjmUmyC6ql7XHvbSIbyYn6M7yxZxIoJCf2BrOrZO5SgB 68KY31dj6lpzPBrYmj0SYEg2fZwrkBBgBNc2o/9PbnS9z7KiGaYJUlLHo3CBWC1sQiPz ve6w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:mime-version:feedback-id :references:in-reply-to:message-id:subject:cc:from:to:date :dkim-signature; bh=YrlLqgk0T9AF3ZZoulLYnjwL1q3OyB+neXh8VwUi1C8=; fh=08tUOxLqaOWRcJBqIgkY0Euc2jLvUTSnmJbQ/5cZiEU=; b=ZAEWLP4Re2R7qIENY1Pg6JLCM1OC2reIdgCDLsTamp5bLe8dCG7UHE3gYvrN/qOJ24 A90fJ4mye2YFg6weHJuxpTbNpaTbUFTAKzFF0WJjJjK1R1bcWCMpuo9jUbVTTG9ebIUC /3sRi71zVPcqox/hHqpjMJgKvKJ1cakCFTfuHOEnJkQniZ+i3m6ovqqUU2hWiqviHH6f 7svwfdpVkO471NN/vqkwTihO4uKF1/6y8nDHX2UaOfnLvs1S1NOkVOqSqDI/AbqOaqno onILaZE8rRg9Oht4BAHsrlwRhVN3YJ2L9G9Sn+a2PmvYx2NyWpaGFUtvO7fRJUM2BNtZ ohDQ==; darn=gnusha.org ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=QB0BZhKB; spf=pass (google.com: domain of conduition@proton.me designates 79.135.106.101 as permitted sender) smtp.mailfrom=conduition@proton.me; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20251104; t=1778319545; x=1778924345; darn=gnusha.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:from:to:cc:subject:date:message-id:reply-to; bh=YrlLqgk0T9AF3ZZoulLYnjwL1q3OyB+neXh8VwUi1C8=; b=XCp/NH7HEzuw0HIWqrsE0fGT4lHTLE5pNOOGdYvTuv982mLuDjKcgbjzJj/PxIiPFB asp26/1EtfpUOGdiPJ99x32gGdAtZXJEyKpCz0FK2nDJq8nBS7WkWQnkYT8sl833MNxO f/ULAm11bnToka0CiYCQ4AfixOEJlozSM2Iq3pK9tO8WMIbdYteQeRpU/5r/7/SIIwa1 em1D35hidWcMX8KtnTSKeV14urFc01zBk1WQzg0zwpzFsnYC8GbsoMksmS7mlsuxS+Iq bGBr3I43LZv1N5yr3lhfiv+msxx3M22QS+tsHBW5/Ne8wTNswg6+YrUsQY1d8mb3fQEs 0zZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778319545; x=1778924345; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :date:x-beenthere:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=YrlLqgk0T9AF3ZZoulLYnjwL1q3OyB+neXh8VwUi1C8=; b=RF03ajToV3AwbbbbPwydZ7bIcBlFNCGUVuh/NzexpqrF/ZTfNQ7mi04WfLB9nVPy9Q Y/TozMcLgylUrsQx1AuDRRTFravcH/UKQXMvU+lPdPH9oM219GIqoS1SYBLcs/BDGqLO SHUHiMqkDYAIx14vV+Sz2oHfj/H1uuWAEByyNdYbFxERVi1vQFzgCUpIs5mTRrS0J4qB iKeTtozv3ic7oFZokgpzNZH8Z15rPb9gLGwh80mGWE2BwblqLz6qhogCRztMdYMm0H5z wFylw2l3xRLI4fogWvWJW8TW4mM9upqplwOGi2/4lqX+Ni6dtVEtKI3sbYWI8OreI2o6 bRlw== X-Forwarded-Encrypted: i=2; AFNElJ/W+qWDthIe/dRpOAQ0A9n08F9g3v4uKVJtBiq+6RtGOO4lbEyEiLQdXVbPEd8f/xpRitB55C8dDbWD@gnusha.org X-Gm-Message-State: AOJu0YwvXbvKFrG+MbOCbsJZXi3JVM8ZBYKCyO1d3i/vbiW6zhBVwlbr d3BBasKlf1NfCDb/3Qfd1uwkxX76Gx2AUXXZrDt2feNCGICPXNuBST5D X-Received: by 2002:a05:6830:43ab:b0:7de:a0e0:1f6 with SMTP id 46e09a7af769-7e1e2db7bc3mr6500627a34.5.1778319544809; Sat, 09 May 2026 02:39:04 -0700 (PDT) X-BeenThere: bitcoindev@googlegroups.com; h="AUV6zMOqn9qenOPzh+5CF9qMt/DbbszmlKf2lFKlZzJxM9nEwA==" Received: by 2002:a05:6871:5213:b0:417:5927:12e9 with SMTP id 586e51a60fabf-43590b3b130ls171556fac.2.-pod-prod-01-us; Sat, 09 May 2026 02:38:58 -0700 (PDT) X-Forwarded-Encrypted: i=2; AFNElJ9yJU82j/DUK1Fpd9dTmJ+2I2HfmwZfgjmQcA+EktS3DvTVsYZRTEmin4ilIGon7GG4fpuE3teJYSh+@googlegroups.com X-Received: by 2002:a05:6808:1805:b0:479:a908:5f50 with SMTP id 5614622812f47-4807fde45c5mr3692354b6e.40.1778319538755; Sat, 09 May 2026 02:38:58 -0700 (PDT) Received: by 2002:a05:600c:3b84:b0:485:53e3:ec5e with SMTP id 5b1f17b1804b1-48e64d06cddms5e9; Fri, 8 May 2026 20:21:41 -0700 (PDT) X-Forwarded-Encrypted: i=2; AFNElJ+BgRcDNfYUni91tHHT8hEgSxOWJ/AaDxCF1G6CA0rgNR1PgDaj21vBU2HW7zJn0lTwofPJzZk01q54@googlegroups.com X-Received: by 2002:a05:600c:2d15:b0:485:9a50:3370 with SMTP id 5b1f17b1804b1-48e51e16d0bmr144308505e9.8.1778296899376; Fri, 08 May 2026 20:21:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1778296899; cv=none; d=google.com; s=arc-20240605; b=kCZG5aNRZJG3E8MWhSEbZfUnQWz6Bk7yRwDucnclAx+LfkRmPFpQ4Jo3G1u7Fqqcnq 1hbvWYcJyJumZ0irP2TK5uFmsiclckczeKvNAZb2pydPWI978iA6S++Mnazg6+FY55I/ RfH/5BIg3R96zZMHd6WUApDuTjsNS5f34dxM3Pt8pvt6OYWOhr5Z/j60wyhiyfcvvBz6 ms/lJn6XxZj7Y3zgcZQR5pMOEBAIpnZ98N0OH8/6v1NEQj4tt+gUp9BQrCSF/g9S681o iAMylLUcSrXVPR4IK4gfPJNwmSwBBmIIbiZxQVMJn4SxTv95C916Xdjkmn1dT82tao/6 Kqew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=mime-version:feedback-id:references:in-reply-to:message-id:subject :cc:from:to:date:dkim-signature; bh=36EKDeMNmWSQ8hLtIe/SVSqMAKzdwfhLn2FvjOz1tao=; fh=JRz+axGi8dlp8x/Igc80lZ3Z7m7umVGO9kcwu8JX5X8=; b=ZKf3oHFBxHbkZXThhmjRSpRypN43OYswF2uKSCbTXIL2XEwjbFzCT8tdEX1m3/qXCT PIhGsXBrjtd+O2JvEHMK1gZcVz4TkcVjqADPWO0aoh/wYt0zv6ta7GopSxdRxt54bQys +vtcSgnPlsOLI0MgdVeJUfLL5YmPV2IPMlLlk5PBXZvhaOhTFuUuZtCDk0rmRFcWVF7e a08c/SOd1Z7WJcfj8nTFyyk4I/0GwRtiazn4VJcUPzJmzHY8JOQXOvat8cHlvqa1LA7f tsh1bIUDXWIQP9vtehw82Ej8udn6nh6IMqM1ngSjeQaPHAW2IlMTuw1TZ6WJNyQdsTiT ef2g==; dara=google.com ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=QB0BZhKB; spf=pass (google.com: domain of conduition@proton.me designates 79.135.106.101 as permitted sender) smtp.mailfrom=conduition@proton.me; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: from mail-106101.protonmail.ch (mail-106101.protonmail.ch. [79.135.106.101]) by gmr-mx.google.com with ESMTPS id 5b1f17b1804b1-48e6f3d7dddsi89145e9.0.2026.05.08.20.21.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 May 2026 20:21:39 -0700 (PDT) Received-SPF: pass (google.com: domain of conduition@proton.me designates 79.135.106.101 as permitted sender) client-ip=79.135.106.101; Date: Sat, 09 May 2026 03:21:34 +0000 To: Jonas Schnelli From: "'conduition' via Bitcoin Development Mailing List" Cc: Olaoluwa Osuntokun , Ethan Heilman , Bitcoin Development Mailing List Subject: Re: [bitcoindev] A Post-Quantum Path for BIP 324 Message-ID: In-Reply-To: <547ADFCA-2BB1-4E16-A26A-C92262EBBD84@gmail.com> References: <547ADFCA-2BB1-4E16-A26A-C92262EBBD84@gmail.com> Feedback-ID: 72003692:user:proton X-Pm-Message-ID: c174e1addafceb69cc58ac3903ad0f44b0969e3e MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg=pgp-sha512; boundary="------8c1e29c5a1c2aa24b2964a9c6ad5ccb5aa179f570be001d3785448137e3009d3"; charset=utf-8 X-Original-Sender: conduition@proton.me X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=QB0BZhKB; spf=pass (google.com: domain of conduition@proton.me designates 79.135.106.101 as permitted sender) smtp.mailfrom=conduition@proton.me; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me X-Original-From: conduition Reply-To: conduition Precedence: list Mailing-list: list bitcoindev@googlegroups.com; contact bitcoindev+owners@googlegroups.com List-ID: X-Google-Group-Id: 786775582512 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , X-Spam-Score: -1.0 (-) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --------8c1e29c5a1c2aa24b2964a9c6ad5ccb5aa179f570be001d3785448137e3009d3 Content-Type: multipart/mixed;boundary=---------------------70aeb7f8668ccd095441ffe211910ec4 -----------------------70aeb7f8668ccd095441ffe211910ec4 Content-Type: multipart/alternative;boundary=---------------------a5150975640a6204639aad6dc639c2bf -----------------------a5150975640a6204639aad6dc639c2bf Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="UTF-8" Hi all, I'm not well-versed in the P2P network transport protocol or BIP324, so I'm= not well-qualified to give feedback on the details of this idea. But I did= want to chime in on this statement: > One thing worth noting is that AFAICT, so far in the NIST PQC world [4], = there is=C2=A0no known non-interactive key exchange protocol like we enjoy = today with ECDH. IIUC, the reason is that lattice based schemes derived fro= m the LWE [3] problem, whose security is predicated on using "noise" to hid= e a secret value. For these cryptosystems, usually a type of "hint" is sent= to make everything work out nicely like in ECDH. However, in the stricter = non-interactive setting=C2=A0(no messages sent), this doesn't map cleanly.= =C2=A0 It's important to emphasize this only considers the NIST-standardized KEMs.= If we zoom out to the broader ecosystem of PQ PKE candidates, there are se= veral options for non-interactive key exchange systems that'd be a drop-in = replacement for ECDH. For instance, oriented isogeny-based systems like CSIDH [1] [2] permit this= kind of construction. Both parties publish a short (64 to 128 byte) pubkey= and can perform key exchange as soon as they've seen the peer's pubkey, no= additional messages required. The down side of CSIDH is that it's quite sl= ow, so it is most useful when pubkeys are static or otherwise don't change = much. There has been a lot of work done with new faster schemes=C2=A0[3] or= speeding up CSIDH with better implementations=C2=A0[4] but still key excha= nge can take a good few dozen milliseconds.=C2=A0 In general, any post-quantum-secure commutative group action scheme allows = non-interactive key exchange. CSIDH is just one such example, and I'm sure = there are and will be others. Being unversed in BIP324 as yet, I'm not sure how crucial this non-interact= ivity property is to the protocol. If it's not a big deal, then I'd gladly = toss my hat in for lattices and a hybridized ML-KEM construction, given so = much of the internet is already migrating to this. It makes sense to follow= standards if we can. Going full-TLS would probably be overkill IMO - It is= designed for a very different (centralized) PKI architecture and would buy= us a ticket for a train we probably don't want to ride. Maybe there's a more applicable standard, a la Noise/Wireguard? For a possi= ble implementation reference, see [5]. Otherwise rolling our own standard s= eems like the way to go, especially if we can do so in a way that is reusab= le for other use-cases beyond Bitcoin. Also, if we go with a hybrid scheme, we should have clear migration paths t= o transition to either pure PQC (if a CRQC appears and breaks ECDH, we migh= t as well discard it), or back to classical ECDH (if CRQCs turn out to be i= mpossible). regards, conduition [1]:=C2=A0https://csidh.isogeny.org/ [2]:=C2=A0https://eprint.iacr.org/2018/383 [3]:=C2=A0https://eprint.iacr.org/2025/1098.pdf [4]:=C2=A0https://ctidh.isogeny.org/ctidh-20210513.pdf [5]:=C2=A0https://github.com/jmlepisto/clatter On Thursday, May 7th, 2026 at 1:45 AM, Jonas Schnelli wrote: > Thanks for writing this up Laolu. >=20 > I think option 1 (classical-then-PQ-upgrade) is probably the right path, = mostly because it keeps the byte-0 pseudorandomness property without needin= g Kemeleon or any new obfuscation primitive. >=20 > If the ML-KEM exchange happens inside the already-established v2 ChaCha20= Poly1305 channel, then to a present-day classical observer the bytes should= still look random,... the inner PQ handshake is just more ciphertext. A fu= ture QC adversary doing harvest-now-decrypt-later would break the outer ECD= H eventually, but I think they'd then still have to break ML-KEM-768 to get= the v3 transport keys, which is kind of the whole point. So we'd probably = get hybrid security against the QC threat and also keep the property that t= oday's wire bytes are indistinguishable from random. >=20 > That said, I'm not sure how far we should really take the pseudorandomnes= s argument,... traffic shape (packet sizes, timings, query/response pattern= s) probably already reveals quite a bit about what's going on, so the byte-= content randomness is only one part of the picture. >=20 > The extra round trip is probably fine given how long Bitcoin P2P connecti= ons live. The DoS angle you flagged might also be smaller in option 1, sinc= e the responder still commits after 64 bytes and not after a 1184-byte ML-K= EM key,... though I haven't thought hard about wether there are other DoS v= ectors the inner upgrade introduces. >=20 > On Ethan's TLS 1.3 suggestionm,... I don't think it really fits. Apart fr= om the dependency cost (which we deliberately kept low in BIP 324), TLS has= it's own fingerprint, which would probably undo the censorship-resistance = angle. And it bundles authentication with encryption, which we explicitly d= ecoupled. >=20 > One thing worth looking at: OpenSSH (whose chacha20-poly1305 construction= we drew from originally) shipped mlkem768x25519-sha256 as default in 10.0 = last year, and they just concatenate-and-hash the two shared secrets. Their= threat model doesn't care about pseudorandomness so they can send ML-KEM m= aterial in the clear, but the combiner shape is probably a reasonable refer= ence for ours. >=20 > /jonas >=20 >=20 > > On May 6, 2026, at 12:15=E2=80=AFPM, Olaoluwa Osuntokun wrote: > >=20 > > Hi Ethan,=C2=A0 > >=20 > > That's a great question.=C2=A0 > >=20 > > First, I don't speak for Bitcoin Core by any means (btcd has also imple= mented > > BIP 324 FWIW). Based on past observed behavior, they typically prefer t= o keep > > dependencies slim. Many years ago there was a concerted push to remove = openssl > > as a dependency from the project. So I would imagine the idea of rollin= g out > > full blown TLS 1.3 might encounter some resistance. > >=20 > > In terms of cryptography, BIP 324 as defined uses secp256k1. TLS 1.3 as > > specified doesn't support secp256k1 within the set of supported cipher = suites. > >=20 > > If ensuring that BIP 324 continues to implement an oblivious KEM is a k= ey > > requirement, then TLS 1.3 doesn't fit the bill. > >=20 > > Regarding a hybrid PQ KEM, there exists an IETF to add a new key agreem= ent > > suite to TLS 1.3:=C2=A0https://datatracker.ietf.org/doc/draft-ietf-tls-= ecdhe-mlkem/. > > Only secp256+384(r1) and x25519 are supported as elliptic curves in thi= s draft. > >=20 > > One additional aspect is that today BIP 324 doesn't implement authentic= ation at > > all, you only get confidentiality. TLS 1.3 would mean introducing certi= ficates > > in some fashion, thereby coupling concerns from the original PoV of Bip= 324. > >=20 > > BIP 324 also includes as section in the BIP detailing the rationale of = BIP 324 > > over a more general purpose protocol (mentions some of the points above= ): > > https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki#:~:text= =3DWhy%20not%20use%20a%20general%2Dpurpose%20transport%20encryption%20proto= col%3F. > >=20 > >=20 > > -- Laolu > >=20 > > On Tue, May 5, 2026 at 2:18=E2=80=AFPM Ethan Heilman = wrote: > >=20 > > > Thanks Laolu for thinking through making PQ BIP 324 and writing this = up. > > >=20 > > > Reading through what you wrote made me what wonder, why not use this = as an opportunity to move to TLS 1.3? > > >=20 > > > What's the case against using TLS 1.3 for PQ P2P connection encryptio= n? Is there some functionality that TLS 1.3 is lacking that we really want?= =C2=A0 Is the case against solely to not have TLS 1.3 as a complex dependen= cy in bitcoin-core? > > > The advantages of TLS 1.3: > > >=20 > > > 1. Make Bitcoin P2P connections blend in with all the other TLS conne= ctions. This isn't strong privacy, you can distinguish TLS encrypted Bitcoi= n traffic via timing and size, but it reduces accidents where a firewall se= es an unknown protocol and blocks it. > > >=20 > > > 2. Use of QUIC for faster relay, oblivious HTTP and QUIC tunnels-in-t= unnels for private relay and similar protocols. > > > 3. Lots of eyeballs on TLS 1.3, we don't need to build or maintain it= . > > >=20 > > >=20 > > > On Tue, May 5, 2026, 00:41 Olaoluwa Osuntokun wro= te: > > >=20 > > > > Hi y'all,=C2=A0 > > > >=20 > > > > In case you weren't already tired of all the recent dev list chatte= r re post > > > > quantum cryptography, here's another! > > > >=20 > > > > When the topic of Bitcoin transitioning to a post quantum world is = brought up, > > > > the discussion typically focuses on the consensus layer re swapping= out > > > > vulnerable signature schemes. However, the consensus layer isn't th= e only area > > > > of Bitcoin that relies in cryptography that would be broken in the = face of a > > > > powerful quantum computer! That's right, I'm talking about BIP 324,= the peer to > > > > peer encryption BIP for Bitcoin. > > > >=20 > > > > Like everything else on the Internet today, BIP 324 uses ECDH to al= low two > > > > connecting peers to derive a shared secret known only to them, whic= h is then > > > > used to encrypt all traffic between them. As ECDH relies on Ellipti= c Curve > > > > cryptography, a future quantum computer would be able to eavesdrop = on a p2p > > > > handshake transcript, then derive the underlying private keys to th= e ephemeral > > > > ECDH public key, permitting it to decrypt all traffic. It's actuall= y worse than > > > > that, as today adversaries can collect all encrypted p2p Bitcoin tr= affic, with > > > > the hope of being able to decrypt it all at a future date. This is = commonly > > > > referred to as the: "harvest, decrypt later" (HNDL) strategy [11]. > > > >=20 > > > > Compared to a consensus change, which requires widespread market ag= reement, and > > > > coordination to achieve, upgrading BIP 324 to be post quantum resis= tant is a > > > > much lower hanging fruit worthy of pursing immediately. > > > >=20 > > > > Last week I starting thinking a bit about this topic, brushing up o= n the latest > > > > literature/techniques, and stumbled onto a few key design questions= . The goal > > > > of this post isn't to propose a new concrete p2p encryption BIP, in= stead I want > > > > to start discussion on the various design tradeoffs that came up as= I was > > > > researching this p2p encryption transition. > > > >=20 > > > > ## PQ BIP 324 Design Questions > > > >=20 > > > > 1. Do we want to pursue a hybrid KEM (key encapsulation mechanism),= or go with > > > > =C2=A0 =C2=A0a pure PQ KEM? > > > >=20 > > > > 2. Is it still a key requirement that the initial handshake be > > > > =C2=A0 =C2=A0indistinguishable from a random byte string? > > > >=20 > > > > =C2=A0 =C2=A02a. If yes to the above, then should we go with classi= cal-then-pq-upgrade, > > > > =C2=A0 =C2=A0or a one shot hybrid oblivious KEM. > > > >=20 > > > >=20 > > > > ## A Brief Intro to KEMs + ML-KEM > > > >=20 > > > > First, let's introduce the new primitive we have to work with: ML-K= EM > > > > (Module-Lattice-Based Key-Encapsulation Mechanism) [1][2]. As it sa= ys on the > > > > tin, ML-KEM is a lattice based Key-Encapsulation Mechanism. The phr= ase KEM > > > > might sound unfamiliar with those comfortable with ECDH, but ECDH i= s actually a > > > > KEM itself. > > > >=20 > > > > A KEM has 3 algorithms: > > > > =C2=A0=C2=A0* KeyGen() -> {sk, pk} > > > > =C2=A0 =C2=A0 =C2=A0* Generates a public/private secret key pair > > > >=20 > > > > =C2=A0=C2=A0* Encaps(pub) -> {secret, capsule} > > > > =C2=A0 =C2=A0 =C2=A0* Generates a new secret value, and a "capsule"= , which only the holder of > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0pub can use to obtain the secret value. > > > >=20 > > > > =C2=A0=C2=A0* Decaps(priv, capsule) -> secret > > > > =C2=A0 =C2=A0 =C2=A0* Uses the private key to extract the secret fr= om the capsule > > > >=20 > > > >=20 > > > > If you squint a bit, then you'll see that ECDH is a KEM, and a rath= er elegant > > > > one at that: > > > > =C2=A0=C2=A0* KeyGen() -> {k, k*G} > > > > =C2=A0 =C2=A0 =C2=A0=C2=A0* Normal EC key generation.=C2=A0 > > > >=20 > > > > =C2=A0=C2=A0* Encaps(pub) -> {capsule =3D x*G, secret =3D pub*x} > > > > =C2=A0 =C2=A0 =C2=A0=C2=A0* The core ECDH routine. The ephemeral pu= blic key is actually the > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0"capsule". The resulting secret is= the ECDH output with the remote > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0party's KEM public key and the loc= al secret. > > > >=20 > > > > =C2=A0=C2=A0* Decaps(priv, capsule) -> secret =3D priv * capsule > > > > =C2=A0 =C2=A0 =C2=A0=C2=A0* The receiver completes the key exchange= using the ephemeral public key > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0and their own private key. > > > >=20 > > > > ECIES is another flavor of EC based KEM. > > > >=20 > > > > One thing worth noting is that AFAICT, so far in the NIST PQC world= [4], there is > > > > no known non-interactive key exchange protocol like we enjoy today = with ECDH. > > > > IIUC, the reason is that lattice based schemes derived from the LWE= [3] > > > > problem, whose security is predicated on using "noise" to hide a se= cret value. > > > > For these cryptosystems, usually a type of "hint" is sent to make e= verything > > > > work out nicely like in ECDH. However, in the stricter non-interact= ive setting > > > > (no messages sent), this doesn't map cleanly. > > > >=20 > > > > As a result, ML-KEM looks more like a hybrid encryption protocol (A= lice > > > > encrypts a shared secret to bob using asymmetric lattice crypto). > > > >=20 > > > > ## To Hybrid KEM, Or Not to Hybrid KEM > > > >=20 > > > > This brings us to our first design question.... > > > >=20 > > > > Should we use a hybrid KEM or a pure post quantum one?=C2=A0 > > > >=20 > > > > A hybrid KEM would keep the existing ECDH, _also_ do ML-KEM, then s= ecurely > > > > combine (there's some subtlety there, see [6][7]) the resulting in = a > > > > final secret value for encryption. A hybrid KEM is attractive as an= encryption > > > > channel derived from such a KEM is secure if _any_ of the combined = schemes are > > > > secure. This permits schemes to hedge a bit, as hey, maybe the PQ s= tuff is > > > > actually broken in the future but ECDH isn't. If it's the other way= around, > > > > then your encryption scheme is still secure. > > > >=20 > > > > ### Pure ML-KEM P2P Encrypted Handshake > > > >=20 > > > > If we opt to not use a hybrid scheme, then the Elligator layer can = be dropped > > > > all together. Instead, the 1.1 KB (ML-KEM-768) encapsulation keys a= re sent, > > > > keeping the trailing garbage+terminator in tact.=C2=A0 > > > >=20 > > > > The initial handshake would look something like:=C2=A0 > > > > =C2=A0* Alice -> Bob: alice_encaps || initiator_garbage > > > > =C2=A0 =C2=A0=C2=A0* Alice derives an encapsulation key, and sends = it to Bob. > > > >=20 > > > > =C2=A0* Bob -> Alice: ml_kem_capsule || responder_garbage || respon= der_garbage_terminator || first_encrypted_packet > > > > =C2=A0 =C2=A0* Bob uses Alice's encapsulation key to encapsulate a = random secret, and > > > > =C2=A0 =C2=A0 =C2=A0sends it over to Alice. He can also encrypt the= first message at this > > > > =C2=A0 =C2=A0 =C2=A0point. > > > >=20 > > > > =C2=A0* Alice -> Bob: initiator_garbage_terminator || first_encrypt= ed_packet > > > > =C2=A0 =C2=A0* Alice de-encapsulates the shared secret, and can now= also start to encrypt > > > > =C2=A0 =C2=A0 =C2=A0messages. > > > >=20 > > > > We'd then replace `v2_ecdh` with something like a `v3_mlkem` that d= erives the > > > > final shared secret based on the sent/received transcript up until = that point: > > > > =C2=A0=C2=A0* `sha256_tagged("bip324_ml_kem", ml_kem_secret, alice_= encaps, ml_kem_capsule)` > > > >=20 > > > > ### Hybrid ML-KEM P2P Encrypted Handshake > > > >=20 > > > > If we want to use a hybrid combiner, then along side the normal ell= swift keys, > > > > the ML-KEM-768 encap key is also sent: > > > >=20 > > > > =C2=A0* Alice -> Bob: ellswift_alice || alice_encaps || initiator_g= arbage > > > > =C2=A0* Bob -> Alice: ellswift_bob || ml_kem_capsule || responder_g= arbage || responder_garbage_terminator || first_encrypted_packet > > > > =C2=A0* Alice -> Bob: initiator_garbage_terminator || first_encrypt= ed_packet > > > >=20 > > > > Then following guidelines of [7], we'd then replace `v2_ecdh` with = something > > > > like `v3_hybrid_shared_secret`: > > > > =C2=A0=C2=A0* `sha256_tagged("bip324_ellswift_xonly_ecdh_mlkem_768"= , ml_kem_ss, ecdh_point_x32, alice_encaps, ml_kem_capsule, ellswift_alice, = ellswift_bob)` > > > >=20 > > > > ## PQ/Hybrid Obfuscated KEMs > > > >=20 > > > > At this point, those that are familiar with BIP 324 will recognize = that both > > > > the pure PQ and hybrid versions renders the ElligatorSwift usage pr= etty much > > > > useless. ElligatorSwift encodes a 32-byte public key as a 64-byte v= alue which > > > > is indistinguishable from a uniformly distributed bitstream. In a b= ubble, this > > > > means that the initial BIP 324 handshake to a 3rd party observer ju= st looks > > > > like random bytes. However, with the introduction of ML-KEM, the ML= -KEM > > > > encapsulation key is sent in plaintext over the wire. An ML-KEM key= has > > > > identifiable structure, as it's a giant vector of polynomial coeffi= cients mod > > > > 3329, which is easily recognizable over the wire. > > > >=20 > > > > Luckily, there's an ML-KEM analogue to ElligatorSwift, called Kemel= eon > > > > [8][9][10]! In a similar fashion to ElligatorSwift, it takes an ML-= KEM public > > > > key, then encodes it as one giant integer, utilizing rejection samp= ling. > > > > Kemeleon applies this mapping both to the encapsulation keys, and a= lso the > > > > capsule ciphertext that encrypts the shared secrets. The ML-KEM key= s end up > > > > being a bit smaller, while the ciphertexts map to a larger value. A= nother > > > > tradeoff is that the Kemeleon key generation is ~3x slower than nor= mal ML-KEM > > > > generation. > > > >=20 > > > > One thing to note here is that Kemeleon's "looks random" property i= sn't quite > > > > on the same footing as ElligatorSwift's. ElligatorSwift is statisti= cally > > > > indistinguishable from random, since every 512-bit string is a vali= d encoding. > > > > Kemeleon's indistinguishability is computational, resting on a Modu= le-LWE > > > > style assumption. So if you naively concatenate an ElligatorSwift k= ey and a > > > > Kemeleon key, the pair is only as obfuscated as the weakest visible= half. This > > > > asymmetry is what motivates the OEINC construction discussed below. > > > >=20 > > > > This brings us to our second design question.... > > > >=20 > > > > Do we still want to ensure that the BIP-324 handshake looks identic= al to a > > > > pseudorandom bytestream from the very first message? > > > >=20 > > > > Assuming yes, then AFAICT, we have two classes of options here:=C2= =A0 > > > > =C2=A0=C2=A01. Retain the existing BIP-324 outer ElligatorSwift han= dshake, but use ML-KEM > > > > =C2=A0 =C2=A0 =C2=A0within that initial encrypted transport to upgr= ade to a PQ shared secret. > > > >=20 > > > > =C2=A0=C2=A02. Use the Outer Encrypts Inner Nested Combiner (OEINC = - "OINK") combiner > > > > =C2=A0 =C2=A0 =C2=A0from [8]. > > > >=20 > > > > =C2=A0=C2=A03. Attempt to adapt Drivel from [8] into the Bitcoin p2= p setting. > > > >=20 > > > > ### Classical Encrypted Channel Upgrades to PQ > > > >=20 > > > > With the first option, we simply use one KEM right after the other.= So BIP 324 > > > > v2 would be mostly unchanged, then we _upgrade_ to BIP 324 v3 withi= n v2.=C2=A0 > > > >=20 > > > > A sketch of this would be something like: > > > > =C2=A0=C2=A0* Phase 0: normal BIP 324 handshake > > > > =C2=A0=C2=A0* Phase 1: negotiation of PQ KEM scheme over the encryp= ted handshake > > > > =C2=A0 =C2=A0 =C2=A0* Can be optional, if we just pick a set PQ KEM= scheme. > > > > =C2=A0 =C2=A0 =C2=A0* Before this point, no Bitcoin p2p message sho= uld be sent, as the channel > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0isn't PQC protected yet. > > > > =C2=A0=C2=A0* Phase 2: do normal ML-KEM within the ElligatorSwift d= erived encrypted > > > > =C2=A0 =C2=A0=C2=A0transport > > > > =C2=A0 =C2=A0 =C2=A01. Alice sends the encapsulation key > > > > =C2=A0 =C2=A0 =C2=A02. Bob derives a secrets, encrypts it using the= encapsulation key > > > > =C2=A0 =C2=A0 =C2=A03. Both sides then derive a PQ shared secret, s= s_PQ > > > > =C2=A0=C2=A0* Phase 3: both sides use a hybrid combiner like sketch= ed out above to derive > > > > =C2=A0 =C2=A0=C2=A0a new set of transport keys > > > > =C2=A0=C2=A0* Phase 4: both sides rekey, switching over to a new th= e transport keys > > > >=20 > > > > The upside of this option is that the outer part of BIP 324 remains= unchanged, > > > > then with another round trip, we're able to upgrade the encryption = keys to PQ > > > > hybrid security. The downside is that the very first messages sent = aren't PQ > > > > from the start, but a PQ adversary wouldn't be able to decrypt the = actual > > > > Bitcoin p2p messages (as we wait to send those until the upgrade). = The > > > > handshake still looks like just random bytes. > > > >=20 > > > > ### Outer Encrypts Inner Nested Combiner > > > >=20 > > > > For the second option, [8] (with talk video [9] and slides [10]) de= scribes an > > > > OEINC scheme where the outer KEM > > > > encrypts the inner KEM, wherein the KEM ciphertext of an inner KEM = is encrypted > > > > using a shared secret derived from the outer KEM. The two KEM ciphe= rtexts and > > > > the two derived keys are then used alongside a hybrid combiner to d= erive a > > > > final shared secret.=C2=A0 > > > >=20 > > > > Unlike the classical-then-pq-upgrade that establishes a classical c= hannel, then > > > > uses that to upgrade to pq channel, OEINC is a special hybrid combi= ner that > > > > achieves a similar output but in one swoop. It defines a special KE= M, which can > > > > then be used as the KEM in the very first handshake I sketched out. > > > >=20 > > > > A sketch of this KEM looks something like: > > > > =C2=A0=C2=A0* Setup: > > > > =C2=A0 =C2=A0=C2=A0* The outer KEM is BIP 324's ElligatorSwift-enco= ded secp256k1 DHKEM. > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0* It serves as the outer KEM because its= on-wire encoding is > > > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0statistically indistinguishable f= rom random. > > > > =C2=A0 =C2=A0=C2=A0* The inner KEM is ML-Kemeleon. > > > >=20 > > > > =C2=A0=C2=A0* KeyGen(): > > > > =C2=A0 =C2=A0=C2=A0* (kem_secret_outer, kem_pubkey_outer) =3D outKE= M.Gen() > > > > =C2=A0 =C2=A0=C2=A0* (kem_secret_inner, kem_pubkey_inner) =3D inKEM= .Gen() > > > > =C2=A0 =C2=A0=C2=A0* combined_pubkey =3D (kem_pubkey_outer, kem_pub= key_inner) > > > > =C2=A0 =C2=A0=C2=A0* combined_secret =3D (kem_secret_outer, kem_sec= ret_inner) > > > >=20 > > > > =C2=A0=C2=A0* Encaps(combined_pubkey): > > > > =C2=A0 =C2=A0=C2=A0* (shared_secret_outer, capsule_outer) =3D outKE= M.Encap(kem_pubkey_outer) > > > > =C2=A0 =C2=A0=C2=A0* (encrypt_key_1, encrypt_key_2) =3D KDF(shared_= secret_outer) > > > > =C2=A0 =C2=A0=C2=A0* (shared_secret_inner, capsule_inner) =3D inKEM= .Encap(kem_pubkey_inner) > > > > =C2=A0 =C2=A0=C2=A0* encrypted_capsule_inner =3D encrypt(encrypt_ke= y_1, capsule_inner) > > > > =C2=A0 =C2=A0=C2=A0* combined_capsule =3D capsule_outer || encrypte= d_capsule_inner > > > > =C2=A0 =C2=A0=C2=A0* combined_shared_secret =3D combine(encrypt_key= _2, shared_secret_inner, combined_capsule) > > > >=20 > > > > =C2=A0=C2=A0* Decaps(combined_secret, combined_capsule): > > > > =C2=A0 =C2=A0=C2=A0* (capsule_outer, encrypted_capsule_inner) =3D c= ombined_capsule > > > > =C2=A0 =C2=A0=C2=A0* shared_secret_outer =3D outKEM.Decaps(kem_secr= et_outer, capsule_outer) > > > > =C2=A0 =C2=A0=C2=A0* (encrypt_key_1, encrypt_key_2) =3D KDF(shared_= secret_outer) > > > > =C2=A0 =C2=A0=C2=A0* capsule_inner =3D decrypt(encrypt_key_1, encry= pted_capsule_inner) > > > > =C2=A0 =C2=A0=C2=A0* shared_secret_inner =3D inKEM.Decaps(kem_secre= t_inner, capsule_inner) > > > > =C2=A0 =C2=A0=C2=A0* combined_shared_secret =3D combine(encrypt_key= _2, shared_secret_inner, combined_capsule) > > > >=20 > > > >=20 > > > > This is done over just sending the two encapsulated secrets plainly= as I > > > > outlined above in order to achieve a stronger security notion. The = issue with > > > > this though is that though ciphertext uniformity (the encapsulated = secrets) is > > > > achieved, the two public keys sent are randomly looking, but not in= a uniform > > > > manner. In practice, this might not really matter much AFAICT (a th= eoretical > > > > adversary would be able to distinguish the Elligator half from the = Kemeleon > > > > half). > > > >=20 > > > > ### Drivel: PQ-Obfuscated Authentication > > > >=20 > > > > The biggest issue with Drivel as a fit for BIP 324 is that it expec= ts the > > > > initiator to already know a long term static public key for the res= ponder. In > > > > the case of BIP 324, only ephemeral keys are exchanged, so there's = no long > > > > term public keys known to either side. > > > >=20 > > > > To get around this, we could extend BIP 155 (or make a new one like= ly, given > > > > size limits) to include a signed OKEM key. However then that would = introduce > > > > authentication into the combined set, which explicitly wasn't a des= ign goal > > > > of BIP 324. > > > >=20 > > > > With that caveat in mind, here's the construction itself. Drivel [8= ] combines > > > > the OEINC scheme with another layer that out-of-the-box assumes an = asymmetric > > > > protocol within a set client and server. The client uses an existin= g OEINC > > > > KEM public key published by the server to then encrypt a fresh new = ephemeral > > > > KEM. > > > >=20 > > > > -----=C2=A0 > > > >=20 > > > > So there we have it. Before drafting a concrete v3 transport, we ne= ed to > > > > decide if we want a hybrid KEM, or are fine with a pure PQ KEM. The= n we need to > > > > decide if we want to attempt to maintain the current quality where = the p2p > > > > handshake transcript is indistinguishable from random. If yes, then= that forces > > > > another series of decisions re how to construct/compose an obliviou= s KEM from > > > > available primitives. > > > >=20 > > > > At a glance, the route of classical-then-pq-upgrade seems to be the= simplest. > > > > BIP 324 stays as is, then we run ML-KEM within that. The ML-KEM key= s are > > > > encrypted, so there's no need to sprinkle in the layer of Kemeleon. > > > >=20 > > > > If we want a nice combined protocol, then we should investigate the= OEINC > > > > route. It's more data to send as part of the initial handshake, but= we still > > > > keep ElligatorSwift and use that as the outer KEM. > > > >=20 > > > > If for some reason we're concerned with a future adversary gaining = a > > > > distinguisher for Kemeleon, then maybe we need to bite the bullet a= nd also > > > > roll out a full blown PQ authentication protocol along side everyth= ing. > > > >=20 > > > > One thing worth flagging for any of the byte-0 designs (where PQ ma= terial is > > > > sent in the clear on the very first flight, like the hybrid and OEI= NC sketches > > > > above): ML-KEM-768 makes the responder do real work before it can d= ecide if a > > > > connection is even legit. Today, the responder only needs the first= 64 bytes > > > > of an ElligatorSwift share before it can derive the shared secret. = With > > > > ML-KEM-768, the responder has to read and validate a 1184 byte enca= psulation > > > > key before running Encaps, and FIPS 203 mandates input checks on ev= ery Encaps > > > > and Decaps. In a permissionless P2P network, that's a meaningful ch= ange in > > > > inbound DoS surface, and probably calls for stricter handshake byte= limits, > > > > tighter timeouts, and possibly some form of stateless cookie/puzzle= if > > > > handshake floods become a real problem. The classical-then-pq-upgra= de path > > > > sidesteps most of this since the PQ material only shows up after th= e v2 > > > > channel is up. > > > >=20 > > > > With all that said, after the above design decisions are addressed,= there > > > > aren't too many concrete blockers here w.r.t rolling this out. Of c= ourse the > > > > development (eg: selecting/creating a library for ML-KEM and maybe > > > > ML-Kemeleon), and upgrade will take some time. But unlike the conse= nsus > > > > layer, p2p encryption doesn't require the widespread market agreeme= nt that an > > > > actual soft fork does. BIP 324 is a much shorter walk to PQ than th= e consensus > > > > layer, and serves as a sort of PQ warm up before the bigger soft fo= rk is > > > > tackled.=C2=A0 > > > >=20 > > > >=20 > > > > -- Laolu > > > >=20 > > > > [1]:=C2=A0https://en.wikipedia.org/wiki/ML-KEM > > > > [2]:=C2=A0https://csrc.nist.gov/pubs/fips/203/final > > > > [3]:=C2=A0https://en.wikipedia.org/wiki/Learning_with_errors > > > > [4]: This statement ignores Isogeny based crypto, and also SWOOSH [= 5] as it requires 200 KB pubkeys > > > > [5]:=C2=A0https://eprint.iacr.org/2023/271 > > > > [6]:=C2=A0https://eprint.iacr.org/2018/024 > > > > [7]:=C2=A0https://eprint.iacr.org/2020/1364 > > > > [8]:=C2=A0https://eprint.iacr.org/2024/1086 > > > > [9]:=C2=A0https://www.youtube.com/watch?v=3DCvFCYUq5rGg > > > > [10]:=C2=A0https://csrc.nist.gov/csrc/media/Presentations/2025/keme= leon/images-media/kemeleon.pdf > > > > [11]:=C2=A0https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later > > > >=20 > > > > --=C2=A0 > > > > You received this message because you are subscribed to the Google = Groups "Bitcoin Development Mailing List" group. > > > > To unsubscribe from this group and stop receiving emails from it, s= end an email to=C2=A0bitcoindev+unsubscribe@googlegroups.com. > > > > To view this discussion visit=C2=A0https://groups.google.com/d/msgi= d/bitcoindev/CAO3Pvs9U3prZJiDs0Ns7LSA07R8hM-GQou_FcTZZz-JUQpUYHw%40mail.gma= il.com. > >=20 > >=20 > > --=C2=A0 > > You received this message because you are subscribed to the Google Grou= ps "Bitcoin Development Mailing List" group. > > To unsubscribe from this group and stop receiving emails from it, send = an email to=C2=A0bitcoindev+unsubscribe@googlegroups.com. > > To view this discussion visit=C2=A0https://groups.google.com/d/msgid/bi= tcoindev/CAO3Pvs8i%3DpLP30nRh_iyjSRJXne19wNezmQmo%3DJAk8%2BE4uJPhg%40mail.g= mail.com. >=20 >=20 >=20 > -- > You received this message because you are subscribed to the Google Groups= "Bitcoin Development Mailing List" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to bitcoindev+unsubscribe@googlegroups.com. > To view this discussion visit https://groups.google.com/d/msgid/bitcoinde= v/547ADFCA-2BB1-4E16-A26A-C92262EBBD84%40gmail.com. --=20 You received this message because you are subscribed to the Google Groups "= Bitcoin Development Mailing List" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoindev+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/= RS1NnL6YB4YFxxuEa9eOQuB5OOkPp6zwxWkLl9QCFQfE9-1y9vB0njN2QycURGNdSkT3sM4erCy= aSkYvkmYTHicE32JMNMRepa1QwV3obVc%3D%40proton.me. -----------------------a5150975640a6204639aad6dc639c2bf Content-Type: multipart/related;boundary=---------------------02ec46135174dd15ba7ef4320d6267aa -----------------------02ec46135174dd15ba7ef4320d6267aa Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi all,

I'm not we= ll-versed in the P2P network transport protocol or BIP324, so I'm not well-= qualified to give feedback on the details of this idea. But I did want to c= hime in on this statement:

One thing worth noting is that AFAICT, so f= ar in the NIST PQC world [4], there is no known non-interactive= key exchange protocol like we enjoy today with ECDH. IIUC, the reason is t= hat lattice based schemes derived from the LWE [3] problem, whose security = is predicated on using "noise" to hide a secret value. For these cryptosyst= ems, usually a type of "hint" is sent to make everything work out nicely li= ke in ECDH. However, in the stricter non-interactive setting (no= messages sent), this doesn't map cleanly. 
It's important to emphasize this only considers the NIST-standard= ized KEMs. If we zoom out to the broader ecosystem of PQ PKE candidates, th= ere are several options for non-interactive key exchange systems that'd be = a drop-in replacement for ECDH.

For instance, oriented i= sogeny-based systems like CSIDH [1] [2] permit this kind of construction. B= oth parties publish a short (64 to 128 byte) pubkey and can perform key exc= hange as soon as they've seen the peer's pubkey, no additional messages req= uired. The down side of CSIDH is that it's quite slow, so it is most useful= when pubkeys are static or otherwise don't change much. There has been a l= ot of work done with new faster schemes [3] or speeding = up CSIDH with better implementations [4] but still key exchange can ta= ke a good few dozen milliseconds. 

In general, any post-= quantum-secure commutative group action scheme allows non-interactive key e= xchange. CSIDH is just one such example, and I'm sure there are and will be= others.


Maybe there's a more = applicable standard, a la Noise/Wireguard? For a possible implementation re= ference, see [5]. Otherwise rolling our own standard seems like the way to = go, especially if we can do so in a way that is reusable for other use-case= s beyond Bitcoin.

Also, if we go with a hybrid scheme, we should have clear migrat= ion paths to transition to either pure PQC (if a CRQC appears and breaks EC= DH, we might as well discard it), or back to classical ECDH (if CRQCs turn = out to be impossible).

regards,
conduition
<= div style=3D"font-family: Arial, sans-serif; font-size: 14px;">



On Thursday, May 7th, 2026 at 1:45 AM, Jonas Schnelli <jonas.sch= nelli@gmail.com> wrote:
Thanks for writing this up Laolu.

I think option 1 (classical-then-PQ-upgrade) is probably the right path, m= ostly because it keeps the byte-0 pseudorandomness property without needing= Kemeleon or any new obfuscation primitive.

If the= ML-KEM exchange happens inside the already-established v2 ChaCha20Poly1305= channel, then to a present-day classical observer the bytes should still l= ook random,... the inner PQ handshake is just more ciphertext. A future QC = adversary doing harvest-now-decrypt-later would break the outer ECDH eventu= ally, but I think they'd then still have to break ML-KEM-768 to get the v3 = transport keys, which is kind of the whole point. So we'd probably get hybr= id security against the QC threat and also keep the property that today's w= ire bytes are indistinguishable from random.

That = said, I'm not sure how far we should really take the pseudorandomness argum= ent,... traffic shape (packet sizes, timings, query/response patterns) prob= ably already reveals quite a bit about what's going on, so the byte-content= randomness is only one part of the picture.

The e= xtra round trip is probably fine given how long Bitcoin P2P connections liv= e. The DoS angle you flagged might also be smaller in option 1, since the r= esponder still commits after 64 bytes and not after a 1184-byte ML-KEM key,= ... though I haven't thought hard about wether there are other DoS vectors = the inner upgrade introduces.

On Ethan's TLS 1.3 s= uggestionm,... I don't think it really fits. Apart from the dependency cost= (which we deliberately kept low in BIP 324), TLS has it's own fingerprint,= which would probably undo the censorship-resistance angle. And it bundles = authentication with encryption, which we explicitly decoupled.
One thing worth looking at: OpenSSH (whose chacha20-poly1305 c= onstruction we drew from originally) shipped mlkem768x25519-sha256 as defau= lt in 10.0 last year, and they just concatenate-and-hash the two shared sec= rets. Their threat model doesn't care about pseudorandomness so they can se= nd ML-KEM material in the clear, but the combiner shape is probably a reaso= nable reference for ours.

/jonas

On May 6, 2026, at 12:15=E2=80=AFPM, Olaoluwa O= suntokun <laolu32@gmail.com> wrote:

Hi Ethan, 

That's a great questio= n. 

First, I don't= speak for Bitcoin Core by any means (btcd has also implemented
BIP 324 = FWIW). Based on past observed behavior, they typically prefer to keep
de= pendencies slim. Many years ago there was a concerted push to remove openss= l
as a dependency from the project. So I would imagine the idea of rolli= ng out
full blown TLS 1.3 might encounter some resistance.

In ter= ms of cryptography, BIP 324 as defined uses secp256k1. TLS 1.3 as
specif= ied doesn't support secp256k1 within the set of supported cipher suites.
If ensuring that BIP 324 continues to implement an oblivious KEM is a = key
requirement, then TLS 1.3 doesn't fit the bill.

Regarding a h= ybrid PQ KEM, there exists an IETF to add a new key agreement
suite to T= LS 1.3: https= ://datatracker.ietf.org/doc/draft-ietf-tls-ecdhe-mlkem/.
Only secp25= 6+384(r1) and x25519 are supported as elliptic curves in this draft.
One additional aspect is that today BIP 324 doesn't implement authenticati= on at
all, you only get confidentiality. TLS 1.3 would mean introducing = certificates
in some fashion, thereby coupling concerns from the origina= l PoV of Bip 324.

BIP 324 also includes as section in the BIP detail= ing the rationale of BIP 324
over a more general purpose protocol (menti= ons some of the points above):
https://githu= b.com/bitcoin/bips/blob/master/bip-0324.mediawiki#:~:text=3DWhy%20not%20use= %20a%20general%2Dpurpose%20transport%20encryption%20protocol%3F.

-- Laolu



On Tue, May 5, 2026 at 2:18=E2=80=AFPM Ethan Heilman &l= t;= eth3rs@gmail.com> wrote:
Thanks Laolu for thinking through making PQ B= IP 324 and writing this up.

Reading through what you wrote made me w= hat wonder, why not use this as an opportunity to move to TLS 1.3?

W= hat's the case against using TLS 1.3 for PQ P2P connection encryption? Is t= here some functionality that TLS 1.3 is lacking that we really want?  = Is the case against solely to not have TLS 1.3 as a complex dependency in b= itcoin-core?

The advantages of= TLS 1.3:

1. Make Bitcoi= n P2P connections blend in with all the other TLS connections. This isn't s= trong privacy, you can distinguish TLS encrypted Bitcoin traffic via timing= and size, but it reduces accidents where a firewall sees an unknown protoc= ol and blocks it.

2. Use= of QUIC for faster relay, oblivious HTTP and QUIC tunnels-in-tunnels for p= rivate relay and similar protocols.

3. Lots of eyeballs o= n TLS 1.3, we don't need to build or maintain it.


On Tue,= May 5, 2026, 00:41 Olaoluwa Osuntokun <laolu32@gmail.c= om> wrote:
Hi= y'all, 

In case y= ou weren't already tired of all the recent dev list chatter re post
quan= tum cryptography, here's another!

When the topic of Bitcoin transiti= oning to a post quantum world is brought up,
the discussion typically fo= cuses on the consensus layer re swapping out
vulnerable signature scheme= s. However, the consensus layer isn't the only area
of Bitcoin that reli= es in cryptography that would be broken in the face of a
powerful quantu= m computer! That's right, I'm talking about BIP 324, the peer to
peer en= cryption BIP for Bitcoin.

Like everything else on the Internet today= , BIP 324 uses ECDH to allow two
connecting peers to derive a shared sec= ret known only to them, which is then
used to encrypt all traffic betwee= n them. As ECDH relies on Elliptic Curve
cryptography, a future quantum = computer would be able to eavesdrop on a p2p
handshake transcript, then = derive the underlying private keys to the ephemeral
ECDH public key, per= mitting it to decrypt all traffic. It's actually worse than
that, as tod= ay adversaries can collect all encrypted p2p Bitcoin traffic, with
the h= ope of being able to decrypt it all at a future date. This is commonly
r= eferred to as the: "harvest, decrypt later" (HNDL) strategy [11].

Co= mpared to a consensus change, which requires widespread market agreement, a= nd
coordination to achieve, upgrading BIP 324 to be post quantum resista= nt is a
much lower hanging fruit worthy of pursing immediately.

L= ast week I starting thinking a bit about this topic, brushing up on the lat= est
literature/techniques, and stumbled onto a few key design questions.= The goal
of this post isn't to propose a new concrete p2p encryption BI= P, instead I want
to start discussion on the various design tradeoffs th= at came up as I was
researching this p2p encryption transition.

#= # PQ BIP 324 Design Questions

1. Do we want to pursue a hybrid KEM (= key encapsulation mechanism), or go with
   a pure PQ KEM?
=
2. Is it still a key requirement that the initial handshake be
 = ;  indistinguishable from a random byte string?

   2a= . If yes to the above, then should we go with classical-then-pq-upgrade,   or a one shot hybrid oblivious KEM.


## A Brief Int= ro to KEMs + ML-KEM

First, let's introduce the new primitive we have= to work with: ML-KEM
(Module-Lattice-Based Key-Encapsulation Mechanism)= [1][2]. As it says on the
tin, ML-KEM is a lattice based Key-Encapsulat= ion Mechanism. The phrase KEM
might sound unfamiliar with those comforta= ble with ECDH, but ECDH is actually a
KEM itself.

A KEM has 3 alg= orithms:
  * KeyG= en() -> {sk, pk}
     * Generates a public/private sec= ret key pair

  * Encaps(pub) -> {secret, capsule}
     * Generates = a new secret value, and a "capsule", which only the holder of
  &nb= sp;    pub can use to obtain the secret value.

  
* Decaps(priv, capsule) ->= secret
     * Uses the private key to extract the secret= from the capsule


If you squint a bit, then you'll see that ECDH= is a KEM, and a rather elegant
one at that:
  * KeyGen() -> {k, k*G}
   =   * Normal EC key g= eneration. 

 =  * Encaps(pub) -> {cap= sule =3D x*G, secret =3D pub*x}
      * The core ECDH routine. The ephemeral publi= c key is actually the
        "capsule". The resulting secret is the ECDH out= put with the remote
        party's KEM public key and the local secret.
<= br>  * Decaps(priv, = capsule) -> secret =3D priv * capsule
      * The receiver completes the key ex= change using the ephemeral public key
        and their own private key.
<= br>ECIES is another flavor of EC based KEM.

One thing worth noting i= s that AFAICT, so far in the NIST PQC world [4], there is
no known non-i= nteractive key exchange protocol like we enjoy today with ECDH.
IIUC, th= e reason is that lattice based schemes derived from the LWE [3]
problem,= whose security is predicated on using "noise" to hide a secret value.
F= or these cryptosystems, usually a type of "hint" is sent to make everything=
work out nicely like in ECDH. However, in the stricter non-interactive = setting
(no messages sent), this doesn't map cleanly.

As a result= , ML-KEM looks more like a hybrid encryption protocol (Alice
encrypts a = shared secret to bob using asymmetric lattice crypto).

## To Hybrid = KEM, Or Not to Hybrid KEM

This brings us to our first design questio= n....

Should we use a hybrid KEM or a pure post quantum one? 

A hybrid KEM would keep = the existing ECDH, _also_ do ML-KEM, then securely
combine (there's some= subtlety there, see [6][7]) the resulting in a
final secret value for e= ncryption. A hybrid KEM is attractive as an encryption
channel derived f= rom such a KEM is secure if _any_ of the combined schemes are
secure. Th= is permits schemes to hedge a bit, as hey, maybe the PQ stuff is
actuall= y broken in the future but ECDH isn't. If it's the other way around,
the= n your encryption scheme is still secure.

### Pure ML-KEM P2P Encryp= ted Handshake

If we opt to not use a hybrid scheme, then the Elligat= or layer can be dropped
all together. Instead, the 1.1 KB (ML-KEM-768) e= ncapsulation keys are sent,
keeping the trailing garbage+terminator in t= act. 

The initial = handshake would look something like:&= nbsp;
 * Alice -> Bob: alice_encaps || initiator_garbage<= br>    * Alice = derives an encapsulation key, and sends it to Bob.

 * Bob ->= Alice: ml_kem_capsule || responder_garbage || responder_garbage_terminator= || first_encrypted_packet
   * Bob uses Alice's encapsulation= key to encapsulate a random secret, and
     sends it ov= er to Alice. He can also encrypt the first message at this
   =  point.

 * Alice -> Bob: initiator_garbage_terminator = || first_encrypted_packet
   * Alice de-encapsulates the share= d secret, and can now also start to encrypt
     messages= .

We'd then replace `v2_ecdh` with something like a `v3_mlkem` that = derives the
final shared secret based on the sent/received transcript up= until that point:
  * `sha256_tagged("bip324_ml_kem", ml_kem_secret, alice_encaps, ml_kem_c= apsule)`

### Hybrid ML-KEM P2P Encrypted Handshake

If we want= to use a hybrid combiner, then along side the normal ellswift keys,
the= ML-KEM-768 encap key is also sent:

 * Alice -> Bob: ellswif= t_alice || alice_encaps || initiator_garbage
 * Bob -> Alice: el= lswift_bob || ml_kem_capsule || responder_garbage || responder_garbage_term= inator || first_encrypted_packet
 * Alice -> Bob: initiator_garb= age_terminator || first_encrypted_packet

Then following guidelines o= f [7], we'd then replace `v2_ecdh` with something
like `v3_hybrid_shared= _secret`:
  * `sh= a256_tagged("bip324_ellswift_xonly_ecdh_mlkem_768", ml_kem_ss, ecdh_point_x= 32, alice_encaps, ml_kem_capsule, ellswift_alice, ellswift_bob)`

## = PQ/Hybrid Obfuscated KEMs

At this point, those that are familiar wit= h BIP 324 will recognize that both
the pure PQ and hybrid versions rende= rs the ElligatorSwift usage pretty much
useless. ElligatorSwift encodes = a 32-byte public key as a 64-byte value which
is indistinguishable from = a uniformly distributed bitstream. In a bubble, this
means that the init= ial BIP 324 handshake to a 3rd party observer just looks
like random byt= es. However, with the introduction of ML-KEM, the ML-KEM
encapsulation k= ey is sent in plaintext over the wire. An ML-KEM key has
identifiable st= ructure, as it's a giant vector of polynomial coefficients mod
3329, whi= ch is easily recognizable over the wire.

Luckily, there's an ML-KEM = analogue to ElligatorSwift, called Kemeleon
[8][9][10]! In a similar fas= hion to ElligatorSwift, it takes an ML-KEM public
key, then encodes it a= s one giant integer, utilizing rejection sampling.
Kemeleon applies this= mapping both to the encapsulation keys, and also the
capsule ciphertext= that encrypts the shared secrets. The ML-KEM keys end up
being a bit sm= aller, while the ciphertexts map to a larger value. Another
tradeoff is = that the Kemeleon key generation is ~3x slower than normal ML-KEM
genera= tion.

One thing to note here is that Kemeleon's "looks random" prope= rty isn't quite
on the same footing as ElligatorSwift's. ElligatorSwift = is statistically
indistinguishable from random, since every 512-bit stri= ng is a valid encoding.
Kemeleon's indistinguishability is computational= , resting on a Module-LWE
style assumption. So if you naively concatenat= e an ElligatorSwift key and a
Kemeleon key, the pair is only as obfuscat= ed as the weakest visible half. This
asymmetry is what motivates the OEI= NC construction discussed below.

This brings us to our second design= question....

Do we still want to ensure that the BIP-324 handshake = looks identical to a
pseudorandom bytestream from the very first message= ?

Assuming yes, then AFAICT, we have two classes of options here: 

  1. Retain the existing BIP-324 outer Elli= gatorSwift handshake, but use ML-KEM
     within that ini= tial encrypted transport to upgrade to a PQ shared secret.

  2. Use the Outer Encrypts I= nner Nested Combiner (OEINC - "OINK") combiner
     from = [8].

  3. Att= empt to adapt Drivel from [8] into the Bitcoin p2p setting.

### Clas= sical Encrypted Channel Upgrades to PQ

With the first option, we sim= ply use one KEM right after the other. So BIP 324
v2 would be mostly unc= hanged, then we _upgrade_ to BIP 324 v3 within v2. 

A sketch of this would be something like:=
  * Phase 0: nor= mal BIP 324 handshake
  = * Phase 1: negotiation of PQ KEM scheme over the encrypted handshake=
     * Can be optional, if we just pick a set PQ KEM sch= eme.
     * Before this point, no Bitcoin p2p message sho= uld be sent, as the channel
       isn't PQC protect= ed yet.
  * Phase= 2: do normal ML-KEM within the ElligatorSwift derived encrypted
  =   transport
 = ;    1. Alice sends the encapsulation key
     = 2. Bob derives a secrets, encrypts it using the encapsulation key
 =    3. Both sides then derive a PQ shared secret, ss_PQ
 =  * Phase 3: both sides us= e a hybrid combiner like sketched out above to derive
    a new set of transport keys  * Phase 4: both = sides rekey, switching over to a new the transport keys

The upside o= f this option is that the outer part of BIP 324 remains unchanged,
then = with another round trip, we're able to upgrade the encryption keys to PQhybrid security. The downside is that the very first messages sent aren't = PQ
from the start, but a PQ adversary wouldn't be able to decrypt the ac= tual
Bitcoin p2p messages (as we wait to send those until the upgrade). = The
handshake still looks like just random bytes.

### Outer Encry= pts Inner Nested Combiner

For the second option, [8] (with talk vide= o [9] and slides [10]) describes an
OEINC scheme where the outer KEM
= encrypts the inner KEM, wherein the KEM ciphertext of an inner KEM is encry= pted
using a shared secret derived from the outer KEM. The two KEM ciphe= rtexts and
the two derived keys are then used alongside a hybrid combine= r to derive a
final shared secret.=  

Unlike the classical-then-pq-upgrade that establishes = a classical channel, then
uses that to upgrade to pq channel, OEINC is a= special hybrid combiner that
achieves a similar output but in one swoop= . It defines a special KEM, which can
then be used as the KEM in the ver= y first handshake I sketched out.

A sketch of this KEM looks somethi= ng like:
  * Setu= p:
    * The= outer KEM is BIP 324's ElligatorSwift-encoded secp256k1 DHKEM.
  &= nbsp;    * It serves as the outer KEM because its on-wire encodin= g is
         statistically indistinguishable f= rom random.
    * The inner KEM is ML-Kemeleon.

  * KeyGen():
    * (kem_secret_outer, kem_pubkey_outer) =3D out= KEM.Gen()
    * (kem_secret_inner, kem_pubkey_inner) =3D inKEM.Gen()
    
* combined_pubkey =3D (kem= _pubkey_outer, kem_pubkey_inner)
    * combined_secret =3D (kem_secret_outer, kem_secre= t_inner)

  * = Encaps(combined_pubkey):
    * (shared_secret_outer, capsule_outer) =3D outKEM.Encap(ke= m_pubkey_outer)
    = ;* (encrypt_key_1, encrypt_key_2) =3D KDF(shared_secret_outer)
&n= bsp;   * (shared_sec= ret_inner, capsule_inner) =3D inKEM.Encap(kem_pubkey_inner)
   = ; * encrypted_capsule_inn= er =3D encrypt(encrypt_key_1, capsule_inner)
    * combined_capsule =3D capsule_outer |= | encrypted_capsule_inner
    * combined_shared_secret =3D combine(encrypt_key_2, share= d_secret_inner, combined_capsule)

  * Decaps(combined_secret, combined_capsule):
&nbs= p;   * (capsule_oute= r, encrypted_capsule_inner) =3D combined_capsule
    * shared_secret_outer =3D outKEM.D= ecaps(kem_secret_outer, capsule_outer)
    * (encrypt_key_1, encrypt_key_2) =3D KDF(sha= red_secret_outer)
   &nb= sp;* capsule_inner =3D decrypt(encrypt_key_1, encrypted_capsule_inne= r)
    * sha= red_secret_inner =3D inKEM.Decaps(kem_secret_inner, capsule_inner)
 = ;   * combined_share= d_secret =3D combine(encrypt_key_2, shared_secret_inner, combined_capsule)<= br>

This is done over just sending the two encapsulated secrets plai= nly as I
outlined above in order to achieve a stronger security notion. = The issue with
this though is that though ciphertext uniformity (the enc= apsulated secrets) is
achieved, the two public keys sent are randomly lo= oking, but not in a uniform
manner. In practice, this might not really m= atter much AFAICT (a theoretical
adversary would be able to distinguish = the Elligator half from the Kemeleon
half).

### Drivel: PQ-Obfusc= ated Authentication

The biggest issue with Drivel as a fit for BIP 3= 24 is that it expects the
initiator to already know a long term static p= ublic key for the responder. In
the case of BIP 324, only ephemeral keys= are exchanged, so there's no long
term public keys known to either side= .

To get around this, we could extend BIP 155 (or make a new one lik= ely, given
size limits) to include a signed OKEM key. However then that = would introduce
authentication into the combined set, which explicitly w= asn't a design goal
of BIP 324.

With that caveat in mind, here's = the construction itself. Drivel [8] combines
the OEINC scheme with anoth= er layer that out-of-the-box assumes an asymmetric
protocol within a set= client and server. The client uses an existing OEINC
KEM public key pub= lished by the server to then encrypt a fresh new ephemeral
KEM.

-= ---- 

So there we = have it. Before drafting a concrete v3 transport, we need to
decide if w= e want a hybrid KEM, or are fine with a pure PQ KEM. Then we need to
dec= ide if we want to attempt to maintain the current quality where the p2p
= handshake transcript is indistinguishable from random. If yes, then that fo= rces
another series of decisions re how to construct/compose an obliviou= s KEM from
available primitives.

At a glance, the route of classi= cal-then-pq-upgrade seems to be the simplest.
BIP 324 stays as is, then = we run ML-KEM within that. The ML-KEM keys are
encrypted, so there's no = need to sprinkle in the layer of Kemeleon.

If we want a nice combine= d protocol, then we should investigate the OEINC
route. It's more data t= o send as part of the initial handshake, but we still
keep ElligatorSwif= t and use that as the outer KEM.

If for some reason we're concerned = with a future adversary gaining a
distinguisher for Kemeleon, then maybe= we need to bite the bullet and also
roll out a full blown PQ authentica= tion protocol along side everything.

One thing worth flagging for an= y of the byte-0 designs (where PQ material is
sent in the clear on the v= ery first flight, like the hybrid and OEINC sketches
above): ML-KEM-768 = makes the responder do real work before it can decide if a
connection is= even legit. Today, the responder only needs the first 64 bytes
of an El= ligatorSwift share before it can derive the shared secret. With
ML-KEM-7= 68, the responder has to read and validate a 1184 byte encapsulation
key= before running Encaps, and FIPS 203 mandates input checks on every Encaps<= br>and Decaps. In a permissionless P2P network, that's a meaningful change = in
inbound DoS surface, and probably calls for stricter handshake byte l= imits,
tighter timeouts, and possibly some form of stateless cookie/puzz= le if
handshake floods become a real problem. The classical-then-pq-upgr= ade path
sidesteps most of this since the PQ material only shows up afte= r the v2
channel is up.

With all that said, after the above desig= n decisions are addressed, there
aren't too many concrete blockers here = w.r.t rolling this out. Of course the
development (eg: selecting/creatin= g a library for ML-KEM and maybe
ML-Kemeleon), and upgrade will take som= e time. But unlike the consensus
layer, p2p encryption doesn't require t= he widespread market agreement that an
actual soft fork does. BIP 324 is= a much shorter walk to PQ than the consensus
layer, and serves as a sor= t of PQ warm up before the bigger soft fork is
tackled. 

-- Laolu

[1]: https://en.wiki= pedia.org/wiki/ML-KEM
[2]:&nbs= p; 
https://en.wikipedia.org/wiki/Learning_wit= h_errors
[4]: This statement ignores Isogeny based crypto, and also = SWOOSH [5] as it requires 200 KB pubkeys
[5]: https://eprint.iacr.org/2023/271
[6]: https://eprint.iacr.org/2018/024
[7]: https://eprint.iacr.org/2020/1364
[8]: https://eprint.iacr.org/2024/1086
[9]: https://www.youtube.com/watch?v= =3DCvFCYUq5rGg
[10]: 
https://csrc.nist.gov/csrc/media/P= resentations/2025/kemeleon/images-media/kemeleon.pdf
[11]: https://en.wikipedia.org/w= iki/Harvest_now,_decrypt_later

-- You received this message because you are subscribed to the Google Groups = "Bitcoin Development Mailing List" group.
To unsubscribe from this group= and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com.
T= o view this discussion visit https:= //groups.google.com/d/msgid/bitcoindev/CAO3Pvs9U3prZJiDs0Ns7LSA07R8hM-GQou_= FcTZZz-JUQpUYHw%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google= Groups "Bitcoin Development Mailing List" group.
T= o unsubscribe from this group and stop receiving emails from it, send an em= ail to bitcoindev+unsubscribe@googlegroups.com.
<= span style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size:= 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; let= ter-spacing: normal; text-align: start; text-indent: 0px; text-transform: n= one; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px= ; text-decoration: none; float: none; display: inline !important;">To view = this discussion visit https://groups.google.com/d/msgid/bitco= indev/CAO3Pvs8i%3DpLP30nRh_iyjSRJXne19wNezmQmo%3DJAk8%2BE4uJPhg%40mail.gmai= l.com To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoindev+u= nsubscribe@googlegroups.com.
To view this discussion visit = https://groups.google.com/d/msgid/bitcoindev/547ADFCA-2BB1-4E16-A26A-C92262= EBBD84%40gmail.com.

--
You received this message because you are subscribed to the Google Groups &= quot;Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to bitcoind= ev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/RS1NnL= 6YB4YFxxuEa9eOQuB5OOkPp6zwxWkLl9QCFQfE9-1y9vB0njN2QycURGNdSkT3sM4erCyaSkYvk= mYTHicE32JMNMRepa1QwV3obVc%3D%40proton.me.
-----------------------02ec46135174dd15ba7ef4320d6267aa-- -----------------------a5150975640a6204639aad6dc639c2bf-- -----------------------70aeb7f8668ccd095441ffe211910ec4 Content-Type: application/pgp-keys; filename="publickey - conduition@proton.me - 0x474891AD.asc"; name="publickey - conduition@proton.me - 0x474891AD.asc" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="publickey - conduition@proton.me - 0x474891AD.asc"; name="publickey - conduition@proton.me - 0x474891AD.asc" LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp4ak1FWkRub0tSWUpLd1lCQkFI YVJ3OEJBUWRBcnBZYWFjZDgwcXdocmNaQW9VbW9NSHNWS21iZWlPZUEKcFhXbk1ybFdPZkxOSzJO dmJtUjFhWFJwYjI1QWNISnZkRzl1TG0xbElEeGpiMjVrZFdsMGFXOXVRSEJ5CmIzUnZiaTV0WlQ3 Q2pBUVFGZ29BUGdXQ1pEbm9LUVFMQ1FjSUNaQjRLV3p0aFBhenhRTVZDQW9FRmdBQwpBUUlaQVFL YkF3SWVBUlloQkVkSWthMENNdHJMZGcxM2EzZ3BiTzJFOXJQRkFBQTZhQUVBM1RmNHdqSVoKYnox K0diS0h4K09WQytNUXlVdi84RStoWUpjTE5QZnA0NEFBLzNiak5OTXN4WHdJTGZEM0xManNVVWFo CitBV2JyblVjVUFqQ2R1d3hUT01LempnRVpEbm9LUklLS3dZQkJBR1hWUUVGQVFFSFFDSXYxZW5J MU5MbAo3Zm55RzlVWk1wQ3ZsdG5vc0JrTmhQUVZxT3BXL3RKSkF3RUlCOEo0QkJnV0NBQXFCWUpr T2VncENaQjQKS1d6dGhQYXp4UUtiREJZaEJFZElrYTBDTXRyTGRnMTNhM2dwYk8yRTlyUEZBQUFR TFFEL2NCR2kwUDdwCkZTTkl2N1B6OVpkeUNVQjhzTy90dWZkV3NjQkNZK2ZMYTV3QkFNK0hTL3Jp S014RGt0TkhLakRGc2EvUgpEVDFxUGNBYXZCaXc2dDZ4Ti9jRgo9Y3d5eAotLS0tLUVORCBQR1Ag UFVCTElDIEtFWSBCTE9DSy0tLS0tCg== -----------------------70aeb7f8668ccd095441ffe211910ec4-- --------8c1e29c5a1c2aa24b2964a9c6ad5ccb5aa179f570be001d3785448137e3009d3 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: ProtonMail wrsEARYKAG0Fgmn+qC4JEHgpbO2E9rPFRRQAAAAAABwAIHNhbHRAbm90YXRp b25zLm9wZW5wZ3Bqcy5vcmfVQlvHF6a5JdYGL8NDH9ne/t87tDumGbt9U/7t 3HxeDRYhBEdIka0CMtrLdg13a3gpbO2E9rPFAAAPmwEAoR6UiD15Goo+GrDA 9VXAgXBsd7U9P2Zt6b8h7UoaVMoA/0iQEVCrUsbiOVT4PnGeASaihT+gQash vNKFJNNtp6QC =sI4v -----END PGP SIGNATURE----- --------8c1e29c5a1c2aa24b2964a9c6ad5ccb5aa179f570be001d3785448137e3009d3--