paulmillr / noble-curves

Audited & minimal JS implementation of elliptic curve cryptography.
https://paulmillr.com/noble
MIT License
664 stars 62 forks source link

Secure Curves in the Javascript Web Cryptography API - secp256k1, X25519, X448, Ed25519, Ed448 #118

Closed suchislife801 closed 7 months ago

suchislife801 commented 7 months ago

Is your feature request related to a problem? Please describe.

The current Web Cryptography API lacks support for Secure Curves such as secp256k1, X25519, X448, Ed25519, Ed448, which are essential for robust cryptographic operations. This limitation restricts the API's utility in scenarios requiring advanced security, such as in the implementation of certain modern cryptographic protocols like Signal's X3DH Key Agreement protocol for example.

Describe the solution you'd like

I propose the integration of Secure Curves into the Web Cryptography API, as outlined in the WICG draft (https://wicg.github.io/webcrypto-secure-curves/). This addition would enhance the cryptographic capabilities of the API, allowing developers to leverage these advanced curves for more secure and efficient cryptographic operations.

The following curves are currectly not available:

x25519 - The "X25519" algorithm identifier is used to perform key agreement using the X25519 algorithm specified in [RFC7748].

x448 - The "X448" algorithm identifier is used to perform key agreement using the X448 algorithm specified in [RFC7748].

ed25519 - The "Ed25519" algorithm identifier is used to perform signing and verification using the Ed25519 algorithm specified in [RFC8032].

ed448 - The "Ed448" algorithm identifier is used to perform signing and verification using the Ed448 algorithm specified in [RFC8032].

Describe alternatives you've considered

An alternative could be to use third-party libraries that implement Secure Curves. However, this approach may not be as efficient or secure as having native support within the Web Cryptography API itself. Native support ensures standardized implementation and better integration with the web platform.

The Web Crypto API looks so clean. Deno has integrated new digests via std/crypto into the Web Crypto API and the experience is seamless so that works too.

Example 1: X25519 key agreement

// Generate a key pair for Alice.
const alice_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
const alice_private_key = alice_x25519_key.privateKey;

// Normally, the public key would be sent by Bob to Alice in advance over some authenticated channel.
// In this example, we'll generate another key pair and use its public key instead.
const bob_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
const bob_public_key = bob_x25519_key.publicKey;

// Perform the key agreement.
const alice_x25519_params = { name: 'X25519', public: bob_public_key };
const alice_shared_key = await crypto.subtle.deriveKey(alice_x25519_params, alice_private_key, 'HKDF', false /* extractable */, ['deriveKey']);

// Derive a symmetric key from the result.
const salt = crypto.getRandomValues(new Uint8Array(32));
const info = new TextEncoder().encode('X25519 key agreement for an AES-GCM-256 key');
const hkdf_params = { name: 'HKDF', hash: 'SHA-256', salt, info };
const gcm_params = { name: 'AES-GCM', length: 256 };
const alice_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, alice_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']);

// Encrypt some data with the symmetric key, and send it to Bob. The IV must be passed along as well.
const iv = crypto.getRandomValues(new Uint8Array(12));
const message = new TextEncoder().encode('Hi Bob!');
const encrypted = await crypto.subtle.encrypt({ ...gcm_params, iv }, alice_symmetric_key, message);

// On Bob's side, Alice's public key and Bob's private key are used, instead.
// To get the same result, Alice and Bob must agree on using the same salt and info.
const alice_public_key = alice_x25519_key.publicKey;
const bob_private_key = bob_x25519_key.privateKey;
const bob_x25519_params = { name: 'X25519', public: alice_public_key };
const bob_shared_key = await crypto.subtle.deriveKey(bob_x25519_params, bob_private_key, 'HKDF', false /* extractable */, ['deriveKey']);
const bob_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, bob_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']);

// On Bob's side, the data can be decrypted.
const decrypted = await crypto.subtle.decrypt({ ...gcm_params, iv }, bob_symmetric_key, encrypted);
const decrypted_message = new TextDecoder().decode(decrypted);
paulmillr commented 7 months ago

stop spamming with this shit

suchislife801 commented 7 months ago

So asking you to follow the WICG draft to stay consistent with the Javascript Web Crypto API is considered spam huh? Right on. I'll figure it out.

paulmillr commented 7 months ago
  1. You copy-pasted this issue from the other repository. You did not even look into noble APIs to understand our problematics or goals. That's why i'm being rude here.
    • In fact, your comment has ZERO mention about what's needed here. You are simply mentioning that "I propose the integration of Secure Curves into the Web Cryptography API". How is this related to noble at all?
  2. Javascript web crypto api is very bad:
    • It has async calls, which messes up the app lifecycle a lot
    • It has very complicated function signatures (argument usage) and key management
    • It does not expose point arithmetics and features harder than signing
  3. Browsers and others implementing the draft have no plans to support secp256k1 - which is one of the most important features of the library. So, even if someone creates the polyfill that looks like webcrypto, it still won't support secp256k1.

If you need something that looks like webcrypto, implement it by yourself.

suchislife801 commented 7 months ago

Right. Ryan Dahl isn't the creator of Node, right? And Deno, right? Deno doesn't implement features that ARE NOT part of JavaScript, right? There is nothing custom in that repo, right? Everything is browser based. I guess I'm used to stand-alone implementations. Not X2559 importing functions from your "abstract utilities" instead of being self contained. But I guess I didn't read through your library right? Right.

paulmillr commented 7 months ago

I don't care about what deno implements or not.

Write your feature requests properly.

suchislife801 commented 7 months ago

Clearly.