diff --git a/IGA.ts b/IGA.ts index e5b5578..8852fe5 100644 --- a/IGA.ts +++ b/IGA.ts @@ -1,6 +1,7 @@ type padding = { padding: number[] seed: number + generator: randomGenerator } type verifyOut = { @@ -51,7 +52,8 @@ function generatePadding(len: number, seed?: number): padding { } return { padding: out, - seed: seed + seed: seed, + generator: generator } } @@ -98,17 +100,6 @@ function hex2bin(hex: string): string { } return bin } -function xor(a: string, b: string): string { - let out = "" - for (let i = 0; i < a.length; i++) { - if (a[i] == b[i]) { - out += "0" - } else { - out += "1" - } - } - return out -} function checksum(input: string) { let state: string[] = [] @@ -135,34 +126,45 @@ function checksum(input: string) { return state.join("") } -function hashBlock(block: number[][], salt: number, iterations: number): number[][] { - for (let it = 0; it < iterations; it++) { - let state: number[][] = copy(block, true) - //Add columns - for (let i = 0; i < block.length; i++) { - for (let ii = 0; ii < block[i].length; ii++) { - let temp = state[i][ii]+(state[i][ii+1] ? state[i][ii+1] : (state[i+1] ? state[i+1][0] : state[0][0])) - while (temp > 65536) { - let subtemp = it==0 ? 2411 : state[i][ii-1] ? state[i][ii-1] : (state[i-1] ? state[i-1][state[i-1].length-1] : state[state.length-1][state[state.length-1].length-1]) - temp -= subtemp == 0 ? 2411 : subtemp - } - block[i][ii] = temp +function hashInternal(toHash: number[], len: number, salt: number): number[] { + let complete: number[] = [] + + while (toHash.length > 0) { + let inp = copy(toHash, true) + for (let i = 0; i < complete.length; i++) { + inp.push(complete[i]) + } + let selected: number[] = [] + for (let i = 0; i < len; i++) { + selected.push(inp[i]) + } + inp = inp.slice(len, inp.length) + toHash = toHash.slice(len, toHash.length) + let curr = 0 + for (let i = 0; i < inp.length; i++) { + selected[curr] = (selected[curr] + inp[i] + salt) % 65536 + curr++ + if (curr >= len) { + curr = 0 } } - state = copy(block, true) - //Add rows - for (let i = 0; i < block.length; i++) { - for (let ii = 0; ii < block[i].length; ii++) { - let temp = state[i][ii]+(state[i+1] ? state[i+1][ii] : (state[0][ii+1] ? state[0][ii+1] : state[0][0])) - while (temp > 65536) { - let subtemp = it==0 ? 2411 : state[i-1] ? state[i-1][ii] : (state[state.length-1][ii-1] ? state[state.length-1][ii-1] : state[state.length-1][state[state.length-1].length-1]) - temp -= subtemp == 0 ? 2411 : subtemp - } - block[i][ii] = temp - } + for (let i = 0; i < selected.length; i++) { + complete.push(selected[i]) } } - return block + + return complete +} +function hashInternal2(toHash: number[], salt: number): number[] { + let state = copy(toHash, true) + for (let i = 0; i < toHash.length; i++) { + let temp = state[i] + (state[i+1] ? state[i+1] : state[0]) + salt + while (temp >= 65536) { + temp -= state[i-1] ? state[i-1] : state[state.length-1] + } + toHash[i] = temp + } + return toHash } function hash(input: string, salt: number = 0, len: number = 32, seed?: number): string { @@ -173,7 +175,7 @@ function hash(input: string, salt: number = 0, len: number = 32, seed?: number): throw new Error("Length must be at least 16") } if (len > 512) { - throw new Error("Length must be at most 512") + throw new Error("Length can't be more than 512") } if (seed != undefined) { if (seed < 0 || seed > 65535) { @@ -182,58 +184,32 @@ function hash(input: string, salt: number = 0, len: number = 32, seed?: number): } const iterations = len*2 const padding = generatePadding(len, seed); - let blocks: number[][][] = [[[]]] // len x 16 - for (let ip = 0; ip < padding.padding.length; ip++) { - if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { - blocks[blocks.length-1].push([]) - } - blocks[blocks.length-1][blocks[blocks.length-1].length-1].push(padding.padding[ip]) + let toHash: number[] = [] + for (let i = 0; i < padding.padding.length; i++) { + toHash.push(padding.padding[i]) } for (let i = 0; i < input.length; i++) { if (input.charCodeAt(i) < 0 || input.charCodeAt(i) > 65535) { throw new Error("Character at index " + i + " is not a valid character") } - if (blocks[blocks.length-1].length == 16 && blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { - blocks.push([[]]) - for (let ip = 0; ip < padding.padding.length; ip++) { - if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { - blocks[blocks.length-1].push([]) - } - blocks[blocks.length-1][blocks[blocks.length-1].length-1].push(padding.padding[ip]) - } + if (i % len == 0) { + toHash.push(padding.generator.next()) } - if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { - blocks[blocks.length-1].push([]) - } - blocks[blocks.length-1][blocks[blocks.length-1].length-1].push(input.charCodeAt(i)) + toHash.push(input.charCodeAt(i)) } - let pPos = 0 - while (blocks[blocks.length-1].length != 16 || blocks[blocks.length-1][blocks[blocks.length-1].length-1].length != len) { - if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { - blocks[blocks.length-1].push([]) - } - blocks[blocks.length-1][blocks[blocks.length-1].length-1].push(padding.padding[pPos]) - pPos++ - if (pPos >= padding.padding.length) { - pPos = 0 - } + while ((toHash.length % len != 0) || (toHash.length < iterations)) { + toHash.push(padding.generator.next()) } - for (let i = 0; i < blocks.length; i++) { - blocks[i] = hashBlock(blocks[i], salt, iterations) + for (let it = 0; it < iterations; it++) { + toHash = hashInternal(toHash, len, salt) + toHash = hashInternal2(toHash, salt) } const pBin = fixbin(dec2bin(padding.seed), 16) - let dataBins: string[] = [] - for (let i = 0; i < blocks.length; i++) { - dataBins[i] = "" - for (let ii = 0; dataBins[i].length < len*4-32; ii++) { - dataBins[i] += fixbin(dec2bin(blocks[i][0][ii]), 16) - } + let dataBin = "" + for (let i = 0; dataBin.length < len*4-32; i++) { + dataBin += fixbin(dec2bin(toHash[i]), 16) } - while (dataBins.length > 1) { - dataBins[0] = xor(dataBins[0], dataBins[1]) - dataBins.splice(1, 1) - } - let hash = bin2hex(pBin + dataBins[0]) + let hash = bin2hex(pBin + dataBin) const crc = checksum(hash) hash += bin2hex(crc) return hash @@ -247,7 +223,7 @@ function verifyHash(input: string, inHash: string, salt: number = 0, len: number throw new Error("Length must be at least 16") } if (len > 512) { - throw new Error("Length must be at most 512") + throw new Error("Length can't be more than 512") } if (inHash.length != len) { throw new Error("The hash is not " + len + " long")