Skip to content
38 changes: 38 additions & 0 deletions example/src/tests/ecdh/ecdh_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,44 @@ test(SUITE, 'should set private key and compute secret for secp256k1', () => {
assert.strictEqual(secret1.toString('hex'), secret2.toString('hex'));
});

test(SUITE, 'should compute secret with sliced public key buffer', () => {
const alice = crypto.createECDH('secp256k1');
alice.generateKeys();

const bob = crypto.createECDH('secp256k1');
bob.generateKeys();

const bobPub = bob.getPublicKey() as Buffer;
assert.isTrue(Buffer.isBuffer(bobPub), 'public key should be a Buffer');

// Force non-zero byteOffset by slicing from a larger packet.
const packet = Buffer.concat([
Buffer.from([0xaa, 0xbb]),
bobPub,
Buffer.from([0xcc]),
]);
const bobPubSlice = packet.slice(2, 2 + bobPub.length);
assert.strictEqual(
bobPubSlice.length,
bobPub.length,
'slice length should match key length',
);
assert.isAbove(
bobPubSlice.byteOffset,
0,
'slice should have non-zero byteOffset',
);

const secretFromOriginal = alice.computeSecret(bobPub);
const secretFromSlice = alice.computeSecret(bobPubSlice);

assert.strictEqual(
secretFromSlice.toString('hex'),
secretFromOriginal.toString('hex'),
'sliced public key should derive the same shared secret',
);
});

test(SUITE, 'getCurves - should return array of supported curves', () => {
const curves = getCurves();
assert.isArray(curves);
Expand Down
12 changes: 5 additions & 7 deletions packages/react-native-quick-crypto/src/diffie-hellman.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NitroModules } from 'react-native-nitro-modules';
import type { DiffieHellman as DiffieHellmanInterface } from './specs/diffie-hellman.nitro';
import { Buffer } from '@craftzdog/react-native-buffer';
import { DH_GROUPS } from './dh-groups';
import { toArrayBuffer } from './utils/conversion';

export class DiffieHellman {
private _hybrid: DiffieHellmanInterface;
Expand Down Expand Up @@ -36,10 +37,7 @@ export class DiffieHellman {
genBuf = Buffer.from(generator, encoding as BufferEncoding);
}

this._hybrid.init(
primeBuf.buffer as ArrayBuffer,
genBuf.buffer as ArrayBuffer,
);
this._hybrid.init(toArrayBuffer(primeBuf), toArrayBuffer(genBuf));
}
}

Expand All @@ -62,7 +60,7 @@ export class DiffieHellman {
}

const secret = Buffer.from(
this._hybrid.computeSecret(keyBuf.buffer as ArrayBuffer),
this._hybrid.computeSecret(toArrayBuffer(keyBuf)),
);
if (outputEncoding) return secret.toString(outputEncoding);
return secret;
Expand Down Expand Up @@ -99,7 +97,7 @@ export class DiffieHellman {
} else {
keyBuf = Buffer.from(publicKey, encoding);
}
this._hybrid.setPublicKey(keyBuf.buffer as ArrayBuffer);
this._hybrid.setPublicKey(toArrayBuffer(keyBuf));
}

setPrivateKey(privateKey: Buffer | string, encoding?: BufferEncoding): void {
Expand All @@ -109,7 +107,7 @@ export class DiffieHellman {
} else {
keyBuf = Buffer.from(privateKey, encoding);
}
this._hybrid.setPrivateKey(keyBuf.buffer as ArrayBuffer);
this._hybrid.setPrivateKey(toArrayBuffer(keyBuf));
}

get verifyError(): number {
Expand Down
13 changes: 5 additions & 8 deletions packages/react-native-quick-crypto/src/ecdh.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NitroModules } from 'react-native-nitro-modules';
import type { ECDH as ECDHInterface } from './specs/ecdh.nitro';
import { Buffer } from '@craftzdog/react-native-buffer';
import { toArrayBuffer } from './utils/conversion';

const POINT_CONVERSION_COMPRESSED = 2;
const POINT_CONVERSION_UNCOMPRESSED = 4;
Expand Down Expand Up @@ -43,7 +44,7 @@ export class ECDH {
}

// ECDH.computeSecret in Node.js returns Buffer
const secret = this._hybrid.computeSecret(keyBuf.buffer as ArrayBuffer);
const secret = this._hybrid.computeSecret(toArrayBuffer(keyBuf));
return Buffer.from(secret);
}

Expand All @@ -58,7 +59,7 @@ export class ECDH {
} else {
keyBuf = Buffer.from(privateKey, encoding);
}
this._hybrid.setPrivateKey(keyBuf.buffer as ArrayBuffer);
this._hybrid.setPrivateKey(toArrayBuffer(keyBuf));
}

getPublicKey(encoding?: BufferEncoding): Buffer | string {
Expand All @@ -80,7 +81,7 @@ export class ECDH {
} else {
keyBuf = Buffer.from(publicKey, encoding);
}
this._hybrid.setPublicKey(keyBuf.buffer as ArrayBuffer);
this._hybrid.setPublicKey(toArrayBuffer(keyBuf));
}

static convertKey(
Expand Down Expand Up @@ -116,11 +117,7 @@ export class ECDH {
}

const result = Buffer.from(
ECDH.convertKeyHybrid.convertKey(
keyBuf.buffer as ArrayBuffer,
curve,
formatNum,
),
ECDH.convertKeyHybrid.convertKey(toArrayBuffer(keyBuf), curve, formatNum),
);

if (outputEncoding) {
Expand Down