151 lines
5.1 KiB
HTML
151 lines
5.1 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>G1 to IPNS Public Key Conversion</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>G1 to IPNS Public Key Conversion</h1>
|
||
|
<input type="text" id="g1PublicKey" size=40 placeholder="Enter G1 Public Key">
|
||
|
<button onclick="convertPublicKey()">Convert</button>
|
||
|
<p>IPNS Public Key:</p>
|
||
|
<p id="ipnsPublicKey"></p>
|
||
|
<br>
|
||
|
<h1>Generate Seed from Salt and Password</h1>
|
||
|
<p>Generate Seed:</p>
|
||
|
<form id="generateSeedForm">
|
||
|
<label for="salt">Salt:</label>
|
||
|
<input type="text" id="salt" name="salt" required>
|
||
|
<br>
|
||
|
<label for="password">Password:</label>
|
||
|
<input type="text" id="password" name="password" required>
|
||
|
<br>
|
||
|
<button type="submit">Generate Seed</button>
|
||
|
</form>
|
||
|
<p>Generated Seed:</p>
|
||
|
<p id="generatedSeed"></p>
|
||
|
|
||
|
<!-- Include the tweetnacl library for Ed25519 operations -->
|
||
|
<script src="./nacl.min.js"></script>
|
||
|
|
||
|
<!-- Include the scrypt-async library for scrypt key derivation -->
|
||
|
<script src="./scrypt-async.min.js"></script>
|
||
|
|
||
|
<script>
|
||
|
function generateSeed(salt, password, scryptParams) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
scrypt(
|
||
|
password,
|
||
|
salt,
|
||
|
scryptParams.N,
|
||
|
scryptParams.r,
|
||
|
scryptParams.p,
|
||
|
scryptParams.seedLength,
|
||
|
function (seedArrayBuffer) {
|
||
|
// Convert the ArrayBuffer to a Uint8Array
|
||
|
const seedBytes = new Uint8Array(seedArrayBuffer);
|
||
|
resolve(seedBytes);
|
||
|
},
|
||
|
function (error) {
|
||
|
reject(error);
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
document.getElementById("generateSeedForm").addEventListener("submit", async function (event) {
|
||
|
event.preventDefault();
|
||
|
|
||
|
const salt = document.getElementById("salt").value;
|
||
|
const password = document.getElementById("password").value;
|
||
|
|
||
|
// Define the scrypt parameters
|
||
|
const scryptParams = {
|
||
|
N: 16384, // N parameter
|
||
|
r: 8, // r parameter
|
||
|
p: 8, // p parameter
|
||
|
seedLength: 64 // Seed length in bytes
|
||
|
};
|
||
|
|
||
|
try {
|
||
|
// Call the generateSeed function with the defined parameters
|
||
|
const seed = await generateSeed(salt, password, scryptParams);
|
||
|
|
||
|
// Now you can use the generated seed as needed
|
||
|
document.getElementById("generatedSeed").innerText = Array.from(seed).map(byte => ('00' + byte.toString(16)).slice(-2)).join('');
|
||
|
} catch (error) {
|
||
|
console.error(error);
|
||
|
alert("Error generating seed: " + error.message); // Display the error message
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
|
||
|
|
||
|
<script>
|
||
|
// Custom Base58 encoding and decoding functions
|
||
|
function base58Encode(bytes) {
|
||
|
const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||
|
const base = BigInt(ALPHABET.length);
|
||
|
let encoded = '';
|
||
|
|
||
|
let value = BigInt('0');
|
||
|
for (let i = 0; i < bytes.length; i++) {
|
||
|
value = value * BigInt(256) + BigInt(bytes[i]);
|
||
|
}
|
||
|
|
||
|
while (value > BigInt(0)) {
|
||
|
const remainder = value % base;
|
||
|
value = value / base;
|
||
|
encoded = ALPHABET[Number(remainder)] + encoded;
|
||
|
}
|
||
|
|
||
|
return encoded;
|
||
|
}
|
||
|
|
||
|
function base58Decode(encoded) {
|
||
|
const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||
|
const base = BigInt(ALPHABET.length);
|
||
|
|
||
|
let value = BigInt('0');
|
||
|
for (let i = 0; i < encoded.length; i++) {
|
||
|
const char = encoded[i];
|
||
|
const charValue = BigInt(ALPHABET.indexOf(char));
|
||
|
value = value * base + charValue;
|
||
|
}
|
||
|
|
||
|
const valueBytes = [];
|
||
|
while (value > BigInt(0)) {
|
||
|
const byteValue = Number(value % BigInt(256));
|
||
|
value = value / BigInt(256);
|
||
|
valueBytes.unshift(byteValue);
|
||
|
}
|
||
|
|
||
|
return new Uint8Array(valueBytes);
|
||
|
}
|
||
|
|
||
|
function convertPublicKey() {
|
||
|
const g1PublicKey = document.getElementById("g1PublicKey").value;
|
||
|
|
||
|
// Decode the Base58 encoded G1 public key using custom function
|
||
|
const decodedShared = base58Decode(g1PublicKey);
|
||
|
|
||
|
// Create a new Uint8Array to hold the IPNS public key bytes
|
||
|
const ipnsPublicKeyBytes = new Uint8Array(decodedShared.length + 6);
|
||
|
|
||
|
// Prefix bytes for IPNS public key
|
||
|
const prefixBytes = new Uint8Array([0, 36, 8, 1, 18, 32]);
|
||
|
|
||
|
// Copy the prefix bytes and G1 public key bytes into the new array
|
||
|
ipnsPublicKeyBytes.set(prefixBytes, 0);
|
||
|
ipnsPublicKeyBytes.set(decodedShared, prefixBytes.length);
|
||
|
|
||
|
// Encode the IPNS public key using custom Base58 encoding
|
||
|
const ipnsPublicKey = '1' + base58Encode(ipnsPublicKeyBytes); // Prepend '1'
|
||
|
|
||
|
document.getElementById("ipnsPublicKey").innerText = ipnsPublicKey;
|
||
|
}
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|
||
|
|