D
Deno

help

Bad implementation of X25519?

AAxone8/5/2023
I can't generate a shared secret with the current implementation of X25519
const alice = await crypto.subtle.generateKey({ name: "X25519" }, true, [
"deriveKey",
"deriveBits",
]) as CryptoKeyPair;

const bob = await crypto.subtle.generateKey({ name: "X25519" }, true, [
"deriveKey",
"deriveBits",
]) as CryptoKeyPair;

const secret = await crypto.subtle.deriveBits(
{ name: "X25519", public: alice.publicKey },
bob.privateKey,
256,
);

console.log(secret);
const alice = await crypto.subtle.generateKey({ name: "X25519" }, true, [
"deriveKey",
"deriveBits",
]) as CryptoKeyPair;

const bob = await crypto.subtle.generateKey({ name: "X25519" }, true, [
"deriveKey",
"deriveBits",
]) as CryptoKeyPair;

const secret = await crypto.subtle.deriveBits(
{ name: "X25519", public: alice.publicKey },
bob.privateKey,
256,
);

console.log(secret);
error: Uncaught OperationError: Invalid key
const secret = await crypto.subtle.deriveBits(
^
at deriveBits (ext:deno_crypto/00_crypto.js:4483:15)
at SubtleCrypto.deriveBits (ext:deno_crypto/00_crypto.js:1123:26)
at file:///D:/Codes/deno/axon/x25519.ts:11:36
error: Uncaught OperationError: Invalid key
const secret = await crypto.subtle.deriveBits(
^
at deriveBits (ext:deno_crypto/00_crypto.js:4483:15)
at SubtleCrypto.deriveBits (ext:deno_crypto/00_crypto.js:1123:26)
at file:///D:/Codes/deno/axon/x25519.ts:11:36
If we look at the implementation we can see the following code: (https://github.com/denoland/deno/blob/8ae706293149fb6e3d40af3ac80a8661fa379111/ext/crypto/00_crypto.js#L4346)
case "X25519": {
// 1.
if (baseKey[_type] !== "private") {
throw new DOMException("Invalid key type", "InvalidAccessError");
}
// 2.
const publicKey = normalizedAlgorithm.public;
// 3.
if (publicKey[_type] !== "public") {
throw new DOMException("Invalid key type", "InvalidAccessError");
}
// 4.
if (publicKey[_algorithm].name !== baseKey[_algorithm].name) {
throw new DOMException(
"Algorithm mismatch",
"InvalidAccessError",
);
}

// 5.
const kHandle = baseKey[_handle];
const k = WeakMapPrototypeGet(KEY_STORE, kHandle);

const uHandle = publicKey[_handle];
const u = WeakMapPrototypeGet(KEY_STORE, uHandle);

const secret = new Uint8Array(32);
const isIdentity = ops.op_crypto_derive_bits_x25519(k, u, secret);

// 6.
if (isIdentity) {
throw new DOMException("Invalid key", "OperationError");
}
case "X25519": {
// 1.
if (baseKey[_type] !== "private") {
throw new DOMException("Invalid key type", "InvalidAccessError");
}
// 2.
const publicKey = normalizedAlgorithm.public;
// 3.
if (publicKey[_type] !== "public") {
throw new DOMException("Invalid key type", "InvalidAccessError");
}
// 4.
if (publicKey[_algorithm].name !== baseKey[_algorithm].name) {
throw new DOMException(
"Algorithm mismatch",
"InvalidAccessError",
);
}

// 5.
const kHandle = baseKey[_handle];
const k = WeakMapPrototypeGet(KEY_STORE, kHandle);

const uHandle = publicKey[_handle];
const u = WeakMapPrototypeGet(KEY_STORE, uHandle);

const secret = new Uint8Array(32);
const isIdentity = ops.op_crypto_derive_bits_x25519(k, u, secret);

// 6.
if (isIdentity) {
throw new DOMException("Invalid key", "OperationError");
}
AAxone8/5/2023
After some research (https://vnhacker.blogspot.com/2015/09/why-not-validating-curve25519-public.html) I found what the isIdentity test was for
Why not validate Curve25519 public keys could be harmful
Update: see this post for a real world protocol that is broken if Curve25519 public keys are not validated. Update: comments on Twitter ....
AAxone8/5/2023
And I try to read some rust (https://github.com/denoland/deno/blob/main/ext/crypto/x25519.rs#L35)
#[op(fast)]
pub fn op_crypto_derive_bits_x25519(
k: &[u8],
u: &[u8],
secret: &mut [u8],
) -> bool {
let k: [u8; 32] = k.try_into().expect("Expected byteLength 32");
let u: [u8; 32] = u.try_into().expect("Expected byteLength 32");
let sh_sec = x25519_dalek::x25519(k, u);
let point = MontgomeryPoint(sh_sec);
if point.ct_eq(&MONTGOMERY_IDENTITY).unwrap_u8() == 1 {
return false;
}
secret.copy_from_slice(&sh_sec);
true
}
#[op(fast)]
pub fn op_crypto_derive_bits_x25519(
k: &[u8],
u: &[u8],
secret: &mut [u8],
) -> bool {
let k: [u8; 32] = k.try_into().expect("Expected byteLength 32");
let u: [u8; 32] = u.try_into().expect("Expected byteLength 32");
let sh_sec = x25519_dalek::x25519(k, u);
let point = MontgomeryPoint(sh_sec);
if point.ct_eq(&MONTGOMERY_IDENTITY).unwrap_u8() == 1 {
return false;
}
secret.copy_from_slice(&sh_sec);
true
}
And it seems that the function does not return if it is the identity point, but if the generated secret successfully passes the test So in the javascript, you should just check if the value is true, correct me if I'm wrong

Looking for more? Join the community!

Recommended Posts
Resize image/convert on uploadHi there, I want to store images uploaded in webp format at 200x200px. Has anyone done something likI cant import the Zustand module from deno.I leave a photo of what it shows when I put the url to the import map. And try to cache the module.Sub hosting SAAS appWhat technologies are behind the Deno Deploy feature, where you can set up your own domain name? I What should my entry point be on Deno Deploy?Only ever used firebase before. I'm getting a 502 bad gateway error when deploying my website.tsParticles & DenoHi, I’m working on a personal project with Deno & Lume. I’m trying to use tsParticles with preact. Looking for a library to pretty print </br>, <a>, etc tagsAs that title says, I'm looking for a library that can pretty print a string containing the mentioneImporting `puppeteer-cluster` from esm.sh causes `does not provide an export named 'default'` errorWhen importing `https://esm.sh/puppeteer-cluster@0.23.0` I get the following error: ``` error: UncauDeno linting not workingHello everyone, I enabled deno for a subpath in my project (`./supabase`) but unfortunately I'm not deno_pythonI'm trying to use Python with Deno with https://deno.land/x/python@0.2.7 What should I do to enable Deno VS Code plugin too aggressive in auto-completionI'm new to Deno and learning through some tutorials. I'm using VS Code and have the Deno plugin enabhow to exit all async command in deno task?consider this code ```json { "tasks": { "dev-server": "deno run --watch --allow-read --allow-nnode-pre-gyp install failing inside docker containerI'm building something that depends on a library with a native component (pulsar-client) and it doesSet a cookie in GET and retrieve in POSTbeen tryinig to do this for a couple hours now. Basically I want a way to return the user to the prWhat are newUserProps()I'm reading saaskit source, and I don't understand the point of `newUserProps()`. Why not just defin