Skip to content

curability4apish/ISAAC-hash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This is my project. Since cryptography is not my major, it needs audit.

About

A hash function to effectively create a secure and unique password for each service.

Philosophy

  • Secure

ISAAC has very strong avalanche effects: every unknown tiny change of its initial state can cause unpredictable output, therefore it is resistant to brute force attack and pre-calculated attack, and hasn't be proven any vulnerabilities for more than 30 years. This hash function implements ISAAC.

  • Customizable

In hash.js, you are encouraged to customize your secret 256-bit salt. It mitigates the risks that your passwords being cracked by preventing pre-calculated attack. I've also developed a tool to generate it.

seed(isaac.state, binaryStringToArray(decompose(yourSalt)));
  • Lightweight

The size of this extension is about 30 kB.

  • Logless

It doesn't use localStorage or produce any logs. ISAAC uses deterministic algorithm, so your password can be retrieved with correct keys whenever you wish.

  • Cross-platform

It is an Chromium extension, and it workable on desktop devices or Android with Kiwi Browser or Lemur Browser.

How it works

When you click on the icon of this extension, it shows a distraction-free tiny pop-up. image

There're two input bars. One is mainKey, and another is siteKey. For example, if you want to generate/retrieve your Facebook password, you should enter correct mainKey and siteKey that align with your registration setup. Those keys are as important as your derived passwords, so they shouldn't be guessable by others, which means you should evaluate their strength yourself. Those keys can be either mnemonic or you can log them elsewhere physically or digitally secure.

Theories

  • How is each password determined

hash is a hash function that implements ISAAC.

function derivePassword(mainKey, siteKey) {
  const hashedSiteKey = simpleHash(siteKey);
  const combinedKey = hashedSiteKey + mainKey;
  return simpleHash(combinedKey);
}

As above, password = hash(mainKey + hash(siteKey)).

  • How is hash designed
function simpleHash(input) {
    const binaryString = decompose(input);
    // Convert the binary string to an array
    const binaryArray = binaryStringToArray(binaryString);
    // Create an instance of the ISAAC PRNG
    const isaac = new ISAAC();
    // Seed the PRNG with yourSalt
    seed(isaac.state, binaryStringToArray(decompose('yourSalt')));
    // Seed the PRNG with the input key
    seed(isaac.state, binaryArray);
    // Generate a hash by taking five 4-byte integers and converting them to hexadecimal
    let hash = '';
    for (let i = 0; i < 5; i++) {
        const randNum = isaac.rand();
        const hexRandNum = randNum.toString(16).padStart(8, '0');
        hash += hexRandNum;
    }
    return hash; // `hash` is a 160-bit hexadecimal
}

As above, when you enter a key string, each character will be transformed into unicode, and be decomposed into 21-bit binary string with decompose. Then those binary strings will be combined together into one.

seed will change the internal state of ISAAC with mix or isaac, dependent on each bit consecutively.

function decompose(str) {
    let binaryString = '';
    // Iterate over the characters in the string
    for (let i = 0; i < str.length; i++) {
        let unicodeValue = str.charCodeAt(i);
        // Convert the Unicode value to a binary string and pad it to 21 bits
        let binaryValue = unicodeValue.toString(2).padStart(21, '0');
        // Append the binary value to the binary string
        binaryString += binaryValue;
    }
    return binaryString;
}
function seed(state, arr) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === 0) {
            // If the value is 0, perform one iteration of the PRNG mixing step
            mix(state); // Corrected: Pass the state object
        } else {
            // Otherwise, refresh the random state
            isaac(state); // Corrected: Pass the state object
        }
    }
}
// Function to convert a binary string to an array
function binaryStringToArray(binaryString) {
    return binaryString.split('').map(char => parseInt(char, 10));
}
  • References

[1]. Code of ISAAC

[2]. ISAAC's theory written by the author

[3]. Rosetta Code

[4]. Wikipedia

Note

If you are using it, please backup yourself, because future updates are possible.

About

A hash function to effectively create a secure and unique password for each service.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published