Move CRC32 code into cryptoUtils module

This commit is contained in:
Slava Bacherikov 2023-11-25 19:55:05 +02:00
parent 3fafde8e43
commit 2816ad255f
4 changed files with 81 additions and 80 deletions

View file

@ -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]);

View file

@ -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");

View file

@ -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");
});
});

View file

@ -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;