From 2816ad255f5a8cffcebdebf0bdda35d475337b33 Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Sat, 25 Nov 2023 19:55:05 +0200 Subject: [PATCH] Move CRC32 code into cryptoUtils module --- src/keygen/cryptoUtils.spec.ts | 12 +++++- src/keygen/cryptoUtils.ts | 68 +++++++++++++++++++++++++++++++++ src/keygen/hpami.spec.ts | 12 +----- src/keygen/hpami.ts | 69 +--------------------------------- 4 files changed, 81 insertions(+), 80 deletions(-) diff --git a/src/keygen/cryptoUtils.spec.ts b/src/keygen/cryptoUtils.spec.ts index 87a387d..ccbf19a 100644 --- a/src/keygen/cryptoUtils.spec.ts +++ b/src/keygen/cryptoUtils.spec.ts @@ -1,4 +1,4 @@ -import { AES128, Crc64, Sha256 } from "./cryptoUtils"; +import { AES128, Crc32, Crc64, Sha256 } from "./cryptoUtils"; describe("Crypto utils", () => { it("sha256", () => { @@ -29,6 +29,16 @@ describe("Crypto utils", () => { expect(myaes.encryptBlock(Uint8Array.from("123456789abcdefg".split("").map((v) => v.charCodeAt(0))))) .toEqual(Uint8Array.from([111, 52, 225, 193, 98, 40, 19, 168, 122, 34, 93, 3, 146, 166, 202, 100])); }); + it("Check crc32", () => { + let crc = new Crc32(); + crc.update("test".split("").map((v) => v.charCodeAt(0))); + expect(crc.digest()).toEqual(3632233996); + crc.update("123".split("").map((v) => v.charCodeAt(0))); + expect(crc.digest()).toEqual(4032078523); // crc32 for "test123" + expect(crc.hexdigest()).toEqual("f054a2bb"); + crc.reset(); + expect(crc.hexdigest()).toEqual("00000000"); + }); it("crc64", () => { let mycrc = new Crc64(Crc64.ECMA_POLYNOMIAL); mycrc.update([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); diff --git a/src/keygen/cryptoUtils.ts b/src/keygen/cryptoUtils.ts index e5bb6f9..774cd0d 100644 --- a/src/keygen/cryptoUtils.ts +++ b/src/keygen/cryptoUtils.ts @@ -3,6 +3,74 @@ /* eslint-disable no-shadow */ import JSBI from "jsbi"; +export class Crc32 { + + public static readonly IEEE_POLYNOMIAL = 0xEDB88320; + private static tableCache: {[key: string]: Uint32Array} = {}; + + private table: Uint32Array; + private crc: number; + + constructor(poly?: number) { + if (poly === undefined) { + poly = Crc32.IEEE_POLYNOMIAL; + } + this.table = Crc32.getCRC32Table(poly); + this.crc = 0; + } + + private static makeTable(poly: number): Uint32Array { + let crcTable = new Uint32Array(256); + for (let i = 0; i < 256; i++) { + let crc = i; + for (let j = 0; j < 8; j++) { + crc = (crc & 1) ? (poly ^ (crc >>> 1)) : (crc >>> 1); + } + crcTable[i] = crc; + } + return crcTable; + } + + private static getCRC32Table(poly: number): Uint32Array { + const key = poly.toString(10); + const val = Crc32.tableCache[key]; + if (val !== undefined && val instanceof Uint32Array) { + return val; + } else { + const table = Crc32.makeTable(poly); + // save only IEEE table + if (poly === Crc32.IEEE_POLYNOMIAL) { + Crc32.tableCache[key] = table; + } + return table; + } + } + + public reset() { + this.crc = 0; + } + + public update(input: Uint8Array | number[]) { + this.crc ^= -1; + + for (let i = 0; i < input.length; i++) { + const b = input[i] & 0xFF; + const index = (this.crc ^ b) & 0xFF; + this.crc = (this.crc >>> 8) ^ this.table[index]; + } + + this.crc = ((this.crc ^ (-1)) >>> 0); + } + + public digest(): number { + return this.crc; + } + + public hexdigest(): string { + return ("0".repeat(8) + this.digest().toString(16)).slice(-8); + } +} + export class Crc64 { // ECMA 182 0xC96C5795D7870F42 public static readonly ECMA_POLYNOMIAL = JSBI.BigInt("14514072000185962306"); diff --git a/src/keygen/hpami.spec.ts b/src/keygen/hpami.spec.ts index 46e1ecb..de32cda 100644 --- a/src/keygen/hpami.spec.ts +++ b/src/keygen/hpami.spec.ts @@ -1,4 +1,4 @@ -import { Crc32, hpAMISolver } from "./hpami"; +import { hpAMISolver } from "./hpami"; describe("HP AMI BIOS", () => { it("Check solver", () => { @@ -9,14 +9,4 @@ describe("HP AMI BIOS", () => { expect(hpAMISolver("757EDC82")).toEqual(["edfe2edd"]); expect(hpAMISolver("7d94422f")).toEqual(["e4eea2c4"]); }); - it("Check crc32", () => { - let crc = new Crc32(); - crc.update("test".split("").map((v) => v.charCodeAt(0))); - expect(crc.digest()).toEqual(3632233996); - crc.update("123".split("").map((v) => v.charCodeAt(0))); - expect(crc.digest()).toEqual(4032078523); // crc32 for "test123" - expect(crc.hexdigest()).toEqual("f054a2bb"); - crc.reset(); - expect(crc.hexdigest()).toEqual("00000000"); - }); }); diff --git a/src/keygen/hpami.ts b/src/keygen/hpami.ts index dacff74..519162b 100644 --- a/src/keygen/hpami.ts +++ b/src/keygen/hpami.ts @@ -1,74 +1,7 @@ /* eslint-disable no-bitwise */ +import { Crc32 } from "./cryptoUtils"; import { makeSolver } from "./utils"; -export class Crc32 { - - public static readonly IEEE_POLYNOMIAL = 0xEDB88320; - private static tableCache: {[key: string]: Uint32Array} = {}; - - private table: Uint32Array; - private crc: number; - - constructor(poly?: number) { - if (poly === undefined) { - poly = Crc32.IEEE_POLYNOMIAL; - } - this.table = Crc32.getCRC32Table(poly); - this.crc = 0; - } - - private static makeTable(poly: number): Uint32Array { - let crcTable = new Uint32Array(256); - for (let i = 0; i < 256; i++) { - let crc = i; - for (let j = 0; j < 8; j++) { - crc = (crc & 1) ? (poly ^ (crc >>> 1)) : (crc >>> 1); - } - crcTable[i] = crc; - } - return crcTable; - } - - private static getCRC32Table(poly: number): Uint32Array { - const key = poly.toString(10); - const val = Crc32.tableCache[key]; - if (val !== undefined && val instanceof Uint32Array) { - return val; - } else { - const table = Crc32.makeTable(poly); - // save only IEEE table - if (poly === Crc32.IEEE_POLYNOMIAL) { - Crc32.tableCache[key] = table; - } - return table; - } - } - - public reset() { - this.crc = 0; - } - - public update(input: Uint8Array | number[]) { - this.crc ^= -1; - - for (let i = 0; i < input.length; i++) { - const b = input[i] & 0xFF; - const index = (this.crc ^ b) & 0xFF; - this.crc = (this.crc >>> 8) ^ this.table[index]; - } - - this.crc = ((this.crc ^ (-1)) >>> 0); - } - - public digest(): number { - return this.crc; - } - - public hexdigest(): string { - return ("0".repeat(8) + this.digest().toString(16)).slice(-8); - } -} - function hpAmiKeygen(input: string): string | undefined { if (input.length !== 8) { return undefined;