}
}
- function sequenceDeriveSignVerify(api, blockHash, privateKey) {
- let start = 0, end = 0, publicKey = null, signature = null, isValid = false
-
- start = performance.now()
- publicKey = derive(privateKey, api)
- signature = sign(blockHash, privateKey, publicKey, api)
- isValid = verify(signature, blockHash, publicKey, api)
- end = performance.now()
-
- if (!isValid) {
- throw new Error(`invalid result\nblock hash: ${blockHash}\nsignature: ${signature}\npublic key: ${publicKey}`)
- }
- if (!start || !end || start > end) {
- throw new Error(`invalid timing\nstart: ${start}\nend: ${end}`)
- }
- return end - start
- }
-
export async function test(api, size, runs) {
if (typeof size !== 'number' || size < 1) {
size = 1
// 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 deriveTimes = []
const deriveRates = []
+ const signTimes = []
const signRates = []
+ const verifyTimes = []
const verifyRates = []
+
for (let i = 0; i < runs; i++) {
await new Promise(r => setTimeout(r))
- const deriveTimes = []
- const signTimes = []
- const verifyTimes = []
+ deriveTimes[i] = []
+ signTimes[i] = []
+ verifyTimes[i] = []
+
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 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, end, duration, blockhash, privateKey, publicKey, signature
+ start = end = duration = 0
+ blockHash = random()
+ privateKey = random()
- let start = 0, end = 0
try {
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])
- }
+ publicKey = derive(privateKey, api)
end = performance.now()
- if (!start || !end || start > end) {
- throw new Error(`invalid derive timing\nstart: ${start}\nend: ${end}`)
- }
- deriveTimes.push((end - start) / 10)
+ duration = end - start
+ deriveTimes[i].push(duration)
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])
- }
+ signature = sign(blockHash, privateKey, publicKey, api)
end = performance.now()
- if (!start || !end || start > end) {
- throw new Error(`invalid sign timing\nstart: ${start}\nend: ${end}`)
- }
- signTimes.push((end - start) / 10)
+ duration = end - start
+ signTimes[i].push(duration)
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}`)
- }
+ if (!verify(signature, blockHash, publicKey, api)) {
+ 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)
+ duration = end - start
+ verifyTimes[i].push(duration)
} catch (err) {
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
console.error(err)
return
}
}
- deriveRates.push(stats(deriveTimes, api).truncatedRate)
- signRates.push(stats(signTimes, api).truncatedRate)
- verifyRates.push(stats(verifyTimes, api).truncatedRate)
+ deriveRates.push(stats(deriveTimes[i]).truncatedRate)
+ signRates.push(stats(signTimes[i]).truncatedRate)
+ verifyRates.push(stats(verifyTimes[i]).truncatedRate)
}
- 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'
+ const deriveResults = stats(deriveRates)
+ const signResults = stats(signRates)
+ const verifyResults = stats(verifyRates)
+ document.getElementById('status').textContent = 'TESTING COMPLETE'
+
+ const summary = document.createElement('pre')
+ summary.textContent += `${api} derive: ${deriveResults.truncatedHarmonic} per second\n`
+ summary.textContent += `${api} sign: ${signResults.truncatedHarmonic} per second\n`
+ summary.textContent += `${api} verify: ${verifyResults.truncatedHarmonic} per second\n`
+ document.getElementById('summary').appendChild(summary)
+ document.getElementById('summary').appendChild(document.createElement('hr'))
+
+ const output = document.createElement('pre')
+ output.textContent += `${api} derive: ${JSON.stringify(stats(deriveTimes.flat()), null, 2)}\n`
+ output.textContent += `${api} sign: ${JSON.stringify(stats(signTimes.flat()), null, 2)}\n`
+ output.textContent += `${api} verify: ${JSON.stringify(stats(verifyTimes.flat()), null, 2)}\n`
+ document.getElementById('output').appendChild(output)
+ document.getElementById('output').appendChild(document.createElement('hr'))
console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
}
<body>
<h1>Speed test for nano25519</h1>
<h2><a href="https://www.npmjs.com/package/nano25519">https://www.npmjs.com/package/nano25519</a></h2>
- <p>This test compares different Ed25519 implementations by running a sequence of functions. A random 32-byte value is generated for a message and private key, and then the test uses the values to derive a public key, sign the message, and verify the signature.</p>
+ <p>This test compares different implementations of Ed25519 primitives. A random 32-byte value is generated for a message and private key, and then the test uses the values to derive a public key, sign the message, and verify the signature.</p>
<ul>
- <li>Each derive-sign-verify sequence is timed as a unit.</li>
+ <li>Each primitive is called 10 times to is timed as a unit.</li>
<li>Each test is comprised of the specified iterations of sequence units.</li>
<li>Each test run is comprised of the specified iterations of tests.</li>
</ul>
<hr />
<h3 id="status">LOADING</h3>
<hr />
- <pre id="output"></pre>
+ <div id="summary"></div>
+ <div id="output"></div>
</body>
</html>