react-native-quick-crypto
Version:
A fast implementation of Node's `crypto` module written in C/C++ JSI
103 lines (101 loc) • 3.25 kB
JavaScript
;
import { NitroModules } from 'react-native-nitro-modules';
import { Buffer } from '@craftzdog/react-native-buffer';
import { toArrayBuffer } from './utils/conversion';
const POINT_CONVERSION_COMPRESSED = 2;
const POINT_CONVERSION_UNCOMPRESSED = 4;
const POINT_CONVERSION_HYBRID = 6;
export class ECDH {
static get convertKeyHybrid() {
if (!this._convertKeyHybrid) {
this._convertKeyHybrid = NitroModules.createHybridObject('ECDH');
}
return this._convertKeyHybrid;
}
constructor(curveName) {
this._hybrid = NitroModules.createHybridObject('ECDH');
this._hybrid.init(curveName);
}
generateKeys() {
const key = this._hybrid.generateKeys();
return Buffer.from(key);
}
computeSecret(otherPublicKey, inputEncoding) {
let keyBuf;
if (Buffer.isBuffer(otherPublicKey)) {
keyBuf = otherPublicKey;
} else if (typeof otherPublicKey === 'string') {
keyBuf = Buffer.from(otherPublicKey, inputEncoding);
} else {
// Handle array view or other types if necessary, but Node.js typically expects Buffer or string + encoding
throw new TypeError('Invalid otherPublicKey type');
}
// ECDH.computeSecret in Node.js returns Buffer
const secret = this._hybrid.computeSecret(toArrayBuffer(keyBuf));
return Buffer.from(secret);
}
getPrivateKey() {
return Buffer.from(this._hybrid.getPrivateKey());
}
setPrivateKey(privateKey, encoding) {
let keyBuf;
if (Buffer.isBuffer(privateKey)) {
keyBuf = privateKey;
} else {
keyBuf = Buffer.from(privateKey, encoding);
}
this._hybrid.setPrivateKey(toArrayBuffer(keyBuf));
}
getPublicKey(encoding) {
// Node.js getPublicKey([encoding[, format]])
// If encoding is provided, returns string. If not, Buffer.
// Our C++ returns ArrayBuffer (Buffer).
// We ignore format for now as C++ implementation defaults to uncompressed.
const pub = Buffer.from(this._hybrid.getPublicKey());
if (encoding) {
return pub.toString(encoding);
}
return pub;
}
setPublicKey(publicKey, encoding) {
let keyBuf;
if (Buffer.isBuffer(publicKey)) {
keyBuf = publicKey;
} else {
keyBuf = Buffer.from(publicKey, encoding);
}
this._hybrid.setPublicKey(toArrayBuffer(keyBuf));
}
static convertKey(key, curve, inputEncoding, outputEncoding, format) {
let keyBuf;
if (Buffer.isBuffer(key)) {
keyBuf = key;
} else {
keyBuf = Buffer.from(key, inputEncoding);
}
let formatNum;
switch (format) {
case 'compressed':
formatNum = POINT_CONVERSION_COMPRESSED;
break;
case 'hybrid':
formatNum = POINT_CONVERSION_HYBRID;
break;
case 'uncompressed':
case undefined:
formatNum = POINT_CONVERSION_UNCOMPRESSED;
break;
default:
throw new TypeError(`Invalid point conversion format: ${format}`);
}
const result = Buffer.from(ECDH.convertKeyHybrid.convertKey(toArrayBuffer(keyBuf), curve, formatNum));
if (outputEncoding) {
return result.toString(outputEncoding);
}
return result;
}
}
export function createECDH(curveName) {
return new ECDH(curveName);
}
//# sourceMappingURL=ecdh.js.map