}
}
- function average(times, type) {
- const averages = stats(times)
- const title = `${type} derive-sign-verify`
- return {
- [title]: averages
- }
- }
-
function random(length = 32) {
const bytes = crypto.getRandomValues(new Uint8Array(length))
return [...bytes].map(b => b.toString(16).padStart(2, '0')).join('')
// run tests
console.log(`%c${api}`, 'color:green', `Calculate truncated harmonic mean of the truncated arithmetic rate of signing random block hashes across ${runs} runs of ${size} samples.`)
- const rates = []
+ const deriveRates = []
+ const signRates = []
+ const verifyRates = []
for (let i = 0; i < runs; i++) {
await new Promise(r => setTimeout(r))
- const times = []
+ const deriveTimes = []
+ const signTimes = []
+ const verifyTimes = []
for (let j = 0; j < size; j++) {
document.getElementById('status').innerHTML = `TESTING IN PROGRESS. THIS MAY TAKE A LONG TIME. ${i}/${runs} ${j}/${size}<br/>`
- const blockHash = random()
- const privateKey = blockHash
+ const blockHashes = []
+ const privateKeys = []
+ const publicKeys = []
+ const signatures = []
+ for (let i = 0; i < 10; i++) {
+ blockHashes[i] = random()
+ }
+ for (let i = 0; i < 10; i++) {
+ privateKeys[i] = random()
+ }
+
+ let start = 0, end = 0
try {
- const duration = await sequenceDeriveSignVerify(api, blockHash, privateKey)
- times.push(duration)
+ start = performance.now()
+ for (let i = 0; i < 10; i++) {
+ console.log('privateKey into derive', i, privateKeys[i])
+ publicKeys[i] = derive(privateKeys[i], api)
+ console.log('publicKey from derive', i, publicKeys[i])
+ }
+ end = performance.now()
+ if (!start || !end || start > end) {
+ throw new Error(`invalid derive timing\nstart: ${start}\nend: ${end}`)
+ }
+ deriveTimes.push((end - start) / 10)
+
+ start = performance.now()
+ for (let i = 0; i < 10; i++) {
+ console.log('blockHash into sign', i, blockHashes[i])
+ console.log('privateKey into sign', i, privateKeys[i])
+ console.log('publicKey into sign', i, publicKeys[i])
+ signatures[i] = sign(blockHashes[i], privateKeys[i], publicKeys[i], api)
+ console.log('signature from sign', i, signatures[i])
+ }
+ end = performance.now()
+ if (!start || !end || start > end) {
+ throw new Error(`invalid sign timing\nstart: ${start}\nend: ${end}`)
+ }
+ signTimes.push((end - start) / 10)
+
+ start = performance.now()
+ for (let i = 0; i < 10; i++) {
+ console.log('signature into verify', i, signatures[i])
+ console.log('blockHash into verify', i, blockHashes[i])
+ console.log('publicKey into verify', i, publicKeys[i])
+ const verified = verify(signatures[i], blockHashes[i], publicKeys[i], api)
+ console.log(verified)
+ if (!verified) {
+ const blockHash = [...blockHashes[i]].map(b => b.toString(16).padStart(2, '0')).join('')
+ const signature = [...signatures[i]].map(b => b.toString(16).padStart(2, '0')).join('')
+ const publicKey = [...publicKeys[i]].map(b => b.toString(16).padStart(2, '0')).join('')
+ throw new Error(`invalid result\nsignature: ${signature}\nblock hash: ${blockHash}\npublic key: ${publicKey}`)
+ }
+ }
+ end = performance.now()
+ if (!start || !end || start > end) {
+ throw new Error(`invalid verify timing\nstart: ${start}\nend: ${end}`)
+ }
+ verifyTimes.push((end - start) / 10)
} catch (err) {
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
console.error(err)
return
}
}
- const avg = average(times, api)
- const result = Object.values(avg)[0]
- const { truncatedRate } = result
- rates.push(truncatedRate)
+ deriveRates.push(stats(deriveTimes, api).truncatedRate)
+ signRates.push(stats(signTimes, api).truncatedRate)
+ verifyRates.push(stats(verifyTimes, api).truncatedRate)
}
- const results = Object.values(average(rates, api))[0]
- const { truncatedHarmonic } = results
- document.getElementById('output').innerHTML += `<hr/>`
- document.getElementById('summary').innerHTML += `${api} derive-sign-verify: ${truncatedHarmonic} per second<br/>`
- document.getElementById('status').innerHTML = `TESTING COMPLETE<br/>`
+ const deriveResults = stats(deriveRates).truncatedHarmonic
+ const signResults = stats(signRates).truncatedHarmonic
+ const verifyResults = stats(verifyRates).truncatedHarmonic
+ document.getElementById('output').innerHTML += '<hr/>'
+ document.getElementById('output').textContent += `${api} derive: ${deriveResults} per second\n`
+ document.getElementById('output').textContent += `${api} sign: ${signResults} per second\n`
+ document.getElementById('output').textContent += `${api} verify: ${verifyResults} per second\n`
+ document.getElementById('status').textContent = 'TESTING COMPLETE\n'
console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
}
const blockHash = document.getElementById('blockHash')?.value
const publicKey = document.getElementById('publicKey')?.value
const validation = document.getElementById('validation')
- validation.innerText = '⏳'
+ validation.textContent = '⏳'
if (signature.length === 128 && blockHash.length === 64 && publicKey.length === 64) {
- nano25519.verify(signature, blockHash, publicKey)
- .then(result => {
- validation.innerText = result
- ? '✔️'
- : '❌'
- })
- .catch(err => {
- validation.innerText = '⏳'
- })
+ try {
+ const verified = nano25519.verify(signature, blockHash, publicKey)
+ validation.textContent = verified ? '✔️' : '❌'
+ } catch (err) {
+ validation.textContent = '⏳'
+ }
}
}
document.getElementById('api').addEventListener('input', startValidation)
<hr />
<h3 id="status">LOADING</h3>
<hr />
- <pre id="summary"></pre>
- <hr />
<pre id="output"></pre>
</body>