{"id":1913,"date":"2025-02-28T16:24:39","date_gmt":"2025-02-28T15:24:39","guid":{"rendered":"https:\/\/blogs.igalia.com\/jfernandez\/?p=1913"},"modified":"2025-03-31T11:36:12","modified_gmt":"2025-03-31T09:36:12","slug":"can-i-use-secure-curves-in-the-web-platform","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/jfernandez\/2025\/02\/28\/can-i-use-secure-curves-in-the-web-platform\/","title":{"rendered":"Can I use Secure Curves in the Web Platform?"},"content":{"rendered":"<p class=\"part\" data-startline=\"3\" data-endline=\"3\">Long story short, yes, it\u2019s possible to use the Ed25519 and X25519 algorithms through the Web Cryptography API exposed by the major browser engines: Blink (Chrome, Edge, Brave, \u2026), WebKit (Safari) and Gecko (Firefox).<\/p>\n<p class=\"part\" data-startline=\"5\" data-endline=\"5\">However, despite the hard work during the last year we haven\u2019t been able to ship Ed25519 in Chrome. It\u2019s still available behind the\u00a0<a href=\"chrome:\/\/flags\/#enable-experimental-web-platform-features\" target=\"_blank\" rel=\"noopener\">Experimental Web Platform Features<\/a>\u00a0runtime flag. In this post, I will explain the current blockers and plans for the future regarding this feature.<\/p>\n<p class=\"part\" data-startline=\"7\" data-endline=\"7\">Although disappointed about the current status of the Ed25519 in Chrome, I\u2019m very satisfied to see the results of our efforts, with the implementation now moving forward in other major web engines and shipping by default for both Ed25119\u00a0<a href=\"https:\/\/caniuse.com\/?search=ed25519%20\" target=\"_blank\" rel=\"noopener\">[1]<\/a>\u00a0and X25119\u00a0<a href=\"https:\/\/caniuse.com\/?search=X25519\" target=\"_blank\" rel=\"noopener\">[2]<\/a>.<\/p>\n<p class=\"part\" data-startline=\"9\" data-endline=\"9\">Finally, I want to remark about the work done to improve interoperability, which is a relevant debt this feature carried the last few years, to ensure applications can realiably use the Curve21559 features in any of the major browsers.<\/p>\n<h2 id=\"Context\" class=\"part\" data-startline=\"12\" data-endline=\"12\"><i class=\"fa fa-link\"><\/i>Context<\/h2>\n<p class=\"part\" data-startline=\"14\" data-endline=\"14\">Before analyzing the current status and blockers, it\u2019s important to understand why browser support for this feature matters, why merging the WICG draft into the Web Cryptography API specification is key.<\/p>\n<p class=\"part\" data-startline=\"16\" data-endline=\"16\">I\u2019ve already written about this in my\u00a0<a href=\"https:\/\/blogs.igalia.com\/jfernandez\/2023\/06\/20\/secure-curves-in-the-web-cryptography-api\/\" target=\"_blank\" rel=\"noopener\">last post<\/a>\u00a0so I\u2019m not going to elaborate too much, but it\u2019s important to describe some of the advantages for the Web Platform users this API has over the current alternatives.<\/p>\n<p class=\"part\" data-startline=\"18\" data-endline=\"18\">The Ed25519 algorithm for EdDSA signing and the X25519 function for key-agreement offer stronger security and better performance than other algorithms. For instance, the RSA keys are explicitly\u00a0<a href=\"https:\/\/w3c.github.io\/webtransport\/#allowed-public-key-algorithms\" target=\"_blank\" rel=\"noopener\">banned from new features like Web Transport<\/a>. The smaller key size (32 bytes) and EdDSA signatures (64 bytes) provide advantages in terms of transmission rates, especially in distributed systems and peer-to-peer communications.<\/p>\n<p class=\"part\" data-startline=\"20\" data-endline=\"20\">The lack of a browser API to use the Curve25519 algorithms have forced web authors to rely on\u00a0<a href=\"https:\/\/www.npmjs.com\/search?q=Ed25519\" target=\"_blank\" rel=\"noopener\">external components<\/a>, either JS libraries or WASM compiled, which implies a security risk. This situation is especially sad, considering that browsers already have support for these algorithms as part of the TLS 1.3 implementation; it\u2019s just not exposed to web authors.<\/p>\n<h3 id=\"Web-Platform-Feature-Development-Timeline-Key-Milestones\" class=\"part\" data-startline=\"22\" data-endline=\"22\"><i class=\"fa fa-link\"><\/i>Web Platform Feature Development Timeline: Key Milestones<\/h3>\n<p class=\"part\" data-startline=\"24\" data-endline=\"24\">To get an idea of of what the time-frame and effort required to develop a web feature like this looks like, lets consider the following milestones:<\/p>\n<ol class=\"part\" data-startline=\"27\" data-endline=\"67\">\n<li class=\"\" data-startline=\"27\" data-endline=\"31\"><strong>2020 &#8211; Jan<\/strong>\n<ul>\n<li class=\"\" data-startline=\"28\" data-endline=\"28\">Secure Curves on WebCrypto API\u00a0<a href=\"https:\/\/github.com\/WICG\/webcrypto-secure-curves\/\" target=\"_blank\" rel=\"noopener\">repository<\/a>\u00a0created in the\u00a0<a href=\"https:\/\/github.com\/WICG\/\" target=\"_blank\" rel=\"noopener\">W3C WICG<\/a><\/li>\n<li class=\"\" data-startline=\"29\" data-endline=\"29\">Intent-To-Prototype\u00a0<a href=\"https:\/\/groups.google.com\/a\/chromium.org\/g\/blink-dev\/c\/PgBVW4ru1EQ\/m\/5dllcdVoDgAJ\" target=\"_blank\" rel=\"noopener\">request<\/a>\u00a0for Blink, sent by Qingsi Wang<\/li>\n<li class=\"\" data-startline=\"30\" data-endline=\"30\">TAG review\u00a0<a href=\"https:\/\/github.com\/w3ctag\/design-reviews\/issues\/466\" target=\"_blank\" rel=\"noopener\">request<\/a><\/li>\n<li class=\"\" data-startline=\"31\" data-endline=\"31\">Standard position\u00a0<a href=\"https:\/\/github.com\/w3ctag\/design-reviews\/issues\/466\" target=\"_blank\" rel=\"noopener\">request<\/a>\u00a0for Gecko about X25519<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"32\" data-endline=\"33\"><strong>2020 &#8211; Feb<\/strong>\n<ul>\n<li class=\"\" data-startline=\"33\" data-endline=\"33\">Initial\u00a0<a href=\"https:\/\/chromium-review.googlesource.com\/c\/chromium\/src\/+\/1958596\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Qingsi Wang of the Ed25519 algorithm for Blink (<strong>Abandoned<\/strong>\u00a0)<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"34\" data-endline=\"37\"><strong>2020 &#8211; Sep<\/strong>\n<ul>\n<li class=\"\" data-startline=\"35\" data-endline=\"35\">Intent-To-Prototype\u00a0<a href=\"https:\/\/groups.google.com\/a\/chromium.org\/g\/blink-dev\/c\/n0uKIqfypW0\/m\/xu5UBbaBAwAJ\" target=\"_blank\" rel=\"noopener\">request<\/a>\u00a0of Ed25519 and X25519 for Blink, sent by Javier Fernandez (Igalia)<\/li>\n<li class=\"\" data-startline=\"36\" data-endline=\"36\">Design\u00a0<a href=\"https:\/\/docs.google.com\/document\/d\/1fDTUY3HVAXehi-eSfbi7nxh8ZPw4MpSKM8U1fMdqJlU\/edit?tab=t.0#heading=h.9yv502gpxrk7\" target=\"_blank\" rel=\"noopener\">document<\/a><\/li>\n<li class=\"\" data-startline=\"37\" data-endline=\"37\">Standard position\u00a0<a href=\"https:\/\/github.com\/WebKit\/standards-positions\/issues\/67\" target=\"_blank\" rel=\"noopener\">request<\/a>\u00a0for WebKit about Secure Curves in WebKit<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"38\" data-endline=\"39\"><strong>2022 &#8211; October<\/strong>\n<ul>\n<li class=\"\" data-startline=\"39\" data-endline=\"39\">Initial\u00a0<a href=\"https:\/\/chromium-review.googlesource.com\/c\/chromium\/src\/+\/3930754\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Javier Fernandez (Igalia) of the Ed25519 algorithm for Blink<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"40\" data-endline=\"41\"><strong>2023 &#8211; Jan<\/strong>\n<ul>\n<li class=\"\" data-startline=\"41\" data-endline=\"41\">Initial\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/8691\" target=\"_blank\" rel=\"noopener\">Implementation<\/a>\u00a0by Angela Izquierdo (Apple) of the Ed25519 algorithm for WebKit (Apple port)<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"42\" data-endline=\"43\"><strong>2023 &#8211; Feb<\/strong>\n<ul>\n<li class=\"\" data-startline=\"43\" data-endline=\"43\">The Ed25519 algorithm is\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/9914\" target=\"_blank\" rel=\"noopener\">enabled by default<\/a>\u00a0in WebKit<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"44\" data-endline=\"45\"><strong>2023 &#8211; Mar<\/strong>\n<ul>\n<li class=\"\" data-startline=\"45\" data-endline=\"45\">Initial\u00a0<a href=\"https:\/\/chromium-review.googlesource.com\/c\/chromium\/src\/+\/4016576\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Javier Fernandez (Igalia) of the X25519 algorithm for Blink<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"46\" data-endline=\"48\"><strong>2023 &#8211; Aug<\/strong>\n<ul>\n<li class=\"\" data-startline=\"47\" data-endline=\"47\">Initial\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/16247\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Javier Fernandez (Igalia) of the Ed25519 algorithm for WebKit (GTK+ port)<\/li>\n<li class=\"\" data-startline=\"48\" data-endline=\"48\">Initial\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/16588\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Javier Fernandez (Igalia) of the X25519 algorithm for WebKit (GTK+ port)<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"49\" data-endline=\"51\"><strong>2023 &#8211; Sep<\/strong>\n<ul>\n<li class=\"\" data-startline=\"50\" data-endline=\"50\">Initial\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/17425\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Javier Fernandez (Igalia) for WebKit of the X25519 algorithm for WebKit (Apple port)<\/li>\n<li class=\"\" data-startline=\"51\" data-endline=\"51\">Safari STP 178\u00a0<a href=\"https:\/\/developer.apple.com\/documentation\/safari-technology-preview-release-notes\/stp-release-178\">release<\/a>\u00a0shipped with Ed25519<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"52\" data-endline=\"53\"><strong>2024 &#8211; March<\/strong>\n<ul>\n<li class=\"\" data-startline=\"53\" data-endline=\"53\">Initial\u00a0<a href=\"https:\/\/phabricator.services.mozilla.com\/D205719\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Anna Weine (Mozilla) for Gecko of the Ed25519 algorithm<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"54\" data-endline=\"55\"><strong>2024 &#8211; Jun<\/strong>\n<ul>\n<li class=\"\" data-startline=\"55\" data-endline=\"55\">Initial\u00a0<a href=\"https:\/\/phabricator.services.mozilla.com\/D213261\" target=\"_blank\" rel=\"noopener\">implementation<\/a>\u00a0by Anna Weine (Mozilla) for Gecko of the X25519 algorithm<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"56\" data-endline=\"57\"><strong>2024 &#8211; Sep<\/strong>\n<ul>\n<li class=\"\" data-startline=\"57\" data-endline=\"57\">Firefox 130\u00a0<a href=\"https:\/\/www.mozilla.org\/en-US\/firefox\/130.0\/releasenotes\/\" target=\"_blank\" rel=\"noopener\">shipped<\/a>\u00a0both Ed25519 and X25519 enabled by default<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"58\" data-endline=\"59\"><strong>2024 &#8211; Nov<\/strong>\n<ul>\n<li class=\"\" data-startline=\"59\" data-endline=\"59\">Intent-to-Ship\u00a0<a href=\"https:\/\/groups.google.com\/a\/chromium.org\/g\/blink-dev\/c\/A7lbRONS1lY\/m\/6J6wRdj4AAAJ\" target=\"_blank\" rel=\"noopener\">request<\/a>\u00a0of X25519 for Blink by Javier Fernandez (Igalia)<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"60\" data-endline=\"62\"><strong>2024 &#8211; Dec<\/strong>\n<ul>\n<li class=\"\" data-startline=\"61\" data-endline=\"61\">The Ed25519 and X25519 algorithms are\u00a0<a href=\"https:\/\/github.com\/w3c\/webcrypto\/pull\/362#issuecomment-2519927404\" target=\"_blank\" rel=\"noopener\">integrated<\/a>\u00a0into the Web Cryptography API draft<\/li>\n<li class=\"\" data-startline=\"62\" data-endline=\"62\">The X25519 algorithm is\u00a0<a href=\"https:\/\/github.com\/WebKit\/WebKit\/pull\/37766\" target=\"_blank\" rel=\"noopener\">enabled by default<\/a>\u00a0in WebKit (all ports)<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"63\" data-endline=\"64\"><strong>2025 &#8211; Jan<\/strong>\n<ul>\n<li class=\"\" data-startline=\"64\" data-endline=\"64\">Safari STP 211\u00a0<a href=\"https:\/\/webkit.org\/blog\/16435\/release-notes-for-safari-technology-preview-211\/\" target=\"_blank\" rel=\"noopener\">release<\/a>\u00a0shipped with X25519<\/li>\n<\/ul>\n<\/li>\n<li class=\"\" data-startline=\"65\" data-endline=\"67\"><strong>2025 &#8211; Feb<\/strong>\n<ul>\n<li class=\"\" data-startline=\"66\" data-endline=\"67\">Chrome 133\u00a0<a href=\"https:\/\/developer.chrome.com\/release-notes\/133#x25519_algorithm_of_the_web_cryptography_api\" target=\"_blank\" rel=\"noopener\">release<\/a>\u00a0shipped with X25519 enabled by default<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"part\" data-startline=\"68\" data-endline=\"68\">This is a good example of a third-party actor not affiliated with a browser-vendor investing time and money to change the priorities of the companies behind the main browsers to bring an important feature to the Web Platform. It\u2019s been a large effort during 2 years, reaching agreement between 3 different browsers, spec editor and contributors and the W3C Web App Sec WG, which manages the Web Cryptography API specification.<\/p>\n<p class=\"part\" data-startline=\"70\" data-endline=\"70\">It\u2019s worth mentioning that a large part of the time has been invested in increasing the testing coverage in the Web Platform Tests\u2019\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI?label=master&amp;label=experimental&amp;aligned\" target=\"_blank\" rel=\"noopener\">WebCryptoAPI test suite<\/a>\u00a0and improving the interoperability between the three main web engines. This effort implies filing bugs in the corresponding browsers, discussing in the Secure Curves WICG about the best approach to address the interop issue and writing tests to ensure we don\u2019t regress in the future.<\/p>\n<p class=\"part\" data-startline=\"72\" data-endline=\"72\">Unfortunately, a few of these interop issues are the reason why the Ed25519 algorithm has not been shipped when I expected, but I\u2019ll elaborate more in this later in this post.<\/p>\n<h2 id=\"Current-implementation-status-of-the-Curve25519-algorithms\" class=\"part\" data-startline=\"75\" data-endline=\"75\"><i class=\"fa fa-link\"><\/i>Current implementation status of the Curve25519 algorithms<\/h2>\n<p class=\"part\" data-startline=\"78\" data-endline=\"78\">The following table provides a high-level overview of the support of the Secure Curve25519 features in some of the main browsers:<\/p>\n<p data-startline=\"78\" data-endline=\"78\"><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1930 aligncenter\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20-300x145.png\" alt=\"\" width=\"407\" height=\"197\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20-300x145.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20-1024x494.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20-768x371.png 768w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20-1536x741.png 1536w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-06-19-35-20.png 1600w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><\/a><\/p>\n<p class=\"part\" data-startline=\"118\" data-endline=\"118\">If we want to take a broader look at the implementation status of these algorithms, there is a nice table in the\u00a0<a href=\"https:\/\/github.com\/WICG\/webcrypto-secure-curves\/issues\/20\" target=\"_blank\" rel=\"noopener\">issue #20<\/a>\u00a0at the WICG repository:<\/p>\n<p class=\"part\" data-startline=\"120\" data-endline=\"120\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/841a6c83-eae0-4de6-b97e-05e772db4bea.png\" alt=\"\" \/><\/p>\n<h3 id=\"Interoperability\" class=\"part\" data-startline=\"123\" data-endline=\"123\"><i class=\"fa fa-link\"><\/i>Interoperability<\/h3>\n<p class=\"part\" data-startline=\"125\" data-endline=\"125\">As I commented before, most of the work done during this year was focused on improving the spec and increasing the test coverage by the WPT suite. The main goal of these efforts was improving the interoperability of the feature between the three main browsers. It\u2019s interesting to compare the results with the data shown in my\u00a0<a href=\"https:\/\/blogs.igalia.com\/jfernandez\/2023\/06\/20\/secure-curves-in-the-web-cryptography-api\/\" target=\"_blank\" rel=\"noopener\">previous<\/a>\u00a0post.<\/p>\n<p>Test\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/generateKey?label=master&amp;label=experimental&amp;aligned&amp;q=25519\" target=\"_blank\" rel=\"noopener\">results<\/a>\u00a0for the\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-generateKey\" target=\"_blank\" rel=\"noopener\">generateKey<\/a>\u00a0method:<\/p>\n<p><strong>Current<\/strong><\/p>\n<p class=\"part\" data-startline=\"131\" data-endline=\"131\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/c3b9927d-fe67-499f-94c2-c2efbaa03a08.png\" alt=\"\" \/><\/p>\n<p data-startline=\"131\" data-endline=\"131\"><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56.png\"><strong>Before<\/strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1941 size-full\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56.png\" alt=\"\" width=\"1840\" height=\"570\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56.png 1840w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56-300x93.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56-1024x317.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56-768x238.png 768w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-34-56-1536x476.png 1536w\" sizes=\"auto, (max-width: 1840px) 100vw, 1840px\" \/><\/a><\/p>\n<p>Test\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/derive_bits_keys?label=master&amp;label=experimental&amp;aligned&amp;q=curves\" target=\"_blank\" rel=\"noopener\">results<\/a>\u00a0for the\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-deriveBits\" target=\"_blank\" rel=\"noopener\">deriveBits<\/a>\u00a0and\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-deriveKey\" target=\"_blank\" rel=\"noopener\">deriveKey<\/a>\u00a0methods:<\/p>\n<p><strong>Current<\/strong><\/p>\n<p class=\"part\" data-startline=\"136\" data-endline=\"136\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/7c59b8ef-07d6-424f-8e3a-aa6283654887.png\" alt=\"\" \/><\/p>\n<p><strong>Before<\/strong><\/p>\n<p><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1942 size-full alignnone\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03.png\" alt=\"\" width=\"1498\" height=\"402\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03.png 1498w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03-300x81.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03-1024x275.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-37-03-768x206.png 768w\" sizes=\"auto, (max-width: 1498px) 100vw, 1498px\" \/><\/a><\/p>\n<p>Tests\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/import_export?label=master&amp;label=experimental&amp;aligned&amp;q=okp\" target=\"_blank\" rel=\"noopener\">results<\/a>\u00a0for the\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-importKey\" target=\"_blank\" rel=\"noopener\">importKey<\/a>\u00a0and\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-exportKey\" target=\"_blank\" rel=\"noopener\">exportKey<\/a>\u00a0methods:<\/p>\n<p><strong>Current<\/strong><\/p>\n<p class=\"part\" data-startline=\"141\" data-endline=\"141\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/7ac07ce2-dc98-46fd-b659-cc81903ec6c4.png\" alt=\"\" \/><\/p>\n<p data-startline=\"141\" data-endline=\"141\"><strong>Before<\/strong><\/p>\n<p data-startline=\"141\" data-endline=\"141\"><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1943 size-full\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40.png\" alt=\"\" width=\"1458\" height=\"534\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40.png 1458w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40-300x110.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40-1024x375.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-00-57-40-768x281.png 768w\" sizes=\"auto, (max-width: 1458px) 100vw, 1458px\" \/><\/a><\/p>\n<p>Tests\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/sign_verify?label=master&amp;label=experimental&amp;aligned&amp;q=eddsa\" target=\"_blank\" rel=\"noopener\">results<\/a>\u00a0for the\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-sign\" target=\"_blank\" rel=\"noopener\">sign<\/a>\u00a0and\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-verify\" target=\"_blank\" rel=\"noopener\">verify<\/a>\u00a0methods:<\/p>\n<p><strong>Current<\/strong><\/p>\n<p class=\"part\" data-startline=\"146\" data-endline=\"146\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/da539951-be17-4e59-b4b9-7efcd5172cbe.png\" alt=\"\" \/><strong>Before<\/strong><\/p>\n<p data-startline=\"146\" data-endline=\"146\"><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1944 size-full\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03.png\" alt=\"\" width=\"1456\" height=\"324\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03.png 1456w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03-300x67.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03-1024x228.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-01-03-768x171.png 768w\" sizes=\"auto, (max-width: 1456px) 100vw, 1456px\" \/><\/a><\/p>\n<p>Tests\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/wrapKey_unwrapKey?label=master&amp;label=experimental&amp;aligned\" target=\"_blank\" rel=\"noopener\">results<\/a>\u00a0for the\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-wrapKey\" target=\"_blank\" rel=\"noopener\">wrap<\/a>\u00a0and\u00a0<a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/#SubtleCrypto-method-unwrapKey\" target=\"_blank\" rel=\"noopener\">unwrap<\/a>\u00a0methods:<\/p>\n<p><strong>Current<\/strong><\/p>\n<p class=\"part\" data-startline=\"151\" data-endline=\"151\"><img decoding=\"async\" class=\"\" src=\"https:\/\/notes.igalia.com\/uploads\/9a8b305e-ca05-40c1-affa-355fe14f9f1a.png\" alt=\"\" \/><\/p>\n<p data-startline=\"151\" data-endline=\"151\"><strong>Before<\/strong><\/p>\n<p data-startline=\"151\" data-endline=\"151\"><a href=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1945 size-full\" src=\"http:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15.png\" alt=\"\" width=\"1450\" height=\"306\" srcset=\"https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15.png 1450w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15-300x63.png 300w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15-1024x216.png 1024w, https:\/\/blogs.igalia.com\/jfernandez\/files\/2025\/02\/Screenshot-from-2025-03-07-01-02-15-768x162.png 768w\" sizes=\"auto, (max-width: 1450px) 100vw, 1450px\" \/><\/a><\/p>\n<h3 id=\"Why-Chrome-didn\u2019t-ship-the-Ed25519-feature-\" class=\"part\" data-startline=\"154\" data-endline=\"154\"><i class=\"fa fa-link\"><\/i>Why Chrome didn\u2019t ship the Ed25519 feature ?<\/h3>\n<p class=\"part\" data-startline=\"156\" data-endline=\"156\">The blockers that prevented the Intent-To-Ship request of the Ed25519 are primarily these 2 issues in the spec:<\/p>\n<ul class=\"part\" data-startline=\"158\" data-endline=\"160\">\n<li class=\"\" data-startline=\"143\" data-endline=\"143\">Use of randomize EdDSA signatures (<a href=\"https:\/\/github.com\/WICG\/webcrypto-secure-curves\/issues\/28\" target=\"_blank\" rel=\"noopener\">issue #28<\/a>)<\/li>\n<li class=\"\" data-startline=\"144\" data-endline=\"145\">Rejection of any invalid and small-order points (<a href=\"https:\/\/github.com\/WICG\/webcrypto-secure-curves\/issues\/27\" target=\"_blank\" rel=\"noopener\">issue #27<\/a>)<\/li>\n<\/ul>\n<p class=\"part\" data-startline=\"161\" data-endline=\"161\">There are other minor disagreements regarding the Ed25519 specification, like the removal of the \u201calg\u201d member in the JWK format in the import\/export operations. There is a\u00a0<a href=\"https:\/\/issues.chromium.org\/issues\/40074061\" target=\"_blank\" rel=\"noopener\">bug 40074061<\/a>\u00a0in Chrome to implement this spec change, but apparently it has not been agreed on by Chrome, and now there is not enough support to proceed. Firefox already implements the specified behavior and there is a similar bug report in WebKit (<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=262613\" target=\"_blank\" rel=\"noopener\">bug 262613<\/a>) where it seems there is support to implement the behavior change. However, I\u2019d rather avoid introducing an interop issue and delay the implementation until there is more consensus regarding the spec.<\/p>\n<p class=\"part\" data-startline=\"163\" data-endline=\"163\">The issue about the use of randomized EdDSA signatures comes from the fact that WebKit\u2019s CryptoKit, the underlaying cryptography component of the WebKit engine, follows that approach in their implementation of the Ed25519 generateKey() operation. It\u2019s been always in the spirit of the Secure Curves spec to rely completely on the corresponding official RFCs. In the case of the Ed25519 algorithm it refers to the\u00a0<a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8032\" target=\"_blank\" rel=\"noopener\">RFC8032<\/a>, where it\u2019s stated the\u00a0<strong>deterministic<\/strong>\u00a0nature of the Ed25519 keys. However, the CRFG is currently discussing the issue and there is a\u00a0<a href=\"https:\/\/github.com\/cfrg\/draft-irtf-cfrg-det-sigs-with-noise\/issues\/7\" target=\"_blank\" rel=\"noopener\">proposal<\/a>\u00a0of defining a Ed25519-bis with randomized signatures.<\/p>\n<p class=\"part\" data-startline=\"165\" data-endline=\"165\">The small-order issue is more complex, it seems. The spec states clearly that any invalid or small-order point should be rejected during the Verify operation. This behavior is based on the RFC8032 mentioned before. Ideally, the underlying cryptography library should take care of performing these checks, and this has been the approach followed by the three main browsers in the implementation of the whole API; in the case of Chrome, this cryptography library is BoringSSL. The main problem here is that there are\u00a0<a href=\"https:\/\/github.com\/novifinancial\/ed25519-speccheck?tab=readme-ov-file#results\" target=\"_blank\" rel=\"noopener\">differences<\/a>\u00a0in how the cryptography libraries implement these checks, and BoringSSL is not an exception. The WPT I have implemented to cover these cases also show\u00a0<a href=\"https:\/\/wpt.fyi\/results\/WebCryptoAPI\/sign_verify\/eddsa_small_order_points.https.any.html?q=node.js%3A%21missing&amp;run_id=5080057735544832&amp;run_id=5161034075865088&amp;run_id=5111533134938112&amp;run_id=5085670653820928&amp;run_id=5139808615923712&amp;run_id=5200196762075136&amp;run_id=6267056605626368&amp;run_id=5191543510269952\" target=\"_blank\" rel=\"noopener\">interop issues<\/a>\u00a0between the three main engines. I\u2019ve filed the\u00a0<a href=\"https:\/\/bugs.chromium.org\/p\/boringssl\/issues\/detail?id=697\" target=\"_blank\" rel=\"noopener\">bug 697<\/a>, but it was marked as low priority. The alternative would be to implement the additional checks in the WebCrypto implementation, but Chrome is not very positive about this approach.<\/p>\n<p class=\"part\" data-startline=\"167\" data-endline=\"167\">The small-order checks has been a request from Mozilla since the initial\u00a0<a href=\"https:\/\/github.com\/mozilla\/standards-positions\/issues\/271#issuecomment-587414223\" target=\"_blank\" rel=\"noopener\">standard-position request<\/a>\u00a0submitted long time ago. This has been\u00a0<a href=\"https:\/\/github.com\/w3c\/webcrypto\/pull\/362#issuecomment-2057109630\" target=\"_blank\" rel=\"noopener\">stated<\/a>\u00a0again in the\u00a0<a href=\"https:\/\/github.com\/w3c\/webcrypto\/pull\/362\" target=\"_blank\" rel=\"noopener\">PR#362<\/a>\u00a0and Apple expressed positive opinions about this as well, so I believe this is going to be the selected approach.<\/p>\n<h2 id=\"Conclusions\" class=\"part\" data-startline=\"170\" data-endline=\"170\"><i class=\"fa fa-link\"><\/i>Conclusions<\/h2>\n<p class=\"part\" data-startline=\"172\" data-endline=\"172\">I believe that Secure Curves being added into the Web Cryptography specification is a great achievement for the Web Platform and brings a very powerful feature for web developers. This is especially true in the realm of a\u00a0<strong>decentralized web<\/strong>\u00a0where Content Addressing is a key concept, which is based on cryptography hashes. Browsers exposing APIs to use Ed25519 and X25519 is going to offer a big advantage for decentralized web applications. I want to thank Daniel Huigens, editor of the Web Cryptography API specification, for his huge effort to address all the spec issues filed during the years, driving discussions always with the aim to reach consensus based resolutions, despite how frustrating the process sometimes is to develop a feature like this until it\u2019s shipped in the browser.<\/p>\n<p class=\"part\" data-startline=\"174\" data-endline=\"174\">The implementation in the three major browsers is a clear sign of the stability of these features and ensures it will be maintained properly in the future. This includes the effort to keep interoperability of the three implementations, which is crucial for a healthy Web Platform ecosystem and ultimately to the web authors. The fact that we couldn\u2019t ship Ed25519 in Chrome is the only negative aspect of the work done this year but I believe it\u2019s going to be resolved soon.<\/p>\n<p class=\"part\" data-startline=\"176\" data-endline=\"176\">At Igalia we expect to continue working in 2025 on the Web Cryptography API specification, at least until the blocker issues mentioned before are addressed and we can send the Intent-To-Ship request. We hope to also find the opportunity to contribute to the spec to add new algorithms and also carry out maintenance work; ensuring an interoperable Web Platform has been always a priority for Igalia and an important factor when evaluating the projects we take on as a company.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Long story short, yes, it\u2019s possible to use the Ed25519 and X25519 algorithms through the Web Cryptography API exposed by the major browser engines: Blink (Chrome, Edge, Brave, \u2026), WebKit (Safari) and Gecko (Firefox). However, despite the hard work during the last year we haven\u2019t been able to ship Ed25519 in Chrome. It\u2019s still available &hellip; <a href=\"https:\/\/blogs.igalia.com\/jfernandez\/2025\/02\/28\/can-i-use-secure-curves-in-the-web-platform\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Can I use Secure Curves in the Web Platform?<\/span><\/a><\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1913","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/posts\/1913","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/comments?post=1913"}],"version-history":[{"count":9,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/posts\/1913\/revisions"}],"predecessor-version":[{"id":1948,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/posts\/1913\/revisions\/1948"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/media?parent=1913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/categories?post=1913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/jfernandez\/wp-json\/wp\/v2\/tags?post=1913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}