update the algorithm again

This commit is contained in:
afonya2 2025-05-29 11:58:16 +02:00
parent 8c461dd178
commit 2bd897a6f6
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC

130
IGA.ts
View file

@ -1,6 +1,7 @@
type padding = { type padding = {
padding: number[] padding: number[]
seed: number seed: number
generator: randomGenerator
} }
type verifyOut = { type verifyOut = {
@ -51,7 +52,8 @@ function generatePadding(len: number, seed?: number): padding {
} }
return { return {
padding: out, padding: out,
seed: seed seed: seed,
generator: generator
} }
} }
@ -98,17 +100,6 @@ function hex2bin(hex: string): string {
} }
return bin 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) { function checksum(input: string) {
let state: string[] = [] let state: string[] = []
@ -135,34 +126,45 @@ function checksum(input: string) {
return state.join("") return state.join("")
} }
function hashBlock(block: number[][], salt: number, iterations: number): number[][] { function hashInternal(toHash: number[], len: number, salt: number): number[] {
for (let it = 0; it < iterations; it++) { let complete: number[] = []
let state: number[][] = copy(block, true)
//Add columns while (toHash.length > 0) {
for (let i = 0; i < block.length; i++) { let inp = copy(toHash, true)
for (let ii = 0; ii < block[i].length; ii++) { for (let i = 0; i < complete.length; i++) {
let temp = state[i][ii]+(state[i][ii+1] ? state[i][ii+1] : (state[i+1] ? state[i+1][0] : state[0][0])) inp.push(complete[i])
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 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) for (let i = 0; i < selected.length; i++) {
//Add rows complete.push(selected[i])
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
} }
} }
return complete
} }
return block 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 { 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") throw new Error("Length must be at least 16")
} }
if (len > 512) { 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 != undefined) {
if (seed < 0 || seed > 65535) { 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 iterations = len*2
const padding = generatePadding(len, seed); const padding = generatePadding(len, seed);
let blocks: number[][][] = [[[]]] // len x 16 let toHash: number[] = []
for (let ip = 0; ip < padding.padding.length; ip++) { for (let i = 0; i < padding.padding.length; i++) {
if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { toHash.push(padding.padding[i])
blocks[blocks.length-1].push([])
}
blocks[blocks.length-1][blocks[blocks.length-1].length-1].push(padding.padding[ip])
} }
for (let i = 0; i < input.length; i++) { for (let i = 0; i < input.length; i++) {
if (input.charCodeAt(i) < 0 || input.charCodeAt(i) > 65535) { if (input.charCodeAt(i) < 0 || input.charCodeAt(i) > 65535) {
throw new Error("Character at index " + i + " is not a valid character") 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) { if (i % len == 0) {
blocks.push([[]]) toHash.push(padding.generator.next())
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]) toHash.push(input.charCodeAt(i))
} }
while ((toHash.length % len != 0) || (toHash.length < iterations)) {
toHash.push(padding.generator.next())
} }
if (blocks[blocks.length-1][blocks[blocks.length-1].length-1].length == len) { for (let it = 0; it < iterations; it++) {
blocks[blocks.length-1].push([]) toHash = hashInternal(toHash, len, salt)
} toHash = hashInternal2(toHash, salt)
blocks[blocks.length-1][blocks[blocks.length-1].length-1].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
}
}
for (let i = 0; i < blocks.length; i++) {
blocks[i] = hashBlock(blocks[i], salt, iterations)
} }
const pBin = fixbin(dec2bin(padding.seed), 16) const pBin = fixbin(dec2bin(padding.seed), 16)
let dataBins: string[] = [] let dataBin = ""
for (let i = 0; i < blocks.length; i++) { for (let i = 0; dataBin.length < len*4-32; i++) {
dataBins[i] = "" dataBin += fixbin(dec2bin(toHash[i]), 16)
for (let ii = 0; dataBins[i].length < len*4-32; ii++) {
dataBins[i] += fixbin(dec2bin(blocks[i][0][ii]), 16)
} }
} let hash = bin2hex(pBin + dataBin)
while (dataBins.length > 1) {
dataBins[0] = xor(dataBins[0], dataBins[1])
dataBins.splice(1, 1)
}
let hash = bin2hex(pBin + dataBins[0])
const crc = checksum(hash) const crc = checksum(hash)
hash += bin2hex(crc) hash += bin2hex(crc)
return hash 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") throw new Error("Length must be at least 16")
} }
if (len > 512) { 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) { if (inHash.length != len) {
throw new Error("The hash is not " + len + " long") throw new Error("The hash is not " + len + " long")