multi-downloader-nx_mirror/modules/playready/elgamal.ts
2024-12-11 17:40:45 +01:00

45 lines
1.2 KiB
TypeScript

import { ec as EC } from 'elliptic';
import { randomBytes } from 'crypto';
import BN from 'bn.js';
export interface Point {
getY(): BN;
getX(): BN;
add(point: Point): Point;
mul(n: BN | bigint | number): Point;
neg(): Point;
}
export default class ElGamal {
curve: EC;
constructor(curve: EC) {
this.curve = curve;
}
static toBytes(n: BN): Uint8Array {
const byteArray = n.toString(16).padStart(2, '0');
if (byteArray.length % 2 !== 0) {
return Uint8Array.from(Buffer.from('0' + byteArray, 'hex'));
}
return Uint8Array.from(Buffer.from(byteArray, 'hex'));
}
encrypt(messagePoint: Point, publicKey: Point): [Point, Point] {
const ephemeralKey = new BN(randomBytes(32).toString('hex'), 16).mod(
this.curve.n!
);
const ephemeralKeyBigInt = BigInt(ephemeralKey.toString(10));
const point1 = this.curve.g.mul(ephemeralKeyBigInt);
const point2 = messagePoint.add(publicKey.mul(ephemeralKeyBigInt));
return [point1, point2];
}
static decrypt(encrypted: [Point, Point], privateKey: BN): Point {
const [point1, point2] = encrypted;
const sharedSecret = point1.mul(privateKey);
const decryptedMessage = point2.add(sharedSecret.neg());
return decryptedMessage;
}
}