@@ -219,6 +219,7 @@ test(SUITE, 'x25519 - error handling', () => {
219219// --- ECDH subtle.deriveBits Tests ---
220220
221221import type { NamedCurve } from 'react-native-quick-crypto' ;
222+ import { createPrivateKey , createPublicKey } from 'react-native-quick-crypto' ;
222223
223224const ecdhCurves : Array < { curve : NamedCurve ; bitLen : number } > = [
224225 { curve : 'P-256' , bitLen : 256 } ,
@@ -461,3 +462,109 @@ test(SUITE, 'x448 - error handling', () => {
461462 } ) ;
462463 } ) . to . throw ( ) ;
463464} ) ;
465+
466+ // --- EC diffieHellman Tests (regression for #959) ---
467+
468+ const ecDhCurves : Array < { curve : string ; secretLen : number } > = [
469+ { curve : 'P-256' , secretLen : 32 } ,
470+ { curve : 'P-384' , secretLen : 48 } ,
471+ { curve : 'P-521' , secretLen : 66 } ,
472+ ] ;
473+
474+ function generateEcKeyObjects ( curve : string ) {
475+ const { privateKey, publicKey } = crypto . generateKeyPairSync ( 'ec' , {
476+ namedCurve : curve ,
477+ publicKeyEncoding : { type : 'spki' , format : 'pem' } ,
478+ privateKeyEncoding : { type : 'pkcs8' , format : 'pem' } ,
479+ } ) ;
480+ return {
481+ privateKey : createPrivateKey ( privateKey as string ) ,
482+ publicKey : createPublicKey ( publicKey as string ) ,
483+ } ;
484+ }
485+
486+ for ( const { curve, secretLen } of ecDhCurves ) {
487+ test ( SUITE , `EC diffieHellman - ${ curve } shared secret` , ( ) => {
488+ const alice = generateEcKeyObjects ( curve ) ;
489+ const bob = generateEcKeyObjects ( curve ) ;
490+
491+ const secret = crypto . diffieHellman ( {
492+ privateKey : alice . privateKey ,
493+ publicKey : bob . publicKey ,
494+ } ) as Buffer ;
495+
496+ expect ( Buffer . isBuffer ( secret ) ) . to . equal ( true ) ;
497+ expect ( secret . length ) . to . equal ( secretLen ) ;
498+
499+ const allZeros = Buffer . alloc ( secretLen , 0 ) ;
500+ expect ( secret . equals ( allZeros ) ) . to . equal ( false ) ;
501+ } ) ;
502+
503+ test ( SUITE , `EC diffieHellman - ${ curve } symmetry` , ( ) => {
504+ const alice = generateEcKeyObjects ( curve ) ;
505+ const bob = generateEcKeyObjects ( curve ) ;
506+
507+ const secretAlice = crypto . diffieHellman ( {
508+ privateKey : alice . privateKey ,
509+ publicKey : bob . publicKey ,
510+ } ) as Buffer ;
511+
512+ const secretBob = crypto . diffieHellman ( {
513+ privateKey : bob . privateKey ,
514+ publicKey : alice . publicKey ,
515+ } ) as Buffer ;
516+
517+ expect ( secretAlice . equals ( secretBob ) ) . to . equal ( true ) ;
518+ } ) ;
519+
520+ test ( SUITE , `EC diffieHellman - ${ curve } deterministic` , ( ) => {
521+ const alice = generateEcKeyObjects ( curve ) ;
522+ const bob = generateEcKeyObjects ( curve ) ;
523+
524+ const secret1 = crypto . diffieHellman ( {
525+ privateKey : alice . privateKey ,
526+ publicKey : bob . publicKey ,
527+ } ) as Buffer ;
528+
529+ const secret2 = crypto . diffieHellman ( {
530+ privateKey : alice . privateKey ,
531+ publicKey : bob . publicKey ,
532+ } ) as Buffer ;
533+
534+ expect ( secret1 . equals ( secret2 ) ) . to . equal ( true ) ;
535+ } ) ;
536+
537+ test (
538+ SUITE ,
539+ `EC diffieHellman - ${ curve } different pairs produce different secrets` ,
540+ ( ) => {
541+ const alice = generateEcKeyObjects ( curve ) ;
542+ const bob = generateEcKeyObjects ( curve ) ;
543+ const charlie = generateEcKeyObjects ( curve ) ;
544+
545+ const secretBob = crypto . diffieHellman ( {
546+ privateKey : alice . privateKey ,
547+ publicKey : bob . publicKey ,
548+ } ) as Buffer ;
549+
550+ const secretCharlie = crypto . diffieHellman ( {
551+ privateKey : alice . privateKey ,
552+ publicKey : charlie . publicKey ,
553+ } ) as Buffer ;
554+
555+ expect ( secretBob . equals ( secretCharlie ) ) . to . equal ( false ) ;
556+ } ,
557+ ) ;
558+ }
559+
560+ test ( SUITE , 'EC diffieHellman - curve mismatch throws' , ( ) => {
561+ const alice = generateEcKeyObjects ( 'P-256' ) ;
562+ const bob = generateEcKeyObjects ( 'P-384' ) ;
563+
564+ expect ( ( ) => {
565+ crypto . diffieHellman ( {
566+ privateKey : alice . privateKey ,
567+ publicKey : bob . publicKey ,
568+ } ) ;
569+ } ) . to . throw ( 'Private and public key curves do not match' ) ;
570+ } ) ;
0 commit comments