redesign algorithm
This commit is contained in:
parent
2c447c9381
commit
667452c49e
1 changed files with 102 additions and 40 deletions
142
IGA.ts
142
IGA.ts
|
@ -55,10 +55,14 @@ function generatePadding(len: number, seed?: number): padding {
|
|||
}
|
||||
}
|
||||
|
||||
function copy(input: number[]): number[] {
|
||||
let out: number[] = []
|
||||
function copy(input: any[], deep: boolean): any[] {
|
||||
let out: any[] = []
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
out[i] = input[i]
|
||||
if (deep && typeof input[i] == "object") {
|
||||
out[i] = copy(input[i], deep)
|
||||
} else {
|
||||
out[i] = input[i]
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -120,83 +124,137 @@ function checksum(input: string) {
|
|||
return state.join("")
|
||||
}
|
||||
|
||||
function hash(input: string, salt: number = 0, iterations: number = 32, len: number = 32, seed?: number): string {
|
||||
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) {
|
||||
temp -= 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])
|
||||
}
|
||||
block[i][ii] = temp
|
||||
}
|
||||
}
|
||||
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) {
|
||||
temp -= 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])
|
||||
}
|
||||
block[i][ii] = temp
|
||||
}
|
||||
}
|
||||
}
|
||||
return block
|
||||
}
|
||||
|
||||
function hash(input: string, salt: number = 0, len: number = 32, seed?: number): string {
|
||||
if (len*4%16 != 0) {
|
||||
throw new Error("Invalid length")
|
||||
}
|
||||
if (len < 16) {
|
||||
throw new Error("Length must be at least 16")
|
||||
}
|
||||
if (len > 512) {
|
||||
throw new Error("Length must be at most 512")
|
||||
}
|
||||
if (seed != undefined) {
|
||||
if (seed < 0 || seed > 65535) {
|
||||
throw new Error("Invalid seed")
|
||||
}
|
||||
}
|
||||
const iterations = len*2
|
||||
const padding = generatePadding(len, seed);
|
||||
let hash: number[] = []
|
||||
for (let i = 0; i < padding.padding.length; i++) {
|
||||
hash[i] = padding.padding[i]
|
||||
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 plus = hash.length
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (input.charCodeAt(i) < 0 || input.charCodeAt(i) > 50000) {
|
||||
throw new Error("Character at index " + i + " is not a valid character")
|
||||
}
|
||||
hash[plus+i] = input.charCodeAt(i)
|
||||
}
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
let state = copy(hash)
|
||||
for (let ii = 0; ii < hash.length; ii++) {
|
||||
let temp = state[ii] + (state[ii+1] ? state[ii+1] : state[0]) + salt
|
||||
while (temp > 65536) {
|
||||
temp -= i==0 ? 2411 : (state[ii-1] ? state[ii-1] : state[state.length-1])
|
||||
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])
|
||||
}
|
||||
hash[ii] = temp
|
||||
}
|
||||
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))
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
const pSeed = fixbin(dec2bin(padding.seed), 16)
|
||||
let sumAdd = ""
|
||||
for (let i = 0; sumAdd.length < 16 && i < padding.padding.length; i++) {
|
||||
sumAdd += padding.padding[i].toString(16)
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
blocks[i] = hashBlock(blocks[i], salt, iterations)
|
||||
}
|
||||
sumAdd = sumAdd.substring(0, 16).toUpperCase()
|
||||
const sum = checksum(input + sumAdd)
|
||||
let bin = ""
|
||||
for (let i = 0; bin.length < len*4-32; i++) {
|
||||
bin += hash[i] ? fixbin(dec2bin(hash[i]), 16) : "0000000000000000"
|
||||
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 hashes: string[] = []
|
||||
for (let i = 0; i < dataBins.length; i++) {
|
||||
let hsh = bin2hex(pBin+dataBins[i])
|
||||
const crc = checksum(hsh)
|
||||
hsh += bin2hex(crc)
|
||||
hashes.push(hsh)
|
||||
}
|
||||
//console.log(hashes);
|
||||
if (hashes.length == 1) {
|
||||
return hashes[0]
|
||||
} else {
|
||||
return hash(hashes.join(""), salt, len, padding.seed)
|
||||
}
|
||||
const outBin = pSeed + bin + sum
|
||||
const out = bin2hex(outBin)
|
||||
return out
|
||||
}
|
||||
|
||||
function verifyHash(input: string, inHash: string, salt: number = 0, iterations: number = 32, len: number = 32): verifyOut {
|
||||
function verifyHash(input: string, inHash: string, salt: number = 0, len: number = 32): verifyOut {
|
||||
if (len*4%16 != 0) {
|
||||
throw new Error("Invalid length")
|
||||
}
|
||||
if (len < 16) {
|
||||
throw new Error("Length must be at least 16")
|
||||
}
|
||||
if (len > 512) {
|
||||
throw new Error("Length must be at most 512")
|
||||
}
|
||||
if (inHash.length != len) {
|
||||
throw new Error("The hash is not " + len + " long")
|
||||
}
|
||||
const hBin = hex2bin(inHash)
|
||||
const pSeed = bin2dec(hBin.substring(0, 16))
|
||||
const inSum = hBin.substring(hBin.length-16, hBin.length)
|
||||
const padding = generatePadding(len, pSeed);
|
||||
let sumAdd = ""
|
||||
for (let i = 0; sumAdd.length < 16 && i < padding.padding.length; i++) {
|
||||
sumAdd += padding.padding[i].toString(16)
|
||||
}
|
||||
sumAdd = sumAdd.substring(0, 16).toUpperCase()
|
||||
const sum = checksum(input + sumAdd)
|
||||
if (inSum != sum) {
|
||||
const inCRC = hBin.substring(hBin.length-16, hBin.length)
|
||||
const crc = checksum(inHash.substring(0, inHash.length-4))
|
||||
if (inCRC != crc) {
|
||||
return {
|
||||
valid: false,
|
||||
reason: "Checksum does not match"
|
||||
}
|
||||
}
|
||||
const verifyHash = hash(input, salt, iterations, len, pSeed)
|
||||
const verifyHash = hash(input, salt, len, pSeed)
|
||||
if (inHash == verifyHash) {
|
||||
return {
|
||||
valid: true,
|
||||
|
@ -210,6 +268,10 @@ function verifyHash(input: string, inHash: string, salt: number = 0, iterations:
|
|||
}
|
||||
}
|
||||
|
||||
/*let hsh = hash("test")
|
||||
console.log(hsh)
|
||||
console.log(verifyHash("test", hsh))*/
|
||||
|
||||
export default {
|
||||
hash,
|
||||
verifyHash
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue