src/crypto/public_key/elliptic/ecdh.js
async function genPrivateEphemeralKey(curve, V, d) {
  if (curve.name === 'curve25519') {
    const one = new BN(1);
    const mask = one.ushln(255 - 3).sub(one).ushln(3);
    let secretKey = new BN(d);
    secretKey = secretKey.or(one.ushln(255 - 1));
    secretKey = secretKey.and(mask);
    secretKey = secretKey.toArrayLike(Uint8Array, 'le', 32);
    const sharedKey = nacl.scalarMult(secretKey, V.subarray(1));
    return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
  }
  V = curve.keyFromPublic(V);
  d = curve.keyFromPrivate(d);
  const secretKey = new Uint8Array(d.getPrivate());
  const S = d.derive(V);
  const len = curve.curve.curve.p.byteLength();
  const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
  return { secretKey, sharedKey };
}
async function genPrivateEphemeralKey(curve, V, d) {
  if (curve.name === 'curve25519') {
    const one = new BN(1);
    const mask = one.ushln(255 - 3).sub(one).ushln(3);
    let secretKey = new BN(d);
    secretKey = secretKey.or(one.ushln(255 - 1));
    secretKey = secretKey.and(mask);
    secretKey = secretKey.toArrayLike(Uint8Array, 'le', 32);
    const sharedKey = nacl.scalarMult(secretKey, V.subarray(1));
    return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
  }
  V = curve.keyFromPublic(V);
  d = curve.keyFromPrivate(d);
  const secretKey = new Uint8Array(d.getPrivate());
  const S = d.derive(V);
  const len = curve.curve.curve.p.byteLength();
  const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
  return { secretKey, sharedKey };
}
async function genPrivateEphemeralKey ( curve , V , d ) { if ( curve . name === 'curve25519' ) { const one = new BN ( 1 ) ; const mask = one . ushln ( 255 - 3 ) . sub ( one ) . ushln ( 3 ) ; let secretKey = new BN ( d ) ; secretKey = secretKey . or ( one . ushln ( 255 - 1 ) ) ; secretKey = secretKey . and ( mask ) ; secretKey = secretKey . toArrayLike ( Uint8Array , 'le' , 32 ) ; const sharedKey = nacl . scalarMult ( secretKey , V . subarray ( 1 ) ) ; return { secretKey , sharedKey } ; // Note: sharedKey is little-endian here, unlike below } V = curve . keyFromPublic ( V ) ; d = curve . keyFromPrivate ( d ) ; const secretKey = new Uint8Array ( d . getPrivate ( ) ) ; const S = d . derive ( V ) ; const len = curve . curve . curve . p . byteLength ( ) ; const sharedKey = S . toArrayLike ( Uint8Array , 'be' , len ) ; return { secretKey , sharedKey } ; }
Generate ECDHE secret from private key and public part of ephemeral key

@param  {Curve}                  curve        Elliptic curve object
@param  {Uint8Array}             V            Public part of ephemeral key
@param  {Uint8Array}             d            Recipient private key
@returns {Promise<BN>}                        Generated ephemeral secret
@async
Generate ECDHE secret from private key and public part of ephemeral key